langgraph-api 0.14.0.dev1__tar.gz → 0.14.0.dev2__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.14.0.dev1 → langgraph_api-0.14.0.dev2}/PKG-INFO +2 -2
  2. langgraph_api-0.14.0.dev2/langgraph_api/__init__.py +1 -0
  3. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/api/a2a.py +261 -34
  4. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/api/assistants.py +39 -4
  5. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/grpc/ops/assistants.py +4 -1
  6. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/package.json +1 -1
  7. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/yarn.lock +4 -4
  8. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/metrics_otlp.py +1 -1
  9. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/conversion/checkpoint.py +1 -2
  10. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/conversion/value.py +1 -2
  11. langgraph_api-0.14.0.dev2/langgraph_grpc_common/proto/core_api_pb2.py +274 -0
  12. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/core_api_pb2.pyi +10 -2
  13. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/pyproject.toml +1 -1
  14. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/uv.lock +49 -49
  15. langgraph_api-0.14.0.dev1/langgraph_api/__init__.py +0 -1
  16. langgraph_api-0.14.0.dev1/langgraph_grpc_common/proto/core_api_pb2.py +0 -274
  17. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/.gitignore +0 -0
  18. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/LICENSE +0 -0
  19. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/Makefile +0 -0
  20. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/README.md +0 -0
  21. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/.gitignore +0 -0
  22. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/Makefile +0 -0
  23. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/README.md +0 -0
  24. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/benchmark-runners/assistant.ts +0 -0
  25. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/benchmark-runners/benchmark-runner.ts +0 -0
  26. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/benchmark-runners/benchmark_profiles.ts +0 -0
  27. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/benchmark-runners/benchmarks.ts +0 -0
  28. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/benchmark-runners/cancel_first_second_completes.ts +0 -0
  29. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/benchmark-runners/enqueued_runs_order.ts +0 -0
  30. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/benchmark-runners/log-failure.ts +0 -0
  31. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/benchmark-runners/meta_workload.ts +0 -0
  32. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/benchmark-runners/store.ts +0 -0
  33. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/benchmark-runners/stream_write.ts +0 -0
  34. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/benchmark-runners/thread.ts +0 -0
  35. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/benchmark-runners/thread_runs_metadata_search.ts +0 -0
  36. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/benchmark-runners/threads_search_metadata.ts +0 -0
  37. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/benchmark-runners/types.ts +0 -0
  38. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/benchmark-runners/wait_write.ts +0 -0
  39. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/clean-cli.js +0 -0
  40. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/clean.js +0 -0
  41. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/continuous/README.md +0 -0
  42. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/continuous/pyproject.toml +0 -0
  43. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/continuous/runner.py +0 -0
  44. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/continuous/uv.lock +0 -0
  45. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/graphs.js +0 -0
  46. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/package.json +0 -0
  47. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/ramp.js +0 -0
  48. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/reporting/dd_reporting.py +0 -0
  49. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/staircase.py +0 -0
  50. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/staircase_step_k6.js +0 -0
  51. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/tsconfig.json +0 -0
  52. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/update-revision.js +0 -0
  53. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/weather.js +0 -0
  54. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/benchmark/yarn.lock +0 -0
  55. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/constraints.txt +0 -0
  56. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/custom_store.sql +0 -0
  57. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/forbidden.txt +0 -0
  58. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/hatch_build.py +0 -0
  59. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/healthcheck.py +0 -0
  60. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph-cloud-debugging-20260210132856.zip +0 -0
  61. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/_checkpointer/__init__.py +0 -0
  62. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/_checkpointer/_adapter.py +0 -0
  63. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/_checkpointer/protocol.py +0 -0
  64. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/_factory_utils.py +0 -0
  65. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/api/__init__.py +0 -0
  66. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/api/event_streaming.py +0 -0
  67. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/api/mcp/__init__.py +0 -0
  68. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/api/mcp/_constants.py +0 -0
  69. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/api/mcp/_handlers.py +0 -0
  70. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/api/mcp/_models.py +0 -0
  71. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/api/mcp/_routes.py +0 -0
  72. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/api/mcp/_sanitizers.py +0 -0
  73. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/api/meta.py +0 -0
  74. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/api/openapi.py +0 -0
  75. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/api/profile.py +0 -0
  76. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/api/runs.py +0 -0
  77. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/api/store.py +0 -0
  78. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/api/threads.py +0 -0
  79. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/api/ui.py +0 -0
  80. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/asgi_transport.py +0 -0
  81. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/asyncio.py +0 -0
  82. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/auth/__init__.py +0 -0
  83. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/auth/custom.py +0 -0
  84. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/auth/errors.py +0 -0
  85. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/auth/langsmith/__init__.py +0 -0
  86. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/auth/langsmith/backend.py +0 -0
  87. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/auth/langsmith/client.py +0 -0
  88. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/auth/middleware.py +0 -0
  89. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/auth/noop.py +0 -0
  90. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/auth/studio_user.py +0 -0
  91. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/cache.py +0 -0
  92. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/cli.py +0 -0
  93. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/command.py +0 -0
  94. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/config/__init__.py +0 -0
  95. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/config/_parse.py +0 -0
  96. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/config/schemas.py +0 -0
  97. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/cron_scheduler.py +0 -0
  98. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/encryption/__init__.py +0 -0
  99. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/encryption/aes_json.py +0 -0
  100. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/encryption/context.py +0 -0
  101. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/encryption/custom.py +0 -0
  102. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/encryption/middleware.py +0 -0
  103. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/encryption/shared.py +0 -0
  104. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/errors.py +0 -0
  105. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/event_streaming/__init__.py +0 -0
  106. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/event_streaming/capabilities.py +0 -0
  107. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/event_streaming/constants.py +0 -0
  108. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/event_streaming/event_normalizers.py +0 -0
  109. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/event_streaming/namespace.py +0 -0
  110. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/event_streaming/service.py +0 -0
  111. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/event_streaming/session.py +0 -0
  112. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/event_streaming/state_normalizers.py +0 -0
  113. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/event_streaming/types.py +0 -0
  114. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/feature_flags.py +0 -0
  115. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/graph.py +0 -0
  116. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/grpc/__init__.py +0 -0
  117. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/grpc/client.py +0 -0
  118. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/grpc/generated/core_api_pb2.pyi +0 -0
  119. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/grpc/ops/__init__.py +0 -0
  120. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/grpc/ops/cache.py +0 -0
  121. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/grpc/ops/crons.py +0 -0
  122. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/grpc/ops/runs.py +0 -0
  123. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/grpc/ops/threads.py +0 -0
  124. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/grpc/server.py +0 -0
  125. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/grpc/servicers/__init__.py +0 -0
  126. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/grpc/servicers/checkpointer.py +0 -0
  127. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/grpc/servicers/encryption.py +0 -0
  128. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/http.py +0 -0
  129. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/http_metrics.py +0 -0
  130. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/http_metrics_utils.py +0 -0
  131. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/.gitignore +0 -0
  132. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/.prettierrc +0 -0
  133. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/.yarnclean +0 -0
  134. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/__init__.py +0 -0
  135. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/base.py +0 -0
  136. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/build.mts +0 -0
  137. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/client.http.mts +0 -0
  138. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/client.mts +0 -0
  139. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/errors.py +0 -0
  140. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/global.d.ts +0 -0
  141. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/remote.py +0 -0
  142. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/schema.py +0 -0
  143. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/src/graph.mts +0 -0
  144. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/src/load.hooks.mjs +0 -0
  145. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/src/preload.mjs +0 -0
  146. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/src/utils/experiment-tracing.mts +0 -0
  147. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/src/utils/files.mts +0 -0
  148. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/src/utils/importMap.mts +0 -0
  149. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
  150. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/src/utils/serde.mts +0 -0
  151. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/sse.py +0 -0
  152. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/traceblock.mts +0 -0
  153. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/tsconfig.json +0 -0
  154. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/js/ui.py +0 -0
  155. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/lc_security/__init__.py +0 -0
  156. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/lc_security/exceptions.py +0 -0
  157. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/lc_security/policy.py +0 -0
  158. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/lc_security/transport.py +0 -0
  159. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/logging.py +0 -0
  160. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/metadata.py +0 -0
  161. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/metrics_collector.py +0 -0
  162. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/middleware/__init__.py +0 -0
  163. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/middleware/ensure_store.py +0 -0
  164. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/middleware/http_logger.py +0 -0
  165. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/middleware/private_network.py +0 -0
  166. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/middleware/request_id.py +0 -0
  167. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/models/__init__.py +0 -0
  168. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/models/run.py +0 -0
  169. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/otel_context.py +0 -0
  170. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/patch.py +0 -0
  171. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/queue_entrypoint.py +0 -0
  172. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/release_tags.py +0 -0
  173. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/route.py +0 -0
  174. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/schema.py +0 -0
  175. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/self_hosted_logs.py +0 -0
  176. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/self_hosted_metrics.py +0 -0
  177. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/serde.py +0 -0
  178. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/server.py +0 -0
  179. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/sse.py +0 -0
  180. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/state.py +0 -0
  181. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/store.py +0 -0
  182. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/stream.py +0 -0
  183. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/stream_v2.py +0 -0
  184. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/timing/__init__.py +0 -0
  185. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/timing/profiler.py +0 -0
  186. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/timing/timer.py +0 -0
  187. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/traceblock.py +0 -0
  188. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/tracing_session.py +0 -0
  189. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/tunneling/cloudflare.py +0 -0
  190. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/utils/__init__.py +0 -0
  191. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/utils/cache.py +0 -0
  192. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/utils/config.py +0 -0
  193. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/utils/errors.py +0 -0
  194. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/utils/extract.py +0 -0
  195. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/utils/future.py +0 -0
  196. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/utils/headers.py +0 -0
  197. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/utils/network.py +0 -0
  198. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/utils/retriable_client.py +0 -0
  199. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/utils/stream_codec.py +0 -0
  200. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/utils/uuids.py +0 -0
  201. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/validation.py +0 -0
  202. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/webhook.py +0 -0
  203. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_api/worker.py +0 -0
  204. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/__init__.py +0 -0
  205. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/checkpointer.py +0 -0
  206. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/conversion/__init__.py +0 -0
  207. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/conversion/_compat.py +0 -0
  208. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/conversion/config.py +0 -0
  209. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/conversion/durability.py +0 -0
  210. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/conversion/store.py +0 -0
  211. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/conversion/struct.py +0 -0
  212. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/__init__.py +0 -0
  213. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/checkpointer_pb2.py +0 -0
  214. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/checkpointer_pb2.pyi +0 -0
  215. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.py +0 -0
  216. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/checkpointer_pb2_grpc.pyi +0 -0
  217. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/core_api_pb2_grpc.py +0 -0
  218. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/core_api_pb2_grpc.pyi +0 -0
  219. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/encryption_pb2.py +0 -0
  220. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/encryption_pb2.pyi +0 -0
  221. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/encryption_pb2_grpc.py +0 -0
  222. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/encryption_pb2_grpc.pyi +0 -0
  223. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/engine_common_pb2.py +0 -0
  224. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/engine_common_pb2.pyi +0 -0
  225. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/engine_common_pb2_grpc.py +0 -0
  226. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/engine_common_pb2_grpc.pyi +0 -0
  227. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.py +0 -0
  228. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2.pyi +0 -0
  229. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.py +0 -0
  230. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_cancel_run_action_pb2_grpc.pyi +0 -0
  231. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_control_signal_pb2.py +0 -0
  232. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_control_signal_pb2.pyi +0 -0
  233. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.py +0 -0
  234. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_control_signal_pb2_grpc.pyi +0 -0
  235. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.py +0 -0
  236. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2.pyi +0 -0
  237. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.py +0 -0
  238. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_cron_on_run_completed_pb2_grpc.pyi +0 -0
  239. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_durability_pb2.py +0 -0
  240. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_durability_pb2.pyi +0 -0
  241. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.py +0 -0
  242. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_durability_pb2_grpc.pyi +0 -0
  243. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.py +0 -0
  244. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2.pyi +0 -0
  245. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.py +0 -0
  246. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_multitask_strategy_pb2_grpc.pyi +0 -0
  247. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_run_status_pb2.py +0 -0
  248. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_run_status_pb2.pyi +0 -0
  249. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.py +0 -0
  250. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_run_status_pb2_grpc.pyi +0 -0
  251. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_stream_mode_pb2.py +0 -0
  252. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_stream_mode_pb2.pyi +0 -0
  253. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.py +0 -0
  254. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_stream_mode_pb2_grpc.pyi +0 -0
  255. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_thread_status_pb2.py +0 -0
  256. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_thread_status_pb2.pyi +0 -0
  257. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.py +0 -0
  258. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_thread_status_pb2_grpc.pyi +0 -0
  259. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.py +0 -0
  260. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2.pyi +0 -0
  261. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.py +0 -0
  262. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/enum_thread_stream_mode_pb2_grpc.pyi +0 -0
  263. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/errors_pb2.py +0 -0
  264. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/errors_pb2.pyi +0 -0
  265. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/errors_pb2_grpc.py +0 -0
  266. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/errors_pb2_grpc.pyi +0 -0
  267. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/store_pb2.py +0 -0
  268. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/store_pb2.pyi +0 -0
  269. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/store_pb2_grpc.py +0 -0
  270. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/proto/store_pb2_grpc.pyi +0 -0
  271. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/serde.py +0 -0
  272. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_grpc_common/store.py +0 -0
  273. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_license/__init__.py +0 -0
  274. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_license/validation.py +0 -0
  275. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_runtime/__init__.py +0 -0
  276. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_runtime/checkpoint.py +0 -0
  277. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_runtime/database.py +0 -0
  278. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_runtime/lifespan.py +0 -0
  279. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_runtime/metrics.py +0 -0
  280. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_runtime/ops.py +0 -0
  281. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_runtime/queue.py +0 -0
  282. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_runtime/retry.py +0 -0
  283. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_runtime/routes.py +0 -0
  284. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/langgraph_runtime/store.py +0 -0
  285. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/logging.json +0 -0
  286. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/openapi.json +0 -0
  287. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/scripts/build_wheel.py +0 -0
  288. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/scripts/create_license.py +0 -0
  289. {langgraph_api-0.14.0.dev1 → langgraph_api-0.14.0.dev2}/scripts/run_a2a_tck.py +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langgraph-api
