langgraph-cli 0.4.25__tar.gz → 0.4.27__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 (149) hide show
  1. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/PKG-INFO +2 -2
  2. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-examples/yarn.lock +4 -5
  3. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-monorepo-example/package.json +1 -1
  4. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-monorepo-example/yarn.lock +43 -44
  5. langgraph_cli-0.4.27/langgraph_cli/__init__.py +1 -0
  6. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/langgraph_cli/config.py +20 -2
  7. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/langgraph_cli/deploy.py +45 -1
  8. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/pyproject.toml +1 -1
  9. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/test_config.py +17 -0
  10. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/test_deploy_helpers.py +155 -0
  11. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/uv-examples/monorepo/apps/agent/pyproject.toml +1 -0
  12. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/uv-examples/monorepo/pyproject.toml +2 -1
  13. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/uv-examples/monorepo/uv.lock +76 -10
  14. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/uv-examples/simple/pyproject.toml +1 -1
  15. langgraph_cli-0.4.27/uv-examples/simple/uv.lock +988 -0
  16. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/uv.lock +26 -13
  17. langgraph_cli-0.4.25/langgraph_cli/__init__.py +0 -1
  18. langgraph_cli-0.4.25/uv-examples/simple/uv.lock +0 -864
  19. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/.gitignore +0 -0
  20. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/LICENSE +0 -0
  21. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/Makefile +0 -0
  22. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/README.md +0 -0
  23. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/.env.example +0 -0
  24. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/.gitignore +0 -0
  25. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/Makefile +0 -0
  26. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graph_prerelease_reqs/agent.py +0 -0
  27. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graph_prerelease_reqs/deps/additional_deps/pyproject.toml +0 -0
  28. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graph_prerelease_reqs/deps/zuper_deps/pyproject.toml +0 -0
  29. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graph_prerelease_reqs/langgraph.json +0 -0
  30. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graph_prerelease_reqs/pyproject.toml +0 -0
  31. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graph_prerelease_reqs_fail/agent.py +0 -0
  32. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graph_prerelease_reqs_fail/langgraph.json +0 -0
  33. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graph_prerelease_reqs_fail/pyproject.toml +0 -0
  34. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graphs/agent.py +0 -0
  35. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graphs/langgraph.json +0 -0
  36. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graphs/storm.py +0 -0
  37. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graphs_reqs_a/__init__.py +0 -0
  38. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graphs_reqs_a/graphs_submod/__init__.py +0 -0
  39. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graphs_reqs_a/graphs_submod/agent.py +0 -0
  40. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graphs_reqs_a/graphs_submod/subprompt.txt +0 -0
  41. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graphs_reqs_a/hello.py +0 -0
  42. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graphs_reqs_a/langgraph.json +0 -0
  43. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graphs_reqs_a/prompt.txt +0 -0
  44. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graphs_reqs_a/requirements.txt +0 -0
  45. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graphs_reqs_b/graphs_submod/agent.py +0 -0
  46. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graphs_reqs_b/graphs_submod/subprompt.txt +0 -0
  47. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graphs_reqs_b/hello.py +0 -0
  48. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graphs_reqs_b/langgraph.json +0 -0
  49. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graphs_reqs_b/prompt.txt +0 -0
  50. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graphs_reqs_b/requirements.txt +0 -0
  51. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graphs_reqs_b/utils/__init__.py +0 -0
  52. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/graphs_reqs_b/utils/greeter.py +0 -0
  53. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/langgraph.json +0 -0
  54. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/my_app.py +0 -0
  55. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/pipconf.txt +0 -0
  56. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/poetry.lock +0 -0
  57. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/examples/pyproject.toml +0 -0
  58. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/generate_schema.py +0 -0
  59. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-examples/.dockerignore +0 -0
  60. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-examples/.editorconfig +0 -0
  61. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-examples/.env.example +0 -0
  62. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-examples/.eslintrc.cjs +0 -0
  63. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-examples/.gitignore +0 -0
  64. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-examples/LICENSE +0 -0
  65. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-examples/README.md +0 -0
  66. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-examples/jest.config.js +0 -0
  67. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-examples/langgraph.json +0 -0
  68. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-examples/package.json +0 -0
  69. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-examples/src/agent/graph.ts +0 -0
  70. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-examples/src/agent/state.ts +0 -0
  71. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-examples/static/studio.png +0 -0
  72. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-examples/tests/agent.test.ts +0 -0
  73. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-examples/tests/graph.int.test.ts +0 -0
  74. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-examples/tsconfig.json +0 -0
  75. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-monorepo-example/.eslintrc.cjs +0 -0
  76. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-monorepo-example/apps/agent/langgraph.json +0 -0
  77. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-monorepo-example/apps/agent/package.json +0 -0
  78. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-monorepo-example/apps/agent/src/graph.ts +0 -0
  79. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-monorepo-example/apps/agent/src/state.ts +0 -0
  80. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-monorepo-example/apps/agent/tsconfig.json +0 -0
  81. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-monorepo-example/libs/shared/package.json +0 -0
  82. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-monorepo-example/libs/shared/src/index.ts +0 -0
  83. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-monorepo-example/libs/shared/tsconfig.json +0 -0
  84. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-monorepo-example/tsconfig.json +0 -0
  85. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/js-monorepo-example/turbo.json +0 -0
  86. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/langgraph_cli/__main__.py +0 -0
  87. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/langgraph_cli/_ignore.py +0 -0
  88. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/langgraph_cli/analytics.py +0 -0
  89. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/langgraph_cli/archive.py +0 -0
  90. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/langgraph_cli/cli.py +0 -0
  91. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/langgraph_cli/constants.py +0 -0
  92. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/langgraph_cli/docker.py +0 -0
  93. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/langgraph_cli/exec.py +0 -0
  94. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/langgraph_cli/host_backend.py +0 -0
  95. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/langgraph_cli/progress.py +0 -0
  96. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/langgraph_cli/py.typed +0 -0
  97. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/langgraph_cli/schemas.py +0 -0
  98. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/langgraph_cli/templates.py +0 -0
  99. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/langgraph_cli/util.py +0 -0
  100. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/langgraph_cli/uv_lock.py +0 -0
  101. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/langgraph_cli/version.py +0 -0
  102. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/python-monorepo-example/apps/agent/.env.example +0 -0
  103. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/python-monorepo-example/apps/agent/langgraph.json +0 -0
  104. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/python-monorepo-example/apps/agent/pyproject.toml +0 -0
  105. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/python-monorepo-example/apps/agent/src/agent/__init__.py +0 -0
  106. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/python-monorepo-example/apps/agent/src/agent/graph.py +0 -0
  107. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/python-monorepo-example/apps/agent/src/agent/state.py +0 -0
  108. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/python-monorepo-example/libs/common/__init__.py +0 -0
  109. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/python-monorepo-example/libs/common/helpers.py +0 -0
  110. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/python-monorepo-example/libs/shared/pyproject.toml +0 -0
  111. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/python-monorepo-example/libs/shared/src/shared/__init__.py +0 -0
  112. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/python-monorepo-example/libs/shared/src/shared/utils.py +0 -0
  113. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/python-monorepo-example/pyproject.toml +0 -0
  114. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/schemas/schema.json +0 -0
  115. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/schemas/schema.v0.json +0 -0
  116. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/schemas/version.schema.json +0 -0
  117. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/__init__.py +0 -0
  118. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/integration_tests/__init__.py +0 -0
  119. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/integration_tests/test_cli.py +0 -0
  120. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/__init__.py +0 -0
  121. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/agent.py +0 -0
  122. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/cli/__init__.py +0 -0
  123. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/cli/langgraph.json +0 -0
  124. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/cli/pyproject.toml +0 -0
  125. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/cli/test_cli.py +0 -0
  126. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/cli/test_templates.py +0 -0
  127. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/conftest.py +0 -0
  128. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/graphs/agent.py +0 -0
  129. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/helpers.py +0 -0
  130. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/multiplatform/js.mts +0 -0
  131. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/multiplatform/python.py +0 -0
  132. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/pipconfig.txt +0 -0
  133. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/test_archive.py +0 -0
  134. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/test_config.json +0 -0
  135. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/test_docker.py +0 -0
  136. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/test_host_backend.py +0 -0
  137. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/test_logs_helpers.py +0 -0
  138. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/tests/unit_tests/test_util.py +0 -0
  139. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/uv-examples/monorepo/apps/agent/.env.example +0 -0
  140. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/uv-examples/monorepo/apps/agent/langgraph.json +0 -0
  141. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/uv-examples/monorepo/apps/agent/src/agent/__init__.py +0 -0
  142. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/uv-examples/monorepo/apps/agent/src/agent/graph.py +0 -0
  143. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/uv-examples/monorepo/libs/shared/pyproject.toml +0 -0
  144. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/uv-examples/monorepo/libs/shared/src/shared/__init__.py +0 -0
  145. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/uv-examples/monorepo/libs/shared/src/shared/utils.py +0 -0
  146. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/uv-examples/simple/.env.example +0 -0
  147. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/uv-examples/simple/langgraph.json +0 -0
  148. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/uv-examples/simple/src/agent/__init__.py +0 -0
  149. {langgraph_cli-0.4.25 → langgraph_cli-0.4.27}/uv-examples/simple/src/agent/graph.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langgraph-cli
