langgraph-api 0.7.78__tar.gz → 0.7.80__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 (284) hide show
  1. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/PKG-INFO +2 -2
  2. langgraph_api-0.7.80/langgraph_api/__init__.py +1 -0
  3. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/_checkpointer/_adapter.py +2 -2
  4. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/auth/custom.py +2 -2
  5. langgraph_api-0.7.80/langgraph_api/cache.py +418 -0
  6. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/cli.py +3 -3
  7. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/command.py +1 -1
  8. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/cron_scheduler.py +1 -1
  9. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/encryption/context.py +1 -1
  10. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/encryption/middleware.py +4 -4
  11. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/graph.py +3 -3
  12. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/grpc/client.py +2 -2
  13. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/grpc/ops/assistants.py +8 -8
  14. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/grpc/ops/crons.py +6 -6
  15. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/grpc/ops/runs.py +8 -8
  16. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/grpc/ops/threads.py +9 -9
  17. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/grpc/servicers/checkpointer.py +4 -4
  18. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/grpc/servicers/encryption.py +1 -1
  19. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/http.py +1 -1
  20. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/remote.py +4 -4
  21. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/sse.py +1 -1
  22. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/logging.py +1 -1
  23. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/metadata.py +1 -1
  24. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/models/run.py +1 -1
  25. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/patch.py +3 -3
  26. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/schema.py +4 -4
  27. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/server.py +1 -1
  28. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/state.py +9 -9
  29. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/store.py +1 -1
  30. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/stream.py +8 -8
  31. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/timing/profiler.py +1 -1
  32. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/timing/timer.py +5 -5
  33. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/traceblock.py +1 -1
  34. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/utils/__init__.py +1 -1
  35. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/utils/config.py +4 -4
  36. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/utils/future.py +1 -1
  37. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/checkpointer_pb2.pyi +1 -1
  38. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.pyi +1 -1
  39. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/core_api_pb2.pyi +10 -10
  40. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/core_api_pb2_grpc.pyi +1 -1
  41. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/encryption_pb2_grpc.pyi +1 -1
  42. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/engine_api_pb2.pyi +5 -5
  43. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/engine_api_pb2_grpc.pyi +1 -1
  44. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/engine_common_pb2.pyi +3 -3
  45. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/executor_api_pb2.pyi +1 -1
  46. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/executor_api_pb2_grpc.pyi +2 -2
  47. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/pyproject.toml +1 -1
  48. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/uv.lock +140 -123
  49. langgraph_api-0.7.78/langgraph_api/__init__.py +0 -1
  50. langgraph_api-0.7.78/langgraph_api/cache.py +0 -51
  51. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/.gitignore +0 -0
  52. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/LICENSE +0 -0
  53. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/Makefile +0 -0
  54. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/README.md +0 -0
  55. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/.gitignore +0 -0
  56. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/Makefile +0 -0
  57. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/README.md +0 -0
  58. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/benchmark-runners/assistant.js +0 -0
  59. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/benchmark-runners/benchmark-runner.js +0 -0
  60. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/benchmark-runners/benchmarks.js +0 -0
  61. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/benchmark-runners/stream_write.js +0 -0
  62. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/benchmark-runners/thread.js +0 -0
  63. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/benchmark-runners/wait_write.js +0 -0
  64. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/burst.js +0 -0
  65. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/capacity_dd_report.py +0 -0
  66. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/capacity_k6.js +0 -0
  67. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/capacity_runner.mjs +0 -0
  68. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/capacity_slack_report.py +0 -0
  69. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/capacity_urls.mjs +0 -0
  70. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/clean-cli.js +0 -0
  71. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/clean.js +0 -0
  72. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/continuous/README.md +0 -0
  73. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/continuous/pyproject.toml +0 -0
  74. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/continuous/runner.py +0 -0
  75. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/continuous/uv.lock +0 -0
  76. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/graphs.js +0 -0
  77. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/mixed_workload_k6.js +0 -0
  78. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/mixed_workload_runner.mjs +0 -0
  79. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/package.json +0 -0
  80. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/ramp.js +0 -0
  81. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/reporting/dd_reporting.py +0 -0
  82. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/reporting/slack_slowest_runs.py +0 -0
  83. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/reporting/slack_summary.py +0 -0
  84. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/run_local.sh +0 -0
  85. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/staircase.py +0 -0
  86. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/staircase_step_k6.js +0 -0
  87. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/update-revision.js +0 -0
  88. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/benchmark/weather.js +0 -0
  89. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/constraints.txt +0 -0
  90. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/custom_store.sql +0 -0
  91. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/forbidden.txt +0 -0
  92. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/hatch_build.py +0 -0
  93. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/healthcheck.py +0 -0
  94. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph-cloud-debugging-20260210132856.zip +0 -0
  95. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/_checkpointer/__init__.py +0 -0
  96. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/_checkpointer/protocol.py +0 -0
  97. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/_factory_utils.py +0 -0
  98. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/api/__init__.py +0 -0
  99. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/api/a2a.py +0 -0
  100. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/api/assistants.py +0 -0
  101. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/api/mcp/__init__.py +0 -0
  102. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/api/mcp/_constants.py +0 -0
  103. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/api/mcp/_handlers.py +0 -0
  104. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/api/mcp/_models.py +0 -0
  105. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/api/mcp/_routes.py +0 -0
  106. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/api/mcp/_sanitizers.py +0 -0
  107. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/api/meta.py +0 -0
  108. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/api/openapi.py +0 -0
  109. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/api/profile.py +0 -0
  110. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/api/runs.py +0 -0
  111. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/api/store.py +0 -0
  112. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/api/threads.py +0 -0
  113. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/api/ui.py +0 -0
  114. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/asgi_transport.py +0 -0
  115. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/asyncio.py +0 -0
  116. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/auth/__init__.py +0 -0
  117. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/auth/errors.py +0 -0
  118. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/auth/langsmith/__init__.py +0 -0
  119. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/auth/langsmith/backend.py +0 -0
  120. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/auth/langsmith/client.py +0 -0
  121. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/auth/middleware.py +0 -0
  122. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/auth/noop.py +0 -0
  123. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/auth/studio_user.py +0 -0
  124. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/config/__init__.py +0 -0
  125. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/config/_parse.py +0 -0
  126. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/config/schemas.py +0 -0
  127. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/encryption/__init__.py +0 -0
  128. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/encryption/aes_json.py +0 -0
  129. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/encryption/custom.py +0 -0
  130. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/encryption/shared.py +0 -0
  131. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/errors.py +0 -0
  132. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/executor_entrypoint.py +0 -0
  133. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/feature_flags.py +0 -0
  134. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/grpc/__init__.py +0 -0
  135. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/grpc/generated/core_api_pb2.pyi +0 -0
  136. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/grpc/ops/__init__.py +0 -0
  137. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/grpc/ops/cache.py +0 -0
  138. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/grpc/server.py +0 -0
  139. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/grpc/servicers/__init__.py +0 -0
  140. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/http_metrics.py +0 -0
  141. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/http_metrics_utils.py +0 -0
  142. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/.gitignore +0 -0
  143. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/.prettierrc +0 -0
  144. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/__init__.py +0 -0
  145. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/base.py +0 -0
  146. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/build.mts +0 -0
  147. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/client.http.mts +0 -0
  148. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/client.mts +0 -0
  149. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/errors.py +0 -0
  150. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/global.d.ts +0 -0
  151. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/package.json +0 -0
  152. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/schema.py +0 -0
  153. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/src/graph.mts +0 -0
  154. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/src/load.hooks.mjs +0 -0
  155. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/src/preload.mjs +0 -0
  156. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/src/utils/files.mts +0 -0
  157. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/src/utils/importMap.mts +0 -0
  158. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
  159. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/src/utils/serde.mts +0 -0
  160. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/traceblock.mts +0 -0
  161. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/tsconfig.json +0 -0
  162. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/ui.py +0 -0
  163. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/js/yarn.lock +0 -0
  164. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/middleware/__init__.py +0 -0
  165. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/middleware/ensure_store.py +0 -0
  166. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/middleware/http_logger.py +0 -0
  167. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/middleware/private_network.py +0 -0
  168. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/middleware/request_id.py +0 -0
  169. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/models/__init__.py +0 -0
  170. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/otel_context.py +0 -0
  171. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/queue_entrypoint.py +0 -0
  172. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/route.py +0 -0
  173. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/self_hosted_logs.py +0 -0
  174. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/self_hosted_metrics.py +0 -0
  175. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/serde.py +0 -0
  176. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/sse.py +0 -0
  177. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/timing/__init__.py +0 -0
  178. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/tunneling/cloudflare.py +0 -0
  179. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/utils/cache.py +0 -0
  180. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/utils/errors.py +0 -0
  181. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/utils/extract.py +0 -0
  182. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/utils/headers.py +0 -0
  183. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/utils/retriable_client.py +0 -0
  184. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/utils/stream_codec.py +0 -0
  185. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/utils/uuids.py +0 -0
  186. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/validation.py +0 -0
  187. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/webhook.py +0 -0
  188. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_api/worker.py +0 -0
  189. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/__init__.py +0 -0
  190. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/checkpointer.py +0 -0
  191. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/conversion/__init__.py +0 -0
  192. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/conversion/_compat.py +0 -0
  193. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/conversion/channel.py +0 -0
  194. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/conversion/checkpoint.py +0 -0
  195. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/conversion/config.py +0 -0
  196. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/conversion/durability.py +0 -0
  197. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/conversion/exception.py +0 -0
  198. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/conversion/graph.py +0 -0
  199. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/conversion/interrupt.py +0 -0
  200. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/conversion/messages.py +0 -0
  201. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/conversion/orchestrator_response.py +0 -0
  202. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/conversion/runopts.py +0 -0
  203. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/conversion/stream_mode.py +0 -0
  204. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/conversion/struct.py +0 -0
  205. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/conversion/task.py +0 -0
  206. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/conversion/value.py +0 -0
  207. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/__init__.py +0 -0
  208. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/checkpointer_pb2.py +0 -0
  209. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.py +0 -0
  210. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/core_api_pb2.py +0 -0
  211. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/core_api_pb2_grpc.py +0 -0
  212. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/encryption_pb2.py +0 -0
  213. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/encryption_pb2.pyi +0 -0
  214. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/encryption_pb2_grpc.py +0 -0
  215. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/engine_api_pb2.py +0 -0
  216. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/engine_api_pb2_grpc.py +0 -0
  217. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/engine_common_pb2.py +0 -0
  218. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/engine_common_pb2_grpc.py +0 -0
  219. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/engine_common_pb2_grpc.pyi +0 -0
  220. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.py +0 -0
  221. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.pyi +0 -0
  222. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.py +0 -0
  223. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.pyi +0 -0
  224. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_control_signal_pb2.py +0 -0
  225. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_control_signal_pb2.pyi +0 -0
  226. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.py +0 -0
  227. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.pyi +0 -0
  228. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.py +0 -0
  229. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.pyi +0 -0
  230. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.py +0 -0
  231. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.pyi +0 -0
  232. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_durability_pb2.py +0 -0
  233. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_durability_pb2.pyi +0 -0
  234. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.py +0 -0
  235. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.pyi +0 -0
  236. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.py +0 -0
  237. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.pyi +0 -0
  238. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.py +0 -0
  239. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.pyi +0 -0
  240. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_run_status_pb2.py +0 -0
  241. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_run_status_pb2.pyi +0 -0
  242. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.py +0 -0
  243. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.pyi +0 -0
  244. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_store_operation_entry_type_pb2.py +0 -0
  245. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_store_operation_entry_type_pb2.pyi +0 -0
  246. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_store_operation_entry_type_pb2_grpc.py +0 -0
  247. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_store_operation_entry_type_pb2_grpc.pyi +0 -0
  248. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_stream_mode_pb2.py +0 -0
  249. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_stream_mode_pb2.pyi +0 -0
  250. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.py +0 -0
  251. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.pyi +0 -0
  252. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_thread_status_pb2.py +0 -0
  253. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_thread_status_pb2.pyi +0 -0
  254. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.py +0 -0
  255. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.pyi +0 -0
  256. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.py +0 -0
  257. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.pyi +0 -0
  258. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.py +0 -0
  259. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.pyi +0 -0
  260. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/errors_pb2.py +0 -0
  261. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/errors_pb2.pyi +0 -0
  262. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/errors_pb2_grpc.py +0 -0
  263. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/errors_pb2_grpc.pyi +0 -0
  264. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/executor_api_pb2.py +0 -0
  265. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/proto/executor_api_pb2_grpc.py +0 -0
  266. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/sanitize.py +0 -0
  267. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_grpc_common/serde.py +0 -0
  268. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_license/__init__.py +0 -0
  269. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_license/validation.py +0 -0
  270. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_runtime/__init__.py +0 -0
  271. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_runtime/checkpoint.py +0 -0
  272. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_runtime/database.py +0 -0
  273. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_runtime/lifespan.py +0 -0
  274. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_runtime/metrics.py +0 -0
  275. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_runtime/ops.py +0 -0
  276. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_runtime/queue.py +0 -0
  277. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_runtime/retry.py +0 -0
  278. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_runtime/routes.py +0 -0
  279. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/langgraph_runtime/store.py +0 -0
  280. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/logging.json +0 -0
  281. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/openapi.json +0 -0
  282. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/scripts/build_wheel.py +0 -0
  283. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/scripts/create_license.py +0 -0
  284. {langgraph_api-0.7.78 → langgraph_api-0.7.80}/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.7.78