3
- Version: 0.14.0.dev1
3
+ Version: 0.14.0.dev2
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
7
7
  Requires-Python: >=3.11
8
8
  Requires-Dist: cloudpickle>=3.0.0
9
- Requires-Dist: cryptography>=42.0.0
9
+ Requires-Dist: cryptography>=50.0.0
10
10
  Requires-Dist: grpcio-health-checking<1.82.0,>=1.81.0
11
11
  Requires-Dist: grpcio-tools==1.81.1
12
12
  Requires-Dist: grpcio<1.82.0,>=1.81.0
@@ -0,0 +1 @@
1
+ __version__ = "0.14.0.dev2"
@@ -11,6 +11,8 @@ Push notifications are not implemented.
11
11
  """
12
12
 
13
13
  import asyncio
14
+ import base64
15
+ import binascii
14
16
  import functools
15
17
  import os
16
18
  import uuid
@@ -92,6 +94,13 @@ ERROR_CODE_INVALID_AGENT_RESPONSE = -32006
92
94
  # ============================================================================
93
95
 
94
96
  A2A_PROTOCOL_VERSION = "1.0"
97
+ _DEFAULT_A2A_INPUT_MODES = ("application/json", "text/plain")
98
+ _DEFAULT_A2A_OUTPUT_MODES = ("application/json", "text/plain")
99
+
100
+
101
+ class InvalidAgentResponseError(ValueError):
102
+ """Raised when public agent output cannot be represented as an A2A part."""
103
+
95
104
 
96
105
  # ============================================================================
97
106
  # Legacy (v0.x) format helpers
@@ -592,6 +601,7 @@ _AGENT_MESSAGE_TYPES = {"ai", "aimessage", "aimessagechunk"}
592
601
  _ROLE_DEFINED_MESSAGE_TYPES = {"chat", "chatmessage", "chatmessagechunk"}
593
602
  _USER_MESSAGE_ROLES = {"human", "user"}
594
603
  _AGENT_MESSAGE_ROLES = {"agent", "assistant"}
604
+ _MEDIA_CONTENT_BLOCK_TYPES = {"audio", "file", "image", "video"}
595
605
 
596
606
 
597
607
  def _normalize_message_label(value: Any) -> str:
@@ -630,6 +640,117 @@ def _a2a_role_for_message(
630
640
  return type_role or role_role
631
641
 
632
642
 
643
+ def _content_block_to_a2a_file_part(block: dict[str, Any]) -> dict[str, Any]:
644
+ """Convert one canonical LangChain media block to an A2A FilePart."""
645
+
646
+ source = next(
647
+ (key for key in ("base64", "data", "url") if block.get(key) is not None),
648
+ None,
649
+ )
650
+ if source is None:
651
+ raise InvalidAgentResponseError(
652
+ "Media content blocks must contain 'base64', 'data', or 'url'."
653
+ )
654
+
655
+ value = block[source]
656
+ file_obj: dict[str, Any] = {}
657
+ if source == "url":
658
+ if not isinstance(value, str) or not value:
659
+ raise InvalidAgentResponseError(
660
+ "Media content block 'url' must be a non-empty string."
661
+ )
662
+ file_obj["uri"] = value
663
+ else:
664
+ if source == "data" and isinstance(value, (bytes, bytearray)):
665
+ value = base64.b64encode(value).decode("ascii")
666
+ if not isinstance(value, str):
667
+ raise InvalidAgentResponseError(
668
+ f"Media content block '{source}' must be base64-encoded text or bytes."
669
+ )
670
+ compact_value = "".join(value.split())
671
+ padded_value = compact_value + ("=" * (-len(compact_value) % 4))
672
+ try:
673
+ decoded = base64.b64decode(
674
+ padded_value,
675
+ altchars=b"-_",
676
+ validate=True,
677
+ )
678
+ except (binascii.Error, ValueError) as e:
679
+ raise InvalidAgentResponseError(
680
+ f"Media content block '{source}' must contain valid base64 data."
681
+ ) from e
682
+ file_obj["bytes"] = base64.b64encode(decoded).decode("ascii")
683
+
684
+ mime_type = block.get("mime_type")
685
+ if mime_type is not None:
686
+ if not isinstance(mime_type, str):
687
+ raise InvalidAgentResponseError(
688
+ "Media content block 'mime_type' must be a string."
689
+ )
690
+ if mime_type:
691
+ file_obj["mimeType"] = mime_type
692
+
693
+ filename = block.get("filename")
694
+ if filename is None:
695
+ extras = block.get("extras")
696
+ if isinstance(extras, dict):
697
+ filename = extras.get("filename")
698
+ if filename is not None:
699
+ if not isinstance(filename, str):
700
+ raise InvalidAgentResponseError(
701
+ "Media content block filename must be a string."
702
+ )
703
+ if filename:
704
+ file_obj["name"] = filename
705
+
706
+ return {"kind": "file", "file": file_obj}
707
+
708
+
709
+ def _content_to_a2a_parts(content: Any) -> list[dict[str, Any]]:
710
+ """Convert public LangChain message content to ordered A2A parts."""
711
+
712
+ if isinstance(content, str):
713
+ return [{"kind": "text", "text": content}]
714
+ if content is None:
715
+ return []
716
+ if not isinstance(content, list):
717
+ return [{"kind": "text", "text": str(content)}]
718
+
719
+ parts: list[dict[str, Any]] = []
720
+ text_parts: list[str] = []
721
+
722
+ def flush_text() -> None:
723
+ if text_parts:
724
+ parts.append({"kind": "text", "text": "".join(text_parts)})
725
+ text_parts.clear()
726
+
727
+ for block in content:
728
+ if isinstance(block, str):
729
+ text_parts.append(block)
730
+ elif isinstance(block, dict) and block.get("type") == "text":
731
+ text = block.get("text")
732
+ if isinstance(text, str):
733
+ text_parts.append(text)
734
+ elif (
735
+ isinstance(block, dict) and block.get("type") in _MEDIA_CONTENT_BLOCK_TYPES
736
+ ):
737
+ flush_text()
738
+ parts.append(_content_block_to_a2a_file_part(block))
739
+
740
+ flush_text()
741
+ return parts
742
+
743
+
744
+ def _a2a_parts_have_content(parts: list[dict[str, Any]]) -> bool:
745
+ """Return whether converted parts contain public text or file content."""
746
+
747
+ return any(
748
+ part.get("kind") == "file"
749
+ or (part.get("kind") == "text" and bool(part.get("text")))
750
+ for part in parts
751
+ )
752
+
753
+
633
754
  def _content_to_text(content: Any) -> str:
634
755
  """Convert public LangChain message content to A2A text."""
635
756
 
@@ -650,41 +771,41 @@ def _content_to_text(content: Any) -> str:
650
771
  return str(content)
651
772
 
652
773
 
653
- def _extract_a2a_response(result: dict[str, Any]) -> str:
654
- """Extract the last assistant message from graph execution result.
774
+ def _extract_a2a_response(result: dict[str, Any]) -> list[dict[str, Any]]:
775
+ """Extract public A2A parts from the last assistant response.
655
776
 
656
777
  Args:
657
778
  result: Graph execution result
658
779
 
659
780
  Returns:
660
- Content of the last assistant message
781
+ Ordered public parts from the last assistant message
661
782
 
662
783
  Raises:
663
784
  ValueError: If result doesn't contain messages or is invalid
664
785
  """
