deepagents-code 0.1.32__tar.gz → 0.1.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 (331) hide show
  1. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/CHANGELOG.md +13 -0
  2. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/PKG-INFO +5 -5
  3. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/THREAT_MODEL.md +1 -1
  4. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/_build_info.py +1 -1
  5. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/_env_vars.py +36 -0
  6. deepagents_code-0.1.33/deepagents_code/_fake_models.py +66 -0
  7. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/_testing_models.py +22 -34
  8. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/_version.py +1 -1
  9. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/agent.py +16 -9
  10. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/app.py +180 -2
  11. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/config.py +55 -8
  12. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/config_manifest.py +44 -0
  13. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/input.py +198 -12
  14. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/main.py +91 -8
  15. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/mcp_disabled.py +52 -22
  16. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/mcp_tools.py +262 -65
  17. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/media_utils.py +137 -3
  18. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/model_config.py +243 -0
  19. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/non_interactive.py +6 -1
  20. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/skills/commands.py +172 -2
  21. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/skills/invocation.py +9 -0
  22. deepagents_code-0.1.33/deepagents_code/skills/trust.py +547 -0
  23. deepagents_code-0.1.33/deepagents_code/tool_catalog.py +354 -0
  24. deepagents_code-0.1.33/deepagents_code/tools_commands.py +402 -0
  25. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/ui.py +49 -0
  26. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/chat_input.py +76 -5
  27. deepagents_code-0.1.33/deepagents_code/widgets/skill_trust.py +131 -0
  28. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/pyproject.toml +4 -4
  29. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/skills/test_commands.py +287 -0
  30. deepagents_code-0.1.33/tests/unit_tests/skills/test_skill_trust.py +528 -0
  31. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_chat_input.py +198 -1
  32. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_main.py +221 -0
  33. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_mcp_disabled.py +59 -2
  34. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_mcp_tools.py +462 -0
  35. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_media_utils.py +369 -0
  36. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_model_config.py +323 -0
  37. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_non_interactive.py +58 -0
  38. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_reload.py +205 -0
  39. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_skill_invocation.py +407 -4
  40. deepagents_code-0.1.33/tests/unit_tests/test_skill_trust_screen.py +78 -0
  41. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_startup_fast_paths.py +1 -0
  42. deepagents_code-0.1.33/tests/unit_tests/test_tool_catalog.py +334 -0
  43. deepagents_code-0.1.33/tests/unit_tests/test_tools_commands.py +527 -0
  44. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/uv.lock +6 -6
  45. deepagents_code-0.1.32/deepagents_code/tools_commands.py +0 -191
  46. deepagents_code-0.1.32/tests/unit_tests/test_tools_commands.py +0 -144
  47. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/.gitignore +0 -0
  48. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/AGENTS.md +0 -0
  49. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/ARCHITECTURE.md +0 -0
  50. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/COMMANDS.md +0 -0
  51. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/DEVELOPMENT.md +0 -0
  52. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/Makefile +0 -0
  53. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/README.md +0 -0
  54. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/__init__.py +0 -0
  55. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/__main__.py +0 -0
  56. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/_ask_user_types.py +0 -0
  57. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/_cli_context.py +0 -0
  58. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/_constants.py +0 -0
  59. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/_debug.py +0 -0
  60. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/_git.py +0 -0
  61. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/_paths.py +0 -0
  62. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/_server_config.py +0 -0
  63. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/_session_stats.py +0 -0
  64. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/_startup_error.py +0 -0
  65. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/_textual_patches.py +0 -0
  66. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/_tool_stream.py +0 -0
  67. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/app.tcss +0 -0
  68. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/approval_mode.py +0 -0
  69. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/ask_user.py +0 -0
  70. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/auth_commands.py +0 -0
  71. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/auth_display.py +0 -0
  72. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/auth_store.py +0 -0
  73. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/built_in_skills/__init__.py +0 -0
  74. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/built_in_skills/remember/SKILL.md +0 -0
  75. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/built_in_skills/skill-creator/SKILL.md +0 -0
  76. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
  77. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
  78. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/clipboard.py +0 -0
  79. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/command_registry.py +0 -0
  80. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/config_commands.py +0 -0
  81. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/configurable_model.py +0 -0
  82. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/default_agent_prompt.md +0 -0
  83. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/doctor.py +0 -0
  84. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/editor.py +0 -0
  85. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/event_bus.py +0 -0
  86. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/extras_info.py +0 -0
  87. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/file_ops.py +0 -0
  88. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/formatting.py +0 -0
  89. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/goal_rubric.py +0 -0
  90. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/goal_tools.py +0 -0
  91. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/hooks.py +0 -0
  92. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/integrations/__init__.py +0 -0
  93. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/integrations/openai_codex.py +0 -0
  94. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/integrations/sandbox_config.py +0 -0
  95. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/integrations/sandbox_factory.py +0 -0
  96. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/integrations/sandbox_provider.py +0 -0
  97. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/integrations/sandbox_registry.py +0 -0
  98. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/iterm_cursor_guide.py +0 -0
  99. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/local_context.py +0 -0
  100. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/managed_tools.py +0 -0
  101. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/mcp_auth.py +0 -0
  102. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/mcp_commands.py +0 -0
  103. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/mcp_login_service.py +0 -0
  104. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/mcp_oauth_ui.py +0 -0
  105. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/mcp_providers/__init__.py +0 -0
  106. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/mcp_providers/_registry.py +0 -0
  107. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/mcp_providers/base.py +0 -0
  108. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/mcp_providers/github.py +0 -0
  109. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/mcp_providers/slack.py +0 -0
  110. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/mcp_trust.py +0 -0
  111. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/memory_guard.py +0 -0
  112. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/notifications.py +0 -0
  113. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/offload.py +0 -0
  114. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/onboarding.py +0 -0
  115. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/output.py +0 -0
  116. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/paste_collapse.py +0 -0
  117. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/project_utils.py +0 -0
  118. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/py.typed +0 -0
  119. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/reasoning_effort.py +0 -0
  120. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/remote_client.py +0 -0
  121. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/resume_state.py +0 -0
  122. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/server.py +0 -0
  123. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/server_graph.py +0 -0
  124. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/server_manager.py +0 -0
  125. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/sessions.py +0 -0
  126. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/skills/__init__.py +0 -0
  127. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/skills/load.py +0 -0
  128. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/state_migration.py +0 -0
  129. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/subagents.py +0 -0
  130. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/system_prompt.md +0 -0
  131. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/terminal_capabilities.py +0 -0
  132. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/terminal_escape.py +0 -0
  133. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/textual_adapter.py +0 -0
  134. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/theme.py +0 -0
  135. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/tool_display.py +0 -0
  136. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/tools.py +0 -0
  137. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/unicode_security.py +0 -0
  138. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/update_check.py +0 -0
  139. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/__init__.py +0 -0
  140. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/_js_eval_display.py +0 -0
  141. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/_links.py +0 -0
  142. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/agent_selector.py +0 -0
  143. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/approval.py +0 -0
  144. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/ask_user.py +0 -0
  145. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/auth.py +0 -0
  146. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/autocomplete.py +0 -0
  147. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/codex_auth.py +0 -0
  148. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/cwd_switch.py +0 -0
  149. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/diff.py +0 -0
  150. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/effort_selector.py +0 -0
  151. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/goal_review.py +0 -0
  152. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/history.py +0 -0
  153. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/install_confirm.py +0 -0
  154. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/launch_init.py +0 -0
  155. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/loading.py +0 -0
  156. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/mcp_login.py +0 -0
  157. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/mcp_reconnect.py +0 -0
  158. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/mcp_viewer.py +0 -0
  159. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/message_store.py +0 -0
  160. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/messages.py +0 -0
  161. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/model_selector.py +0 -0
  162. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/notification_center.py +0 -0
  163. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/notification_detail.py +0 -0
  164. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/notification_settings.py +0 -0
  165. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/restart_prompt.py +0 -0
  166. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/status.py +0 -0
  167. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/subagent_panel.py +0 -0
  168. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/theme_selector.py +0 -0
  169. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/thread_selector.py +0 -0
  170. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/tool_renderers.py +0 -0
  171. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/tool_widgets.py +0 -0
  172. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/update_available.py +0 -0
  173. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/update_confirm.py +0 -0
  174. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/update_progress.py +0 -0
  175. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/deepagents_code/widgets/welcome.py +0 -0
  176. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/examples/skills/arxiv-search/SKILL.md +0 -0
  177. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/examples/skills/arxiv-search/arxiv_search.py +0 -0
  178. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/examples/skills/langgraph-docs/SKILL.md +0 -0
  179. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/examples/skills/skill-creator/SKILL.md +0 -0
  180. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
  181. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
  182. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/examples/skills/web-research/SKILL.md +0 -0
  183. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/hatch_build.py +0 -0
  184. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/images/tui.png +0 -0
  185. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/scripts/check_imports.py +0 -0
  186. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/scripts/debug_server.sh +0 -0
  187. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/scripts/generate_commands_catalog.py +0 -0
  188. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/scripts/install.sh +0 -0
  189. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/README.md +0 -0
  190. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/integration_tests/__init__.py +0 -0
  191. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/integration_tests/benchmarks/__init__.py +0 -0
  192. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
  193. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
  194. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/integration_tests/conftest.py +0 -0
  195. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/integration_tests/test_acp_mode.py +0 -0
  196. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/integration_tests/test_auto_approve_remote.py +0 -0
  197. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/integration_tests/test_compact_resume.py +0 -0
  198. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/integration_tests/test_sandbox_factory.py +0 -0
  199. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/integration_tests/test_sandbox_operations.py +0 -0
  200. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/__init__.py +0 -0
  201. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/conftest.py +0 -0
  202. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/data/coding_agent_v1_validator.json +0 -0
  203. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/skills/__init__.py +0 -0
  204. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/skills/test_load.py +0 -0
  205. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/skills/test_skills_json.py +0 -0
  206. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/smoke_tests/__init__.py +0 -0
  207. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/smoke_tests/conftest.py +0 -0
  208. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/smoke_tests/snapshots/system_prompt_interactive_local.md +0 -0
  209. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/smoke_tests/test_system_prompt.py +0 -0
  210. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test__tool_stream.py +0 -0
  211. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_agent.py +0 -0
  212. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_agent_friendly.py +0 -0
  213. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_agent_selector.py +0 -0
  214. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_app.py +0 -0
  215. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_approval.py +0 -0
  216. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_approval_mode.py +0 -0
  217. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_args.py +0 -0
  218. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_ask_user.py +0 -0
  219. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_ask_user_middleware.py +0 -0
  220. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_auth_commands.py +0 -0
  221. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_auth_display.py +0 -0
  222. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_auth_store.py +0 -0
  223. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_auth_widgets.py +0 -0
  224. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_autocomplete.py +0 -0
  225. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_charset.py +0 -0
  226. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_clipboard.py +0 -0
  227. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_coding_agent_metadata.py +0 -0
  228. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_command_registry.py +0 -0
  229. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_compact_tool.py +0 -0
  230. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_config.py +0 -0
  231. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_config_manifest.py +0 -0
  232. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_configurable_model.py +0 -0
  233. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_cursor_blink.py +0 -0
  234. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_cwd_switch.py +0 -0
  235. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_debug.py +0 -0
  236. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_doctor.py +0 -0
  237. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_editor.py +0 -0
  238. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_end_to_end.py +0 -0
  239. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_env_vars.py +0 -0
  240. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_event_bus.py +0 -0
  241. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_exception_handling.py +0 -0
  242. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_extras_info.py +0 -0
  243. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_file_ops.py +0 -0
  244. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_formatting.py +0 -0
  245. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_git.py +0 -0
  246. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_goal_review.py +0 -0
  247. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_goal_rubric.py +0 -0
  248. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_goal_tools.py +0 -0
  249. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_hatch_build.py +0 -0
  250. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_history.py +0 -0
  251. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_hooks.py +0 -0
  252. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_imports.py +0 -0
  253. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_input_parsing.py +0 -0
  254. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_install_command.py +0 -0
  255. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_install_confirm.py +0 -0
  256. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_install_script.py +0 -0
  257. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
  258. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_launch_init.py +0 -0
  259. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_links.py +0 -0
  260. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_loading.py +0 -0
  261. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_local_context.py +0 -0
  262. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_main_acp_mode.py +0 -0
  263. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_main_args.py +0 -0
  264. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_managed_tools.py +0 -0
  265. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_mcp_auth.py +0 -0
  266. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_mcp_commands.py +0 -0
  267. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_mcp_login_modal.py +0 -0
  268. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_mcp_login_service.py +0 -0
  269. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_mcp_oauth_ui.py +0 -0
  270. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_mcp_reconnect.py +0 -0
  271. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_mcp_trust.py +0 -0
  272. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_mcp_viewer.py +0 -0
  273. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_memory_guard.py +0 -0
  274. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_message_store.py +0 -0
  275. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_messages.py +0 -0
  276. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_model_selector.py +0 -0
  277. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_model_switch.py +0 -0
  278. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_notification_center.py +0 -0
  279. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_notification_detail.py +0 -0
  280. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_notifications.py +0 -0
  281. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_offload.py +0 -0
  282. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_offload_dict_messages.py +0 -0
  283. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_onboarding.py +0 -0
  284. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_openai_codex_integration.py +0 -0
  285. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_output.py +0 -0
  286. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_paths.py +0 -0
  287. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_reasoning_effort.py +0 -0
  288. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_remote_client.py +0 -0
  289. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_restart_prompt.py +0 -0
  290. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_resume_state.py +0 -0
  291. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_rubric_cli.py +0 -0
  292. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_sandbox_config.py +0 -0
  293. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_sandbox_factory.py +0 -0
  294. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_sandbox_provider.py +0 -0
  295. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_sandbox_registry.py +0 -0
  296. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_server.py +0 -0
  297. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_server_config.py +0 -0
  298. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_server_graph.py +0 -0
  299. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_server_helpers.py +0 -0
  300. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_server_manager.py +0 -0
  301. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_session_stats.py +0 -0
  302. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_sessions.py +0 -0
  303. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_shell_allow_list.py +0 -0
  304. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_state_migration.py +0 -0
  305. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_status.py +0 -0
  306. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_subagent_panel.py +0 -0
  307. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_subagent_stream.py +0 -0
  308. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_subagents.py +0 -0
  309. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_terminal_capabilities.py +0 -0
  310. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_terminal_escape.py +0 -0
  311. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_terminal_progress_preference.py +0 -0
  312. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_textual_adapter.py +0 -0
  313. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_textual_patches.py +0 -0
  314. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_theme.py +0 -0
  315. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_thread_selector.py +0 -0
  316. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_tool_display.py +0 -0
  317. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_tool_renderers.py +0 -0
  318. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_tracing_replicas.py +0 -0
  319. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_ui.py +0 -0
  320. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_unicode_security.py +0 -0
  321. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_update_available.py +0 -0
  322. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_update_check.py +0 -0
  323. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_update_confirm.py +0 -0
  324. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_update_progress.py +0 -0
  325. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_version.py +0 -0
  326. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/test_welcome.py +0 -0
  327. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/tools/__init__.py +0 -0
  328. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/tools/test_current_thread.py +0 -0
  329. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/tools/test_fetch_url.py +0 -0
  330. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/widgets/__init__.py +0 -0
  331. {deepagents_code-0.1.32 → deepagents_code-0.1.33}/tests/unit_tests/widgets/test_diff.py +0 -0
