langgraph-api 0.18.0.dev12__tar.gz → 0.18.0.dev13__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 (343) hide show
  1. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/PKG-INFO +2 -2
  2. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/REPORTS.md +8 -5
  3. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/daily-report.js +2 -3
  4. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/delta-report.js +21 -13
  5. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/delta-report.test.js +24 -6
  6. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/history.js +16 -6
  7. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/history.test.js +10 -1
  8. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/constraints.txt +1 -1
  9. langgraph_api-0.18.0.dev13/langgraph_api/__init__.py +1 -0
  10. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/__init__.py +12 -13
  11. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/event_streaming.py +1 -1
  12. langgraph_api-0.18.0.dev13/langgraph_api/api/mcp/_call_thread.py +220 -0
  13. langgraph_api-0.18.0.dev13/langgraph_api/api/mcp/_calls.py +20 -0
  14. langgraph_api-0.18.0.dev13/langgraph_api/api/mcp/_constants.py +25 -0
  15. langgraph_api-0.18.0.dev13/langgraph_api/api/mcp/_digest.py +11 -0
  16. langgraph_api-0.18.0.dev13/langgraph_api/api/mcp/_elicitation.py +371 -0
  17. langgraph_api-0.18.0.dev13/langgraph_api/api/mcp/_forms.py +314 -0
  18. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/mcp/_outcome.py +23 -2
  19. langgraph_api-0.18.0.dev13/langgraph_api/api/mcp/_pauses.py +276 -0
  20. langgraph_api-0.18.0.dev13/langgraph_api/api/mcp/_request_state.py +109 -0
  21. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/mcp/_server.py +3 -3
  22. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/mcp/_tools.py +40 -42
  23. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/runs.py +2 -0
  24. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/config/__init__.py +2 -0
  25. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/config/schemas.py +2 -0
  26. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/route.py +3 -20
  27. langgraph_api-0.18.0.dev13/langgraph_api/sse.py +171 -0
  28. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/validation.py +15 -0
  29. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/pyproject.toml +1 -1
  30. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/uv.lock +1 -1
  31. langgraph_api-0.18.0.dev12/langgraph_api/__init__.py +0 -1
  32. langgraph_api-0.18.0.dev12/langgraph_api/api/mcp/_calls.py +0 -6
  33. langgraph_api-0.18.0.dev12/langgraph_api/api/mcp/_constants.py +0 -11
  34. langgraph_api-0.18.0.dev12/langgraph_api/sse.py +0 -136
  35. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/.gitignore +0 -0
  36. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/LICENSE +0 -0
  37. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/Makefile +0 -0
  38. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/README.md +0 -0
  39. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/.gitignore +0 -0
  40. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/Makefile +0 -0
  41. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/README.md +0 -0
  42. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/assistant.ts +0 -0
  43. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/benchmark-runner.ts +0 -0
  44. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/benchmark_profiles.ts +0 -0
  45. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/benchmarks.ts +0 -0
  46. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/cancel_first_second_completes.ts +0 -0
  47. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/classify-error.test.js +0 -0
  48. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/classify-error.ts +0 -0
  49. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/delta-turns-lib.test.js +0 -0
  50. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/delta-turns-lib.ts +0 -0
  51. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/delta_turns.ts +0 -0
  52. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/enqueued_runs_order.ts +0 -0
  53. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/interrupt_resume.ts +0 -0
  54. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/log-failure.ts +0 -0
  55. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/meta_workload.ts +0 -0
  56. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/store.ts +0 -0
  57. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/stream_write.ts +0 -0
  58. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/thread.ts +0 -0
  59. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/thread_runs_metadata_search.ts +0 -0
  60. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/threads_search_metadata.ts +0 -0
  61. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/types.ts +0 -0
  62. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/benchmark-runners/wait_write.ts +0 -0
  63. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/capacity-ci.js +0 -0
  64. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/capacity-ci.test.js +0 -0
  65. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/clean-cli.js +0 -0
  66. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/clean.js +0 -0
  67. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/continuous/README.md +0 -0
  68. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/continuous/pyproject.toml +0 -0
  69. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/continuous/runner.py +0 -0
  70. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/continuous/uv.lock +0 -0
  71. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/cpu-probe.js +0 -0
  72. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/daily-report.test.js +0 -0
  73. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/graphs.js +0 -0
  74. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/host-v2.js +0 -0
  75. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/host-v2.test.js +0 -0
  76. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/multer.test.js +0 -0
  77. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/package.json +0 -0
  78. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/ramp.js +0 -0
  79. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/reporting/dd_reporting.py +0 -0
  80. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/runner-descriptions.js +0 -0
  81. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/server-metrics.js +0 -0
  82. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/server-metrics.test.js +0 -0
  83. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/slack.js +0 -0
  84. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/staircase.py +0 -0
  85. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/staircase_step_k6.js +0 -0
  86. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/tsconfig.json +0 -0
  87. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/update-revision.js +0 -0
  88. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/weather.js +0 -0
  89. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/benchmark/yarn.lock +0 -0
  90. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/custom_store.sql +0 -0
  91. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/forbidden.txt +0 -0
  92. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/hatch_build.py +0 -0
  93. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/healthcheck.py +0 -0
  94. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph-cloud-debugging-20260210132856.zip +0 -0
  95. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/_checkpointer/__init__.py +0 -0
  96. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/_checkpointer/_adapter.py +0 -0
  97. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/_checkpointer/protocol.py +0 -0
  98. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/_factory_utils.py +0 -0
  99. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/a2a.py +0 -0
  100. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/a2ui.py +0 -0
  101. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/a2ui_schemas/README.md +0 -0
  102. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/a2ui_schemas/client_capabilities.json +0 -0
  103. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/a2ui_schemas/client_data_model.json +0 -0
  104. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/a2ui_schemas/client_to_server.json +0 -0
  105. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/a2ui_schemas/server_to_client.json +0 -0
  106. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/assistants.py +0 -0
  107. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/mcp/__init__.py +0 -0
  108. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/mcp/_origins.py +0 -0
  109. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/mcp/_routes.py +0 -0
  110. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/mcp/_sanitizers.py +0 -0
  111. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/mcp/_sdk.py +0 -0
  112. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/meta.py +0 -0
  113. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/openapi.py +0 -0
  114. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/profile.py +0 -0
  115. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/store.py +0 -0
  116. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/threads.py +0 -0
  117. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/api/ui.py +0 -0
  118. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/asgi_transport.py +0 -0
  119. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/asyncio.py +0 -0
  120. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/auth/__init__.py +0 -0
  121. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/auth/custom.py +0 -0
  122. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/auth/errors.py +0 -0
  123. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/auth/langsmith/__init__.py +0 -0
  124. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/auth/langsmith/backend.py +0 -0
  125. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/auth/langsmith/client.py +0 -0
  126. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/auth/middleware.py +0 -0
  127. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/auth/noop.py +0 -0
  128. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/auth/studio_user.py +0 -0
  129. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/beacon_data_plane_jwt_auth.py +0 -0
  130. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/cache.py +0 -0
  131. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/cli.py +0 -0
  132. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/command.py +0 -0
  133. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/config/_parse.py +0 -0
  134. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/cron_scheduler.py +0 -0
  135. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/drain.py +0 -0
  136. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/encryption/__init__.py +0 -0
  137. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/encryption/aes_json.py +0 -0
  138. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/encryption/context.py +0 -0
  139. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/encryption/custom.py +0 -0
  140. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/encryption/middleware.py +0 -0
  141. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/encryption/shared.py +0 -0
  142. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/errors.py +0 -0
  143. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/event_streaming/__init__.py +0 -0
  144. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/event_streaming/capabilities.py +0 -0
  145. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/event_streaming/constants.py +0 -0
  146. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/event_streaming/event_normalizers.py +0 -0
  147. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/event_streaming/namespace.py +0 -0
  148. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/event_streaming/service.py +0 -0
  149. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/event_streaming/session.py +0 -0
  150. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/event_streaming/state_normalizers.py +0 -0
  151. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/event_streaming/types.py +0 -0
  152. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/executor/__init__.py +0 -0
  153. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/executor/__main__.py +0 -0
  154. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/feature_flags.py +0 -0
  155. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/graph.py +0 -0
  156. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/grpc/__init__.py +0 -0
  157. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/grpc/client.py +0 -0
  158. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/grpc/generated/core_api_pb2.pyi +0 -0
  159. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/grpc/ops/__init__.py +0 -0
  160. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/grpc/ops/assistants.py +0 -0
  161. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/grpc/ops/cache.py +0 -0
  162. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/grpc/ops/crons.py +0 -0
  163. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/grpc/ops/runs.py +0 -0
  164. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/grpc/ops/threads.py +0 -0
  165. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/grpc/server.py +0 -0
  166. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/grpc/servicers/__init__.py +0 -0
  167. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/grpc/servicers/checkpointer.py +0 -0
  168. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/grpc/servicers/encryption.py +0 -0
  169. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/http.py +0 -0
  170. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/http_metrics.py +0 -0
  171. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/http_metrics_utils.py +0 -0
  172. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/.gitignore +0 -0
  173. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/.prettierrc +0 -0
  174. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/.yarnclean +0 -0
  175. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/__init__.py +0 -0
  176. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/base.py +0 -0
  177. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/build.mts +0 -0
  178. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/client.http.mts +0 -0
  179. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/client.mts +0 -0
  180. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/errors.py +0 -0
  181. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/global.d.ts +0 -0
  182. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/package.json +0 -0
  183. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/remote.py +0 -0
  184. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/schema.py +0 -0
  185. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/src/auth-mutations.mts +0 -0
  186. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/src/graph.mts +0 -0
  187. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/src/load.hooks.mjs +0 -0
  188. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/src/preload.mjs +0 -0
  189. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/src/utils/experiment-tracing.mts +0 -0
  190. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/src/utils/files.mts +0 -0
  191. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/src/utils/importMap.mts +0 -0
  192. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
  193. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/src/utils/serde.mts +0 -0
  194. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/sse.py +0 -0
  195. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/traceblock.mts +0 -0
  196. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/tsconfig.json +0 -0
  197. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/ui.py +0 -0
  198. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/js/yarn.lock +0 -0
  199. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/lc_security/__init__.py +0 -0
  200. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/lc_security/exceptions.py +0 -0
  201. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/lc_security/policy.py +0 -0
  202. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/lc_security/transport.py +0 -0
  203. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/logging.py +0 -0
  204. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/metadata.py +0 -0
  205. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/metrics_collector.py +0 -0
  206. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/metrics_otlp.py +0 -0
  207. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/middleware/__init__.py +0 -0
  208. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/middleware/ensure_store.py +0 -0
  209. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/middleware/http_logger.py +0 -0
  210. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/middleware/private_network.py +0 -0
  211. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/middleware/request_id.py +0 -0
  212. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/models/__init__.py +0 -0
  213. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/models/run.py +0 -0
  214. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/operator_routes.py +0 -0
  215. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/otel_context.py +0 -0
  216. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/patch.py +0 -0
  217. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/queue_entrypoint.py +0 -0
  218. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/release_tags.py +0 -0
  219. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/schema.py +0 -0
  220. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/self_hosted_logs.py +0 -0
  221. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/self_hosted_metrics.py +0 -0
  222. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/serde.py +0 -0
  223. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/server.py +0 -0
  224. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/state.py +0 -0
  225. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/store.py +0 -0
  226. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/stream.py +0 -0
  227. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/stream_v2.py +0 -0
  228. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/timing/__init__.py +0 -0
  229. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/timing/profiler.py +0 -0
  230. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/timing/startup.py +0 -0
  231. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/timing/timer.py +0 -0
  232. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/traceblock.py +0 -0
  233. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/tracing_session.py +0 -0
  234. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/tunneling/cloudflare.py +0 -0
  235. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/utils/__init__.py +0 -0
  236. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/utils/cache.py +0 -0
  237. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/utils/config.py +0 -0
  238. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/utils/errors.py +0 -0
  239. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/utils/extract.py +0 -0
  240. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/utils/future.py +0 -0
  241. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/utils/headers.py +0 -0
  242. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/utils/network.py +0 -0
  243. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/utils/retriable_client.py +0 -0
  244. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/utils/stream_codec.py +0 -0
  245. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/utils/uuids.py +0 -0
  246. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/webhook.py +0 -0
  247. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/worker.py +0 -0
  248. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_api/worker_runtime.py +0 -0
  249. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/__init__.py +0 -0
  250. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/checkpointer.py +0 -0
  251. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/conversion/__init__.py +0 -0
  252. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/conversion/_compat.py +0 -0
  253. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/conversion/checkpoint.py +0 -0
  254. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/conversion/config.py +0 -0
  255. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/conversion/durability.py +0 -0
  256. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/conversion/store.py +0 -0
  257. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/conversion/struct.py +0 -0
  258. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/conversion/value.py +0 -0
  259. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/__init__.py +0 -0
  260. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/checkpointer_pb2.py +0 -0
  261. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/checkpointer_pb2.pyi +0 -0
  262. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.py +0 -0
  263. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.pyi +0 -0
  264. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/core_api_pb2.py +0 -0
  265. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/core_api_pb2.pyi +0 -0
  266. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/core_api_pb2_grpc.py +0 -0
  267. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/core_api_pb2_grpc.pyi +0 -0
  268. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/encryption_pb2.py +0 -0
  269. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/encryption_pb2.pyi +0 -0
  270. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/encryption_pb2_grpc.py +0 -0
  271. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/encryption_pb2_grpc.pyi +0 -0
  272. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/engine_common_pb2.py +0 -0
  273. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/engine_common_pb2.pyi +0 -0
  274. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/engine_common_pb2_grpc.py +0 -0
  275. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/engine_common_pb2_grpc.pyi +0 -0
  276. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.py +0 -0
  277. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.pyi +0 -0
  278. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.py +0 -0
  279. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.pyi +0 -0
  280. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_control_signal_pb2.py +0 -0
  281. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_control_signal_pb2.pyi +0 -0
  282. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.py +0 -0
  283. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.pyi +0 -0
  284. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.py +0 -0
  285. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.pyi +0 -0
  286. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.py +0 -0
  287. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.pyi +0 -0
  288. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_durability_pb2.py +0 -0
  289. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_durability_pb2.pyi +0 -0
  290. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.py +0 -0
  291. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.pyi +0 -0
  292. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.py +0 -0
  293. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.pyi +0 -0
  294. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.py +0 -0
  295. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.pyi +0 -0
  296. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_run_status_pb2.py +0 -0
  297. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_run_status_pb2.pyi +0 -0
  298. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.py +0 -0
  299. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.pyi +0 -0
  300. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_stream_mode_pb2.py +0 -0
  301. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_stream_mode_pb2.pyi +0 -0
  302. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.py +0 -0
  303. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.pyi +0 -0
  304. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_thread_status_pb2.py +0 -0
  305. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_thread_status_pb2.pyi +0 -0
  306. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.py +0 -0
  307. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.pyi +0 -0
  308. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.py +0 -0
  309. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.pyi +0 -0
  310. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.py +0 -0
  311. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.pyi +0 -0
  312. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/errors_pb2.py +0 -0
  313. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/errors_pb2.pyi +0 -0
  314. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/errors_pb2_grpc.py +0 -0
  315. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/errors_pb2_grpc.pyi +0 -0
  316. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/orchestrator_pb2.py +0 -0
  317. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/orchestrator_pb2.pyi +0 -0
  318. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/orchestrator_pb2_grpc.py +0 -0
  319. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/orchestrator_pb2_grpc.pyi +0 -0
  320. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/store_pb2.py +0 -0
  321. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/store_pb2.pyi +0 -0
  322. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/store_pb2_grpc.py +0 -0
  323. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/proto/store_pb2_grpc.pyi +0 -0
  324. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/serde.py +0 -0
  325. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_grpc_common/store.py +0 -0
  326. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_license/__init__.py +0 -0
  327. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_license/validation.py +0 -0
  328. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_runtime/__init__.py +0 -0
  329. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_runtime/checkpoint.py +0 -0
  330. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_runtime/database.py +0 -0
  331. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_runtime/encryption.py +0 -0
  332. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_runtime/lifespan.py +0 -0
  333. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_runtime/metrics.py +0 -0
  334. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_runtime/ops.py +0 -0
  335. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_runtime/queue.py +0 -0
  336. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_runtime/retry.py +0 -0
  337. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_runtime/routes.py +0 -0
  338. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/langgraph_runtime/store.py +0 -0
  339. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/logging.json +0 -0
  340. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/openapi.json +0 -0
  341. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/scripts/build_wheel.py +0 -0
  342. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/scripts/create_license.py +0 -0
  343. {langgraph_api-0.18.0.dev12 → langgraph_api-0.18.0.dev13}/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.dev12
