langgraph-api 0.9.0.dev6__tar.gz → 0.10.0rc1__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 (287) hide show
  1. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/PKG-INFO +3 -3
  2. langgraph_api-0.10.0rc1/langgraph_api/__init__.py +1 -0
  3. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/auth/custom.py +115 -0
  4. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/event_streaming/service.py +251 -66
  5. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/event_streaming/types.py +6 -0
  6. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/pyproject.toml +2 -2
  7. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/uv.lock +4 -4
  8. langgraph_api-0.9.0.dev6/langgraph_api/__init__.py +0 -1
  9. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/.gitignore +0 -0
  10. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/LICENSE +0 -0
  11. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/Makefile +0 -0
  12. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/README.md +0 -0
  13. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/.gitignore +0 -0
  14. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/Makefile +0 -0
  15. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/README.md +0 -0
  16. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/benchmark-runners/assistant.ts +0 -0
  17. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/benchmark-runners/benchmark-runner.ts +0 -0
  18. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/benchmark-runners/benchmark_profiles.ts +0 -0
  19. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/benchmark-runners/benchmarks.ts +0 -0
  20. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/benchmark-runners/cancel_first_second_completes.ts +0 -0
  21. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/benchmark-runners/enqueued_runs_order.ts +0 -0
  22. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/benchmark-runners/log-failure.ts +0 -0
  23. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/benchmark-runners/meta_workload.ts +0 -0
  24. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/benchmark-runners/stream_write.ts +0 -0
  25. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/benchmark-runners/thread.ts +0 -0
  26. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/benchmark-runners/thread_runs_metadata_search.ts +0 -0
  27. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/benchmark-runners/threads_search_metadata.ts +0 -0
  28. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/benchmark-runners/types.ts +0 -0
  29. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/benchmark-runners/wait_write.ts +0 -0
  30. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/capacity_dd_report.py +0 -0
  31. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/capacity_k6.js +0 -0
  32. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/capacity_runner.mjs +0 -0
  33. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/capacity_slack_report.py +0 -0
  34. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/capacity_urls.mjs +0 -0
  35. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/clean-cli.js +0 -0
  36. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/clean.js +0 -0
  37. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/continuous/README.md +0 -0
  38. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/continuous/pyproject.toml +0 -0
  39. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/continuous/runner.py +0 -0
  40. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/continuous/uv.lock +0 -0
  41. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/graphs.js +0 -0
  42. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/mixed_workload_k6.js +0 -0
  43. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/mixed_workload_runner.mjs +0 -0
  44. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/package.json +0 -0
  45. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/ramp.js +0 -0
  46. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/reporting/dd_reporting.py +0 -0
  47. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/reporting/slack_slowest_runs.py +0 -0
  48. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/reporting/slack_summary.py +0 -0
  49. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/run_local.sh +0 -0
  50. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/staircase.py +0 -0
  51. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/staircase_step_k6.js +0 -0
  52. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/tsconfig.json +0 -0
  53. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/update-revision.js +0 -0
  54. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/benchmark/weather.js +0 -0
  55. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/constraints.txt +0 -0
  56. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/custom_store.sql +0 -0
  57. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/forbidden.txt +0 -0
  58. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/hatch_build.py +0 -0
  59. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/healthcheck.py +0 -0
  60. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph-cloud-debugging-20260210132856.zip +0 -0
  61. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/_checkpointer/__init__.py +0 -0
  62. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/_checkpointer/_adapter.py +0 -0
  63. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/_checkpointer/protocol.py +0 -0
  64. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/_factory_utils.py +0 -0
  65. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/api/__init__.py +0 -0
  66. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/api/a2a.py +0 -0
  67. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/api/assistants.py +0 -0
  68. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/api/event_streaming.py +0 -0
  69. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/api/mcp/__init__.py +0 -0
  70. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/api/mcp/_constants.py +0 -0
  71. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/api/mcp/_handlers.py +0 -0
  72. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/api/mcp/_models.py +0 -0
  73. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/api/mcp/_routes.py +0 -0
  74. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/api/mcp/_sanitizers.py +0 -0
  75. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/api/meta.py +0 -0
  76. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/api/openapi.py +0 -0
  77. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/api/profile.py +0 -0
  78. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/api/runs.py +0 -0
  79. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/api/store.py +0 -0
  80. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/api/threads.py +0 -0
  81. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/api/ui.py +0 -0
  82. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/asgi_transport.py +0 -0
  83. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/asyncio.py +0 -0
  84. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/auth/__init__.py +0 -0
  85. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/auth/errors.py +0 -0
  86. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/auth/langsmith/__init__.py +0 -0
  87. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/auth/langsmith/backend.py +0 -0
  88. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/auth/langsmith/client.py +0 -0
  89. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/auth/middleware.py +0 -0
  90. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/auth/noop.py +0 -0
  91. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/auth/studio_user.py +0 -0
  92. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/cache.py +0 -0
  93. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/cli.py +0 -0
  94. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/command.py +0 -0
  95. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/config/__init__.py +0 -0
  96. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/config/_parse.py +0 -0
  97. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/config/schemas.py +0 -0
  98. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/cron_scheduler.py +0 -0
  99. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/encryption/__init__.py +0 -0
  100. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/encryption/aes_json.py +0 -0
  101. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/encryption/context.py +0 -0
  102. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/encryption/custom.py +0 -0
  103. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/encryption/middleware.py +0 -0
  104. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/encryption/shared.py +0 -0
  105. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/errors.py +0 -0
  106. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/event_streaming/__init__.py +0 -0
  107. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/event_streaming/capabilities.py +0 -0
  108. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/event_streaming/constants.py +0 -0
  109. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/event_streaming/event_normalizers.py +0 -0
  110. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/event_streaming/namespace.py +0 -0
  111. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/event_streaming/session.py +0 -0
  112. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/event_streaming/state_normalizers.py +0 -0
  113. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/feature_flags.py +0 -0
  114. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/graph.py +0 -0
  115. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/grpc/__init__.py +0 -0
  116. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/grpc/client.py +0 -0
  117. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/grpc/generated/core_api_pb2.pyi +0 -0
  118. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/grpc/ops/__init__.py +0 -0
  119. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/grpc/ops/assistants.py +0 -0
  120. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/grpc/ops/cache.py +0 -0
  121. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/grpc/ops/crons.py +0 -0
  122. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/grpc/ops/runs.py +0 -0
  123. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/grpc/ops/threads.py +0 -0
  124. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/grpc/server.py +0 -0
  125. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/grpc/servicers/__init__.py +0 -0
  126. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/grpc/servicers/checkpointer.py +0 -0
  127. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/grpc/servicers/encryption.py +0 -0
  128. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/http.py +0 -0
  129. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/http_metrics.py +0 -0
  130. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/http_metrics_utils.py +0 -0
  131. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/.gitignore +0 -0
  132. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/.prettierrc +0 -0
  133. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/__init__.py +0 -0
  134. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/base.py +0 -0
  135. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/build.mts +0 -0
  136. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/client.http.mts +0 -0
  137. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/client.mts +0 -0
  138. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/errors.py +0 -0
  139. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/global.d.ts +0 -0
  140. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/package.json +0 -0
  141. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/remote.py +0 -0
  142. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/schema.py +0 -0
  143. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/src/graph.mts +0 -0
  144. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/src/load.hooks.mjs +0 -0
  145. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/src/preload.mjs +0 -0
  146. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/src/utils/experiment-tracing.mts +0 -0
  147. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/src/utils/files.mts +0 -0
  148. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/src/utils/importMap.mts +0 -0
  149. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
  150. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/src/utils/serde.mts +0 -0
  151. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/sse.py +0 -0
  152. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/traceblock.mts +0 -0
  153. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/tsconfig.json +0 -0
  154. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/ui.py +0 -0
  155. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/js/yarn.lock +0 -0
  156. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/lc_security/__init__.py +0 -0
  157. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/lc_security/exceptions.py +0 -0
  158. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/lc_security/policy.py +0 -0
  159. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/lc_security/transport.py +0 -0
  160. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/logging.py +0 -0
  161. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/metadata.py +0 -0
  162. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/metrics_datadog.py +0 -0
  163. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/middleware/__init__.py +0 -0
  164. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/middleware/ensure_store.py +0 -0
  165. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/middleware/http_logger.py +0 -0
  166. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/middleware/private_network.py +0 -0
  167. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/middleware/request_id.py +0 -0
  168. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/models/__init__.py +0 -0
  169. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/models/run.py +0 -0
  170. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/otel_context.py +0 -0
  171. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/patch.py +0 -0
  172. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/queue_entrypoint.py +0 -0
  173. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/release_tags.py +0 -0
  174. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/route.py +0 -0
  175. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/schema.py +0 -0
  176. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/self_hosted_logs.py +0 -0
  177. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/self_hosted_metrics.py +0 -0
  178. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/serde.py +0 -0
  179. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/server.py +0 -0
  180. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/sse.py +0 -0
  181. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/state.py +0 -0
  182. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/store.py +0 -0
  183. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/stream.py +0 -0
  184. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/stream_v2.py +0 -0
  185. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/timing/__init__.py +0 -0
  186. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/timing/profiler.py +0 -0
  187. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/timing/timer.py +0 -0
  188. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/traceblock.py +0 -0
  189. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/tunneling/cloudflare.py +0 -0
  190. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/utils/__init__.py +0 -0
  191. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/utils/cache.py +0 -0
  192. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/utils/config.py +0 -0
  193. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/utils/errors.py +0 -0
  194. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/utils/extract.py +0 -0
  195. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/utils/future.py +0 -0
  196. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/utils/headers.py +0 -0
  197. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/utils/network.py +0 -0
  198. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/utils/retriable_client.py +0 -0
  199. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/utils/stream_codec.py +0 -0
  200. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/utils/uuids.py +0 -0
  201. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/validation.py +0 -0
  202. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/webhook.py +0 -0
  203. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_api/worker.py +0 -0
  204. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/__init__.py +0 -0
  205. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/checkpointer.py +0 -0
  206. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/conversion/__init__.py +0 -0
  207. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/conversion/_compat.py +0 -0
  208. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/conversion/checkpoint.py +0 -0
  209. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/conversion/config.py +0 -0
  210. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/conversion/durability.py +0 -0
  211. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/conversion/struct.py +0 -0
  212. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/conversion/value.py +0 -0
  213. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/__init__.py +0 -0
  214. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/checkpointer_pb2.py +0 -0
  215. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/checkpointer_pb2.pyi +0 -0
  216. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.py +0 -0
  217. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.pyi +0 -0
  218. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/core_api_pb2.py +0 -0
  219. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/core_api_pb2.pyi +0 -0
  220. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/core_api_pb2_grpc.py +0 -0
  221. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/core_api_pb2_grpc.pyi +0 -0
  222. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/encryption_pb2.py +0 -0
  223. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/encryption_pb2.pyi +0 -0
  224. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/encryption_pb2_grpc.py +0 -0
  225. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/encryption_pb2_grpc.pyi +0 -0
  226. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/engine_common_pb2.py +0 -0
  227. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/engine_common_pb2.pyi +0 -0
  228. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/engine_common_pb2_grpc.py +0 -0
  229. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/engine_common_pb2_grpc.pyi +0 -0
  230. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.py +0 -0
  231. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.pyi +0 -0
  232. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.py +0 -0
  233. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.pyi +0 -0
  234. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_control_signal_pb2.py +0 -0
  235. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_control_signal_pb2.pyi +0 -0
  236. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.py +0 -0
  237. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.pyi +0 -0
  238. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.py +0 -0
  239. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.pyi +0 -0
  240. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.py +0 -0
  241. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.pyi +0 -0
  242. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_durability_pb2.py +0 -0
  243. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_durability_pb2.pyi +0 -0
  244. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.py +0 -0
  245. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.pyi +0 -0
  246. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.py +0 -0
  247. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.pyi +0 -0
  248. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.py +0 -0
  249. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.pyi +0 -0
  250. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_run_status_pb2.py +0 -0
  251. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_run_status_pb2.pyi +0 -0
  252. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.py +0 -0
  253. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.pyi +0 -0
  254. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_stream_mode_pb2.py +0 -0
  255. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_stream_mode_pb2.pyi +0 -0
  256. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.py +0 -0
  257. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.pyi +0 -0
  258. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_thread_status_pb2.py +0 -0
  259. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_thread_status_pb2.pyi +0 -0
  260. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.py +0 -0
  261. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.pyi +0 -0
  262. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.py +0 -0
  263. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.pyi +0 -0
  264. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.py +0 -0
  265. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.pyi +0 -0
  266. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/errors_pb2.py +0 -0
  267. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/errors_pb2.pyi +0 -0
  268. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/errors_pb2_grpc.py +0 -0
  269. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/proto/errors_pb2_grpc.pyi +0 -0
  270. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_grpc_common/serde.py +0 -0
  271. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_license/__init__.py +0 -0
  272. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_license/validation.py +0 -0
  273. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_runtime/__init__.py +0 -0
  274. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_runtime/checkpoint.py +0 -0
  275. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_runtime/database.py +0 -0
  276. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_runtime/lifespan.py +0 -0
  277. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_runtime/metrics.py +0 -0
  278. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_runtime/ops.py +0 -0
  279. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_runtime/queue.py +0 -0
  280. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_runtime/retry.py +0 -0
  281. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_runtime/routes.py +0 -0
  282. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/langgraph_runtime/store.py +0 -0
  283. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/logging.json +0 -0
  284. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/openapi.json +0 -0
  285. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/scripts/build_wheel.py +0 -0
  286. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/scripts/create_license.py +0 -0
  287. {langgraph_api-0.9.0.dev6 → langgraph_api-0.10.0rc1}/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.9.0.dev6
3
+ Version: 0.10.0rc1
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
@@ -14,9 +14,9 @@ Requires-Dist: httptools>=0.5.0; platform_system != 'Windows'
14
14
  Requires-Dist: httpx>=0.25.0
15
15
  Requires-Dist: jsonschema-rs<0.45,>=0.20.0
16
16
  Requires-Dist: langchain-core>=0.3.64
17
- Requires-Dist: langchain-protocol<0.1,>=0.0.15
17
+ Requires-Dist: langchain-protocol<0.1,>=0.0.16
18
18
  Requires-Dist: langgraph-checkpoint<5,>=3.0.1
19
- Requires-Dist: langgraph-runtime-inmem<0.29.0,>=0.28.0
19
+ Requires-Dist: langgraph-runtime-inmem<0.31.0.dev0,>=0.30.0.dev0
20
20
  Requires-Dist: langgraph-sdk>=0.3.5
21
21
  Requires-Dist: langgraph<2,>=0.4.10
22
22
  Requires-Dist: langsmith[otel]>=0.6.3
@@ -0,0 +1 @@
1
+ __version__ = "0.10.0rc1"
@@ -250,6 +250,12 @@ def _get_custom_auth_middleware(
250
250
  ' return "my-user-id"'
251
251
  )
252
252
 
253
+ # We are wiring custom auth into the server middleware stack — emit the
254
+ # missing-handler warning here (once at startup) rather than inside
255
+ # `_get_auth_instance`, which is also reached from per-request dispatch
256
+ # and from telemetry helpers that have no opinion about coverage.
257
+ _warn_on_missing_handlers(auth_instance)
258
+
253
259
  result = CustomAuthBackend(
254
260
  auth_instance._authenticate_handler,
255
261
  disable_studio_auth,
@@ -276,6 +282,115 @@ def _get_auth_instance(path: str | None = None) -> Auth | Literal["js"] | None:
276
282
  return auth_instance
277
283
 
278
284
 
285
+ def _derive_known_resource_actions(auth: Auth) -> dict[str, frozenset[str]]:
286
+ """Walk an ``Auth.on`` namespace to discover every (resource, action) pair
287
+ the SDK supports for handler registration.
288
+
289
+ The SDK's ``_On`` class declares ``__slots__`` listing top-level resource
290
+ namespaces (``assistants``, ``threads``, ``crons``, ``store``). Inside
291
+ each namespace, the SDK installs one ``_ResourceActionOn`` /
292
+ ``_StoreActionOn`` instance per supported action, each carrying a
293
+ ``.action`` string attribute (and a ``.resource`` for the non-store ones).
294
+ Duck-typing on those attributes avoids a hand-maintained list and keeps
295
+ this in sync as the SDK adds resources/actions.
296
+ """
297
+ on = auth.on
298
+ matrix: dict[str, set[str]] = {}
299
+ for slot in getattr(type(on), "__slots__", ()) or ():
300
+ if slot.startswith("_") or slot == "value":
301
+ continue
302
+ namespace = getattr(on, slot, None)
303
+ if namespace is None:
304
+ continue
305
+ for attr_name in dir(namespace):
306
+ if attr_name.startswith("_"):
307
+ continue
308
+ attr = getattr(namespace, attr_name, None)
309
+ action = getattr(attr, "action", None)
310
+ if not isinstance(action, str):
311
+ continue
312
+ # `_StoreActionOn` doesn't carry `.resource` (it's always
313
+ # "store"); fall back to the outer namespace name.
314
+ resource = getattr(attr, "resource", slot)
315
+ if not isinstance(resource, str):
316
+ continue
317
+ matrix.setdefault(resource, set()).add(action)
318
+ return {resource: frozenset(actions) for resource, actions in matrix.items()}
319
+
320
+
321
+ def _missing_handler_paths(auth: Auth) -> list[tuple[str, str]]:
322
+ """Return ``(resource, action)`` pairs with no matching authorization handler.
323
+
324
+ Mirrors the dispatch precedence in :func:`_get_handler`:
325
+ - specific ``(resource, action)``
326
+ - resource wildcard ``(resource, "*")``
327
+ - action wildcard ``("*", action)``
328
+ - full wildcard ``("*", "*")`` registered via ``auth.on(resources=["*"], actions=["*"])``
329
+ - global ``@auth.on``
330
+
331
+ Either of the last two covers everything, so an empty list is returned
332
+ in those cases. Otherwise the returned list enumerates every
333
+ resource/action pair the server may dispatch which would currently fall
334
+ through to "allow".
335
+ """
336
+ if auth._global_handlers:
337
+ return []
338
+ handlers = auth._handlers
339
+ # `auth.on(resources=["*"], actions=["*"])` stores under ("*", "*") in
340
+ # `_handlers` (not `_global_handlers`) and `_get_handler` matches it as
341
+ # the final fallback before `_global_handlers`. Treat it as full coverage.
342
+ if ("*", "*") in handlers:
343
+ return []
344
+ missing: list[tuple[str, str]] = []
345
+ for resource, actions in _derive_known_resource_actions(auth).items():
346
+ for action in actions:
347
+ if (resource, action) in handlers:
348
+ continue
349
+ if (resource, "*") in handlers:
350
+ continue
351
+ if ("*", action) in handlers:
352
+ continue
353
+ missing.append((resource, action))
354
+ return missing
355
+
356
+
357
+ def _warn_on_missing_handlers(auth: Auth) -> None:
358
+ """Log a warning when the user has registered some auth handlers but
359
+ left other dispatch paths uncovered.
360
+
361
+ Custom auth currently fails open: a request whose ``(resource, action)``
362
+ has no matching handler is allowed without filtering. This is a common
363
+ source of cross-user authorization bugs (see GHSA-38q2-qc5v-fccw and
364
+ related issues), so we surface a warning at startup listing every
365
+ uncovered path and a suggested default-deny snippet.
366
+
367
+ """
368
+ if not auth._handlers and not auth._global_handlers:
369
+ # Auth instance with only an `@auth.authenticate` handler — the user
370
+ # hasn't opted into resource-level authorization at all, so warning
371
+ # about every path would be too noisy. The auth dispatch is a no-op
372
+ # in this case.
373
+ return
374
+ missing = _missing_handler_paths(auth)
375
+ if not missing:
376
+ return
377
+ paths = sorted(f"{resource}.{action}" for resource, action in missing)
378
+ logger.warning(
379
+ "Custom auth has no handler registered for some dispatch paths. "
380
+ "Authentication (@auth.authenticate) still applies, but requests "
381
+ "to these paths will be allowed without resource-level authorization "
382
+ "checks (a common source of cross-user data leaks).",
383
+ missing_paths=paths,
384
+ suggestion=(
385
+ "Add a default-deny global handler and override per-resource "
386
+ "as needed:\n"
387
+ " @auth.on\n"
388
+ " async def deny_all(ctx, value):\n"
389
+ " return False"
390
+ ),
391
+ )
392
+
393
+
279
394
  def _extract_arguments_from_scope(
280
395
  scope: Mapping[str, Any],
281
396
  param_names: set[str],
@@ -22,8 +22,8 @@ import asyncio
22
22
  import contextlib
23
23
  import inspect
24
24
  from collections.abc import Awaitable, Callable
25
- from typing import Any, cast
26
- from uuid import uuid4
25
+ from typing import Any, cast, get_args
26
+ from uuid import UUID, uuid4
27
27
 
28
28
  import orjson
29
29
  import structlog
@@ -43,6 +43,7 @@ from langgraph_api.event_streaming.session import (
43
43
  )
44
44
  from langgraph_api.event_streaming.types import Subscription
45
45
  from langgraph_api.feature_flags import FF_V2_EVENT_STREAMING
46
+ from langgraph_api.schema import MultitaskStrategy
46
47
 
47
48
  logger = structlog.stdlib.get_logger(__name__)
48
49
 
@@ -51,6 +52,75 @@ def _is_record(value: Any) -> bool:
51
52
  return isinstance(value, dict)
52
53
 
53
54
 
55
+ def _checkpoint_id_from_run_start_config(params: dict[str, Any]) -> str | None:
56
+ """Extract ``config.configurable.checkpoint_id`` from ``run.start`` params.
57
+
58
+ Protocol v2 clients pass fork/time-travel targets via RunnableConfig::
59
+
60
+ {
61
+ "input": null,
62
+ "config": { "configurable": { "checkpoint_id": "<uuid>" } },
63
+ }
64
+
65
+ Returns the checkpoint id (validated as a non-empty string) or ``None``
66
+ when no fork target is present.
67
+ """
68
+ config = params.get("config")
69
+ if not _is_record(config):
70
+ return None
71
+ configurable = config.get("configurable")
72
+ if not _is_record(configurable):
73
+ return None
74
+ checkpoint_id = configurable.get("checkpoint_id")
75
+ if checkpoint_id is None:
76
+ return None
77
+ if not isinstance(checkpoint_id, str) or not checkpoint_id.strip():
78
+ raise ValueError(
79
+ "config.configurable.checkpoint_id must be a non-empty string."
80
+ )
81
+ return checkpoint_id
82
+
83
+
84
+ def validate_checkpoint_id_from_runnable_config(params: dict[str, Any]) -> str | None:
85
+ """Return a client-facing validation message, or ``None`` if valid/absent."""
86
+ try:
87
+ checkpoint_id = _checkpoint_id_from_run_start_config(params)
88
+ except ValueError as exc:
89
+ return str(exc)
90
+ if checkpoint_id is None:
91
+ return None
92
+ try:
93
+ UUID(checkpoint_id)
94
+ except ValueError:
95
+ return f"Invalid config.configurable.checkpoint_id: {checkpoint_id!r}."
96
+ return None
97
+
98
+
99
+ # Concurrency strategies accepted on ``run.start`` — the four values the
100
+ # SDK's ``multitaskStrategy`` option can take, derived from the canonical
101
+ # ``MultitaskStrategy`` literal so the two never drift.
102
+ VALID_MULTITASK_STRATEGIES: tuple[str, ...] = get_args(MultitaskStrategy)
103
+ # Legacy stream-endpoint default: queue new runs behind active ones instead
104
+ # of interrupting. Used when the caller omits ``multitaskStrategy``.
105
+ DEFAULT_MULTITASK_STRATEGY = "enqueue"
106
+
107
+
108
+ def _multitask_strategy_from_run_start(params: dict[str, Any]) -> str:
109
+ """Resolve the per-run ``multitaskStrategy`` from ``run.start`` params.
110
+
111
+ The SDK forwards the caller's ``multitaskStrategy`` on every
112
+ ``run.start`` (one of ``reject`` | ``rollback`` | ``interrupt`` |
113
+ ``enqueue``). Honor it when it is one of the recognized strategies,
114
+ otherwise fall back to ``DEFAULT_MULTITASK_STRATEGY`` (the legacy
115
+ stream-endpoint default). This mirrors the JS reference server's
116
+ lenient normalization so both behave identically.
117
+ """
118
+ strategy = params.get("multitaskStrategy")
119
+ if isinstance(strategy, str) and strategy in VALID_MULTITASK_STRATEGIES:
120
+ return strategy
121
+ return DEFAULT_MULTITASK_STRATEGY
122
+
123
+
54
124
  EventSink = Callable[[dict[str, Any]], Awaitable[None] | None]
55
125
 
56
126
 
@@ -401,6 +471,10 @@ class ThreadRunManager:
401
471
  "run.start requires an assistant_id.",
402
472
  )
403
473
 
474
+ checkpoint_error = validate_checkpoint_id_from_runnable_config(params)
475
+ if checkpoint_error is not None:
476
+ return self._error(command.get("id"), "invalid_argument", checkpoint_error)
477
+
404
478
  try:
405
479
  run = await self._create_or_resume_run(assistant_id, params)
406
480
  except ProtocolV2UnsupportedError as exc:
@@ -419,69 +493,150 @@ class ThreadRunManager:
419
493
  "meta": self._meta(),
420
494
  }
421
495
 
422
- async def _handle_input_respond(self, command: dict[str, Any]) -> dict[str, Any]:
423
- params = command.get("params", {}) if _is_record(command.get("params")) else {}
496
+ @staticmethod
497
+ def _coerce_respond_namespace(raw: Any) -> list[str] | None:
498
+ """Validate an ``input.respond`` namespace.
499
+
500
+ CDDL ``InputRespondParams`` marks ``namespace`` as required, but an
501
+ omitted value is treated as the root namespace (``[]``). Returns the
502
+ coerced list, or ``None`` when the value is not a list of strings.
503
+ """
504
+ if not isinstance(raw, list) or not all(isinstance(seg, str) for seg in raw):
505
+ return None
506
+ return list(raw)
507
+
508
+ def _normalize_respond_entries(
509
+ self, cmd_id: int | None, params: dict[str, Any]
510
+ ) -> tuple[list[tuple[str, list[str], Any]] | None, dict[str, Any] | None]:
511
+ """Normalize ``input.respond`` params into resume entries.
512
+
513
+ Clients send either a single ``interrupt_id`` / ``response`` (with an
514
+ optional ``namespace``) or a ``responses`` batch — a list of
515
+ ``{interrupt_id, response, namespace?}`` objects. The batch form
516
+ resumes several interrupts pending at the same checkpoint (e.g.
517
+ parallel tool-authorization prompts) in one command; sequential
518
+ single resumes cannot, since the first resume starts a run, leaving
519
+ the rest with no interrupted run to respond to. Both forms are part
520
+ of the streaming protocol (``InputRespondParams`` =
521
+ ``InputRespondOne / InputRespondMany``); the batch entries are read
522
+ leniently to tolerate clients pinned to older bindings.
523
+
524
+ Returns ``(entries, None)`` on success or ``(None, error)`` with a
525
+ protocol error envelope. Each entry is
526
+ ``(interrupt_id, namespace, response)``.
527
+ """
528
+ raw_responses = params.get("responses")
529
+ if isinstance(raw_responses, list):
530
+ if not raw_responses:
531
+ return None, self._error(
532
+ cmd_id,
533
+ "invalid_argument",
534
+ "input.respond requires at least one response.",
535
+ )
536
+ entries: list[tuple[str, list[str], Any]] = []
537
+ for entry in raw_responses:
538
+ if not _is_record(entry):
539
+ return None, self._error(
540
+ cmd_id,
541
+ "invalid_argument",
542
+ "input.respond responses entries must be objects.",
543
+ )
544
+ entry_id = entry.get("interrupt_id")
545
+ if not isinstance(entry_id, str):
546
+ return None, self._error(
547
+ cmd_id,
548
+ "invalid_argument",
549
+ "input.respond responses entries require an interrupt_id.",
550
+ )
551
+ namespace = self._coerce_respond_namespace(entry.get("namespace", []))
552
+ if namespace is None:
553
+ return None, self._error(
554
+ cmd_id,
555
+ "invalid_argument",
556
+ "input.respond requires namespace to be a list of strings.",
557
+ )
558
+ entries.append((entry_id, namespace, entry.get("response")))
559
+ return entries, None
560
+
424
561
  interrupt_id = params.get("interrupt_id")
