langgraph-api 0.18.0.dev9__tar.gz → 0.18.0.dev11__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 (341) hide show
  1. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/PKG-INFO +4 -2
  2. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/REPORTS.md +25 -7
  3. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/capacity-ci.js +40 -3
  4. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/capacity-ci.test.js +40 -0
  5. langgraph_api-0.18.0.dev11/benchmark/cpu-probe.js +55 -0
  6. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/daily-report.js +28 -7
  7. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/daily-report.test.js +50 -0
  8. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/delta-report.js +3 -2
  9. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/delta-report.test.js +5 -0
  10. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/history.js +54 -0
  11. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/history.test.js +43 -1
  12. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/ramp.js +5 -0
  13. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/staircase.py +8 -0
  14. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/staircase_step_k6.js +3 -0
  15. langgraph_api-0.18.0.dev11/langgraph_api/__init__.py +1 -0
  16. langgraph_api-0.18.0.dev11/langgraph_api/api/mcp/__init__.py +21 -0
  17. langgraph_api-0.18.0.dev11/langgraph_api/api/mcp/_calls.py +6 -0
  18. langgraph_api-0.18.0.dev11/langgraph_api/api/mcp/_constants.py +11 -0
  19. langgraph_api-0.18.0.dev11/langgraph_api/api/mcp/_routes.py +35 -0
  20. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/api/mcp/_sanitizers.py +43 -0
  21. langgraph_api-0.18.0.dev11/langgraph_api/api/mcp/_sdk.py +40 -0
  22. langgraph_api-0.18.0.dev11/langgraph_api/api/mcp/_server.py +66 -0
  23. langgraph_api-0.18.0.dev11/langgraph_api/api/mcp/_tools.py +219 -0
  24. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/api/meta.py +2 -0
  25. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/api/openapi.py +2 -3
  26. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/api/threads.py +91 -33
  27. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/config/__init__.py +3 -1
  28. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/event_streaming/service.py +10 -4
  29. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/executor/__main__.py +32 -9
  30. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/graph.py +4 -1
  31. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/grpc/ops/threads.py +6 -0
  32. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/logging.py +7 -1
  33. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/models/run.py +5 -8
  34. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/schema.py +13 -0
  35. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/state.py +52 -2
  36. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/stream.py +5 -0
  37. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/worker.py +4 -6
  38. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/checkpointer.py +20 -0
  39. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/checkpointer_pb2.py +30 -30
  40. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/checkpointer_pb2.pyi +9 -1
  41. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/orchestrator_pb2.py +12 -12
  42. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/orchestrator_pb2.pyi +8 -1
  43. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/openapi.json +87 -4
  44. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/pyproject.toml +3 -1
  45. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/uv.lock +363 -25
  46. langgraph_api-0.18.0.dev9/langgraph_api/__init__.py +0 -1
  47. langgraph_api-0.18.0.dev9/langgraph_api/api/mcp/__init__.py +0 -14
  48. langgraph_api-0.18.0.dev9/langgraph_api/api/mcp/_calls.py +0 -29
  49. langgraph_api-0.18.0.dev9/langgraph_api/api/mcp/_constants.py +0 -28
  50. langgraph_api-0.18.0.dev9/langgraph_api/api/mcp/_handlers.py +0 -365
  51. langgraph_api-0.18.0.dev9/langgraph_api/api/mcp/_models.py +0 -29
  52. langgraph_api-0.18.0.dev9/langgraph_api/api/mcp/_protocol.py +0 -224
  53. langgraph_api-0.18.0.dev9/langgraph_api/api/mcp/_routes.py +0 -37
  54. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/.gitignore +0 -0
  55. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/LICENSE +0 -0
  56. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/Makefile +0 -0
  57. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/README.md +0 -0
  58. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/.gitignore +0 -0
  59. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/Makefile +0 -0
  60. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/README.md +0 -0
  61. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/assistant.ts +0 -0
  62. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/benchmark-runner.ts +0 -0
  63. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/benchmark_profiles.ts +0 -0
  64. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/benchmarks.ts +0 -0
  65. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/cancel_first_second_completes.ts +0 -0
  66. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/classify-error.test.js +0 -0
  67. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/classify-error.ts +0 -0
  68. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/delta-turns-lib.test.js +0 -0
  69. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/delta-turns-lib.ts +0 -0
  70. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/delta_turns.ts +0 -0
  71. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/enqueued_runs_order.ts +0 -0
  72. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/interrupt_resume.ts +0 -0
  73. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/log-failure.ts +0 -0
  74. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/meta_workload.ts +0 -0
  75. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/store.ts +0 -0
  76. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/stream_write.ts +0 -0
  77. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/thread.ts +0 -0
  78. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/thread_runs_metadata_search.ts +0 -0
  79. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/threads_search_metadata.ts +0 -0
  80. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/types.ts +0 -0
  81. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/benchmark-runners/wait_write.ts +0 -0
  82. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/clean-cli.js +0 -0
  83. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/clean.js +0 -0
  84. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/continuous/README.md +0 -0
  85. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/continuous/pyproject.toml +0 -0
  86. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/continuous/runner.py +0 -0
  87. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/continuous/uv.lock +0 -0
  88. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/graphs.js +0 -0
  89. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/host-v2.js +0 -0
  90. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/host-v2.test.js +0 -0
  91. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/multer.test.js +0 -0
  92. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/package.json +0 -0
  93. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/reporting/dd_reporting.py +0 -0
  94. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/runner-descriptions.js +0 -0
  95. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/server-metrics.js +0 -0
  96. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/server-metrics.test.js +0 -0
  97. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/slack.js +0 -0
  98. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/tsconfig.json +0 -0
  99. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/update-revision.js +0 -0
  100. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/weather.js +0 -0
  101. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/benchmark/yarn.lock +0 -0
  102. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/constraints.txt +0 -0
  103. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/custom_store.sql +0 -0
  104. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/forbidden.txt +0 -0
  105. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/hatch_build.py +0 -0
  106. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/healthcheck.py +0 -0
  107. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph-cloud-debugging-20260210132856.zip +0 -0
  108. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/_checkpointer/__init__.py +0 -0
  109. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/_checkpointer/_adapter.py +0 -0
  110. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/_checkpointer/protocol.py +0 -0
  111. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/_factory_utils.py +0 -0
  112. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/api/__init__.py +0 -0
  113. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/api/a2a.py +0 -0
  114. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/api/a2ui.py +0 -0
  115. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/api/a2ui_schemas/README.md +0 -0
  116. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/api/a2ui_schemas/client_capabilities.json +0 -0
  117. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/api/a2ui_schemas/client_data_model.json +0 -0
  118. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/api/a2ui_schemas/client_to_server.json +0 -0
  119. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/api/a2ui_schemas/server_to_client.json +0 -0
  120. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/api/assistants.py +0 -0
  121. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/api/event_streaming.py +0 -0
  122. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/api/mcp/_origins.py +0 -0
  123. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/api/mcp/_outcome.py +0 -0
  124. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/api/profile.py +0 -0
  125. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/api/runs.py +0 -0
  126. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/api/store.py +0 -0
  127. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/api/ui.py +0 -0
  128. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/asgi_transport.py +0 -0
  129. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/asyncio.py +0 -0
  130. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/auth/__init__.py +0 -0
  131. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/auth/custom.py +0 -0
  132. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/auth/errors.py +0 -0
  133. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/auth/langsmith/__init__.py +0 -0
  134. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/auth/langsmith/backend.py +0 -0
  135. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/auth/langsmith/client.py +0 -0
  136. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/auth/middleware.py +0 -0
  137. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/auth/noop.py +0 -0
  138. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/auth/studio_user.py +0 -0
  139. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/beacon_data_plane_jwt_auth.py +0 -0
  140. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/cache.py +0 -0
  141. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/cli.py +0 -0
  142. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/command.py +0 -0
  143. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/config/_parse.py +0 -0
  144. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/config/schemas.py +0 -0
  145. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/cron_scheduler.py +0 -0
  146. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/drain.py +0 -0
  147. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/encryption/__init__.py +0 -0
  148. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/encryption/aes_json.py +0 -0
  149. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/encryption/context.py +0 -0
  150. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/encryption/custom.py +0 -0
  151. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/encryption/middleware.py +0 -0
  152. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/encryption/shared.py +0 -0
  153. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/errors.py +0 -0
  154. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/event_streaming/__init__.py +0 -0
  155. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/event_streaming/capabilities.py +0 -0
  156. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/event_streaming/constants.py +0 -0
  157. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/event_streaming/event_normalizers.py +0 -0
  158. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/event_streaming/namespace.py +0 -0
  159. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/event_streaming/session.py +0 -0
  160. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/event_streaming/state_normalizers.py +0 -0
  161. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/event_streaming/types.py +0 -0
  162. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/executor/__init__.py +0 -0
  163. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/feature_flags.py +0 -0
  164. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/grpc/__init__.py +0 -0
  165. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/grpc/client.py +0 -0
  166. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/grpc/generated/core_api_pb2.pyi +0 -0
  167. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/grpc/ops/__init__.py +0 -0
  168. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/grpc/ops/assistants.py +0 -0
  169. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/grpc/ops/cache.py +0 -0
  170. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/grpc/ops/crons.py +0 -0
  171. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/grpc/ops/runs.py +0 -0
  172. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/grpc/server.py +0 -0
  173. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/grpc/servicers/__init__.py +0 -0
  174. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/grpc/servicers/checkpointer.py +0 -0
  175. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/grpc/servicers/encryption.py +0 -0
  176. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/http.py +0 -0
  177. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/http_metrics.py +0 -0
  178. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/http_metrics_utils.py +0 -0
  179. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/.gitignore +0 -0
  180. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/.prettierrc +0 -0
  181. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/.yarnclean +0 -0
  182. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/__init__.py +0 -0
  183. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/base.py +0 -0
  184. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/build.mts +0 -0
  185. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/client.http.mts +0 -0
  186. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/client.mts +0 -0
  187. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/errors.py +0 -0
  188. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/global.d.ts +0 -0
  189. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/package.json +0 -0
  190. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/remote.py +0 -0
  191. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/schema.py +0 -0
  192. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/src/auth-mutations.mts +0 -0
  193. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/src/graph.mts +0 -0
  194. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/src/load.hooks.mjs +0 -0
  195. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/src/preload.mjs +0 -0
  196. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/src/utils/experiment-tracing.mts +0 -0
  197. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/src/utils/files.mts +0 -0
  198. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/src/utils/importMap.mts +0 -0
  199. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
  200. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/src/utils/serde.mts +0 -0
  201. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/sse.py +0 -0
  202. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/traceblock.mts +0 -0
  203. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/tsconfig.json +0 -0
  204. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/ui.py +0 -0
  205. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/js/yarn.lock +0 -0
  206. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/lc_security/__init__.py +0 -0
  207. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/lc_security/exceptions.py +0 -0
  208. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/lc_security/policy.py +0 -0
  209. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/lc_security/transport.py +0 -0
  210. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/metadata.py +0 -0
  211. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/metrics_collector.py +0 -0
  212. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/metrics_otlp.py +0 -0
  213. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/middleware/__init__.py +0 -0
  214. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/middleware/ensure_store.py +0 -0
  215. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/middleware/http_logger.py +0 -0
  216. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/middleware/private_network.py +0 -0
  217. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/middleware/request_id.py +0 -0
  218. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/models/__init__.py +0 -0
  219. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/operator_routes.py +0 -0
  220. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/otel_context.py +0 -0
  221. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/patch.py +0 -0
  222. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/queue_entrypoint.py +0 -0
  223. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/release_tags.py +0 -0
  224. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/route.py +0 -0
  225. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/self_hosted_logs.py +0 -0
  226. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/self_hosted_metrics.py +0 -0
  227. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/serde.py +0 -0
  228. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/server.py +0 -0
  229. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/sse.py +0 -0
  230. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/store.py +0 -0
  231. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/stream_v2.py +0 -0
  232. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/timing/__init__.py +0 -0
  233. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/timing/profiler.py +0 -0
  234. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/timing/startup.py +0 -0
  235. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/timing/timer.py +0 -0
  236. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/traceblock.py +0 -0
  237. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/tracing_session.py +0 -0
  238. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/tunneling/cloudflare.py +0 -0
  239. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/utils/__init__.py +0 -0
  240. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/utils/cache.py +0 -0
  241. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/utils/config.py +0 -0
  242. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/utils/errors.py +0 -0
  243. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/utils/extract.py +0 -0
  244. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/utils/future.py +0 -0
  245. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/utils/headers.py +0 -0
  246. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/utils/network.py +0 -0
  247. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/utils/retriable_client.py +0 -0
  248. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/utils/stream_codec.py +0 -0
  249. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/utils/uuids.py +0 -0
  250. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/validation.py +0 -0
  251. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/webhook.py +0 -0
  252. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_api/worker_runtime.py +0 -0
  253. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/__init__.py +0 -0
  254. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/conversion/__init__.py +0 -0
  255. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/conversion/_compat.py +0 -0
  256. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/conversion/checkpoint.py +0 -0
  257. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/conversion/config.py +0 -0
  258. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/conversion/durability.py +0 -0
  259. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/conversion/store.py +0 -0
  260. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/conversion/struct.py +0 -0
  261. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/conversion/value.py +0 -0
  262. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/__init__.py +0 -0
  263. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.py +0 -0
  264. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.pyi +0 -0
  265. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/core_api_pb2.py +0 -0
  266. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/core_api_pb2.pyi +0 -0
  267. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/core_api_pb2_grpc.py +0 -0
  268. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/core_api_pb2_grpc.pyi +0 -0
  269. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/encryption_pb2.py +0 -0
  270. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/encryption_pb2.pyi +0 -0
  271. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/encryption_pb2_grpc.py +0 -0
  272. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/encryption_pb2_grpc.pyi +0 -0
  273. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/engine_common_pb2.py +0 -0
  274. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/engine_common_pb2.pyi +0 -0
  275. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/engine_common_pb2_grpc.py +0 -0
  276. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/engine_common_pb2_grpc.pyi +0 -0
  277. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.py +0 -0
  278. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.pyi +0 -0
  279. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.py +0 -0
  280. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.pyi +0 -0
  281. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_control_signal_pb2.py +0 -0
  282. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_control_signal_pb2.pyi +0 -0
  283. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.py +0 -0
  284. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.pyi +0 -0
  285. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.py +0 -0
  286. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.pyi +0 -0
  287. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.py +0 -0
  288. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.pyi +0 -0
  289. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_durability_pb2.py +0 -0
  290. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_durability_pb2.pyi +0 -0
  291. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.py +0 -0
  292. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.pyi +0 -0
  293. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.py +0 -0
  294. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.pyi +0 -0
  295. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.py +0 -0
  296. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.pyi +0 -0
  297. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_run_status_pb2.py +0 -0
  298. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_run_status_pb2.pyi +0 -0
  299. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.py +0 -0
  300. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.pyi +0 -0
  301. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_stream_mode_pb2.py +0 -0
  302. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_stream_mode_pb2.pyi +0 -0
  303. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.py +0 -0
  304. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.pyi +0 -0
  305. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_thread_status_pb2.py +0 -0
  306. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_thread_status_pb2.pyi +0 -0
  307. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.py +0 -0
  308. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.pyi +0 -0
  309. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.py +0 -0
  310. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.pyi +0 -0
  311. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.py +0 -0
  312. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.pyi +0 -0
  313. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/errors_pb2.py +0 -0
  314. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/errors_pb2.pyi +0 -0
  315. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/errors_pb2_grpc.py +0 -0
  316. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/errors_pb2_grpc.pyi +0 -0
  317. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/orchestrator_pb2_grpc.py +0 -0
  318. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/orchestrator_pb2_grpc.pyi +0 -0
  319. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/store_pb2.py +0 -0
  320. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/store_pb2.pyi +0 -0
  321. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/store_pb2_grpc.py +0 -0
  322. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/proto/store_pb2_grpc.pyi +0 -0
  323. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/serde.py +0 -0
  324. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_grpc_common/store.py +0 -0
  325. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_license/__init__.py +0 -0
  326. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_license/validation.py +0 -0
  327. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_runtime/__init__.py +0 -0
  328. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_runtime/checkpoint.py +0 -0
  329. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_runtime/database.py +0 -0
  330. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_runtime/encryption.py +0 -0
  331. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_runtime/lifespan.py +0 -0
  332. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_runtime/metrics.py +0 -0
  333. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_runtime/ops.py +0 -0
  334. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_runtime/queue.py +0 -0
  335. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_runtime/retry.py +0 -0
  336. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_runtime/routes.py +0 -0
  337. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/langgraph_runtime/store.py +0 -0
  338. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/logging.json +0 -0
  339. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/scripts/build_wheel.py +0 -0
  340. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/scripts/create_license.py +0 -0
  341. {langgraph_api-0.18.0.dev9 → langgraph_api-0.18.0.dev11}/scripts/run_a2a_tck.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langgraph-api
3
- Version: 0.18.0.dev9
3
+ Version: 0.18.0.dev11
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
@@ -21,11 +21,13 @@ Requires-Dist: langgraph-runtime-inmem<0.39.0.dev0,>=0.38.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
24
+ Requires-Dist: mcp<3,>=2.3.0
24
25
  Requires-Dist: opentelemetry-api>=0.0.1
25
26
  Requires-Dist: opentelemetry-exporter-otlp-proto-http>=0.0.1
26
- Requires-Dist: opentelemetry-exporter-prometheus<0.64,>=0.63b1
27
+ Requires-Dist: opentelemetry-exporter-prometheus<0.67,>=0.63b1
27
28
  Requires-Dist: opentelemetry-sdk>=0.0.1
28
29
  Requires-Dist: orjson>=3.9.7
30
+ Requires-Dist: packaging>=23.2
29
31
  Requires-Dist: prometheus-client>=0.0.1
30
32
  Requires-Dist: protobuf<7.0.0,>=6.32.1
31
33
  Requires-Dist: pyjwt>=2.15.0
@@ -16,13 +16,24 @@ in the same channel is separate and not covered here.
16
16
  - **Failed / Errors / Regressed / Bottlenecks** lines only appear when there is
17
17
  something to say, worst first.
18
18
  - **Regressed / Improved.** A figure is flagged only when it leaves its own