3
+ Version: 0.18.0.dev13
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
@@ -13,7 +13,7 @@ Requires-Dist: grpcio-tools==1.81.1
13
13
  Requires-Dist: grpcio<1.82.0,>=1.81.0
14
14
  Requires-Dist: httptools>=0.5.0; platform_system != 'Windows'
15
15
  Requires-Dist: httpx>=0.25.0
16
- Requires-Dist: jsonschema-rs<0.45,>=0.20.0
16
+ Requires-Dist: jsonschema-rs<0.45,>=0.23.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
@@ -17,8 +17,8 @@ in the same channel is separate and not covered here.
17
17
  something to say, worst first.
18
18
  - **Regressed / Improved.** A figure is flagged only when it leaves its own
19
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
20
+ daily and delta reports, the 7 latest on tonight's CPUs for capacity, where
21
+ ▲ 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
@@ -32,7 +32,10 @@ in the same channel is separate and not covered here.
32
32
  line says when a path or tier moved since the night before, and flags only
33
33
  compare nights on the same CPUs, so a night on a slower machine starts its
34
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.
35
+ workers is labeled `mostly amd rome` when at least three in four ran on it,
36
+ and by every CPU it saw otherwise, so a night with one slow worker in ten is
37
+ not compared with a night with nine; the daily and delta threads give the
38
+ counts.
36
39
  Nights from before this check only compare with each other.
