deepagents-code 0.1.3__tar.gz → 0.1.4__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 (250) hide show
  1. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/CHANGELOG.md +16 -0
  2. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/PKG-INFO +5 -3
  3. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_server_config.py +55 -0
  4. deepagents_code-0.1.4/deepagents_code/_startup_error.py +45 -0
  5. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_version.py +1 -1
  6. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/agent.py +175 -1
  7. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/app.py +76 -5
  8. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/config.py +325 -15
  9. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/extras_info.py +39 -0
  10. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/integrations/sandbox_factory.py +28 -5
  11. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/main.py +126 -8
  12. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_commands.py +74 -2
  13. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_login_service.py +4 -4
  14. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/non_interactive.py +16 -0
  15. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/server_graph.py +21 -8
  16. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/server_manager.py +30 -0
  17. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/sessions.py +104 -7
  18. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/textual_adapter.py +16 -9
  19. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/tool_display.py +8 -0
  20. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/ui.py +37 -6
  21. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/chat_input.py +80 -59
  22. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/mcp_login.py +0 -1
  23. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/messages.py +7 -0
  24. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/pyproject.toml +14 -2
  25. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/scripts/install.sh +30 -19
  26. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_agent.py +351 -0
  27. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_app.py +187 -19
  28. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_args.py +194 -11
  29. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_chat_input.py +221 -77
  30. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_config.py +68 -0
  31. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_extras_info.py +36 -8
  32. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_mcp_commands.py +1 -1
  33. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_mcp_login_service.py +2 -2
  34. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_non_interactive.py +45 -0
  35. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_sandbox_factory.py +80 -0
  36. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_server_config.py +27 -0
  37. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_server_graph.py +58 -0
  38. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_server_manager.py +1 -0
  39. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_sessions.py +254 -8
  40. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_textual_adapter.py +27 -3
  41. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/uv.lock +79 -9
  42. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/.gitignore +0 -0
  43. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/AGENTS.md +0 -0
  44. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/COMMANDS.md +0 -0
  45. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/DEV.md +0 -0
  46. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/Makefile +0 -0
  47. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/README.md +0 -0
  48. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/THREAT_MODEL.md +0 -0
  49. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/__init__.py +0 -0
  50. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/__main__.py +0 -0
  51. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_ask_user_types.py +0 -0
  52. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_cli_context.py +0 -0
  53. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_constants.py +0 -0
  54. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_debug.py +0 -0
  55. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_env_vars.py +0 -0
  56. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_git.py +0 -0
  57. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_session_stats.py +0 -0
  58. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_testing_models.py +0 -0
  59. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/_textual_patches.py +0 -0
  60. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/app.tcss +0 -0
  61. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/ask_user.py +0 -0
  62. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/auth_store.py +0 -0
  63. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/built_in_skills/__init__.py +0 -0
  64. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/built_in_skills/remember/SKILL.md +0 -0
  65. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/built_in_skills/skill-creator/SKILL.md +0 -0
  66. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
  67. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
  68. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/clipboard.py +0 -0
  69. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/command_registry.py +0 -0
  70. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/configurable_model.py +0 -0
  71. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/default_agent_prompt.md +0 -0
  72. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/editor.py +0 -0
  73. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/event_bus.py +0 -0
  74. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/file_ops.py +0 -0
  75. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/formatting.py +0 -0
  76. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/hooks.py +0 -0
  77. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/input.py +0 -0
  78. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/integrations/__init__.py +0 -0
  79. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/integrations/sandbox_provider.py +0 -0
  80. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/iterm_cursor_guide.py +0 -0
  81. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/local_context.py +0 -0
  82. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_auth.py +0 -0
  83. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_disabled.py +0 -0
  84. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_oauth_ui.py +0 -0
  85. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_providers/__init__.py +0 -0
  86. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_providers/_registry.py +0 -0
  87. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_providers/base.py +0 -0
  88. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_providers/github.py +0 -0
  89. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_providers/slack.py +0 -0
  90. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_tools.py +0 -0
  91. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/mcp_trust.py +0 -0
  92. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/media_utils.py +0 -0
  93. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/model_config.py +0 -0
  94. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/notifications.py +0 -0
  95. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/offload.py +0 -0
  96. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/onboarding.py +0 -0
  97. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/output.py +0 -0
  98. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/project_utils.py +0 -0
  99. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/py.typed +0 -0
  100. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/remote_client.py +0 -0
  101. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/server.py +0 -0
  102. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/skills/__init__.py +0 -0
  103. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/skills/commands.py +0 -0
  104. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/skills/invocation.py +0 -0
  105. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/skills/load.py +0 -0
  106. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/state_migration.py +0 -0
  107. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/subagents.py +0 -0
  108. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/system_prompt.md +0 -0
  109. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/terminal_capabilities.py +0 -0
  110. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/terminal_escape.py +0 -0
  111. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/theme.py +0 -0
  112. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/token_state.py +0 -0
  113. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/tools.py +0 -0
  114. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/unicode_security.py +0 -0
  115. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/update_check.py +0 -0
  116. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/__init__.py +0 -0
  117. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/_links.py +0 -0
  118. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/agent_selector.py +0 -0
  119. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/approval.py +0 -0
  120. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/ask_user.py +0 -0
  121. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/auth.py +0 -0
  122. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/autocomplete.py +0 -0
  123. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/diff.py +0 -0
  124. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/history.py +0 -0
  125. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/launch_init.py +0 -0
  126. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/loading.py +0 -0
  127. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/mcp_reconnect.py +0 -0
  128. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/mcp_viewer.py +0 -0
  129. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/message_store.py +0 -0
  130. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/model_selector.py +0 -0
  131. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/notification_center.py +0 -0
  132. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/notification_detail.py +0 -0
  133. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/notification_settings.py +0 -0
  134. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/status.py +0 -0
  135. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/theme_selector.py +0 -0
  136. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/thread_selector.py +0 -0
  137. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/tool_renderers.py +0 -0
  138. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/tool_widgets.py +0 -0
  139. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/update_available.py +0 -0
  140. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/update_progress.py +0 -0
  141. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/deepagents_code/widgets/welcome.py +0 -0
  142. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/examples/skills/arxiv-search/SKILL.md +0 -0
  143. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/examples/skills/arxiv-search/arxiv_search.py +0 -0
  144. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/examples/skills/langgraph-docs/SKILL.md +0 -0
  145. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/examples/skills/skill-creator/SKILL.md +0 -0
  146. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
  147. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
  148. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/examples/skills/web-research/SKILL.md +0 -0
  149. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/images/tui.png +0 -0
  150. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/scripts/check_imports.py +0 -0
  151. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/scripts/debug_server.sh +0 -0
  152. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/scripts/generate_commands_catalog.py +0 -0
  153. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/README.md +0 -0
  154. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/integration_tests/__init__.py +0 -0
  155. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/integration_tests/benchmarks/__init__.py +0 -0
  156. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
  157. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
  158. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/integration_tests/conftest.py +0 -0
  159. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/integration_tests/test_acp_mode.py +0 -0
  160. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/integration_tests/test_compact_resume.py +0 -0
  161. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/integration_tests/test_sandbox_factory.py +0 -0
  162. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/integration_tests/test_sandbox_operations.py +0 -0
  163. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/__init__.py +0 -0
  164. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/conftest.py +0 -0
  165. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/skills/__init__.py +0 -0
  166. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/skills/test_commands.py +0 -0
  167. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/skills/test_load.py +0 -0
  168. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/skills/test_skills_json.py +0 -0
  169. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_agent_friendly.py +0 -0
  170. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_agent_selector.py +0 -0
  171. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_approval.py +0 -0
  172. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_ask_user.py +0 -0
  173. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_ask_user_middleware.py +0 -0
  174. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_auth_store.py +0 -0
  175. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_auth_widgets.py +0 -0
  176. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_autocomplete.py +0 -0
  177. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_charset.py +0 -0
  178. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_clipboard.py +0 -0
  179. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_command_registry.py +0 -0
  180. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_compact_tool.py +0 -0
  181. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_configurable_model.py +0 -0
  182. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_debug.py +0 -0
  183. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_editor.py +0 -0
  184. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_end_to_end.py +0 -0
  185. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_env_vars.py +0 -0
  186. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_event_bus.py +0 -0
  187. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_exception_handling.py +0 -0
  188. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_file_ops.py +0 -0
  189. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_formatting.py +0 -0
  190. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_git.py +0 -0
  191. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_history.py +0 -0
  192. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_hooks.py +0 -0
  193. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_imports.py +0 -0
  194. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_input_parsing.py +0 -0
  195. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
  196. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_launch_init.py +0 -0
  197. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_links.py +0 -0
  198. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_loading.py +0 -0
  199. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_local_context.py +0 -0
  200. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_main.py +0 -0
  201. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_main_acp_mode.py +0 -0
  202. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_main_args.py +0 -0
  203. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_mcp_auth.py +0 -0
  204. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_mcp_disabled.py +0 -0
  205. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_mcp_login_modal.py +0 -0
  206. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_mcp_oauth_ui.py +0 -0
  207. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_mcp_reconnect.py +0 -0
  208. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_mcp_tools.py +0 -0
  209. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_mcp_trust.py +0 -0
  210. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_mcp_viewer.py +0 -0
  211. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_media_utils.py +0 -0
  212. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_message_store.py +0 -0
  213. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_messages.py +0 -0
  214. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_model_config.py +0 -0
  215. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_model_selector.py +0 -0
  216. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_model_switch.py +0 -0
  217. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_notification_center.py +0 -0
  218. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_notification_detail.py +0 -0
  219. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_notifications.py +0 -0
  220. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_offload.py +0 -0
  221. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_offload_dict_messages.py +0 -0
  222. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_onboarding.py +0 -0
  223. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_output.py +0 -0
  224. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_reload.py +0 -0
  225. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_remote_client.py +0 -0
  226. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_server.py +0 -0
  227. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_server_helpers.py +0 -0
  228. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_session_stats.py +0 -0
  229. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_shell_allow_list.py +0 -0
  230. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_skill_invocation.py +0 -0
  231. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_startup_fast_paths.py +0 -0
  232. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_state_migration.py +0 -0
  233. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_status.py +0 -0
  234. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_subagents.py +0 -0
  235. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_terminal_capabilities.py +0 -0
  236. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_terminal_escape.py +0 -0
  237. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_textual_patches.py +0 -0
  238. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_theme.py +0 -0
  239. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_thread_selector.py +0 -0
  240. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_token_tracker.py +0 -0
  241. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_tool_display.py +0 -0
  242. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_ui.py +0 -0
  243. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_unicode_security.py +0 -0
  244. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_update_available.py +0 -0
  245. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_update_check.py +0 -0
  246. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_update_progress.py +0 -0
  247. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_version.py +0 -0
  248. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/test_welcome.py +0 -0
  249. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/tools/__init__.py +0 -0
  250. {deepagents_code-0.1.3 → deepagents_code-0.1.4}/tests/unit_tests/tools/test_fetch_url.py +0 -0
