deepagents-cli 0.0.31__tar.gz → 0.0.33__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 (168) hide show
  1. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/CHANGELOG.md +62 -0
  2. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/Makefile +3 -2
  3. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/PKG-INFO +22 -8
  4. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/README.md +2 -2
  5. deepagents_cli-0.0.33/deepagents_cli/_debug.py +50 -0
  6. deepagents_cli-0.0.33/deepagents_cli/_server_config.py +320 -0
  7. deepagents_cli-0.0.33/deepagents_cli/_server_constants.py +4 -0
  8. deepagents_cli-0.0.33/deepagents_cli/_testing_models.py +144 -0
  9. deepagents_cli-0.0.33/deepagents_cli/_version.py +3 -0
  10. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/agent.py +144 -54
  11. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/app.py +649 -596
  12. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/app.tcss +5 -2
  13. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/config.py +103 -20
  14. deepagents_cli-0.0.33/deepagents_cli/configurable_model.py +133 -0
  15. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/input.py +11 -2
  16. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/integrations/daytona.py +6 -1
  17. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/integrations/sandbox_factory.py +6 -2
  18. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/main.py +142 -156
  19. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/mcp_tools.py +36 -9
  20. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/model_config.py +307 -43
  21. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/non_interactive.py +88 -117
  22. deepagents_cli-0.0.33/deepagents_cli/offload.py +371 -0
  23. deepagents_cli-0.0.33/deepagents_cli/output.py +69 -0
  24. deepagents_cli-0.0.33/deepagents_cli/project_utils.py +188 -0
  25. deepagents_cli-0.0.33/deepagents_cli/remote_client.py +515 -0
  26. deepagents_cli-0.0.33/deepagents_cli/server.py +513 -0
  27. deepagents_cli-0.0.33/deepagents_cli/server_graph.py +190 -0
  28. deepagents_cli-0.0.33/deepagents_cli/server_manager.py +351 -0
  29. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/sessions.py +151 -31
  30. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/skills/commands.py +183 -51
  31. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/textual_adapter.py +95 -48
  32. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/ui.py +70 -59
  33. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/widgets/approval.py +42 -22
  34. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/widgets/ask_user.py +25 -27
  35. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/widgets/autocomplete.py +18 -2
  36. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/widgets/chat_input.py +72 -24
  37. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/widgets/diff.py +47 -39
  38. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/widgets/history.py +18 -2
  39. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/widgets/loading.py +3 -2
  40. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/widgets/mcp_viewer.py +27 -15
  41. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/widgets/messages.py +160 -142
  42. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/widgets/model_selector.py +135 -56
  43. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/widgets/status.py +6 -10
  44. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/widgets/thread_selector.py +104 -25
  45. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/widgets/tool_widgets.py +39 -27
  46. deepagents_cli-0.0.33/deepagents_cli/widgets/welcome.py +268 -0
  47. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/pyproject.toml +18 -6
  48. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/scripts/install.sh +1 -1
  49. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +9 -12
  50. deepagents_cli-0.0.33/tests/integration_tests/test_compact_resume.py +223 -0
  51. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/integration_tests/test_sandbox_operations.py +229 -125
  52. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/conftest.py +22 -0
  53. deepagents_cli-0.0.33/tests/unit_tests/skills/test_skills_json.py +154 -0
  54. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_agent.py +368 -6
  55. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_app.py +114 -0
  56. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_approval.py +25 -28
  57. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_args.py +60 -2
  58. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_autocomplete.py +8 -8
  59. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_chat_input.py +142 -4
  60. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_config.py +43 -1
  61. deepagents_cli-0.0.33/tests/unit_tests/test_configurable_model.py +412 -0
  62. deepagents_cli-0.0.33/tests/unit_tests/test_debug.py +69 -0
  63. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_end_to_end.py +7 -0
  64. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_main.py +145 -16
  65. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_main_acp_mode.py +20 -12
  66. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_mcp_tools.py +99 -0
  67. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_message_store.py +2 -2
  68. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_messages.py +76 -42
  69. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_model_config.py +695 -18
  70. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_model_selector.py +165 -19
  71. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_model_switch.py +184 -356
  72. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_non_interactive.py +89 -241
  73. deepagents_cli-0.0.33/tests/unit_tests/test_offload.py +1390 -0
  74. deepagents_cli-0.0.33/tests/unit_tests/test_output.py +62 -0
  75. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_reload.py +4 -2
  76. deepagents_cli-0.0.33/tests/unit_tests/test_remote_client.py +615 -0
  77. deepagents_cli-0.0.33/tests/unit_tests/test_server.py +285 -0
  78. deepagents_cli-0.0.33/tests/unit_tests/test_server_config.py +217 -0
  79. deepagents_cli-0.0.33/tests/unit_tests/test_server_graph.py +129 -0
  80. deepagents_cli-0.0.33/tests/unit_tests/test_server_helpers.py +95 -0
  81. deepagents_cli-0.0.33/tests/unit_tests/test_server_manager.py +266 -0
  82. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_sessions.py +381 -71
  83. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_textual_adapter.py +23 -2
  84. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_thread_selector.py +249 -30
  85. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_version.py +0 -2
  86. deepagents_cli-0.0.33/tests/unit_tests/test_welcome.py +423 -0
  87. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/uv.lock +627 -33
  88. deepagents_cli-0.0.31/deepagents_cli/_version.py +0 -3
  89. deepagents_cli-0.0.31/deepagents_cli/project_utils.py +0 -59
  90. deepagents_cli-0.0.31/deepagents_cli/widgets/welcome.py +0 -164
  91. deepagents_cli-0.0.31/tests/unit_tests/test_compact.py +0 -1134
  92. deepagents_cli-0.0.31/tests/unit_tests/test_welcome.py +0 -225
  93. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/.gitignore +0 -0
  94. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/__init__.py +0 -0
  95. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/__main__.py +0 -0
  96. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/ask_user.py +0 -0
  97. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/built_in_skills/__init__.py +0 -0
  98. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/built_in_skills/skill-creator/SKILL.md +0 -0
  99. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
  100. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
  101. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/clipboard.py +0 -0
  102. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/default_agent_prompt.md +0 -0
  103. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/file_ops.py +0 -0
  104. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/hooks.py +0 -0
  105. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/integrations/__init__.py +0 -0
  106. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/integrations/langsmith.py +0 -0
  107. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/integrations/modal.py +0 -0
  108. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/integrations/runloop.py +0 -0
  109. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/integrations/sandbox_provider.py +0 -0
  110. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/local_context.py +0 -0
  111. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/mcp_trust.py +0 -0
  112. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/media_utils.py +0 -0
  113. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/py.typed +0 -0
  114. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/skills/__init__.py +0 -0
  115. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/skills/load.py +0 -0
  116. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/subagents.py +0 -0
  117. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/system_prompt.md +0 -0
  118. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/tool_display.py +0 -0
  119. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/tools.py +0 -0
  120. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/unicode_security.py +0 -0
  121. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/update_check.py +0 -0
  122. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/widgets/__init__.py +0 -0
  123. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/widgets/_links.py +0 -0
  124. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/widgets/message_store.py +0 -0
  125. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/deepagents_cli/widgets/tool_renderers.py +0 -0
  126. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/examples/skills/arxiv-search/SKILL.md +0 -0
  127. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/examples/skills/arxiv-search/arxiv_search.py +0 -0
  128. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/examples/skills/langgraph-docs/SKILL.md +0 -0
  129. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/examples/skills/skill-creator/SKILL.md +0 -0
  130. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
  131. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
  132. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/examples/skills/web-research/SKILL.md +0 -0
  133. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/images/cli.png +0 -0
  134. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/scripts/check_imports.py +0 -0
  135. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/README.md +0 -0
  136. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/integration_tests/__init__.py +0 -0
  137. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/integration_tests/benchmarks/__init__.py +0 -0
  138. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/integration_tests/conftest.py +0 -0
  139. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/integration_tests/test_acp_mode.py +0 -0
  140. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/integration_tests/test_sandbox_factory.py +0 -0
  141. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/__init__.py +0 -0
  142. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/skills/__init__.py +0 -0
  143. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/skills/test_commands.py +0 -0
  144. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/skills/test_load.py +0 -0
  145. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_ask_user.py +0 -0
  146. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_ask_user_middleware.py +0 -0
  147. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_charset.py +0 -0
  148. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_compact_tool.py +0 -0
  149. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_exception_handling.py +0 -0
  150. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_file_ops.py +0 -0
  151. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_history.py +0 -0
  152. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_hooks.py +0 -0
  153. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_imports.py +0 -0
  154. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_input_parsing.py +0 -0
  155. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_local_context.py +0 -0
  156. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_main_args.py +0 -0
  157. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_mcp_trust.py +0 -0
  158. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_mcp_viewer.py +0 -0
  159. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_media_utils.py +0 -0
  160. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_shell_allow_list.py +0 -0
  161. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_status.py +0 -0
  162. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_subagents.py +0 -0
  163. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_token_tracker.py +0 -0
  164. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_ui.py +0 -0
  165. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_unicode_security.py +0 -0
  166. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/test_update_check.py +0 -0
  167. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/tools/__init__.py +0 -0
  168. {deepagents_cli-0.0.31 → deepagents_cli-0.0.33}/tests/unit_tests/tools/test_fetch_url.py +0 -0
@@ -1,5 +1,67 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.0.33](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.32...deepagents-cli==0.0.33) (2026-03-16)
4
+
5
+ ### Highlights
6
+
7
+ * **Client-server architecture:** The CLI can now connect to a remote agent backend via `langgraph dev`, decoupling the UI from the runtime and unlocking server-side execution workflows.
8
+ * **Expanded model ecosystem:** Added LiteLLM and Baseten as built-in providers. The `/model` selector now shows live model status, supports an `enabled` flag to hide providers, and auto-discovers models for `class_path` (arbitrary) providers.
9
+ * **CLI ergonomics:** New `-y` and `-S` short flags for `--auto-approve` and `--shell-allow-list`. The `ask_user` tool is now enabled by default, and the welcome banner rotates helpful tips.
10
+ * **Performance:** Integrated `textual-speedups` for Rust-based layout primitives, switched the messages container to stream layout, and offloaded blocking path ops from the event loop — noticeably snappier on long conversations.
11
+ * **Stability:** 15 bug fixes covering markup injection, scrollbar flicker during streaming, reentrant model switching, and autocomplete race conditions.
12
+
13
+ ### Features
14
+
15
+ * Client-server architecture via `langgraph dev` ([#1759](https://github.com/langchain-ai/deepagents/issues/1759)) ([f5407e6](https://github.com/langchain-ai/deepagents/commit/f5407e6300e6ee51d8c88f1f183dd960b30a5b56))
16
+ * Show model status in `/model` selector ([#1820](https://github.com/langchain-ai/deepagents/issues/1820)) ([92ce0cf](https://github.com/langchain-ai/deepagents/commit/92ce0cffde6f49131541b5985bc80058ae0ad46e))
17
+ * Enable `ask_user` tool by default ([#1830](https://github.com/langchain-ai/deepagents/issues/1830)) ([ed0c745](https://github.com/langchain-ai/deepagents/commit/ed0c745eef8d8fad40aa39b0dfd4de2ba9988fe5))
18
+ * Add `-y` and `-S` short flags for auto-approve and shell-allow-list ([#1919](https://github.com/langchain-ai/deepagents/issues/1919)) ([1036b16](https://github.com/langchain-ai/deepagents/commit/1036b16276d59d8be669d963901c91aeb8cc2236))
19
+ * Add `enabled` flag to hide providers from `/model` switcher ([#1897](https://github.com/langchain-ai/deepagents/issues/1897)) ([72a216c](https://github.com/langchain-ai/deepagents/commit/72a216c88f661f9e53eaf92aedce40fac7b76d3c))
20
+ * Add `litellm` optional dep ([#1818](https://github.com/langchain-ai/deepagents/issues/1818)) ([defa21b](https://github.com/langchain-ai/deepagents/commit/defa21bc6eea596bc67e70372e022d5b78049c0d))
21
+ * Add `sessions` as hidden keyword alias for `/threads` ([#1823](https://github.com/langchain-ai/deepagents/issues/1823)) ([ffa98cc](https://github.com/langchain-ai/deepagents/commit/ffa98ccf9ebe12eadb7f0e95f278dd9bd8eca240))
22
+ * Add Baseten as a built-in model provider/optional dep ([#1819](https://github.com/langchain-ai/deepagents/issues/1819)) ([e05ee66](https://github.com/langchain-ai/deepagents/commit/e05ee66b0d6c5cb996208d554686fc128f1094a2))
23
+ * Add rotating tips to welcome banner ([#1898](https://github.com/langchain-ai/deepagents/issues/1898)) ([d882ca8](https://github.com/langchain-ai/deepagents/commit/d882ca81e2c9a11768a07824fd5b5ce8579bdcd7))
24
+ * Add sandbox type to trace metadata ([#1845](https://github.com/langchain-ai/deepagents/issues/1845)) ([59ef941](https://github.com/langchain-ai/deepagents/commit/59ef94143fc0adabb5f70f308527d98aa1511e44))
25
+ * Show versions in non-interactive header ([#1881](https://github.com/langchain-ai/deepagents/issues/1881)) ([adacc3f](https://github.com/langchain-ai/deepagents/commit/adacc3fd0a0f040373b8ef39032978019b5c8e5f))
26
+ * Show editable install source path in help and banner ([#1916](https://github.com/langchain-ai/deepagents/issues/1916)) ([4ce1cee](https://github.com/langchain-ai/deepagents/commit/4ce1ceebdd2e4aa6db008061519d3df1e422c2db))
27
+
28
+ ### Bug Fixes
29
+
30
+ * Replace per-chunk `scroll_end` with anchor to fix scrollbar flicker ([#1891](https://github.com/langchain-ai/deepagents/issues/1891)) ([a9be236](https://github.com/langchain-ai/deepagents/commit/a9be2368509f9f2c66537014ae2138253cf0dc39))
31
+ * Auto-discover models for `class_path` providers ([#1816](https://github.com/langchain-ai/deepagents/issues/1816)) ([177fe0f](https://github.com/langchain-ai/deepagents/commit/177fe0f663926d6879aa2177b7988d45cd1e4055))
32
+ * Correct model selector footer showing wrong profile after search ([#1805](https://github.com/langchain-ai/deepagents/issues/1805)) ([2f1d52f](https://github.com/langchain-ai/deepagents/commit/2f1d52f4ad65add210d6f840b1b78e62eba37195))
33
+ * Escape dynamic strings in rich markup to prevent markup injection ([#1888](https://github.com/langchain-ai/deepagents/issues/1888)) ([d349d10](https://github.com/langchain-ai/deepagents/commit/d349d1061647325fdb4ea6322254b24555abf751))
34
+ * Forward `DAYTONA_API_URL` to avoid deprecated `server_url` access ([#1844](https://github.com/langchain-ai/deepagents/issues/1844)) ([7d19ca8](https://github.com/langchain-ai/deepagents/commit/7d19ca8e6404a2ea98aac6a9d4cae7a2b529922c))
35
+ * Let unknown providers through credential check ([#1815](https://github.com/langchain-ai/deepagents/issues/1815)) ([89d39de](https://github.com/langchain-ai/deepagents/commit/89d39ded171bf300e9b17972f18063e9157f298f))
36
+ * Persist `models.recent` on every session start ([#1802](https://github.com/langchain-ai/deepagents/issues/1802)) ([32aa371](https://github.com/langchain-ai/deepagents/commit/32aa371a371208146cc093c4e5eb7a752a74b3c9))
37
+ * Prevent reentrant model switching ([#1824](https://github.com/langchain-ai/deepagents/issues/1824)) ([09d16a8](https://github.com/langchain-ai/deepagents/commit/09d16a8151466fd2d82976d44d7b4e957255bcd9))
38
+ * Remove double slash in skills path template ([#1808](https://github.com/langchain-ai/deepagents/issues/1808)) ([2bc9620](https://github.com/langchain-ai/deepagents/commit/2bc962075146548f2ef4c8851bd502df9d6a1fa5))
39
+ * Show checkmark for `class_path` providers in model selector ([#1899](https://github.com/langchain-ai/deepagents/issues/1899)) ([4adb712](https://github.com/langchain-ai/deepagents/commit/4adb712c8eacbcfbc06801c31bfd74fc0705bed3))
40
+ * Sort prefetched threads by user preference on initial render ([#1806](https://github.com/langchain-ai/deepagents/issues/1806)) ([6f71153](https://github.com/langchain-ai/deepagents/commit/6f711532976821a92e3396fe458ec7874b1237ef))
41
+ * Use `max-height` for `tool-info-scroll` to shrink-wrap content ([#1835](https://github.com/langchain-ai/deepagents/issues/1835)) ([a4e1908](https://github.com/langchain-ai/deepagents/commit/a4e1908527c3a30a6f967dd1d989739d540ddd2a))
42
+ * Use ASCII-safe glyphs in tool status restore path ([#1895](https://github.com/langchain-ai/deepagents/issues/1895)) ([2a9cbc8](https://github.com/langchain-ai/deepagents/commit/2a9cbc8540b2ab77362cbb00764a3533e234891f))
43
+ * Use counter to close history-recall autocomplete race ([#1901](https://github.com/langchain-ai/deepagents/issues/1901)) ([bfd08af](https://github.com/langchain-ai/deepagents/commit/bfd08afbc0eca844e565842dff50eddb067e4750))
44
+ * Use UUID7 for thread IDs instead of 8-char hex ([#1826](https://github.com/langchain-ai/deepagents/issues/1826)) ([821885b](https://github.com/langchain-ai/deepagents/commit/821885bab8ae2eef873a33fdaa6dc427a473d764))
45
+
46
+ ### Performance Improvements
47
+
48
+ * Add `textual-speedups` for Rust-based layout primitives ([#1910](https://github.com/langchain-ai/deepagents/issues/1910)) ([45b58a1](https://github.com/langchain-ai/deepagents/commit/45b58a13e14abfb58ef3688cee51a5819d8ca52d))
49
+ * Use stream layout for messages container ([#1896](https://github.com/langchain-ai/deepagents/issues/1896)) ([b35401b](https://github.com/langchain-ai/deepagents/commit/b35401b885a7651db548f1826ddb24476ecde5b7))
50
+ * Offload blocking path ops from textual event loop ([#1894](https://github.com/langchain-ai/deepagents/issues/1894)) ([d3eedcc](https://github.com/langchain-ai/deepagents/commit/d3eedccc7edd21103ca1e586fc365d721f674099))
51
+ * Speed up `/model` selector with cache pre-warming and async saves ([#1813](https://github.com/langchain-ai/deepagents/issues/1813)) ([2aec75c](https://github.com/langchain-ai/deepagents/commit/2aec75c8dca6c0510671cf1288a924c4ca9bce1c))
52
+ * Speed up `/threads` modal startup ([#1811](https://github.com/langchain-ai/deepagents/issues/1811)) ([5758df1](https://github.com/langchain-ai/deepagents/commit/5758df1b663cd09726b8cd08d86897351142ed5e))
53
+
54
+ ## [0.0.32](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.31...deepagents-cli==0.0.32) (2026-03-11)
55
+
56
+ ### Features
57
+
58
+ * Add token breakdown to `/tokens` and simplify `/compact` messages ([#1782](https://github.com/langchain-ai/deepagents/issues/1782)) ([2f37bff](https://github.com/langchain-ai/deepagents/commit/2f37bffa9d7a9ced6945abe4ab6bc3409bfb97b1))
59
+ * `--json` flag for machine-readable output ([#1768](https://github.com/langchain-ai/deepagents/issues/1768)) ([6f62496](https://github.com/langchain-ai/deepagents/commit/6f62496bb699dfa6086ee1850b83f38d3b1242fa))
60
+
61
+ ### Bug Fixes
62
+
63
+ * Work around VS Code 1.110 space key regression ([#1748](https://github.com/langchain-ai/deepagents/issues/1748)) ([f5fe431](https://github.com/langchain-ai/deepagents/commit/f5fe4315143bf5b636cf42fc98cbfe3d99918cfc))
64
+
3
65
  ## [0.0.31](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.30...deepagents-cli==0.0.31) (2026-03-09)
4
66
 
5
67
  ### Features
@@ -13,11 +13,12 @@ UV_FROZEN = true
13
13
  TEST_FILE ?= tests/unit_tests/
14
14
  integration_test integration_tests: TEST_FILE=tests/integration_tests/
15
15
 
16
+ COV_ARGS ?= --cov=deepagents_cli --cov-report=term-missing
17
+
16
18
  test: ## Run unit tests
17
19
  test tests:
18
20
  uv run --group test pytest -n auto --disable-socket --allow-unix-socket $(TEST_FILE) \
19
- --cov=deepagents_cli \
20
- --cov-report=term-missing
21
+ $(COV_ARGS)
21
22
 
22
23
  coverage: ## Run unit tests with coverage
23
24
  uv run --group test pytest --cov \
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepagents-cli
3
- Version: 0.0.31
3
+ Version: 0.0.33
4
4
  Summary: Terminal interface for Deep Agents - interactive AI agent with file operations, shell access, and sub-agent capabilities.
5
5
  Project-URL: Homepage, https://docs.langchain.com/oss/python/deepagents/overview
6
6
  Project-URL: Documentation, https://reference.langchain.com/python/deepagents/
@@ -26,11 +26,17 @@ Requires-Python: <4.0,>=3.11
26
26
  Requires-Dist: aiosqlite<1.0.0,>=0.19.0
27
27
  Requires-Dist: daytona<1.0.0,>=0.113.0
28
28
  Requires-Dist: deepagents-acp>=0.0.4
29
- Requires-Dist: deepagents==0.4.7
29
+ Requires-Dist: deepagents==0.4.11
30
+ Requires-Dist: httpx<1.0.0,>=0.28.1
31
+ Requires-Dist: langchain-anthropic<2.0.0,>=1.3.5
32
+ Requires-Dist: langchain-google-genai<5.0.0,>=4.2.1
30
33
  Requires-Dist: langchain-mcp-adapters<1.0.0,>=0.2.0
31
34
  Requires-Dist: langchain-openai<2.0.0,>=1.1.8
32
35
  Requires-Dist: langchain<2.0.0,>=1.2.10
33
36
  Requires-Dist: langgraph-checkpoint-sqlite<4.0.0,>=3.0.0
37
+ Requires-Dist: langgraph-cli[inmem]<1.0.0,>=0.4.15
38
+ Requires-Dist: langgraph-sdk<1.0.0,>=0.3.11
39
+ Requires-Dist: langgraph<2.0.0,>=1.1.2
34
40
  Requires-Dist: langsmith[sandbox]>=0.7.7
35
41
  Requires-Dist: markdownify<2.0.0,>=0.13.0
36
42
  Requires-Dist: modal<2.0.0,>=0.65.0
@@ -44,19 +50,23 @@ Requires-Dist: rich<15.0.0,>=14.0.0
44
50
  Requires-Dist: runloop-api-client>=0.69.0
45
51
  Requires-Dist: tavily-python<1.0.0,>=0.7.21
46
52
  Requires-Dist: textual-autocomplete<5.0.0,>=3.0.0
53
+ Requires-Dist: textual-speedups<1.0.0,>=0.2.1
47
54
  Requires-Dist: textual<9.0.0,>=8.0.0
48
55
  Requires-Dist: tomli-w<2.0.0,>=1.0.0
56
+ Requires-Dist: uuid-utils<1.0.0,>=0.10.0
49
57
  Provides-Extra: all-providers
50
- Requires-Dist: langchain-anthropic<2.0.0,>=1.0.0; extra == 'all-providers'
58
+ Requires-Dist: langchain-anthropic<2.0.0,>=1.3.5; extra == 'all-providers'
51
59
  Requires-Dist: langchain-aws<2.0.0,>=1.0.0; extra == 'all-providers'
60
+ Requires-Dist: langchain-baseten<1.0.0,>=0.1.9; extra == 'all-providers'
52
61
  Requires-Dist: langchain-cohere<1.0.0,>=0.5.0; extra == 'all-providers'
53
62
  Requires-Dist: langchain-deepseek<2.0.0,>=1.0.0; extra == 'all-providers'
54
63
  Requires-Dist: langchain-fireworks<2.0.0,>=1.0.0; extra == 'all-providers'
55
- Requires-Dist: langchain-google-genai<5.0.0,>=4.0.0; extra == 'all-providers'
64
+ Requires-Dist: langchain-google-genai<5.0.0,>=4.2.1; extra == 'all-providers'
56
65
  Requires-Dist: langchain-google-vertexai<4.0.0,>=3.0.0; extra == 'all-providers'
57
66
  Requires-Dist: langchain-groq<2.0.0,>=1.0.0; extra == 'all-providers'
58
67
  Requires-Dist: langchain-huggingface<2.0.0,>=1.0.0; extra == 'all-providers'
59
68
  Requires-Dist: langchain-ibm<2.0.0,>=1.0.0; extra == 'all-providers'
69
+ Requires-Dist: langchain-litellm<2.0.0,>=0.6.1; extra == 'all-providers'
60
70
  Requires-Dist: langchain-mistralai<2.0.0,>=1.0.0; extra == 'all-providers'
61
71
  Requires-Dist: langchain-nvidia-ai-endpoints<2.0.0,>=1.0.0; extra == 'all-providers'
62
72
  Requires-Dist: langchain-ollama<2.0.0,>=1.0.0; extra == 'all-providers'
@@ -65,7 +75,9 @@ Requires-Dist: langchain-openrouter<2.0.0,>=0.1.0; extra == 'all-providers'
65
75
  Requires-Dist: langchain-perplexity<2.0.0,>=1.0.0; extra == 'all-providers'
66
76
  Requires-Dist: langchain-xai<2.0.0,>=1.0.0; extra == 'all-providers'
67
77
  Provides-Extra: anthropic
68
- Requires-Dist: langchain-anthropic<2.0.0,>=1.0.0; extra == 'anthropic'
78
+ Requires-Dist: langchain-anthropic<2.0.0,>=1.3.5; extra == 'anthropic'
79
+ Provides-Extra: baseten
80
+ Requires-Dist: langchain-baseten<1.0.0,>=0.1.9; extra == 'baseten'
69
81
  Provides-Extra: bedrock
70
82
  Requires-Dist: langchain-aws<2.0.0,>=1.0.0; extra == 'bedrock'
71
83
  Provides-Extra: cohere
@@ -75,13 +87,15 @@ Requires-Dist: langchain-deepseek<2.0.0,>=1.0.0; extra == 'deepseek'
75
87
  Provides-Extra: fireworks
76
88
  Requires-Dist: langchain-fireworks<2.0.0,>=1.0.0; extra == 'fireworks'
77
89
  Provides-Extra: google-genai
78
- Requires-Dist: langchain-google-genai<5.0.0,>=4.0.0; extra == 'google-genai'
90
+ Requires-Dist: langchain-google-genai<5.0.0,>=4.2.1; extra == 'google-genai'
79
91
  Provides-Extra: groq
80
92
  Requires-Dist: langchain-groq<2.0.0,>=1.0.0; extra == 'groq'
81
93
  Provides-Extra: huggingface
82
94
  Requires-Dist: langchain-huggingface<2.0.0,>=1.0.0; extra == 'huggingface'
83
95
  Provides-Extra: ibm
84
96
  Requires-Dist: langchain-ibm<2.0.0,>=1.0.0; extra == 'ibm'
97
+ Provides-Extra: litellm
98
+ Requires-Dist: langchain-litellm<2.0.0,>=0.6.1; extra == 'litellm'
85
99
  Provides-Extra: mistralai
86
100
  Requires-Dist: langchain-mistralai<2.0.0,>=1.0.0; extra == 'mistralai'
87
101
  Provides-Extra: nvidia
@@ -114,12 +128,12 @@ Description-Content-Type: text/markdown
114
128
  ## Quick Install
115
129
 
116
130
  ```bash
117
- curl -LsSf https://raw.githubusercontent.com/langchain-ai/deepagents/main/scripts/install.sh | bash
131
+ curl -LsSf https://raw.githubusercontent.com/langchain-ai/deepagents/main/libs/cli/scripts/install.sh | bash
118
132
  ```
119
133
 
120
134
  ```bash
121
135
  # With model provider extras (OpenAI is included by default)
122
- DEEPAGENTS_EXTRAS="anthropic,groq" curl -LsSf https://raw.githubusercontent.com/langchain-ai/deepagents/main/scripts/install.sh | bash
136
+ DEEPAGENTS_EXTRAS="anthropic,groq" curl -LsSf https://raw.githubusercontent.com/langchain-ai/deepagents/main/libs/cli/scripts/install.sh | bash
123
137
  ```
124
138
 
125
139
  Or install directly with `uv`:
@@ -12,12 +12,12 @@
12
12
  ## Quick Install
13
13
 
14
14
  ```bash
15
- curl -LsSf https://raw.githubusercontent.com/langchain-ai/deepagents/main/scripts/install.sh | bash
15
+ curl -LsSf https://raw.githubusercontent.com/langchain-ai/deepagents/main/libs/cli/scripts/install.sh | bash
16
16
  ```
17
17
 
18
18
  ```bash
19
19
  # With model provider extras (OpenAI is included by default)
20
- DEEPAGENTS_EXTRAS="anthropic,groq" curl -LsSf https://raw.githubusercontent.com/langchain-ai/deepagents/main/scripts/install.sh | bash
20
+ DEEPAGENTS_EXTRAS="anthropic,groq" curl -LsSf https://raw.githubusercontent.com/langchain-ai/deepagents/main/libs/cli/scripts/install.sh | bash
21
21
  ```
22
22
 
23
23
  Or install directly with `uv`:
@@ -0,0 +1,50 @@
1
+ """Shared debug-logging configuration for verbose file-based tracing.
2
+
3
+ When the `DEEPAGENTS_DEBUG` environment variable is set, modules that handle
4
+ streaming or remote communication can enable detailed file-based logging. This
5
+ helper centralizes the setup so the env-var name, file path, and format are
6
+ defined in one place.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import logging
12
+ import os
13
+ from pathlib import Path
14
+
15
+
16
+ def configure_debug_logging(target: logging.Logger) -> None:
17
+ """Attach a file handler to *target* when `DEEPAGENTS_DEBUG` is set.
18
+
19
+ The log file defaults to `'/tmp/deepagents_debug.log'` but can be overridden
20
+ with `DEEPAGENTS_DEBUG_FILE`. The handler appends so that multiple modules
21
+ share the same log file across a session.
22
+
23
+ Does nothing when `DEEPAGENTS_DEBUG` is not set.
24
+
25
+ Args:
26
+ target: Logger to configure.
27
+ """
28
+ if not os.environ.get("DEEPAGENTS_DEBUG"):
29
+ return
30
+
31
+ debug_path = Path(
32
+ os.environ.get(
33
+ "DEEPAGENTS_DEBUG_FILE",
34
+ "/tmp/deepagents_debug.log", # noqa: S108
35
+ )
36
+ )
37
+ try:
38
+ handler = logging.FileHandler(str(debug_path), mode="a")
39
+ except OSError as exc:
40
+ import sys
41
+
42
+ print( # noqa: T201
43
+ f"Warning: could not open debug log file {debug_path}: {exc}",
44
+ file=sys.stderr,
45
+ )
46
+ return
47
+ handler.setLevel(logging.DEBUG)
48
+ handler.setFormatter(logging.Formatter("%(asctime)s %(name)s %(message)s"))
49
+ target.addHandler(handler)
50
+ target.setLevel(logging.DEBUG)
@@ -0,0 +1,320 @@
1
+ """Typed configuration for the CLI-to-server subprocess communication channel.
2
+
3
+ The CLI spawns a `langgraph dev` subprocess and passes configuration via
4
+ environment variables prefixed with `DA_SERVER_`. This module provides a single
5
+ `ServerConfig` dataclass that both sides share so that the set of variables,
6
+ their serialization format, and their default values are defined in one place.
7
+ The CLI writes config with `to_env()` and the server graph reads it back
8
+ with `from_env()`.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import json
14
+ import logging
15
+ import os
16
+ from dataclasses import dataclass
17
+ from pathlib import Path
18
+ from typing import TYPE_CHECKING, Any
19
+
20
+ from deepagents_cli._server_constants import ENV_PREFIX as _ENV_PREFIX
21
+
22
+ if TYPE_CHECKING:
23
+ from deepagents_cli.project_utils import ProjectContext
24
+
25
+ logger = logging.getLogger(__name__)
26
+
27
+ _DEFAULT_ASSISTANT_ID = "agent"
28
+
29
+
30
+ def _read_env_bool(suffix: str, *, default: bool = False) -> bool:
31
+ """Read a `DA_SERVER_*` boolean from the environment.
32
+
33
+ Boolean env vars use the `'true'` / `'false'` convention (case insensitive).
34
+ Missing variables fall back to *default*.
35
+
36
+ Args:
37
+ suffix: Variable name suffix after the `DA_SERVER_` prefix.
38
+ default: Value when the variable is absent.
39
+
40
+ Returns:
41
+ Parsed boolean.
42
+ """
43
+ raw = os.environ.get(f"{_ENV_PREFIX}{suffix}")
44
+ if raw is None:
45
+ return default
46
+ return raw.lower() == "true"
47
+
48
+
49
+ def _read_env_json(suffix: str) -> Any: # noqa: ANN401
50
+ """Read a JSON-encoded `DA_SERVER_*` variable.
51
+
52
+ Args:
53
+ suffix: Variable name suffix after the `DA_SERVER_` prefix.
54
+
55
+ Returns:
56
+ Parsed JSON value, or `None` if the variable is absent.
57
+
58
+ Raises:
59
+ ValueError: If the variable is present but not valid JSON.
60
+ """
61
+ raw = os.environ.get(f"{_ENV_PREFIX}{suffix}")
62
+ if raw is None:
63
+ return None
64
+ try:
65
+ return json.loads(raw)
66
+ except json.JSONDecodeError as exc:
67
+ msg = (
68
+ f"Failed to parse {_ENV_PREFIX}{suffix} as JSON: {exc}. "
69
+ f"Value was: {raw[:200]!r}"
70
+ )
71
+ raise ValueError(msg) from exc
72
+
73
+
74
+ def _read_env_str(suffix: str) -> str | None:
75
+ """Read an optional `DA_SERVER_*` string variable.
76
+
77
+ Args:
78
+ suffix: Variable name suffix after the `DA_SERVER_` prefix.
79
+
80
+ Returns:
81
+ The string value, or `None` if absent.
82
+ """
83
+ return os.environ.get(f"{_ENV_PREFIX}{suffix}")
84
+
85
+
86
+ def _read_env_optional_bool(suffix: str) -> bool | None:
87
+ """Read a tri-state `DA_SERVER_*` boolean (`True` / `False` / `None`).
88
+
89
+ Used for settings where `None` carries a distinct meaning (e.g. "not
90
+ specified, use default logic").
91
+
92
+ Args:
93
+ suffix: Variable name suffix after the `DA_SERVER_` prefix.
94
+
95
+ Returns:
96
+ `True`, `False`, or `None` when the variable is absent.
97
+ """
98
+ raw = os.environ.get(f"{_ENV_PREFIX}{suffix}")
99
+ if raw is None:
100
+ return None
101
+ return raw.lower() == "true"
102
+
103
+
104
+ @dataclass(frozen=True)
105
+ class ServerConfig:
106
+ """Full configuration payload passed from the CLI to the server subprocess.
107
+
108
+ Serialized to/from `DA_SERVER_*` environment variables so that the server
109
+ graph (which runs in a separate Python interpreter) can reconstruct the
110
+ CLI's intent without sharing memory.
111
+ """
112
+
113
+ model: str | None = None
114
+ model_params: dict[str, Any] | None = None
115
+ assistant_id: str = _DEFAULT_ASSISTANT_ID
116
+ system_prompt: str | None = None
117
+ auto_approve: bool = False
118
+ interactive: bool = True
119
+ enable_shell: bool = True
120
+ enable_ask_user: bool = False
121
+ enable_memory: bool = True
122
+ enable_skills: bool = True
123
+ sandbox_type: str | None = None
124
+ sandbox_id: str | None = None
125
+ sandbox_setup: str | None = None
126
+ cwd: str | None = None
127
+ project_root: str | None = None
128
+ mcp_config_path: str | None = None
129
+ no_mcp: bool = False
130
+ trust_project_mcp: bool | None = None
131
+
132
+ def __post_init__(self) -> None:
133
+ """Normalize fields that have canonical representations."""
134
+ if self.sandbox_type == "none":
135
+ object.__setattr__(self, "sandbox_type", None)
136
+
137
+ # ------------------------------------------------------------------
138
+ # Serialization
139
+ # ------------------------------------------------------------------
140
+
141
+ def to_env(self) -> dict[str, str | None]:
142
+ """Serialize this config to a `DA_SERVER_*` env-var mapping.
143
+
144
+ `None` values signal that the variable should be *cleared* from the
145
+ environment (rather than set to an empty string), so callers can
146
+ iterate and set or clear each variable in `os.environ`.
147
+
148
+ Returns:
149
+ Dict mapping env-var suffixes (without the prefix) to their
150
+ string values or `None`.
151
+ """
152
+ return {
153
+ "MODEL": self.model,
154
+ "MODEL_PARAMS": (
155
+ json.dumps(self.model_params) if self.model_params is not None else None
156
+ ),
157
+ "ASSISTANT_ID": self.assistant_id,
158
+ "SYSTEM_PROMPT": self.system_prompt,
159
+ "AUTO_APPROVE": str(self.auto_approve).lower(),
160
+ "INTERACTIVE": str(self.interactive).lower(),
161
+ "ENABLE_SHELL": str(self.enable_shell).lower(),
162
+ "ENABLE_ASK_USER": str(self.enable_ask_user).lower(),
163
+ "ENABLE_MEMORY": str(self.enable_memory).lower(),
164
+ "ENABLE_SKILLS": str(self.enable_skills).lower(),
165
+ "SANDBOX_TYPE": self.sandbox_type,
166
+ "SANDBOX_ID": self.sandbox_id,
167
+ "SANDBOX_SETUP": self.sandbox_setup,
168
+ "CWD": self.cwd,
169
+ "PROJECT_ROOT": self.project_root,
170
+ "MCP_CONFIG_PATH": self.mcp_config_path,
171
+ "NO_MCP": str(self.no_mcp).lower(),
172
+ "TRUST_PROJECT_MCP": (
173
+ str(self.trust_project_mcp).lower()
174
+ if self.trust_project_mcp is not None
175
+ else None
176
+ ),
177
+ }
178
+
179
+ @classmethod
180
+ def from_env(cls) -> ServerConfig:
181
+ """Reconstruct a `ServerConfig` from the current `DA_SERVER_*` env vars.
182
+
183
+ This is the inverse of `to_env()` and is called inside the server
184
+ subprocess to recover the CLI's configuration.
185
+
186
+ Returns:
187
+ A `ServerConfig` populated from the environment.
188
+ """
189
+ return cls(
190
+ model=_read_env_str("MODEL"),
191
+ model_params=_read_env_json("MODEL_PARAMS"),
192
+ assistant_id=_read_env_str("ASSISTANT_ID") or _DEFAULT_ASSISTANT_ID,
193
+ system_prompt=_read_env_str("SYSTEM_PROMPT"),
194
+ auto_approve=_read_env_bool("AUTO_APPROVE"),
195
+ interactive=_read_env_bool("INTERACTIVE", default=True),
196
+ enable_shell=_read_env_bool("ENABLE_SHELL", default=True),
197
+ enable_ask_user=_read_env_bool("ENABLE_ASK_USER"),
198
+ enable_memory=_read_env_bool("ENABLE_MEMORY", default=True),
199
+ enable_skills=_read_env_bool("ENABLE_SKILLS", default=True),
200
+ sandbox_type=_read_env_str("SANDBOX_TYPE"),
201
+ sandbox_id=_read_env_str("SANDBOX_ID"),
202
+ sandbox_setup=_read_env_str("SANDBOX_SETUP"),
203
+ cwd=_read_env_str("CWD"),
204
+ project_root=_read_env_str("PROJECT_ROOT"),
205
+ mcp_config_path=_read_env_str("MCP_CONFIG_PATH"),
206
+ no_mcp=_read_env_bool("NO_MCP"),
207
+ trust_project_mcp=_read_env_optional_bool("TRUST_PROJECT_MCP"),
208
+ )
209
+
210
+ # ------------------------------------------------------------------
211
+ # Factory
212
+ # ------------------------------------------------------------------
213
+
214
+ @classmethod
215
+ def from_cli_args(
216
+ cls,
217
+ *,
218
+ project_context: ProjectContext | None,
219
+ model_name: str | None,
220
+ model_params: dict[str, Any] | None,
221
+ assistant_id: str,
222
+ auto_approve: bool,
223
+ sandbox_type: str,
224
+ sandbox_id: str | None,
225
+ sandbox_setup: str | None,
226
+ enable_shell: bool,
227
+ enable_ask_user: bool,
228
+ mcp_config_path: str | None,
229
+ no_mcp: bool,
230
+ trust_project_mcp: bool | None,
231
+ interactive: bool,
232
+ ) -> ServerConfig:
233
+ """Build a `ServerConfig` from parsed CLI arguments.
234
+
235
+ Handles path normalization (e.g. resolving relative MCP config paths
236
+ against the user's working directory) so that the raw serialized values
237
+ are always absolute and unambiguous.
238
+
239
+ Args:
240
+ project_context: Explicit user/project path context.
241
+ model_name: Model spec string.
242
+ model_params: Extra model kwargs.
243
+ assistant_id: Agent identifier.
244
+ auto_approve: Auto-approve all tools.
245
+ sandbox_type: Sandbox type.
246
+ sandbox_id: Existing sandbox ID to reuse.
247
+ sandbox_setup: Path to setup script for the sandbox.
248
+ enable_shell: Enable shell execution tools.
249
+ enable_ask_user: Enable ask_user tool.
250
+ mcp_config_path: Path to MCP config.
251
+ no_mcp: Disable MCP.
252
+ trust_project_mcp: Trust project MCP servers.
253
+ interactive: Whether the agent is interactive.
254
+
255
+ Returns:
256
+ A fully resolved `ServerConfig`.
257
+ """
258
+ normalized_mcp = _normalize_path(mcp_config_path, project_context, "MCP config")
259
+
260
+ return cls(
261
+ model=model_name,
262
+ model_params=model_params,
263
+ assistant_id=assistant_id,
264
+ auto_approve=auto_approve,
265
+ interactive=interactive,
266
+ enable_shell=enable_shell,
267
+ enable_ask_user=enable_ask_user,
268
+ sandbox_type=sandbox_type,
269
+ sandbox_id=sandbox_id,
270
+ sandbox_setup=_normalize_path(
271
+ sandbox_setup, project_context, "sandbox setup"
272
+ ),
273
+ cwd=(
274
+ str(project_context.user_cwd) if project_context is not None else None
275
+ ),
276
+ project_root=(
277
+ str(project_context.project_root)
278
+ if project_context is not None
279
+ and project_context.project_root is not None
280
+ else None
281
+ ),
282
+ mcp_config_path=normalized_mcp,
283
+ no_mcp=no_mcp,
284
+ trust_project_mcp=trust_project_mcp,
285
+ )
286
+
287
+
288
+ def _normalize_path(
289
+ raw_path: str | None,
290
+ project_context: ProjectContext | None,
291
+ label: str,
292
+ ) -> str | None:
293
+ """Resolve a possibly-relative path to absolute.
294
+
295
+ The server subprocess runs in a different working directory, so relative
296
+ paths must be resolved against the user's original cwd before serialization.
297
+
298
+ Args:
299
+ raw_path: Path from CLI arguments (may be relative).
300
+ project_context: User/project context for path resolution.
301
+ label: Human-readable label for error messages (e.g. "MCP config").
302
+
303
+ Returns:
304
+ Absolute path string, or `None` when *raw_path* is `None` or empty.
305
+
306
+ Raises:
307
+ ValueError: If the path cannot be resolved.
308
+ """
309
+ if not raw_path:
310
+ return None
311
+ try:
312
+ if project_context is not None:
313
+ return str(project_context.resolve_user_path(raw_path))
314
+ return str(Path(raw_path).expanduser().resolve())
315
+ except OSError as exc:
316
+ msg = (
317
+ f"Could not resolve {label} path {raw_path!r}: {exc}. "
318
+ "Ensure the path exists and is accessible."
319
+ )
320
+ raise ValueError(msg) from exc
@@ -0,0 +1,4 @@
1
+ """Shared constants for server communication between CLI and server graph."""
2
+
3
+ ENV_PREFIX = "DA_SERVER_"
4
+ """Environment variable prefix used to pass CLI config to the server subprocess."""