665
786
  if "__error__" in result:
666
787
  # Let the caller handle errors
667
- return str(result)
788
+ return [{"kind": "text", "text": str(result)}]
668
789
 
669
790
  if "messages" not in result:
670
791
  # Fallback to the full result if no messages schema. It is not optimal to do A2A on assistants without
671
792
  # a messages key, but it is not a hard requirement.
672
- return str(result)
793
+ return [{"kind": "text", "text": str(result)}]
673
794
 
674
795
  messages = result["messages"]
675
796
  if not isinstance(messages, list) or not messages:
676
- return str(result)
797
+ return [{"kind": "text", "text": str(result)}]
677
798
 
678
799
  # Find the last assistant message
679
800
  for message in reversed(messages):
680
801
  if not isinstance(message, dict):
681
802
  continue
682
803
  if _a2a_role_for_message(message) == "ROLE_AGENT" and "content" in message:
683
- text = _content_to_text(message["content"])
684
- if text:
685
- return text
804
+ parts = _content_to_a2a_parts(message["content"])
805
+ if _a2a_parts_have_content(parts):
806
+ return parts
686
807
 
687
- return ""
808
+ return [{"kind": "text", "text": ""}]
688
809
 
689
810
 
690
811
  def _create_interrupt_artifact(interrupts: list[dict[str, Any]]) -> dict[str, Any]:
@@ -714,25 +835,27 @@ def _create_interrupt_artifact(interrupts: list[dict[str, Any]]) -> dict[str, An
714
835
  }
715
836
 
716
837
 
717
- def _create_response_artifact(text: str, assistant_id: str) -> dict[str, Any]:
718
- """Create an A2A artifact carrying the agent's final response text.
838
+ def _create_response_artifact(
839
+ parts: list[dict[str, Any]], assistant_id: str
840
+ ) -> dict[str, Any]:
841
+ """Create an A2A artifact carrying the agent's final response parts.
719
842
 
720
843
  Shared by ``message/send`` and ``message/stream`` so both paths return the
721
844
  same first-class Artifact shape. Per A2A spec section 3.7, task outputs
722
845
  SHOULD be returned via Artifacts rather than embedded in a status Message.
723
846
 
724
847
  Args:
725
- text: The final response text (from ``_extract_a2a_response``).
848
+ parts: The final response parts (from ``_extract_a2a_response``).
726
849
  assistant_id: The assistant ID, used only for the description.
727
850
 
728
851
  Returns:
729
- A2A artifact dict with a single text part.
852
+ A2A artifact dict containing the ordered public response parts.
730
853
  """
731
854
  return {
732
855
  "artifactId": str(uuid.uuid4()),
733
856
  "name": "Assistant Response",
734
857
  "description": f"Response from assistant {assistant_id}",
735
- "parts": [{"kind": "text", "text": text}],
858
+ "parts": parts,
736
859
  }
737
860
 
738
861
 
@@ -740,7 +863,7 @@ def _create_response_artifact_update(
740
863
  *,
741
864
  task_id: str,
742
865
  context_id: str,
743
- text: str,
866
+ parts: list[dict[str, Any]],
744
867
  assistant_id: str,
745
868
  ) -> dict[str, Any]:
746
869
  """Create a final streaming update containing the response artifact."""
@@ -749,7 +872,7 @@ def _create_response_artifact_update(
749
872
  "taskId": task_id,
750
873
  "contextId": context_id,
751
874
  "kind": "artifact-update",
752
- "artifact": _create_response_artifact(text, assistant_id),
875
+ "artifact": _create_response_artifact(parts, assistant_id),
753
876
  "append": False,
754
877
  "lastChunk": True,
755
878
  }
@@ -985,14 +1108,16 @@ def _convert_messages_to_a2a_format(
985
1108
 
986
1109
  content = msg.get("content", "")
987
1110
  id = msg.get("id") or str(uuid7())
988
- text = _content_to_text(content)
989
- if a2a_role == "ROLE_AGENT" and not text:
1111
+ parts = _content_to_a2a_parts(content)
1112
+ if a2a_role == "ROLE_AGENT" and not _a2a_parts_have_content(parts):
990
1113
  continue
1114
+ if not parts:
1115
+ parts = [{"kind": "text", "text": ""}]
991
1116
 
992
1117
  a2a_message = {
993
1118
  "kind": "message",
994
1119
  "role": a2a_role,
995
- "parts": [{"kind": "text", "text": text}],
1120
+ "parts": parts,
996
1121
  "messageId": id,
997
1122
  "taskId": task_id,
998
1123
  "contextId": context_id,
@@ -1556,6 +1681,13 @@ async def handle_message_send(
1556
1681
  history_length=history_length,
1557
1682
  )
1558
1683
 
1684
+ except InvalidAgentResponseError as e:
1685
+ return {
1686
+ "error": {
1687
+ "code": ERROR_CODE_INVALID_AGENT_RESPONSE,
1688
+ "message": str(e),
1689
+ }
1690
+ }
1559
1691
  except Exception:
1560
1692
  logger.exception(f"Error in message/send for assistant {assistant_id}")
1561
1693
  return {
@@ -1704,6 +1836,13 @@ async def handle_tasks_get(
1704
1836
  context_id,
1705
1837
  history_length=history_length,
1706
1838
  )
1839
+ except InvalidAgentResponseError as e:
1840
+ return {
1841
+ "error": {
1842
+ "code": ERROR_CODE_INVALID_AGENT_RESPONSE,
1843
+ "message": str(e),
1844
+ }
1845
+ }
1707
1846
  except Exception as e:
1708
1847
  await logger.aexception(
1709
1848
  f"Failed to get thread state for tasks/get: {e}"
@@ -2106,6 +2245,13 @@ async def handle_list_tasks(
2106
2245
  }
2107
2246
  }
2108
2247
 
2248
+ except InvalidAgentResponseError as e:
2249
+ return {
2250
+ "error": {
2251
+ "code": ERROR_CODE_INVALID_AGENT_RESPONSE,
2252
+ "message": str(e),
2253
+ }
2254
+ }
2109
2255
  except Exception:
2110
2256
  logger.exception("Error in ListTasks")
2111
2257
  return {
@@ -2156,6 +2302,60 @@ async def handle_get_extended_card(
2156
2302
  # ============================================================================
2157
2303
 
2158
2304
 
2305
+ def _validate_agent_card_modes(
2306
+ value: Any,
2307
+ *,
2308
+ field: str,
2309
+ default: tuple[str, ...],
2310
+ ) -> list[str]:
2311
+ """Validate one optional assistant A2A media-mode override."""
2312
+
2313
+ if value is None:
2314
+ return list(default)
2315
+ if not isinstance(value, list) or not value:
2316
+ raise ValueError(
2317
+ f"Assistant metadata.a2a.{field} must be a non-empty array of strings."
2318
+ )
2319
+
2320
+ modes: list[str] = []
2321
+ for mode in value:
2322
+ if not isinstance(mode, str) or not mode.strip():
2323
+ raise ValueError(
2324
+ f"Assistant metadata.a2a.{field} must be a non-empty array of strings."
2325
+ )
2326
+ modes.append(mode.strip())
2327
+ return modes
2328
+
2329
+
2330
+ def _resolve_agent_card_modes(
2331
+ assistant: dict[str, Any],
2332
+ ) -> tuple[list[str], list[str]]:
2333
+ """Resolve per-assistant A2A modes with backward-compatible defaults."""
2334
+
2335
+ metadata = assistant.get("metadata") or {}
2336
+ if not isinstance(metadata, dict):
2337
+ raise ValueError("Assistant metadata must be an object.")
2338
+
2339
+ a2a_metadata = metadata.get("a2a")
2340
+ if a2a_metadata is None:
2341
+ return list(_DEFAULT_A2A_INPUT_MODES), list(_DEFAULT_A2A_OUTPUT_MODES)
2342
+ if not isinstance(a2a_metadata, dict):
2343
+ raise ValueError("Assistant metadata.a2a must be an object.")
2344
+
2345
+ return (
2346
+ _validate_agent_card_modes(
2347
+ a2a_metadata.get("input_modes"),
2348
+ field="input_modes",
2349
+ default=_DEFAULT_A2A_INPUT_MODES,
2350
+ ),
2351
+ _validate_agent_card_modes(
2352
+ a2a_metadata.get("output_modes"),
2353
+ field="output_modes",
2354
+ default=_DEFAULT_A2A_OUTPUT_MODES,
2355
+ ),
2356
+ )
2357
+
2358
+
2159
2359
  async def generate_agent_card(request: ApiRequest, assistant_id: str) -> dict[str, Any]:
2160
2360
  """Generate A2A Agent Card for a specific assistant.