@@ -2,6 +2,19 @@
2
2
 
3
3
  # Deep Agents Code Changelog
4
4
 
5
+ ## [0.1.33](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.32...deepagents-code==0.1.33) (2026-07-06)
6
+
7
+ ### Features
8
+
9
+ * In-the-moment trust prompt for symlinked skills ([#4200](https://github.com/langchain-ai/deepagents/issues/4200)) ([a4431e4](https://github.com/langchain-ai/deepagents/commit/a4431e4339348431e91533cb2b177259ab94b083))
10
+ * Selective per-server project MCP trust ([#4507](https://github.com/langchain-ai/deepagents/issues/4507)) ([aaa22a9](https://github.com/langchain-ai/deepagents/commit/aaa22a9340cb3d2c8e9ce1a921957d0a9121da20))
11
+ * Add `dcode tools list` command ([#4461](https://github.com/langchain-ai/deepagents/issues/4461)) ([1402d0e](https://github.com/langchain-ai/deepagents/commit/1402d0e735a1580503f240457c77db76fcd779d7))
12
+
13
+ ### Bug Fixes
14
+
15
+ * Strip media placeholders from model-facing message text ([#4462](https://github.com/langchain-ai/deepagents/issues/4462)) ([aa0ae36](https://github.com/langchain-ai/deepagents/commit/aa0ae36b00df6411a9200610a9075ef2dc28b1af))
16
+ * Re-apply theme preference on `/reload` ([#4514](https://github.com/langchain-ai/deepagents/issues/4514)) ([5d1c392](https://github.com/langchain-ai/deepagents/commit/5d1c3928f7ca0ea97f28fd4d34ae1a4ee885e888))
17
+
5
18
  ## [0.1.32](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.31...deepagents-code==0.1.32) (2026-07-06)
6
19
 
7
20
  ### Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepagents-code
3
- Version: 0.1.32
3
+ Version: 0.1.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/
@@ -27,10 +27,10 @@ Classifier: Topic :: Terminals
27
27
  Requires-Python: <4.0,>=3.11
28
28
  Requires-Dist: aiosqlite<1.0.0,>=0.22.1
29
29
  Requires-Dist: deepagents-acp<1.0.0,>=0.0.8
30
- Requires-Dist: deepagents==0.7.0a3
30
+ Requires-Dist: deepagents==0.7.0a4
31
31
  Requires-Dist: httpx<1.0.0,>=0.28.1
32
32
  Requires-Dist: langchain-anthropic<2.0.0,>=1.4.7
33
- Requires-Dist: langchain-google-genai<5.0.0,>=4.2.6
33
+ Requires-Dist: langchain-google-genai<5.0.0,>=4.2.7
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
36
  Requires-Dist: langchain-quickjs<0.4.0,>=0.3.2
@@ -67,7 +67,7 @@ Requires-Dist: langchain-baseten<1.0.0,>=0.2.1; extra == 'all-providers'
67
67
  Requires-Dist: langchain-cohere<1.0.0,>=0.6.0; extra == 'all-providers'
68
68
  Requires-Dist: langchain-deepseek<2.0.0,>=1.1.0; extra == 'all-providers'
69
69
  Requires-Dist: langchain-fireworks<2.0.0,>=1.4.3; extra == 'all-providers'
70
- Requires-Dist: langchain-google-genai<5.0.0,>=4.2.6; extra == 'all-providers'
70
+ Requires-Dist: langchain-google-genai<5.0.0,>=4.2.7; extra == 'all-providers'
71
71
  Requires-Dist: langchain-google-vertexai<4.0.0,>=3.2.4; extra == 'all-providers'
72
72
  Requires-Dist: langchain-groq<2.0.0,>=1.1.3; extra == 'all-providers'
73
73
  Requires-Dist: langchain-huggingface<2.0.0,>=1.2.2; extra == 'all-providers'
@@ -102,7 +102,7 @@ Requires-Dist: langchain-deepseek<2.0.0,>=1.1.0; extra == 'deepseek'
102
102
  Provides-Extra: fireworks
103
103
  Requires-Dist: langchain-fireworks<2.0.0,>=1.4.3; extra == 'fireworks'
104
104
  Provides-Extra: google-genai
105
- Requires-Dist: langchain-google-genai<5.0.0,>=4.2.6; extra == 'google-genai'
105
+ Requires-Dist: langchain-google-genai<5.0.0,>=4.2.7; extra == 'google-genai'
106
106
  Provides-Extra: groq
107
107
  Requires-Dist: langchain-groq<2.0.0,>=1.1.3; extra == 'groq'
108
108
  Provides-Extra: huggingface
@@ -232,7 +232,7 @@
232
232
 
233
233
  #### TB4: MCP Config → Process / Network
234
234
 
235
- - **Inside**: `mcp_tools._validate_server_config` validates JSON structure and field types. `mcp_trust.compute_config_fingerprint` computes SHA-256 over config file contents. Project-level stdio servers require trust approval (fingerprint prompt) unless `--trust-project-mcp` is set.
235
+ - **Inside**: `mcp_tools._validate_server_config` validates JSON structure and field types. `mcp_trust.compute_config_fingerprint` computes SHA-256 over config file contents. Project-level stdio servers require trust approval (fingerprint prompt) unless `--trust-project-mcp` is set. A user can selectively pre-approve or reject individual project servers by name via `[mcp].enabled_project_servers` / `disabled_project_servers` (or the `DEEPAGENTS_CODE_ENABLED_PROJECT_MCP_SERVERS` / `..._DISABLED_...` env vars); reject wins over approval and over full trust. These lists are read by `model_config.load_mcp_server_trust_lists` only from user-controlled sources — the user-level `~/.deepagents/config.toml`, the global `~/.deepagents/.env`, and shell-exported env — never from `.mcp.json` or any repo-committed file, so a committed config cannot self-approve its own servers. In particular, the env forms (`DEEPAGENTS_CODE_ENABLED_PROJECT_MCP_SERVERS` / `..._DISABLED_...`) are added to `config._PROJECT_DOTENV_DENIED_ENV_KEYS`, so a committed *project* `.env` cannot inject them into `os.environ` even though it is loaded at bootstrap. Enabled resolves env-over-TOML, but disabled *unions* TOML and env so a deny can never be silently emptied by the other source. If the user's `config.toml` exists but cannot be read or parsed, the loader fails closed (project configs are treated as untrusted and the error is surfaced) rather than proceeding with an empty deny list. Only allowlisted (or fully trusted) names survive into the merged config, so a non-allowlisted remote entry is never preflighted and its interpolated headers are never resolved. Note that the allow list binds by server *name*, not by fingerprint: an allowlisted name is loaded whatever definition the repo currently gives it, bypassing the fingerprint change-detection that re-prompts on full-config trust — so users should only allowlist names in repos they would otherwise trust.
236
236
  - **Outside**: Stdio server `command`, `args`, and `env` fields are user-controlled strings passed directly to `StdioConnection`. The `env` dict from MCP config is forwarded without filtering — users can set arbitrary environment variables (including `PATH`, `LD_PRELOAD`, `PYTHONPATH`) for the MCP subprocess.
237
237
  - **Crossing mechanism**: `subprocess.Popen` (via `langchain_mcp_adapters`) for stdio; HTTP/SSE for remote servers.
238
238
 
@@ -1,3 +1,3 @@
1
1
  """Generated at build time. Do not edit or commit."""
2
2
 
3
- BUILD_COMMIT = "9d4d7ba"
3
+ BUILD_COMMIT = "0199007"
@@ -93,6 +93,42 @@ real PyPI release.
93
93
  Any non-empty value enables the flag (including `"0"` or `"false"`).
94
94
  """
95
95
 
96
+ DISABLED_PROJECT_MCP_SERVERS = "DEEPAGENTS_CODE_DISABLED_PROJECT_MCP_SERVERS"
97
+ """Comma-separated project MCP server names to always reject by name.
98
+
99
+ A user-level equivalent of `[mcp].disabled_project_servers`.
100
+
101
+ Rejection wins over approval: a name listed here is dropped even when it also
102
+ appears in `ENABLED_PROJECT_MCP_SERVERS` (or `[mcp].enabled_project_servers`)
103
+ and even when the project config is otherwise trusted. Unlike the enabled list,
104
+ this env var *unions* with (rather than replaces)
105
+ `[mcp].disabled_project_servers` — denies accumulate across sources, so neither
106
+ can silently empty a deny set in the other. This is process env the user
107
+ controls, not a repo file, so it does not weaken the user-level-only
108
+ trust boundary: a committed *project* `.env` is blocked from setting it
109
+ (see `config._PROJECT_DOTENV_DENIED_ENV_KEYS`); only the user's shell,
110
+ launch env, or global `~/.deepagents/.env` can.
111
+ """
112
+
113
+ ENABLED_PROJECT_MCP_SERVERS = "DEEPAGENTS_CODE_ENABLED_PROJECT_MCP_SERVERS"
114
+ """Comma-separated project MCP server names to pre-approve by name.
115
+
116
+ A user-level equivalent of `[mcp].enabled_project_servers`.
117
+
118
+ Servers named here load from an otherwise-untrusted project `.mcp.json` without
119
+ prompting (they are omitted from the interactive approval prompt), while
120
+ non-listed servers stay dropped. Like `DISABLED_PROJECT_MCP_SERVERS`, this is
121
+ user-controlled process env, not a repo file, so it does not weaken
122
+ the user-level-only trust boundary (a committed *project* `.env` cannot set it;
123
+ see `config._PROJECT_DOTENV_DENIED_ENV_KEYS`). This contract is name-based:
124
+ a project command or URL change under the same server name still matches.
125
+
126
+ When set, this replaces (takes precedence over) the
127
+ `[mcp].enabled_project_servers` TOML list.
128
+ (`DISABLED_PROJECT_MCP_SERVERS` instead *unions* with its TOML list, so a deny
129
+ is never silently emptied.)
130
+ """
131
+
96
132
  EXTERNAL_EVENT_SOCKET = "DEEPAGENTS_CODE_EXTERNAL_EVENT_SOCKET"
97
133
  """Enable the local Unix-socket external event listener.
98
134
 
@@ -0,0 +1,66 @@
1
+ """Fake chat model base shared by integration tests and tool enumeration.
2
+
3
+ Holds the tool-binding base that both the local integration-test fakes
4
+ (`_testing_models`) and the `dcode tools list` tool-enumeration path
5
+ (`tool_catalog._CatalogModel`) build on. It lives in a use-neutral module — not
6
+ under a `_testing_`-prefixed name — so a production import path never depends on
7
+ something that reads as test-only and might be pruned or excluded from the wheel.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from typing import TYPE_CHECKING, Any
13
+
14
+ from langchain_core.language_models.fake_chat_models import GenericFakeChatModel
15
+ from pydantic import Field
16
+
17
+ if TYPE_CHECKING:
18
+ from collections.abc import Callable, Sequence
19
+
20
+ from langchain_core.language_models import LanguageModelInput
21
+ from langchain_core.messages import AIMessage
22
+ from langchain_core.runnables import Runnable
23
+ from langchain_core.tools import BaseTool
24
+
25
+
26
+ _TOOL_BINDING_MODEL_PROFILE: dict[str, Any] = {
27
+ "tool_calling": True,
28
+ "max_input_tokens": 8000,
29
+ }
30
+ """Minimal capability profile the agent runtime reads while compiling a model.
31
+
32
+ Only `tool_calling` is load-bearing — the agent negotiates tool support at
33
+ setup. `max_input_tokens` is part of the profile surface but inert here: these
34
+ models are compiled to bind tools and are never invoked, so no token budget ever
35
+ applies. Defined once so both the integration-test fakes and
36
+ `tool_catalog._CatalogModel` share a single source of truth.
37
+ """
38
+
39
+
40
+ class _ToolBindingFakeModel(GenericFakeChatModel):
41
+ """Base for fake chat models that must bind tools but are never invoked.
42
+
43
+ The agent runtime calls `model.bind_tools(schemas)` and reads `model.profile`
44
+ while compiling the graph, and a bare `GenericFakeChatModel` cannot be
45
+ compiled into an agent graph: it inherits `BaseChatModel.bind_tools`, which
46
+ raises `NotImplementedError`, and its `profile` is `None`, which breaks
47
+ capability negotiation. This base supplies a no-op `bind_tools` passthrough
48
+ and a minimal `profile`, leaving subclasses to add generation behavior
49
+ (tests) or nothing at all (tool enumeration).
50
+ """
51
+
52
+ # Required by `GenericFakeChatModel`, but subclasses never consume it.
53
+ messages: object = Field(default_factory=lambda: iter(()))
54
+ profile: dict[str, Any] | None = Field(
55
+ default_factory=lambda: dict(_TOOL_BINDING_MODEL_PROFILE)
56
+ )
57
+
58
+ def bind_tools(
59
+ self,
60
+ tools: Sequence[dict[str, Any] | type | Callable | BaseTool], # noqa: ARG002
61
+ *,
62
+ tool_choice: str | None = None, # noqa: ARG002
63
+ **kwargs: Any, # noqa: ARG002
64
+ ) -> Runnable[LanguageModelInput, AIMessage]:
65
+ """Return self so the agent can bind tool schemas without a real model."""
66
+ return self
@@ -1,21 +1,23 @@
1
- """Internal chat models used by local integration tests."""
1
+ """Internal fake chat models for local integration tests.
2
+
3
+ The tool-binding base these build on (`_fake_models._ToolBindingFakeModel`) is
4
+ factored out into a use-neutral module so the `dcode tools list` enumeration
5
+ path can reuse it without importing this test-named module.
6
+ """
2
7
 
3
8
  from __future__ import annotations
4
9
 
5
10
  from typing import TYPE_CHECKING, Any
6
11
 
7
- from langchain_core.language_models.fake_chat_models import GenericFakeChatModel
8
12
  from langchain_core.messages import AIMessage, BaseMessage
9
13
  from langchain_core.outputs import ChatGeneration, ChatResult
10
- from pydantic import Field
14
+
15
+ from deepagents_code._fake_models import _ToolBindingFakeModel
11
16
 
12
17
  if TYPE_CHECKING:
13
- from collections.abc import Callable, Sequence
18
+ from collections.abc import Callable
14
19
 
15
20
  from langchain_core.callbacks import CallbackManagerForLLMRun
16
- from langchain_core.language_models import LanguageModelInput
17
- from langchain_core.runnables import Runnable
18
- from langchain_core.tools import BaseTool
19
21
 
20
22
 
21
23
  # Prompt markers that drive `ToolCallingIntegrationChatModel`. Each marker is the
@@ -33,13 +35,13 @@ TOP_LEVEL_WRITE_CONTENT = "auto-approved"
33
35
  SUBAGENT_WRITE_CONTENT = "auto-approved-subagent"
34
36
 
35
37
 
36
- class DeterministicIntegrationChatModel(GenericFakeChatModel):
38
+ class DeterministicIntegrationChatModel(_ToolBindingFakeModel):
37
39
  """Deterministic chat model for integration tests.
38
40
 
39
- This subclasses LangChain's `GenericFakeChatModel` so the implementation
40
- stays aligned with the core fake-chat-model test surface, while overriding
41
- generation to remain prompt-driven and restart-safe for real CLI server
42
- integration tests.
41
+ This subclasses `_ToolBindingFakeModel` (itself a `GenericFakeChatModel`) so
42
+ the implementation stays aligned with the core fake-chat-model test surface,
43
+ while overriding generation to remain prompt-driven and restart-safe for real
44
+ CLI server integration tests.
43
45
 
44
46
  Why the existing `langchain_core` fakes cannot be reused here:
45
47
 
@@ -53,13 +55,15 @@ class DeterministicIntegrationChatModel(GenericFakeChatModel):
53
55
  identical output regardless of process lifecycle.
54
56
 
55
57
  2. The agent runtime calls `model.bind_tools(schemas)` during
56
- initialization. None of the core fakes implement `bind_tools`, so they
57
- raise `AttributeError` in any agent-loop context. This model provides a
58
+ initialization. A bare `GenericFakeChatModel` inherits
59
+ `BaseChatModel.bind_tools`, which raises `NotImplementedError` in any
60
+ agent-loop context. The inherited `_ToolBindingFakeModel` supplies a
58
61
  no-op passthrough.
59
62
 
60
63
  3. The app server reads `model.profile` for capability negotiation (e.g.
61
- `tool_calling`, `max_input_tokens`). Core fakes have no such attribute,
62
- causing `AttributeError` or silent misconfiguration at runtime.
64
+ `tool_calling`, `max_input_tokens`). A bare fake's `profile` is `None`,
65
+ causing silent misconfiguration at runtime. The inherited
66
+ `_ToolBindingFakeModel` supplies a minimal profile.
63
67
 
64
68
  Additionally, the compact middleware issues summarization prompts mid-
65
69
  conversation. A list-based model cannot distinguish these from normal user
@@ -68,24 +72,8 @@ class DeterministicIntegrationChatModel(GenericFakeChatModel):
68
72
  """
69
73
 
70
74
  model: str = "fake"
71
- # Required by `GenericFakeChatModel`, but our override does not consume it.
72
- messages: object = Field(default_factory=lambda: iter(()))
73
- profile: dict[str, Any] | None = Field(
74
- default_factory=lambda: {
75
- "tool_calling": True,
76
- "max_input_tokens": 8000,
77
- }
78
- )
79
-
80
- def bind_tools(
81
- self,
82
- tools: Sequence[dict[str, Any] | type | Callable | BaseTool], # noqa: ARG002
83
- *,
84
- tool_choice: str | None = None, # noqa: ARG002
85
- **kwargs: Any, # noqa: ARG002
86
- ) -> Runnable[LanguageModelInput, AIMessage]:
87
- """Return self so the agent can bind tool schemas during tests."""
88
- return self
75
+ # `messages`, `profile`, and the `bind_tools` passthrough are inherited from
76
+ # `_ToolBindingFakeModel`; this model adds only prompt-driven generation.
89
77
 
90
78
  def _generate(
91
79
  self,
@@ -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.32" # x-release-please-version
5
+ __version__ = "0.1.33" # 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."""
@@ -1702,6 +1702,9 @@ def create_cli_agent(
1702
1702
  )
1703
1703
  raise ValueError(msg)
1704
1704
  # Lazy import keeps `dcode -v` fast — see AGENTS.md startup-perf rule.
1705
+ from langchain_core._api import ( # noqa: PLC2701 # re-exported in _api.__all__
1706
+ suppress_langchain_beta_warning,
1707
+ )
1705
1708
  from langchain_quickjs import CodeInterpreterMiddleware, PTCOption
1706
1709
 
1707
1710
  ptc_names = _resolve_ptc_option(
@@ -1713,16 +1716,20 @@ def create_cli_agent(
1713
1716
  ptc_option: PTCOption | None = (
1714
1717
  cast("PTCOption", list(ptc_names)) if ptc_names is not None else None
1715
1718
  )
1716
- agent_middleware.append(
1717
- CodeInterpreterMiddleware(
1718
- tool_name="js_eval",
1719
- timeout=settings.interpreter_timeout_seconds,
1720
- memory_limit=settings.interpreter_memory_limit_mb * 1024 * 1024,
1721
- max_ptc_calls=settings.interpreter_max_ptc_calls,
1722
- max_result_chars=settings.interpreter_max_result_chars,
1723
- ptc=ptc_option,
1719
+ # `CodeInterpreterMiddleware` is decorated `@beta()`, which emits a
1720
+ # `LangChainBetaWarning` on every instantiation. We intentionally use it
1721
+ # and the warning is not actionable for users, so suppress it.
1722
+ with suppress_langchain_beta_warning():
1723
+ agent_middleware.append(
1724
+ CodeInterpreterMiddleware(
1725
+ tool_name="js_eval",
1726
+ timeout=settings.interpreter_timeout_seconds,
1727
+ memory_limit=settings.interpreter_memory_limit_mb * 1024 * 1024,
1728
+ max_ptc_calls=settings.interpreter_max_ptc_calls,
1729
+ max_result_chars=settings.interpreter_max_result_chars,
1730
+ ptc=ptc_option,
1731
+ )
1724
1732
  )
1725
- )
1726
1733
 
1727
1734
  # Local context middleware (git info, directory tree, etc.).
1728
1735
  if isinstance(backend, (_ExecutableBackend, _AsyncExecutableBackend)):
@@ -279,6 +279,11 @@ def _create_model_with_deepagents_import_lock(
279
279
  )
280
280
 
281
281
 
282
+ def _resolve_parent_dir(path: str | Path) -> str:
283
+ """Return the resolved parent directory for a path."""
284
+ return str(Path(path).resolve().parent)
285
+
286
+
282
287
  def _extra_is_ready(extra: str) -> bool | None:
283
288
  """Return whether all dependencies for `extra` are installed.
284
289
 
@@ -2786,6 +2791,13 @@ class DeepAgentsApp(App):
2786
2791
  Built alongside `_discovered_skills`.
2787
2792
  """
2788
2793
 
2794
+ self._skill_trust_denied: set[str] = set()
2795
+ """Resolved skill directories the user declined to trust this session.
2796
+
2797
+ Prevents re-prompting for the same untrusted location after a deny
2798
+ within a single run.
2799
+ """
2800
+
2789
2801
  # Media
2790
2802
  # Lazily imported here to avoid pulling image dependencies into
2791
2803
  # argument parsing paths.
@@ -9630,6 +9642,28 @@ class DeepAgentsApp(App):
9630
9642
  theme_reload_ok = False
9631
9643
  logger.warning("Failed to reload user themes", exc_info=True)
9632
9644
 
9645
+ # Re-resolve and apply the theme preference so a per-terminal or
9646
+ # global default saved by another session is picked up. This
9647
+ # re-syncs to on-disk config using the same resolution as startup
9648
+ # (env -> [ui.terminal_themes][TERM_PROGRAM] -> [ui].theme ->
9649
+ # default), which intentionally overrides an unsaved in-session
9650
+ # `/theme` choice. Guarded on the registry reload succeeding since
9651
+ # the target theme must be registered before it can be applied.
9652
+ theme_switched_to: str | None = None
9653
+ if theme_reload_ok:
9654
+ try:
9655
+ new_theme = _load_theme_preference()
9656
+ if new_theme != self.theme and new_theme in theme.get_registry():
9657
+ self.theme = new_theme
9658
+ self.sync_terminal_background()
9659
+ self.refresh_css(animate=False)
9660
+ theme_switched_to = new_theme
9661
+ except Exception:
9662
+ logger.warning(
9663
+ "Failed to re-apply theme preference on reload",
9664
+ exc_info=True,
9665
+ )
9666
+
9633
9667
  # Re-discover skills so autocomplete reflects any new/removed
9634
9668
  # skills. Run via the same exclusive-group worker used at
9635
9669
  # startup so any in-flight startup discovery is cancelled
@@ -9655,6 +9689,10 @@ class DeepAgentsApp(App):
9655
9689
  report += "\nModel config caches cleared."
9656
9690
  if theme_reload_ok:
9657
9691
  report += "\nTheme registry reloaded."
9692
+ if theme_switched_to is not None:
9693
+ entry = theme.get_registry().get(theme_switched_to)
9694
+ label = entry.label if entry is not None else theme_switched_to
9695
+ report += f"\nSwitched theme to {label}."
9658
9696
  else:
9659
9697
  report += (
9660
9698
  "\nTheme registry reload failed. Check config.toml for errors."
@@ -9791,8 +9829,15 @@ class DeepAgentsApp(App):
9791
9829
  normalized_name,
9792
9830
  exc_info=True,
9793
9831
  )
9794
- await _mount_error(str(exc))
9795
- return
9832
+ content = await self._prompt_skill_trust_and_retry(
9833
+ normalized_name,
9834
+ skill_path,
9835
+ allowed_roots,
9836
+ fallback_error=str(exc),
9837
+ mount_error=_mount_error,
9838
+ )
9839
+ if content is None:
9840
+ return
9796
9841
  except OSError as exc:
9797
9842
  logger.warning(
9798
9843
  "Filesystem error loading skill %r",
@@ -9842,6 +9887,139 @@ class DeepAgentsApp(App):
9842
9887
  message_kwargs=envelope.message_kwargs,
9843
9888
  )
9844
9889
 
9890
+ async def _prompt_skill_trust_and_retry(
9891
+ self,
9892
+ skill_name: str,
9893
+ skill_path: str | Path,
9894
+ allowed_roots: list[Path],
9895
+ *,
9896
+ fallback_error: str,
9897
+ mount_error: Callable[[str], Awaitable[None]],
9898
+ ) -> str | None:
9899
+ """Prompt to trust an out-of-bounds skill directory, then reload it.
9900
+
9901
+ Mirrors the MCP project-trust flow: when containment fails, the user is
9902
+ asked once to allow the resolved target directory. Allowing persists the
9903
+ decision, extends the in-session containment allowlist, and retries the
9904
+ read. Denying (or a prior deny this session) shows the original error.
9905
+
9906
+ Args:
9907
+ skill_name: Normalized skill name, for messaging.
9908
+ skill_path: Path to the skill's `SKILL.md`.
9909
+ allowed_roots: Containment roots to extend on approval.
9910
+ fallback_error: Original `PermissionError` message to show on deny.
9911
+ mount_error: Callback to surface an error in the chat log.
9912
+
9913
+ Returns:
9914
+ The skill content on approval and successful reload, or `None` when
9915
+ the user declined or the retry failed (an error was mounted).
9916
+ """
9917
+ from deepagents_code.skills.load import load_skill_content
9918
+ from deepagents_code.skills.trust import trust_skill_dir
9919
+ from deepagents_code.widgets.skill_trust import SkillTrustScreen
9920
+
9921
+ try:
9922
+ target_dir = await asyncio.to_thread(_resolve_parent_dir, skill_path)
9923
+ except (OSError, RuntimeError):
9924
+ # Resolving the skill path can fail (e.g. a symlink loop introduced
9925
+ # in the window after the first containment check raised). Fail
9926
+ # closed with the original error rather than letting the worker
9927
+ # exception escape unhandled — this mirrors the retry block below,
9928
+ # which already guards its own resolve.
9929
+ logger.warning(
9930
+ "Could not resolve skill path %r for the trust prompt; refusing",
9931
+ skill_path,
9932
+ exc_info=True,
9933
+ )
9934
+ await mount_error(fallback_error)
9935
+ return None
9936
+
9937
+ if target_dir in self._skill_trust_denied:
9938
+ await mount_error(fallback_error)
9939
+ return None
9940
+
9941
+ try:
9942
+ allowed = await self._push_screen_wait(
9943
+ SkillTrustScreen(skill_name, target_dir)
9944
+ )
9945
+ except Exception:
9946
+ # This runs inside `_invoke_skill`'s `except PermissionError` block,
9947
+ # so an error escaping the modal push would not be caught by that
9948
+ # method's sibling handlers and would surface as an unhandled worker
9949
+ # crash. Fail closed: treat a modal failure as a deny.
9950
+ logger.warning(
9951
+ "Skill trust prompt failed to display for %s; refusing",
9952
+ target_dir,
9953
+ exc_info=True,
9954
+ )
9955
+ self._skill_trust_denied.add(target_dir)
9956
+ await mount_error(fallback_error)
9957
+ return None
9958
+ if not allowed:
9959
+ self._skill_trust_denied.add(target_dir)
9960
+ await mount_error(fallback_error)
9961
+ return None
9962
+
9963
+ if not await asyncio.to_thread(trust_skill_dir, target_dir):
9964
+ # The modal told the user this location would be remembered for
9965
+ # future sessions. Persisting failed (read-only/full `.state`), so
9966
+ # surface that: we honor the approval this session, but they will be
9967
+ # asked again next launch. Logging alone would silently break that
9968
+ # promise.
9969
+ logger.warning("Could not persist skill trust for %s", target_dir)
9970
+ self.notify(
9971
+ "Approved for this session, but the decision could not be "
9972
+ "saved — you may be asked again next time.",
9973
+ severity="warning",
9974
+ markup=False,
9975
+ )
9976
+
9977
+ target_path = Path(target_dir)
9978
+ for roots in (allowed_roots, self._skill_allowed_roots):
9979
+ if target_path not in roots:
9980
+ roots.append(target_path)
9981
+
9982
+ def _retry() -> str | None:
9983
+ return load_skill_content(str(skill_path), allowed_roots=allowed_roots)
9984
+
9985
+ try:
9986
+ content = await asyncio.to_thread(_retry)
9987
+ except PermissionError:
9988
+ # Containment failed *after* the target dir was allowlisted, so the
9989
+ # skill path must now resolve somewhere else — a symlink swap during
9990
+ # the prompt window. Refuse and flag it distinctly from a plain read
9991
+ # error. (PermissionError is an OSError subclass, so this must come
9992
+ # first.)
9993
+ logger.warning(
9994
+ "Skill %r resolved outside the approved directory on retry "
9995
+ "(target may have changed since approval); refusing",
9996
+ skill_name,
9997
+ exc_info=True,
9998
+ )
9999
+ await mount_error(
10000
+ f"Could not load skill: {skill_name}. Its location changed "
10001
+ "after you approved it, so it was not read.",
10002
+ )
10003
+ return None
10004
+ except OSError:
10005
+ logger.warning(
10006
+ "Retry load failed for skill %r after trust",
10007
+ skill_name,
10008
+ exc_info=True,
10009
+ )
10010
+ await mount_error(
10011
+ f"Could not load skill: {skill_name} after granting trust.",
10012
+ )
10013
+ return None
10014
+
10015
+ if content is None:
10016
+ await mount_error(
10017
+ f"Could not read content for skill: {skill_name}. "
10018
+ "Check that the SKILL.md file exists, is readable, "
10019
+ "and is saved as UTF-8.",
10020
+ )
10021
+ return content
10022
+
9845
10023
  async def _handle_skill_command(self, command: str) -> None:
9846
10024
  """Handle a `/skill:<name>` command by loading and invoking a skill.
9847
10025