37
40
  - **The thread** holds the full numbers: per-run or per-cell detail and
38
41
  improvements with before and after values; the daily threads also give the
@@ -72,8 +75,8 @@ that run's threads, not a growing history.
72
75
  - `p95 s`: 95% of iterations finished within this many seconds tonight. When
73
76
  it left its usual range, the Regressed or Improved line says so, with the
74
77
  before and after.
75
- - `last 10`: p95 over the same 10 nights the flags use, oldest on the left,
76
- tonight on the right. Taller is slower. Each row has its own scale, so a full
78
+ - `last 10`: p95 over tonight and the 9 nights before it on any CPU, oldest on
79
+ the left, tonight on the right; the flags use only the nights on tonight's CPU. Taller is slower. Each row has its own scale, so a full
77
80
  bar means that runner's slowest night of the ten, not a number of seconds:
78
81
  compare a row with itself, not with the row below. The bars never stretch
79
82
  small noise to full height, so a real step stands out.
@@ -235,13 +235,12 @@ function failureReason(run) {
235
235
  return `step finished as \`${run.stepOutcome}\``;
236
236
  }
237
237
 
238
- /** The flag baseline stays at a week; the older nights only draw the trend. */
239
- /** Nights in the table's trend, tonight included. The flags compare against the other nights, so both mean the same window. */
238
+ /** Nights in the table's trend, tonight included. The flags compare with as many past nights, taken from those on tonight's CPU. */
240
239
  export const NIGHTS = 10;