2161
2361
 
@@ -2183,6 +2383,7 @@ async def generate_agent_card(request: ApiRequest, assistant_id: str) -> dict[st
2183
2383
  assistant_description = (
2184
2384
  assistant.get("description") or f"{assistant_name} assistant"
2185
2385
  )
2386
+ input_modes, output_modes = _resolve_agent_card_modes(assistant)
2186
2387
 
2187
2388
  # For now, each assistant has one main skill - itself
2188
2389
  skills = [
@@ -2192,8 +2393,8 @@ async def generate_agent_card(request: ApiRequest, assistant_id: str) -> dict[st
2192
2393
  "description": assistant_description,
2193
2394
  "tags": ["assistant", "langgraph"],
2194
2395
  "examples": [],
2195
- "inputModes": ["application/json", "text/plain"],
2196
- "outputModes": ["application/json", "text/plain"],
2396
+ "inputModes": input_modes,
2397
+ "outputModes": output_modes,
2197
2398
  "metadata": {
2198
2399
  "inputSchema": {
2199
2400
  "required": required,
@@ -2242,8 +2443,8 @@ async def generate_agent_card(request: ApiRequest, assistant_id: str) -> dict[st
2242
2443
  "pushNotifications": False, # Not implemented yet
2243
2444
  "stateTransitionHistory": False,
2244
2445
  },
2245
- "defaultInputModes": ["application/json", "text/plain"],
2246
- "defaultOutputModes": ["application/json", "text/plain"],
2446
+ "defaultInputModes": input_modes,
2447
+ "defaultOutputModes": output_modes,
2247
2448
  "skills": skills,
2248
2449
  "version": __version__,
2249
2450
  }
@@ -2558,19 +2759,32 @@ async def handle_message_stream(
2558
2759
  is_interrupt = (
2559
2760
  isinstance(result, dict) and "__interrupt__" in result
2560
2761
  )
2561
- # Extract the final response text (shared by both
2762
+ # Extract the final response parts (shared by both
2562
2763
  # the completed and interrupt paths).
2563
- final_text: str | None = None
2764
+ final_parts: list[dict[str, Any]] | None = None
2564
2765
  if isinstance(result, dict):
2565
2766
  try:
2566
- final_text = _extract_a2a_response(result)
2767
+ final_parts = _extract_a2a_response(result)
2768
+ except InvalidAgentResponseError as e:
2769
+ yield (
2770
+ b"message",
2771
+ {
2772
+ "jsonrpc": "2.0",
2773
+ "id": rpc_id,
2774
+ "error": {
2775
+ "code": ERROR_CODE_INVALID_AGENT_RESPONSE,
2776
+ "message": str(e),
2777
+ },
2778
+ },
2779
+ )
2780
+ return
2567
2781
  except Exception:
2568
2782
  await logger.aexception(
2569
2783
  "Failed to extract final message from result",
2570
2784
  result=result,
2571
2785
  )
2572
- if final_text is None:
2573
- final_text = str(result)
2786
+ if final_parts is None:
2787
+ final_parts = [{"kind": "text", "text": str(result)}]
2574
2788
 
2575
2789
  if is_interrupt:
2576
2790
  # Interrupt path is unchanged: emit the interrupt
@@ -2579,7 +2793,7 @@ async def handle_message_stream(
2579
2793
  final_message = {
2580
2794
  "kind": "message",
2581
2795
  "role": "ROLE_AGENT",
2582
- "parts": [{"kind": "text", "text": final_text}],
2796
+ "parts": final_parts,
2583
2797
  "messageId": str(uuid.uuid4()),
2584
2798
  "taskId": task_id,
2585
2799
  "contextId": context_id,
@@ -2634,7 +2848,7 @@ async def handle_message_stream(
2634
2848
  "result": _create_response_artifact_update(
2635
2849
  task_id=task_id,
2636
2850
  context_id=context_id,
2637
- text=final_text,
2851
+ parts=final_parts,
2638
2852
  assistant_id=assistant_id,
2639
2853
  ),
2640
2854
  },
@@ -2756,13 +2970,26 @@ async def handle_message_stream(
2756
2970
  # its plain terminal status-update.
2757
2971
  if fallback_state == "TASK_STATE_COMPLETED" and isinstance(result, dict):
2758
2972
  try:
2759
- fallback_text = _extract_a2a_response(result)
2973
+ fallback_parts = _extract_a2a_response(result)
2974
+ except InvalidAgentResponseError as e:
2975
+ yield (
2976
+ b"message",
2977
+ {
2978
+ "jsonrpc": "2.0",
2979
+ "id": rpc_id,
2980
+ "error": {
2981
+ "code": ERROR_CODE_INVALID_AGENT_RESPONSE,
2982
+ "message": str(e),
2983
+ },
2984
+ },
2985
+ )
2986
+ return
2760
2987
  except Exception:
2761
2988
  await logger.aexception(
2762
2989
  "Failed to extract final message from result",
2763
2990
  result=result,
2764
2991
  )
2765
- fallback_text = str(result)
2992
+ fallback_parts = [{"kind": "text", "text": str(result)}]
2766
2993
  yield (
2767
2994
  b"message",
2768
2995
  {
@@ -2771,7 +2998,7 @@ async def handle_message_stream(
2771
2998
  "result": _create_response_artifact_update(
2772
2999
  task_id=task_id,
2773
3000
  context_id=context_id,
2774
- text=fallback_text,
3001
+ parts=fallback_parts,
2775
3002
  assistant_id=assistant_id,
2776
3003
  ),
2777
3004
  },
@@ -27,7 +27,13 @@ from langgraph_api.feature_flags import (
27
27
  IS_POSTGRES_OR_GRPC_BACKEND,
28
28
  USE_RUNTIME_CONTEXT_API,
29
29
  )
30
- from langgraph_api.graph import get_assistant_id, get_graph
30
+ from langgraph_api.graph import (
31
+ GRAPHS,
32
+ assert_graph_exists,
33
+ get_assistant_id,
34
+ get_graph,
35
+ graph_exists,
36
+ )
31
37
  from langgraph_api.js.base import BaseRemotePregel
32
38
  from langgraph_api.route import ApiRequest, ApiResponse, ApiRoute
33
39
  from langgraph_api.schema import ASSISTANT_ENCRYPTION_FIELDS, ASSISTANT_FIELDS
@@ -58,6 +64,14 @@ if IS_POSTGRES_OR_GRPC_BACKEND:
58
64
  else:
59
65
  from langgraph_runtime.ops import Assistants
60
66
 
67
+
68
+ def graph_scope() -> dict[str, list[str]]:
69
+ """Restrict assistant reads to the graphs this server has registered."""
70
+ if not IS_POSTGRES_OR_GRPC_BACKEND:
71
+ return {}
72
+ return {"graph_id_allowlist": sorted(GRAPHS)}
73
+
74
+
61
75
  EXCLUDED_CONFIG_SCHEMA = (
62
76
  "__pregel_checkpointer",
63
77
  "__pregel_store",
@@ -187,6 +201,8 @@ async def create_assistant(request: ApiRequest) -> ApiResponse:
187
201
  except jsonschema_rs.ValidationError as e:
188
202
  raise HTTPException(status_code=422, detail=str(e)) from e
189
203
 
204
+ assert_graph_exists(payload["graph_id"])
205
+
190
206
  if IS_POSTGRES_OR_GRPC_BACKEND and using_custom_encryption():
191
207
  effective_payload = payload
192
208
  else:
@@ -227,6 +243,9 @@ async def search_assistants(
227
243
  payload = await request.json(AssistantSearchRequest)
228
244
  select = validate_select_columns(payload.get("select") or None, ASSISTANT_FIELDS)
229
245
  offset = int(payload.get("offset") or 0)
246
+ graph_id = payload.get("graph_id")
247
+ if graph_id is not None:
248
+ assert_graph_exists(graph_id)
230
249
  config = payload.get("config")
231
250
  if config:
232
251
  try:
@@ -236,7 +255,7 @@ async def search_assistants(
236
255
  async with connect() as conn:
237
256
  assistants_iter, next_offset = await Assistants.search(
238
257
  conn,
239
- graph_id=payload.get("graph_id"),
258
+ graph_id=graph_id,
240
259
  name=payload.get("name"),
241
260
  metadata=payload.get("metadata"),
242
261
  limit=int(payload.get("limit") or 10),
@@ -244,6 +263,7 @@ async def search_assistants(
244
263
  sort_by=payload.get("sort_by"),
245
264
  sort_order=payload.get("sort_order"),
246
265
  select=select,
266
+ **graph_scope(),
247
267
  )
248
268
  assistants, response_headers = await get_pagination_headers(
249
269
  assistants_iter, next_offset, offset
@@ -267,12 +287,16 @@ async def count_assistants(
267
287
  ) -> ApiResponse:
268
288
  """Count assistants."""
269
289
  payload = await request.json(AssistantCountRequest)
290
+ graph_id = payload.get("graph_id")
291
+ if graph_id is not None:
292
+ assert_graph_exists(graph_id)
270
293
  async with connect() as conn:
271
294
  count = await Assistants.count(
272
295
  conn,
273
- graph_id=payload.get("graph_id"),
296
+ graph_id=graph_id,
274
297
  name=payload.get("name"),
275
298
  metadata=payload.get("metadata"),
299
+ **graph_scope(),
276
300
  )
277
301
  return ApiResponse(count)
278
302
 
@@ -288,6 +312,12 @@ async def get_assistant(
288
312
  assistant = await Assistants.get(conn, assistant_id)
289
313
 
290
314
  assistant_data = await fetchone(assistant)
315
+ # Assistants outside this server's registry are hidden rather than reported,
316
+ # matching the filter graph_scope() applies to search and count.
317
+ if not graph_exists(assistant_data["graph_id"]):
318
+ raise HTTPException(
319
+ status_code=404, detail=f"assistant {assistant_id} not found"
320
+ )
291
321
  if not IS_POSTGRES_OR_GRPC_BACKEND or using_aes_encryption():
292
322
  assistant_data = await decrypt_response(
293
323
  assistant_data,
@@ -464,6 +494,11 @@ async def patch_assistant(
464
494
  except jsonschema_rs.ValidationError as e:
465
495
  raise HTTPException(status_code=422, detail=str(e)) from e
466
496
 
497
+ # A patch that leaves graph_id alone needs no check.
498
+ graph_id = payload.get("graph_id")
499
+ if graph_id is not None:
500
+ assert_graph_exists(graph_id)
501
+
467
502
  if IS_POSTGRES_OR_GRPC_BACKEND and using_custom_encryption():
468
503
  effective_payload = payload
469
504
  else:
@@ -479,7 +514,7 @@ async def patch_assistant(
479
514
  assistant_id,
480
515
  config=effective_payload.get("config"),
481
516
  context=effective_payload.get("context"),
482
- graph_id=payload.get("graph_id"),
517
+ graph_id=graph_id,
483
518
  metadata=effective_payload.get("metadata"),
484
519
  name=payload.get("name"),
485
520
  description=payload.get("description"),
@@ -86,10 +86,10 @@ class Assistants(Authenticated):
86
86
  sort_by: str | None = None,
87
87
  sort_order: str | None = None,
88
88
  select: list[AssistantSelectField] | None = None,
89
+ graph_id_allowlist: list[str] | None = None,
89
90
  ctx: Any = None,
90
91
  ) -> tuple[AsyncIterator[Assistant], int | None]:
91
92
  """Search assistants via gRPC."""
92
- # Handle auth filters
93
93
  auth_filters = await Assistants.handle_event(
94
94
  ctx,
95
95
  "search",
@@ -112,6 +112,7 @@ class Assistants(Authenticated):
112
112
  sort_order=_map_sort_order(sort_order),
113
113
  select=select,
114
114
  name=name,
115
+ graph_id_allowlist=graph_id_allowlist,
115
116
  )
116
117
 
117
118
  client = await get_shared_client()
@@ -411,6 +412,7 @@ class Assistants(Authenticated):
411
412
  graph_id: str | None = None,
412
413
  name: str | None = None,
413
414
  metadata: MetadataInput = None,
415
+ graph_id_allowlist: list[str] | None = None,
414
416
  ctx: Any = None,
415
417
  ) -> int:
416
418
  """Count assistants via gRPC."""
@@ -425,6 +427,7 @@ class Assistants(Authenticated):
425
427
  graph_id=graph_id,
426
428
  name=name,
427
429
  metadata_json=json_dumpb_optional(metadata),
430
+ graph_id_allowlist=graph_id_allowlist,
428
431
  )
429
432
 
430
433
  client = await get_shared_client()
@@ -7,7 +7,7 @@
7
7
  "format": "prettier --write ."
8
8
  },
9
9
  "dependencies": {
10
- "@hono/node-server": "^2.0.12",
10
+ "@hono/node-server": "^2.1.0",
11
11
  "@hono/zod-validator": "^0.9.0",
12
12
  "@langchain/core": "^1.2.3",
13
13
  "@langchain/langgraph": "^1.4.9",