3
- Version: 0.4.25
3
+ Version: 0.4.27
4
4
  Summary: CLI for interacting with LangGraph API
5
5
  Project-URL: Source, https://github.com/langchain-ai/langgraph/tree/main/libs/cli
6
6
  Project-URL: Twitter, https://x.com/langchain_oss
@@ -16,7 +16,7 @@ Requires-Dist: pathspec>=0.11.0
16
16
  Requires-Dist: python-dotenv>=0.8.0
17
17
  Requires-Dist: tomli>=2.0.1; python_version < '3.11'
18
18
  Provides-Extra: inmem
19
- Requires-Dist: langgraph-api<0.9.0,>=0.5.35; (python_version >= '3.11') and extra == 'inmem'
19
+ Requires-Dist: langgraph-api<0.10.0,>=0.5.35; (python_version >= '3.11') and extra == 'inmem'
20
20
  Requires-Dist: langgraph-runtime-inmem>=0.7; (python_version >= '3.11') and extra == 'inmem'
21
21
  Description-Content-Type: text/markdown
22
22
 
@@ -3675,12 +3675,11 @@ keyv@^4.5.4:
3675
3675
  json-buffer "3.0.1"
3676
3676
 
3677
3677
  "langsmith@>=0.5.0 <1.0.0":
