langgraph-api 0.12.0.dev9__tar.gz → 0.12.0.dev11__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (289) hide show
  1. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/Makefile +1 -1
  2. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/PKG-INFO +2 -2
  3. langgraph_api-0.12.0.dev11/langgraph_api/__init__.py +1 -0
  4. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/_checkpointer/_adapter.py +26 -1
  5. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/event_streaming/service.py +49 -8
  6. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/event_streaming/state_normalizers.py +8 -0
  7. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/feature_flags.py +10 -0
  8. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/servicers/checkpointer.py +14 -0
  9. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/checkpointer.py +115 -21
  10. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/conversion/checkpoint.py +95 -6
  11. langgraph_api-0.12.0.dev11/langgraph_grpc_common/conversion/struct.py +60 -0
  12. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/conversion/value.py +11 -1
  13. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/checkpointer_pb2.py +13 -3
  14. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/checkpointer_pb2.pyi +113 -0
  15. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.py +47 -0
  16. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.pyi +24 -0
  17. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/serde.py +36 -4
  18. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/pyproject.toml +1 -1
  19. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/uv.lock +53 -67
  20. langgraph_api-0.12.0.dev9/langgraph_api/__init__.py +0 -1
  21. langgraph_api-0.12.0.dev9/langgraph_grpc_common/conversion/struct.py +0 -27
  22. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/.gitignore +0 -0
  23. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/LICENSE +0 -0
  24. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/README.md +0 -0
  25. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/.gitignore +0 -0
  26. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/Makefile +0 -0
  27. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/README.md +0 -0
  28. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/assistant.ts +0 -0
  29. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/benchmark-runner.ts +0 -0
  30. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/benchmark_profiles.ts +0 -0
  31. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/benchmarks.ts +0 -0
  32. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/cancel_first_second_completes.ts +0 -0
  33. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/enqueued_runs_order.ts +0 -0
  34. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/log-failure.ts +0 -0
  35. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/meta_workload.ts +0 -0
  36. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/stream_write.ts +0 -0
  37. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/thread.ts +0 -0
  38. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/thread_runs_metadata_search.ts +0 -0
  39. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/threads_search_metadata.ts +0 -0
  40. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/types.ts +0 -0
  41. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/benchmark-runners/wait_write.ts +0 -0
  42. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/capacity_dd_report.py +0 -0
  43. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/capacity_k6.js +0 -0
  44. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/capacity_runner.mjs +0 -0
  45. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/capacity_slack_report.py +0 -0
  46. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/capacity_urls.mjs +0 -0
  47. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/clean-cli.js +0 -0
  48. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/clean.js +0 -0
  49. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/continuous/README.md +0 -0
  50. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/continuous/pyproject.toml +0 -0
  51. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/continuous/runner.py +0 -0
  52. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/continuous/uv.lock +0 -0
  53. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/graphs.js +0 -0
  54. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/mixed_workload_k6.js +0 -0
  55. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/mixed_workload_runner.mjs +0 -0
  56. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/package.json +0 -0
  57. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/ramp.js +0 -0
  58. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/reporting/dd_reporting.py +0 -0
  59. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/reporting/slack_slowest_runs.py +0 -0
  60. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/reporting/slack_summary.py +0 -0
  61. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/run_local.sh +0 -0
  62. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/staircase.py +0 -0
  63. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/staircase_step_k6.js +0 -0
  64. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/tsconfig.json +0 -0
  65. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/update-revision.js +0 -0
  66. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/benchmark/weather.js +0 -0
  67. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/constraints.txt +0 -0
  68. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/custom_store.sql +0 -0
  69. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/forbidden.txt +0 -0
  70. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/hatch_build.py +0 -0
  71. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/healthcheck.py +0 -0
  72. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph-cloud-debugging-20260210132856.zip +0 -0
  73. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/_checkpointer/__init__.py +0 -0
  74. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/_checkpointer/protocol.py +0 -0
  75. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/_factory_utils.py +0 -0
  76. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/__init__.py +0 -0
  77. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/a2a.py +0 -0
  78. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/assistants.py +0 -0
  79. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/event_streaming.py +0 -0
  80. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/mcp/__init__.py +0 -0
  81. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/mcp/_constants.py +0 -0
  82. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/mcp/_handlers.py +0 -0
  83. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/mcp/_models.py +0 -0
  84. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/mcp/_routes.py +0 -0
  85. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/mcp/_sanitizers.py +0 -0
  86. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/meta.py +0 -0
  87. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/openapi.py +0 -0
  88. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/profile.py +0 -0
  89. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/runs.py +0 -0
  90. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/store.py +0 -0
  91. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/threads.py +0 -0
  92. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/api/ui.py +0 -0
  93. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/asgi_transport.py +0 -0
  94. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/asyncio.py +0 -0
  95. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/auth/__init__.py +0 -0
  96. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/auth/custom.py +0 -0
  97. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/auth/errors.py +0 -0
  98. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/auth/langsmith/__init__.py +0 -0
  99. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/auth/langsmith/backend.py +0 -0
  100. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/auth/langsmith/client.py +0 -0
  101. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/auth/middleware.py +0 -0
  102. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/auth/noop.py +0 -0
  103. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/auth/studio_user.py +0 -0
  104. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/cache.py +0 -0
  105. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/cli.py +0 -0
  106. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/command.py +0 -0
  107. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/config/__init__.py +0 -0
  108. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/config/_parse.py +0 -0
  109. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/config/schemas.py +0 -0
  110. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/cron_scheduler.py +0 -0
  111. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/encryption/__init__.py +0 -0
  112. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/encryption/aes_json.py +0 -0
  113. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/encryption/context.py +0 -0
  114. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/encryption/custom.py +0 -0
  115. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/encryption/middleware.py +0 -0
  116. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/encryption/shared.py +0 -0
  117. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/errors.py +0 -0
  118. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/event_streaming/__init__.py +0 -0
  119. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/event_streaming/capabilities.py +0 -0
  120. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/event_streaming/constants.py +0 -0
  121. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/event_streaming/event_normalizers.py +0 -0
  122. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/event_streaming/namespace.py +0 -0
  123. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/event_streaming/session.py +0 -0
  124. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/event_streaming/types.py +0 -0
  125. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/graph.py +0 -0
  126. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/__init__.py +0 -0
  127. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/client.py +0 -0
  128. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/generated/core_api_pb2.pyi +0 -0
  129. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/ops/__init__.py +0 -0
  130. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/ops/assistants.py +0 -0
  131. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/ops/cache.py +0 -0
  132. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/ops/crons.py +0 -0
  133. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/ops/runs.py +0 -0
  134. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/ops/threads.py +0 -0
  135. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/server.py +0 -0
  136. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/servicers/__init__.py +0 -0
  137. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/grpc/servicers/encryption.py +0 -0
  138. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/http.py +0 -0
  139. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/http_metrics.py +0 -0
  140. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/http_metrics_utils.py +0 -0
  141. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/.gitignore +0 -0
  142. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/.prettierrc +0 -0
  143. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/__init__.py +0 -0
  144. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/base.py +0 -0
  145. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/build.mts +0 -0
  146. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/client.http.mts +0 -0
  147. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/client.mts +0 -0
  148. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/errors.py +0 -0
  149. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/global.d.ts +0 -0
  150. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/package.json +0 -0
  151. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/remote.py +0 -0
  152. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/schema.py +0 -0
  153. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/src/graph.mts +0 -0
  154. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/src/load.hooks.mjs +0 -0
  155. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/src/preload.mjs +0 -0
  156. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/src/utils/experiment-tracing.mts +0 -0
  157. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/src/utils/files.mts +0 -0
  158. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/src/utils/importMap.mts +0 -0
  159. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
  160. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/src/utils/serde.mts +0 -0
  161. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/sse.py +0 -0
  162. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/traceblock.mts +0 -0
  163. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/tsconfig.json +0 -0
  164. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/ui.py +0 -0
  165. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/js/yarn.lock +0 -0
  166. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/lc_security/__init__.py +0 -0
  167. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/lc_security/exceptions.py +0 -0
  168. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/lc_security/policy.py +0 -0
  169. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/lc_security/transport.py +0 -0
  170. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/logging.py +0 -0
  171. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/metadata.py +0 -0
  172. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/metrics_collector.py +0 -0
  173. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/metrics_otlp.py +0 -0
  174. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/middleware/__init__.py +0 -0
  175. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/middleware/ensure_store.py +0 -0
  176. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/middleware/http_logger.py +0 -0
  177. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/middleware/private_network.py +0 -0
  178. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/middleware/request_id.py +0 -0
  179. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/models/__init__.py +0 -0
  180. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/models/run.py +0 -0
  181. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/otel_context.py +0 -0
  182. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/patch.py +0 -0
  183. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/queue_entrypoint.py +0 -0
  184. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/release_tags.py +0 -0
  185. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/route.py +0 -0
  186. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/schema.py +0 -0
  187. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/self_hosted_logs.py +0 -0
  188. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/self_hosted_metrics.py +0 -0
  189. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/serde.py +0 -0
  190. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/server.py +0 -0
  191. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/sse.py +0 -0
  192. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/state.py +0 -0
  193. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/store.py +0 -0
  194. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/stream.py +0 -0
  195. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/stream_v2.py +0 -0
  196. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/timing/__init__.py +0 -0
  197. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/timing/profiler.py +0 -0
  198. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/timing/timer.py +0 -0
  199. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/traceblock.py +0 -0
  200. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/tunneling/cloudflare.py +0 -0
  201. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/__init__.py +0 -0
  202. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/cache.py +0 -0
  203. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/config.py +0 -0
  204. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/errors.py +0 -0
  205. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/extract.py +0 -0
  206. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/future.py +0 -0
  207. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/headers.py +0 -0
  208. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/network.py +0 -0
  209. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/retriable_client.py +0 -0
  210. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/stream_codec.py +0 -0
  211. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/utils/uuids.py +0 -0
  212. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/validation.py +0 -0
  213. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/webhook.py +0 -0
  214. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_api/worker.py +0 -0
  215. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/__init__.py +0 -0
  216. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/conversion/__init__.py +0 -0
  217. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/conversion/_compat.py +0 -0
  218. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/conversion/config.py +0 -0
  219. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/conversion/durability.py +0 -0
  220. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/__init__.py +0 -0
  221. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/core_api_pb2.py +0 -0
  222. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/core_api_pb2.pyi +0 -0
  223. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/core_api_pb2_grpc.py +0 -0
  224. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/core_api_pb2_grpc.pyi +0 -0
  225. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/encryption_pb2.py +0 -0
  226. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/encryption_pb2.pyi +0 -0
  227. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/encryption_pb2_grpc.py +0 -0
  228. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/encryption_pb2_grpc.pyi +0 -0
  229. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/engine_common_pb2.py +0 -0
  230. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/engine_common_pb2.pyi +0 -0
  231. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/engine_common_pb2_grpc.py +0 -0
  232. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/engine_common_pb2_grpc.pyi +0 -0
  233. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.py +0 -0
  234. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.pyi +0 -0
  235. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.py +0 -0
  236. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.pyi +0 -0
  237. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_control_signal_pb2.py +0 -0
  238. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_control_signal_pb2.pyi +0 -0
  239. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.py +0 -0
  240. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.pyi +0 -0
  241. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.py +0 -0
  242. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.pyi +0 -0
  243. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.py +0 -0
  244. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.pyi +0 -0
  245. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_durability_pb2.py +0 -0
  246. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_durability_pb2.pyi +0 -0
  247. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.py +0 -0
  248. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.pyi +0 -0
  249. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.py +0 -0
  250. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.pyi +0 -0
  251. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.py +0 -0
  252. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.pyi +0 -0
  253. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_run_status_pb2.py +0 -0
  254. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_run_status_pb2.pyi +0 -0
  255. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.py +0 -0
  256. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.pyi +0 -0
  257. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_stream_mode_pb2.py +0 -0
  258. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_stream_mode_pb2.pyi +0 -0
  259. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.py +0 -0
  260. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.pyi +0 -0
  261. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_thread_status_pb2.py +0 -0
  262. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_thread_status_pb2.pyi +0 -0
  263. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.py +0 -0
  264. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.pyi +0 -0
  265. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.py +0 -0
  266. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.pyi +0 -0
  267. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.py +0 -0
  268. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.pyi +0 -0
  269. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/errors_pb2.py +0 -0
  270. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/errors_pb2.pyi +0 -0
  271. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/errors_pb2_grpc.py +0 -0
  272. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_grpc_common/proto/errors_pb2_grpc.pyi +0 -0
  273. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_license/__init__.py +0 -0
  274. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_license/validation.py +0 -0
  275. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_runtime/__init__.py +0 -0
  276. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_runtime/checkpoint.py +0 -0
  277. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_runtime/database.py +0 -0
  278. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_runtime/lifespan.py +0 -0
  279. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_runtime/metrics.py +0 -0
  280. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_runtime/ops.py +0 -0
  281. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_runtime/queue.py +0 -0
  282. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_runtime/retry.py +0 -0
  283. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_runtime/routes.py +0 -0
  284. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/langgraph_runtime/store.py +0 -0
  285. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/logging.json +0 -0
  286. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/openapi.json +0 -0
  287. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/scripts/build_wheel.py +0 -0
  288. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/scripts/create_license.py +0 -0
  289. {langgraph_api-0.12.0.dev9 → langgraph_api-0.12.0.dev11}/scripts/run_a2a_tck.py +0 -0