241
240
 
242
241
  const baseline = (run) => (run.history ?? []).slice(0, NIGHTS - 1);
243
242
 
244
- // The trend draws every night; the flags compare only nights on tonight's kinds of CPU.
243
+ // The trend draws every night; the flags compare only nights on tonight's CPU.
245
244
  const comparable = (run) => sameCpu(run.history ?? [], run.summary?.metrics?.serverCpus).slice(0, NIGHTS - 1);
246
245
 
247
246
  const cpuOf = (run) => cpuSignature(run.summary?.metrics?.serverCpus);
@@ -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, describeCpus, flaggedChange, formatMove, sparkline } from './history.js';
13
+ import { MIN_HISTORY_NIGHTS, cpuSignature, describeCpus, flaggedChange, formatMove, sameCpu, 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));
@@ -173,7 +173,16 @@ export async function collectRun(resultsDir) {
173
173
  };
174
174
  }
175
175
 
176
- /** Newest night first. */
176
+ /** What a night saves as `delta_report.json` for the trend and flags of the nights after it. */
177
+ export function nightRecord(run) {
178
+ return {
179
+ design: DESIGN,
180
+ serverCpus: run.summary?.metrics?.serverCpus ?? null,
181
+ cells: Object.fromEntries(run.cells.map((c) => [c.cell, { buckets: c.buckets }])),
182
+ };
183
+ }
184
+
185
+ /** Newest night first, each as `nightRecord` saved it. */
177
186
  export function loadDeltaHistory(dir) {
178
187
  let runs;
179
188
  try {
@@ -194,7 +203,7 @@ export function loadDeltaHistory(dir) {
194
203
  }
195
204
  const file = files.find((name) => path.basename(name) === 'delta_report.json');
196
205
  const report = file ? readSummary(path.join(dir, run, file)) : null;
197
- if (report?.design === DESIGN && report.cells) nights.push(report.cells);
206
+ if (report?.design === DESIGN && report.cells) nights.push(report);
198
207
  }
199
208
  return nights;
200
209
  }
