deepagents-code 0.1.23__tar.gz → 0.1.25__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 (304) hide show
  1. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/CHANGELOG.md +30 -0
  2. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/Makefile +1 -1
  3. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/PKG-INFO +8 -2
  4. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/README.md +6 -0
  5. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/THREAT_MODEL.md +21 -10
  6. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_build_info.py +1 -1
  7. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_cli_context.py +11 -0
  8. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_env_vars.py +19 -0
  9. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_server_config.py +75 -3
  10. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_version.py +1 -1
  11. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/agent.py +59 -3
  12. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/app.py +248 -38
  13. deepagents_code-0.1.25/deepagents_code/approval_mode.py +131 -0
  14. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/auth_store.py +5 -1
  15. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/config.py +47 -6
  16. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/config_commands.py +189 -31
  17. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/config_manifest.py +30 -3
  18. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/configurable_model.py +3 -0
  19. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/extras_info.py +115 -17
  20. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/file_ops.py +42 -11
  21. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/main.py +146 -33
  22. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/managed_tools.py +77 -6
  23. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/memory_guard.py +83 -15
  24. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/non_interactive.py +2 -2
  25. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/remote_client.py +52 -0
  26. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/server.py +102 -10
  27. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/server_graph.py +132 -67
  28. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/server_manager.py +15 -9
  29. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/sessions.py +2 -2
  30. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/textual_adapter.py +109 -6
  31. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/tool_display.py +1 -1
  32. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/tools.py +89 -2
  33. deepagents_code-0.1.25/deepagents_code/tools_commands.py +191 -0
  34. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/ui.py +61 -3
  35. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/update_check.py +242 -19
  36. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/_links.py +21 -1
  37. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/approval.py +7 -4
  38. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/chat_input.py +83 -26
  39. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/messages.py +20 -1
  40. deepagents_code-0.1.25/deepagents_code/widgets/subagent_panel.py +969 -0
  41. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/tool_renderers.py +42 -1
  42. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/welcome.py +2 -1
  43. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/pyproject.toml +8 -5
  44. deepagents_code-0.1.25/scripts/check_imports.py +44 -0
  45. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/scripts/install.sh +37 -1
  46. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/conftest.py +32 -13
  47. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_agent.py +185 -6
  48. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_agent_friendly.py +8 -0
  49. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_app.py +520 -21
  50. deepagents_code-0.1.25/tests/unit_tests/test_approval_mode.py +129 -0
  51. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_auth_store.py +8 -0
  52. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_chat_input.py +280 -12
  53. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_config.py +4 -4
  54. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_config_manifest.py +392 -0
  55. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_configurable_model.py +34 -1
  56. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_extras_info.py +223 -11
  57. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_file_ops.py +90 -0
  58. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_install_command.py +3 -9
  59. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_install_script.py +92 -2
  60. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_launch_init.py +1 -1
  61. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_links.py +29 -1
  62. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_local_context.py +39 -0
  63. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_main.py +48 -0
  64. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_main_args.py +342 -10
  65. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_managed_tools.py +150 -1
  66. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_memory_guard.py +112 -0
  67. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_messages.py +79 -1
  68. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_non_interactive.py +1 -0
  69. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_reload.py +64 -0
  70. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_remote_client.py +75 -0
  71. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_server.py +185 -4
  72. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_server_config.py +151 -0
  73. deepagents_code-0.1.25/tests/unit_tests/test_server_graph.py +425 -0
  74. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_server_helpers.py +13 -10
  75. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_server_manager.py +48 -3
  76. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_sessions.py +24 -0
  77. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_startup_fast_paths.py +2 -0
  78. deepagents_code-0.1.25/tests/unit_tests/test_subagent_panel.py +549 -0
  79. deepagents_code-0.1.25/tests/unit_tests/test_subagent_stream.py +41 -0
  80. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_textual_adapter.py +227 -2
  81. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_tool_display.py +9 -3
  82. deepagents_code-0.1.25/tests/unit_tests/test_tool_renderers.py +43 -0
  83. deepagents_code-0.1.25/tests/unit_tests/test_tools_commands.py +144 -0
  84. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_update_check.py +290 -1
  85. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_version.py +65 -4
  86. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_welcome.py +5 -0
  87. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/tools/test_fetch_url.py +132 -1
  88. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/uv.lock +11 -14
  89. deepagents_code-0.1.23/scripts/check_imports.py +0 -32
  90. deepagents_code-0.1.23/tests/unit_tests/test_server_graph.py +0 -199
  91. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/.gitignore +0 -0
  92. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/AGENTS.md +0 -0
  93. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/ARCHITECTURE.md +0 -0
  94. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/COMMANDS.md +0 -0
  95. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/DEVELOPMENT.md +0 -0
  96. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/__init__.py +0 -0
  97. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/__main__.py +0 -0
  98. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_ask_user_types.py +0 -0
  99. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_constants.py +0 -0
  100. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_debug.py +0 -0
  101. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_git.py +0 -0
  102. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_paths.py +0 -0
  103. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_session_stats.py +0 -0
  104. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_startup_error.py +0 -0
  105. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_testing_models.py +0 -0
  106. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/_textual_patches.py +0 -0
  107. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/app.tcss +0 -0
  108. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/ask_user.py +0 -0
  109. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/auth_commands.py +0 -0
  110. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/auth_display.py +0 -0
  111. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/built_in_skills/__init__.py +0 -0
  112. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/built_in_skills/remember/SKILL.md +0 -0
  113. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/built_in_skills/skill-creator/SKILL.md +0 -0
  114. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
  115. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
  116. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/clipboard.py +0 -0
  117. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/command_registry.py +0 -0
  118. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/default_agent_prompt.md +0 -0
  119. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/doctor.py +0 -0
  120. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/editor.py +0 -0
  121. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/event_bus.py +0 -0
  122. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/formatting.py +0 -0
  123. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/hooks.py +0 -0
  124. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/input.py +0 -0
  125. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/integrations/__init__.py +0 -0
  126. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/integrations/openai_codex.py +0 -0
  127. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/integrations/sandbox_config.py +0 -0
  128. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/integrations/sandbox_factory.py +0 -0
  129. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/integrations/sandbox_provider.py +0 -0
  130. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/integrations/sandbox_registry.py +0 -0
  131. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/iterm_cursor_guide.py +0 -0
  132. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/local_context.py +0 -0
  133. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_auth.py +0 -0
  134. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_commands.py +0 -0
  135. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_disabled.py +0 -0
  136. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_login_service.py +0 -0
  137. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_oauth_ui.py +0 -0
  138. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_providers/__init__.py +0 -0
  139. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_providers/_registry.py +0 -0
  140. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_providers/base.py +0 -0
  141. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_providers/github.py +0 -0
  142. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_providers/slack.py +0 -0
  143. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_tools.py +0 -0
  144. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/mcp_trust.py +0 -0
  145. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/media_utils.py +0 -0
  146. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/model_config.py +0 -0
  147. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/notifications.py +0 -0
  148. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/offload.py +0 -0
  149. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/onboarding.py +0 -0
  150. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/output.py +0 -0
  151. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/project_utils.py +0 -0
  152. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/py.typed +0 -0
  153. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/resume_state.py +0 -0
  154. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/skills/__init__.py +0 -0
  155. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/skills/commands.py +0 -0
  156. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/skills/invocation.py +0 -0
  157. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/skills/load.py +0 -0
  158. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/state_migration.py +0 -0
  159. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/subagents.py +0 -0
  160. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/system_prompt.md +0 -0
  161. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/terminal_capabilities.py +0 -0
  162. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/terminal_escape.py +0 -0
  163. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/theme.py +0 -0
  164. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/unicode_security.py +0 -0
  165. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/__init__.py +0 -0
  166. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/_js_eval_display.py +0 -0
  167. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/agent_selector.py +0 -0
  168. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/ask_user.py +0 -0
  169. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/auth.py +0 -0
  170. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/autocomplete.py +0 -0
  171. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/codex_auth.py +0 -0
  172. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/cwd_switch.py +0 -0
  173. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/diff.py +0 -0
  174. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/history.py +0 -0
  175. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/install_confirm.py +0 -0
  176. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/launch_init.py +0 -0
  177. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/loading.py +0 -0
  178. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/mcp_login.py +0 -0
  179. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/mcp_reconnect.py +0 -0
  180. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/mcp_viewer.py +0 -0
  181. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/message_store.py +0 -0
  182. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/model_selector.py +0 -0
  183. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/notification_center.py +0 -0
  184. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/notification_detail.py +0 -0
  185. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/notification_settings.py +0 -0
  186. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/restart_prompt.py +0 -0
  187. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/status.py +0 -0
  188. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/theme_selector.py +0 -0
  189. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/thread_selector.py +0 -0
  190. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/tool_widgets.py +0 -0
  191. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/update_available.py +0 -0
  192. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/update_confirm.py +0 -0
  193. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/deepagents_code/widgets/update_progress.py +0 -0
  194. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/examples/skills/arxiv-search/SKILL.md +0 -0
  195. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/examples/skills/arxiv-search/arxiv_search.py +0 -0
  196. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/examples/skills/langgraph-docs/SKILL.md +0 -0
  197. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/examples/skills/skill-creator/SKILL.md +0 -0
  198. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
  199. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
  200. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/examples/skills/web-research/SKILL.md +0 -0
  201. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/hatch_build.py +0 -0
  202. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/images/tui.png +0 -0
  203. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/scripts/debug_server.sh +0 -0
  204. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/scripts/generate_commands_catalog.py +0 -0
  205. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/README.md +0 -0
  206. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/integration_tests/__init__.py +0 -0
  207. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/integration_tests/benchmarks/__init__.py +0 -0
  208. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
  209. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
  210. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/integration_tests/conftest.py +0 -0
  211. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/integration_tests/test_acp_mode.py +0 -0
  212. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/integration_tests/test_compact_resume.py +0 -0
  213. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/integration_tests/test_sandbox_factory.py +0 -0
  214. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/integration_tests/test_sandbox_operations.py +0 -0
  215. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/__init__.py +0 -0
  216. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/skills/__init__.py +0 -0
  217. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/skills/test_commands.py +0 -0
  218. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/skills/test_load.py +0 -0
  219. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/skills/test_skills_json.py +0 -0
  220. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_agent_selector.py +0 -0
  221. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_approval.py +0 -0
  222. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_args.py +0 -0
  223. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_ask_user.py +0 -0
  224. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_ask_user_middleware.py +0 -0
  225. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_auth_commands.py +0 -0
  226. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_auth_display.py +0 -0
  227. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_auth_widgets.py +0 -0
  228. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_autocomplete.py +0 -0
  229. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_charset.py +0 -0
  230. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_clipboard.py +0 -0
  231. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_command_registry.py +0 -0
  232. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_compact_tool.py +0 -0
  233. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_cursor_blink.py +0 -0
  234. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_cwd_switch.py +0 -0
  235. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_debug.py +0 -0
  236. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_doctor.py +0 -0
  237. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_editor.py +0 -0
  238. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_end_to_end.py +0 -0
  239. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_env_vars.py +0 -0
  240. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_event_bus.py +0 -0
  241. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_exception_handling.py +0 -0
  242. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_formatting.py +0 -0
  243. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_git.py +0 -0
  244. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_hatch_build.py +0 -0
  245. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_history.py +0 -0
  246. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_hooks.py +0 -0
  247. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_imports.py +0 -0
  248. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_input_parsing.py +0 -0
  249. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_install_confirm.py +0 -0
  250. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
  251. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_loading.py +0 -0
  252. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_main_acp_mode.py +0 -0
  253. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_mcp_auth.py +0 -0
  254. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_mcp_commands.py +0 -0
  255. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_mcp_disabled.py +0 -0
  256. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_mcp_login_modal.py +0 -0
  257. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_mcp_login_service.py +0 -0
  258. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_mcp_oauth_ui.py +0 -0
  259. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_mcp_reconnect.py +0 -0
  260. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_mcp_tools.py +0 -0
  261. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_mcp_trust.py +0 -0
  262. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_mcp_viewer.py +0 -0
  263. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_media_utils.py +0 -0
  264. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_message_store.py +0 -0
  265. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_model_config.py +0 -0
  266. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_model_selector.py +0 -0
  267. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_model_switch.py +0 -0
  268. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_notification_center.py +0 -0
  269. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_notification_detail.py +0 -0
  270. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_notifications.py +0 -0
  271. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_offload.py +0 -0
  272. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_offload_dict_messages.py +0 -0
  273. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_onboarding.py +0 -0
  274. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_openai_codex_integration.py +0 -0
  275. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_output.py +0 -0
  276. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_paths.py +0 -0
  277. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_restart_prompt.py +0 -0
  278. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_resume_state.py +0 -0
  279. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_sandbox_config.py +0 -0
  280. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_sandbox_factory.py +0 -0
  281. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_sandbox_provider.py +0 -0
  282. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_sandbox_registry.py +0 -0
  283. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_session_stats.py +0 -0
  284. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_shell_allow_list.py +0 -0
  285. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_skill_invocation.py +0 -0
  286. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_state_migration.py +0 -0
  287. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_status.py +0 -0
  288. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_subagents.py +0 -0
  289. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_terminal_capabilities.py +0 -0
  290. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_terminal_escape.py +0 -0
  291. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_terminal_progress_preference.py +0 -0
  292. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_textual_patches.py +0 -0
  293. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_theme.py +0 -0
  294. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_thread_selector.py +0 -0
  295. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_tracing_replicas.py +0 -0
  296. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_ui.py +0 -0
  297. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_unicode_security.py +0 -0
  298. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_update_available.py +0 -0
  299. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_update_confirm.py +0 -0
  300. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/test_update_progress.py +0 -0
  301. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/tools/__init__.py +0 -0
  302. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/tools/test_current_thread.py +0 -0
  303. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/widgets/__init__.py +0 -0
  304. {deepagents_code-0.1.23 → deepagents_code-0.1.25}/tests/unit_tests/widgets/test_diff.py +0 -0
@@ -2,6 +2,36 @@
2
2
 
3
3
  # Deep Agents Code Changelog
4
4
 
5
+ ## [0.1.25](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.24...deepagents-code==0.1.25) (2026-06-26)
6
+
7
+ ### Bug Fixes
8
+
9
+ * Bind ephemeral port instead of squatting `langgraph dev`'s 2024 ([#4264](https://github.com/langchain-ai/deepagents/issues/4264)) ([11e5359](https://github.com/langchain-ai/deepagents/commit/11e5359851f0291783661b4311ad5e4436a36fb7))
10
+ * Block dotenv shell startup hooks ([#4288](https://github.com/langchain-ai/deepagents/issues/4288)) ([686d6f3](https://github.com/langchain-ai/deepagents/commit/686d6f3a1da8b6393efb4c0cf87b3eb35e0cca50))
11
+ * Defer server graph construction ([#4300](https://github.com/langchain-ai/deepagents/issues/4300)) ([220dfc0](https://github.com/langchain-ai/deepagents/commit/220dfc0e6b03f9ccb499c6b850c586b9d57cc077))
12
+ * Avoid blocking MCP imports during graph readiness ([#4302](https://github.com/langchain-ai/deepagents/issues/4302)) ([7533ca8](https://github.com/langchain-ai/deepagents/commit/7533ca89f3afc9863ba5e1ecee2d4c5974dea320))
13
+ * Gate `delete` file operations ([#4299](https://github.com/langchain-ai/deepagents/issues/4299)) ([92a8681](https://github.com/langchain-ai/deepagents/commit/92a86819adfefbc6ccfd01a861191ba292eca754))
14
+ * Handle recursive `fetch_url` conversion ([#4257](https://github.com/langchain-ai/deepagents/issues/4257)) ([f240a40](https://github.com/langchain-ai/deepagents/commit/f240a40dc05d812c38e9926c1d81ba38deb86e3f))
15
+ * Report editable SDK runtime version ([#4304](https://github.com/langchain-ai/deepagents/issues/4304)) ([4439e91](https://github.com/langchain-ai/deepagents/commit/4439e912da4bfa6f1e38e14b5a03d2bfe9367d3b))
16
+ * Show months instead of "0y ago" for 360-364 day old timestamps ([#4267](https://github.com/langchain-ai/deepagents/issues/4267)) ([820b331](https://github.com/langchain-ai/deepagents/commit/820b331552cb7ce4695ddca3c9b8343a3144392b))
17
+ * Surface `/auth`-stored credentials in `config show`/`get` ([#4258](https://github.com/langchain-ai/deepagents/issues/4258)) ([c7c8788](https://github.com/langchain-ai/deepagents/commit/c7c8788ecf0068914298a6055a5f3fd31c36bd44))
18
+ * Switch input mode without flashing the mode trigger ([#4243](https://github.com/langchain-ai/deepagents/issues/4243)) ([fc5d9cb](https://github.com/langchain-ai/deepagents/commit/fc5d9cb8fb978ec95f98407692d4809ea1e86577))
19
+
20
+ ## [0.1.24](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.23...deepagents-code==0.1.24) (2026-06-25)
21
+
22
+ ### Features
23
+
24
+ * Enable `js_eval` by default ([#4245](https://github.com/langchain-ai/deepagents/issues/4245)) ([2e04ff3](https://github.com/langchain-ai/deepagents/commit/2e04ff397e60389c9a19c4a9b528e15602ad8338))
25
+ * Dynamic subagents UI ([#4221](https://github.com/langchain-ai/deepagents/issues/4221)) ([10bcba2](https://github.com/langchain-ai/deepagents/commit/10bcba25600e51aba135f170b34aa6315c0f53d6))
26
+ * Gate onboarding integrations modal behind opt-in flag ([#4227](https://github.com/langchain-ai/deepagents/issues/4227)) ([6c930c5](https://github.com/langchain-ai/deepagents/commit/6c930c5e4502f572be554acc896c5fb6d061e0e5))
27
+
28
+ ### Bug Fixes
29
+
30
+ * Eager managed ripgrep install via `dcode tools install` ([#4199](https://github.com/langchain-ai/deepagents/issues/4199)) ([cf536f3](https://github.com/langchain-ai/deepagents/commit/cf536f339958d6726fa41f896c4a3e42df644c9f))
31
+ * Interrupt remote runs on chat cancellation ([#4234](https://github.com/langchain-ai/deepagents/issues/4234)) ([37c5fa2](https://github.com/langchain-ai/deepagents/commit/37c5fa23e621616836694bc59c1b0c38def81604))
32
+ * Sync approval toggles during active runs ([#4239](https://github.com/langchain-ai/deepagents/issues/4239)) ([4600365](https://github.com/langchain-ai/deepagents/commit/4600365ea0b60c3e9113ecf59b5336be37d03428))
33
+ * Clear stale live approval mode keys ([#4242](https://github.com/langchain-ai/deepagents/issues/4242)) ([f11a769](https://github.com/langchain-ai/deepagents/commit/f11a76962c9d536a38e27ac05b32feca364b2424))
34
+
5
35
  ## [0.1.23](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.22...deepagents-code==0.1.23) (2026-06-25)
6
36
 
7
37
  ### Features
@@ -105,7 +105,7 @@ check: lint check_imports test
105
105
  @echo "🔍 Verifying pyproject.toml and _version.py agree..."
106
106
  uv run --all-groups python "$(REPO_ROOT)/.github/scripts/check_version_equality.py"
107
107
  @echo "🔒 Verifying uv.lock is up-to-date..."
108
- uv lock --check
108
+ UV_FROZEN=false uv lock --check
109
109
  @echo "🔗 Checking SDK pin against workspace SDK (advisory)..."
110
110
  @uv run --all-groups python "$(REPO_ROOT)/.github/scripts/check_sdk_pin.py" || \
111
111
  { rc=$$?; [ $$rc -eq 1 ] && echo "⚠️ Stale SDK pin (advisory, non-fatal)." || exit $$rc; }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepagents-code
3
- Version: 0.1.23
3
+ Version: 0.1.25
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/
@@ -33,6 +33,7 @@ Requires-Dist: langchain-anthropic<2.0.0,>=1.4.7
33
33
  Requires-Dist: langchain-google-genai<5.0.0,>=4.2.5
34
34
  Requires-Dist: langchain-mcp-adapters<1.0.0,>=0.3.0
35
35
  Requires-Dist: langchain-openai<2.0.0,>=1.3.3
36
+ Requires-Dist: langchain-quickjs<0.4.0,>=0.3.2
36
37
  Requires-Dist: langchain<2.0.0,>=1.3.11
37
38
  Requires-Dist: langgraph-checkpoint-sqlite<4.0.0,>=3.1.0
38
39
  Requires-Dist: langgraph-cli[inmem]<1.0.0,>=0.4.30
@@ -123,7 +124,6 @@ Requires-Dist: langchain-openrouter<2.0.0,>=0.2.4; extra == 'openrouter'
123
124
  Provides-Extra: perplexity
124
125
  Requires-Dist: langchain-perplexity<2.0.0,>=1.4.0; extra == 'perplexity'
125
126
  Provides-Extra: quickjs
126
- Requires-Dist: langchain-quickjs<0.4.0,>=0.3.1; extra == 'quickjs'
127
127
  Provides-Extra: runloop
128
128
  Requires-Dist: langchain-runloop>=0.0.6; extra == 'runloop'
129
129
  Provides-Extra: together
@@ -180,6 +180,12 @@ The fastest way to start using Deep Agents. `deepagents-code` is a pre-built cod
180
180
  - **Headless mode** — run non-interactively for scripting and CI
181
181
  - **Human-in-the-loop** — approve or reject tool calls before execution
182
182
 
183
+ ## 🔒 Security model
184
+
185
+ By default, `dcode` trusts the directory you run it in. Human-in-the-loop approval gates model-requested tool calls, but project artifacts are read before any approval prompt.
186
+
187
+ Do not run `dcode` in a directory you do not trust without a sandbox backend. For untrusted repositories, use a [remote sandbox](https://docs.langchain.com/oss/python/deepagents/code/remote-sandboxes) so execution is isolated from your machine. Running `dcode` in a directory lets that directory's files shape execution. See [`THREAT_MODEL.md`](https://github.com/langchain-ai/deepagents/blob/main/libs/code/THREAT_MODEL.md) for details.
188
+
183
189
  ## 📖 Resources
184
190
 
185
191
  - **[Documentation](https://docs.langchain.com/deepagents-code)**
@@ -42,6 +42,12 @@ The fastest way to start using Deep Agents. `deepagents-code` is a pre-built cod
42
42
  - **Headless mode** — run non-interactively for scripting and CI
43
43
  - **Human-in-the-loop** — approve or reject tool calls before execution
44
44
 
45
+ ## 🔒 Security model
46
+
47
+ By default, `dcode` trusts the directory you run it in. Human-in-the-loop approval gates model-requested tool calls, but project artifacts are read before any approval prompt.
48
+
49
+ Do not run `dcode` in a directory you do not trust without a sandbox backend. For untrusted repositories, use a [remote sandbox](https://docs.langchain.com/oss/python/deepagents/code/remote-sandboxes) so execution is isolated from your machine. Running `dcode` in a directory lets that directory's files shape execution. See [`THREAT_MODEL.md`](https://github.com/langchain-ai/deepagents/blob/main/libs/code/THREAT_MODEL.md) for details.
50
+
45
51
  ## 📖 Resources
46
52
 
47
53
  - **[Documentation](https://docs.langchain.com/deepagents-code)**
@@ -207,7 +207,7 @@
207
207
  | TB8 | CLI → Server Subprocess IPC | Config passed from CLI to `langgraph dev` subprocess via `DA_SERVER_*` env vars | `ServerConfig.to_env()` serialization; env var scoping to parent+child process | Subprocess environment post-fork; /proc visibility to same-uid processes |
208
208
  | TB9 | LocalContextMiddleware → Host Env | Bash detect script output (git info, project files, Makefile) injected into system prompt | Script is framework-generated static code; 30s timeout; exit-code check | Content of Makefile, pyproject.toml, git branch names, directory listing |
209
209
  | TB10 | RemoteAgent → LangGraph Dev Server | CLI communicates with agent via HTTP+SSE on localhost | Server bound to `127.0.0.1` (`server.py:_DEFAULT_HOST`); ephemeral per session | No authentication (`LANGGRAPH_AUTH_TYPE=noop`); any localhost process can reach the API |
210
- | TB11 | Config File → Code Execution | `class_path` in `config.toml` triggers `importlib.import_module()` to load arbitrary Python modules | Format validation (`module:ClassName`); `issubclass(BaseChatModel)` check | Module-level side effects execute during import; user controls config file |
210
+ | TB11 | Config File → Code Execution | `class_path` in `config.toml` triggers `importlib.import_module()`; project/global `.env` values are loaded into the process environment and can reach Bash startup hooks | Format validation (`module:ClassName`); `issubclass(BaseChatModel)` check; dotenv loading denies shell startup / environment-hijack keys (`BASH_ENV`, `ENV`) | Module-level side effects execute during import; user controls config file; project files in the working directory influence execution |
211
211
 
212
212
  ### Boundary Details
213
213
 
@@ -250,7 +250,7 @@
250
250
 
251
251
  #### TB10: RemoteAgent → LangGraph Dev Server
252
252
 
253
- - **Inside**: Server bound to `127.0.0.1` by default; `server.py:_DEFAULT_HOST = "127.0.0.1"`. `RemoteAgent` only connects to the URL returned by `ServerProcess.url`. Server is ephemeral — started at session start, stopped at session end. Port defaults to 2024 but auto-selects a free port if occupied.
253
+ - **Inside**: Server bound to `127.0.0.1` by default; `server.py:_DEFAULT_HOST = "127.0.0.1"`. `RemoteAgent` only connects to the URL returned by `ServerProcess.url`. Server is ephemeral — started at session start, stopped at session end. Binds a free ephemeral port by default (`server.py:_EPHEMERAL_PORT`); an explicit port is honored but still falls back to a free port if occupied.
254
254
  - **Outside**: `LANGGRAPH_AUTH_TYPE=noop` disables all LangGraph server authentication. Any process on localhost that discovers the port can submit requests, read thread state, or inject messages.
255
255
  - **Crossing mechanism**: HTTP POST/GET to `http://127.0.0.1:{port}` using `langgraph.pregel.remote.RemoteGraph`.
256
256
 
@@ -259,6 +259,8 @@
259
259
  - **Inside**: `config._create_model_from_class` validates `class_path` format (`module:ClassName`), imports the module via `importlib.import_module()`, and checks `issubclass(cls, BaseChatModel)` before instantiation.
260
260
  - **Outside**: Module-level code in the imported module executes unconditionally during `import_module()`. The `issubclass` check only runs after import. Any side effects (file I/O, network calls, subprocess spawning) in the module's top-level scope execute before the type check.
261
261
  - **Crossing mechanism**: `importlib.import_module(module_path)` in `config._create_model_from_class`.
262
+ - **Inside (dotenv)**: `config._load_dotenv` loads project and global `.env` values with `override=False` and drops shell startup / environment-hijack keys (`BASH_ENV`, `ENV`, and related) so a project `.env` cannot register a script that Bash would source at startup. The preview path (`_preview_dotenv_environ`) applies the same denylist so a dry-run config change cannot report a value a real reload would reject.
263
+ - **Outside (dotenv)**: All other `.env` keys are applied to the process environment, and any project file in the working directory (`.env`, `Makefile`, build scripts) can still influence execution. See T12.
262
264
 
263
265
  ---
264
266
 
@@ -346,6 +348,7 @@
346
348
  | T8 | DF21 | DC3 | Custom subagent AGENTS.md body used verbatim as system_prompt without content validation | None | Low | Verified | `subagents._parse_subagent_file`, `agent.create_cli_agent` |
347
349
  | T9 | DF23 | — | `class_path` in config.toml triggers arbitrary Python code execution via `importlib.import_module()` | TB11 | Low | Verified | `config._create_model_from_class`, `model_config.ProviderConfig` |
348
350
  | T10 | DF24 | DC1 | MCP stdio subprocess env dict accepts arbitrary keys including `PATH`, `LD_PRELOAD`, `PYTHONPATH` without filtering | TB4 | Low | Verified | `mcp_tools._validate_server_config`, `mcp_tools._load_tools_from_config` |
351
+ | T12 | DF10 | — | Project `.env` sets shell startup-hook variables (`BASH_ENV`, `ENV`) that run attacker-controlled scripts when `dcode` spawns Bash, before any HITL approval | TB11 | High | Verified | `config._load_dotenv`, `local_context.build_detect_script` |
349
352
 
350
353
  ### Threat Details
351
354
 
@@ -382,7 +385,7 @@
382
385
  #### T6: Unauthenticated LangGraph Dev Server on Localhost
383
386
 
384
387
  - **Flow**: DF3/DF4 (CLI ↔ LangGraph dev server)
385
- - **Description**: The CLI spawns a `langgraph dev` server subprocess with `LANGGRAPH_AUTH_TYPE=noop` (`server.py:_build_server_env`). This disables all server-side authentication. The server binds to `127.0.0.1:{port}` (default port 2024, or a random free port if 2024 is occupied). Any local process that discovers the port can: send arbitrary inputs to the running agent thread, read the agent's conversation state (including tool results that may contain file contents or secrets), inject messages into the conversation history, or trigger state updates. The server is ephemeral — it lives only for the duration of the CLI session — but this is the entire attack window. Port discovery is feasible via localhost port scanning or by reading `/proc/{pid}/cmdline` which contains the `--port` argument.
388
+ - **Description**: The CLI spawns a `langgraph dev` server subprocess with `LANGGRAPH_AUTH_TYPE=noop` (`server.py:_build_server_env`). This disables all server-side authentication. The server binds to `127.0.0.1:{port}` (a free ephemeral port by default, so it no longer squats the well-known `langgraph dev` port 2024). Any local process that discovers the port can: send arbitrary inputs to the running agent thread, read the agent's conversation state (including tool results that may contain file contents or secrets), inject messages into the conversation history, or trigger state updates. The server is ephemeral — it lives only for the duration of the CLI session — but this is the entire attack window. Port discovery is feasible via localhost port scanning or by reading `/proc/{pid}/cmdline` which contains the `--port` argument.
386
389
  - **Preconditions**: (1) Attacker has a local process running as the same user (or as root); (2) Attacker discovers the server port (port scan on localhost, or reads process arguments).
387
390
 
388
391
  #### T7: LocalContextMiddleware Injects Host File Contents into System Prompt
@@ -411,10 +414,16 @@
411
414
 
412
415
  #### T11: Auto-Installed ripgrep Binary from Upstream Release
413
416
 
414
- - **Flow**: First-run download performed by `managed_tools.ensure_ripgrep` when `rg` is not on `PATH`.
415
- - **Description**: On first invocation without a system `rg`, Deep Agents Code fetches the pinned ripgrep release tarball from `github.com/BurntSushi/ripgrep/releases/...`, verifies it against an in-tree SHA-256 (`RIPGREP_ASSETS`), extracts it under a `TemporaryDirectory`, and atomically moves the binary into `~/.deepagents/bin/rg`. The binary then runs unsandboxed, inheriting the same trust as a user-installed `rg` (the SDK invokes it via `subprocess.run(["rg", ...])`).
416
- - **Mitigations**: (1) SHA-256 verified against the pinned hash table before move — a mismatch aborts the install and leaves `BIN_DIR` clean. (2) Network egress is limited to `github.com`. (3) Opt-out via `DEEPAGENTS_CODE_OFFLINE` for air-gapped environments. (4) Pinned version + checksums are bumped in-tree, so a compromised upstream release is detected on the next Deep Agents Code release rather than silently propagating. (5) Atomic move-into-place avoids partial installs when concurrent CLI invocations race.
417
- - **Preconditions**: User has not installed `rg` via their package manager, `DEEPAGENTS_CODE_OFFLINE` is unset, and the host can reach `github.com`. The pinned SHA-256 in `RIPGREP_ASSETS` would need to be incorrect (a supply-chain compromise of the deepagents-code release) for a tampered binary to be installed.
417
+ - **Flow**: Download performed by `managed_tools.ensure_ripgrep` when `rg` is not on `PATH` — either on first run, or eagerly at install time via `dcode tools install` (invoked by `scripts/install.sh`).
418
+ - **Description**: Without a system `rg`, Deep Agents Code fetches the pinned ripgrep release tarball from `github.com/BurntSushi/ripgrep/releases/...`, verifies it against an in-tree SHA-256 (`RIPGREP_ASSETS`), extracts it under a `TemporaryDirectory`, and atomically moves the binary into `~/.deepagents/bin/rg`. The binary then runs unsandboxed, inheriting the same trust as a user-installed `rg` (the SDK invokes it via `subprocess.run(["rg", ...])`). The same verified path backs the `dcode tools install` verb, so the install script reuses it rather than re-encoding the version + checksum table in bash.
419
+ - **Mitigations**: (1) SHA-256 verified against the pinned hash table before move — a mismatch aborts the install and leaves `BIN_DIR` clean. (2) Network egress is limited to `github.com`. (3) Opt-out via `DEEPAGENTS_CODE_OFFLINE` for air-gapped environments, or `DEEPAGENTS_CODE_RIPGREP_INSTALLER=system` to defer to the OS package manager instead of the managed binary. (4) Pinned version + checksums are bumped in-tree, so a compromised upstream release is detected on the next Deep Agents Code release rather than silently propagating. (5) Atomic move-into-place avoids partial installs when concurrent CLI invocations race. (6) The eager install-script path is non-`sudo` (no system package manager is invoked in the default `managed` mode).
420
+ - **Preconditions**: User has not installed `rg` via their package manager, `DEEPAGENTS_CODE_OFFLINE` is unset, `DEEPAGENTS_CODE_RIPGREP_INSTALLER` is not `system`, and the host can reach `github.com`. The pinned SHA-256 in `RIPGREP_ASSETS` would need to be incorrect (a supply-chain compromise of the deepagents-code release) for a tampered binary to be installed.
421
+
422
+ #### T12: Project `.env` Injects Shell Interpreter Startup Hooks
423
+
424
+ - **Flow**: DF10 (project `.env` → process environment) → bash subprocess startup (DF19)
425
+ - **Description**: `config._load_dotenv` discovers the nearest project `.env` by walking up from the working directory and applies its values to the process environment (`override=False`, so shell-exported values still win). Bash treats several environment variables as startup hooks — `BASH_ENV` and `ENV` name a file that is sourced when a non-interactive shell starts. Because Deep Agents Code runs its own local-context detection through Bash at startup (`local_context.build_detect_script`) and spawns shells for the `execute` tool, a project `.env` that sets one of these keys could run attacker-controlled scripts inside the `dcode` process *before* any model-requested tool call or HITL approval prompt. The broader trust boundary is that running `dcode` in a project directory lets that project influence the process environment.
426
+ - **Preconditions**: (1) User launches `dcode` in a directory containing an attacker-controlled `.env` (for example, a freshly cloned untrusted repository); (2) the `.env` sets a shell startup-hook key that is not already exported in the user's shell (dotenv uses `override=False`).
418
427
 
419
428
  ---
420
429
 
@@ -426,7 +435,7 @@
426
435
  | LLM output | DF6, DF7 | T1, T2, T3, T4| HITL gate; shell allow-list; Unicode/URL warnings on tool args | Project | LLM-generated tool args not scanned for injection beyond Unicode/URL |
427
436
  | Tool/function results | DF9, DF11 | T1 | Unicode warning on URL args; `markdownify` HTML conversion | Shared | Tool *results* pass to context without prompt-injection scan |
428
437
  | URL-fetched content | DF8, DF9 | T1 | `check_url_safety` on URL arg; HTML→markdown conversion | Shared | Markup-embedded instructions survive markdownify; no LLM-layer guardrail |
429
- | Configuration | DF10, DF12, DF15, DF23| T9, T10 | TOML schema; MCP schema + fingerprint; JSON structure check; `class_path` format check | User | `class_path` executes module code before type check; MCP env dict unfiltered |
438
+ | Configuration | DF10, DF12, DF15, DF23| T9, T10, T12 | Dotenv shell-env precedence; TOML schema; MCP schema + fingerprint; JSON structure check; `class_path` format check | User | Project `.env` can set shell startup-hook vars; `class_path` executes module code before type check; MCP env dict unfiltered |
430
439
  | Session restore | DF14 | T5 | OS file permissions; SQLite | Project | Unencrypted at rest |
431
440
  | Server IPC (env vars) | DF18 | T6 | `ServerConfig` serialization; parent env passed to child | Project | Provider API keys flow to server subprocess; system prompt in env |
432
441
  | Host environment | DF19, DF20 | T7 | Static script; exit code check; 30s timeout | Shared | Makefile content injected into system prompt without sanitization |
@@ -450,8 +459,8 @@ Threats that appear valid in isolation but fall outside project responsibility b
450
459
  | Sandbox provider security vulnerabilities | Daytona, LangSmith, Modal, Runloop, and AgentCore are third-party services. Their internal security is not this project's responsibility. | Correctly initializing sandbox sessions via `integrations.sandbox_factory.create_sandbox`. |
451
460
  | Hook commands doing harmful things | Hooks in `~/.deepagents/hooks.json` are 100% user-authored. The payload is data-only (JSON on stdin). | JSON structure validation (`hooks._load_hooks`); 5-second timeout. |
452
461
  | Async subagent traffic interception / MitM | Async subagents connect to user-configured LangGraph deployment URLs. The project does not control those endpoints or their TLS certificates. | Accepting URL/headers from user config and passing them to the LangGraph SDK (`agent.load_async_subagents`). |
453
- | LangGraph dev server port enumeration / discovery | Discovering the local dev server port requires local access. Port scanning localhost is a general OS security concern, not a framework vulnerability. | Binding to `127.0.0.1` by default (`server._DEFAULT_HOST`); ephemeral server lifetime. |
454
- | `.env` file from parent directory changes behavior | `config._find_dotenv_from_start_path` walks up the directory tree to find `.env` files. This is standard `python-dotenv` behavior for project discovery. The user controls their filesystem. | Finding `.env` from the project root (`config._find_dotenv_from_start_path`); `override=False` by default (existing env vars preserved). |
462
+ | LangGraph dev server port enumeration / discovery | Discovering the local dev server port requires local access. Port scanning localhost is a general OS security concern, not a framework vulnerability. | Binding to `127.0.0.1` by default (`server._DEFAULT_HOST`); ephemeral server lifetime; OS-assigned ephemeral port (`server._EPHEMERAL_PORT`) is not predictable across runs. |
463
+ | `.env` file from parent directory changes app/API configuration | `config._find_dotenv_from_start_path` walks up the directory tree to find `.env` files. Discovering ordinary configuration values (API keys, `DEEPAGENTS_CODE_*` settings) this way is standard `python-dotenv` behavior, and the user controls their filesystem. The *code-execution* implication of a project `.env` (shell startup hooks) is tracked in-scope as T12. | Finding `.env` from the project root (`config._find_dotenv_from_start_path`); `override=False` by default (existing env vars preserved); shell startup / environment-hijack keys (`BASH_ENV`, `ENV`) denied during dotenv loading. |
455
464
 
456
465
  ### Rationale
457
466
 
@@ -483,3 +492,5 @@ Threats that appear valid in isolation but fall outside project responsibility b
483
492
  | 2026-03-10 | langster-threat-model (automated) | Initial threat model |
484
493
  | 2026-03-27 | langster-threat-model (automated) | Deep expansion: added C11-C16 (server subprocess, RemoteAgent, LocalContextMiddleware, async subagent config, custom subagent loader); added TB8-TB10 (CLI/server IPC, LocalContext/host env, RemoteAgent/dev server); added DF18-DF22; added T6 (unauthenticated dev server), T7 (Makefile injection), T8 (subagent body injection); updated T5 (upstream msgpack fix confirmed); added data classification; added Investigated and Dismissed section; updated architecture diagram to reflect server-subprocess model |
485
494
  | 2026-03-28 | langster-threat-model (automated) | Deep validation pass: added C17 (Model Config Loader with class_path), TB11 (Config→Code Execution); added DC5 (offloaded conversation history); added DF23-DF25 (class_path flow, MCP env dict flow, offload flow); added T9 (class_path arbitrary code execution), T10 (MCP env dict unfiltered); added D3 (SSRF dismissed — HITL is intended control), D4 (offload path injection dismissed — UUID7); **removed Status column and Mitigations/Residual Risk fields from all threats** (open source visibility compliance — mitigation status must not appear in public threat models); updated T6 validation from Likely to Verified (port is deterministic at 2024 default, discoverable via /proc); updated external context (no published advisories found); updated architecture diagram |
495
+ | 2026-06-25 | manual update | Added T12 (project `.env` injects shell interpreter startup hooks) under TB11; extended the TB11 boundary controls and details with the dotenv shell-startup-hook denylist (`BASH_ENV`, `ENV`); clarified the `.env` out-of-scope row to separate ordinary config discovery from the in-scope code-execution implication |
496
+ | 2026-06-25 | manual update | Updated T6 and TB10 to reflect the dev server binding an OS-assigned ephemeral port by default (`server._EPHEMERAL_PORT`) instead of squatting the well-known `langgraph dev` port 2024; noted unpredictable-port-across-runs as added defense-in-depth in the port-discovery dismissal row |
@@ -1,3 +1,3 @@
1
1
  """Generated at build time. Do not edit or commit."""
2
2
 
3
- BUILD_COMMIT = "649443a"
3
+ BUILD_COMMIT = "9f2622d"
@@ -39,6 +39,8 @@ class CLIContextSchema:
39
39
 
40
40
  auto_approve: bool = False
41
41
 
42
+ approval_mode_key: str | None = None
43
+
42
44
 
43
45
  class CLIContext(TypedDict, total=False):
44
46
  """Client-facing builder for the per-run graph context payload.
@@ -76,3 +78,12 @@ class CLIContext(TypedDict, total=False):
76
78
  this to suppress interrupts at the source when "approve always" is on,
77
79
  avoiding the interrupt-then-auto-resolve round-trip.
78
80
  """
81
+
82
+ approval_mode_key: str | None
83
+ """Store key for the live approval-mode control record.
84
+
85
+ The TUI updates this record when the user toggles approval mode mid-run.
86
+ The server-side interrupt predicate reads it from the LangGraph Store on
87
+ each gated tool call so auto-to-manual changes can take effect before the
88
+ current stream returns.
89
+ """
@@ -158,6 +158,15 @@ and `/api/show`. See `_ollama_discovery_enabled` for accepted truthy/falsy
158
158
  values.
159
159
  """
160
160
 
161
+ ONBOARDING_INTEGRATIONS_SCREEN = "DEEPAGENTS_CODE_ONBOARDING_INTEGRATIONS_SCREEN"
162
+ """Show the "Installed Integrations" summary screen during first-run onboarding.
163
+
164
+ Off by default: onboarding goes straight from the name prompt to the model
165
+ selector, which already surfaces (and installs) uninstalled model providers.
166
+ Set to a truthy value to bring the standalone integrations screen back into the
167
+ flow. Parsed by `is_env_truthy`: accepts `1`, `true`, `yes`, `on` as enabled.
168
+ """
169
+
161
170
  RESTARTED_AFTER_UPDATE = "DEEPAGENTS_CODE_RESTARTED_AFTER_UPDATE"
162
171
  """Internal sentinel recording the target version immediately before the
163
172
  startup auto-update re-execs the process.
@@ -168,6 +177,16 @@ version), skips auto-updating to break out of an otherwise endless
168
177
  upgrade/restart loop. Set and read internally across `os.execv`.
169
178
  """
170
179
 
180
+ RIPGREP_INSTALLER = "DEEPAGENTS_CODE_RIPGREP_INSTALLER"
181
+ """Select how ripgrep is provisioned: `managed` (default) or `system`.
182
+
183
+ `managed` downloads the pinned, SHA-256-verified upstream binary into
184
+ `~/.deepagents/bin` (no sudo). `system` skips that download so power users can
185
+ rely on their distro package / existing toolchain instead; the install script's
186
+ `system` mode keeps the brew/apt/cargo path. A system `rg` already on `PATH` is
187
+ reused under either setting. Unrecognized values fall back to `managed`. See
188
+ `managed_tools.ripgrep_installer`."""
189
+
171
190
  SERVER_ENV_PREFIX = "DEEPAGENTS_CODE_SERVER_"
172
191
  """Environment variable prefix used to pass CLI config to the server subprocess."""
173
192
 
@@ -101,6 +101,67 @@ def _read_env_optional_bool(suffix: str) -> bool | None:
101
101
  return raw.lower() == "true"
102
102
 
103
103
 
104
+ def _resolve_enable_interpreter(
105
+ enable_interpreter: bool | None, sandbox_type: str | None
106
+ ) -> bool:
107
+ """Resolve the interpreter's tri-state caller option to a concrete boolean.
108
+
109
+ Args:
110
+ enable_interpreter: Explicit caller preference, or `None` to use the
111
+ sandbox-aware default.
112
+ sandbox_type: Sandbox backend identifier. Any falsy value (`None`, `""`)
113
+ or `"none"` is treated as local execution.
114
+
115
+ Returns:
116
+ The explicit `enable_interpreter` value when not `None`; `False` for
117
+ remote-sandbox defaults; otherwise the configured local default
118
+ (`settings.enable_interpreter`).
119
+ """
120
+ if enable_interpreter is not None:
121
+ return enable_interpreter
122
+ if sandbox_type and sandbox_type != "none":
123
+ return False
124
+
125
+ from deepagents_code.config import settings
126
+
127
+ return settings.enable_interpreter
128
+
129
+
130
+ def _interpreter_suppressed_by_sandbox(
131
+ *, enable_interpreter: bool | None, sandbox_type: str | None, local_default: bool
132
+ ) -> bool:
133
+ """Whether a remote sandbox suppressed the otherwise-default interpreter.
134
+
135
+ Used to decide whether to surface an advisory: returns `True` only when the
136
+ user made no explicit choice, a remote sandbox is active, and the local
137
+ default would have enabled it — i.e. the sandbox (not an explicit
138
+ `--no-interpreter` opt-out, nor a disabled `[interpreter]` config) is why
139
+ `js_eval` is unavailable.
140
+
141
+ Takes the *raw* tri-state caller intent rather than the resolved boolean: a
142
+ sandbox-suppressed default and an explicit `--no-interpreter` both resolve to
143
+ `False`, so the resolved value cannot distinguish them. Any explicit choice
144
+ (`not None`) is the user's own decision and is left unannounced.
145
+
146
+ Args:
147
+ enable_interpreter: The raw tri-state caller intent (`--interpreter` →
148
+ `True`, `--no-interpreter` → `False`, unset → `None`).
149
+ sandbox_type: Sandbox backend identifier. Any falsy value (`None`, `""`)
150
+ or `"none"` is treated as local execution.
151
+ local_default: The local-mode default (`settings.enable_interpreter`);
152
+ gating on it keeps the advisory quiet for users who disabled the
153
+ interpreter in config.
154
+
155
+ Returns:
156
+ `True` when the advisory should be shown, otherwise `False`.
157
+ """
158
+ if enable_interpreter is not None:
159
+ return False
160
+ if not (sandbox_type and sandbox_type != "none"):
161
+ return False
162
+ return local_default
163
+
164
+
104
165
  @dataclass(frozen=True)
105
166
  class ServerConfig:
106
167
  """Full configuration payload passed from the app to the server subprocess.
@@ -155,6 +216,13 @@ class ServerConfig:
155
216
  enable_interpreter: bool = False
156
217
  """Enable `CodeInterpreterMiddleware` (`js_eval` REPL) on the main agent.
157
218
 
219
+ Always the resolved concrete value: `from_cli_args` collapses the tri-state
220
+ caller option via `_resolve_enable_interpreter` before constructing the
221
+ config, so the `bool | None` "defer to default" sentinel never reaches this
222
+ field. The `False` default here is only the bare-constructor/`from_env`
223
+ fallback; the user-facing default (on in local mode) lives in
224
+ `settings.enable_interpreter`.
225
+
158
226
  Local-mode only; the server graph raises if a sandbox is configured and
159
227
  this flag is `True`.
160
228
  """
@@ -341,7 +409,7 @@ class ServerConfig:
341
409
  sandbox_setup: str | None,
342
410
  enable_shell: bool,
343
411
  enable_ask_user: bool,
344
- enable_interpreter: bool = False,
412
+ enable_interpreter: bool | None = None,
345
413
  interpreter_ptc: str | list[str] | None = None,
346
414
  interpreter_ptc_acknowledge_unsafe: bool = False,
347
415
  mcp_config_path: str | None,
@@ -373,7 +441,7 @@ class ServerConfig:
373
441
  enable_shell: Enable shell execution tools.
374
442
  enable_ask_user: Enable ask_user tool.
375
443
  enable_interpreter: Enable `CodeInterpreterMiddleware` on the main
376
- agent.
444
+ agent. `None` uses the sandbox-aware default.
377
445
  interpreter_ptc: Override for `settings.interpreter_ptc`.
378
446
  interpreter_ptc_acknowledge_unsafe: Mirror of
379
447
  `settings.interpreter_ptc_acknowledge_unsafe`.
@@ -387,6 +455,10 @@ class ServerConfig:
387
455
  """
388
456
  normalized_mcp = _normalize_path(mcp_config_path, project_context, "MCP config")
389
457
 
458
+ resolved_enable_interpreter = _resolve_enable_interpreter(
459
+ enable_interpreter, sandbox_type
460
+ )
461
+
390
462
  return cls(
391
463
  model=model_name,
392
464
  model_params=model_params,
@@ -397,7 +469,7 @@ class ServerConfig:
397
469
  interactive=interactive,
398
470
  enable_shell=enable_shell,
399
471
  enable_ask_user=enable_ask_user,
400
- enable_interpreter=enable_interpreter,
472
+ enable_interpreter=resolved_enable_interpreter,
401
473
  interpreter_ptc=interpreter_ptc,
402
474
  interpreter_ptc_acknowledge_unsafe=interpreter_ptc_acknowledge_unsafe,
403
475
  sandbox_type=sandbox_type,
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Keep the `x-release-please-version` annotation — release-please uses it to
4
4
  # bump `__version__` in sync with `pyproject.toml` on every release PR.
5
- __version__ = "0.1.23" # x-release-please-version
5
+ __version__ = "0.1.25" # x-release-please-version
6
6
 
7
7
  DOCS_URL = "https://docs.langchain.com/oss/python/deepagents/code"
8
8
  """URL for `deepagents-code` documentation."""
@@ -217,7 +217,7 @@ class ShellAllowListMiddleware(AgentMiddleware):
217
217
 
218
218
 
219
219
  _INTERPRETER_WRITE_TOOLS: frozenset[str] = frozenset(
220
- {"execute", "write_file", "edit_file"}
220
+ {"execute", "write_file", "edit_file", "delete"}
221
221
  )
222
222
  """Tools considered write/shell capable for PTC auditing.
223
223
 
@@ -910,6 +910,17 @@ def _format_edit_file_description(
910
910
  return f"Action: Replace text ({scope})"
911
911
 
912
912
 
913
+ def _format_delete_description(
914
+ _tool_call: ToolCall, _state: AgentState[Any], _runtime: Runtime[Any]
915
+ ) -> str:
916
+ """Format delete tool call for approval prompt.
917
+
918
+ Returns:
919
+ Formatted description string for the delete tool call.
920
+ """
921
+ return "Action: Delete file or directory"
922
+
923
+
913
924
  def _format_web_search_description(
914
925
  tool_call: ToolCall, _state: AgentState[Any], _runtime: Runtime[Any]
915
926
  ) -> str:
@@ -1030,6 +1041,38 @@ def _is_auto_approve_enabled(value: object) -> bool:
1030
1041
  return isinstance(value, bool) and value
1031
1042
 
1032
1043
 
1044
+ def _read_live_auto_approve(store: object, key: str | None) -> bool | None:
1045
+ """Return live approval mode from the LangGraph Store when configured.
1046
+
1047
+ Args:
1048
+ store: `request.runtime.store` from the graph server.
1049
+ key: Live approval-mode store key, or `None` when this run has no live
1050
+ control record.
1051
+
1052
+ Returns:
1053
+ `None` when no live key is configured for this run — the caller should
1054
+ fall back to the static `auto_approve` context snapshot.
1055
+ `True` or `False` when a live key is configured: these reflect
1056
+ the stored mode, and `False` is also returned when the key
1057
+ is configured but the store is unreadable (missing item,
1058
+ malformed value, read error), so an unreadable live mode fails
1059
+ closed and interrupts.
1060
+ `None` therefore means "feature not in play," the opposite of the store
1061
+ reader's `None` ("unreadable, be careful").
1062
+ """
1063
+ if not key:
1064
+ return None
1065
+ from deepagents_code.approval_mode import read_approval_mode_from_store
1066
+
1067
+ value = read_approval_mode_from_store(store, key)
1068
+ if value is None:
1069
+ logger.warning(
1070
+ "Approval-mode store item is unavailable; interrupting for safety"
1071
+ )
1072
+ return False
1073
+ return value
1074
+
1075
+
1033
1076
  def _should_interrupt_tool_call(request: ToolCallRequest) -> bool:
1034
1077
  """Decide whether a gated tool call should pause for human approval.
1035
1078
 
@@ -1052,9 +1095,16 @@ def _should_interrupt_tool_call(request: ToolCallRequest) -> bool:
1052
1095
  """
1053
1096
  runtime = getattr(request, "runtime", None)
1054
1097
  ctx = getattr(runtime, "context", None)
1098
+ store = getattr(runtime, "store", None)
1055
1099
  if isinstance(ctx, CLIContextSchema):
1100
+ if (live := _read_live_auto_approve(store, ctx.approval_mode_key)) is not None:
1101
+ return not live
1056
1102
  return not _is_auto_approve_enabled(ctx.auto_approve)
1057
1103
  if isinstance(ctx, dict):
1104
+ raw_key = ctx.get("approval_mode_key")
1105
+ key = raw_key if isinstance(raw_key, str) else None
1106
+ if (live := _read_live_auto_approve(store, key)) is not None:
1107
+ return not live
1058
1108
  # Type-checked (not truthiness) check: over the JSON/RemoteGraph boundary a
1059
1109
  # malformed payload (e.g. "yes", 1) must fail closed and interrupt, not
1060
1110
  # silently auto-approve. Only a genuine boolean `True` suppresses.
@@ -1107,6 +1157,12 @@ def _add_interrupt_on() -> dict[str, InterruptOnConfig]:
1107
1157
  "when": _should_interrupt_tool_call,
1108
1158
  }
1109
1159
 
1160
+ delete_interrupt_config: InterruptOnConfig = {
1161
+ "allowed_decisions": ["approve", "reject"],
1162
+ "description": _format_delete_description, # ty: ignore[invalid-argument-type] # Callable description narrower than TypedDict expects
1163
+ "when": _should_interrupt_tool_call,
1164
+ }
1165
+
1110
1166
  web_search_interrupt_config: InterruptOnConfig = {
1111
1167
  "allowed_decisions": ["approve", "reject"],
1112
1168
  "description": _format_web_search_description, # ty: ignore[invalid-argument-type] # Callable description narrower than TypedDict expects
@@ -1135,6 +1191,7 @@ def _add_interrupt_on() -> dict[str, InterruptOnConfig]:
1135
1191
  "execute": execute_interrupt_config,
1136
1192
  "write_file": write_file_interrupt_config,
1137
1193
  "edit_file": edit_file_interrupt_config,
1194
+ "delete": delete_interrupt_config,
1138
1195
  "web_search": web_search_interrupt_config,
1139
1196
  "fetch_url": fetch_url_interrupt_config,
1140
1197
  "task": task_interrupt_config,
@@ -1267,8 +1324,7 @@ def create_cli_agent(
1267
1324
  list or `interpreter_ptc="all"` with
1268
1325
  `interpreter_ptc_acknowledge_unsafe=True`.
1269
1326
 
1270
- Requires the `quickjs` optional extra
1271
- (`langchain-quickjs>=0.3.1,<0.4.0`).
1327
+ Requires the core `langchain-quickjs` dependency.
1272
1328
  checkpointer: Optional checkpointer for session persistence.
1273
1329
  When `None`, the graph is compiled without a checkpointer.
1274
1330
  mcp_server_info: MCP server metadata to surface in the system prompt.