@@ -1,7 +1,7 @@
1
1
  .PHONY: build release lint format test test_watch start start-inmem start-inmem-license-oss start start-js-server build-go-server start-go-server stop-go-server check-version check-base-imports test-a2a-tck test-a2a-tck-mandatory start-test-a2a-tck start-test-a2a-tck-mandatory start-test-a2a-tck-watch test-mcp-conformance start-test-mcp-conformance list-mcp-scenarios test-auth-read-only-assistant
2
2
 
3
3
  # Environment variables
4
- LANGSERVE_GRAPHS_ALL = '{"agent": {"path": "./tests/graphs/agent.py:graph", "description": "agent"}, "assistant_id_runtime": "./tests/graphs/assistant_id_runtime.py:graph", "custom_lifespan": "./tests/graphs/my_router.py:graph", "single_node": "./tests/graphs/single_node.py:graph", "benchmark": "./tests/graphs/benchmark.py:graph", "config_graph": "./tests/graphs/config_graph.py:graph", "other": "./tests/graphs/other.py:make_graph", "weather": "./tests/graphs/weather.py:mk_weather_graph", "searchy": "./tests/graphs/searchy.py:graph", "agent_simple": "./tests/graphs/agent_simple.py:graph", "simple_runtime": "./tests/graphs/simple_runtime.py:graph", "agent_interrupt": "./tests/graphs/agent_interrupt.py:graph", "agent_parallel_interrupt": "./tests/graphs/agent_parallel_interrupt.py:graph", "message_type_test": "./tests/graphs/message_type_test.py:graph", "remote_subgraph_parent": "./tests/graphs/remote_subgraph_parent.py:graph", "simple_remote": "./tests/graphs/simple_remote.py:graph", "nested_subgraphs": "./tests/graphs/nested_subgraphs.py:graph", "functional_fibonacci": "./tests/graphs/functional_fibonacci.py:fibonacci", "state_graph_fibonacci": "./tests/graphs/state_graph_fibonacci.py:fibonacci", "max_concurrency_graph": "./tests/graphs/max_concurrency_graph.py:graph", "unserializable_subgraph": "./tests/graphs/unserializable_subgraph.py:graph", "agent_interrupt_text": "./tests/graphs/agent_interrupt_text.py:graph", "agent_echo_stream": "./tests/graphs/agent_echo_stream.py:graph", "agent_tool_stream": "./tests/graphs/agent_tool_stream.py:graph", "runtime_graph": "./tests/graphs/runtime_graph.py:graph", "tool_call_chunk_stream": "./tests/graphs/tool_call_chunk_stream.py:graph", "ui_tool_call_stream": "./tests/graphs/ui_tool_call_stream.py:graph", "agent_metrics_stream": "./tests/graphs/agent_metrics_stream.py:graph", "agent_multimodal_stream": "./tests/graphs/agent_multimodal_stream.py:graph", "agent_bedtime_story": "./tests/graphs/agent_bedtime_story.py:graph", "delta_channel": "./tests/graphs/delta_channel.py:graph", "delta_channel_freq": "./tests/graphs/delta_channel_freq.py:graph", "delta_channel_files": "./tests/graphs/delta_channel_files.py:graph", "delta_channel_files_freq": "./tests/graphs/delta_channel_files_freq.py:graph", "delta_channel_legacy": "./tests/graphs/delta_channel_migration.py:graph_legacy", "delta_channel_delta": "./tests/graphs/delta_channel_migration.py:graph_delta", "delta_channel_messages_freq": "./tests/graphs/delta_channel_messages.py:graph_freq", "delta_channel_messages": "./tests/graphs/delta_channel_messages.py:graph", "delta_channel_messages_legacy": "./tests/graphs/delta_channel_messages.py:graph_legacy", "delta_channel_messages_remove": "./tests/graphs/delta_channel_messages.py:graph_remove", "delta_channel_messages_update": "./tests/graphs/delta_channel_messages.py:graph_update", "delta_channel_messages_delta": "./tests/graphs/delta_channel_messages.py:graph_delta"}'
4
+ LANGSERVE_GRAPHS_ALL = '{"agent": {"path": "./tests/graphs/agent.py:graph", "description": "agent"}, "assistant_id_runtime": "./tests/graphs/assistant_id_runtime.py:graph", "custom_lifespan": "./tests/graphs/my_router.py:graph", "single_node": "./tests/graphs/single_node.py:graph", "benchmark": "./tests/graphs/benchmark.py:graph", "config_graph": "./tests/graphs/config_graph.py:graph", "other": "./tests/graphs/other.py:make_graph", "weather": "./tests/graphs/weather.py:mk_weather_graph", "searchy": "./tests/graphs/searchy.py:graph", "agent_simple": "./tests/graphs/agent_simple.py:graph", "simple_runtime": "./tests/graphs/simple_runtime.py:graph", "agent_interrupt": "./tests/graphs/agent_interrupt.py:graph", "agent_parallel_interrupt": "./tests/graphs/agent_parallel_interrupt.py:graph", "message_type_test": "./tests/graphs/message_type_test.py:graph", "remote_subgraph_parent": "./tests/graphs/remote_subgraph_parent.py:graph", "simple_remote": "./tests/graphs/simple_remote.py:graph", "nested_subgraphs": "./tests/graphs/nested_subgraphs.py:graph", "functional_fibonacci": "./tests/graphs/functional_fibonacci.py:fibonacci", "state_graph_fibonacci": "./tests/graphs/state_graph_fibonacci.py:fibonacci", "max_concurrency_graph": "./tests/graphs/max_concurrency_graph.py:graph", "unserializable_subgraph": "./tests/graphs/unserializable_subgraph.py:graph", "agent_interrupt_text": "./tests/graphs/agent_interrupt_text.py:graph", "agent_echo_stream": "./tests/graphs/agent_echo_stream.py:graph", "agent_tool_stream": "./tests/graphs/agent_tool_stream.py:graph", "runtime_graph": "./tests/graphs/runtime_graph.py:graph", "tool_call_chunk_stream": "./tests/graphs/tool_call_chunk_stream.py:graph", "ui_tool_call_stream": "./tests/graphs/ui_tool_call_stream.py:graph", "agent_metrics_stream": "./tests/graphs/agent_metrics_stream.py:graph", "agent_multimodal_stream": "./tests/graphs/agent_multimodal_stream.py:graph", "agent_bedtime_story": "./tests/graphs/agent_bedtime_story.py:graph", "delta_channel": "./tests/graphs/delta_channel.py:graph", "delta_channel_freq": "./tests/graphs/delta_channel_freq.py:graph", "delta_channel_files": "./tests/graphs/delta_channel_files.py:graph", "delta_channel_files_freq": "./tests/graphs/delta_channel_files_freq.py:graph", "delta_channel_legacy": "./tests/graphs/delta_channel_migration.py:graph_legacy", "delta_channel_delta": "./tests/graphs/delta_channel_migration.py:graph_delta", "delta_channel_delta_filter": "./tests/graphs/delta_channel_migration.py:graph_delta_filter", "delta_channel_messages_freq": "./tests/graphs/delta_channel_messages.py:graph_freq", "delta_channel_messages": "./tests/graphs/delta_channel_messages.py:graph", "delta_channel_messages_legacy": "./tests/graphs/delta_channel_messages.py:graph_legacy", "delta_channel_messages_remove": "./tests/graphs/delta_channel_messages.py:graph_remove", "delta_channel_messages_update": "./tests/graphs/delta_channel_messages.py:graph_update", "delta_channel_messages_delta": "./tests/graphs/delta_channel_messages.py:graph_delta"}'
5
5
  LANGSERVE_GRAPHS_AUTH = '{"agent": {"path": "./tests/graphs/agent.py:graph", "description": "agent"}, "assistant_id_runtime": "./tests/graphs/assistant_id_runtime.py:graph", "config_graph": "./tests/graphs/config_graph.py:graph", "other": "./tests/graphs/other.py:make_graph", "weather": "./tests/graphs/weather.py:mk_weather_graph", "searchy": "./tests/graphs/searchy.py:graph", "agent_simple": "./tests/graphs/agent_simple.py:graph", "simple_runtime": "./tests/graphs/simple_runtime.py:graph", "agent_parallel_interrupt": "./tests/graphs/agent_parallel_interrupt.py:graph", "functional_fibonacci": "./tests/graphs/functional_fibonacci.py:fibonacci", "state_graph_fibonacci": "./tests/graphs/state_graph_fibonacci.py:fibonacci", "runtime_graph": "./tests/graphs/runtime_graph.py:graph"}'