3
+ Version: 0.7.80
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
@@ -24,7 +24,7 @@ Requires-Dist: opentelemetry-sdk>=1.37.0
24
24
  Requires-Dist: orjson>=3.9.7
25
25
  Requires-Dist: protobuf<7.0.0,>=6.32.1
26
26
  Requires-Dist: pyjwt>=2.9.0
27
- Requires-Dist: sse-starlette<3.4.0,>=3.0.0
27
+ Requires-Dist: sse-starlette<3.4.0,>=2.1.3
28
28
  Requires-Dist: starlette>=0.38.6
29
29
  Requires-Dist: structlog<26,>=24.1.0
30
30
  Requires-Dist: tenacity>=8.0.0
@@ -0,0 +1 @@
1
+ __version__ = "0.7.80"
@@ -309,7 +309,7 @@ async def get_checkpointer(
309
309
  # Create a fresh adapter each time (not cached) - each gets own latest_iter
310
310
  if _CHECKPOINTER_CAPABILITIES is None:
311
311
  raise RuntimeError("Capabilities not initialized")
312
- return _CustomCheckpointerAdapter( # type: ignore[return-value]
312
+ return _CustomCheckpointerAdapter(
313
313
  inner=CHECKPOINTER_STACK.inner, capabilities=_CHECKPOINTER_CAPABILITIES
314
314
  )
315
315
 
@@ -431,7 +431,7 @@ def _load_checkpointer(checkpointer_path: str) -> Any:
431
431
  raise ValueError(f"Could not find checkpointer file: {path_name}")
432
432
  module = importlib.util.module_from_spec(modspec)
433
433
  sys.modules[modname] = module
434
- modspec.loader.exec_module(module) # type: ignore[possibly-unbound-attribute]
434
+ modspec.loader.exec_module(module)
435
435
  else:
436
436
  path_name, function = checkpointer_path.rsplit(".", 1)
437
437
  module = importlib.import_module(path_name)
@@ -251,7 +251,7 @@ def _get_auth_instance(path: str | None = None) -> Auth | Literal["js"] | None:
251
251
  deps := _get_dependencies(auth_instance._authenticate_handler)
252
252
  ):
253
253
  auth_instance._authenticate_handler = _solve_fastapi_dependencies(
254
- auth_instance._authenticate_handler, # type: ignore[invalid-argument-type]
254
+ auth_instance._authenticate_handler,
255
255
  deps,
256
256
  )
257
257
  logger.info(f"Loaded auth instance from path {path}: {auth_instance}")
@@ -631,7 +631,7 @@ def _load_auth_obj(path: str) -> Auth | Literal["js"]:
631
631
  raise ValueError(f"Could not load file: {module_name}")
632
632
  module = importlib.util.module_from_spec(modspec)
633
633
  sys.modules[modname] = module
634
- modspec.loader.exec_module(module) # type: ignore[possibly-unbound-attribute]
634
+ modspec.loader.exec_module(module)
635
635
  else:
636
636
  # Load from Python module
637
637
  module = importlib.import_module(module_name)
@@ -0,0 +1,418 @@
1
+ """Basic distributed key/value cache for internal use."""
2
+
3
+ import asyncio
4
+ import logging
5
+ import time
6
+ from collections.abc import Awaitable, Callable
7
+ from dataclasses import dataclass, field
8
+ from datetime import timedelta
9
+ from typing import Any, Generic, Literal, TypedDict, TypeVar, cast
10
+
11
+ import orjson
12
+
13
+ from langgraph_api.feature_flags import IS_POSTGRES_OR_GRPC_BACKEND
14
+ from langgraph_api.utils.cache import LRUCache
15
+
16
+ MAX_CACHE_TTL = timedelta(hours=24)
17
+
18
+ if IS_POSTGRES_OR_GRPC_BACKEND:
19
+ from langgraph_api.grpc.ops.cache import cache_get as _cache_get
20
+ from langgraph_api.grpc.ops.cache import cache_set as _cache_set
21
+ else:
22
+ _CACHE: LRUCache[bytes] = LRUCache(ttl=MAX_CACHE_TTL.total_seconds())
23
+
24
+ async def _cache_get(key: str) -> bytes | None:
25
+ return await _CACHE.get(key)
26
+
27
+ async def _cache_set(key: str, value: bytes, ttl: timedelta | None = None) -> None:
28
+ ttl = _clamp_ttl(ttl)
29
+ _CACHE.set(key, value)
30
+
31
+
32
+ logger = logging.getLogger(__name__)
33
+
34
+ _SWR_KEY_PREFIX = "__lg_swr__:"
35
+ _SWR_SCHEMA_VERSION = 1
36
+ _DELTA_ZERO = timedelta(0)
37
+ _UNSET: Any = object()
38
+
39
+
40
+ JsonValue = dict[str, Any] | list[Any] | str | int | float | bool | None
41
+
42
+ CacheStatus = Literal["miss", "fresh", "stale", "expired"]
43
+
44
+ T = TypeVar("T")
45
+
46
+ __all__ = ["CacheStatus", "JsonValue", "SWRResult", "cache_get", "cache_set", "swr"]
47
+
48
+
49
+ class SWRResult(Generic[T]):
50
+ """Result wrapper returned by :func:`swr`.
51
+
52
+ Attributes:
53
+ value: The cached (or freshly loaded) value.
54
+ status: How the value was resolved: ``"miss"``, ``"fresh"``,
55
+ ``"stale"``, or ``"expired"``.
56
+ """
57
+
58
+ __slots__ = ("_cache_key", "_loader", "_max_age", "_model", "status", "value")
59
+
60
+ def __init__(
61
+ self,
62
+ value: T,
63
+ *,
64
+ cache_key: str,
65
+ loader: Callable[[], Awaitable[Any]],
66
+ max_age: timedelta,
67
+ status: CacheStatus,
68
+ model: type[T] | None = None,
69
+ ) -> None:
70
+ self.value = value
71
+ self._cache_key = cache_key
72
+ self._loader = loader
73
+ self._max_age = max_age
74
+ self._model = model
75
+ self.status: CacheStatus = status
76
+
77
+ async def mutate(self, value: T = _UNSET) -> T: # ty: ignore[invalid-parameter-default]
78
+ """Update or revalidate the cached value.
79
+
80
+ Args:
81
+ value: If provided, optimistically write this value into the cache.
82
+ If omitted, re-run the original loader to revalidate.
83
+
84
+ Returns:
85
+ The new cached value.
86
+ """
87
+ if value is _UNSET:
88
+ raw = await _await_swr_load(self._cache_key, self._loader, self._max_age)
89
+ result = (
90
+ cast("T", self._model.model_validate(raw))
91
+ if self._model is not None
92
+ else cast("T", raw)
93
+ )
94
+ else:
95
+ raw = value.model_dump(mode="json") if self._model is not None else value
96
+ await _write_swr_value(self._cache_key, raw, self._max_age)
97
+ result = value
98
+ self.value = result
99
+ return result
100
+
101
+ def __repr__(self) -> str:
102
+ return f"SWRResult(value={self.value!r}, status={self.status!r})"
103
+
104
+
105
+ async def cache_get(key: str) -> Any | None:
106
+ """Get a value from the cache."""
107
+ val = await _cache_get(key)
108
+ return orjson.loads(val) if val is not None else None
109
+
110
+
111
+ async def cache_set(key: str, value: Any, ttl: timedelta | None = None) -> None:
112
+ """Set a value in the cache.
113
+
114
+ Args:
115
+ key: The cache key.
116
+ value: The value to cache (must be serializable to JSON).
117
+ ttl: Optional time-to-live. Capped at MAX_CACHE_TTL (24 hours by default);
118
+ `None` or zero defaults to MAX_CACHE_TTL.
119
+ """
120
+ ttl = _clamp_ttl(ttl)
121
+ await _cache_set(key, orjson.dumps(value), ttl)
122
+
123
+
124
+ class _SWREntry(TypedDict):
125
+ v: int
126
+ value: Any
127
+ stored_at_ms: int
128
+
129
+
130
+ @dataclass(slots=True)
131
+ class _SWRState:
132
+ task: asyncio.Task[Any] | None = None
133
+ write_epoch: int = 0
134
+ write_lock: asyncio.Lock = field(default_factory=asyncio.Lock)
135
+ users: int = 0
136
+
137
+
138
+ _SWR_STATES: dict[str, _SWRState] = {}
139
+
140
+
141
+ async def swr(
142
+ key: str,
143
+ loader: Callable[[], Awaitable[T]],
144
+ *,
145
+ fresh_for: timedelta = _DELTA_ZERO,
146
+ max_age: timedelta | None = None,
147
+ model: type[T] | None = None,
148
+ ) -> SWRResult[T]:
149
+ """Load a cached value using stale-while-revalidate semantics.
150
+
151
+ This helper is server-side only and is intended for caching internal async
152
+ dependencies such as auth or metadata lookups.
153
+
154
+ Args:
155
+ key: Cache key.
156
+ loader: Async callable that fetches the value on miss/revalidation.
157
+ fresh_for: How long a cached value is considered fresh (no revalidation).
158
+ Defaults to ``timedelta(0)`` so every access triggers a background
159
+ revalidate while still returning the cached value instantly. Values
160
+ above :data:`MAX_CACHE_TTL` are clamped to the backend maximum.
161
+ max_age: Total lifetime of a cached entry. After this, the next access
162
+ blocks on the loader. Defaults to :data:`MAX_CACHE_TTL` (24 h by
163
+ default). Values above :data:`MAX_CACHE_TTL` are clamped to the
164
+ backend maximum.
165
+ model: Optional Pydantic model class. When provided, values are
166
+ serialized via ``model_dump(mode="json")`` before storage and
167
+ deserialized via ``model.model_validate()`` on read.
168
+
169
+ Returns:
170
+ An :class:`SWRResult` with ``.value``, ``.status``, and an async
171
+ ``.mutate()`` method.
172
+
173
+ Semantics:
174
+ - cache miss: await ``loader()``, store the value, return it
175
+ - fresh hit (age < fresh_for): return the cached value
176
+ - stale hit (fresh_for <= age < max_age): return the cached value
177
+ immediately and trigger a best-effort background refresh
178
+ - expired (age >= max_age): await ``loader()``, store the value, return it
179
+ """
180
+ resolved_fresh_for = min(fresh_for, MAX_CACHE_TTL)
181
+ resolved_max_age = _resolve_swr_max_age(max_age)
182
+ fresh_for_ms, max_age_ms, resolved_max_age = _validate_swr_windows(
183
+ resolved_fresh_for, resolved_max_age
184
+ )
185
+ cache_key = _swr_cache_key(key)
186
+
187
+ # When a pydantic model is provided, wrap the loader to serialize before
188
+ # storage and deserialize after reads. The internal helpers always deal
189
+ # with plain JSON-compatible values.
190
+ if model is not None and hasattr(model, "model_validate"):
191
+ _original_loader = loader
192
+
193
+ async def _json_loader() -> Any:
194
+ val = await _original_loader()
195
+ return val.model_dump(mode="json")
196
+
197
+ json_loader: Callable[[], Awaitable[Any]] = _json_loader
198
+
199
+ def _deserialize(raw: Any) -> T:
200
+ return cast("T", model.model_validate(raw)) # ty: ignore[call-non-callable]
201
+ else:
202
+ json_loader = loader
203
+
204
+ def _deserialize(raw: Any) -> T:
205
+ return cast("T", raw)
206
+
207
+ def _result(value: T, status: CacheStatus) -> SWRResult[T]:
208
+ return SWRResult(
209
+ value,
210
+ cache_key=cache_key,
211
+ loader=json_loader,
212
+ max_age=resolved_max_age,
213
+ status=status,
214
+ model=model,
215
+ )
216
+
217
+ entry = _parse_swr_entry(await cache_get(cache_key))
218
+ if entry is None:
219
+ raw = await _await_swr_load(cache_key, json_loader, resolved_max_age)
220
+ return _result(_deserialize(raw), "miss")
221
+
222
+ age_ms = max(0, _now_ms() - entry["stored_at_ms"])
223
+ cached_value = _deserialize(entry["value"])
224
+
225
+ if age_ms < fresh_for_ms:
226
+ return _result(cached_value, "fresh")
227
+
228
+ if age_ms < max_age_ms:
229
+ _start_swr_refresh(cache_key, json_loader, resolved_max_age)
230
+ return _result(cached_value, "stale")
231
+
232
+ raw = await _await_swr_load(cache_key, json_loader, resolved_max_age)
233
+ return _result(_deserialize(raw), "expired")
234
+
235
+
236
+ def _clamp_ttl(ttl: timedelta | None) -> timedelta:
237
+ """Normalise caller-supplied TTL: None/0 -> MAX, >MAX -> MAX."""
238
+ if ttl is None or ttl <= timedelta(0):
239
+ return MAX_CACHE_TTL
240
+ return min(ttl, MAX_CACHE_TTL)
241
+
242
+
243
+ def _resolve_swr_max_age(max_age: timedelta | None) -> timedelta:
244
+ if max_age is None:
245
+ return MAX_CACHE_TTL
246
+ if max_age <= _DELTA_ZERO:
247
+ return max_age
248
+ return min(max_age, MAX_CACHE_TTL)
249
+
250
+
251
+ def _swr_cache_key(key: str) -> str:
252
+ return f"{_SWR_KEY_PREFIX}{key}"
253
+
254
+
255
+ def _validate_swr_windows(
256
+ fresh_for: timedelta, max_age: timedelta
257
+ ) -> tuple[int, int, timedelta]:
258
+ if fresh_for < _DELTA_ZERO:
259
+ raise ValueError("fresh_for must be >= 0")
260
+ if max_age <= _DELTA_ZERO:
261
+ raise ValueError("max_age must be > 0")
262
+ if fresh_for > max_age:
263
+ raise ValueError("fresh_for must be <= max_age")
264
+
265
+ return (
266
+ int(fresh_for.total_seconds() * 1000),
267
+ int(max_age.total_seconds() * 1000),
268
+ max_age,
269
+ )
270
+
271
+
272
+ def _now_ms() -> int:
273
+ return time.time_ns() // 1_000_000
274
+
275
+
276
+ def _parse_swr_entry(value: Any) -> _SWREntry | None:
277
+ if not isinstance(value, dict):
278
+ return None
279
+
280
+ version = value.get("v")
281
+ stored_at_ms = value.get("stored_at_ms")
282
+ if version != _SWR_SCHEMA_VERSION or not isinstance(stored_at_ms, int):
283
+ return None
284
+ if "value" not in value:
285
+ return None
286
+
287
+ return {
288
+ "v": _SWR_SCHEMA_VERSION,
289
+ "value": value["value"],
290
+ "stored_at_ms": stored_at_ms,
291
+ }
292
+
293
+
294
+ def _acquire_swr_state(cache_key: str) -> _SWRState:
295
+ state = _SWR_STATES.get(cache_key)
296
+ if state is None:
297
+ state = _SWRState()
298
+ _SWR_STATES[cache_key] = state
299
+ state.users += 1
300
+ return state
301
+
302
+
303
+ def _release_swr_state(cache_key: str, state: _SWRState) -> None:
304
+ state.users -= 1
305
+ _maybe_cleanup_swr_state(cache_key, state)
306
+
307
+
308
+ def _maybe_cleanup_swr_state(cache_key: str, state: _SWRState) -> None:
309
+ if (
310
+ state.users == 0
311
+ and state.task is None
312
+ and not state.write_lock.locked()
313
+ and _SWR_STATES.get(cache_key) is state
314
+ ):
315
+ _SWR_STATES.pop(cache_key, None)
316
+
317
+
318
+ async def _cache_swr_entry(cache_key: str, value: Any, ttl: timedelta) -> None:
319
+ entry: _SWREntry = {
320
+ "v": _SWR_SCHEMA_VERSION,
321
+ "value": value,
322
+ "stored_at_ms": _now_ms(),
323
+ }
324
+ await cache_set(cache_key, entry, ttl=ttl)
325
+
326
+
327
+ async def _write_swr_value(cache_key: str, value: Any, ttl: timedelta) -> None:
328
+ state = _acquire_swr_state(cache_key)
329
+ try:
330
+ async with state.write_lock:
331
+ state.write_epoch += 1
332
+ await _cache_swr_entry(cache_key, value, ttl)
333
+ finally:
334
+ _release_swr_state(cache_key, state)
335
+
336
+
337
+ async def _store_loaded_swr_value(
338
+ cache_key: str, value: Any, ttl: timedelta, *, start_epoch: int
339
+ ) -> bool:
340
+ state = _acquire_swr_state(cache_key)
341
+ try:
342
+ async with state.write_lock:
343
+ if start_epoch != state.write_epoch:
344
+ return False
345
+ await _cache_swr_entry(cache_key, value, ttl)
346
+ return True
347
+ finally:
348
+ _release_swr_state(cache_key, state)
349
+
350
+
351
+ async def _load_and_store_swr_value(
352
+ cache_key: str,
353
+ loader: Callable[[], Awaitable[T]],
354
+ ttl: timedelta,
355
+ *,
356
+ start_epoch: int,
357
+ ) -> T:
358
+ value = await loader()
359
+ if await _store_loaded_swr_value(cache_key, value, ttl, start_epoch=start_epoch):
360
+ return value
361
+
362
+ entry = _parse_swr_entry(await cache_get(cache_key))
363
+ if entry is not None:
364
+ return cast("T", entry["value"])
365
+ return value
366
+
367
+
368
+ def _ensure_swr_load_task(
369
+ cache_key: str,
370
+ loader: Callable[[], Awaitable[T]],
371
+ ttl: timedelta,
372
+ *,
373
+ log_errors: bool,
374
+ ) -> asyncio.Task[T]:
375
+ state = _acquire_swr_state(cache_key)
376
+ try:
377
+ existing = state.task
378
+ if existing is not None and not existing.done():
379
+ return cast("asyncio.Task[T]", existing)
380
+
381
+ task = asyncio.create_task(
382
+ _load_and_store_swr_value(
383
+ cache_key, loader, ttl, start_epoch=state.write_epoch
384
+ )
385
+ )
386
+ state.task = task
387
+
388
+ def _cleanup(done: asyncio.Task[Any]) -> None:
389
+ cleanup_state = _SWR_STATES.get(cache_key)
390
+ if cleanup_state is not None and cleanup_state.task is done:
391
+ cleanup_state.task = None
392
+ _maybe_cleanup_swr_state(cache_key, cleanup_state)
393
+ try:
394
+ done.result()
395
+ except Exception:
396
+ if log_errors:
397
+ logger.debug(
398
+ "Background swr refresh failed for %s",
399
+ cache_key,
400
+ exc_info=True,
401
+ )
402
+
403
+ task.add_done_callback(_cleanup)
404
+ return task
405
+ finally:
406
+ _release_swr_state(cache_key, state)
407
+
408
+
409
+ async def _await_swr_load(
410
+ cache_key: str, loader: Callable[[], Awaitable[T]], ttl: timedelta
411
+ ) -> T:
412
+ return await _ensure_swr_load_task(cache_key, loader, ttl, log_errors=False)
413
+
414
+
415
+ def _start_swr_refresh(
416
+ cache_key: str, loader: Callable[[], Awaitable[Any]], ttl: timedelta
417
+ ) -> None:
418
+ _ensure_swr_load_task(cache_key, loader, ttl, log_errors=True)
@@ -135,7 +135,7 @@ def run_server(
135
135
  mount_prefix = os.environ.get("LANGGRAPH_MOUNT_PREFIX")
136
136
  if isinstance(env, str | pathlib.Path):
137
137
  try:
138
- from dotenv.main import ( # type: ignore[unresolved-import] # noqa: PLC0415
138
+ from dotenv.main import ( # noqa: PLC0415
139
139
  DotEnv,
140
140
  )
141
141
 
@@ -149,7 +149,7 @@ def run_server(
149
149
 
150
150
  if debug_port is not None:
151
151
  try:
152
- import debugpy # type: ignore[unresolved-import] # noqa: PLC0415
152
+ import debugpy # noqa: PLC0415 # ty: ignore[unresolved-import]
153
153
  except ImportError:
154
154
  logger.warning("debugpy is not installed. Debugging will not be available.")
155
155
  logger.info("To enable debugging, install debugpy: pip install debugpy")
@@ -226,7 +226,7 @@ def run_server(
226
226
  if k in to_patch:
227
227
  logger.debug(f"Skipping loaded env var {k}={v}")
228
228
  continue
229
- to_patch[k] = v # type: ignore[invalid-assignment]
229
+ to_patch[k] = v
230
230
  with patch_environment(
231
231
  **to_patch,
232
232
  ):
@@ -21,7 +21,7 @@ def map_cmd(cmd: RunCommand) -> Command:
21
21
  update=update,
22
22
  goto=(
23
23
  [
24
- it if isinstance(it, str) else Send(it["node"], it["input"]) # type: ignore[non-subscriptable]
24
+ it if isinstance(it, str) else Send(it["node"], it["input"])
25
25
  for it in goto
26
26
  ]
27
27
  if goto
@@ -87,7 +87,7 @@ async def cron_scheduler():
87
87
  )
88
88
 
89
89
  if on_run_completed == "keep":
90
- run_payload.setdefault("on_completion", "keep") # type: ignore[union-attr]
90
+ run_payload.setdefault("on_completion", "keep")
91
91
 
92
92
  run_payload["metadata"] = get_metadata_from_payload(
93
93
  cron, run_payload
@@ -11,7 +11,7 @@ from typing import Any
11
11
  # Request-scoped encryption context
12
12
  # Set by API middleware when X-Encryption-Context header is present
13
13
  # Accessed by serializers during checkpoint encryption/decryption
14
- encryption_context: ContextVar[dict[str, Any] | None] = ContextVar( # type: ignore[assignment]
14
+ encryption_context: ContextVar[dict[str, Any] | None] = ContextVar(
15
15
  "encryption_context", default=None
16
16
  )
17
17
 
@@ -539,7 +539,7 @@ async def decrypt_response(
539
539
  )
540
540
  result["error"] = json_loads(error_bytes)
541
541
  return result
542
- return obj # type: ignore[return-value]
542
+ return obj
543
543
 
544
544
  result = dict(obj)
545
545
  await _decrypt_object(result, model_type, fields, encryption_instance)
@@ -595,9 +595,9 @@ async def decrypt_responses(
595
595
  result["error"] = json_loads(error_bytes)
596
596
  results.append(result)
597
597
  else:
598
- results.append(obj) # type: ignore[arg-type]
598
+ results.append(obj)
599
599
  return results
600
- return objects # type: ignore[return-value]
600
+ return objects
601
601
 
602
602
  results = [dict(obj) for obj in objects]
603
603
  await asyncio.gather(
@@ -728,7 +728,7 @@ async def encrypt_request(
728
728
  """
729
729
  encryption_instance = get_encryption()
730
730
  if encryption_instance is None:
731
- return data # type: ignore[return-value]
731
+ return data
732
732
 
733
733
  result = dict(data)
734
734
  encrypted_fields = await asyncio.gather(
@@ -557,7 +557,7 @@ def _graph_from_spec(spec: GraphSpec) -> GraphValue:
557
557
  raise ValueError(f"Could not find python file for graph: {spec}")
558
558
  module = importlib.util.module_from_spec(modspec)
559
559
  sys.modules[modname] = module
560
- modspec.loader.exec_module(module) # type: ignore[possibly-unbound-attribute]
560
+ modspec.loader.exec_module(module)
561
561
  except ImportError as e:
562
562
  e.add_note(f"Could not import python module for graph:\n{spec}")
563
563
  if lg_api_config.API_VARIANT == "local_dev":
@@ -665,7 +665,7 @@ def _graph_from_spec(spec: GraphSpec) -> GraphValue:
665
665
  @functools.lru_cache(maxsize=1)
666
666
  def _get_init_embeddings() -> Callable[[str, ...], "Embeddings"] | None:
667
667
  try:
668
- from langchain.embeddings import ( # type: ignore[unresolved-import] # noqa: PLC0415
668
+ from langchain.embeddings import ( # noqa: PLC0415 # ty: ignore[unresolved-import]
669
669
  init_embeddings,
670
670
  )
671
671
 
@@ -730,7 +730,7 @@ def resolve_embeddings(index_config: dict) -> "Embeddings":
730
730
  )
731
731
  module = importlib.util.module_from_spec(modspec)
732
732
  sys.modules[modname] = module
733
- modspec.loader.exec_module(module) # type: ignore[possibly-unbound-attribute]
733
+ modspec.loader.exec_module(module)
734
734
  else:
735
735
  # Load from Python module
736
736
  module = importlib.import_module(module_name)
@@ -6,8 +6,8 @@ import threading
6
6
  import time
7
7
 
8
8
  import structlog
9
- from grpc import aio # type: ignore[import]
10
- from grpc_health.v1 import health_pb2, health_pb2_grpc # type: ignore[import]
9
+ from grpc import aio
10
+ from grpc_health.v1 import health_pb2, health_pb2_grpc
11
11
  from langgraph_grpc_common.proto.checkpointer_pb2_grpc import CheckpointerStub
12
12
  from langgraph_grpc_common.proto.core_api_pb2_grpc import (
13
13
  AdminStub,
@@ -87,7 +87,7 @@ class Assistants(Authenticated):
87
87
  sort_order: str | None = None,
88
88
  select: list[AssistantSelectField] | None = None,
89
89
  ctx: Any = None,
90
- ) -> tuple[AsyncIterator[Assistant], int | None]: # type: ignore[return-value]
90
+ ) -> tuple[AsyncIterator[Assistant], int | None]:
91
91
  """Search assistants via gRPC."""
92
92
  # Handle auth filters
93
93
  auth_filters = await Assistants.handle_event(
@@ -139,7 +139,7 @@ class Assistants(Authenticated):
139
139
  conn, # Not used in gRPC implementation
140
140
  assistant_id: UUID | str,
141
141
  ctx: Any = None,
142
- ) -> AsyncIterator[Assistant]: # type: ignore[return-value]
142
+ ) -> AsyncIterator[Assistant]:
143
143
  """Get assistant by ID via gRPC."""
144
144
  # Handle auth filters
145
145
  auth_filters = await Assistants.handle_event(
@@ -177,7 +177,7 @@ class Assistants(Authenticated):
177
177
  description: str | None = None,
178
178
  ctx: Any = None,
179
179
  system: bool = False,
180
- ) -> AsyncIterator[Assistant]: # type: ignore[return-value]
180
+ ) -> AsyncIterator[Assistant]:
181
181
  """Create/update assistant via gRPC."""
182
182
  metadata = metadata if metadata is not None else {}
183
183
  config = config if config is not None else Config()
@@ -240,7 +240,7 @@ class Assistants(Authenticated):
240
240
  name: str | None = None,
241
241
  description: str | None = None,
242
242
  ctx: Any = None,
243
- ) -> AsyncIterator[Assistant]: # type: ignore[return-value]
243
+ ) -> AsyncIterator[Assistant]:
244
244
  """Update assistant via gRPC."""
245
245
  metadata = metadata if metadata is not None else {}
246
246
  config = config if config is not None else Config()
@@ -295,7 +295,7 @@ class Assistants(Authenticated):
295
295
  ctx: Any = None,
296
296
  *,
297
297
  delete_threads: bool = False,
298
- ) -> AsyncIterator[UUID]: # type: ignore[return-value]
298
+ ) -> AsyncIterator[UUID]:
299
299
  """Delete assistant via gRPC."""
300
300
  # Handle auth filters
301
301
  auth_filters = await Assistants.handle_event(
@@ -324,7 +324,7 @@ class Assistants(Authenticated):
324
324
  assistant_id: UUID | str,
325
325
  version: int,
326
326
  ctx: Any = None,
327
- ) -> AsyncIterator[Assistant]: # type: ignore[return-value]
327
+ ) -> AsyncIterator[Assistant]:
328
328
  """Set latest version of assistant via gRPC."""
329
329
  # Handle auth filters
330
330
  auth_filters = await Assistants.handle_event(
@@ -362,7 +362,7 @@ class Assistants(Authenticated):
362
362
  limit: int,
363
363
  offset: int,
364
364
  ctx: Any = None,
365
- ) -> AsyncIterator[Assistant]: # type: ignore[return-value]
365
+ ) -> AsyncIterator[Assistant]:
366
366
  """Get all versions of assistant via gRPC."""
367
367
  # Handle auth filters
368
368
  auth_filters = await Assistants.handle_event(
@@ -412,7 +412,7 @@ class Assistants(Authenticated):
412
412
  name: str | None = None,
413
413
  metadata: MetadataInput = None,
414
414
  ctx: Any = None,
415
- ) -> int: # type: ignore[return-value]
415
+ ) -> int:
416
416
  """Count assistants via gRPC."""
417
417
  # Handle auth filters
418
418
  auth_filters = await Assistants.handle_event(