@@ -242,7 +251,7 @@ export function cellChanges(cell, depth, history) {
242
251
  const tonight = cell.buckets?.[depth];
243
252
  const changes = [];
244
253
  for (const [key, label, format, unit] of METRICS) {
245
- const past = history.map((night) => night[cell.cell]?.buckets?.[depth]?.[key]).filter(isNumber);
254
+ const past = history.map((night) => night.cells[cell.cell]?.buckets?.[depth]?.[key]).filter(isNumber);
246
255
  const flagged = flaggedChange(tonight?.[key], past, { higherIsBetter: false });
247
256
  if (!flagged) continue;
248
257
  changes.push({ key, better: flagged.better, text: `${cell.label} ${label} ${formatMove(format(flagged.median), format(tonight[key]), flagged.deltaPct, unit)}` });
@@ -265,7 +274,7 @@ function mainTable(cells, depth, history) {
265
274
  const lines = ['```', `${''.padEnd(6)}${'base'.padStart(5)} delta last ${NIGHTS}`];
266
275
  for (const [key, label, format] of METRICS) {
267
276
  if (key === 'bytes' && !anyBytes(base)) continue;
268
- const past = history.slice(0, NIGHTS - 1).reverse().map((night) => night[delta.cell]?.buckets?.[depth]?.[key]);
277
+ const past = history.slice(0, NIGHTS - 1).reverse().map((night) => night.cells[delta.cell]?.buckets?.[depth]?.[key]);
269
278
  const trend = sparkline([...past, delta.buckets[depth]?.[key]]);
270
279
  lines.push(`${label.padEnd(6)}${format(base.buckets[depth]?.[key]).padStart(5)}${format(delta.buckets[depth]?.[key]).padStart(5)} ${trend}`);
271
280
  }
@@ -305,7 +314,9 @@ export function buildReport(run, context = {}) {
305
314
  const depth = deepestComplete(run.cells, Number(run.load?.loadSize) || null);
306
315
  const target = Number(run.load?.turns) || null;
307
316
  const stoppedAt = target && (!depth || bucketEnd(depth) < target) ? (depth ? bucketEnd(depth) : 0) : null;
308
- const changes = depth ? run.cells.flatMap((cell) => cellChanges(cell, depth, history)) : [];
317
+ // The trend draws every night; the flags compare only nights on tonight's CPU.
318
+ const comparable = sameCpu(history, metrics?.serverCpus).slice(0, NIGHTS - 1);
319
+ const changes = depth ? run.cells.flatMap((cell) => cellChanges(cell, depth, comparable)) : [];
309
320
  const regressed = changes.filter((c) => !c.better);
310
321
  const improved = changes.filter((c) => c.better);
311
322
 
@@ -321,7 +332,8 @@ export function buildReport(run, context = {}) {
321
332
 
322
333
  const dot = dotFor({ failed, attention: guard > 0 || httpCount >= ERROR_ATTENTION || stoppedAt !== null || regressed.length > 0 });
323
334
  const date = now.toLocaleDateString('en-US', { month: 'short', day: 'numeric', timeZone: 'UTC' });
324
- const lines = [`${dot} *Delta Channel · ${date}*${manual ? ' · manual run' : ''}${apiVersion ? ` · API ${apiVersion}` : ''} · ${clauses.join(' · ')}`];
335
+ const cpu = cpuSignature(metrics?.serverCpus);
336
+ const lines = [`${dot} *Delta Channel · ${date}*${manual ? ' · manual run' : ''}${apiVersion ? ` · API ${apiVersion}` : ''}${cpu ? ` · ${cpu}` : ''} · ${clauses.join(' · ')}`];
325
337
  if (failed) lines.push(`*Failed:* ${failureReason(run)}`);
326
338
  if (guard > 0 || httpParts.length > 0) {
327
339
  lines.push(`*Errors:* ${[...httpParts, guard > 0 ? `correctness check failed × ${count(guard)}` : null].filter(Boolean).join(', ')}`);
@@ -335,7 +347,7 @@ export function buildReport(run, context = {}) {
335
347
  if (depth && !anyBytes(run.cells[0])) {
336
348
  lines.push('_No data row: the deployment runs an API without `GET /threads/{id}/storage` yet._');
337
349
  }
338
- if (history.length < MIN_HISTORY_NIGHTS) lines.push(`_${history.length} of ${MIN_HISTORY_NIGHTS} nights of history, no change flags yet_`);
350
+ if (comparable.length < MIN_HISTORY_NIGHTS) lines.push(`_${comparable.length} of ${MIN_HISTORY_NIGHTS} nights of history${cpu ? ' on this cpu' : ''}, no change flags yet_`);
339
351
  lines.push(footer('delta-channel', artifactUrl));
340
352
 
341
353
  return { text: lines.join('\n'), thread: [threadText(run, metrics, guard, improved)] };
@@ -375,11 +387,7 @@ async function main() {
375
387
  const run = await collectRun(process.env.RESULTS_DIR || path.join(HERE, 'results'));
376
388
  const outDir = process.env.OUT_DIR || path.join(HERE, 'delta-report');
377
389
  mkdirSync(outDir, { recursive: true });
378
- // Tonight's aggregate, for the trend and flags of the nights to come.
379
- writeFileSync(
380
- path.join(outDir, 'delta_report.json'),
381
- JSON.stringify({ design: DESIGN, cells: Object.fromEntries(run.cells.map((c) => [c.cell, { buckets: c.buckets }])) }, null, 2)
382
- );
390
+ writeFileSync(path.join(outDir, 'delta_report.json'), JSON.stringify(nightRecord(run), null, 2));
383
391
  const report = safeBuildReport(run, {
384
392
  apiVersion: process.env.API_VERSION || readApiVersion(),
385
393
  artifactUrl: process.env.ARTIFACT_URL,
@@ -3,7 +3,7 @@ import assert from 'node:assert/strict';
3
3
  import { mkdirSync, mkdtempSync, writeFileSync } from 'node:fs';
4
4
  import { tmpdir } from 'node:os';
5
5
  import path from 'node:path';
6
- import { DESIGN, aggregateByCell, aggregateSamples, buildReport, collectRun, gain, growthTables, loadDeltaHistory } from './delta-report.js';
6
+ import { DESIGN, aggregateByCell, aggregateSamples, buildReport, collectRun, gain, growthTables, loadDeltaHistory, nightRecord } from './delta-report.js';
7
7
  import { PHONE_WIDTH, footer, widestCodeLine } from './slack.js';
8
8
 
9
9
  const MB = 1024 * 1024;
@@ -66,11 +66,10 @@ function run({ base = {}, delta = {}, summary, stepOutcome = 'success' } = {}) {
66
66
  };
67
67
  }
68
68
 
69
- const nightFrom = (r) => Object.fromEntries(r.cells.map((c) => [c.cell, { buckets: c.buckets }]));
70
69
  const base = { apiVersion: '0.16.0rc2', now: new Date('2026-09-30T14:00:00Z'), artifactUrl: 'https://github.com/x/y/actions/runs/1' };
71
70
 
72
71
  test('a clean night is the verdict, one table at the last turn, and a footer', () => {
73
- const history = Array.from({ length: 9 }, () => nightFrom(run()));
72
+ const history = Array.from({ length: 9 }, () => nightRecord(run()));
74
73
  const { text } = buildReport(run(), { ...base, history });
75
74
  assert.deepEqual(text.split('\n'), [
76
75
  '🟢 *Delta Channel · Sep 30* · API 0.16.0rc2 · all quiet',
@@ -106,7 +105,7 @@ test('the thread shows each metric as the threads grow, with the gain at every r
106
105
  });
107
106
 
108
107
  test('a delta metric outside its usual range is named above the table once five nights exist', () => {
109
- const history = Array.from({ length: 5 }, () => nightFrom(run()));
108
+ const history = Array.from({ length: 5 }, () => nightRecord(run()));
110
109
  const { text, thread } = buildReport(run({ delta: { read: 130, save: 30 } }), { ...base, history });
111
110
  assert.match(text, /^🟡 .* · 1 regression$/m);
112
111
  assert.match(text, /^⚠️ \*delta read 0\.10 → 0\.13 s \(\+30%\)\*$/m);
@@ -115,12 +114,31 @@ test('a delta metric outside its usual range is named above the table once five
115
114
  });
116
115
 
117
116
  test('fewer than five nights compare nothing, and the post says so', () => {
118
- const history = Array.from({ length: 4 }, () => nightFrom(run()));
117
+ const history = Array.from({ length: 4 }, () => nightRecord(run()));
119
118
  const { text } = buildReport(run({ delta: { read: 500 } }), { ...base, history });
120
119
  assert.doesNotMatch(text, /⚠️/);
121
120
  assert.match(text, /^_4 of 5 nights of history, no change flags yet_$/m);
122
121
  });
123
122
 
123
+ test('a night is compared with the nine latest nights saved on its cpu', () => {
124
+ const rome = { 'AuthenticAMD 143/49': 10 };
125
+ const dir = mkdtempSync(path.join(tmpdir(), 'delta-cpu-'));
126
+ const save = (runId, night) => {
127
+ mkdirSync(path.join(dir, runId), { recursive: true });
128
+ writeFileSync(path.join(dir, runId, 'delta_report.json'), JSON.stringify(nightRecord(night)));
129
+ };
130
+ save('100', run({ delta: { read: 200 }, summary: { serverCpus: rome } }));
131
+ for (let runId = 101; runId <= 109; runId++) save(String(runId), run({ summary: { serverCpus: rome } }));
132
+ const history = loadDeltaHistory(dir);
133
+
134
+ const moved = buildReport(run({ delta: { read: 130 }, summary: { serverCpus: { 'AuthenticAMD 143/49': 2, 'GenuineIntel 6/79': 8 } } }), { ...base, history });
135
+ assert.match(moved.text, /^🟢 \*Delta Channel · Sep 30\* · API 0\.16\.0rc2 · mostly intel broadwell · all quiet$/m, 'against the rome nights this would be +30%');
136
+ assert.match(moved.text, /^_0 of 5 nights of history on this cpu, no change flags yet_$/m);
137
+
138
+ const stayed = buildReport(run({ delta: { read: 130 }, summary: { serverCpus: rome } }), { ...base, history });
139
+ assert.match(stayed.text, /^⚠️ \*delta read 0\.10 → 0\.13 s \(\+30%\)\*$/m, 'the 0.20 s read of the tenth night back is outside the baseline');
140
+ });
141
+
124
142
  test('history keeps only nights measured with this design, newest first', () => {
125
143
  const dir = mkdtempSync(path.join(tmpdir(), 'delta-history-'));
126
144
  const write = (runId, report) => {
@@ -131,7 +149,7 @@ test('history keeps only nights measured with this design, newest first', () =>
131
149
  write('300', { design: DESIGN, cells: { control: { tag: 'newer' } } });
132
150
  write('200', { cells: { control: { tag: 'one job per cell' } } });
133
151
  write('250', { design: 'paired-messages', cells: { control: { tag: 'median write' } } });
134
- assert.deepEqual(loadDeltaHistory(dir).map((night) => night.control.tag), ['newer', 'older']);
152
+ assert.deepEqual(loadDeltaHistory(dir).map((night) => night.cells.control.tag), ['newer', 'older']);
135
153
  });
136
154
 
137
155
  test('without storage readings the data row is left out and the post says why', () => {
@@ -170,31 +170,41 @@ function cpuName(key) {
170
170
  return CPU_NAMES[normalized] ?? normalized;
171
171
  }
172
172
 
173
+ /** `[name, workers]` per kind of CPU, most workers first. */
173
174
  function cpuCounts(serverCpus) {
174
175
  const counts = {};
175
176
  for (const [key, workers] of Object.entries(serverCpus ?? {})) {
176
177
  const name = cpuName(key);
177
178
  counts[name] = (counts[name] ?? 0) + (isNumber(workers) ? workers : 0);
178
179
  }
179
- return counts;
180
+ return Object.entries(counts).sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]));
180
181
  }
181
182
 
182
- /** The kinds of CPU a night ran on, the key the reports compare nights by; null when unknown. */
183
+ /**
184
+ * The key the reports compare nights by, null when unknown: "amd rome" when
185
+ * every worker ran on it, "mostly amd rome" when at least three in four did,
186
+ * every CPU seen otherwise. The share of slow workers moves a night's p95 and
187
+ * capacity, so one slow worker in ten and nine in ten are different machines;
188
+ * the wide middle keeps near-even mixes, the usual case on staging, on one baseline.
189
+ */
183
190
  export function cpuSignature(serverCpus) {
184
- const names = Object.keys(cpuCounts(serverCpus)).sort();
185
- return names.length > 0 ? names.join(" + ") : null;
191
+ const entries = cpuCounts(serverCpus);
192
+ if (entries.length < 2) return entries[0]?.[0] ?? null;
193
+ const workers = entries.reduce((sum, [, n]) => sum + n, 0);
194
+ const [top, most] = entries[0];
195
+ return most * 4 >= workers * 3 ? `mostly ${top}` : entries.map(([name]) => name).sort().join(" + ");
186
196
  }
187
197
 
188
198
  /** "amd rome" for one worker, "6 amd rome, 4 intel broadwell" for several. */
189
199
  export function describeCpus(serverCpus) {
190
- const entries = Object.entries(cpuCounts(serverCpus)).sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]));
200
+ const entries = cpuCounts(serverCpus);
191
201
  if (entries.length === 0) return null;
192
202
  const workers = entries.reduce((sum, [, n]) => sum + n, 0);
193
203
  return workers === 1 ? entries[0][0] : entries.map(([name, n]) => `${n} ${name}`).join(", ");
194
204
  }
195
205
 
196
206
  /**
197
- * The nights that ran on tonight's kinds of CPU. A night without the probe only
207
+ * The nights with tonight's CPU label. A night without the probe only
198
208
  * matches a night without it, so reports keep their history until the probe
199
209
  * starts answering.
200
210
  */
@@ -149,9 +149,11 @@ test("cpus are named the same inside and outside gVisor, and unknown ones keep t
149
149
  assert.equal(cpuSignature({}), null);
150
150
  });
151
151
 
152
- test("a mix of cpus is one signature, and the description counts the workers", () => {
152
+ test("several workers are mostly one cpu when three in four ran on it, and the description counts them", () => {
153
153
  const mixed = { "GenuineIntel 6/79": 4, "AuthenticAMD 143/49": 6 };
154
154
  assert.equal(cpuSignature(mixed), "amd rome + intel broadwell");
155
+ assert.equal(cpuSignature({ "GenuineIntel 6/79": 9, "AuthenticAMD 143/49": 1 }), "mostly intel broadwell");
156
+ assert.equal(cpuSignature({ "GenuineIntel 6/79": 2, "AuthenticAMD 143/49": 6 }), "mostly amd rome", "exactly three in four");
155
157
  assert.equal(describeCpus(mixed), "6 amd rome, 4 intel broadwell");
156
158
  assert.equal(describeCpus({ "AuthenticAMD 143/49": 1 }), "amd rome", "one worker needs no count");
157
159
  assert.equal(describeCpus(null), null);
@@ -165,6 +167,13 @@ test("only nights on the same cpus compare, and nights before the probe only com
165
167
  assert.deepEqual(sameCpu(nights, rome.serverCpus), [rome, rome]);
166
168
  assert.deepEqual(sameCpu(nights, broadwell.serverCpus), [broadwell]);
167
169
  assert.deepEqual(sameCpu(nights, null), [before]);
170
+
171
+ const mostlyRome = { serverCpus: { "AuthenticAMD 143/49": 8, "GenuineIntel 6/79": 2 } };
172
+ const even = { serverCpus: { "AuthenticAMD 143/49": 5, "GenuineIntel 6/79": 5 } };
173
+ const mostlyBroadwell = { serverCpus: { "AuthenticAMD 143/49": 1, "GenuineIntel 6/79": 9 } };
174
+ const split = [mostlyBroadwell, even, mostlyRome, rome];
175
+ assert.deepEqual(sameCpu(split, { "AuthenticAMD 143/49": 9, "GenuineIntel 6/79": 1 }), [mostlyRome], "one slow worker in ten compares with two, not with none, five or nine");
176
+ assert.deepEqual(sameCpu(split, { "AuthenticAMD 143/49": 4, "GenuineIntel 6/79": 6 }), [even], "six in ten compares with five");
168
177
  });
169
178
 
170
179
  test("sparkline keeps noise mid-height, draws a real step full height, and leaves gaps for missing nights", () => {
@@ -13,7 +13,7 @@ uvicorn>=0.29.0
13
13
  sse-starlette>=2.1.3,<4.0.0
14
14
  uvloop>=0.18.0
15
15
  httptools>=0.5.0
16
- jsonschema-rs>=0.20.0
16
+ jsonschema-rs>=0.23.0
17
17
  structlog>=24.1.0
18
18
  cloudpickle>=3.0.0
19
19
  truststore>=0.1
@@ -0,0 +1 @@
1
+ __version__ = "0.18.0.dev13"
@@ -28,10 +28,14 @@ from langgraph_api.api.threads import threads_routes
28
28
  from langgraph_api.api.ui import ui_routes
29
29
  from langgraph_api.auth.middleware import auth_middleware
30
30
  from langgraph_api.config import (
31
+ A2A_ENABLED,
31
32
  FF_PYSPY_PROFILING_ENABLED,
32
33
  HTTP_CONFIG,
33
34
  LANGGRAPH_ENCRYPTION,
35
+ MCP_ENABLED,
34
36
  MIGRATIONS_PATH,
37
+ RUNS_ENABLED,
38
+ THREADS_ENABLED,
35
39
  )
36
40
  from langgraph_api.feature_flags import (
37
41
  FF_V2_EVENT_STREAMING,
@@ -166,9 +170,9 @@ protected_routes: list[BaseRoute] = []
166
170
  if HTTP_CONFIG:
167
171
  if not HTTP_CONFIG.get("disable_assistants"):
168
172
  protected_routes.extend(assistants_routes)
169
- if not HTTP_CONFIG.get("disable_runs"):
173
+ if RUNS_ENABLED:
170
174
  protected_routes.extend(runs_routes)
171
- if not HTTP_CONFIG.get("disable_threads"):
175
+ if THREADS_ENABLED:
172
176
  protected_routes.extend(threads_routes)
173
177
  if not HTTP_CONFIG.get("disable_store"):
174
178
  protected_routes.extend(store_routes)
@@ -176,21 +180,16 @@ if HTTP_CONFIG:
176
180
  protected_routes.extend(profile_routes)
177
181
  if not HTTP_CONFIG.get("disable_ui"):
178
182
  protected_routes.extend(ui_routes)
179
- if not HTTP_CONFIG.get("disable_mcp"):
183
+ if MCP_ENABLED:
180
184
  protected_routes.extend(mcp_routes)
181
- if not HTTP_CONFIG.get("disable_a2a"):
185
+ if A2A_ENABLED:
182
186
  protected_routes.extend(a2a_routes)
183
- # ``disable_runs`` also gates event streaming because the v2 transport
184
- # exposes run-creating commands (``run.start`` / ``run.cancel`` /
185
- # ``run.attach`` over the WS, plus the ``/runs/{run_id}/protocol``
186
- # attach route). If an operator hardens a deployment with
187
- # ``disable_runs=true``, leaving event streaming open would be a
188
- # backdoor that lets clients create runs anyway. ``disable_event_streaming``
189
- # is the narrow knob (turn off just v2); ``disable_runs`` is the broad
190
- # knob (no run-related functionality at all).
187
+ # disable_runs also unmounts event streaming: its WebSocket and the
188
+ # /runs/{run_id}/protocol route can start, cancel and attach runs, so leaving
189
+ # them mounted would let clients create runs on a deployment that disabled runs.
191
190
  if (
192
191
  FF_V2_EVENT_STREAMING
193
- and not HTTP_CONFIG.get("disable_runs")
192
+ and RUNS_ENABLED
194
193
  and not HTTP_CONFIG.get("disable_event_streaming")
195
194
  ):
196
195
  protected_routes.extend(event_streaming_routes)
@@ -330,7 +330,7 @@ async def _thread_events(request: Request) -> Response:
330
330
  finally:
331
331
  await manager.close()
332
332
 
333
- return EventSourceResponse(body_iter())
333
+ return EventSourceResponse(body_iter(), on_close=manager.close)
334
334
 
335
335
 
336
336
  # ---------------------------------------------------------------------------
@@ -0,0 +1,220 @@
1
+ from __future__ import annotations
2
+
3
+ from contextlib import asynccontextmanager, contextmanager
4
+ from dataclasses import dataclass
5
+ from http import HTTPStatus
6
+ from typing import TYPE_CHECKING
7
+
8
+ import httpx
9
+ import jsonschema_rs
10
+ import mcp_types as types
11
+ import structlog
12
+ from mcp.shared.exceptions import MCPError
13
+ from starlette.exceptions import HTTPException
14
+
15
+ from langgraph_api.api.mcp._constants import (
16
+ BREAKPOINT_MESSAGE,
17
+ FINISHED_CALL_TTL_MINUTES,
18
+ PAUSED_CALL_TTL_MINUTES,
19
+ )
20
+ from langgraph_api.api.mcp._outcome import Failed, Paused, RunOutcome, parse_outcome
21
+ from langgraph_api.api.mcp._request_state import Binding, InvalidRequestState
22
+ from langgraph_api.config import THREAD_TTL
23
+ from langgraph_api.models.run import create_valid_run
24
+ from langgraph_api.validation import RunCreateStateful, sanitize_and_validate
25
+ from langgraph_runtime.database import connect
26
+ from langgraph_runtime.retry import retry_db
27
+
28
+ if TYPE_CHECKING:
29
+ from collections.abc import AsyncIterator, Iterator, Mapping
30
+ from uuid import UUID
31
+
32
+ from langgraph_sdk.client import LangGraphClient
33
+ from langgraph_sdk.schema import Thread
34
+ from pydantic import JsonValue
35
+
36
+ from langgraph_api.api.mcp._calls import ToolCallParams
37
+ from langgraph_api.api.mcp._request_state import RequestState
38
+ from langgraph_api.schema import Interrupt
39
+
40
+ logger = structlog.stdlib.get_logger(__name__)
41
+
42
+
43
+ @dataclass(frozen=True, slots=True)
44
+ class CallThread:
45
+ client: LangGraphClient
46
+ headers: Mapping[str, str]
47
+ assistant_id: str
48
+ thread_id: str
49
+
50
+ @classmethod
51
+ async def create(
52
+ cls, client: LangGraphClient, headers: Mapping[str, str], assistant_id: str
53
+ ) -> CallThread:
54
+ thread = await client.threads.create(
55
+ ttl=_within_operator_ttl(PAUSED_CALL_TTL_MINUTES), headers=headers
56
+ )
57
+ return cls(client, headers, assistant_id, thread["thread_id"])
58
+
59
+ async def get(self) -> Thread:
60
+ with _invalid_state_if_missing():
61
+ return await self.client.threads.get(self.thread_id, headers=self.headers)
62
+
63
+ async def pending(self, thread: Thread) -> list[Interrupt]:
64
+ if thread["status"] != "interrupted":
65
+ return []
66
+ with _invalid_state_if_missing():
67
+ state = await self.client.threads.get_state(
68
+ self.thread_id, headers=self.headers
69
+ )
70
+ return [
71
+ interrupt for task in state["tasks"] for interrupt in task["interrupts"]
72
+ ]
73
+
74
+ async def bind(self, binding: Binding, replacing: Binding | None) -> None:
75
+ if binding == replacing:
76
+ return
77
+ if replacing is not None and await self._bound() not in (replacing, binding):
78
+ return
79
+ await self.client.threads.update(
80
+ self.thread_id,
81
+ metadata=binding.metadata,
82
+ ttl=_within_operator_ttl(PAUSED_CALL_TTL_MINUTES),
83
+ headers=self.headers,
84
+ )
85
+
86
+ async def run(self, params: ToolCallParams) -> RunOutcome:
87
+ value = await self.client.runs.wait(
88
+ thread_id=self.thread_id,
89
+ assistant_id=self.assistant_id,
90
+ input=params.input,
91
+ context=params.context,
92
+ durability="exit",
93
+ headers=self.headers,
94
+ raise_error=False,
95
+ )
96
+ return await self._outcome(value)
97
+
98
+ async def resume(
99
+ self,
100
+ value: JsonValue,
101
+ state: RequestState,
102
+ context: Mapping[str, JsonValue] | None,
103
+ ) -> RunOutcome:
104
+ try:
105
+ await self._create_run(self._resume_payload(value, context), state.run_id)
106
+ except HTTPException as error:
107
+ if error.status_code == HTTPStatus.NOT_FOUND:
108
+ raise InvalidRequestState from None
109
+ if error.status_code != HTTPStatus.CONFLICT:
110
+ raise
111
+ return await self.join(state)
112
+ return await self._wait_for(state)
113
+
114
+ async def join(self, state: RequestState) -> RunOutcome:
115
+ if not await self.resumed_with(state):
116
+ raise InvalidRequestState
117
+ return await self._wait_for(state)
118
+
119
+ async def resumed_with(self, state: RequestState) -> bool:
120
+ try:
121
+ await self.client.runs.get(
122
+ self.thread_id, str(state.run_id), headers=self.headers
123
+ )
124
+ except httpx.HTTPStatusError as error:
125
+ if error.response.status_code != HTTPStatus.NOT_FOUND:
126
+ raise
127
+ return False
128
+ return True
129
+
130
+ async def delete(self) -> None:
131
+ async with self._best_effort("Could not delete a finished MCP call's thread"):
132
+ await self.client.threads.delete(self.thread_id, headers=self.headers)
133
+
134
+ async def expire_soon(self) -> None:
135
+ async with self._best_effort("Could not shorten a finished MCP call's TTL"):
136
+ await self.client.threads.update(
137
+ self.thread_id,
138
+ metadata={},
139
+ ttl=_within_operator_ttl(FINISHED_CALL_TTL_MINUTES),
140
+ headers=self.headers,
141
+ )
142
+
143
+ async def _bound(self) -> Binding | None:
144
+ return Binding.stored((await self.get())["metadata"])
145
+
146
+ @asynccontextmanager
147
+ async def _best_effort(self, failure: str) -> AsyncIterator[None]:
148
+ try:
149
+ yield
150
+ except httpx.HTTPStatusError as error:
151
+ if error.response.status_code != HTTPStatus.NOT_FOUND:
152
+ await logger.awarning(
153
+ failure,
154
+ thread_id=self.thread_id,
155
+ status_code=error.response.status_code,
156
+ )
157
+
158
+ @retry_db
159
+ async def _create_run(self, payload: dict[str, JsonValue], run_id: UUID) -> None:
160
+ async with connect() as conn:
161
+ await create_valid_run(
162
+ conn, self.thread_id, payload, self.headers, run_id=run_id
163
+ )
164
+
165
+ async def _wait_for(self, state: RequestState) -> RunOutcome:
166
+ with _invalid_state_if_missing():
167
+ value = await self.client.runs.join(
168
+ self.thread_id, str(state.run_id), headers=self.headers
169
+ )
170
+ return await self._outcome(value)
171
+
172
+ async def _outcome(self, value: JsonValue) -> RunOutcome:
173
+ outcome = parse_outcome(value)
174
+ if isinstance(outcome, Failed):
175
+ return outcome
176
+ thread = await self.get()
177
+ match thread["status"]:
178
+ case "busy":
179
+ raise InvalidRequestState
180
+ case "interrupted":
181
+ return await self._paused_or_stopped(thread)
182
+ case _:
183
+ return outcome
184
+
185
+ async def _paused_or_stopped(self, thread: Thread) -> Paused | Failed:
186
+ if interrupts := await self.pending(thread):
187
+ return Paused(tuple(interrupts))
188
+ return Failed(BREAKPOINT_MESSAGE)
189
+
190
+ def _resume_payload(
191
+ self, value: JsonValue, context: Mapping[str, JsonValue] | None
192
+ ) -> dict[str, JsonValue]:
193
+ payload: dict[str, JsonValue] = {
194
+ "assistant_id": self.assistant_id,
195
+ "command": {"resume": value},
196
+ "multitask_strategy": "reject",
197
+ "durability": "exit",
198
+ }
199
+ if context is not None:
200
+ payload["context"] = dict(context)
201
+ try:
202
+ sanitize_and_validate(payload, RunCreateStateful)
203
+ except jsonschema_rs.ValidationError:
204
+ raise MCPError(types.INVALID_PARAMS, "Invalid tool call context") from None
205
+ return payload
206
+
207
+
208
+ def _within_operator_ttl(minutes: float) -> float:
209
+ operator_ttl = THREAD_TTL.get("default_ttl") if THREAD_TTL else None
210
+ return minutes if operator_ttl is None else min(minutes, operator_ttl)
211
+
212
+
213
+ @contextmanager
214
+ def _invalid_state_if_missing() -> Iterator[None]:
215
+ try:
216
+ yield
217
+ except httpx.HTTPStatusError as error:
218
+ if error.response.status_code != HTTPStatus.NOT_FOUND:
219
+ raise
220
+ raise InvalidRequestState from None
@@ -0,0 +1,20 @@
1
+ import mcp_types as types
2
+ from pydantic import JsonValue
3
+
4
+ from langgraph_api.api.mcp._digest import digest
5
+
6
+
7
+ class ToolCallParams(types.CallToolRequestParams):
8
+ arguments: dict[str, JsonValue] | None = None
9
+ context: dict[str, JsonValue] | None = None
10
+
11
+ @property
12
+ def input(self) -> dict[str, JsonValue]:
13
+ return self.arguments or {}
14
+
15
+ @property
16
+ def answers(self) -> types.InputResponses:
17
+ return self.input_responses or {}
18
+
19
+ def digest(self, assistant_id: str) -> str:
20
+ return digest(assistant_id, self.name, self.input)