6
6
 
7
7
  # Go server management
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langgraph-api
3
- Version: 0.12.0.dev9
3
+ Version: 0.12.0.dev11
4
4
  Author-email: Will Fu-Hinthorn <will@langchain.dev>, Josh Rogers <josh@langchain.dev>, Parker Rule <parker@langchain.dev>
5
5
  License: Elastic-2.0
6
6
  License-File: LICENSE
@@ -16,7 +16,7 @@ Requires-Dist: jsonschema-rs<0.45,>=0.20.0
16
16
  Requires-Dist: langchain-core>=0.3.64
17
17
  Requires-Dist: langchain-protocol<0.1,>=0.0.18
18
18
  Requires-Dist: langgraph-checkpoint<5,>=3.0.1
19
- Requires-Dist: langgraph-runtime-inmem<0.32.0.dev0,>=0.31.0.dev0
19
+ Requires-Dist: langgraph-runtime-inmem<0.33.0.dev0,>=0.32.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.12.0.dev11"
@@ -24,6 +24,14 @@ from langgraph_grpc_common.checkpointer import GrpcCheckpointer
24
24
  from langgraph_api import config, timing
25
25
  from langgraph_api.asyncio import as_asynccontextmanager
26
26
  from langgraph_api.grpc.client import get_shared_client