@@ -1,5 +1,21 @@
1
1
  # Deep Agents Code Changelog
2
2
 
3
+ ## [0.1.4](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.3...deepagents-code==0.1.4) (2026-05-23)
4
+
5
+ ### Features
6
+
7
+ * Add `--sandbox-snapshot-name` flag ([#3538](https://github.com/langchain-ai/deepagents/issues/3538)) ([b01392e](https://github.com/langchain-ai/deepagents/commit/b01392e7549798434f27f3784fa8c4e734053787))
8
+ * `dcode mcp config` and unify `--mcp-config` flag ([#3541](https://github.com/langchain-ai/deepagents/issues/3541)) ([f037b14](https://github.com/langchain-ai/deepagents/commit/f037b140f90a1ba3725b3ef23ab385b3cafe223b))
9
+ * Interpreter middleware via `langchain-quickjs` ([#3525](https://github.com/langchain-ai/deepagents/issues/3525)) ([f0ca89c](https://github.com/langchain-ai/deepagents/commit/f0ca89c962c22058194121526638bc2d29f546bd))
10
+
11
+ ### Bug Fixes
12
+
13
+ * Chat input history navigation and newline scrolling ([#3560](https://github.com/langchain-ai/deepagents/issues/3560)) ([3b51cbd](https://github.com/langchain-ai/deepagents/commit/3b51cbdc8c50d9990477e18a47de6a58e9165bab))
14
+ * Distinguish LangSmith failure modes in `/trace` ([#3558](https://github.com/langchain-ai/deepagents/issues/3558)) ([4d158a0](https://github.com/langchain-ai/deepagents/commit/4d158a031aecad8862e02e332f127573003938ec))
15
+ * Recover initial session prompts from writes table ([#3535](https://github.com/langchain-ai/deepagents/issues/3535)) ([46b6f3f](https://github.com/langchain-ai/deepagents/commit/46b6f3f3e6ce880cd5ec9cf59622bb745d6ac2eb))
16
+ * Install script binary checks reference `dcode` ([#3546](https://github.com/langchain-ai/deepagents/issues/3546)) ([f8977a6](https://github.com/langchain-ai/deepagents/commit/f8977a63769e3f2037619f32596cb9bb7bd1020b))
17
+ * Show tool call previews during batched HITL approvals ([#3530](https://github.com/langchain-ai/deepagents/issues/3530)) ([84daa1a](https://github.com/langchain-ai/deepagents/commit/84daa1a2e27963a6d7694dc9278de83782b4a7b7))
18
+
3
19
  ## [0.1.3](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.2...deepagents-code==0.1.3) (2026-05-20)
4
20
 
5
21
  ### Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepagents-code
3
- Version: 0.1.3
3
+ Version: 0.1.4
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/
@@ -69,7 +69,7 @@ Requires-Dist: langchain-google-vertexai<4.0.0,>=3.2.3; extra == 'all-providers'
69
69
  Requires-Dist: langchain-groq<2.0.0,>=1.1.2; extra == 'all-providers'
70
70
  Requires-Dist: langchain-huggingface<2.0.0,>=1.2.2; extra == 'all-providers'
71
71
  Requires-Dist: langchain-ibm<2.0.0,>=1.0.7; extra == 'all-providers'
72
- Requires-Dist: langchain-litellm<2.0.0,>=0.6.4; extra == 'all-providers'
72
+ Requires-Dist: langchain-litellm<2.0.0,>=0.6.6; extra == 'all-providers'
73
73
  Requires-Dist: langchain-mistralai<2.0.0,>=1.1.4; extra == 'all-providers'
74
74
  Requires-Dist: langchain-nvidia-ai-endpoints<2.0.0,>=1.2.1; extra == 'all-providers'
75
75
  Requires-Dist: langchain-ollama<2.0.0,>=1.1.0; extra == 'all-providers'
@@ -106,7 +106,7 @@ Requires-Dist: langchain-huggingface<2.0.0,>=1.2.2; extra == 'huggingface'
106
106
  Provides-Extra: ibm
107
107
  Requires-Dist: langchain-ibm<2.0.0,>=1.0.7; extra == 'ibm'
108
108
  Provides-Extra: litellm
109
- Requires-Dist: langchain-litellm<2.0.0,>=0.6.4; extra == 'litellm'
109
+ Requires-Dist: langchain-litellm<2.0.0,>=0.6.6; extra == 'litellm'
110
110
  Provides-Extra: mistralai
111
111
  Requires-Dist: langchain-mistralai<2.0.0,>=1.1.4; extra == 'mistralai'
112
112
  Provides-Extra: modal
@@ -121,6 +121,8 @@ Provides-Extra: openrouter
121
121
  Requires-Dist: langchain-openrouter<2.0.0,>=0.2.3; extra == 'openrouter'
122
122
  Provides-Extra: perplexity
123
123
  Requires-Dist: langchain-perplexity<2.0.0,>=1.2.0; extra == 'perplexity'
124
+ Provides-Extra: quickjs
125
+ Requires-Dist: langchain-quickjs<0.2.0,>=0.1.2; extra == 'quickjs'
124
126
  Provides-Extra: runloop
125
127
  Requires-Dist: langchain-runloop>=0.0.4; extra == 'runloop'
126
128
  Provides-Extra: together
@@ -152,6 +152,26 @@ class ServerConfig:
152
152
  enable_skills: bool = True
153
153
  """Enable the skills subsystem (SKILL.md loading and skill tools)."""
154
154
 
155
+ enable_interpreter: bool = False
156
+ """Enable `CodeInterpreterMiddleware` (`js_eval` REPL) on the main agent.
157
+
158
+ Local-mode only; the server graph raises if a sandbox is configured and
159
+ this flag is `True`.
160
+ """
161
+
162
+ interpreter_ptc: str | list[str] | None = None
163
+ """Override for `settings.interpreter_ptc`.
164
+
165
+ `None` means "fall through to whatever `settings.interpreter_ptc` resolves
166
+ to from `~/.deepagents/config.toml`". A string is one of `"safe"`/`"all"`;
167
+ a list is an explicit allowlist of tool names.
168
+ """
169
+
170
+ interpreter_ptc_acknowledge_unsafe: bool = False
171
+ """Mirror of `settings.interpreter_ptc_acknowledge_unsafe` — required when
172
+ `interpreter_ptc="all"` is paired with non-`auto_approve` mode.
173
+ """
174
+
155
175
  sandbox_type: str | None = None
156
176
  """Sandbox backend identifier (e.g. `'daytona'`); `None` runs tools on the
157
177
  host. `'none'` is normalized to `None` in `__post_init__`."""
@@ -159,6 +179,10 @@ class ServerConfig:
159
179
  sandbox_id: str | None = None
160
180
  """Existing sandbox ID to attach to; `None` creates a fresh sandbox."""
161
181
 
182
+ sandbox_snapshot_name: str | None = None
183
+ """Sandbox snapshot name to use or create. LangSmith-only; must be `None`
184
+ when `sandbox_id` is set."""
185
+
162
186
  sandbox_setup: str | None = None
163
187
  """Absolute path to a setup script executed inside the sandbox on first attach."""
164
188
 
@@ -226,8 +250,18 @@ class ServerConfig:
226
250
  "ENABLE_ASK_USER": str(self.enable_ask_user).lower(),
227
251
  "ENABLE_MEMORY": str(self.enable_memory).lower(),
228
252
  "ENABLE_SKILLS": str(self.enable_skills).lower(),
253
+ "ENABLE_INTERPRETER": str(self.enable_interpreter).lower(),
254
+ "INTERPRETER_PTC": (
255
+ json.dumps(self.interpreter_ptc)
256
+ if self.interpreter_ptc is not None
257
+ else None
258
+ ),
259
+ "INTERPRETER_PTC_ACKNOWLEDGE_UNSAFE": str(
260
+ self.interpreter_ptc_acknowledge_unsafe
261
+ ).lower(),
229
262
  "SANDBOX_TYPE": self.sandbox_type,
230
263
  "SANDBOX_ID": self.sandbox_id,
264
+ "SANDBOX_SNAPSHOT_NAME": self.sandbox_snapshot_name,
231
265
  "SANDBOX_SETUP": self.sandbox_setup,
232
266
  "CWD": self.cwd,
233
267
  "PROJECT_ROOT": self.project_root,
@@ -268,8 +302,14 @@ class ServerConfig:
268
302
  enable_ask_user=_read_env_bool("ENABLE_ASK_USER"),
269
303
  enable_memory=_read_env_bool("ENABLE_MEMORY", default=True),
270
304
  enable_skills=_read_env_bool("ENABLE_SKILLS", default=True),
305
+ enable_interpreter=_read_env_bool("ENABLE_INTERPRETER"),
306
+ interpreter_ptc=_read_env_json("INTERPRETER_PTC"),
307
+ interpreter_ptc_acknowledge_unsafe=_read_env_bool(
308
+ "INTERPRETER_PTC_ACKNOWLEDGE_UNSAFE"
309
+ ),
271
310
  sandbox_type=_read_env_str("SANDBOX_TYPE"),
272
311
  sandbox_id=_read_env_str("SANDBOX_ID"),
312
+ sandbox_snapshot_name=_read_env_str("SANDBOX_SNAPSHOT_NAME") or None,
273
313
  sandbox_setup=_read_env_str("SANDBOX_SETUP"),
274
314
  cwd=_read_env_str("CWD"),
275
315
  project_root=_read_env_str("PROJECT_ROOT"),
@@ -295,9 +335,13 @@ class ServerConfig:
295
335
  shell_allow_list: list[str] | None = None,
296
336
  sandbox_type: str = "none",
297
337
  sandbox_id: str | None,
338
+ sandbox_snapshot_name: str | None,
298
339
  sandbox_setup: str | None,
299
340
  enable_shell: bool,
300
341
  enable_ask_user: bool,
342
+ enable_interpreter: bool = False,
343
+ interpreter_ptc: str | list[str] | None = None,
344
+ interpreter_ptc_acknowledge_unsafe: bool = False,
301
345
  mcp_config_path: str | None,
302
346
  no_mcp: bool,
303
347
  trust_project_mcp: bool | None,
@@ -321,9 +365,16 @@ class ServerConfig:
321
365
  server subprocess for `ShellAllowListMiddleware`.
322
366
  sandbox_type: Sandbox type.
323
367
  sandbox_id: Existing sandbox ID to reuse.
368
+ sandbox_snapshot_name: Sandbox snapshot name to use or create
369
+ (langsmith only).
324
370
  sandbox_setup: Path to setup script for the sandbox.
325
371
  enable_shell: Enable shell execution tools.
326
372
  enable_ask_user: Enable ask_user tool.
373
+ enable_interpreter: Enable `CodeInterpreterMiddleware` on the main
374
+ agent.
375
+ interpreter_ptc: Override for `settings.interpreter_ptc`.
376
+ interpreter_ptc_acknowledge_unsafe: Mirror of
377
+ `settings.interpreter_ptc_acknowledge_unsafe`.
327
378
  mcp_config_path: Path to MCP config.
328
379
  no_mcp: Disable MCP.
329
380
  trust_project_mcp: Trust project MCP servers.
@@ -344,8 +395,12 @@ class ServerConfig:
344
395
  interactive=interactive,
345
396
  enable_shell=enable_shell,
346
397
  enable_ask_user=enable_ask_user,
398
+ enable_interpreter=enable_interpreter,
399
+ interpreter_ptc=interpreter_ptc,
400
+ interpreter_ptc_acknowledge_unsafe=interpreter_ptc_acknowledge_unsafe,
347
401
  sandbox_type=sandbox_type,
348
402
  sandbox_id=sandbox_id,
403
+ sandbox_snapshot_name=sandbox_snapshot_name,
349
404
  sandbox_setup=_normalize_path(
350
405
  sandbox_setup, project_context, "sandbox setup"
351
406
  ),
@@ -0,0 +1,45 @@
1
+ """Stderr marker emission used by the langgraph server graph entry point.
2
+
3
+ Lives in its own module so unit tests can exercise the marker contract
4
+ without triggering `server_graph.make_graph()` at import time.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import logging
10
+ import sys
11
+ import traceback
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+ STARTUP_ERROR_MARKER = "DEEPAGENTS_STARTUP_ERROR:"
16
+ """Stderr marker the parent app scans for in `server._extract_startup_error_marker`
17
+ to upgrade an opaque "Server process exited with code N" into a one-line summary.
18
+ Format is `{STARTUP_ERROR_MARKER}{single-line message}`."""
19
+
20
+
21
+ def emit_startup_failure(exc: BaseException) -> None:
22
+ """Report a server graph startup failure to the parent app process.
23
+
24
+ Emits two stderr outputs: the full traceback for logs/debugging, then a
25
+ single-line `{STARTUP_ERROR_MARKER}{type}: {summary}` line that
26
+ `server._extract_startup_error_marker` parses to upgrade an opaque
27
+ "Server process exited with code N" into an actionable summary.
28
+
29
+ Args:
30
+ exc: The exception raised during graph initialization.
31
+ """
32
+ logger.critical("Failed to initialize server graph", exc_info=exc)
33
+ print( # noqa: T201 # stderr fallback — logger may not reach parent process
34
+ f"Failed to initialize server graph: {exc}\n{traceback.format_exc()}",
35
+ file=sys.stderr,
36
+ )
37
+ # Marker contract is single-line; guard against multi-line/empty `str(exc)`
38
+ # and include the type so e.g. `ValueError` and `RuntimeError` are
39
+ # distinguishable in the parent's truncated summary.
40
+ exc_lines = str(exc).splitlines()
41
+ summary = exc_lines[0] if exc_lines else "<no message>"
42
+ print( # noqa: T201
43
+ f"{STARTUP_ERROR_MARKER}{type(exc).__name__}: {summary}",
44
+ file=sys.stderr,
45
+ )
@@ -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.3" # x-release-please-version
5
+ __version__ = "0.1.4" # 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."""
@@ -9,7 +9,7 @@ import shutil
9
9
  import tempfile
10
10
  import tomllib
11
11
  from pathlib import Path
12
- from typing import TYPE_CHECKING, Any
12
+ from typing import TYPE_CHECKING, Any, cast
13
13
 
14
14
  from deepagents import create_deep_agent
15
15
  from deepagents.backends import CompositeBackend, LocalShellBackend
@@ -198,6 +198,121 @@ class ShellAllowListMiddleware(AgentMiddleware):
198
198
  return await handler(request)
199
199
 
200
200
 
201
+ _INTERPRETER_WRITE_TOOLS: frozenset[str] = frozenset(
202
+ {"execute", "write_file", "edit_file"}
203
+ )
204
+ """Tools considered write/shell capable for PTC auditing.
205
+
206
+ When `interpreter_ptc="all"` resolves to this set, an INFO log names every
207
+ write tool that was included so the audit trail is searchable. The `"safe"`
208
+ preset already excludes them; this is the belt-and-braces check for `"all"`.
209
+ """
210
+
211
+
212
+ def _resolve_ptc_option(
213
+ ptc: str | bool | list[str],
214
+ *,
215
+ tools: Sequence[BaseTool | Callable | dict[str, Any]],
216
+ acknowledge_unsafe: bool,
217
+ auto_approve: bool,
218
+ ) -> list[str] | None:
219
+ """Resolve the configured PTC allowlist to a concrete list of tool names.
220
+
221
+ Args:
222
+ ptc: Raw `interpreter_ptc` value from settings or CLI. Accepts
223
+ `False`/`[]`, `"safe"`, `"all"`, or a list of names.
224
+ tools: Live tool list given to `create_cli_agent`. Used to validate
225
+ explicit names, intersect the `"safe"` preset, and enumerate
226
+ `"all"`.
227
+ acknowledge_unsafe: Mirrors `settings.interpreter_ptc_acknowledge_unsafe`;
228
+ required when `ptc="all"` and `auto_approve` is `False`.
229
+ auto_approve: Whether HITL approval is globally disabled. When `True`,
230
+ `"all"` does not require `acknowledge_unsafe` because every host
231
+ tool already runs without prompting.
232
+
233
+ Returns:
234
+ `None` when PTC should be disabled, otherwise a list of tool names
235
+ suitable for `CodeInterpreterMiddleware(ptc=...)`.
236
+
237
+ Raises:
238
+ ValueError: For unknown names in an explicit list, or for `"all"`
239
+ without `acknowledge_unsafe` outside of `auto_approve`.
240
+ """
241
+ from langchain.tools import BaseTool as _BaseTool
242
+
243
+ if ptc is False or ptc is None or ptc == []:
244
+ return None
245
+
246
+ live_names: list[str] = []
247
+ for tool in tools:
248
+ if isinstance(tool, _BaseTool):
249
+ name = tool.name
250
+ if isinstance(name, str):
251
+ live_names.append(name)
252
+ elif isinstance(tool, dict):
253
+ raw_name = cast("dict[str, Any]", tool).get("name")
254
+ if isinstance(raw_name, str):
255
+ live_names.append(raw_name)
256
+ else:
257
+ attr = getattr(tool, "name", None)
258
+ if isinstance(attr, str):
259
+ live_names.append(attr)
260
+ live_set: set[str] = set(live_names)
261
+
262
+ if isinstance(ptc, str):
263
+ normalized = ptc.strip().lower()
264
+ if normalized == "safe":
265
+ from deepagents_code.config import INTERPRETER_PTC_SAFE_PRESET
266
+
267
+ selected = sorted(INTERPRETER_PTC_SAFE_PRESET & live_set)
268
+ dropped = sorted(INTERPRETER_PTC_SAFE_PRESET - live_set)
269
+ if dropped:
270
+ logger.debug(
271
+ "interpreter_ptc='safe' preset members not present in toolset: %s",
272
+ dropped,
273
+ )
274
+ return selected
275
+ if normalized == "all":
276
+ if not auto_approve and not acknowledge_unsafe:
277
+ msg = (
278
+ "interpreter_ptc='all' exposes every host tool to PTC "
279
+ "calls that bypass HITL approval. Set "
280
+ "interpreter_ptc_acknowledge_unsafe=True (or use "
281
+ "auto_approve=True) to opt in."
282
+ )
283
+ raise ValueError(msg)
284
+ included = sorted(live_set)
285
+ write_included = sorted(_INTERPRETER_WRITE_TOOLS & live_set)
286
+ if write_included:
287
+ logger.info(
288
+ "interpreter_ptc='all' includes write/shell tools: %s",
289
+ write_included,
290
+ )
291
+ return included
292
+ msg = (
293
+ f"Invalid interpreter_ptc string {ptc!r}; expected 'safe', 'all', "
294
+ "or a list of tool names."
295
+ )
296
+ raise ValueError(msg)
297
+
298
+ if isinstance(ptc, list):
299
+ unknown = [name for name in ptc if name not in live_set]
300
+ if unknown:
301
+ available = ", ".join(sorted(live_set)) or "<none>"
302
+ msg = (
303
+ "Unknown tool names in interpreter_ptc: "
304
+ f"{sorted(set(unknown))}. Available tools: {available}."
305
+ )
306
+ raise ValueError(msg)
307
+ return list(ptc)
308
+
309
+ msg = (
310
+ "interpreter_ptc must be False, 'safe', 'all', or a list of tool names; "
311
+ f"got {type(ptc).__name__}."
312
+ )
313
+ raise ValueError(msg)
314
+
315
+
201
316
  def load_async_subagents(config_path: Path | None = None) -> list[AsyncSubAgent]:
202
317
  """Load async subagent definitions from `config.toml`.
203
318
 
@@ -924,6 +1039,7 @@ def create_cli_agent(
924
1039
  enable_memory: bool = True,
925
1040
  enable_skills: bool = True,
926
1041
  enable_shell: bool = True,
1042
+ enable_interpreter: bool = False,
927
1043
  checkpointer: BaseCheckpointSaver | None = None,
928
1044
  mcp_server_info: list[MCPServerInfo] | None = None,
929
1045
  cwd: str | Path | None = None,
@@ -980,6 +1096,27 @@ def create_cli_agent(
980
1096
  enable_skills: Enable `SkillsMiddleware` for custom agent skills
981
1097
  enable_shell: Enable shell execution via `LocalShellBackend`
982
1098
  (only in local mode). When enabled, the `execute` tool is available.
1099
+ enable_interpreter: Wire `CodeInterpreterMiddleware` from
1100
+ `langchain-quickjs` into the main agent.
1101
+
1102
+ Local-mode only — passing a non-`None` `sandbox` while
1103
+ `enable_interpreter=True` raises `ValueError`. Subagents do not
1104
+ receive the interpreter in v1.
1105
+
1106
+ PTC (`tools.*` host bridge) calls bypass `interrupt_on`/HITL
1107
+ approval, so `settings.interpreter_ptc` is the only effective
1108
+ control over which host tools can be invoked from inside the
1109
+ REPL. `js_eval` itself is intentionally not gated by HITL —
1110
+ per-call approval would be unusably noisy and would not block
1111
+ PTC fan-out anyway. The `"safe"` preset is therefore restricted
1112
+ to tools that are already non-HITL outside the REPL (read-only
1113
+ file inspection); exposing HITL-gated tools — network fetch,
1114
+ subagent dispatch, shell, file writes — requires an explicit
1115
+ list or `interpreter_ptc="all"` with
1116
+ `interpreter_ptc_acknowledge_unsafe=True`.
1117
+
1118
+ Requires the `quickjs` optional extra
1119
+ (`langchain-quickjs>=0.1.2,<0.2.0`).
983
1120
  checkpointer: Optional checkpointer for session persistence.
984
1121
  When `None`, the graph is compiled without a checkpointer.
985
1122
  mcp_server_info: MCP server metadata to surface in the system prompt.
@@ -998,6 +1135,12 @@ def create_cli_agent(
998
1135
  - `agent_graph`: Configured LangGraph Pregel instance ready
999
1136
  for execution
1000
1137
  - `composite_backend`: `CompositeBackend` for file operations
1138
+
1139
+ Raises:
1140
+ ValueError: When `enable_interpreter=True` is paired with a
1141
+ non-`None` `sandbox`, when `settings.interpreter_ptc` contains
1142
+ unknown tool names, or when `interpreter_ptc="all"` is used
1143
+ without `auto_approve` or `interpreter_ptc_acknowledge_unsafe`.
1001
1144
  """
1002
1145
  tools = tools or []
1003
1146
  effective_cwd = (
@@ -1201,6 +1344,37 @@ def create_cli_agent(
1201
1344
  # Note: Shell middleware not used in sandbox mode
1202
1345
  # File operations and execute tool are provided by the sandbox backend
1203
1346
 
1347
+ if enable_interpreter:
1348
+ if sandbox is not None:
1349
+ msg = (
1350
+ "enable_interpreter=True is not supported with a remote "
1351
+ "sandbox in this release. Disable the sandbox or unset "
1352
+ "enable_interpreter."
1353
+ )
1354
+ raise ValueError(msg)
1355
+ # Lazy import keeps `dcode -v` fast — see AGENTS.md startup-perf rule.
1356
+ from langchain_quickjs import CodeInterpreterMiddleware, PTCOption
1357
+
1358
+ ptc_names = _resolve_ptc_option(
1359
+ settings.interpreter_ptc,
1360
+ tools=tools,
1361
+ acknowledge_unsafe=settings.interpreter_ptc_acknowledge_unsafe,
1362
+ auto_approve=auto_approve,
1363
+ )
1364
+ ptc_option: PTCOption | None = (
1365
+ cast("PTCOption", list(ptc_names)) if ptc_names is not None else None
1366
+ )
1367
+ agent_middleware.append(
1368
+ CodeInterpreterMiddleware(
1369
+ tool_name="js_eval",
1370
+ timeout=settings.interpreter_timeout_seconds,
1371
+ memory_limit=settings.interpreter_memory_limit_mb * 1024 * 1024,
1372
+ max_ptc_calls=settings.interpreter_max_ptc_calls,
1373
+ max_result_chars=settings.interpreter_max_result_chars,
1374
+ ptc=ptc_option,
1375
+ )
1376
+ )
1377
+
1204
1378
  # Local context middleware (git info, directory tree, etc.).
1205
1379
  if isinstance(backend, (_ExecutableBackend, _AsyncExecutableBackend)):
1206
1380
  agent_middleware.append(
@@ -3446,7 +3446,13 @@ class DeepAgentsApp(App):
3446
3446
  Custom themes use their stored registry colors; built-in Textual themes
3447
3447
  resolve colors from the active app theme. Terminal write failures are
3448
3448
  logged and swallowed because the OSC background sync is cosmetic.
3449
+
3450
+ ANSI themes intentionally skip this step so the terminal's native
3451
+ background is preserved.
3449
3452
  """
3453
+ if self.theme in {"ansi-dark", "ansi-light"}:
3454
+ return
3455
+
3450
3456
  from deepagents_code.terminal_escape import set_terminal_background
3451
3457
 
3452
3458
  entry = theme.get_registry().get(self.theme)
@@ -4918,7 +4924,14 @@ class DeepAgentsApp(App):
4918
4924
  Args:
4919
4925
  command: The raw command text (displayed as user message).
4920
4926
  """
4921
- from deepagents_code.config import build_langsmith_thread_url
4927
+ from deepagents_code.config import (
4928
+ LangSmithApiError,
4929
+ LangSmithImportError,
4930
+ LangSmithLookupTimeoutError,
4931
+ _assemble_langsmith_thread_url,
4932
+ fetch_langsmith_project_url_or_raise,
4933
+ get_langsmith_project_name,
4934
+ )
4922
4935
 
4923
4936
  if not self._session_state:
4924
4937
  await self._mount_message(UserMessage(command))
@@ -4926,15 +4939,18 @@ class DeepAgentsApp(App):
4926
4939
  return
4927
4940
  thread_id = self._session_state.thread_id
4928
4941
  try:
4929
- url = await asyncio.to_thread(build_langsmith_thread_url, thread_id)
4942
+ project_name = await asyncio.to_thread(get_langsmith_project_name)
4930
4943
  except Exception:
4931
- logger.exception("Failed to build LangSmith thread URL for %s", thread_id)
4944
+ logger.exception(
4945
+ "Failed to resolve LangSmith project name for thread %s",
4946
+ thread_id,
4947
+ )
4932
4948
  await self._mount_message(UserMessage(command))
4933
4949
  await self._mount_message(
4934
- AppMessage("Failed to resolve LangSmith thread URL."),
4950
+ AppMessage("Failed to resolve LangSmith project name."),
4935
4951
  )
4936
4952
  return
4937
- if not url:
4953
+ if not project_name:
4938
4954
  await self._mount_message(UserMessage(command))
4939
4955
  await self._mount_message(
4940
4956
  AppMessage(
@@ -4943,6 +4959,61 @@ class DeepAgentsApp(App):
4943
4959
  ),
4944
4960
  )
4945
4961
  return
4962
+ try:
4963
+ project_url = await asyncio.to_thread(
4964
+ fetch_langsmith_project_url_or_raise, project_name
4965
+ )
4966
+ except LangSmithImportError:
4967
+ logger.warning(
4968
+ "langsmith package not installed; cannot resolve thread URL for %s",
4969
+ thread_id,
4970
+ )
4971
+ await self._mount_message(UserMessage(command))
4972
+ await self._mount_message(
4973
+ AppMessage(
4974
+ "The `langsmith` package is not installed. "
4975
+ "Install it with `pip install langsmith` to enable `/trace`.",
4976
+ ),
4977
+ )
4978
+ return
4979
+ except LangSmithLookupTimeoutError:
4980
+ logger.warning(
4981
+ "LangSmith project URL lookup timed out for thread %s",
4982
+ thread_id,
4983
+ )
4984
+ await self._mount_message(UserMessage(command))
4985
+ await self._mount_message(
4986
+ AppMessage(
4987
+ "Could not reach LangSmith to resolve the thread URL. "
4988
+ "Check your network connection and try again.",
4989
+ ),
4990
+ )
4991
+ return
4992
+ except LangSmithApiError as exc:
4993
+ logger.warning(
4994
+ "LangSmith API call failed while resolving thread URL for %s: %s",
4995
+ thread_id,
4996
+ exc,
4997
+ )
4998
+ await self._mount_message(UserMessage(command))
4999
+ await self._mount_message(
5000
+ AppMessage(
5001
+ f"LangSmith rejected the project lookup: {exc}. "
5002
+ "Verify LANGSMITH_API_KEY and the project name are correct.",
5003
+ ),
5004
+ )
5005
+ return
5006
+ except Exception:
5007
+ logger.exception(
5008
+ "Failed to fetch LangSmith project URL for thread %s",
5009
+ thread_id,
5010
+ )
5011
+ await self._mount_message(UserMessage(command))
5012
+ await self._mount_message(
5013
+ AppMessage("Failed to resolve LangSmith thread URL."),
5014
+ )
5015
+ return
5016
+ url = _assemble_langsmith_thread_url(project_url, thread_id)
4946
5017
 
4947
5018
  def _open_browser() -> None:
4948
5019
  try: