deepagents-code 0.1.32__tar.gz → 0.1.34__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 (339) hide show
  1. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/AGENTS.md +3 -3
  2. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/CHANGELOG.md +20 -0
  3. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/COMMANDS.md +1 -1
  4. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/PKG-INFO +5 -5
  5. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/THREAT_MODEL.md +22 -22
  6. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_build_info.py +1 -1
  7. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_env_vars.py +36 -0
  8. deepagents_code-0.1.34/deepagents_code/_fake_models.py +66 -0
  9. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_session_stats.py +86 -3
  10. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_testing_models.py +22 -34
  11. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_tool_stream.py +42 -4
  12. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_version.py +1 -1
  13. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/agent.py +16 -9
  14. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/app.py +266 -78
  15. deepagents_code-0.1.34/deepagents_code/client/__init__.py +1 -0
  16. deepagents_code-0.1.34/deepagents_code/client/commands/__init__.py +1 -0
  17. deepagents_code-0.1.34/deepagents_code/client/commands/tools.py +402 -0
  18. deepagents_code-0.1.34/deepagents_code/client/launch/__init__.py +1 -0
  19. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/client/launch}/server.py +1 -1
  20. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/client/launch}/server_manager.py +40 -21
  21. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/client}/non_interactive.py +8 -3
  22. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/command_registry.py +1 -1
  23. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/config.py +55 -8
  24. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/config_manifest.py +44 -0
  25. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/input.py +198 -12
  26. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/main.py +105 -19
  27. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_disabled.py +52 -22
  28. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_tools.py +262 -65
  29. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/media_utils.py +137 -3
  30. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/model_config.py +243 -0
  31. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/offload.py +1 -1
  32. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/skills/commands.py +172 -2
  33. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/skills/invocation.py +9 -0
  34. deepagents_code-0.1.34/deepagents_code/skills/trust.py +547 -0
  35. deepagents_code-0.1.34/deepagents_code/tool_catalog.py +354 -0
  36. deepagents_code-0.1.34/deepagents_code/tui/__init__.py +1 -0
  37. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/textual_adapter.py +2 -80
  38. deepagents_code-0.1.34/deepagents_code/tui/widgets/__init__.py +9 -0
  39. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/approval.py +1 -1
  40. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/auth.py +6 -6
  41. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/chat_input.py +78 -7
  42. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/codex_auth.py +1 -1
  43. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/goal_review.py +1 -1
  44. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/install_confirm.py +1 -1
  45. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/mcp_login.py +2 -2
  46. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/message_store.py +2 -2
  47. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/messages.py +4 -4
  48. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/model_selector.py +8 -8
  49. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/notification_center.py +6 -2
  50. deepagents_code-0.1.34/deepagents_code/tui/widgets/skill_trust.py +131 -0
  51. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/status.py +1 -1
  52. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/subagent_panel.py +1 -1
  53. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/thread_selector.py +1 -1
  54. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/tool_renderers.py +2 -2
  55. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/update_available.py +1 -1
  56. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/update_progress.py +1 -1
  57. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/welcome.py +20 -8
  58. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/ui.py +49 -0
  59. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/pyproject.toml +11 -5
  60. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +1 -1
  61. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +1 -1
  62. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/integration_tests/test_auto_approve_remote.py +5 -2
  63. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/integration_tests/test_compact_resume.py +2 -2
  64. deepagents_code-0.1.34/tests/unit_tests/client/__init__.py +1 -0
  65. deepagents_code-0.1.34/tests/unit_tests/client/commands/__init__.py +1 -0
  66. deepagents_code-0.1.32/tests/unit_tests/test_auth_commands.py → deepagents_code-0.1.34/tests/unit_tests/client/commands/test_auth.py +1 -1
  67. deepagents_code-0.1.32/tests/unit_tests/test_mcp_commands.py → deepagents_code-0.1.34/tests/unit_tests/client/commands/test_mcp.py +11 -11
  68. deepagents_code-0.1.34/tests/unit_tests/client/commands/test_tools.py +527 -0
  69. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/conftest.py +1 -1
  70. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/skills/test_commands.py +287 -0
  71. deepagents_code-0.1.34/tests/unit_tests/skills/test_skill_trust.py +528 -0
  72. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_app.py +162 -156
  73. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_args.py +5 -5
  74. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_config_manifest.py +3 -3
  75. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_install_command.py +6 -6
  76. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_install_script.py +1 -0
  77. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_main.py +224 -2
  78. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_main_args.py +19 -13
  79. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_mcp_disabled.py +59 -2
  80. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_mcp_tools.py +462 -0
  81. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_media_utils.py +369 -0
  82. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_model_config.py +323 -0
  83. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_model_switch.py +3 -3
  84. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_non_interactive.py +294 -212
  85. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_offload.py +5 -5
  86. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_reasoning_effort.py +2 -2
  87. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_reload.py +206 -1
  88. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_remote_client.py +5 -3
  89. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_rubric_cli.py +2 -2
  90. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_server.py +138 -56
  91. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_server_helpers.py +2 -2
  92. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_server_manager.py +99 -29
  93. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_session_stats.py +95 -0
  94. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_skill_invocation.py +410 -7
  95. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_startup_fast_paths.py +1 -0
  96. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_theme.py +28 -28
  97. deepagents_code-0.1.34/tests/unit_tests/test_tool_catalog.py +334 -0
  98. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_version.py +34 -34
  99. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui}/test_subagent_stream.py +1 -1
  100. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui}/test_textual_adapter.py +101 -319
  101. deepagents_code-0.1.34/tests/unit_tests/tui/widgets/__init__.py +0 -0
  102. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_agent_selector.py +9 -9
  103. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_approval.py +1 -1
  104. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_ask_user.py +4 -3
  105. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_auth_widgets.py +30 -30
  106. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_autocomplete.py +2 -2
  107. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_chat_input.py +203 -6
  108. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_cwd_switch.py +4 -1
  109. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui}/widgets/test_diff.py +1 -1
  110. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_goal_review.py +4 -3
  111. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_history.py +1 -1
  112. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_install_confirm.py +1 -1
  113. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_launch_init.py +1 -1
  114. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_links.py +17 -14
  115. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_loading.py +4 -4
  116. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_mcp_login_modal.py +1 -1
  117. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_mcp_reconnect.py +1 -1
  118. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_mcp_viewer.py +22 -22
  119. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_message_store.py +3 -3
  120. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_messages.py +31 -29
  121. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_model_selector.py +39 -39
  122. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_notification_center.py +3 -3
  123. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_notification_detail.py +1 -1
  124. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_restart_prompt.py +1 -1
  125. deepagents_code-0.1.34/tests/unit_tests/tui/widgets/test_skill_trust_screen.py +78 -0
  126. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_status.py +4 -4
  127. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_subagent_panel.py +1 -1
  128. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_thread_selector.py +56 -56
  129. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_tool_renderers.py +2 -2
  130. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_update_available.py +1 -1
  131. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_update_confirm.py +1 -1
  132. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_update_progress.py +1 -1
  133. {deepagents_code-0.1.32/tests/unit_tests → deepagents_code-0.1.34/tests/unit_tests/tui/widgets}/test_welcome.py +31 -8
  134. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/uv.lock +6 -6
  135. deepagents_code-0.1.32/deepagents_code/tools_commands.py +0 -191
  136. deepagents_code-0.1.32/deepagents_code/widgets/__init__.py +0 -9
  137. deepagents_code-0.1.32/tests/unit_tests/test_tools_commands.py +0 -144
  138. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/.gitignore +0 -0
  139. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/ARCHITECTURE.md +0 -0
  140. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/DEVELOPMENT.md +0 -0
  141. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/Makefile +0 -0
  142. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/README.md +0 -0
  143. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/__init__.py +0 -0
  144. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/__main__.py +0 -0
  145. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_ask_user_types.py +0 -0
  146. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_cli_context.py +0 -0
  147. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_constants.py +0 -0
  148. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_debug.py +0 -0
  149. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_git.py +0 -0
  150. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_paths.py +0 -0
  151. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_server_config.py +0 -0
  152. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_startup_error.py +0 -0
  153. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/_textual_patches.py +0 -0
  154. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/app.tcss +0 -0
  155. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/approval_mode.py +0 -0
  156. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/ask_user.py +0 -0
  157. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/auth_display.py +0 -0
  158. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/auth_store.py +0 -0
  159. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/built_in_skills/__init__.py +0 -0
  160. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/built_in_skills/remember/SKILL.md +0 -0
  161. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/built_in_skills/skill-creator/SKILL.md +0 -0
  162. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
  163. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
  164. /deepagents_code-0.1.32/deepagents_code/auth_commands.py → /deepagents_code-0.1.34/deepagents_code/client/commands/auth.py +0 -0
  165. /deepagents_code-0.1.32/deepagents_code/config_commands.py → /deepagents_code-0.1.34/deepagents_code/client/commands/config.py +0 -0
  166. /deepagents_code-0.1.32/deepagents_code/mcp_commands.py → /deepagents_code-0.1.34/deepagents_code/client/commands/mcp.py +0 -0
  167. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/client}/remote_client.py +0 -0
  168. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/clipboard.py +0 -0
  169. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/configurable_model.py +0 -0
  170. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/default_agent_prompt.md +0 -0
  171. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/doctor.py +0 -0
  172. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/editor.py +0 -0
  173. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/event_bus.py +0 -0
  174. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/extras_info.py +0 -0
  175. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/file_ops.py +0 -0
  176. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/formatting.py +0 -0
  177. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/goal_rubric.py +0 -0
  178. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/goal_tools.py +0 -0
  179. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/hooks.py +0 -0
  180. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/integrations/__init__.py +0 -0
  181. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/integrations/openai_codex.py +0 -0
  182. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/integrations/sandbox_config.py +0 -0
  183. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/integrations/sandbox_factory.py +0 -0
  184. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/integrations/sandbox_provider.py +0 -0
  185. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/integrations/sandbox_registry.py +0 -0
  186. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/iterm_cursor_guide.py +0 -0
  187. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/local_context.py +0 -0
  188. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/managed_tools.py +0 -0
  189. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_auth.py +0 -0
  190. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_login_service.py +0 -0
  191. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_oauth_ui.py +0 -0
  192. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_providers/__init__.py +0 -0
  193. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_providers/_registry.py +0 -0
  194. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_providers/base.py +0 -0
  195. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_providers/github.py +0 -0
  196. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_providers/slack.py +0 -0
  197. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/mcp_trust.py +0 -0
  198. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/memory_guard.py +0 -0
  199. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/notifications.py +0 -0
  200. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/onboarding.py +0 -0
  201. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/output.py +0 -0
  202. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/paste_collapse.py +0 -0
  203. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/project_utils.py +0 -0
  204. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/py.typed +0 -0
  205. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/reasoning_effort.py +0 -0
  206. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/resume_state.py +0 -0
  207. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/server_graph.py +0 -0
  208. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/sessions.py +0 -0
  209. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/skills/__init__.py +0 -0
  210. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/skills/load.py +0 -0
  211. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/state_migration.py +0 -0
  212. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/subagents.py +0 -0
  213. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/system_prompt.md +0 -0
  214. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/terminal_capabilities.py +0 -0
  215. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/terminal_escape.py +0 -0
  216. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/theme.py +0 -0
  217. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/tool_display.py +0 -0
  218. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/tools.py +0 -0
  219. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/_js_eval_display.py +0 -0
  220. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/_links.py +0 -0
  221. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/agent_selector.py +0 -0
  222. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/ask_user.py +0 -0
  223. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/autocomplete.py +0 -0
  224. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/cwd_switch.py +0 -0
  225. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/diff.py +0 -0
  226. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/effort_selector.py +0 -0
  227. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/history.py +0 -0
  228. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/launch_init.py +0 -0
  229. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/loading.py +0 -0
  230. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/mcp_reconnect.py +0 -0
  231. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/mcp_viewer.py +0 -0
  232. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/notification_detail.py +0 -0
  233. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/notification_settings.py +0 -0
  234. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/restart_prompt.py +0 -0
  235. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/theme_selector.py +0 -0
  236. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/tool_widgets.py +0 -0
  237. {deepagents_code-0.1.32/deepagents_code → deepagents_code-0.1.34/deepagents_code/tui}/widgets/update_confirm.py +0 -0
  238. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/unicode_security.py +0 -0
  239. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/deepagents_code/update_check.py +0 -0
  240. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/examples/skills/arxiv-search/SKILL.md +0 -0
  241. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/examples/skills/arxiv-search/arxiv_search.py +0 -0
  242. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/examples/skills/langgraph-docs/SKILL.md +0 -0
  243. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/examples/skills/skill-creator/SKILL.md +0 -0
  244. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
  245. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
  246. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/examples/skills/web-research/SKILL.md +0 -0
  247. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/hatch_build.py +0 -0
  248. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/images/tui.png +0 -0
  249. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/scripts/check_imports.py +0 -0
  250. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/scripts/debug_server.sh +0 -0
  251. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/scripts/generate_commands_catalog.py +0 -0
  252. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/scripts/install.sh +0 -0
  253. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/README.md +0 -0
  254. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/integration_tests/__init__.py +0 -0
  255. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/integration_tests/benchmarks/__init__.py +0 -0
  256. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/integration_tests/conftest.py +0 -0
  257. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/integration_tests/test_acp_mode.py +0 -0
  258. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/integration_tests/test_sandbox_factory.py +0 -0
  259. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/integration_tests/test_sandbox_operations.py +0 -0
  260. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/__init__.py +0 -0
  261. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/data/coding_agent_v1_validator.json +0 -0
  262. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/skills/__init__.py +0 -0
  263. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/skills/test_load.py +0 -0
  264. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/skills/test_skills_json.py +0 -0
  265. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/smoke_tests/__init__.py +0 -0
  266. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/smoke_tests/conftest.py +0 -0
  267. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/smoke_tests/snapshots/system_prompt_interactive_local.md +0 -0
  268. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/smoke_tests/test_system_prompt.py +0 -0
  269. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test__tool_stream.py +0 -0
  270. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_agent.py +0 -0
  271. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_agent_friendly.py +0 -0
  272. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_approval_mode.py +0 -0
  273. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_ask_user_middleware.py +0 -0
  274. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_auth_display.py +0 -0
  275. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_auth_store.py +0 -0
  276. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_charset.py +0 -0
  277. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_clipboard.py +0 -0
  278. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_coding_agent_metadata.py +0 -0
  279. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_command_registry.py +0 -0
  280. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_compact_tool.py +0 -0
  281. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_config.py +0 -0
  282. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_configurable_model.py +0 -0
  283. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_cursor_blink.py +0 -0
  284. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_debug.py +0 -0
  285. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_doctor.py +0 -0
  286. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_editor.py +0 -0
  287. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_end_to_end.py +0 -0
  288. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_env_vars.py +0 -0
  289. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_event_bus.py +0 -0
  290. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_exception_handling.py +0 -0
  291. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_extras_info.py +0 -0
  292. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_file_ops.py +0 -0
  293. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_formatting.py +0 -0
  294. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_git.py +0 -0
  295. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_goal_rubric.py +0 -0
  296. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_goal_tools.py +0 -0
  297. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_hatch_build.py +0 -0
  298. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_hooks.py +0 -0
  299. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_imports.py +0 -0
  300. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_input_parsing.py +0 -0
  301. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
  302. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_local_context.py +0 -0
  303. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_main_acp_mode.py +0 -0
  304. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_managed_tools.py +0 -0
  305. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_mcp_auth.py +0 -0
  306. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_mcp_login_service.py +0 -0
  307. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_mcp_oauth_ui.py +0 -0
  308. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_mcp_trust.py +0 -0
  309. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_memory_guard.py +0 -0
  310. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_notifications.py +0 -0
  311. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_offload_dict_messages.py +0 -0
  312. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_onboarding.py +0 -0
  313. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_openai_codex_integration.py +0 -0
  314. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_output.py +0 -0
  315. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_paths.py +0 -0
  316. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_resume_state.py +0 -0
  317. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_sandbox_config.py +0 -0
  318. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_sandbox_factory.py +0 -0
  319. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_sandbox_provider.py +0 -0
  320. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_sandbox_registry.py +0 -0
  321. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_server_config.py +0 -0
  322. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_server_graph.py +0 -0
  323. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_sessions.py +0 -0
  324. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_shell_allow_list.py +0 -0
  325. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_state_migration.py +0 -0
  326. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_subagents.py +0 -0
  327. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_terminal_capabilities.py +0 -0
  328. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_terminal_escape.py +0 -0
  329. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_terminal_progress_preference.py +0 -0
  330. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_textual_patches.py +0 -0
  331. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_tool_display.py +0 -0
  332. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_tracing_replicas.py +0 -0
  333. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_ui.py +0 -0
  334. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_unicode_security.py +0 -0
  335. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/test_update_check.py +0 -0
  336. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/tools/__init__.py +0 -0
  337. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/tools/test_current_thread.py +0 -0
  338. {deepagents_code-0.1.32 → deepagents_code-0.1.34}/tests/unit_tests/tools/test_fetch_url.py +0 -0
  339. {deepagents_code-0.1.32/tests/unit_tests/widgets → deepagents_code-0.1.34/tests/unit_tests/tui}/__init__.py +0 -0