27
+
28
+ # Used as the per-instance serializer for ``GrpcCheckpointer`` below so
29
+ # checkpoint payloads honour the same ``USE_PICKLE_FALLBACK`` /
30
+ # encryption / ``allowed_json_modules`` policy as the in-process Python
31
+ # ``Checkpointer``. Scoped to checkpointer RPCs only (via the contextvar
32
+ # in ``langgraph_grpc_common.serde``) so non-checkpointer gRPC ops keep
33
+ # using the safer ``JsonPlusSerializer`` default.
34
+ from langgraph_api.serde import Serializer as _ApiSerializer
27
35
  from langgraph_api.timing import profiled_import
28
36
  from langgraph_api.utils.config import run_in_executor
29
37
 
@@ -320,7 +328,24 @@ async def get_checkpointer(
320
328
  ):
321
329
  return cast(
322
330
  "FullCheckpointerProtocol",
323
- GrpcCheckpointer(get_stub=_get_shared_checkpointer_stub),
331
+ GrpcCheckpointer(
332
+ get_stub=_get_shared_checkpointer_stub,
333
+ serializer=_ApiSerializer(),
334
+ ),
335
+ )
336
+
337
+ from langgraph_api.feature_flags import ( # noqa: PLC0415
338
+ IS_POSTGRES_BACKEND,
339
+ PREFER_GRPC_CHECKPOINTER,
340
+ )
341
+
342
+ if IS_POSTGRES_BACKEND and PREFER_GRPC_CHECKPOINTER:
343
+ return cast(
344
+ "FullCheckpointerProtocol",
345
+ GrpcCheckpointer(
346
+ get_stub=_get_shared_checkpointer_stub,
347
+ serializer=_ApiSerializer(),
348
+ ),
324
349
  )
325
350
 
326
351
  from langgraph_runtime.checkpoint import Checkpointer # noqa: PLC0415
@@ -21,6 +21,7 @@ from __future__ import annotations
21
21
  import asyncio
22
22
  import contextlib
23
23
  import inspect
24
+ import time
24
25
  from collections.abc import Awaitable, Callable
25
26
  from typing import Any, cast, get_args
26
27
  from uuid import UUID, uuid4
@@ -124,6 +125,12 @@ def _multitask_strategy_from_run_start(params: dict[str, Any]) -> str:
124
125
  EventSink = Callable[[dict[str, Any]], Awaitable[None] | None]
125
126
 
126
127
 
128
+ # ``set_joint_status`` commits interrupts after the stream event; gRPC can lag.
129
+ _IN_FLIGHT_THREAD_STATUS = "busy"
130
+ _INTERRUPT_SETTLE_TIMEOUT_SECONDS = 5.0
131
+ _INTERRUPT_SETTLE_POLL_INTERVAL_SECONDS = 0.05
132
+
133
+
127
134
  # Protocol v2 commands this server implements. Anything outside this
128
135
  # set returns ``unknown_command`` up front from ``handle_command`` so
129
136
  # pre-session dispatch does not mislabel typos (or removed methods
@@ -593,13 +600,11 @@ class ThreadRunManager:
593
600
  # this HTTP request (the stateless ``POST /commands`` transport) its
594
601
  # source task hasn't had a chance to emit ``input.requested`` yet —
595
602
  # ``_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.
603
+ # the thread-state check (``_collect_settled_interrupt_ids``) so we
604
+ # don't reject legitimate resumes with a fresh handle.
599
605
  #
600
606
  # 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.
607
+ # cached in ``thread_state_ids``.
603
608
  thread_state_ids: set[str] | None = None
604
609
  thread_state_fetched = False
605
610
  for interrupt_id, claimed_namespace, _ in entries:
@@ -623,7 +628,7 @@ class ThreadRunManager:
623
628
  # only, so trust the client-claimed namespace and validate by
624
629
  # existence (the id is a namespace hash, so that's sufficient).
625
630
  if not thread_state_fetched:
626
- thread_state_ids = await self._collect_persisted_interrupt_ids()
631
+ thread_state_ids = await self._collect_settled_interrupt_ids()
627
632
  thread_state_fetched = True
628
633
  # Fail open when the lookup is unavailable (``None``): only reject
629
634
  # when a definitive id set was read and lacks the target. The
@@ -669,6 +674,7 @@ class ThreadRunManager:
669
674
  {
670
675
  "assistant_id": assistant_id,
671
676
  "input": resume_input,
677
+ "force_resume": True,
672
678
  "update": params.get("update"),
673
679
  "goto": params.get("goto"),
674
680
  "config": params.get("config"),
@@ -732,7 +738,8 @@ class ThreadRunManager:
732
738
  has_interrupts = await self._has_pending_interrupts()
733
739
 
734
740
  is_resume = params.get("input") is not None and (
735
- (current_run is not None and current_status == "interrupted")
741
+ params.get("force_resume")
742
+ or (current_run is not None and current_status == "interrupted")
736
743
  or has_interrupts
737
744
  )
738
745
 
@@ -1108,6 +1115,40 @@ class ThreadRunManager:
1108
1115
  found.add(entry_id)
1109
1116
  return found
1110
1117
 
1118
+ async def _fetch_thread_status(self) -> str | None:
1119
+ """Return durable thread status, or ``None`` if unreadable."""
1120
+ from langgraph_runtime.database import connect # noqa: PLC0415
1121
+
1122
+ try:
1123
+ async with connect() as conn:
1124
+ result = await self._threads.get(conn, self._thread_id)
1125
+ thread = await anext(result) if hasattr(result, "__anext__") else result
1126
+ except Exception:
1127
+ return None
1128
+ status = thread.get("status") if _is_record(thread) else None
1129
+ return status if isinstance(status, str) else None
1130
+
1131
+ async def _collect_settled_interrupt_ids(self) -> set[str] | None:
1132
+ """Persisted interrupt ids, polling while the thread is still ``busy``."""
1133
+ ids = await self._collect_persisted_interrupt_ids()
1134
+ if ids is None:
1135
+ return None
1136
+ if ids:
1137
+ return ids
1138
+ deadline = time.monotonic() + _INTERRUPT_SETTLE_TIMEOUT_SECONDS
1139
+ while True:
1140
+ status = await self._fetch_thread_status()
1141
+ if status != _IN_FLIGHT_THREAD_STATUS:
1142
+ return await self._collect_persisted_interrupt_ids()
1143
+ if time.monotonic() >= deadline:
1144
+ return set()
1145
+ await asyncio.sleep(_INTERRUPT_SETTLE_POLL_INTERVAL_SECONDS)
1146
+ ids = await self._collect_persisted_interrupt_ids()
1147
+ if ids is None:
1148
+ return None
1149
+ if ids:
1150
+ return ids
1151
+
1111
1152
  async def _has_pending_interrupts(self) -> bool:
1112
1153
  # Prefer the session's in-memory pending interrupts (populated the
1113
1154
  # instant ``input.requested`` surfaces) to skip a DB round-trip;
@@ -1116,7 +1157,7 @@ class ThreadRunManager:
1116
1157
  # the ``current_status == "interrupted"`` signal for resume-vs-start.
1117
1158
  if self._session is not None and self._session._pending_interrupts:
1118
1159
  return True
1119
- found = await self._collect_persisted_interrupt_ids()
1160
+ found = await self._collect_settled_interrupt_ids()
1120
1161
  return bool(found)
1121
1162
 
1122
1163
  # ------------------------------------------------------------------
@@ -320,6 +320,14 @@ def _normalize_state_message(value: dict[str, Any]) -> dict[str, Any]:
320
320
  if msg_type in ("ai", "human") and isinstance(value.get("example"), bool):
321
321
  message["example"] = value["example"]
322
322
 
323
+ # Preserve ``response_metadata`` when present. It is a first-class protocol
324
+ # message field, and HITL flows rely on it: an interrupt's card is carried
325
+ # on ``AIMessage.response_metadata`` (e.g. ``{"cards": ...}``) and the
326
+ # frontend pushes that message into state via ``respond(decision, update)``.
327
+ # We only forward a non-empty record to keep the common (empty) case minimal.
328
+ if _is_record(value.get("response_metadata")) and value["response_metadata"]:
329
+ message["response_metadata"] = value["response_metadata"]
330
+
323
331
  if msg_type == "tool":
324
332
  if isinstance(value.get("tool_call_id"), str):
325
333
  message["tool_call_id"] = value["tool_call_id"]
@@ -35,6 +35,16 @@ FF_V2_EVENT_STREAMING = os.getenv("FF_V2_EVENT_STREAMING", "true").lower() in (
35
35
  "yes",
36
36
  )
37
37
 
38
+ # When true on the postgres runtime, use ``GrpcCheckpointer``.
39
+ # Inmem edition is unaffected (``IS_POSTGRES_BACKEND`` is false there).
40
+ # Custom checkpointer (``backend=custom`` in ``LANGGRAPH_CHECKPOINTER``) and
41
+ # Mongo (``backend=mongo``) is also unaffected.
42
+ PREFER_GRPC_CHECKPOINTER = os.getenv("PREFER_GRPC_CHECKPOINTER", "false").lower() in (
43
+ "true",
44
+ "1",
45
+ "yes",
46
+ )
47
+
38
48
  # In langgraph <= 1.0.3, we automatically subscribed to updates stream events to surface interrupts. In langgraph 1.0.4 we include interrupts in values events (which we are automatically subscribed to), so we no longer need to implicitly subscribe to updates stream events
39
49
  # Strip prerelease suffixes (e.g. "0a5" -> 0) so versions like 1.2.0a5 still
40
50
  # parse correctly; fall back to (0, 0, 0) only if no leading digits at all.
@@ -242,3 +242,17 @@ class CheckpointerServicerImpl(CheckpointerServicer):
242
242
  context.set_code(grpc.StatusCode.INTERNAL)
243
243
  context.set_details(f"Checkpointer Prune failed: {e}")
244
244
  raise
245
+
246
+ async def GetDeltaChannelHistory(
247
+ self,
248
+ request: checkpointer_pb2.GetDeltaChannelHistoryRequest,
249
+ context: grpc_aio.ServicerContext,
250
+ ) -> checkpointer_pb2.GetDeltaChannelHistoryResponse:
251
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
252
+ context.set_details(
253
+ "GetDeltaChannelHistory is not implemented by the Python "
254
+ "checkpointer servicer"
255
+ )
256
+ raise NotImplementedError(
257
+ "GetDeltaChannelHistory not implemented by the Python checkpointer servicer"
258
+ )
@@ -8,10 +8,14 @@ from collections.abc import (
8
8
  Callable,
9
9
  Coroutine,
10
10
  Iterator,
11
+ Mapping,
11
12
  Sequence,
12
13
  )
14
+ from contextlib import AbstractContextManager, nullcontext
13
15
  from typing import TYPE_CHECKING, Any, TypeVar, cast
14
16
 
17
+ import grpc
18
+ import grpc.aio
15
19
  from langgraph.checkpoint.base import (
16
20
  BaseCheckpointSaver,
17
21
  ChannelVersions,
@@ -20,6 +24,7 @@ from langgraph.checkpoint.base import (
20
24
  CheckpointTuple,
21
25
  )
22
26
 
27
+ from langgraph_grpc_common import serde as _grpc_serde
23
28
  from langgraph_grpc_common.conversion import checkpoint as ckpt_conv
24
29
  from langgraph_grpc_common.conversion.config import (
25
30
  config_from_proto,
@@ -30,6 +35,7 @@ from langgraph_grpc_common.proto import checkpointer_pb2
30
35
 
31
36
  if TYPE_CHECKING:
32
37
  from langchain_core.runnables import RunnableConfig
38
+ from langgraph.checkpoint.serde.base import SerializerProtocol
33
39
 
34
40
  from langgraph_grpc_common.proto.checkpointer_pb2_grpc import CheckpointerStub
35
41
 
@@ -49,17 +55,43 @@ class GrpcCheckpointer(BaseCheckpointSaver):
49
55
  get_stub: StubProvider,
50
56
  retry: RetryFn | None = None,
51
57
  retry_context_prefix: str | None = None,
58
+ serializer: SerializerProtocol | None = None,
52
59
  ) -> None:
60
+ """Construct a gRPC checkpointer client.
61
+
62
+ Args:
63
+ get_stub: Async factory returning the ``CheckpointerStub`` to
64
+ use for the next RPC. Called per-call so the caller can
65
+ pool / refresh connections.
66
+ retry: Optional retry wrapper. When provided, every RPC is
67
+ dispatched through ``retry(func, context)``.
68
+ retry_context_prefix: Label included in ``retry``'s context
69
+ string. Defaults to the concrete class name.
70
+ serializer: Optional ``SerializerProtocol`` to use for
71
+ payload (de)serialization on *this* checkpointer
72
+ instance only. Scoped via a :class:`~contextvars.ContextVar`
73
+ so unrelated gRPC ops sharing
74
+ ``langgraph_grpc_common.conversion.*`` keep using the
75
+ process-wide default
76
+ """
53
77
  super().__init__(serde=None)
54
78
  self._get_stub = get_stub
55
79
  self._retry = retry
56
80
  self._retry_context_prefix = retry_context_prefix or type(self).__name__
81
+ self._serializer = serializer
57
82
  self.latest_iter = None
58
83
  try:
59
84
  self._loop: asyncio.AbstractEventLoop | None = asyncio.get_running_loop()
60
85
  except RuntimeError:
61
86
  self._loop = None
62
87
 
88
+ def _scoped(self) -> AbstractContextManager[None]:
89
+ """Bind ``self._serializer`` for the duration of a conversion call.
90
+ """
91
+ if self._serializer is None:
92
+ return nullcontext()
93
+ return _grpc_serde.use_serializer(self._serializer)
94
+
63
95
  @property
64
96
  def loop(self) -> asyncio.AbstractEventLoop:
65
97
  if self._loop is None:
@@ -94,13 +126,15 @@ class GrpcCheckpointer(BaseCheckpointSaver):
94
126
  return None
95
127
 
96
128
  async def aget_tuple(self, config: RunnableConfig) -> CheckpointTuple | None:
97
- request = checkpointer_pb2.GetTupleRequest(config=config_to_proto(config))
129
+ with self._scoped():
130
+ request = checkpointer_pb2.GetTupleRequest(config=config_to_proto(config))
98
131
 
99
132
  async def _request() -> CheckpointTuple | None:
100
133
  response = await (await self._stub()).GetTuple(request)
101
134
  if not response.HasField("checkpoint_tuple"):
102
135
  return None
103
- return ckpt_conv.checkpoint_tuple_from_proto(response.checkpoint_tuple)
136
+ with self._scoped():
137
+ return ckpt_conv.checkpoint_tuple_from_proto(response.checkpoint_tuple)
104
138
 
105
139
  return await self._call("aget_tuple", _request)
106
140
 
@@ -128,16 +162,18 @@ class GrpcCheckpointer(BaseCheckpointSaver):
128
162
  metadata: CheckpointMetadata,
129
163
  new_versions: ChannelVersions,
130
164
  ) -> RunnableConfig:
131
- request = checkpointer_pb2.PutRequest(
132
- config=config_to_proto(config),
133
- checkpoint=ckpt_conv.checkpoint_to_proto(checkpoint),
134
- metadata=ckpt_conv.checkpoint_metadata_to_proto(metadata),
135
- new_versions={k: str(v) for k, v in new_versions.items()},
136
- )
165
+ with self._scoped():
166
+ request = checkpointer_pb2.PutRequest(
167
+ config=config_to_proto(config),
168
+ checkpoint=ckpt_conv.checkpoint_to_proto(checkpoint),
169
+ metadata=ckpt_conv.checkpoint_metadata_to_proto(metadata),
170
+ new_versions={k: str(v) for k, v in new_versions.items()},
171
+ )
137
172
 
138
173
  async def _request() -> RunnableConfig:
139
174
  response = await (await self._stub()).Put(request)
140
- next_config = config_from_proto(response.next_config)
175
+ with self._scoped():
176
+ next_config = config_from_proto(response.next_config)
141
177
  if next_config is None:
142
178
  raise ValueError("Unexpected None value for next_config")
143
179
  return next_config
@@ -160,12 +196,13 @@ class GrpcCheckpointer(BaseCheckpointSaver):
160
196
  task_id: str,
161
197
  task_path: str = "",
162
198
  ) -> None:
163
- request = checkpointer_pb2.PutWritesRequest(
164
- config=config_to_proto(config),
165
- writes=ckpt_conv.writes_to_proto(writes),
166
- task_id=task_id,
167
- task_path=task_path,
168
- )
199
+ with self._scoped():
200
+ request = checkpointer_pb2.PutWritesRequest(
201
+ config=config_to_proto(config),
202
+ writes=ckpt_conv.writes_to_proto(writes),
203
+ task_id=task_id,
204
+ task_path=task_path,
205
+ )
169
206
 
170
207
  async def _request() -> None:
171
208
  await (await self._stub()).PutWrites(request)
@@ -212,11 +249,12 @@ class GrpcCheckpointer(BaseCheckpointSaver):
212
249
  before: RunnableConfig | None = None,
213
250
  limit: int | None = None,
214
251
  ) -> AsyncIterator[CheckpointTuple]:
215
- request = checkpointer_pb2.ListRequest(
216
- config=config_to_proto(config) if config is not None else None,
217
- filter_json=convert_dict_to_json_bytes(filter) or b"",
218
- before=config_to_proto(before) if before is not None else None,
219
- )
252
+ with self._scoped():
253
+ request = checkpointer_pb2.ListRequest(
254
+ config=config_to_proto(config) if config is not None else None,
255
+ filter_json=convert_dict_to_json_bytes(filter) or b"",
256
+ before=config_to_proto(before) if before is not None else None,
257
+ )
220
258
  if limit is not None:
221
259
  request.limit = limit
222
260
 
@@ -225,7 +263,11 @@ class GrpcCheckpointer(BaseCheckpointSaver):
225
263
 
226
264
  response = await self._call("alist", _request)
227
265
  for proto_tuple in response.checkpoint_tuples:
228
- if (tup := ckpt_conv.checkpoint_tuple_from_proto(proto_tuple)) is not None:
266
+ # Bind inside the loop body so the override does not leak
267
+ # across ``yield`` into the consumer's frame.
268
+ with self._scoped():
269
+ tup = ckpt_conv.checkpoint_tuple_from_proto(proto_tuple)
270
+ if tup is not None:
229
271
  yield tup
230
272
 
231
273
  def delete_thread(self, thread_id: str) -> None:
@@ -298,3 +340,55 @@ class GrpcCheckpointer(BaseCheckpointSaver):
298
340
  next_v = current_v + 1
299
341
  next_h = random.random()
300
342
  return f"{next_v:032}.{next_h:.16f}"
343
+
344
+ def get_delta_channel_history(
345
+ self,
346
+ *,
347
+ config: RunnableConfig,
348
+ channels: Sequence[str],
349
+ ) -> Mapping[str, dict[str, Any]]:
350
+ """Synchronous wrapper for ``aget_delta_channel_history``.
351
+
352
+ langgraph >= 1.2 calls the async variant from the loop, but the
353
+ BaseCheckpointSaver protocol expects sync wrappers to exist.
354
+ """
355
+ return self._run_sync(
356
+ self.aget_delta_channel_history(config=config, channels=channels)
357
+ )
358
+
359
+ async def aget_delta_channel_history(
360
+ self,
361
+ *,
362
+ config: RunnableConfig,
363
+ channels: Sequence[str],
364
+ ) -> Mapping[str, dict[str, Any]]:
365
+ if not channels:
366
+ return {}
367
+ configurable = config.get("configurable", {}) if config else {}
368
+ request = checkpointer_pb2.GetDeltaChannelHistoryRequest(
369
+ thread_id=configurable.get("thread_id", "") or "",
370
+ checkpoint_ns=configurable.get("checkpoint_ns", "") or "",
371
+ # Empty checkpoint_id => server resolves the latest checkpoint.
372
+ checkpoint_id=configurable.get("checkpoint_id", "") or "",
373
+ channels=list(channels),
374
+ )
375
+
376
+ async def _request() -> checkpointer_pb2.GetDeltaChannelHistoryResponse:
377
+ return await (await self._stub()).GetDeltaChannelHistory(request)
378
+
379
+ try:
380
+ response = await self._call("aget_delta_channel_history", _request)
381
+ except grpc.aio.AioRpcError as e:
382
+ if e.code() == grpc.StatusCode.UNIMPLEMENTED:
383
+ # The backend has no native fast path for delta-channel
384
+ # reconstruction (e.g. the Go mongo/sqlite checkpointers).
385
+ # Fall back to BaseCheckpointSaver's parent-chain walk, which
386
+ # drives aget_tuple (-> gRPC GetTuple) per ancestor. langgraph
387
+ # calls this method unguarded, so we must degrade gracefully
388
+ # rather than raise.
389
+ return await super().aget_delta_channel_history(
390
+ config=config, channels=channels
391
+ )
392
+ raise
393
+ with self._scoped():
394
+ return ckpt_conv.delta_channel_history_from_proto(response.entries)
@@ -1,3 +1,4 @@
1
+ from collections.abc import Mapping
1
2
  from collections.abc import Sequence as SequenceType
2
3
  from typing import Any, Literal, cast
3
4
 
@@ -16,7 +17,7 @@ from langgraph_grpc_common.conversion.config import (
16
17
  )
17
18
  from langgraph_grpc_common.conversion.struct import dict_from_raw_map, raw_map_from_dict
18
19
  from langgraph_grpc_common.conversion.value import (
19
- any_to_serialized_value,
20
+ base_value_to_proto,
20
21
  send_to_proto,
21
22
  value_from_proto,
22
23
  value_to_proto,
@@ -86,11 +87,7 @@ def checkpoint_to_proto(checkpoint: Checkpoint) -> engine_common_pb2.Checkpoint:
86
87
  )
87
88
  )
88
89
  else:
89
- checkpoint_proto.channel_values[k].CopyFrom(
90
- engine_common_pb2.ChannelValue(
91
- serialized_value=any_to_serialized_value(v)
92
- )
93
- )
90
+ checkpoint_proto.channel_values[k].CopyFrom(base_value_to_proto(v))
94
91
 
95
92
  return checkpoint_proto
96
93
 