19
- usual range over the recent nights: the 9 before tonight for the daily and
20
- delta reports, the last 7 for capacity, where ▲ better and ▼ worse also
21
- mark the cell in the table. The usual range is half the spread
19
+ usual range over the recent nights: the 9 latest on tonight's CPUs for the
20
+ daily reports, the 9 before tonight for delta, the 7 latest on tonight's CPUs
21
+ for capacity, where ▲ better and ▼ worse also mark the cell in the table. The usual range is half the spread
22
22
  between the best and worst of those nights, and never less than 10%, so a
23
23
  series that swings 40% night to night is not flagged for moving 15%.
24
24
  Flags start once five nights of history exist; until then the post says how
25
25
  many it has.
26
+ - **Machines.** Staging hands out machines with CPUs of different
27
+ generations, and the oldest (Intel Broadwell) runs the same code about 1.5x
28
+ slower than AMD Rome. After each run, 20 short runs ask the benchmark graph
29
+ which CPU its workers are on (capacity asks after every step and keeps every
30
+ worker it saw), so the check never warms a deployment before it is timed. The first line of the daily reports names it
31
+ (`cpus differ by runner` when the paths got different ones), a `New machine:`
32
+ line says when a path or tier moved since the night before, and flags only
33
+ compare nights on the same CPUs, so a night on a slower machine starts its
34
+ own baseline instead of reading as a regression. A deployment with several
35
+ workers is compared by the set of CPUs they ran on; the thread gives the mix.
36
+ Nights from before this check only compare with each other.
26
37
  - **The thread** holds the full numbers: per-run or per-cell detail and
27
38
  improvements with before and after values; the daily threads also give the
28
39
  load that ran.
@@ -84,7 +95,11 @@ it is shown but never flagged).
84
95
 
85
96
  The daily benchmark against a second deployment that scales to zero when
86
97
  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
98
+ start; a manual run skips the redeploy unless it is asked for. Its pods must
99
+ run on their cell's application machines (host-backend's
100
+ `HOST_DEV_ZERO_REQUIRED_CELL_POOL_PROJECT_IDS`, set for this deployment and the
101
+ serverless capacity one); other scale-to-zero deployments only prefer them and
102
+ also land on Redis machines or in another cell. 200 users per
88
103
  path instead of the daily's 1,000 (300 for search), and the pass bar is p95