@@ -43,7 +43,7 @@ Textual's `App.notify(message)` parses the message string as Rich markup by defa
43
43
  Charset-dependent characters and animations have **single sources of truth**. Reuse them instead of hand-rolling new ones — copies drift, and (more subtly) a hardcoded Unicode literal won't degrade to ASCII on terminals that need it.
44
44
 
45
45
  - **Glyphs** (checkmarks, arrows, ellipsis, cursor, box-drawing, branch icon, etc.): pull from `get_glyphs()` (`config.Glyphs`). Each glyph has a Unicode and an ASCII variant; `get_glyphs()` returns the right set for the active terminal. Never inline `"✓"`, `"…"`, `"›"`, and friends.
46
- - **Animated spinners**: reuse the `Spinner` class in `widgets/loading.py`, which wraps `get_glyphs().spinner_frames` (braille on Unicode, `(-) (\) (|) (/)` on ASCII) and exposes `next_frame()`/`current_frame()`. Do **not** define your own frame tuples or interval constants for a spinner — drive a `Spinner` on a `set_interval`. The status-bar reconnect indicator (`widgets/status.py`) is the reference example; it ticks at the same 0.1s cadence as `LoadingWidget`. All connection/queue progress lives in the status bar — the welcome banner deliberately stays out of it, so there are currently no bespoke spinners to carve an exception for.
46
+ - **Animated spinners**: reuse the `Spinner` class in `tui/widgets/loading.py`, which wraps `get_glyphs().spinner_frames` (braille on Unicode, `(-) (\) (|) (/)` on ASCII) and exposes `next_frame()`/`current_frame()`. Do **not** define your own frame tuples or interval constants for a spinner — drive a `Spinner` on a `set_interval`. The status-bar reconnect indicator (`tui/widgets/status.py`) is the reference example; it ticks at the same 0.1s cadence as `LoadingWidget`. All connection/queue progress lives in the status bar — the welcome banner deliberately stays out of it, so there are currently no bespoke spinners to carve an exception for.
47
47
 
48
48
  ### Textual patterns used in this codebase
49
49
 
@@ -99,7 +99,7 @@ The `deepagents-code --help` screen is hand-maintained in `ui.show_help()`, sepa
99
99
 
100
100
  ## Splash screen tips
101
101
 
102
- When adding a user-facing CLI feature (new slash command, keybinding, workflow), add a corresponding tip to the `_TIPS` list in `deepagents_code/widgets/welcome.py`. Tips are shown randomly on startup to help users discover features. Keep tips short and action-oriented (e.g., `"Press ctrl+x to compose prompts in your external editor"`).
102
+ When adding a user-facing CLI feature (new slash command, keybinding, workflow), add a corresponding tip to the `_TIPS` list in `deepagents_code/tui/widgets/welcome.py`. Tips are shown randomly on startup to help users discover features. Keep tips short and action-oriented (e.g., `"Press ctrl+x to compose prompts in your external editor"`).
103
103
 
104
104
  ## Slash commands
105
105
 
@@ -115,7 +115,7 @@ To add a new slash command: (1) add a `SlashCommand` entry to `COMMANDS`, (2) se
115
115
  2. `deepagents_code/model_config.py` — if the provider reads a *dedicated* endpoint env var, add `"provider_name": ("CANONICAL_BASE_URL", "ALTERNATE", ...)` to `PROVIDER_BASE_URL_ENV` (see guidelines below); omit the provider entirely when it has no provider-specific endpoint variable
116
116
  3. `pyproject.toml` — add `provider = ["langchain-provider>=X.Y.Z,<N.0.0"]` to `[project.optional-dependencies]` and include it in the `all-providers` composite extra
117
117
  4. `deepagents_code/model_config.py` — add `"provider_name"` to `RETRY_PARAM_BY_PROVIDER` if the provider's chat model accepts `max_retries`
118
- 5. `deepagents_code/widgets/auth.py` — add `"provider_name": "Display Name"` to `PROVIDER_DISPLAY_NAMES` so the `/auth` UI shows a branded label instead of the title-cased key, and (if the provider issues API keys from a self-serve page) `"provider_name": "https://…"` to `PROVIDER_API_KEY_URLS` so the prompt links straight to the key page
118
+ 5. `deepagents_code/tui/widgets/auth.py` — add `"provider_name": "Display Name"` to `PROVIDER_DISPLAY_NAMES` so the `/auth` UI shows a branded label instead of the title-cased key, and (if the provider issues API keys from a self-serve page) `"provider_name": "https://…"` to `PROVIDER_API_KEY_URLS` so the prompt links straight to the key page
119
119
  6. `tests/unit_tests/test_model_config.py` — add `assert PROVIDER_API_KEY_ENV["provider_name"] == "ENV_VAR_NAME"` to `TestProviderApiKeyEnv.test_contains_major_providers`, and pin any `PROVIDER_BASE_URL_ENV` entry with a matching assertion
120
120
 
121
121
  ### `PROVIDER_BASE_URL_ENV` guidelines
@@ -2,6 +2,26 @@
2
2
 
3
3
  # Deep Agents Code Changelog
4
4
 