3678
- version "0.5.20"
3679
- resolved "https://registry.yarnpkg.com/langsmith/-/langsmith-0.5.20.tgz#4021847d2ccd5a86c5eb96060f9bb5f19f80eca5"
3680
- integrity sha512-ULhLM8RswvQDXufLtNtvclHrWCBx8Cb5UPI6lAZC+8Dq59iHsVPz/3Ac9khWNm1VIvChRsuykixD/WrmzuuA3Q==
3678
+ version "0.6.3"
3679
+ resolved "https://registry.yarnpkg.com/langsmith/-/langsmith-0.6.3.tgz#a3d8ad58d66a47d3697e3c69b2be3f6df5233190"
3680
+ integrity sha512-pXrQ4/4myQvjFFOAUmt5pWRrLEZR20gzIJD7MNdUH+5/S5nLI4ZRBo/SYKC6coaYj9pYTfQdBIzcs+3kfJ5uDA==
3681
3681
  dependencies:
3682
3682
  p-queue "6.6.2"
3683
- uuid "10.0.0"
3684
3683
 
3685
3684
  leven@^3.1.0:
3686
3685
  version "3.1.0"
@@ -4848,7 +4847,7 @@ uri-js@^4.2.2:
4848
4847
  dependencies:
4849
4848
  punycode "^2.1.0"
4850
4849
 
4851
- uuid@10.0.0, uuid@^10.0.0:
4850
+ uuid@^10.0.0:
4852
4851
  version "10.0.0"
4853
4852
  resolved "https://registry.yarnpkg.com/uuid/-/uuid-10.0.0.tgz#5a95aa454e6e002725c79055fd42aaba30ca6294"
4854
4853
  integrity sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==
@@ -17,7 +17,7 @@
17
17
  "lint": "eslint 'apps/**/*.ts' 'libs/**/*.ts'"
18
18
  },
19
19
  "devDependencies": {
20
- "turbo": "^2.9.7",
20
+ "turbo": "^2.9.14",
21
21
  "typescript": "^5.9.3",
22
22
  "@tsconfig/recommended": "^1.0.13",
23
23
  "@eslint/eslintrc": "^3.3.5",
@@ -166,35 +166,35 @@
166
166
  resolved "https://registry.yarnpkg.com/@tsconfig/recommended/-/recommended-1.0.13.tgz#269fce3ad04ca70b93269ff44cca81b950f542da"
167
167
  integrity sha512-sySRuBfMKyKO/j2ZAhR8kSembhjuPEV4Ra3AHtmWLq51+iGaudr45crPSzNC5b7/Ctrh9dfUpBuTlYrH6rM58Q==
168
168
 
169
- "@turbo/darwin-64@2.9.7":
170
- version "2.9.7"
171
- resolved "https://registry.yarnpkg.com/@turbo/darwin-64/-/darwin-64-2.9.7.tgz#46fddae01ea7817192dc6ff36a678cc3879b753b"
172
- integrity sha512-wnvOWuVWJ5EUHNKxExEWiGlTeVpLG1L0PCu5MUozyC1P2SHGiWsmpW6/yAuShH91Fa2TAHOvdCRBzriZh4j4Eg==
173
-
174
- "@turbo/darwin-arm64@2.9.7":
175
- version "2.9.7"
176
- resolved "https://registry.yarnpkg.com/@turbo/darwin-arm64/-/darwin-arm64-2.9.7.tgz#cd7cf3a024509af0f59ae3885216d62fd090fdb6"
177
- integrity sha512-mA0FIPMwwN3lodDkQYaGxj6PeT7ZaN5aCEbkKn/WB+ZB9yJdVWA4J83GH7t43jqDc5dcnVluVN5UFx3plRiXhA==
178
-
179
- "@turbo/linux-64@2.9.7":
180
- version "2.9.7"
181
- resolved "https://registry.yarnpkg.com/@turbo/linux-64/-/linux-64-2.9.7.tgz#25ee9a2cb3042498a3203e14653b14041105020f"
182
- integrity sha512-fEbUYpgb5l7P+q+5tsWF2gw+/GSjUsuUTcnfm+f0lozUjgcjLKyOat6PgtAChmIFcTPchCL/8rJ3TvkBy01gfA==
183
-
184
- "@turbo/linux-arm64@2.9.7":
185
- version "2.9.7"
186
- resolved "https://registry.yarnpkg.com/@turbo/linux-arm64/-/linux-arm64-2.9.7.tgz#5b19d6249a50cb8153b8f2bc22ad10bbda614fbe"
187
- integrity sha512-VkUjulo9ytfHKUHOS5gy0XPoh4CTKPXWCL8nLdrlHVi9fSut31ECeUqnm/dAbETP5D4xo9mH9XkJ+qMzGe/zmg==
188
-
189
- "@turbo/windows-64@2.9.7":
190
- version "2.9.7"
191
- resolved "https://registry.yarnpkg.com/@turbo/windows-64/-/windows-64-2.9.7.tgz#900645776fa44ff8333e801d890992736f6dbc72"
192
- integrity sha512-/GWdY6/x4aIHqkYJq596Rpdk1x0MkpRPkJcLAoB3yGRwyUms0+u2F1GnV54IbyAZTeKLRWSJKzNC+QwVGdYchA==
193
-
194
- "@turbo/windows-arm64@2.9.7":
195
- version "2.9.7"
196
- resolved "https://registry.yarnpkg.com/@turbo/windows-arm64/-/windows-arm64-2.9.7.tgz#e678d73fdbcbb12a679403fe7ba070fb67f37810"
197
- integrity sha512-xBBgxCC5PK2+WZ1PPRZdp+aJ0bMBcEbweXWux3RUHJvX9ZodcoQySkrW6qt+ahb+uk8ZjyQodLfDwtVSoYds1w==
169
+ "@turbo/darwin-64@2.9.14":
170
+ version "2.9.14"
171
+ resolved "https://registry.yarnpkg.com/@turbo/darwin-64/-/darwin-64-2.9.14.tgz#b9ec6ac637b9c5fdba5dae9d743f5d121f091242"
172
+ integrity sha512-t7QiPflaEyBE4oayeZtSmu4mEfjgIrcNlNNl1z1dmIVPqEdtA7+CfTf8d7KXsOGPh6aNgWjKxyvQg9uGfDQF+A==
173
+
174
+ "@turbo/darwin-arm64@2.9.14":
175
+ version "2.9.14"
176
+ resolved "https://registry.yarnpkg.com/@turbo/darwin-arm64/-/darwin-arm64-2.9.14.tgz#99d19f3e59842c595d2828c72a2e4ef537408f38"
177
+ integrity sha512-d23147mC9BsCPA9mJ0h/ubcpbRgcJBXbcG3+Vq7YLhjz3IXuvQsJ1UXH8f4MD76ZjJ4m/E4aRdJV+MW88CDfbw==
178
+
179
+ "@turbo/linux-64@2.9.14":
180
+ version "2.9.14"
181
+ resolved "https://registry.yarnpkg.com/@turbo/linux-64/-/linux-64-2.9.14.tgz#9c907434f091cd75529f5496516f79b71935d2bb"
182
+ integrity sha512-P3ZKB5tuUDdDQWuAsACGUR1qv9W7BNWxdxqVJ0kZNuNNPRaVYTPPikLcp79+GiEcW3npsR+KyP38lnQiBc5aSA==
183
+
184
+ "@turbo/linux-arm64@2.9.14":
185
+ version "2.9.14"
186
+ resolved "https://registry.yarnpkg.com/@turbo/linux-arm64/-/linux-arm64-2.9.14.tgz#79ae9060e6ee9e0fb784ae0747e980f582e75313"
187
+ integrity sha512-ZRTlzcUMrrPv9ZuDzRF9n60Ym13bKeG9jDB8WjxyLhWNzV+AJQN+zdpIk3NJYf2zQsGUm1mNar2P0elRzLw25g==
188
+
189
+ "@turbo/windows-64@2.9.14":
190
+ version "2.9.14"
191
+ resolved "https://registry.yarnpkg.com/@turbo/windows-64/-/windows-64-2.9.14.tgz#68a80f299f35189314184c88301caad982d1c0c2"
192
+ integrity sha512-exanwN6sIduZwykYeiTQj8kCmOhazP5WOz3bvXMcYtjhL6Z3iRWLewKrXCBq0bqwSP3iBMb/AerRCnHI4lx46A==
193
+
194
+ "@turbo/windows-arm64@2.9.14":
195
+ version "2.9.14"
196
+ resolved "https://registry.yarnpkg.com/@turbo/windows-arm64/-/windows-arm64-2.9.14.tgz#4dc16684f0ddce53fafe56ad8f55205c4473d17a"
197
+ integrity sha512-fVdCsnmYoKICsycbWuuGp6Jvi51/3G/UluFWuAUCvR8PIW5IJkAk5BM9UF8PSm0Q2IphWHFZjYEgjHsh3B9y/g==
198
198
 
199
199
  "@types/esrecurse@^4.3.1":
200
200
  version "4.3.1"
@@ -1327,12 +1327,11 @@ keyv@^4.5.4:
1327
1327
  json-buffer "3.0.1"
1328
1328
 
1329
1329
  "langsmith@>=0.5.0 <1.0.0":
1330
- version "0.5.20"
1331
- resolved "https://registry.yarnpkg.com/langsmith/-/langsmith-0.5.20.tgz#4021847d2ccd5a86c5eb96060f9bb5f19f80eca5"
1332
- integrity sha512-ULhLM8RswvQDXufLtNtvclHrWCBx8Cb5UPI6lAZC+8Dq59iHsVPz/3Ac9khWNm1VIvChRsuykixD/WrmzuuA3Q==
1330
+ version "0.7.1"
1331
+ resolved "https://registry.yarnpkg.com/langsmith/-/langsmith-0.7.1.tgz#d721ad2e5211f9a5373e8a84eb4fed36b5621971"
1332
+ integrity sha512-Wjk90UjNoY5cBHMlNAC/eZx5clI8jnjBOBW8uJu8+MWBtx0QesNjsUiLtjI+I3UnrpxFFpDqGXcnhBjH654Mqg==
1333
1333
  dependencies:
1334
1334
  p-queue "6.6.2"
1335
- uuid "10.0.0"
1336
1335
 
1337
1336
  levn@^0.4.1:
1338
1337
  version "0.4.1"
@@ -1814,17 +1813,17 @@ tsconfig-paths@^3.15.0:
1814
1813
  minimist "^1.2.6"
1815
1814
  strip-bom "^3.0.0"
1816
1815
 
1817
- turbo@^2.9.7:
1818
- version "2.9.7"
1819
- resolved "https://registry.yarnpkg.com/turbo/-/turbo-2.9.7.tgz#da6d5a821f0bde5174e1a55af6690dad5c2fb004"
1820
- integrity sha512-epxzqVO2s0IxcSWcgb+qKrtco8isfe7g3VtiS6hkYnEK4A9XQDZbrtavQ6MtWR1KoQn+1fUomaQth2rfRHlUlg==
1816
+ turbo@^2.9.14:
1817
+ version "2.9.14"
1818
+ resolved "https://registry.yarnpkg.com/turbo/-/turbo-2.9.14.tgz#d412fcc4c9bd8dba29cec5bbd54d5a74ab2b1bee"
1819
+ integrity sha512-BQqXRr4UoWI3UPFrtznCLykYHxwxWh53iCB57x092jPMjIlW1wnm3N895g5irpiXmnxUhREBB0n6+y8BHhs4nw==
1821
1820
  optionalDependencies:
1822
- "@turbo/darwin-64" "2.9.7"
1823
- "@turbo/darwin-arm64" "2.9.7"
1824
- "@turbo/linux-64" "2.9.7"
1825
- "@turbo/linux-arm64" "2.9.7"
1826
- "@turbo/windows-64" "2.9.7"
1827
- "@turbo/windows-arm64" "2.9.7"
1821
+ "@turbo/darwin-64" "2.9.14"
1822
+ "@turbo/darwin-arm64" "2.9.14"
1823
+ "@turbo/linux-64" "2.9.14"
1824
+ "@turbo/linux-arm64" "2.9.14"
1825
+ "@turbo/windows-64" "2.9.14"
1826
+ "@turbo/windows-arm64" "2.9.14"
1828
1827
 
1829
1828
  type-check@^0.4.0, type-check@~0.4.0:
1830
1829
  version "0.4.0"
@@ -1900,7 +1899,7 @@ uri-js@^4.2.2:
1900
1899
  dependencies:
1901
1900
  punycode "^2.1.0"
1902
1901
 
1903
- uuid@10.0.0, uuid@^10.0.0:
1902
+ uuid@^10.0.0:
1904
1903
  version "10.0.0"
1905
1904
  resolved "https://registry.yarnpkg.com/uuid/-/uuid-10.0.0.tgz#5a95aa454e6e002725c79055fd42aaba30ca6294"
1906
1905
  integrity sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==
@@ -0,0 +1 @@
1
+ __version__ = "0.4.27"
@@ -35,6 +35,12 @@ DISALLOWED_BUILD_COMMAND_CHARS = [
35
35
  # This blocks background execution (cmd &) while allowing command
36
36
  # chaining (cmd1 && cmd2) which is common in build commands.
37
37
  _SINGLE_AMPERSAND_RE = re.compile(r"(?<!&)&(?:&&)*(?!&)")
38
+ _API_VERSION_PATTERN = re.compile(
39
+ r"^(?P<major>\d+)"
40
+ r"(?:\.(?P<minor>\d+))?"
41
+ r"(?:\.(?P<patch>\d+))?"
42
+ r"(?:(?:\.|)(?:[A-Za-z][0-9A-Za-z]*))?$"
43
+ )
38
44
 
39
45
 
40
46
  def has_disallowed_build_command_content(command: str) -> bool:
@@ -123,6 +129,18 @@ def _parse_node_version(version_str: str) -> int:
123
129
  ) from None
124
130
 
125
131
 
132
+ def _parse_api_version_parts(version_str: str) -> tuple[int, ...]:
133
+ """Parse an API version into numeric components.
134
+
135
+ Supports optional prerelease suffixes, e.g. `0.9.0rc1`.
136
+ """
137
+ version_core = version_str.split("-", 1)[0]
138
+ match = _API_VERSION_PATTERN.fullmatch(version_core)
139
+ if not match:
140
+ raise ValueError("Version must be major or major.minor or major.minor.patch.")
141
+ return tuple(int(part) for part in match.groups() if part is not None)
142
+
143
+
126
144
  def _is_node_graph(spec: str | dict) -> bool:
127
145
  """Check if a graph is a Node.js graph based on the file extension."""
128
146
  if isinstance(spec, dict):
@@ -176,12 +194,12 @@ def validate_config(config: Config) -> Config:
176
194
  )