89
104
  under 25 s to allow for the cold start. Read it like the [daily benchmark](#daily-benchmark).
90
105
 
@@ -94,7 +109,8 @@ under 25 s to allow for the cold start. Read it like the [daily benchmark](#dail
94
109
  before it breaks its latency target, and what runs out first?
95
110
 
96
111
  **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
112
+ get a new revision on scheduled runs and are then resized to each tier
113
+ (L, M, S) in turn. For each tier and path, k6 sends a
98
114
  fixed request rate regardless of how fast the server answers (an "open
99
115
  model", the way real traffic arrives), and raises it every 60 s: dedicated by
100
116
  50 req/s starting at 50, serverless by 5 starting at 10.
@@ -118,7 +134,8 @@ number.
118
134
  **Thread.** Improvements with before and after values, then per deployment
119
135
  two small tables grouped by tier: peak CPU as % of the pod's request, and pods
120
136
  at the start and end of the cell. Both cover the whole cell, including steps
121
- that failed. Last, the request rate actually served at the top step.
137
+ that failed. Then the request rate actually served at the top step, and the
138
+ CPU each tier ran on (`Machines:`, per path where a tier's paths differ).
122
139
 
123
140
  ## Delta channel
124
141
 
@@ -162,7 +179,8 @@ what the run returned.
162
179
 
163
180
  **Thread.** Turn, write, read and data at turns 350, 700, 1050 and 1400, with
164
181
  `gain`: how many times better delta is (`same` within 15%, below `1.0x` when
165
- delta is worse). Then the run's size, failures and correctness checks.
182
+ delta is worse). Then the run's size, failures, correctness checks and the
183
+ CPUs the workers ran on.
166
184
 
167
185
  ## Changing a report
168
186
 
@@ -22,9 +22,11 @@ import { RUNNERS } from "./daily-report.js";
22
22
  import {
23
23
  MIN_HISTORY_NIGHTS,
24
24
  cellKey,
25
+ cpuSignature,
25
26
  flaggedChange,
26
27
  formatMove,
27
28
  loadCapacityHistory,
29
+ sameCpu,
28
30
  } from "./history.js";
29
31
  import { runnerColumnName, runnerShortName } from "./runner-descriptions.js";
30
32
  import { cellWindow, peakCpu, podRange, summarizeServerMetrics } from "./server-metrics.js";
@@ -229,15 +231,33 @@ function indexCells(deployments, summaries) {
229
231
  return byDeployment;
230
232
  }
231
233
 
232
- function pastNights(deployment, tier, runner, summary, history) {
234
+ function sameExecutorNights(deployment, tier, runner, summary, history) {
233
235
  const executor = summary?.config?.k6Executor ?? "constant-vus";
234
236
  // Nights measured in users and nights measured in req/s are different
235
237
  // scales; only the same executor is a baseline.
236
238
  return (history[cellKey({ deploymentSlug: deployment.slug, computeTier: tier, benchmarkType: runner })] ?? [])
237
- .filter((night) => (night.executor ?? "constant-vus") === executor)
239
+ .filter((night) => (night.executor ?? "constant-vus") === executor);
240
+ }
241
+
242
+ // The baseline stays a week of nights on tonight's cpu; the workflow fetches more so a week can be found.
243
+ const PAST_NIGHTS = 7;
244
+
245
+ function pastNights(deployment, tier, runner, summary, history) {
246
+ return sameCpu(sameExecutorNights(deployment, tier, runner, summary, history), summary?.serverCpus)
247
+ .slice(0, PAST_NIGHTS)
238
248
  .map((night) => night.capacityVUs);
239
249
  }
240
250
 
251
+ /** Tonight's CPUs against the newest comparable night's, when both are known and differ. */
252
+ function newMachine(row, history) {
253
+ if (!row.summary || row.summary.error) return null;
254
+ const tonight = cpuSignature(row.summary.serverCpus);
255
+ const before = cpuSignature(sameExecutorNights(row.deployment, row.tier, row.runner, row.summary, history)[0]?.serverCpus);
256
+ return tonight && before && tonight !== before
257
+ ? `${deploymentName(row.deployment)} ${tierLabel(row.deployment, row.tier)} on ${tonight} (was ${before})`
258
+ : null;
259
+ }
260
+
241
261
  function analyseDeployment(deployment, cells, history) {
242
262
  const rows = [];
243
263
  let nights = 0;
@@ -404,12 +424,16 @@ export function formatAggregateTable(
404
424
  if (reasons.size > 0) lines.push(`*Why:* ${[...reasons].join(" · ")}`);
405
425
  if (regressed.length > 0) lines.push(`*Regressed:* ${regressed.map((row) => moveLine(row, unit)).join(" · ")}`);
406
426
  if (bottlenecks.length > 0) lines.push(`*Bottlenecks:* ${bottlenecks.join(" · ")}`);
427
+ // A tier's runners share its pods, so one line per tier.
428
+ const moved = [...new Set(rows.map((row) => newMachine(row, history)).filter(Boolean))];
429
+ if (moved.length > 0) lines.push(`*New machine:* ${moved.join(" · ")} · compared only with nights on the same cpu`);
407
430
  for (const warning of allWarnings) lines.push(`:warning: ${warning}`);
408
431
 
409
432
  for (const { deployment, rows: deploymentRows, nights } of analysed) {
410
433
  lines.push("", ...capacityTable(deployment, deploymentRows, unitFor(executorOf(deploymentRows.map((r) => r.summary).filter(Boolean)))));
411
434
  if (nights < MIN_HISTORY_NIGHTS) {
412
- lines.push(`_${nights} of ${MIN_HISTORY_NIGHTS} nights of history, no change flags yet_`);
435
+ const cpuKnown = deploymentRows.some((row) => cpuSignature(row.summary?.serverCpus));
436
+ lines.push(`_${nights} of ${MIN_HISTORY_NIGHTS} nights of history${cpuKnown ? " on this cpu" : ""}, no change flags yet_`);
413
437
  }
414
438
  }
415
439
  return lines.join("\n");
@@ -473,6 +497,17 @@ function serverTable(deployment, cells, kind) {
473
497
  return lines.join("\n");
474
498
  }
475
499
 
500
+ /** "Machines: L amd rome · M intel broadwell", per runner only where a tier's runners differ. */
501
+ function machines(deployment, cells) {
502
+ const parts = [];
503
+ for (const tier of deployment.tiers) {
504
+ const cpus = RUNNERS.map((r) => cpuSignature(cells[tier]?.[r]?.serverCpus) ?? "-");
505
+ if (cpus.every((cpu) => cpu === "-")) continue;
506
+ parts.push(`${tierLabel(deployment, tier)} ${cpus.every((cpu) => cpu === cpus[0]) ? cpus[0] : cpus.join(" / ")}`);
507
+ }
508
+ return parts.length > 0 ? `Machines: ${parts.join(" · ")}` : null;
509
+ }
510
+
476
511
  export function formatServerView(deployments, summaries) {
477
512
  const byDeployment = indexCells(deployments, summaries);
478
513
  const blocks = [];
@@ -484,6 +519,7 @@ export function formatServerView(deployments, summaries) {
484
519
  .map((tier) => `${tierLabel(deployment, tier)} ${RUNNERS.map((r) => servedRate(cells[tier]?.[r])).join(" / ")}`)
485
520
  .join(" · ");
486
521
  const servedLine = `Runs/sec actually served at the top step, as ${RUNNERS.map(runnerColumnName).join(" / ")}: ${served}`;
522
+ const machinesLine = machines(deployment, cells);
487
523
  // The served rate is k6's; the pod and CPU tables are the dashboard's, which is best effort.
488
524
  const cpu = serverTable(deployment, cells, "cpu");
489
525
  const pods = serverTable(deployment, cells, "pods");
@@ -493,6 +529,7 @@ export function formatServerView(deployments, summaries) {
493
529
  cpu ? `_CPU, % of request_\n${cpu}` : null,
494
530
  pods ? `_Pods, start → end_\n${pods}` : null,
495
531
  servedLine,
532
+ machinesLine,
496
533
  ]
497
534
  .filter(Boolean)
498
535
  .join("\n"),
@@ -440,3 +440,43 @@ test("a crashed cell's multi-line error keeps its detail on the Why line", () =>
440
440
  const table = formatAggregateTable(deployments, [buildErrorSummary({ deploymentSlug: "dep", computeTier: "TIER_A", benchmarkType: "wait_write" }, error)]);
441
441
  assert.match(table, /^\*Why:\* PATCH \/resource-tiers failed: 409 \{ "detail": "Unable to resize the deployment database\." \}$/m);
442
442
  });
443
+
444
+ const ROME = { "AuthenticAMD 143/49": 1 };
445
+ const BROADWELL = { "GenuineIntel 6/79": 1 };
446
+ const nightsOn = (serverCpus, ...values) => nights(...values).map((night) => ({ ...night, serverCpus }));
447
+
448
+ test("a cell that moved to an older cpu says so and is not compared with the faster cpu's nights", () => {
449
+ const deployments = [{ slug: "serverless", name: "Serverless", tiers: ["SERVERLESS_M"] }];
450
+ const tonight = (targetVUs, serverCpus) => ({
451
+ capacity: { targetVUs },
452
+ serverCpus,
453
+ config: { deploymentSlug: "serverless", computeTier: "SERVERLESS_M", benchmarkType: "wait_write", k6Executor: "constant-arrival-rate" },
454
+ });
455
+ const history = { "serverless|SERVERLESS_M|wait_write": nightsOn(ROME, 40, 40, 40, 40, 40) };
456
+
457
+ const moved = formatAggregateTable(deployments, [tonight(25, BROADWELL)], [], NIGHT, history);
458
+ assert.doesNotMatch(moved, /Regressed:/, "against the rome nights this would be -37%");
459
+ assert.match(moved, /^\*New machine:\* Serverless M on intel broadwell \(was amd rome\) · compared only with nights on the same cpu$/m);
460
+ assert.match(moved, /^_0 of 5 nights of history on this cpu, no change flags yet_$/m);
461
+
462
+ const stayed = formatAggregateTable(deployments, [tonight(25, ROME)], [], NIGHT, history);
463
+ assert.match(stayed, /^\*Regressed:\* Serverless M wait 40 → 25 req\/s \(-37%\)$/m, "the same drop on the same cpu is still a regression");
464
+ assert.doesNotMatch(stayed, /New machine/);
465
+ });
466
+
467
+ test("the thread names each tier's cpu, per runner only where they differ", () => {
468
+ const deployments = [{ slug: "serverless", name: "Serverless", tiers: ["SERVERLESS_L", "SERVERLESS_S"] }];
469
+ const cell = (tier, benchmarkType, serverCpus) => ({
470
+ capacity: { targetVUs: 30, successfulRunsPerSec: 29.5 },
471
+ serverCpus,
472
+ config: { deploymentSlug: "serverless", computeTier: tier, benchmarkType, k6Executor: "constant-arrival-rate" },
473
+ });
474
+ const view = formatServerView(deployments, [
475
+ cell("SERVERLESS_L", "wait_write", ROME),
476
+ cell("SERVERLESS_L", "stream_write", ROME),
477
+ cell("SERVERLESS_L", "threads_search_metadata", ROME),
478
+ cell("SERVERLESS_S", "wait_write", BROADWELL),
479
+ cell("SERVERLESS_S", "stream_write", ROME),
480
+ ]);
481
+ assert.match(view, /^Machines: L amd rome · S intel broadwell \/ amd rome \/ -$/m);
482
+ });
@@ -0,0 +1,55 @@
1
+ /*
2
+ * Which CPUs the deployment's workers run on, asked of the benchmark graph:
3
+ * every run returns the `host` and `host_cpu` of the worker that ran it.
4
+ * Staging hands out machines of several CPU generations and the oldest runs the
5
+ * same code about 1.5x slower, so the reports only compare nights that ran on
6
+ * the same kind. Callers ask from handleSummary, after the measured scenario,
7
+ * so the probe never warms a fresh scale-to-zero deployment before its cold
8
+ * start is timed, and it sees the workers a deployment added under load.
9
+ */
10
+ import http from 'k6/http';
11
+
12
+ // A dedicated deployment spreads runs over up to ten workers; twenty runs see most of them.
13
+ const PROBE_RUNS = 20;
14
+ // After an overloaded staircase step a run waits behind the backlog; the summary should not wait with it.
15
+ const PROBE_BUDGET_MS = 30000;
16
+
17
+ /** `{ "<host>": "<vendor family/model>" }` for each worker that answered. */
18
+ export function probeServerCpus(baseUrl, apiKey) {
19
+ const headers = { 'Content-Type': 'application/json' };
20
+ if (apiKey) headers['x-api-key'] = apiKey;
21
+ const body = JSON.stringify({
22
+ assistant_id: 'benchmark',
23
+ input: {},
24
+ context: { steps: 1, expand: 1 },
25
+ config: { recursion_limit: 3 },
26
+ });
27
+ const deadline = Date.now() + PROBE_BUDGET_MS;
28
+ const cpuByHost = {};
29
+ for (let i = 0; i < PROBE_RUNS && Date.now() < deadline; i++) {
30
+ const response = http.post(`${baseUrl}/runs/wait`, body, {
31
+ headers,
32
+ timeout: Math.max(1000, deadline - Date.now()),
33
+ // Not part of the measurement, so a failed probe must not count against http_req_failed.
34
+ responseCallback: http.expectedStatuses({ min: 100, max: 599 }),
35
+ });
36
+ if (response.status !== 200) continue;
37
+ let output;
38
+ try {
39
+ output = response.json();
40
+ } catch (error) {
41
+ continue;
42
+ }
43
+ if (typeof output?.host === 'string' && typeof output?.host_cpu === 'string') {
44
+ cpuByHost[output.host] = output.host_cpu;
45
+ }
46
+ }
47
+ return cpuByHost;
48
+ }
49
+
50
+ /** `{ "<vendor family/model>": workers seen }`, or null when no worker answered. */
51
+ export function countByCpu(cpuByHost) {
52
+ const counts = {};
53
+ for (const cpu of Object.values(cpuByHost ?? {})) counts[cpu] = (counts[cpu] ?? 0) + 1;
54
+ return Object.keys(counts).length > 0 ? counts : null;
55
+ }
@@ -8,7 +8,7 @@ import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
8
8
  import path from 'node:path';
9
9
  import { fileURLToPath } from 'node:url';
10
10
 
11
- import { MIN_HISTORY_NIGHTS, compare, flaggedChange, formatDelta, formatMove, loadDailyHistory, sparkline } from './history.js';
11
+ import { MIN_HISTORY_NIGHTS, compare, cpuSignature, describeCpus, flaggedChange, formatDelta, formatMove, loadDailyHistory, sameCpu, sparkline } from './history.js';
12
12
  import { runnerColumnName, runnerShortName } from './runner-descriptions.js';
13
13
  import { dotFor, footer, postReport } from './slack.js';
14
14
 
@@ -241,6 +241,24 @@ export const NIGHTS = 10;
241
241
 
242
242
  const baseline = (run) => (run.history ?? []).slice(0, NIGHTS - 1);
243
243
 
244
+ // The trend draws every night; the flags compare only nights on tonight's kinds of CPU.
245
+ const comparable = (run) => sameCpu(run.history ?? [], run.summary?.metrics?.serverCpus).slice(0, NIGHTS - 1);
246
+
247
+ const cpuOf = (run) => cpuSignature(run.summary?.metrics?.serverCpus);
248
+
249
+ /** Tonight's CPUs against the newest past night's, when both are known and differ. */
250
+ function newMachine(run) {
251
+ const tonight = cpuOf(run);
252
+ const before = cpuSignature(run.history?.[0]?.serverCpus);
253
+ return tonight && before && tonight !== before ? `${runName(run)} on ${tonight} (was ${before})` : null;
254
+ }
255
+
256
+ function cpuClause(runs) {
257
+ const known = runs.map(cpuOf).filter(Boolean);
258
+ if (known.length === 0) return '';
259
+ return known.every((cpu) => cpu === known[0]) ? ` · ${known[0]}` : ' · cpus differ by runner';
260
+ }
261
+
244
262
  function p95Of(metrics) {
245
263
  return succeeded(metrics) && isNumber(metrics?.p95Duration) ? metrics.p95Duration : null;
246
264
  }
@@ -281,7 +299,7 @@ export function buildDigest(runs, context = {}) {
281
299
  } = context;
282
300
 
283
301
  const changesByRun = new Map(
284
- runs.map((run) => [run, run.summary?.metrics ? figureChanges(run.summary.metrics, baseline(run)) : []])
302
+ runs.map((run) => [run, run.summary?.metrics ? figureChanges(run.summary.metrics, comparable(run)) : []])
285
303
  );
286
304
  const unhealthy = runs.filter((run) => !isHealthy({ stepOutcome: run.stepOutcome, metrics: run.summary?.metrics }));
287
305
  const withErrors = runs.filter((run) => hasErrors(run.summary?.metrics));
@@ -295,7 +313,7 @@ export function buildDigest(runs, context = {}) {
295
313
  if (moved.length > 0) list.push(`${runName(run)} ${moved.map((c, i) => (i === 0 ? `${c.label} ${c.move}` : `${c.label} ${roundedDelta(c.deltaPct)}`)).join(', ')}`);
296
314
  }
297
315
  }
298
- const nights = Math.max(0, ...runs.map((run) => baseline(run).length));
316
+ const nights = Math.max(0, ...runs.map((run) => comparable(run).length));
299
317
  const checked = nights >= MIN_HISTORY_NIGHTS;
300
318
  const tools = runs.map((run) => [run, toolLine(run.summary?.metrics)]).filter(([, line]) => line);
301
319
 
@@ -312,7 +330,7 @@ export function buildDigest(runs, context = {}) {
312
330
  const date = now.toLocaleDateString('en-US', { month: 'short', day: 'numeric', timeZone: 'UTC' });
313
331
  const passed = runs.length - unhealthy.length;
314
332
  const lines = [
315
- `${dot} *Daily Benchmark${titleSuffix} · ${date}*${manual ? ' · manual run' : ''}${apiVersion ? ` · API ${apiVersion}` : ''} · ${passed} of ${runs.length} passed · ${clauses.join(' · ')}`,
333
+ `${dot} *Daily Benchmark${titleSuffix} · ${date}*${manual ? ' · manual run' : ''}${apiVersion ? ` · API ${apiVersion}` : ''}${cpuClause(runs)} · ${passed} of ${runs.length} passed · ${clauses.join(' · ')}`,
316
334
  ];
317
335
  if (unhealthy.length > 0) {
318
336
  lines.push(`*Failed:* ${unhealthy.map((run) => `${runName(run)}: ${failureReason(run)}`).join(' · ')}`);
@@ -333,10 +351,12 @@ export function buildDigest(runs, context = {}) {
333
351
  );
334
352
  }
335
353
  if (regressed.length > 0) lines.push(`*Regressed:* ${regressed.join(' · ')}`);
354
+ const moved = runs.map(newMachine).filter(Boolean);
355
+ if (moved.length > 0) lines.push(`*New machine:* ${moved.join(' · ')} · compared only with nights on the same cpu`);
336
356
  for (const [run, line] of tools) lines.push(`:warning: ${runName(run)}: ${line}`);
337
357
 
338
358
  lines.push(...digestTable(runs));
339
- if (!checked) lines.push(`_${nights} of ${MIN_HISTORY_NIGHTS} nights of history, no change flags yet_`);
359
+ if (!checked) lines.push(`_${nights} of ${MIN_HISTORY_NIGHTS} nights of history${runs.some(cpuOf) ? ' on this cpu' : ''}, no change flags yet_`);
340
360
  lines.push(footer(docsAnchor, artifactUrl));
341
361
 
342
362
  return { text: lines.join('\n'), thread: [perRunDetail(runs, changesByRun, improved, loadSentence(runs))] };
@@ -365,9 +385,10 @@ function perRunDetail(runs, changesByRun, improved, load) {
365
385
  lines.push(`${runName(run)}: ${noResults(run)}`);
366
386
  continue;
367
387
  }
368
- const counts = `${count(metrics.totalRuns)} runs, ${count(metrics.failedRuns)} failed`;
388
+ const cpus = describeCpus(metrics.serverCpus);
389
+ const counts = `${count(metrics.totalRuns)} runs, ${count(metrics.failedRuns)} failed${cpus ? ` · ${cpus}` : ''}`;
369
390
  const changes = changesByRun.get(run);
370
- const nights = baseline(run).length;
391
+ const nights = comparable(run).length;
371
392
  const drift =
372
393
  changes.length > 0
373
394
  ? `vs ${nights} nights: ${changes.map((c) => `${c.label} ${formatDelta(c.deltaPct)}${c.flagged ? ` ${c.arrow}` : ''}`).join(' · ')}`
@@ -516,3 +516,53 @@ test('every table line in the channel message and the thread fits a phone', () =
516
516
  assert.ok(widestCodeLine(text) <= PHONE_WIDTH, `channel table is ${widestCodeLine(text)} wide`);
517
517
  assert.ok(widestCodeLine(thread[0]) <= PHONE_WIDTH, `thread table is ${widestCodeLine(thread[0])} wide`);
518
518
  });
519
+
520
+ const ROME = { 'AuthenticAMD 143/49': 1 };
521
+ const BROADWELL = { 'GenuineIntel 6/79': 1 };
522
+ const on = (serverCpus) => () => ({ serverCpus });
523
+
524
+ test('a slow night on an older cpu is compared only with nights on that cpu, so it is no regression', () => {
525
+ const past = [...nights([9.6, 9.9, 10.2], on(BROADWELL)), ...nights([4.5, 4.5, 4.5, 4.5, 4.5, 4.5], on(ROME))];
526
+ const tonight = { ...healthyMetrics, p95Duration: 10.1, serverCpus: BROADWELL };
527
+ const { text, thread } = buildDigest([run('wait_write', { summary: { metrics: tonight }, history: past })], base);
528
+ assert.match(text, /^🟢 \*Daily Benchmark · Aug 17\* · API 0\.14\.0 · intel broadwell · 1 of 1 passed · all quiet$/m);
529
+ assert.doesNotMatch(text, /Regressed:/, 'against the rome nights this would be +124%');
530
+ assert.match(text, /^_3 of 5 nights of history on this cpu, no change flags yet_$/m);
531
+ assert.match(thread[0], /^wait_write: 133,000 runs, 0 failed · intel broadwell · vs 3 nights: /m);
532
+ });
533
+
534
+ test('a regression on the same cpu is still flagged', () => {
535
+ const past = nights([4.5, 4.5, 4.5, 4.5, 4.5, 4.5], on(ROME));
536
+ const { text } = buildDigest([run('wait_write', { summary: { metrics: { ...healthyMetrics, p95Duration: 9.0, serverCpus: ROME } }, history: past })], base);
537
+ assert.match(text, /^\*Regressed:\* wait_write p95 4\.5 → 9\.0 s \(\+100%\)$/m);
538
+ });
539
+
540
+ test('a night on a different cpu than the night before says so instead of flagging', () => {
541
+ const past = nights([4.5, 4.5, 4.5, 4.5, 4.5, 4.5], on(ROME));
542
+ const { text } = buildDigest([run('stream_write', { summary: { metrics: { ...healthyMetrics, p95Duration: 9.0, serverCpus: BROADWELL } }, history: past })], base);
543
+ assert.match(text, /^\*New machine:\* stream_write on intel broadwell \(was amd rome\) · compared only with nights on the same cpu$/m);
544
+ assert.doesNotMatch(text, /Regressed:/);
545
+ assert.match(text, /^_0 of 5 nights of history on this cpu, no change flags yet_$/m);
546
+ assert.match(text, /^stream\s+9\.0 [▁-█]+$/m, 'the trend still draws every night');
547
+ });
548
+
549
+ test('nights before the probe keep comparing with each other', () => {
550
+ const past = nights([4.5, 4.5, 4.5, 4.5, 4.5, 4.5]);
551
+ const { text } = buildDigest([run('wait_write', { summary: { metrics: { ...healthyMetrics, p95Duration: 9.0 } }, history: past })], base);
552
+ assert.match(text, /^\*Regressed:\* wait_write p95 4\.5 → 9\.0 s/m);
553
+ assert.doesNotMatch(text, /New machine|intel|amd/);
554
+ });
555
+
556
+ test('runners on different cpus say so in the header and name their cpu in the thread', () => {
557
+ const mixed = { 'AuthenticAMD 143/49': 6, 'GenuineIntel 6/79': 4 };
558
+ const runs = [
559
+ run('wait_write', { summary: { metrics: { ...healthyMetrics, serverCpus: BROADWELL } } }),
560
+ run('stream_write', { summary: { metrics: { ...healthyMetrics, serverCpus: mixed } } }),
561
+ ];
562
+ const { text, thread } = buildDigest(runs, base);
563
+ assert.match(text, /· API 0\.14\.0 · cpus differ by runner · 2 of 2 passed/);
564
+ assert.match(thread[0], /^wait_write: 133,000 runs, 0 failed · intel broadwell · /m);
565
+ assert.match(thread[0], /^stream_write: 133,000 runs, 0 failed · 6 amd rome, 4 intel broadwell · /m);
566
+ const same = buildDigest([runs[1]], base).text;
567
+ assert.match(same, /· API 0\.14\.0 · amd rome \+ intel broadwell · 1 of 1 passed/);
568
+ });
@@ -10,7 +10,7 @@ import readline from 'node:readline';
10
10
  import { fileURLToPath } from 'node:url';
11
11
 
12
12
  import { ERROR_ATTENTION, MIN_SUCCESS_RATE, describeThreshold, errorParts, findLatestSummary, isHealthy, readApiVersion, readSummary } from './daily-report.js';
13
- import { MIN_HISTORY_NIGHTS, flaggedChange, formatMove, sparkline } from './history.js';
13
+ import { MIN_HISTORY_NIGHTS, describeCpus, flaggedChange, formatMove, sparkline } from './history.js';
14
14
  import { dotFor, footer, postReport } from './slack.js';
15
15
 
16
16
  const HERE = path.dirname(fileURLToPath(import.meta.url));
@@ -345,8 +345,9 @@ function threadText(run, metrics, guard, improved) {
345
345
  const users = Number(run.load?.loadSize) || null;
346
346
  const turns = Number(run.load?.turns) || null;
347
347
  const shape = users && turns ? `${count(users)} users × ${count(turns)} turns × ${run.cells.length} setups · ` : '';
348
+ const cpus = describeCpus(metrics?.serverCpus);
348
349
  const health = metrics
349
- ? `${count(metrics.failedRuns)} failed of ${count(metrics.totalRuns)} turns · ${guard > 0 ? `correctness check failed × ${count(guard)}` : 'no correctness failures'}`
350
+ ? `${count(metrics.failedRuns)} failed of ${count(metrics.totalRuns)} turns · ${guard > 0 ? `correctness check failed × ${count(guard)}` : 'no correctness failures'}${cpus ? ` · ${cpus}` : ''}`
350
351
  : 'no results';
351
352
  return [
352
353
  '*As the thread grows*',
@@ -194,3 +194,8 @@ test('a single downloaded artifact is read from the results directory itself', a
194
194
  assert.equal(run.stepOutcome, 'success');
195
195
  assert.equal(run.cells.find((c) => c.cell === 'delta_50').buckets['1-50'].saveMeanMs, 30);
196
196
  });
197
+
198
+ test('the run line names the cpus the workers ran on', () => {
199
+ const { thread } = buildReport(run({ summary: { serverCpus: { 'AuthenticAMD 143/49': 6, 'GenuineIntel 6/79': 4 } } }), base);
200
+ assert.match(thread[0], /^\*Run\* · .* · no correctness failures · 6 amd rome, 4 intel broadwell$/m);
201
+ });
@@ -138,6 +138,7 @@ export function loadCapacityHistory(dir) {
138
138
  if (summary.error) continue;
139
139
  (history[cellKey(config)] ??= []).push({
140
140
  executor: config.k6Executor ?? "constant-vus",
141
+ serverCpus: summary.serverCpus ?? null,
141
142
  capacityVUs: summary.capacity?.targetVUs ?? 0,
142
143
  runsPerSec:
143
144
  summary.capacity?.successfulRunsPerSec ??
@@ -149,6 +150,59 @@ export function loadCapacityHistory(dir) {
149
150
  return history;
150
151
  }
151
152
 
153
+ // The CPUs staging's E2 machines come with, keyed `vendor family/model` as cpu-probe.js records them.
154
+ const CPU_NAMES = {
155
+ "GenuineIntel 6/63": "intel haswell",
156
+ "GenuineIntel 6/79": "intel broadwell",
157
+ "GenuineIntel 6/85": "intel skylake or cascade lake",
158
+ "AuthenticAMD 23/49": "amd rome",
159
+ "AuthenticAMD 25/1": "amd milan",
160
+ };
161
+
162
+ /** gVisor prints an AMD family as `(extended << 4) | 0xF`, 143 where Linux says 23. */
163
+ function cpuName(key) {
164
+ const match = /^(\S+) (\d+)\/(\d+)$/.exec(key);
165
+ if (!match) return key;
166
+ const [, vendor, familyText, model] = match;
167
+ const raw = Number(familyText);
168
+ const family = raw > 0xf && (raw & 0xf) === 0xf ? 0xf + (raw >> 4) : raw;
169
+ const normalized = `${vendor} ${family}/${model}`;
170
+ return CPU_NAMES[normalized] ?? normalized;
171
+ }
172
+
173
+ function cpuCounts(serverCpus) {
174
+ const counts = {};
175
+ for (const [key, workers] of Object.entries(serverCpus ?? {})) {
176
+ const name = cpuName(key);
177
+ counts[name] = (counts[name] ?? 0) + (isNumber(workers) ? workers : 0);
178
+ }
179
+ return counts;
180
+ }
181
+
182
+ /** The kinds of CPU a night ran on, the key the reports compare nights by; null when unknown. */
183
+ export function cpuSignature(serverCpus) {
184
+ const names = Object.keys(cpuCounts(serverCpus)).sort();
185
+ return names.length > 0 ? names.join(" + ") : null;
186
+ }
187
+
188
+ /** "amd rome" for one worker, "6 amd rome, 4 intel broadwell" for several. */
189
+ export function describeCpus(serverCpus) {
190
+ const entries = Object.entries(cpuCounts(serverCpus)).sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]));
191
+ if (entries.length === 0) return null;
192
+ const workers = entries.reduce((sum, [, n]) => sum + n, 0);
193
+ return workers === 1 ? entries[0][0] : entries.map(([name, n]) => `${n} ${name}`).join(", ");
194
+ }
195
+
196
+ /**
197
+ * The nights that ran on tonight's kinds of CPU. A night without the probe only
198
+ * matches a night without it, so reports keep their history until the probe
199
+ * starts answering.
200
+ */
201
+ export function sameCpu(nights, serverCpus) {
202
+ const tonight = cpuSignature(serverCpus);
203
+ return nights.filter((night) => cpuSignature(night?.serverCpus) === tonight);
204
+ }
205
+
152
206
  function median(values) {
153
207
  const sorted = [...values].sort((a, b) => a - b);
154
208
  const mid = Math.floor(sorted.length / 2);
@@ -8,6 +8,8 @@ import {
8
8
  MIN_HISTORY_NIGHTS,
9
9
  cellKey,
10
10
  compare,
11
+ cpuSignature,
12
+ describeCpus,
11
13
  flaggedChange,
12
14
  formatDelta,
13
15
  formatMove,
@@ -15,6 +17,7 @@ import {
15
17
  historyCandidates,
16
18
  loadCapacityHistory,
17
19
  loadDailyHistory,
20
+ sameCpu,
18
21
  sparkline,
19
22
  } from "./history.js";
20
23
 
@@ -112,7 +115,7 @@ test("capacity history groups nights by cell and skips crashed cells", () => {
112
115
  const key = cellKey({ deploymentSlug: "d", computeTier: "L", benchmarkType: "wait_write" });
113
116
  assert.deepEqual(history[key].map((n) => n.capacityVUs).sort((a, b) => a - b), [700, 1000]);
114
117
  const serverless = history[cellKey({ deploymentSlug: "s", computeTier: "L", benchmarkType: "wait_write" })];
115
- assert.deepEqual(serverless, [{ executor: "constant-vus", capacityVUs: 0, runsPerSec: 46.3 }], "a cell with no passing step keeps its ceiling, and a night without an executor is closed-model");
118
+ assert.deepEqual(serverless, [{ executor: "constant-vus", serverCpus: null, capacityVUs: 0, runsPerSec: 46.3 }], "a cell with no passing step keeps its ceiling, and a night without an executor is closed-model");
116
119
  });
117
120
 
118
121
  test("capacity history remembers which executor measured each night", () => {
@@ -125,6 +128,45 @@ test("capacity history remembers which executor measured each night", () => {
125
128
  assert.equal(night.executor, "constant-arrival-rate");
126
129
  });
127
130
 
131
+ test("capacity history remembers the CPUs each night ran on", () => {
132
+ const root = mkdtempSync(path.join(tmpdir(), "cap-cpu-"));
133
+ writeFileSync(path.join(runDir(root, 1), "staircase_summary_s.json"), JSON.stringify({
134
+ config: { deploymentSlug: "s", computeTier: "M", benchmarkType: "wait_write" },
135
+ capacity: { targetVUs: 40, successfulRunsPerSec: 39.6 },
136
+ serverCpus: { "GenuineIntel 6/79": 1 },
137
+ }));
138
+ const [night] = loadCapacityHistory(root)[cellKey({ deploymentSlug: "s", computeTier: "M", benchmarkType: "wait_write" })];
139
+ assert.equal(cpuSignature(night.serverCpus), "intel broadwell");
140
+ });
141
+
142
+ test("cpus are named the same inside and outside gVisor, and unknown ones keep their numbers", () => {
143
+ assert.equal(cpuSignature({ "AuthenticAMD 143/49": 1 }), "amd rome", "gVisor's AMD family 143 is Linux's 23");
144
+ assert.equal(cpuSignature({ "AuthenticAMD 23/49": 1 }), "amd rome");
145
+ assert.equal(cpuSignature({ "GenuineIntel 6/79": 1 }), "intel broadwell");
146
+ assert.equal(cpuSignature({ "GenuineIntel 6/207": 1 }), "GenuineIntel 6/207");
147
+ assert.equal(cpuSignature({ "AuthenticAMD 175/17": 1 }), "AuthenticAMD 25/17", "an unnamed AMD still gets the Linux family");
148
+ assert.equal(cpuSignature(null), null);
149
+ assert.equal(cpuSignature({}), null);
150
+ });
151
+
152
+ test("a mix of cpus is one signature, and the description counts the workers", () => {
153
+ const mixed = { "GenuineIntel 6/79": 4, "AuthenticAMD 143/49": 6 };
154
+ assert.equal(cpuSignature(mixed), "amd rome + intel broadwell");
155
+ assert.equal(describeCpus(mixed), "6 amd rome, 4 intel broadwell");
156
+ assert.equal(describeCpus({ "AuthenticAMD 143/49": 1 }), "amd rome", "one worker needs no count");
157
+ assert.equal(describeCpus(null), null);
158
+ });
159
+
160
+ test("only nights on the same cpus compare, and nights before the probe only compare with each other", () => {
161
+ const rome = { serverCpus: { "AuthenticAMD 143/49": 1 }, p95Duration: 4.5 };
162
+ const broadwell = { serverCpus: { "GenuineIntel 6/79": 1 }, p95Duration: 9.8 };
163
+ const before = { p95Duration: 5.1 };
164
+ const nights = [broadwell, rome, before, rome];
165
+ assert.deepEqual(sameCpu(nights, rome.serverCpus), [rome, rome]);
166
+ assert.deepEqual(sameCpu(nights, broadwell.serverCpus), [broadwell]);
167
+ assert.deepEqual(sameCpu(nights, null), [before]);
168
+ });
169
+
128
170
  test("sparkline keeps noise mid-height, draws a real step full height, and leaves gaps for missing nights", () => {
129
171
  assert.equal(sparkline([5, 5.2, 4.9, 5.1, 5]), "▄▅▄▅▄");
130
172
  assert.equal(sparkline([12.8, 12.5, 4.6, 4.8]), "██▁▁");
@@ -2,6 +2,7 @@ import { sleep } from 'k6';
2
2
  import { Counter, Trend } from 'k6/metrics';
3
3
  import { Benchmarks } from './benchmark-runners/dist/benchmarks.js';
4
4
  import { get_profile } from './benchmark-runners/dist/benchmark_profiles.js';
5
+ import { countByCpu, probeServerCpus } from './cpu-probe.js';
5
6
 
6
7
  // Custom metrics
7
8
  const runDuration = new Trend('run_duration');
@@ -199,6 +200,8 @@ export function handleSummary(data) {
199
200
  const successfulRuns = data.metrics.successful_runs?.values?.count || 0;
200
201
  const failedRuns = data.metrics.failed_runs?.values?.count || 0;
201
202
  const totalRuns = successfulRuns + failedRuns;
203
+ const serverCpus = countByCpu(probeServerCpus(BASE_URL, LANGSMITH_API_KEY));
204
+ console.log(`Server CPUs (workers seen): ${JSON.stringify(serverCpus)}`);
202
205
 
203
206
  const summary = {
204
207
  startTimestamp: data.setup_data.startTime,
@@ -218,6 +221,8 @@ export function handleSummary(data) {
218
221
  : null,
219
222
  clientOverheadMs: trendMs(data.metrics.client_overhead),
220
223
  httpReqBlockedP95Ms: data.metrics.http_req_blocked?.values?.["p(95)"] ?? null,
224
+ // In metrics, not beside them, so every report's history carries it without another reader.
225
+ serverCpus,
221
226
  errors: {
222
227
  timeout: data.metrics.timeout_errors ? data.metrics.timeout_errors.values.count : 0,
223
228
  connection: data.metrics.connection_errors ? data.metrics.connection_errors.values.count : 0,