langgraph-cli 0.4.7__tar.gz → 0.4.9__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 (124) hide show
  1. langgraph_cli-0.4.9/.gitignore +1 -0
  2. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/Makefile +4 -1
  3. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/PKG-INFO +6 -3
  4. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/generate_schema.py +6 -0
  5. langgraph_cli-0.4.9/js-examples/.editorconfig +10 -0
  6. langgraph_cli-0.4.9/langgraph_cli/__init__.py +1 -0
  7. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/langgraph_cli/cli.py +1 -0
  8. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/langgraph_cli/config.py +70 -0
  9. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/langgraph_cli/schemas.py +132 -4
  10. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/pyproject.toml +6 -2
  11. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/schemas/schema.json +158 -6
  12. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/schemas/schema.v0.json +158 -6
  13. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/tests/unit_tests/test_config.py +137 -0
  14. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/uv.lock +987 -420
  15. langgraph_cli-0.4.7/.gitignore +0 -184
  16. langgraph_cli-0.4.7/langgraph_cli/__init__.py +0 -1
  17. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/LICENSE +0 -0
  18. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/README.md +0 -0
  19. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/.env.example +0 -0
  20. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/.gitignore +0 -0
  21. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/Makefile +0 -0
  22. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graph_prerelease_reqs/agent.py +0 -0
  23. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graph_prerelease_reqs/deps/additional_deps/pyproject.toml +0 -0
  24. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graph_prerelease_reqs/deps/zuper_deps/pyproject.toml +0 -0
  25. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graph_prerelease_reqs/langgraph.json +0 -0
  26. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graph_prerelease_reqs/pyproject.toml +0 -0
  27. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graph_prerelease_reqs_fail/agent.py +0 -0
  28. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graph_prerelease_reqs_fail/langgraph.json +0 -0
  29. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graph_prerelease_reqs_fail/pyproject.toml +0 -0
  30. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graphs/agent.py +0 -0
  31. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graphs/langgraph.json +0 -0
  32. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graphs/storm.py +0 -0
  33. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graphs_reqs_a/__init__.py +0 -0
  34. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graphs_reqs_a/graphs_submod/__init__.py +0 -0
  35. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graphs_reqs_a/graphs_submod/agent.py +0 -0
  36. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graphs_reqs_a/graphs_submod/subprompt.txt +0 -0
  37. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graphs_reqs_a/hello.py +0 -0
  38. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graphs_reqs_a/langgraph.json +0 -0
  39. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graphs_reqs_a/prompt.txt +0 -0
  40. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graphs_reqs_a/requirements.txt +0 -0
  41. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graphs_reqs_b/graphs_submod/agent.py +0 -0
  42. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graphs_reqs_b/graphs_submod/subprompt.txt +0 -0
  43. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graphs_reqs_b/hello.py +0 -0
  44. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graphs_reqs_b/langgraph.json +0 -0
  45. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graphs_reqs_b/prompt.txt +0 -0
  46. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graphs_reqs_b/requirements.txt +0 -0
  47. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graphs_reqs_b/utils/__init__.py +0 -0
  48. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/graphs_reqs_b/utils/greeter.py +0 -0
  49. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/langgraph.json +0 -0
  50. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/my_app.py +0 -0
  51. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/pipconf.txt +0 -0
  52. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/poetry.lock +0 -0
  53. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/examples/pyproject.toml +0 -0
  54. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-examples/.dockerignore +0 -0
  55. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-examples/.env.example +0 -0
  56. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-examples/.eslintrc.cjs +0 -0
  57. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-examples/.gitignore +0 -0
  58. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-examples/LICENSE +0 -0
  59. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-examples/README.md +0 -0
  60. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-examples/jest.config.js +0 -0
  61. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-examples/langgraph.json +0 -0
  62. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-examples/package.json +0 -0
  63. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-examples/src/agent/graph.ts +0 -0
  64. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-examples/src/agent/state.ts +0 -0
  65. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-examples/static/studio.png +0 -0
  66. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-examples/tests/agent.test.ts +0 -0
  67. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-examples/tests/graph.int.test.ts +0 -0
  68. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-examples/tsconfig.json +0 -0
  69. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-examples/yarn.lock +0 -0
  70. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-monorepo-example/.eslintrc.cjs +0 -0
  71. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-monorepo-example/apps/agent/langgraph.json +0 -0
  72. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-monorepo-example/apps/agent/package.json +0 -0
  73. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-monorepo-example/apps/agent/src/graph.ts +0 -0
  74. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-monorepo-example/apps/agent/src/state.ts +0 -0
  75. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-monorepo-example/apps/agent/tsconfig.json +0 -0
  76. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-monorepo-example/libs/shared/package.json +0 -0
  77. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-monorepo-example/libs/shared/src/index.ts +0 -0
  78. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-monorepo-example/libs/shared/tsconfig.json +0 -0
  79. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-monorepo-example/package.json +0 -0
  80. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-monorepo-example/tsconfig.json +0 -0
  81. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-monorepo-example/turbo.json +0 -0
  82. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/js-monorepo-example/yarn.lock +0 -0
  83. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/langgraph_cli/__main__.py +0 -0
  84. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/langgraph_cli/analytics.py +0 -0
  85. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/langgraph_cli/constants.py +0 -0
  86. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/langgraph_cli/docker.py +0 -0
  87. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/langgraph_cli/exec.py +0 -0
  88. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/langgraph_cli/progress.py +0 -0
  89. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/langgraph_cli/py.typed +0 -0
  90. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/langgraph_cli/templates.py +0 -0
  91. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/langgraph_cli/util.py +0 -0
  92. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/langgraph_cli/version.py +0 -0
  93. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/python-monorepo-example/apps/agent/.env.example +0 -0
  94. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/python-monorepo-example/apps/agent/langgraph.json +0 -0
  95. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/python-monorepo-example/apps/agent/pyproject.toml +0 -0
  96. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/python-monorepo-example/apps/agent/src/agent/__init__.py +0 -0
  97. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/python-monorepo-example/apps/agent/src/agent/graph.py +0 -0
  98. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/python-monorepo-example/apps/agent/src/agent/state.py +0 -0
  99. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/python-monorepo-example/libs/common/__init__.py +0 -0
  100. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/python-monorepo-example/libs/common/helpers.py +0 -0
  101. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/python-monorepo-example/libs/shared/pyproject.toml +0 -0
  102. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/python-monorepo-example/libs/shared/src/shared/__init__.py +0 -0
  103. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/python-monorepo-example/libs/shared/src/shared/utils.py +0 -0
  104. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/python-monorepo-example/pyproject.toml +0 -0
  105. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/schemas/version.schema.json +0 -0
  106. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/tests/__init__.py +0 -0
  107. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/tests/integration_tests/__init__.py +0 -0
  108. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/tests/integration_tests/test_cli.py +0 -0
  109. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/tests/unit_tests/__init__.py +0 -0
  110. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/tests/unit_tests/agent.py +0 -0
  111. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/tests/unit_tests/cli/__init__.py +0 -0
  112. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/tests/unit_tests/cli/langgraph.json +0 -0
  113. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/tests/unit_tests/cli/pyproject.toml +0 -0
  114. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/tests/unit_tests/cli/test_cli.py +0 -0
  115. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/tests/unit_tests/cli/test_templates.py +0 -0
  116. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/tests/unit_tests/conftest.py +0 -0
  117. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/tests/unit_tests/graphs/agent.py +0 -0
  118. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/tests/unit_tests/helpers.py +0 -0
  119. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/tests/unit_tests/multiplatform/js.mts +0 -0
  120. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/tests/unit_tests/multiplatform/python.py +0 -0
  121. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/tests/unit_tests/pipconfig.txt +0 -0
  122. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/tests/unit_tests/test_config.json +0 -0
  123. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/tests/unit_tests/test_docker.py +0 -0
  124. {langgraph_cli-0.4.7 → langgraph_cli-0.4.9}/tests/unit_tests/test_util.py +0 -0
@@ -0,0 +1 @@
1
+ .langgraph_api/
@@ -1,4 +1,4 @@
1
- .PHONY: test lint format test-integration update-schema
1
+ .PHONY: test lint format test-integration update-schema bump-version
2
2
 
3
3
  ######################
4
4
  # TESTING AND COVERAGE
@@ -35,3 +35,6 @@ format format_diff:
35
35
 
36
36
  update-schema:
37
37
  uv run python generate_schema.py
38
+
39
+ bump-version:
40
+ uv run hatch version patch
@@ -1,15 +1,18 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langgraph-cli
3
- Version: 0.4.7
3
+ Version: 0.4.9
4
4
  Summary: CLI for interacting with LangGraph API
5
- Project-URL: Repository, https://www.github.com/langchain-ai/langgraph
5
+ Project-URL: Source, https://github.com/langchain-ai/langgraph/tree/main/libs/cli
6
+ Project-URL: Twitter, https://x.com/LangChainAI
7
+ Project-URL: Slack, https://www.langchain.com/join-community
8
+ Project-URL: Reddit, https://www.reddit.com/r/LangChain/
6
9
  License-Expression: MIT
7
10
  License-File: LICENSE
8
11
  Requires-Python: >=3.10
9
12
  Requires-Dist: click>=8.1.7
10
13
  Requires-Dist: langgraph-sdk>=0.1.0; python_version >= '3.11'
11
14
  Provides-Extra: inmem
12
- Requires-Dist: langgraph-api<0.6.0,>=0.4; (python_version >= '3.11') and extra == 'inmem'
15
+ Requires-Dist: langgraph-api<0.6.0,>=0.5.35; (python_version >= '3.11') and extra == 'inmem'
13
16
  Requires-Dist: langgraph-runtime-inmem>=0.7; (python_version >= '3.11') and extra == 'inmem'
14
17
  Requires-Dist: python-dotenv>=0.8.0; extra == 'inmem'
15
18
  Description-Content-Type: text/markdown
@@ -15,6 +15,7 @@ import msgspec
15
15
 
16
16
  from langgraph_cli.schemas import (
17
17
  AuthConfig,
18
+ CacheConfig,
18
19
  CheckpointerConfig,
19
20
  Config,
20
21
  ConfigurableHeaderConfig,
@@ -26,6 +27,8 @@ from langgraph_cli.schemas import (
26
27
  StoreConfig,
27
28
  ThreadTTLConfig,
28
29
  TTLConfig,
30
+ WebhooksConfig,
31
+ WebhookUrlPolicy,
29
32
  )
30
33
 
31
34
 
@@ -111,11 +114,14 @@ def add_descriptions_to_schema(schema, cls):
111
114
  SecurityConfig,
112
115
  HttpConfig,
113
116
  CorsConfig,
117
+ CacheConfig,
114
118
  ThreadTTLConfig,
115
119
  CheckpointerConfig,
116
120
  SerdeConfig,
117
121
  TTLConfig,
118
122
  ConfigurableHeaderConfig,
123
+ WebhooksConfig,
124
+ WebhookUrlPolicy,
119
125
  ]:
120
126
  if potential_cls.__name__ == def_name:
121
127
  add_descriptions_to_schema(def_schema, potential_cls)
@@ -0,0 +1,10 @@
1
+ root = true
2
+
3
+ [*]
4
+ end_of_line = lf
5
+ insert_final_newline = true
6
+
7
+ [*.{js,json,yml}]
8
+ charset = utf-8
9
+ indent_style = space
10
+ indent_size = 2
@@ -0,0 +1 @@
1
+ __version__ = "0.4.9"
@@ -760,6 +760,7 @@ def dev(
760
760
  http=config_json.get("http"),
761
761
  ui=config_json.get("ui"),
762
762
  ui_config=config_json.get("ui_config"),
763
+ webhooks=config_json.get("webhooks"),
763
764
  studio_url=studio_url,
764
765
  allow_blocking=allow_blocking,
765
766
  tunnel=tunnel,
@@ -154,7 +154,10 @@ def validate_config(config: Config) -> Config:
154
154
  "env": config.get("env", {}),
155
155
  "store": config.get("store"),
156
156
  "auth": config.get("auth"),
157
+ "encryption": config.get("encryption"),
157
158
  "http": config.get("http"),
159
+ # Pass through webhooks config so it can be injected into the image
160
+ "webhooks": config.get("webhooks"),
158
161
  "checkpointer": config.get("checkpointer"),
159
162
  "ui": config.get("ui"),
160
163
  "ui_config": config.get("ui_config"),
@@ -228,6 +231,14 @@ def validate_config(config: Config) -> Config:
228
231
  f"Invalid auth.path format: '{auth_conf['path']}'. "
229
232
  "Must be in format './path/to/file.py:attribute_name'"
230
233
  )
234
+ # Validate encryption config
235
+ if encryption_conf := config.get("encryption"):
236
+ if "path" in encryption_conf:
237
+ if ":" not in encryption_conf["path"]:
238
+ raise ValueError(
239
+ f"Invalid encryption.path format: '{encryption_conf['path']}'. "
240
+ "Must be in format './path/to/file.py:attribute_name'"
241
+ )
231
242
  if http_conf := config.get("http"):
232
243
  if "app" in http_conf:
233
244
  if ":" not in http_conf["app"]:
@@ -614,6 +625,49 @@ def _update_auth_path(
614
625
  )
615
626
 
616
627
 
628
+ def _update_encryption_path(
629
+ config_path: pathlib.Path, config: Config, local_deps: LocalDeps
630
+ ) -> None:
631
+ """Update encryption.path to use Docker container paths."""
632
+ encryption_conf = config.get("encryption")
633
+ if not encryption_conf or not (path_str := encryption_conf.get("path")):
634
+ return
635
+
636
+ module_str, sep, attr_str = path_str.partition(":")
637
+ if not sep or not module_str.startswith("."):
638
+ return # Already validated or absolute path
639
+
640
+ resolved = config_path.parent / module_str
641
+ if not resolved.exists():
642
+ raise FileNotFoundError(
643
+ f"Encryption file not found: {resolved} (from {path_str})"
644
+ )
645
+ if not resolved.is_file():
646
+ raise IsADirectoryError(f"Encryption path must be a file: {resolved}")
647
+
648
+ # Check faux packages first (higher priority)
649
+ for faux_path, (_, destpath) in local_deps.faux_pkgs.items():
650
+ if resolved.is_relative_to(faux_path):
651
+ new_path = f"{destpath}/{resolved.relative_to(faux_path)}:{attr_str}"
652
+ encryption_conf["path"] = new_path
653
+ return
654
+
655
+ # Check real packages
656
+ for real_path in local_deps.real_pkgs:
657
+ if resolved.is_relative_to(real_path):
658
+ new_path = (
659
+ f"/deps/{real_path.name}/{resolved.relative_to(real_path)}:{attr_str}"
660
+ )
661
+ encryption_conf["path"] = new_path
662
+ return
663
+
664
+ raise ValueError(
665
+ f"Encryption file '{resolved}' not covered by dependencies.\n"
666
+ "Add its parent directory to the 'dependencies' array in your config.\n"
667
+ f"Current dependencies: {config['dependencies']}"
668
+ )
669
+
670
+
617
671
  def _update_http_app_path(
618
672
  config_path: pathlib.Path, config: Config, local_deps: LocalDeps
619
673
  ) -> None:
@@ -809,6 +863,8 @@ def python_config_to_docker(
809
863
  _update_graph_paths(config_path, config, local_deps)
810
864
  # Rewrite auth path, so it points to the correct location in the Docker container
811
865
  _update_auth_path(config_path, config, local_deps)
866
+ # Rewrite encryption path, so it points to the correct location in the Docker container
867
+ _update_encryption_path(config_path, config, local_deps)
812
868
  # Rewrite HTTP app path, so it points to the correct location in the Docker container
813
869
  _update_http_app_path(config_path, config, local_deps)
814
870
 
@@ -899,9 +955,16 @@ ADD {relpath} /deps/{name}
899
955
  if (auth_config := config.get("auth")) is not None:
900
956
  env_vars.append(f"ENV LANGGRAPH_AUTH='{json.dumps(auth_config)}'")
901
957
 
958
+ if (encryption_config := config.get("encryption")) is not None:
959
+ env_vars.append(f"ENV LANGGRAPH_ENCRYPTION='{json.dumps(encryption_config)}'")
960
+
902
961
  if (http_config := config.get("http")) is not None:
903
962
  env_vars.append(f"ENV LANGGRAPH_HTTP='{json.dumps(http_config)}'")
904
963
 
964
+ # Inject webhooks configuration if provided
965
+ if (webhooks_config := config.get("webhooks")) is not None:
966
+ env_vars.append(f"ENV LANGGRAPH_WEBHOOKS='{json.dumps(webhooks_config)}'")
967
+
905
968
  if (checkpointer_config := config.get("checkpointer")) is not None:
906
969
  env_vars.append(
907
970
  f"ENV LANGGRAPH_CHECKPOINTER='{json.dumps(checkpointer_config)}'"
@@ -1022,9 +1085,16 @@ def node_config_to_docker(
1022
1085
  if (auth_config := config.get("auth")) is not None:
1023
1086
  env_vars.append(f"ENV LANGGRAPH_AUTH='{json.dumps(auth_config)}'")
1024
1087
 
1088
+ if (encryption_config := config.get("encryption")) is not None:
1089
+ env_vars.append(f"ENV LANGGRAPH_ENCRYPTION='{json.dumps(encryption_config)}'")
1090
+
1025
1091
  if (http_config := config.get("http")) is not None:
1026
1092
  env_vars.append(f"ENV LANGGRAPH_HTTP='{json.dumps(http_config)}'")
1027
1093
 
1094
+ # Inject webhooks configuration if provided
1095
+ if (webhooks_config := config.get("webhooks")) is not None:
1096
+ env_vars.append(f"ENV LANGGRAPH_WEBHOOKS='{json.dumps(webhooks_config)}'")
1097
+
1028
1098
  if (checkpointer_config := config.get("checkpointer")) is not None:
1029
1099
  env_vars.append(
1030
1100
  f"ENV LANGGRAPH_CHECKPOINTER='{json.dumps(checkpointer_config)}'"
@@ -233,6 +233,27 @@ class SecurityConfig(TypedDict, total=False):
233
233
  """
234
234
 
235
235
 
236
+ class CacheConfig(TypedDict, total=False):
237
+ cache_keys: list[str]
238
+ """Optional. List of header keys to use for caching.
239
+
240
+ Example:
241
+ ["user_id", "workspace_id"]
242
+ """
243
+ ttl_seconds: int
244
+ """Optional. Time-to-live in seconds for cached items.
245
+
246
+ Example:
247
+ 3600
248
+ """
249
+ max_size: int
250
+ """Optional. Maximum size of the cache.
251
+
252
+ Example:
253
+ 100
254
+ """
255
+
256
+
236
257
  class AuthConfig(TypedDict, total=False):
237
258
  """Configuration for custom authentication logic and how it integrates into the OpenAPI spec."""
238
259
 
@@ -269,6 +290,37 @@ class AuthConfig(TypedDict, total=False):
269
290
  ]
270
291
  }
271
292
  """
293
+ cache: CacheConfig
294
+ """Optional. Cache configuration for the server.
295
+
296
+ Example:
297
+ {
298
+ "cache_keys": ["user_id", "workspace_id"],
299
+ "ttl_seconds": 3600,
300
+ "max_size": 100
301
+ }
302
+ """
303
+
304
+
305
+ class EncryptionConfig(TypedDict, total=False):
306
+ """Configuration for custom at-rest encryption logic.
307
+
308
+ Allows you to implement custom encryption for sensitive data stored in the database,
309
+ including metadata fields and checkpoint blobs.
310
+ """
311
+
312
+ path: str
313
+ """Required. Path to an instance of the Encryption() class that implements custom encryption handlers.
314
+
315
+ Format: "path/to/file.py:my_encryption"
316
+
317
+ Example:
318
+ {
319
+ "encryption": {
320
+ "path": "./encryption.py:my_encryption"
321
+ }
322
+ }
323
+ """
272
324
 
273
325
 
274
326
  class CorsConfig(TypedDict, total=False):
@@ -310,7 +362,7 @@ class CorsConfig(TypedDict, total=False):
310
362
  """
311
363
 
312
364
 
313
- class ConfigurableHeaderConfig(TypedDict):
365
+ class ConfigurableHeaderConfig(TypedDict, total=False):
314
366
  """Customize which headers to include as configurable values in your runs.
315
367
 
316
368
  By default, omits x-api-key, x-tenant-id, and x-service-key.
@@ -321,7 +373,7 @@ class ConfigurableHeaderConfig(TypedDict):
321
373
  """
322
374
 
323
375
  includes: list[str] | None
324
- """Headers to include (if not also matches against an 'exludes' pattern.
376
+ """Headers to include (if not also matched against an 'excludes' pattern).
325
377
 
326
378
  Examples:
327
379
  - 'user-agent'
@@ -367,7 +419,12 @@ class HttpConfig(TypedDict, total=False):
367
419
  Default is False.
368
420
  """
369
421
  disable_mcp: bool
370
- """Optional. If `True`, /mcp routes are removed, disabling the MCP server.
422
+ """Optional. If `True`, /mcp routes are removed, disabling default support to expose the deployment as an MCP server.
423
+
424
+ Default is False.
425
+ """
426
+ disable_a2a: bool
427
+ """Optional. If `True`, /a2a routes are removed, disabling default support to expose the deployment as an agent-to-agent (A2A) server.
371
428
 
372
429
  Default is False.
373
430
  """
@@ -377,6 +434,17 @@ class HttpConfig(TypedDict, total=False):
377
434
  Set to True to disable the following endpoints: /openapi.json, /info, /metrics, /docs.
378
435
  This will also make the /ok endpoint skip any DB or other checks, always returning {"ok": True}.
379
436
 
437
+ Default is False.
438
+ """
439
+ disable_ui: bool
440
+ """Optional. If `True`, /ui routes are removed, disabling the UI server.
441
+
442
+ Default is False.
443
+ """
444
+ disable_webhooks: bool
445
+ """Optional. If `True`, webhooks are disabled. Runs created with an associated webhook will
446
+ still be executed, but the webhook event will not be sent.
447
+
380
448
  Default is False.
381
449
  """
382
450
  cors: CorsConfig | None
@@ -409,6 +477,52 @@ class HttpConfig(TypedDict, total=False):
409
477
  Default is False. This flag only affects authentication behavior
410
478
  if `app` is provided and contains custom routes.
411
479
  """
480
+ mount_prefix: str
481
+ """Optional. URL prefix to prepend to all the routes.
482
+
483
+ Example:
484
+ "/api"
485
+ """
486
+
487
+
488
+ class WebhookUrlPolicy(TypedDict, total=False):
489
+ require_https: bool
490
+ """Enforce HTTPS scheme for absolute URLs; reject `http://` when true."""
491
+ allowed_domains: list[str]
492
+ """Hostname allowlist. Supports exact hosts and wildcard subdomains.
493
+
494
+ Use entries like "hooks.example.com" or "*.mycorp.com". The wildcard only
495
+ matches subdomains ("foo.mycorp.com"), not the apex ("mycorp.com"). When
496
+ empty or omitted, any public host is allowed (subject to SSRF IP checks).
497
+ """
498
+ allowed_ports: list[int]
499
+ """Explicit port allowlist for absolute URLs.
500
+
501
+ If set, requests must use one of these ports. Defaults are respected when
502
+ a port is not present in the URL (443 for https, 80 for http).
503
+ """
504
+ max_url_length: int
505
+ """Maximum permitted URL length in characters; longer inputs are rejected early."""
506
+ disable_loopback: bool
507
+ """Disallow relative URLs (internal loopback calls) when true."""
508
+
509
+
510
+ class WebhooksConfig(TypedDict, total=False):
511
+ env_prefix: str
512
+ """Required prefix for environment variables referenced in header templates.
513
+
514
+ Acts as an allowlist boundary to prevent leaking arbitrary environment
515
+ variables. Defaults to "LG_WEBHOOK_" when omitted.
516
+ """
517
+ url: WebhookUrlPolicy
518
+ """URL validation policy for user-supplied webhook endpoints."""
519
+ headers: dict[str, str]
520
+ """Static headers to include with webhook requests.
521
+
522
+ Values may contain templates of the form "${{ env.VAR }}". On startup, these
523
+ are resolved via the process environment after verifying `VAR` starts with
524
+ `env_prefix`. Mixed literals and multiple templates are allowed.
525
+ """
412
526
 
413
527
 
414
528
  class Config(TypedDict, total=False):
@@ -524,15 +638,28 @@ class Config(TypedDict, total=False):
524
638
  """
525
639
 
526
640
  auth: AuthConfig | None
527
- """Optional. Custom authentication config, including the path to your Python auth logic and
641
+ """Optional. Custom authentication config, including the path to your Python auth logic and
528
642
  the OpenAPI security definitions it uses.
529
643
  """
530
644
 
645
+ encryption: EncryptionConfig | None
646
+ """Optional. Custom at-rest encryption config, including the path to your Python encryption logic.
647
+
648
+ Allows you to implement custom encryption for sensitive data stored in the database.
649
+ """
650
+
531
651
  http: HttpConfig | None
532
652
  """Optional. Configuration for the built-in HTTP server, controlling which custom routes are exposed
533
653
  and how cross-origin requests are handled.
534
654
  """
535
655
 
656
+ webhooks: WebhooksConfig | None
657
+ """Optional. Webhooks configuration for outbound event delivery.
658
+
659
+ Forwarded into the container as `LANGGRAPH_WEBHOOKS`. See `WebhooksConfig`
660
+ for URL policy and header templating details.
661
+ """
662
+
536
663
  ui: dict[str, str] | None
537
664
  """Optional. Named definitions of UI components emitted by the agent, each pointing to a JS/TS file.
538
665
  """
@@ -550,6 +677,7 @@ __all__ = [
550
677
  "StoreConfig",
551
678
  "CheckpointerConfig",
552
679
  "AuthConfig",
680
+ "EncryptionConfig",
553
681
  "HttpConfig",
554
682
  "MiddlewareOrders",
555
683
  "Distros",
@@ -19,13 +19,16 @@ dependencies = [
19
19
  path = "langgraph_cli/__init__.py"
20
20
  [project.optional-dependencies]
21
21
  inmem = [
22
- "langgraph-api>=0.4,<0.6.0 ; python_version >= '3.11'",
22
+ "langgraph-api>=0.5.35,<0.6.0 ; python_version >= '3.11'",
23
23
  "langgraph-runtime-inmem>=0.7 ; python_version >= '3.11'",
24
24
  "python-dotenv>=0.8.0",
25
25
  ]
26
26
 
27
27
  [project.urls]
28
- Repository = "https://www.github.com/langchain-ai/langgraph"
28
+ Source = "https://github.com/langchain-ai/langgraph/tree/main/libs/cli"
29
+ Twitter = "https://x.com/LangChainAI"
30
+ Slack = "https://www.langchain.com/join-community"
31
+ Reddit = "https://www.reddit.com/r/LangChain/"
29
32
 
30
33
  [project.scripts]
31
34
  langgraph = "langgraph_cli.cli:cli"
@@ -46,6 +49,7 @@ lint = [
46
49
  dev = [
47
50
  {include-group = "test"},
48
51
  {include-group = "lint"},
52
+ "hatch>=1.16.2",
49
53
  ]
50
54
 
51
55
  [tool.uv]