5
+ ## [0.1.34](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.33...deepagents-code==0.1.34) (2026-07-07)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * **code:** show `(local)` tag under ANSI themes ([#4534](https://github.com/langchain-ai/deepagents/issues/4534)) ([699e439](https://github.com/langchain-ai/deepagents/commit/699e439699723e477a621f95eef87a7d76aac5f5))
11
+
12
+ ## [0.1.33](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.32...deepagents-code==0.1.33) (2026-07-06)
13
+
14
+ ### Features
15
+
16
+ * 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))
17
+ * Selective per-server project MCP trust ([#4507](https://github.com/langchain-ai/deepagents/issues/4507)) ([aaa22a9](https://github.com/langchain-ai/deepagents/commit/aaa22a9340cb3d2c8e9ce1a921957d0a9121da20))
18
+ * Add `dcode tools list` command ([#4461](https://github.com/langchain-ai/deepagents/issues/4461)) ([1402d0e](https://github.com/langchain-ai/deepagents/commit/1402d0e735a1580503f240457c77db76fcd779d7))
19
+
20
+ ### Bug Fixes
21
+
22
+ * 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))
23
+ * Re-apply theme preference on `/reload` ([#4514](https://github.com/langchain-ai/deepagents/issues/4514)) ([5d1c392](https://github.com/langchain-ai/deepagents/commit/5d1c3928f7ca0ea97f28fd4d34ae1a4ee885e888))
24
+
5
25
  ## [0.1.32](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.31...deepagents-code==0.1.32) (2026-07-06)
6
26
 
7
27
  ### Features
@@ -29,7 +29,7 @@ aliases, descriptions, visibility, or hidden-command metadata.
29
29
  | `/mcp` | | Manage MCP servers and authentication |
30
30
  | `/model` | | Switch models or edit model settings |
31
31
  | `/notifications` | | Configure startup warnings |
32
- | `/offload` | `/compact` | Offload older messages to free context |
32
+ | `/offload` | `/compact` | Summarize and offload older messages to free context |
33
33
  | `/quit` | `/q` | Exit app |
34
34
  | `/reload` | | Reload environment and config |
35
35
  | `/remember` | | Save useful context to memory or skills |
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepagents-code
3
- Version: 0.1.32
3
+ Version: 0.1.34
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.0a6
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
@@ -12,8 +12,8 @@
12
12
 
13
13
  - `deepagents_code/` — all Python source modules shipped as the `deepagents-code` package
14
14
  - CLI entry point (`main.py`, `__init__.py`)
15
- - Interactive TUI (`app.py`, `textual_adapter.py`, `widgets/`)
16
- - Non-interactive pipeline runner (`non_interactive.py`)
15
+ - Interactive TUI (`app.py`, `tui/textual_adapter.py`, `tui/widgets/`)
16
+ - Non-interactive pipeline runner (`client/non_interactive.py`)
17
17
  - Agent creation (`agent.py`)
18
18
  - Built-in tools (`tools.py`: `http_request`, `web_search`, `fetch_url`)
19
19
  - MCP config loader and trust store (`mcp_tools.py`, `mcp_trust.py`)
@@ -22,8 +22,8 @@
22
22
  - Session persistence (`sessions.py`)
23
23
  - Configuration system (`config.py`, `model_config.py`)
24
24
  - Unicode/URL safety helpers (`unicode_security.py`)
25
- - LangGraph dev server subprocess management (`server.py`, `server_manager.py`, `server_graph.py`)
26
- - Remote agent client (`remote_client.py`)
25
+ - LangGraph dev server subprocess management (`client/launch/server.py`, `client/launch/server_manager.py`, `server_graph.py`)
26
+ - Remote agent client (`client/remote_client.py`)
27
27
  - Local context middleware (`local_context.py`)
28
28
  - Custom subagent loader (`subagents.py`, `agent.py:load_async_subagents`)
29
29
  - Conversation offload (`offload.py`)
@@ -47,7 +47,7 @@
47
47
  3. `~/.deepagents/` is only writable by the authenticated local user — no multi-user shared home directories.
48
48
  4. Sandbox backends are trusted third-party services. CLI responsibility ends at correctly constructing and dispatching requests to them.
49
49
  5. LangSmith tracing, if enabled, is user-opted-in via environment variables.
50
- 6. The LangGraph dev server subprocess binds to `127.0.0.1` by default (`server.py:_DEFAULT_HOST`) and is ephemeral — started and stopped per CLI session.
50
+ 6. The LangGraph dev server subprocess binds to `127.0.0.1` by default (`client/launch/server.py:_DEFAULT_HOST`) and is ephemeral — started and stopped per CLI session.
51
51
  7. `DA_SERVER_*` environment variables are readable only by the CLI process and its child server subprocess (OS process isolation assumption).
52
52
  8. Users who set `class_path` in `config.toml` accept the same trust model as `pyproject.toml` build scripts — they control their own machine.
53
53
 
@@ -68,19 +68,19 @@
68
68
  │ ┌────────────────┼─────────────────────┐ │
69
69
  │ ▼ ▼ ▼ │
70
70
  │ C2: TUI (app.py) C2b: Non-interactive C13: Config Channel │
71
- │ │ (non_interactive.py) (DA_SERVER_* env vars)│
71
+ │ │ (client/non_interactive.py) (DA_SERVER_* vars)
72
72
  │ - - - - - - - - - - TB8: CLI / Server IPC - - - - - │ - - - - - - - │
73
73
  │ │ ▼ │
74
- │ │ C11: Server Manager (server_manager)
74
+ │ │ C11: Server Manager (client/launch)
75
75
  │ │ │ spawns │
76
76
  │ │ ▼ │
77
77
  │ │ C11b: LangGraph Dev Server │
78
- │ │ (server.py:ServerProcess)
78
+ │ │ (client/launch/server.py:ServerProcess)
79
79
  │ │ LANGGRAPH_AUTH_TYPE=noop │
80
80
  │ - - - - - - - - │ - - - - - TB10: RemoteAgent / Dev Server - - - - │
81
81
  │ │ ▲ │
82
82
  │ └─►C12: RemoteAgent────┘ (HTTP+SSE on 127.0.0.1) │
83
- │ (remote_client.py)
83
+ │ (client/remote_client.py)
84
84
  │ │ │
85
85
  │ C3: Agent Engine (server_graph.py) │
86
86
  │ (create_cli_agent, deepagents SDK) │
@@ -122,7 +122,7 @@
122
122
  | ID | Component | Description | Trust Level | Default? | Entry Points |
123
123
  |-----|-----------------------------|---------------------------------------------------------------------------------------------------------------------|----------------------|----------|---------------------------------------------------------------------------------------------------|
124
124
  | C1 | CLI Entry Point | Parses argv, loads config/env, bootstraps session | framework-controlled | Yes | `main.cli_main`, `main.parse_args` |
125
- | C2 | TUI / Non-interactive | Textual UI for interactive chat; `non_interactive.py` for headless pipelines (both use `RemoteAgent`) | framework-controlled | Yes | `app.DeepAgentsApp.run`, `non_interactive.run_non_interactive` |
125
+ | C2 | TUI / Non-interactive | Textual UI for interactive chat; `client/non_interactive.py` for headless pipelines (both use `RemoteAgent`) | framework-controlled | Yes | `app.DeepAgentsApp.run`, `client.non_interactive.run_non_interactive` |
126
126
  | C3 | Agent Engine | LangGraph agent graph running inside `langgraph dev` server, assembled by `create_cli_agent` | framework-controlled | Yes | `agent.create_cli_agent`, `agent._add_interrupt_on`, `server_graph.make_graph` |
127
127
  | C4 | Built-in Tools | `http_request`, `web_search` (Tavily), `fetch_url` (HTML→markdown) | framework-controlled | Partial¹ | `tools.http_request`, `tools.web_search`, `tools.fetch_url` |
128
128
  | C5 | MCP Loader & Trust | Discovers/loads `.mcp.json`, validates server configs, manages trust store | framework-controlled | No² | `mcp_tools.resolve_and_load_mcp_tools`, `mcp_trust.compute_config_fingerprint` |
@@ -131,8 +131,8 @@
131
131
  | C8 | Session Persistence | SQLite checkpoint store for LangGraph thread state | framework-controlled | Yes | `sessions.get_db_path`, `sessions.generate_thread_id` |
132
132
  | C9 | Configuration System | TOML config, env vars, `AGENTS.md` system prompts, model config | user-controlled | N/A | `config.settings`, `model_config.ModelConfig`, `~/.deepagents/config.toml` |
133
133
  | C10 | Unicode/URL Safety | Detects hidden Unicode, checks URL domain spoofing for approval UI warnings | framework-controlled | Yes | `unicode_security.detect_dangerous_unicode`, `unicode_security.check_url_safety` |
134
- | C11 | LangGraph Dev Server | Subprocess running `langgraph dev` with `LANGGRAPH_AUTH_TYPE=noop`; managed by `ServerProcess` | framework-controlled | Yes⁵ | `server.ServerProcess.start`, `server.generate_langgraph_json`, `server_manager.start_server_and_get_agent` |
135
- | C12 | Remote Agent Client | HTTP+SSE client wrapping `RemoteGraph`; connects to C11 on localhost | framework-controlled | Yes⁵ | `remote_client.RemoteAgent.astream`, `remote_client.RemoteAgent.aget_state` |
134
+ | C11 | LangGraph Dev Server | Subprocess running `langgraph dev` with `LANGGRAPH_AUTH_TYPE=noop`; managed by `ServerProcess` | framework-controlled | Yes⁵ | `client.launch.server.ServerProcess.start`, `client.launch.server.generate_langgraph_json`, `client.launch.server_manager.start_server_and_get_agent` |
135
+ | C12 | Remote Agent Client | HTTP+SSE client wrapping `RemoteGraph`; connects to C11 on localhost | framework-controlled | Yes⁵ | `client.remote_client.RemoteAgent.astream`, `client.remote_client.RemoteAgent.aget_state` |
136
136
  | C13 | Server Config Channel | Passes CLI config to server subprocess via `DA_SERVER_*` environment variables | framework-controlled | Yes | `_server_config.ServerConfig.to_env`, `_server_config.ServerConfig.from_env` |
137
137
  | C14 | Async Subagent Config | Loads remote LangGraph deployment specs from `[async_subagents]` in `config.toml` | user-controlled | No | `agent.load_async_subagents` |
138
138
  | C15 | LocalContext Middleware | Runs a bash detection script via backend; injects git/project/env context into system prompt each turn | framework-controlled | Yes⁶ | `local_context.LocalContextMiddleware.before_agent`, `local_context.build_detect_script` |
@@ -164,7 +164,7 @@
164
164
  #### DC1: API Keys / Credentials
165
165
 
166
166
  - **Fields**: `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `TAVILY_API_KEY`, `LANGSMITH_API_KEY`, `LANGGRAPH_API_KEY`, and any provider-specific keys in the user's environment.
167
- - **Storage**: Loaded from environment at process start (`config.py`). The CLI explicitly strips `LANGGRAPH_CLOUD_LICENSE_KEY` and related auth vars from the server subprocess environment (`server.py:_build_server_env`) but passes the remaining env vars (including provider API keys) to the server subprocess via `os.environ.copy()`.
167
+ - **Storage**: Loaded from environment at process start (`config.py`). The CLI explicitly strips `LANGGRAPH_CLOUD_LICENSE_KEY` and related auth vars from the server subprocess environment (`client/launch/server.py:_build_server_env`) but passes the remaining env vars (including provider API keys) to the server subprocess via `os.environ.copy()`.
168
168
  - **Access**: Available to both the CLI process and the server subprocess (which inherits the full environment minus stripped vars).
169
169
  - **Encryption**: Not encrypted — in-memory process environment only.
170
170
  - **Retention**: Process lifetime; cleared on CLI exit.
@@ -206,20 +206,20 @@
206
206
  | TB7 | External LLM API → Agent State | LLM API responses drive tool call decisions | LLM client configuration, model selection, request params | LLM output content; provider-side safety |
207
207
  | TB8 | CLI → Server Subprocess IPC | Config passed from CLI to `langgraph dev` subprocess via `DA_SERVER_*` env vars | `ServerConfig.to_env()` serialization; env var scoping to parent+child process | Subprocess environment post-fork; /proc visibility to same-uid processes |
208
208
  | TB9 | LocalContextMiddleware → Host Env | Bash detect script output (git info, project files, Makefile) injected into system prompt | Script is framework-generated static code; 30s timeout; exit-code check | Content of Makefile, pyproject.toml, git branch names, directory listing |
209
- | TB10 | RemoteAgent → LangGraph Dev Server | CLI communicates with agent via HTTP+SSE on localhost | Server bound to `127.0.0.1` (`server.py:_DEFAULT_HOST`); ephemeral per session | No authentication (`LANGGRAPH_AUTH_TYPE=noop`); any localhost process can reach the API |
209
+ | TB10 | RemoteAgent → LangGraph Dev Server | CLI communicates with agent via HTTP+SSE on localhost | Server bound to `127.0.0.1` (`client/launch/server.py:_DEFAULT_HOST`); ephemeral per session | No authentication (`LANGGRAPH_AUTH_TYPE=noop`); any localhost process can reach the API |
210
210
  | TB11 | Config File → Code Execution | `class_path` in `config.toml` triggers `importlib.import_module()`; project/global `.env` values are loaded into the process environment and can reach Bash startup hooks | Format validation (`module:ClassName`); `issubclass(BaseChatModel)` check; dotenv loading denies shell startup / environment-hijack keys (`BASH_ENV`, `ENV`) | Module-level side effects execute during import; user controls config file; project files in the working directory influence execution |
211
211
 
212
212
  ### Boundary Details
213
213
 
214
214
  #### TB1: User Input → Agent Engine
215
215
 
216
- - **Inside**: `app.DeepAgentsApp` routes keystrokes to message queue; `non_interactive.run_non_interactive` reads from stdin/argv. Both paths now go through `RemoteAgent.astream` to the server. Session ID assigned per thread (`sessions.generate_thread_id`).
216
+ - **Inside**: `app.DeepAgentsApp` routes keystrokes to message queue; `client.non_interactive.run_non_interactive` reads from stdin/argv. Both paths now go through `RemoteAgent.astream` to the server. Session ID assigned per thread (`sessions.generate_thread_id`).
217
217
  - **Outside**: Prompt content — the agent accepts any text the user types. No content filtering at this layer (HITL handles downstream tool calls, not prompt intent).
218
- - **Crossing mechanism**: HTTP POST to `127.0.0.1:{port}` via `remote_client.RemoteAgent.astream`.
218
+ - **Crossing mechanism**: HTTP POST to `127.0.0.1:{port}` via `client.remote_client.RemoteAgent.astream`.
219
219
 
220
220
  #### TB2: LLM Decision → Tool Execution Gate (HITL)
221
221
 
222
- - **Inside**: `agent._add_interrupt_on` registers interrupt configs for `execute`, `write_file`, `edit_file`, `web_search`, `fetch_url`, `task`, `compact_conversation`, `launch_async_subagent`, `update_async_subagent`, `cancel_async_subagent`. In non-interactive mode, `non_interactive._handle_action_request` enforces the shell allow-list via `config.is_shell_command_allowed`.
222
+ - **Inside**: `agent._add_interrupt_on` registers interrupt configs for `execute`, `write_file`, `edit_file`, `web_search`, `fetch_url`, `task`, `compact_conversation`, `launch_async_subagent`, `update_async_subagent`, `cancel_async_subagent`. In non-interactive mode, `client.non_interactive._handle_action_request` enforces the shell allow-list via `config.is_shell_command_allowed`.
223
223
  - **Outside**: Once the user clicks "approve" (interactive) or a command passes the allow-list check (non-interactive), the tool executes with no further framework-level gating.
224
224
  - **Crossing mechanism**: LangGraph HITL interrupt routed through `RemoteAgent` SSE stream.
225
225
  - **Key note**: `auto_approve` mode bypasses all HITL approval prompts while still displaying Unicode/URL warnings.
@@ -232,13 +232,13 @@
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
 
239
239
  #### TB8: CLI → Server Subprocess IPC
240
240
 
241
- - **Inside**: `ServerConfig.to_env()` serializes all config (model, assistant_id, system_prompt, sandbox settings, cwd, MCP config path, shell-enable flags) to `DA_SERVER_*` env vars. `server_manager._apply_server_config` writes these to `os.environ` before `subprocess.Popen`. `server.py:_build_server_env` strips cloud auth vars (`LANGGRAPH_CLOUD_LICENSE_KEY`, `LANGSMITH_CONTROL_PLANE_API_KEY`, `LANGSMITH_TENANT_ID`, `LANGGRAPH_AUTH`).
241
+ - **Inside**: `ServerConfig.to_env()` serializes all config (model, assistant_id, system_prompt, sandbox settings, cwd, MCP config path, shell-enable flags) to `DA_SERVER_*` env vars. `client.launch.server_manager._apply_server_config` writes these to `os.environ` before `subprocess.Popen`. `client/launch/server.py:_build_server_env` strips cloud auth vars (`LANGGRAPH_CLOUD_LICENSE_KEY`, `LANGSMITH_CONTROL_PLANE_API_KEY`, `LANGSMITH_TENANT_ID`, `LANGGRAPH_AUTH`).
242
242
  - **Outside**: The full parent environment including provider API keys flows to the child via `os.environ.copy()`. The system prompt string becomes `DA_SERVER_SYSTEM_PROMPT`. After process start, the env is fixed — no runtime mutation across processes.
243
243
  - **Crossing mechanism**: `subprocess.Popen` env kwarg; subsequent `os.environ` reads in `_server_config.ServerConfig.from_env`.
244
244
 
@@ -250,7 +250,7 @@
250
250
 
251
251
  #### TB10: RemoteAgent → LangGraph Dev Server
252
252
 
253
- - **Inside**: Server bound to `127.0.0.1` by default; `server.py:_DEFAULT_HOST = "127.0.0.1"`. `RemoteAgent` only connects to the URL returned by `ServerProcess.url`. Server is ephemeral — started at session start, stopped at session end. Binds a free ephemeral port by default (`server.py:_EPHEMERAL_PORT`); an explicit port is honored but still falls back to a free port if occupied.
253
+ - **Inside**: Server bound to `127.0.0.1` by default; `client/launch/server.py:_DEFAULT_HOST = "127.0.0.1"`. `RemoteAgent` only connects to the URL returned by `ServerProcess.url`. Server is ephemeral — started at session start, stopped at session end. Binds a free ephemeral port by default (`client/launch/server.py:_EPHEMERAL_PORT`); an explicit port is honored but still falls back to a free port if occupied.
254
254
  - **Outside**: `LANGGRAPH_AUTH_TYPE=noop` disables all LangGraph server authentication. Any process on localhost that discovers the port can submit requests, read thread state, or inject messages.
255
255
  - **Crossing mechanism**: HTTP POST/GET to `http://127.0.0.1:{port}` using `langgraph.pregel.remote.RemoteGraph`.
256
256
 
@@ -339,7 +339,7 @@
339
339
  | ID | Data Flow | Classification | Threat | Boundary | Severity | Validation | Code Reference |
340
340
  |-----|-----------|----------------|---------------------------------------------------------------------------------------------|----------|----------|------------|------------------------------------------------------------------------|
341
341
  | T1 | DF8, DF9 | — | Prompt injection via fetched web content causes LLM to request harmful actions | TB3 | Medium | Likely | `tools.fetch_url`, `agent._add_interrupt_on` |
342
- | T2 | DF7 | — | `--shell-allow-list all` removes pattern checks; LLM-injected shell commands execute without approval in non-interactive mode | TB2 | Medium | Verified | `config.is_shell_command_allowed`, `non_interactive._handle_action_request` |
342
+ | T2 | DF7 | — | `--shell-allow-list all` removes pattern checks; LLM-injected shell commands execute without approval in non-interactive mode | TB2 | Medium | Verified | `config.is_shell_command_allowed`, `client.non_interactive._handle_action_request` |
343
343
  | T3 | DF7 | — | Unicode-homoglyph URL in LLM-generated tool args deceives user during approval | TB2 | Low | Disproven | `unicode_security.check_url_safety`, `agent._format_fetch_url_description` |
344
344
  | T4 | DF5, DF9 | — | Auto-approve mode bypasses all HITL gates; any LLM-initiated tool call executes | TB2 | Low | Verified | `agent.create_cli_agent` (`auto_approve` param), `agent._add_interrupt_on` |
345
345
  | T5 | DF13, DF14| DC2 | Local SQLite checkpoint file tampered with to inject adversarial content into future LLM context | None | Low | Unverified | `sessions.get_db_path` |
@@ -385,7 +385,7 @@
385
385
  #### T6: Unauthenticated LangGraph Dev Server on Localhost
386
386
 
387
387
  - **Flow**: DF3/DF4 (CLI ↔ LangGraph dev server)
388
- - **Description**: The CLI spawns a `langgraph dev` server subprocess with `LANGGRAPH_AUTH_TYPE=noop` (`server.py:_build_server_env`). This disables all server-side authentication. The server binds to `127.0.0.1:{port}` (a free ephemeral port by default, so it no longer squats the well-known `langgraph dev` port 2024). Any local process that discovers the port can: send arbitrary inputs to the running agent thread, read the agent's conversation state (including tool results that may contain file contents or secrets), inject messages into the conversation history, or trigger state updates. The server is ephemeral — it lives only for the duration of the CLI session — but this is the entire attack window. Port discovery is feasible via localhost port scanning or by reading `/proc/{pid}/cmdline` which contains the `--port` argument.
388
+ - **Description**: The CLI spawns a `langgraph dev` server subprocess with `LANGGRAPH_AUTH_TYPE=noop` (`client/launch/server.py:_build_server_env`). This disables all server-side authentication. The server binds to `127.0.0.1:{port}` (a free ephemeral port by default, so it no longer squats the well-known `langgraph dev` port 2024). Any local process that discovers the port can: send arbitrary inputs to the running agent thread, read the agent's conversation state (including tool results that may contain file contents or secrets), inject messages into the conversation history, or trigger state updates. The server is ephemeral — it lives only for the duration of the CLI session — but this is the entire attack window. Port discovery is feasible via localhost port scanning or by reading `/proc/{pid}/cmdline` which contains the `--port` argument.
389
389
  - **Preconditions**: (1) Attacker has a local process running as the same user (or as root); (2) Attacker discovers the server port (port scan on localhost, or reads process arguments).
390
390
 
391
391
  #### T7: LocalContextMiddleware Injects Host File Contents into System Prompt
@@ -1,3 +1,3 @@
1
1
  """Generated at build time. Do not edit or commit."""
2
2
 
3
- BUILD_COMMIT = "9d4d7ba"
3
+ BUILD_COMMIT = "bd9bafa"
@@ -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,6 +1,8 @@
1
- """Lightweight session statistics and token formatting utilities.
1
+ """Lightweight session statistics, token formatting, and usage-table rendering.
2
2
 
3
- This module is intentionally kept free of heavy dependencies (no pydantic, no
3
+ Holds `SessionStats`/`ModelStats`, the `format_token_count` formatter, and
4
+ `print_usage_table` (which imports `rich.table` lazily). The module is
5
+ intentionally kept free of heavy top-level dependencies (no pydantic, no
4
6
  config, no widget imports) so that `app.py` can import `SessionStats` and
5
7
  `format_token_count` at module level without pulling in the full
6
8
  `textual_adapter` dependency tree.
@@ -9,7 +11,12 @@ config, no widget imports) so that `app.py` can import `SessionStats` and
9
11
  from __future__ import annotations
10
12
 
11
13
  from dataclasses import dataclass, field
12
- from typing import Literal
14
+ from typing import TYPE_CHECKING, Literal
15
+
16
+ from deepagents_code.formatting import format_duration
17
+
18
+ if TYPE_CHECKING:
19
+ from rich.console import Console
13
20
 
14
21
  SpinnerStatus = (
15
22
  Literal[
@@ -150,3 +157,79 @@ def format_token_count(count: int) -> str:
150
157
  if count >= 1000: # noqa: PLR2004
151
158
  return f"{count / 1000:.1f}K"
152
159
  return str(count)
160
+
161
+
162
+ def print_usage_table(
163
+ stats: SessionStats,
164
+ wall_time: float,
165
+ console: Console,
166
+ ) -> None:
167
+ """Print a model-usage stats table to a Rich console.
168
+
169
+ Each row shows the serving provider alongside the model name. When the
170
+ session spans multiple models each gets its own row with a totals row
171
+ appended; single-model sessions show one row.
172
+
173
+ Args:
174
+ stats: Cumulative session stats.
175
+ wall_time: Total wall-clock time in seconds.
176
+ console: Rich console for output.
177
+ """
178
+ from rich.table import Table
179
+
180
+ has_time = wall_time >= 0.1 # noqa: PLR2004
181
+ if not (stats.request_count or stats.input_tokens or has_time):
182
+ return
183
+
184
+ if stats.per_model:
185
+ multi_model = len(stats.per_model) > 1
186
+
187
+ table = Table(
188
+ show_header=True,
189
+ header_style="bold",
190
+ box=None,
191
+ padding=(0, 2, 0, 0),
192
+ show_edge=False,
193
+ )
194
+ table.add_column("Provider", style="dim")
195
+ table.add_column("Model", style="dim")
196
+ table.add_column("Reqs", justify="right", style="dim")
197
+ table.add_column("InputTok", justify="right", style="dim")
198
+ table.add_column("OutputTok", justify="right", style="dim")
199
+
200
+ if multi_model:
201
+ for ms in stats.per_model.values():
202
+ table.add_row(
203
+ ms.provider,
204
+ ms.model_name,
205
+ str(ms.request_count),
206
+ format_token_count(ms.input_tokens),
207
+ format_token_count(ms.output_tokens),
208
+ )
209
+ table.add_row(
210
+ "",
211
+ "Total",
212
+ str(stats.request_count),
213
+ format_token_count(stats.input_tokens),
214
+ format_token_count(stats.output_tokens),
215
+ )
216
+ else:
217
+ ms = next(iter(stats.per_model.values()))
218
+ table.add_row(
219
+ ms.provider,
220
+ ms.model_name,
221
+ str(stats.request_count),
222
+ format_token_count(stats.input_tokens),
223
+ format_token_count(stats.output_tokens),
224
+ )
225
+
226
+ console.print()
227
+ console.print("[bold]Usage Stats[/bold]")
228
+ console.print(table)
229
+ if has_time:
230
+ console.print()
231
+ console.print(
232
+ f"Agent active {format_duration(wall_time)}",
233
+ style="dim",
234
+ highlight=False,
235
+ )
@@ -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,