@@ -241,3 +238,95 @@ def prune_strategy_to_proto(
241
238
  case "delete_all":
242
239
  return checkpointer_pb2.PruneRequest.PruneStrategy.DELETE_ALL
243
240
  raise ValueError("Unknown prune strategy: " + strategy)
241
+
242
+
243
+ # ---------------------------------------------------------------------------
244
+ # DeltaChannelHistory conversion
245
+ # ---------------------------------------------------------------------------
246
+ #
247
+ # ``DeltaChannelHistory`` is a TypedDict from langgraph >= 1.2:
248
+ #
249
+ # class DeltaChannelHistory(TypedDict, total=False):
250
+ # seed: Any # optional snapshot value
251
+ # writes: list[PendingWrite] # (task_id, channel, value) tuples
252
+ #
253
+ # These helpers serialize/deserialize that shape to/from the wire-format
254
+ # ``DeltaChannelHistoryEntry`` proto.
255
+ #
256
+ # We accept and return plain ``dict[str, dict]`` rather than importing
257
+ # the ``DeltaChannelHistory`` TypedDict — langgraph treats the TypedDict
258
+ # structurally, so any dict with the right keys is accepted by the
259
+ # consumer (langgraph's ``DeltaChannel.replay_writes``).
260
+
261
+
262
+ def delta_channel_history_entry_to_proto(
263
+ entry: Mapping[str, Any],
264
+ *,
265
+ channel: str,
266
+ ) -> checkpointer_pb2.DeltaChannelHistoryEntry:
267
+ """Encode one channel's ``DeltaChannelHistory`` dict as proto.
268
+
269
+ Args:
270
+ entry: Mapping with optional ``seed`` and optional ``writes``.
271
+ ``writes`` is a sequence of ``(task_id, channel, value)`` tuples
272
+ (langgraph's ``PendingWrite``).
273
+ channel: The channel name this entry corresponds to. We pass it to
274
+ ``value_to_proto`` so the TASKS channel special-cases the
275
+ seed/write conversion if it ever appears here.
276
+ """
277
+ pb_entry = checkpointer_pb2.DeltaChannelHistoryEntry()
278
+ if "seed" in entry:
279
+ pb_entry.seed.CopyFrom(value_to_proto(channel, entry["seed"]))
280
+ for write in entry.get("writes", ()) or ():
281
+ task_id, write_channel, write_value = write
282
+ pb_entry.writes.append(
283
+ engine_common_pb2.PendingWrite(
284
+ task_id=str(task_id),
285
+ channel=str(write_channel),
286
+ value=value_to_proto(write_channel, write_value),
287
+ )
288
+ )
289
+ return pb_entry
290
+
291
+
292
+ def delta_channel_history_to_proto(
293
+ history: Mapping[str, Mapping[str, Any]],
294
+ ) -> dict[str, checkpointer_pb2.DeltaChannelHistoryEntry]:
295
+ """Encode the full per-channel mapping for the response proto."""
296
+ return {
297
+ ch: delta_channel_history_entry_to_proto(entry, channel=ch)
298
+ for ch, entry in history.items()
299
+ }
300
+
301
+
302
+ def delta_channel_history_entry_from_proto(
303
+ entry: checkpointer_pb2.DeltaChannelHistoryEntry,
304
+ ) -> dict[str, Any]:
305
+ """Decode one channel's proto entry to a ``DeltaChannelHistory`` dict.
306
+
307
+ The ``seed`` key is omitted from the result when the proto has no
308
+ seed set — matches the Python source's "absence means MISSING"
309
+ contract (see ``_assemble_delta_history`` in
310
+ ``storage_postgres/langgraph_runtime_postgres/checkpoint.py``).
311
+ """
312
+ out: dict[str, Any] = {
313
+ "writes": [
314
+ (write.task_id, write.channel, value_from_proto(write.value))
315
+ for write in entry.writes
316
+ ],
317
+ }
318
+ if entry.HasField("seed"):
319
+ out["seed"] = value_from_proto(entry.seed)
320
+ return out
321
+
322
+
323
+ def delta_channel_history_from_proto(
324
+ entries: Mapping[str, checkpointer_pb2.DeltaChannelHistoryEntry],
325
+ ) -> dict[str, dict[str, Any]]:
326
+ """Decode the full per-channel response proto map."""
327
+ return {
328
+ ch: delta_channel_history_entry_from_proto(entry)
329
+ for ch, entry in entries.items()
330
+ }
331
+
332
+
@@ -0,0 +1,60 @@
1
+ import re
2
+ from collections.abc import Mapping
3
+ from typing import Any
4
+
5
+ import orjson
6
+ from google.protobuf import struct_pb2
7
+
8
+
9
+ def struct_from_dict(d: Mapping[str, Any]) -> struct_pb2.Struct:
10
+ s = struct_pb2.Struct()
11
+ s.update(d)
12
+ return s
13
+
14
+
15
+ def _default_serializer(obj: Any) -> Any:
16
+ if hasattr(obj, "dict") and callable(obj.dict):
17
+ return obj.dict()
18
+ if hasattr(obj, "__dict__"):
19
+ return obj.__dict__
20
+ raise TypeError(f"Type is not JSON serializable: {type(obj).__name__}")
21
+
22
+
23
+ _SURROGATE_RE = re.compile(r"[\ud800-\udfff]")
24
+
25
+
26
+ def _replace_surrogates(o: Any) -> Any:
27
+ """Recursively replace lone-surrogate codepoints (orjson rejects them).
28
+
29
+ Mirrors ``_sanitise`` in ``langgraph_grpc_common.serde`` so metadata
30
+ encode falls back gracefully instead of raising. Without this,
31
+ fixtures that intentionally embed surrogates (e.g.
32
+ ``test_thread_copy``'s ``"surrogate"`` field on
33
+ ``langgraph==0.4.10`` which mirrors input into metadata) crash the
34
+ whole put.
35
+ """
36
+ if isinstance(o, str):
37
+ return _SURROGATE_RE.sub("?", o) if _SURROGATE_RE.search(o) else o
38
+ if isinstance(o, Mapping):
39
+ return {_replace_surrogates(k): _replace_surrogates(v) for k, v in o.items()}
40
+ if isinstance(o, (list, tuple, set)):
41
+ return type(o)(_replace_surrogates(x) for x in o)
42
+ return o
43
+
44
+
45
+ def raw_map_from_dict(d: Mapping[str, Any]) -> Mapping[str, bytes]:
46
+ out: dict[str, bytes] = {}
47
+ for k, v in d.items():
48
+ try:
49
+ out[k] = orjson.dumps(v, default=_default_serializer)
50
+ except (TypeError, ValueError):
51
+ # orjson rejects e.g. lone surrogates and a few other oddities
52
+ # that the in-process Python ``Checkpointer.aput`` happily
53
+ # stores via its own serde. Sanitize and retry rather than
54
+ # failing the entire put.
55
+ out[k] = orjson.dumps(_replace_surrogates(v), default=_default_serializer)
56
+ return out
57
+
58
+
59
+ def dict_from_raw_map(m: Mapping[str, bytes]) -> dict[str, Any]:
60
+ return {k: orjson.loads(v) for k, v in m.items()}