177
195
  if api_version:
178
196
  try:
179
- parts = tuple(map(int, api_version.split("-")[0].split(".")))
197
+ parts = _parse_api_version_parts(api_version)
180
198
  if len(parts) > 3:
181
199
  raise ValueError(
182
200
  "Version must be major or major.minor or major.minor.patch."
183
201
  )
184
- except TypeError:
202
+ except (TypeError, ValueError):
185
203
  raise click.UsageError(
186
204
  f"Invalid version format: {api_version}.\n\n"
187
205
  "Pin to a minor version, e.g.:\n"
@@ -849,6 +849,41 @@ def _upload_to_gcs(signed_url: str, file_path: str, file_size: int) -> None:
849
849
  # ---------------------------------------------------------------------------
850
850
 
851
851
 
852
+ def _resolve_pushed_image_digest(
853
+ runner,
854
+ *,
855
+ remote_image: str,
856
+ docker_config_dir: str | None,
857
+ verbose: bool,
858
+ ) -> str:
859
+ """Return ``{registry}/{repo}@sha256:<hex>`` for a freshly-pushed image.
860
+
861
+ Reads ``RepoDigests`` via ``docker image inspect`` — the local daemon
862
+ records the registry's manifest digest there after a successful push.
863
+ Falls back to ``remote_image`` with a warning if no matching digest is
864
+ found, rather than failing the deploy.
865
+ """
866
+ # rsplit preserves ``:port`` in the registry host.
867
+ repo_no_tag = remote_image.rsplit(":", 1)[0]
868
+ args: list[str] = ["docker"]
869
+ if docker_config_dir:
870
+ args += ["--config", docker_config_dir]
871
+ args += ["image", "inspect", "--format", "{{json .RepoDigests}}", remote_image]
872
+ stdout, _ = runner.run(subp_exec(*args, collect=True, verbose=verbose))
873
+ try:
874
+ digests = json_mod.loads(stdout or "[]") or []
875
+ except json_mod.JSONDecodeError:
876
+ digests = []
877
+ for d in digests:
878
+ if isinstance(d, str) and d.startswith(f"{repo_no_tag}@sha256:"):
879
+ return d
880
+ _get_emitter().warn(
881
+ f"Could not resolve image digest for {remote_image}; "
882
+ "falling back to the tag-based reference. Re-run with --verbose for details."
883
+ )
884
+ return remote_image
885
+
886
+
852
887
  def _run_local_build(
853
888
  *,
854
889
  client: HostBackendClient,
@@ -1015,9 +1050,18 @@ def _run_local_build(
1015
1050
  raise
1016
1051
  step += 1
1017
1052
 
1053
+ resolved_image = _resolve_pushed_image_digest(
1054
+ runner,
1055
+ remote_image=remote_image,
1056
+ docker_config_dir=None,
1057
+ verbose=verbose,
1058
+ )
1059
+
1018
1060
  # -- Step: Update deployment --
1019
1061
  _log_deploy_step(step, f"Updating deployment {deployment_id}")
1020
- updated = client.update_deployment(deployment_id, remote_image, secrets=secrets)
1062
+ updated = client.update_deployment(
1063
+ deployment_id, resolved_image, secrets=secrets
1064
+ )
1021
1065
 
1022
1066
  return BuildResult(
1023
1067
  updated=updated if isinstance(updated, dict) else {},
@@ -23,7 +23,7 @@ dependencies = [
23
23
  path = "langgraph_cli/__init__.py"
24
24
  [project.optional-dependencies]
25
25
  inmem = [
26
- "langgraph-api>=0.5.35,<0.9.0 ; python_version >= '3.11'",
26
+ "langgraph-api>=0.5.35,<0.10.0 ; python_version >= '3.11'",
27
27
  "langgraph-runtime-inmem>=0.7 ; python_version >= '3.11'",
28
28
  ]
29
29
 
@@ -2944,6 +2944,23 @@ def test_docker_tag_with_api_version(in_config: bool):
2944
2944
  assert tag == f"langchain/langgraph-server:{version}-py3.11"
2945
2945
 
2946
2946
 
2947
+ @pytest.mark.parametrize("in_config", [False, True])
2948
+ @pytest.mark.parametrize("version", ["0.9.0rc1", "0.9.0.dev1"])
2949
+ def test_docker_tag_with_prerelease_api_version(version: str, in_config: bool):
2950
+ """Test docker_tag with prerelease and dev api_version values."""
2951
+ config = validate_config(
2952
+ {
2953
+ "python_version": "3.11",
2954
+ "dependencies": ["."],
2955
+ "graphs": {"agent": "./agent.py:graph"},
2956
+ "api_version": version if in_config else None,
2957
+ }
2958
+ )
2959
+
2960
+ tag = docker_tag(config, api_version=version if not in_config else None)
2961
+ assert tag == f"langchain/langgraph-api:{version}-py3.11"
2962
+
2963
+
2947
2964
  def test_config_to_docker_with_api_version():
2948
2965
  """Test config_to_docker function with api_version parameter."""
2949
2966
 
@@ -3,6 +3,7 @@ import io
3
3
  import json
4
4
  import os
5
5
  import sys
6
+ from unittest.mock import MagicMock
6
7
 
7
8
  import click
8
9
  import httpx
@@ -16,6 +17,7 @@ from langgraph_cli.deploy import (
16
17
  _env_without_deployment_name,
17
18
  _parse_env_from_config,
18
19
  _resolve_env_path,
20
+ _resolve_pushed_image_digest,
19
21
  _smith_dashboard_base_url,
20
22
  normalize_image_tag,
21
23
  normalize_name,
@@ -532,3 +534,156 @@ class TestSmithDashboardBaseUrl:
532
534
  _smith_dashboard_base_url("https://custom.example.com")
533
535
  == "https://smith.langchain.com"
534
536
  )
537
+
538
+
539
+ class TestResolvePushedImageDigest:
540
+ """Tests for ``_resolve_pushed_image_digest`` — runner is mocked to
541
+ return the ``(stdout, stderr)`` tuple that ``subp_exec(collect=True)``
542
+ would produce.
543
+ """
544
+
545
+ @staticmethod
546
+ def _runner(stdout: str | None) -> MagicMock:
547
+ # Close the unawaited subp_exec coroutine to silence gc warnings.
548
+ runner = MagicMock()
549
+
550
+ def _run(coro, *args, **kwargs):
551
+ if hasattr(coro, "close"):
552
+ coro.close()
553
+ return (stdout, "")
554
+
555
+ runner.run.side_effect = _run
556
+ return runner
557
+
558
+ def test_happy_path_returns_digest(self):
559
+ runner = self._runner('["us-central1-docker.pkg.dev/proj/repo@sha256:abc123"]')
560
+ out = _resolve_pushed_image_digest(
561
+ runner,
562
+ remote_image="us-central1-docker.pkg.dev/proj/repo:latest",
563
+ docker_config_dir=None,
564
+ verbose=False,
565
+ )
566
+ assert out == "us-central1-docker.pkg.dev/proj/repo@sha256:abc123"
567
+
568
+ def test_filters_to_matching_repo(self):
569
+ # Same image ID can hold digests for multiple repos — pick the one
570
+ # matching the just-pushed repo.
571
+ runner = self._runner(
572
+ json.dumps(
573
+ [
574
+ "other-registry.example.com/some/repo@sha256:000000",
575
+ "us-central1-docker.pkg.dev/proj/repo@sha256:abc123",
576
+ ]
577
+ )
578
+ )
579
+ out = _resolve_pushed_image_digest(
580
+ runner,
581
+ remote_image="us-central1-docker.pkg.dev/proj/repo:v1.2.3",
582
+ docker_config_dir=None,
583
+ verbose=False,
584
+ )
585
+ assert out == "us-central1-docker.pkg.dev/proj/repo@sha256:abc123"
586
+
587
+ def test_empty_repodigests_falls_back_with_warning(self, mocker):
588
+ emitter = mocker.MagicMock()
589
+ mocker.patch("langgraph_cli.deploy._get_emitter", return_value=emitter)
590
+ runner = self._runner("[]")
591
+ remote = "us-central1-docker.pkg.dev/proj/repo:latest"
592
+ out = _resolve_pushed_image_digest(
593
+ runner,
594
+ remote_image=remote,
595
+ docker_config_dir=None,
596
+ verbose=False,
597
+ )
598
+ assert out == remote
599
+ assert emitter.warn.called
600
+ assert remote in emitter.warn.call_args.args[0]
601
+
602
+ def test_null_repodigests_falls_back_with_warning(self, mocker):
603
+ # ``docker inspect --format '{{json .RepoDigests}}'`` emits ``null``
604
+ # when the field is absent.
605
+ emitter = mocker.MagicMock()
606
+ mocker.patch("langgraph_cli.deploy._get_emitter", return_value=emitter)
607
+ runner = self._runner("null")
608
+ remote = "us-central1-docker.pkg.dev/proj/repo:latest"
609
+ out = _resolve_pushed_image_digest(
610
+ runner,
611
+ remote_image=remote,
612
+ docker_config_dir=None,
613
+ verbose=False,
614
+ )
615
+ assert out == remote
616
+ assert emitter.warn.called
617
+
618
+ def test_no_matching_repo_falls_back_with_warning(self, mocker):
619
+ # No matching digest for the pushed repo — warn and fall back to the
620
+ # tag-based ref rather than failing the deploy.
621
+ emitter = mocker.MagicMock()
622
+ mocker.patch("langgraph_cli.deploy._get_emitter", return_value=emitter)
623
+ runner = self._runner('["other-registry.example.com/some/repo@sha256:000000"]')
624
+ remote = "us-central1-docker.pkg.dev/proj/repo:latest"
625
+ out = _resolve_pushed_image_digest(
626
+ runner,
627
+ remote_image=remote,
628
+ docker_config_dir=None,
629
+ verbose=False,
630
+ )
631
+ assert out == remote
632
+ assert emitter.warn.called
633
+
634
+ def test_registry_with_port_in_host(self):
635
+ # Only the rightmost ``:`` (the ``:latest`` tag) should be stripped.
636
+ runner = self._runner('["localhost:5000/repo@sha256:deadbeef"]')
637
+ out = _resolve_pushed_image_digest(
638
+ runner,
639
+ remote_image="localhost:5000/repo:latest",
640
+ docker_config_dir=None,
641
+ verbose=False,
642
+ )
643
+ assert out == "localhost:5000/repo@sha256:deadbeef"
644
+
645
+ @staticmethod
646
+ def _capturing_runner(stdout: str) -> tuple[MagicMock, dict]:
647
+ """Like ``_runner`` but exposes the coroutine for arg introspection.
648
+ Caller must close ``captured["coro"]``.
649
+ """
650
+ runner = MagicMock()
651
+ captured: dict = {}
652
+
653
+ def _run(coro, *args, **kwargs):
654
+ captured["coro"] = coro
655
+ return (stdout, "")
656
+
657
+ runner.run.side_effect = _run
658
+ return runner, captured
659
+
660
+ def test_passes_docker_config_dir(self):
661
+ runner, captured = self._capturing_runner(
662
+ '["us-central1-docker.pkg.dev/proj/repo@sha256:abc"]'
663
+ )
664
+ _resolve_pushed_image_digest(
665
+ runner,
666
+ remote_image="us-central1-docker.pkg.dev/proj/repo:latest",
667
+ docker_config_dir="/tmp/some-cfg",
668
+ verbose=False,
669
+ )
670
+ frame_locals = captured["coro"].cr_frame.f_locals
671
+ assert frame_locals["cmd"] == "docker"
672
+ assert "--config" in frame_locals["args"]
673
+ cfg_idx = frame_locals["args"].index("--config")
674
+ assert frame_locals["args"][cfg_idx + 1] == "/tmp/some-cfg"
675
+ captured["coro"].close()
676
+
677
+ def test_omits_docker_config_dir_when_none(self):
678
+ runner, captured = self._capturing_runner(
679
+ '["us-central1-docker.pkg.dev/proj/repo@sha256:abc"]'
680
+ )
681
+ _resolve_pushed_image_digest(
682
+ runner,
683
+ remote_image="us-central1-docker.pkg.dev/proj/repo:latest",
684
+ docker_config_dir=None,
685
+ verbose=False,
686
+ )
687
+ frame_locals = captured["coro"].cr_frame.f_locals
688
+ assert "--config" not in frame_locals["args"]
689
+ captured["coro"].close()
@@ -7,6 +7,7 @@ dependencies = [
7
7
  "langgraph>=0.6.0,<2",
8
8
  "langchain-core>=0.2.14",
9
9
  "shared",
10
+ "langgraph-checkpoint-postgres>=3.0.0"
10
11
  ]
11
12
 
12
13
  [build-system]
@@ -5,7 +5,8 @@ description = "uv workspace monorepo example for LangGraph CLI integration test"
5
5
  requires-python = ">=3.11"
6
6
  dependencies = [
7
7
  "langgraph>=0.6.0,<2",
8
- "langchain-core>=0.2.14",
8
+ "langchain-core>=1.3.3",
9
+ "langgraph-checkpoint-postgres>=3.0.0"
9
10
  ]
10
11
 
11
12
  [tool.uv.workspace]