425
562
  if not isinstance(interrupt_id, str):
426
- return self._error(
427
- command.get("id"),
563
+ return None, self._error(
564
+ cmd_id,
428
565
  "invalid_argument",
429
566
  "input.respond requires an interrupt_id.",
430
567
  )
431
-
432
- # CDDL InputRespondParams marks ``namespace`` as required. Accept an
433
- # empty list (root) but reject anything that is not a list of strings.
434
- raw_namespace = params.get("namespace", [])
435
- if not isinstance(raw_namespace, list) or not all(
436
- isinstance(seg, str) for seg in raw_namespace
437
- ):
438
- return self._error(
439
- command.get("id"),
568
+ namespace = self._coerce_respond_namespace(params.get("namespace", []))
569
+ if namespace is None:
570
+ return None, self._error(
571
+ cmd_id,
440
572
  "invalid_argument",
441
573
  "input.respond requires namespace to be a list of strings.",
442
574
  )
443
- claimed_namespace: list[str] = list(raw_namespace)
444
-
445
- # Cross-check against the session's pending interrupts so we can
446
- # return ``no_such_interrupt`` for unknown/mismatched pairs.
447
- # When the session was attached fresh by this HTTP request (the
448
- # stateless ``POST /commands`` transport) its source task hasn't
449
- # had a chance to emit ``input.requested`` yet — ``_pending_interrupts``
450
- # is still empty. In that case, fall back to the thread-state
451
- # check so we don't reject legitimate resumes with a fresh
452
- # handle. The WebSocket path (long-lived session) hits the
453
- # in-memory check and skips the DB round-trip.
454
- pending_namespace = (
455
- self._session.lookup_pending_interrupt(interrupt_id)
456
- if self._session is not None
457
- else None
575
+ return [(interrupt_id, namespace, params.get("response"))], None
576
+
577
+ async def _handle_input_respond(self, command: dict[str, Any]) -> dict[str, Any]:
578
+ params = command.get("params", {}) if _is_record(command.get("params")) else {}
579
+
580
+ entries, normalize_error = self._normalize_respond_entries(
581
+ command.get("id"), params
458
582
  )
459
- if pending_namespace is not None:
460
- # Authoritative: the session observed the ``input.requested``
461
- # event and recorded the exact subgraph namespace. Enforce
462
- # strict comparison.
463
- if pending_namespace != claimed_namespace:
464
- return self._error(
465
- command.get("id"),
466
- "no_such_interrupt",
467
- "Interrupt namespace does not match the pending interrupt.",
468
- )
469
- else:
470
- # HTTP fallback: ``_lookup_interrupt_in_thread_state`` only
471
- # walks root tasks and returns ``[]`` for any match, so it
583
+ if normalize_error is not None:
584
+ return normalize_error
585
+ if entries is None: # narrowed by the error branch above
586
+ return self._error(
587
+ command.get("id"), "unknown_error", "No entries to respond to."
588
+ )
589
+
590
+ # Cross-check every targeted interrupt against the session's pending
591
+ # interrupts so we can return ``no_such_interrupt`` for
592
+ # unknown/mismatched pairs. When the session was attached fresh by
593
+ # this HTTP request (the stateless ``POST /commands`` transport) its
594
+ # source task hasn't had a chance to emit ``input.requested`` yet —
595
+ # ``_pending_interrupts`` is still empty. In that case, fall back to
596
+ # the thread-state check so we don't reject legitimate resumes with a
597
+ # fresh handle. The WebSocket path (long-lived session) hits the
598
+ # in-memory check and skips the DB round-trip.
599
+ #
600
+ # The thread-state fallback is fetched at most once per batch and
601
+ # cached in ``thread_state_ids``: a batch of N entries that all miss
602
+ # the session would otherwise issue N identical ``State.get`` calls.
603
+ thread_state_ids: set[str] | None = None
604
+ thread_state_fetched = False
605
+ for interrupt_id, claimed_namespace, _ in entries:
606
+ pending_namespace = (
607
+ self._session.lookup_pending_interrupt(interrupt_id)
608
+ if self._session is not None
609
+ else None
610
+ )
611
+ if pending_namespace is not None:
612
+ # Authoritative: the session observed the ``input.requested``
613
+ # event and recorded the exact subgraph namespace. Enforce
614
+ # strict comparison.
615
+ if pending_namespace != claimed_namespace:
616
+ return self._error(
617
+ command.get("id"),
618
+ "no_such_interrupt",
619
+ "Interrupt namespace does not match the pending interrupt.",
620
+ )
621
+ continue
622
+ # HTTP fallback: the bulk thread-state lookup only walks root
623
+ # tasks and surfaces interrupts by id (not namespace), so it
472
624
  # cannot validate subgraph namespaces. Verify the interrupt
473
625
  # exists on persisted state and trust the client-claimed
474
- # namespace — the interrupt_id is a UUID, so the existence
475
- # check alone is sufficient. (Without this, every HTTP
476
- # ``input.respond`` for a subgraph interrupt would 404.)
477
- if await self._lookup_interrupt_in_thread_state(interrupt_id) is None:
626
+ # namespace — the interrupt_id is a UUID, so the existence check
627
+ # alone is sufficient. (Without this, every HTTP ``input.respond``
628
+ # for a subgraph interrupt would 404.)
629
+ if not thread_state_fetched:
630
+ thread_state_ids = await self._collect_thread_state_interrupt_ids()
631
+ thread_state_fetched = True
632
+ if thread_state_ids is None or interrupt_id not in thread_state_ids:
478
633
  return self._error(
479
634
  command.get("id"),
480
635
  "no_such_interrupt",
481
636
  f"Unknown or already-consumed interrupt: {interrupt_id}",
482
637
  )
483
638
 
484
- # At this point we've confirmed the interrupt exists on the
639
+ # At this point we've confirmed every interrupt exists on the
485
640
  # thread state (or was surfaced via the session). No need for a
486
641
  # second ``_has_pending_interrupts`` round-trip.
487
642
 
@@ -496,12 +651,17 @@ class ThreadRunManager:
496
651
  "No interrupted run is bound to this thread.",
497
652
  )
498
653
 
654
+ # Merge every entry into a single ``{interrupt_id: response}`` resume
655
+ # map. ``_create_or_resume_run`` forwards it verbatim as
656
+ # ``Command(resume=...)``, which resumes all targeted interrupts in
657
+ # one run.
658
+ resume_input = {interrupt_id: response for interrupt_id, _, response in entries}
499
659
  try:
500
660
  await self._create_or_resume_run(
501
661
  assistant_id,
502
662
  {
503
663
  "assistant_id": assistant_id,
504
- "input": {interrupt_id: params.get("response")},
664
+ "input": resume_input,
505
665
  "config": params.get("config"),
506
666
  "metadata": params.get("metadata"),
507
667
  },
@@ -512,7 +672,8 @@ class ThreadRunManager:
512
672
  return self._error(command.get("id"), "unknown_error", str(exc))
513
673
 
514
674
  if self._session is not None:
515
- self._session.clear_pending_interrupt(interrupt_id)
675
+ for interrupt_id, _, _ in entries:
676
+ self._session.clear_pending_interrupt(interrupt_id)
516
677
 
517
678
  return {
518
679
  "type": "success",
@@ -575,13 +736,26 @@ class ThreadRunManager:
575
736
  },
576
737
  }
577
738
 
739
+ # The fork target arrives only via ``config.configurable.checkpoint_id``
740
+ # (the SDK folds its ergonomic ``forkFrom`` option into this field
741
+ # client-side, so there is a single way to provide it). Extract it
742
+ # here and map it onto the top-level ``checkpoint_id`` / ``checkpoint``
743
+ # fields of ``run_payload`` below: ``create_valid_run`` — the shared
744
+ # run-creation path also used by the legacy REST run-create endpoints —
745
+ # reads the fork target from those fields (UUID-validating it and
746
+ # injecting it back into ``config.configurable``), so populating them is
747
+ # what makes the run replay from the requested checkpoint rather than
748
+ # the thread's latest state.
749
+ checkpoint_id = _checkpoint_id_from_run_start_config(params)
750
+
578
751
  run_payload: dict[str, Any] = {
579
752
  "assistant_id": assistant_id,
580
753
  "input": None if is_resume else params.get("input"),
581
754
  "command": {"resume": params["input"]} if is_resume else None,
582
755
  "config": run_config,
583
756
  "metadata": params.get("metadata"),
584
- "checkpoint_id": None,
757
+ "checkpoint_id": checkpoint_id,
758
+ "checkpoint": {"checkpoint_id": checkpoint_id} if checkpoint_id else None,
585
759
  "context": None,
586
760
  "webhook": None,
587
761
  "stream_mode": list(DEFAULT_RUN_STREAM_MODES),
@@ -596,11 +770,10 @@ class ThreadRunManager:
596
770
  # chokes on None. Zero means "start immediately".
597
771
  "after_seconds": 0,
598
772
  "if_not_exists": "create",
599
- # Match legacy stream endpoint default: queue new runs behind active
600
- # ones instead of interrupting. The protocol spec describes this
601
- # case as "inject into running graph", which Python LangGraph does
602
- # not yet support; enqueue is the least surprising approximation.
603
- "multitask_strategy": "enqueue",
773
+ # Honor the caller's ``multitaskStrategy`` (the SDK sends it on
774
+ # every run.start), falling back to ``enqueue`` the legacy
775
+ # stream-endpoint default when omitted.
776
+ "multitask_strategy": _multitask_strategy_from_run_start(params),
604
777
  "langsmith_tracer": None,
605
778
  "durability": None,
606
779
  }
@@ -862,6 +1035,24 @@ class ThreadRunManager:
862
1035
  treat ``[]`` as "interrupt found, namespace unknown" and trust
863
1036
  the client-claimed namespace.
864
1037
  """
1038
+ found = await self._collect_thread_state_interrupt_ids()
1039
+ if found is None:
1040
+ return None
1041
+ return [] if interrupt_id in found else None
1042
+
1043
+ async def _collect_thread_state_interrupt_ids(self) -> set[str] | None:
1044
+ """Fetch persisted thread state once and collect all interrupt ids.
1045
+
1046
+ Bulk counterpart to ``_lookup_interrupt_in_thread_state`` for the
1047
+ ``input.respond`` batch path: a single ``State.get`` round-trip is
1048
+ shared across every entry in the batch instead of one DB call per
1049
+ interrupt. Returns the set of interrupt ids present on the thread's
1050
+ root tasks, or ``None`` if the state fetch failed (callers treat a
1051
+ ``None`` result as "lookup unavailable", not "no interrupts").
1052
+
1053
+ Like the single lookup, this only walks root-level tasks — subgraph
1054
+ interrupts surface by id but not by namespace.
1055
+ """
865
1056
  from langgraph_runtime.database import connect # noqa: PLC0415
866
1057
 
867
1058
  # ``supports_core_api=False`` so the postgres backend yields a
@@ -879,7 +1070,6 @@ class ThreadRunManager:
879
1070
  logger.warning(
880
1071
  "interrupt_lookup_failed",
881
1072
  thread_id=self._thread_id,
882
- interrupt_id=interrupt_id,
883
1073
  error=str(exc),
884
1074
  error_type=type(exc).__name__,
885
1075
  )
@@ -888,6 +1078,7 @@ class ThreadRunManager:
888
1078
  tasks = (
889
1079
  state.get("tasks") if _is_record(state) else getattr(state, "tasks", None)
890
1080
  ) or ()
1081
+ found: set[str] = set()
891
1082
  for task in tasks:
892
1083
  interrupts = (
893
1084
  task.get("interrupts")
@@ -900,15 +1091,9 @@ class ThreadRunManager:
900
1091
  entry_id = (
901
1092
  entry.get("id") if _is_record(entry) else getattr(entry, "id", None)
902
1093
  )
903
- if entry_id == interrupt_id:
904
- # Existence-only signal. We can't reliably derive
905
- # the subgraph namespace from this state shape
906
- # (subgraph tasks aren't always materialized in
907
- # ``state.tasks``), so we return ``[]`` as an
908
- # "interrupt found" sentinel. The caller knows not
909
- # to use this for namespace comparison.
910
- return []
911
- return None
1094
+ if isinstance(entry_id, str):
1095
+ found.add(entry_id)
1096
+ return found
912
1097
 
913
1098
  async def _has_pending_interrupts(self) -> bool:
914
1099
  # Prefer the session's locally-tracked pending interrupts when
@@ -28,6 +28,9 @@ from langchain_protocol import (
28
28
  FinalizedContentBlock,
29
29
  ImageContentBlock,
30
30
  InputRequestedData,
31
+ InputRespondEntry,
32
+ InputRespondMany,
33
+ InputRespondOne,
31
34
  InputRespondParams,
32
35
  LifecycleCause,
33
36
  LifecycleCauseEdge,
@@ -90,6 +93,9 @@ __all__ = [
90
93
  "FinalizedContentBlock",
91
94
  "ImageContentBlock",
92
95
  "InputRequestedData",
96
+ "InputRespondEntry",
97
+ "InputRespondMany",
98
+ "InputRespondOne",
93
99
  "InputRespondParams",
94
100
  "LifecycleCause",
95
101
  "LifecycleCauseEdge",
@@ -39,7 +39,7 @@ dependencies = [
39
39
  "cryptography>=42.0.0",
40
40
  "langgraph-sdk>=0.3.5",
41
41
  "cloudpickle>=3.0.0",
42
- "langgraph-runtime-inmem>=0.28.0,<0.29.0",
42
+ "langgraph-runtime-inmem>=0.30.0.dev0,<0.31.0.dev0",
43
43
  "truststore>=0.1",
44
44
  "protobuf>=6.32.1,<7.0.0",
45
45
  "grpcio>=1.80.0,<1.81.0",
@@ -50,7 +50,7 @@ dependencies = [
50
50
  "opentelemetry-exporter-otlp-proto-http>=0.0.1",
51
51
  "uuid-utils>=0.12.0",
52
52
  "zstandard>=0.23.0",
53
- "langchain-protocol>=0.0.15,<0.1",
53
+ "langchain-protocol>=0.0.16,<0.1",
54
54
  ]
55
55
 
56
56
  [project.scripts]
@@ -684,14 +684,14 @@ wheels = [
684
684
 
685
685
  [[package]]
686
686
  name = "langchain-protocol"
687
- version = "0.0.15"
687
+ version = "0.0.16"
688
688
  source = { registry = "https://pypi.org/simple" }
689
689
  dependencies = [
690
690
  { name = "typing-extensions" },
691
691
  ]
692
- sdist = { url = "https://files.pythonhosted.org/packages/4f/24/9777489d6fbbee64af0c8f96d4f840239c408cf694f3394672807dafc490/langchain_protocol-0.0.15.tar.gz", hash = "sha256:9ab2d11ee73944754f10e037e717098d3a6796f0e58afa9cadda6154e7655ade", size = 5862, upload-time = "2026-05-01T22:30:04.748Z" }
692
+ sdist = { url = "https://files.pythonhosted.org/packages/36/e7/8300ba22d968653051fd06e3117d783872dddf3dcebdd6b1d386836eb43c/langchain_protocol-0.0.16.tar.gz", hash = "sha256:806c7cdd951b1c4f692fa40fce60821ff0f221d4360e27673ddf2c2b99c2b7ff", size = 5969, upload-time = "2026-05-28T23:05:11.121Z" }
693
693
  wheels = [
694
- { url = "https://files.pythonhosted.org/packages/1d/7a/9c97a7b9cbe4c5dc6a44cdb1545450c28f0c8ce89b9c1f0ee7fbad896263/langchain_protocol-0.0.15-py3-none-any.whl", hash = "sha256:461eb794358f83d5e42635a5797799ffec7b4702314e34edf73ac21e75d3ef79", size = 6982, upload-time = "2026-05-01T22:30:03.877Z" },
694
+ { url = "https://files.pythonhosted.org/packages/1f/9c/06dfcc88d02a6364e8d864c421ddd3736305cb0a6c853f75c302c80fe17c/langchain_protocol-0.0.16-py3-none-any.whl", hash = "sha256:3658c142c5d0fb3a023a4be442ce4c15c6d626aab6135eb79a76dc64ad19c3c3", size = 7037, upload-time = "2026-05-28T23:05:10.163Z" },
695
695
  ]
696
696
 
697
697
  [[package]]
@@ -785,7 +785,7 @@ requires-dist = [
785
785
  { name = "httpx", specifier = ">=0.25.0" },
786
786
  { name = "jsonschema-rs", specifier = ">=0.20.0,<0.45" },
787
787
  { name = "langchain-core", specifier = ">=0.3.64" },
788
- { name = "langchain-protocol", specifier = ">=0.0.15,<0.1" },
788
+ { name = "langchain-protocol", specifier = ">=0.0.16,<0.1" },
789
789
  { name = "langgraph", specifier = ">=0.4.10,<2" },
790
790
  { name = "langgraph-checkpoint", specifier = ">=3.0.1,<5" },
791
791
  { name = "langgraph-runtime-inmem", editable = "../runtime_inmem" },
@@ -1 +0,0 @@
1
- __version__ = "0.9.0.dev6"