deepagents-code 0.1.72__tar.gz → 0.1.73__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 (563) hide show
  1. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/CHANGELOG.md +23 -0
  2. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/PKG-INFO +15 -15
  3. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_build_info.py +1 -1
  4. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_dep_floor_check.py +4 -1
  5. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_paths.py +6 -1
  6. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_server_config.py +129 -2
  7. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_session_stats.py +165 -80
  8. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_version.py +1 -1
  9. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/agent.py +130 -13
  10. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/app.py +289 -27
  11. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/auto_mode.py +243 -114
  12. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +8 -4
  13. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +1 -1
  14. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/client/non_interactive.py +3 -3
  15. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/client/remote_client.py +37 -2
  16. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/cold_cache.py +44 -1
  17. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/config.py +1 -1
  18. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/configurable_model.py +41 -2
  19. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/cost_tracking.py +682 -57
  20. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/integrations/sandbox_factory.py +9 -9
  21. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/offload_api.py +19 -2
  22. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/offload_middleware.py +1 -0
  23. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/resume_state.py +8 -0
  24. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/server_graph.py +191 -23
  25. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/skills/commands.py +1 -1
  26. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/system_prompt.md +6 -26
  27. deepagents_code-0.1.73/deepagents_code/tui/modals/cost_breakdown.py +95 -0
  28. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/modals/resume_compact.py +5 -3
  29. deepagents_code-0.1.73/deepagents_code/tui/modals/session_cost.py +69 -0
  30. deepagents_code-0.1.73/deepagents_code/tui/modals/session_cost.tcss +32 -0
  31. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/textual_adapter.py +151 -7
  32. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/debug_console.py +70 -2
  33. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/status.py +90 -2
  34. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/thread_selector.py +23 -4
  35. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/update_check.py +78 -39
  36. deepagents_code-0.1.73/deepagents_code/workspace.py +861 -0
  37. deepagents_code-0.1.73/deepagents_code/workspace_diagnostics.py +438 -0
  38. deepagents_code-0.1.73/images/debug-console-cost-breakdown.png +0 -0
  39. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/pyproject.toml +10 -10
  40. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/scripts/install.sh +41 -5
  41. deepagents_code-0.1.73/tests/unit_tests/smoke_tests/snapshots/system_prompt_headless_local.md +297 -0
  42. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/smoke_tests/snapshots/system_prompt_interactive_local.md +2 -3
  43. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/smoke_tests/test_system_prompt.py +75 -13
  44. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_agent.py +84 -0
  45. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_app.py +610 -0
  46. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_auto_mode.py +1009 -69
  47. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_configurable_model.py +88 -1
  48. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_cost_tracking.py +712 -10
  49. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_debug_console.py +59 -6
  50. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_dep_floor_check.py +9 -7
  51. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_install_script.py +310 -62
  52. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_non_interactive.py +26 -12
  53. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_offload_api.py +77 -0
  54. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_paths.py +12 -0
  55. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_remote_client.py +27 -0
  56. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_resume_state.py +50 -0
  57. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_sandbox_factory.py +132 -1
  58. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_server_config.py +62 -0
  59. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_server_graph.py +90 -5
  60. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_session_stats.py +146 -11
  61. deepagents_code-0.1.73/tests/unit_tests/test_text_encoding.py +130 -0
  62. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_update_check.py +200 -0
  63. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_workspace.py +109 -3
  64. deepagents_code-0.1.73/tests/unit_tests/test_workspace_diagnostics.py +309 -0
  65. deepagents_code-0.1.73/tests/unit_tests/tui/modals/test_session_cost.py +24 -0
  66. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/test_textual_adapter.py +332 -12
  67. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_status.py +58 -0
  68. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_thread_selector.py +18 -0
  69. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/uv.lock +43 -43
  70. deepagents_code-0.1.72/deepagents_code/workspace.py +0 -497
  71. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/.gitignore +0 -0
  72. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/AGENTS.md +0 -0
  73. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/ARCHITECTURE.md +0 -0
  74. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/COMMANDS.md +0 -0
  75. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/DEVELOPMENT.md +0 -0
  76. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/EXTENSIONS.md +0 -0
  77. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/HOOKS.md +0 -0
  78. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/LICENSE +0 -0
  79. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/Makefile +0 -0
  80. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/PRICING.md +0 -0
  81. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/README.md +0 -0
  82. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/THREAT_MODEL.md +0 -0
  83. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/__init__.py +0 -0
  84. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/__main__.py +0 -0
  85. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_ask_user_types.py +0 -0
  86. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_cli_context.py +0 -0
  87. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_constants.py +0 -0
  88. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_content_blocks.py +0 -0
  89. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_debug.py +0 -0
  90. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_debug_buffer.py +0 -0
  91. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_env_vars.py +0 -0
  92. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_fake_models.py +0 -0
  93. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_git.py +0 -0
  94. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_glm_5p2_profile.py +0 -0
  95. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_home_error.py +0 -0
  96. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_invocation.py +0 -0
  97. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_markdown.py +0 -0
  98. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_repository_bounds.py +0 -0
  99. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_reserved_names.py +0 -0
  100. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_startup_error.py +0 -0
  101. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_terminal_stderr.py +0 -0
  102. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_testing_models.py +0 -0
  103. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_textual_patches.py +0 -0
  104. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_tool_stream.py +0 -0
  105. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/_tracing.py +0 -0
  106. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/acp.py +0 -0
  107. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/app.tcss +0 -0
  108. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/approval_mode.py +0 -0
  109. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/ask_user.py +0 -0
  110. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/auth_display.py +0 -0
  111. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/auth_store.py +0 -0
  112. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/built_in_skills/__init__.py +0 -0
  113. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/built_in_skills/deepagents-thread-inspector/SKILL.md +0 -0
  114. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/built_in_skills/deepagents-thread-inspector/scripts/inspect_sessions.py +0 -0
  115. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/built_in_skills/remember/SKILL.md +0 -0
  116. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/built_in_skills/skill-creator/SKILL.md +0 -0
  117. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/bundled_prices.README.md +0 -0
  118. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/bundled_prices.json +0 -0
  119. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/client/__init__.py +0 -0
  120. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/client/commands/__init__.py +0 -0
  121. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/client/commands/auth.py +0 -0
  122. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/client/commands/config.py +0 -0
  123. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/client/commands/extras.py +0 -0
  124. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/client/commands/mcp.py +0 -0
  125. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/client/commands/tools.py +0 -0
  126. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/client/launch/__init__.py +0 -0
  127. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/client/launch/server.py +0 -0
  128. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/client/launch/server_manager.py +0 -0
  129. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/clipboard.py +0 -0
  130. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/command_registry.py +0 -0
  131. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/config_manifest.py +0 -0
  132. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/configuration/__init__.py +0 -0
  133. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/configuration/interpreter.py +0 -0
  134. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/configuration/paths.py +0 -0
  135. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/configuration/provider.py +0 -0
  136. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/configuration/providers.py +0 -0
  137. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/configuration/resolver.py +0 -0
  138. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/configuration/service.py +0 -0
  139. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/configuration/theme_resolution.py +0 -0
  140. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/configuration/types.py +0 -0
  141. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/configuration/writer.py +0 -0
  142. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/context_doctor.py +0 -0
  143. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/default_agent_prompt.md +0 -0
  144. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/diff_utils.py +0 -0
  145. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/doctor.py +0 -0
  146. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/editor.py +0 -0
  147. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/event_bus.py +0 -0
  148. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/extensions/__init__.py +0 -0
  149. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/extensions/api.py +0 -0
  150. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/extensions/discovery.py +0 -0
  151. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/extensions/hosting.py +0 -0
  152. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/extensions/loader.py +0 -0
  153. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/extensions/registry.py +0 -0
  154. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/extensions/runtime.py +0 -0
  155. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/extensions/settings.py +0 -0
  156. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/extensions/trust.py +0 -0
  157. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/extras_info.py +0 -0
  158. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/file_ops.py +0 -0
  159. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/formatting.py +0 -0
  160. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/goal_rubric.py +0 -0
  161. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/goal_state_limits.py +0 -0
  162. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/goal_state_notice.py +0 -0
  163. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/goal_tools.py +0 -0
  164. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/__init__.py +0 -0
  165. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/capabilities.py +0 -0
  166. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/client.py +0 -0
  167. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/client_lifecycle.py +0 -0
  168. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/context.py +0 -0
  169. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/engine.py +0 -0
  170. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/env.py +0 -0
  171. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/envelope.py +0 -0
  172. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/interrupt.py +0 -0
  173. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/legacy.py +0 -0
  174. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/loading.py +0 -0
  175. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/manager.py +0 -0
  176. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/migration.py +0 -0
  177. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/models/__init__.py +0 -0
  178. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/models/adapters.py +0 -0
  179. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/models/config.py +0 -0
  180. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/models/domain.py +0 -0
  181. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/models/transport.py +0 -0
  182. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/models/wire.py +0 -0
  183. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/permissions.py +0 -0
  184. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/presenter.py +0 -0
  185. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/projection.py +0 -0
  186. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/reducer.py +0 -0
  187. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/runner.py +0 -0
  188. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/runtime.py +0 -0
  189. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/server_middleware.py +0 -0
  190. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/snapshot.py +0 -0
  191. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/tools.py +0 -0
  192. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/transcript.py +0 -0
  193. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/trust.py +0 -0
  194. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/hooks/validate_terminal_sequence.py +0 -0
  195. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/input.py +0 -0
  196. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/integrations/__init__.py +0 -0
  197. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/integrations/openai_codex.py +0 -0
  198. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/integrations/sandbox_config.py +0 -0
  199. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/integrations/sandbox_provider.py +0 -0
  200. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/integrations/sandbox_registry.py +0 -0
  201. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/iterm_cursor_guide.py +0 -0
  202. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/json_types.py +0 -0
  203. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/local_context.py +0 -0
  204. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/main.py +0 -0
  205. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/managed_tools.py +0 -0
  206. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/mcp_auth.py +0 -0
  207. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/mcp_config.py +0 -0
  208. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/mcp_disabled.py +0 -0
  209. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/mcp_login_service.py +0 -0
  210. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/mcp_middleware.py +0 -0
  211. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/mcp_oauth_ui.py +0 -0
  212. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/mcp_providers/__init__.py +0 -0
  213. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/mcp_providers/_registry.py +0 -0
  214. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/mcp_providers/base.py +0 -0
  215. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/mcp_providers/github.py +0 -0
  216. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/mcp_providers/slack.py +0 -0
  217. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/mcp_proxy.py +0 -0
  218. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/mcp_tools.py +0 -0
  219. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/media_utils.py +0 -0
  220. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/memory_guard.py +0 -0
  221. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/model_config.py +0 -0
  222. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/model_retry.py +0 -0
  223. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/notifications.py +0 -0
  224. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/offload.py +0 -0
  225. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/onboarding.py +0 -0
  226. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/output.py +0 -0
  227. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/paste_collapse.py +0 -0
  228. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/plugins/__init__.py +0 -0
  229. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/plugins/_json.py +0 -0
  230. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/plugins/adapters/__init__.py +0 -0
  231. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/plugins/adapters/hooks.py +0 -0
  232. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/plugins/adapters/mcp.py +0 -0
  233. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/plugins/adapters/skills.py +0 -0
  234. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/plugins/adapters/skills_middleware.py +0 -0
  235. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/plugins/commands_cli.py +0 -0
  236. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/plugins/discovery.py +0 -0
  237. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/plugins/manifest.py +0 -0
  238. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/plugins/marketplace.py +0 -0
  239. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/plugins/models.py +0 -0
  240. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/plugins/store.py +0 -0
  241. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/plugins/substitution.py +0 -0
  242. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/project_utils.py +0 -0
  243. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/py.typed +0 -0
  244. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/reasoning_effort.py +0 -0
  245. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/reliable_rubric.py +0 -0
  246. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/sessions.py +0 -0
  247. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/skills/__init__.py +0 -0
  248. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/skills/invocation.py +0 -0
  249. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/skills/load.py +0 -0
  250. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/skills/merge.py +0 -0
  251. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/skills/trust.py +0 -0
  252. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/state_migration.py +0 -0
  253. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/subagents.py +0 -0
  254. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/terminal_capabilities.py +0 -0
  255. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/terminal_escape.py +0 -0
  256. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/theme.py +0 -0
  257. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tool_catalog.py +0 -0
  258. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tool_display.py +0 -0
  259. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tools.py +0 -0
  260. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/__init__.py +0 -0
  261. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/key_hints.py +0 -0
  262. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/modals/__init__.py +0 -0
  263. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/modals/cold_cache.py +0 -0
  264. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/modals/model_switch.py +0 -0
  265. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/modals/plugin_manager/__init__.py +0 -0
  266. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/modals/plugin_manager/content.py +0 -0
  267. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/modals/plugin_manager/models.py +0 -0
  268. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/modals/plugin_manager/plugin_manager.tcss +0 -0
  269. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/modals/plugin_manager/state.py +0 -0
  270. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/modals/plugin_manager/tabs.py +0 -0
  271. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/modals/prompt_clipboard.py +0 -0
  272. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/modals/prompt_clipboard.tcss +0 -0
  273. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/modals/resume_blocked.py +0 -0
  274. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/screens/__init__.py +0 -0
  275. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/__init__.py +0 -0
  276. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/_condense_path.py +0 -0
  277. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/_copy_spans.py +0 -0
  278. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/_inline_prompt.py +0 -0
  279. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/_js_eval_display.py +0 -0
  280. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/_links.py +0 -0
  281. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/_paste_textarea.py +0 -0
  282. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/agent_selector.py +0 -0
  283. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/approval.py +0 -0
  284. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/ask_user.py +0 -0
  285. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/auth.py +0 -0
  286. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/auto_mode_notice.py +0 -0
  287. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/autocomplete.py +0 -0
  288. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/chat_input.py +0 -0
  289. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/codex_auth.py +0 -0
  290. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/context_usage.py +0 -0
  291. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/cwd_switch.py +0 -0
  292. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/diff.py +0 -0
  293. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/effort_selector.py +0 -0
  294. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/goal_review.py +0 -0
  295. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/goal_status.py +0 -0
  296. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/history.py +0 -0
  297. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/install_confirm.py +0 -0
  298. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/launch_init.py +0 -0
  299. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/loading.py +0 -0
  300. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/mcp_login.py +0 -0
  301. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/mcp_reconnect.py +0 -0
  302. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/mcp_viewer.py +0 -0
  303. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/message_store.py +0 -0
  304. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/messages.py +0 -0
  305. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/model_selector.py +0 -0
  306. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/notification_center.py +0 -0
  307. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/notification_detail.py +0 -0
  308. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/notification_settings.py +0 -0
  309. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/prompt_search.py +0 -0
  310. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/restart_prompt.py +0 -0
  311. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/skill_trust.py +0 -0
  312. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/startup_tip.py +0 -0
  313. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/subagent_panel.py +0 -0
  314. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/theme_selector.py +0 -0
  315. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/thread_agent_switch.py +0 -0
  316. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/tool_renderers.py +0 -0
  317. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/tool_widgets.py +0 -0
  318. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/update_available.py +0 -0
  319. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/update_confirm.py +0 -0
  320. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/update_progress.py +0 -0
  321. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/welcome.py +0 -0
  322. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/tui/widgets/yolo_mode_notice.py +0 -0
  323. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/ui.py +0 -0
  324. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/deepagents_code/unicode_security.py +0 -0
  325. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/examples/extensions/memory_store.py +0 -0
  326. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/examples/skills/arxiv-search/SKILL.md +0 -0
  327. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/examples/skills/arxiv-search/arxiv_search.py +0 -0
  328. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/examples/skills/langgraph-docs/SKILL.md +0 -0
  329. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/examples/skills/skill-creator/SKILL.md +0 -0
  330. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
  331. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
  332. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/examples/skills/web-research/SKILL.md +0 -0
  333. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/hatch_build.py +0 -0
  334. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/images/model-stream-retry.png +0 -0
  335. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/images/tui.png +0 -0
  336. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/scripts/check_imports.py +0 -0
  337. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/scripts/check_process_cwd.py +0 -0
  338. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/scripts/debug_server.sh +0 -0
  339. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/scripts/generate_commands_catalog.py +0 -0
  340. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/README.md +0 -0
  341. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/integration_tests/__init__.py +0 -0
  342. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/integration_tests/benchmarks/__init__.py +0 -0
  343. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
  344. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/integration_tests/benchmarks/test_local_context_benchmarks.py +0 -0
  345. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
  346. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/integration_tests/conftest.py +0 -0
  347. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/integration_tests/test_acp_mode.py +0 -0
  348. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/integration_tests/test_auto_approve_remote.py +0 -0
  349. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/integration_tests/test_compact_resume.py +0 -0
  350. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/integration_tests/test_offload_server_side.py +0 -0
  351. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/integration_tests/test_pending_work_recovery.py +0 -0
  352. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/integration_tests/test_sandbox_factory.py +0 -0
  353. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/integration_tests/test_sandbox_operations.py +0 -0
  354. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/__init__.py +0 -0
  355. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/client/__init__.py +0 -0
  356. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/client/commands/__init__.py +0 -0
  357. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/client/commands/test_auth.py +0 -0
  358. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/client/commands/test_extras.py +0 -0
  359. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/client/commands/test_mcp.py +0 -0
  360. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/client/commands/test_tools.py +0 -0
  361. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/conftest.py +0 -0
  362. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/data/coding_agent_v1_validator.json +0 -0
  363. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/hooks/__init__.py +0 -0
  364. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/hooks/models/__init__.py +0 -0
  365. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/hooks/models/test_models.py +0 -0
  366. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/hooks/test_client_lifecycle.py +0 -0
  367. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/hooks/test_configuration.py +0 -0
  368. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/hooks/test_engine.py +0 -0
  369. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/hooks/test_execution.py +0 -0
  370. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/hooks/test_manager.py +0 -0
  371. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/hooks/test_presenter.py +0 -0
  372. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/hooks/test_server_lifecycle.py +0 -0
  373. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/hooks/test_transcript.py +0 -0
  374. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/hooks/test_trust.py +0 -0
  375. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/plugins/__init__.py +0 -0
  376. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/plugins/test_marketplace.py +0 -0
  377. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/plugins/test_plugin_hooks.py +0 -0
  378. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/plugins/test_plugins_p0.py +0 -0
  379. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/skills/__init__.py +0 -0
  380. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/skills/test_commands.py +0 -0
  381. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/skills/test_load.py +0 -0
  382. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/skills/test_merge.py +0 -0
  383. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/skills/test_skill_trust.py +0 -0
  384. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/skills/test_skills_json.py +0 -0
  385. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/skills/test_thread_inspector.py +0 -0
  386. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/smoke_tests/__init__.py +0 -0
  387. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/smoke_tests/conftest.py +0 -0
  388. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test__tool_stream.py +0 -0
  389. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_acp.py +0 -0
  390. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_agent_friendly.py +0 -0
  391. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_approval_mode.py +0 -0
  392. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_args.py +0 -0
  393. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_ask_user_middleware.py +0 -0
  394. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_ask_user_types.py +0 -0
  395. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_auth_display.py +0 -0
  396. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_auth_store.py +0 -0
  397. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_auth_web_search_restart.py +0 -0
  398. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_charset.py +0 -0
  399. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_cli_provider.py +0 -0
  400. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_clipboard.py +0 -0
  401. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_coding_agent_metadata.py +0 -0
  402. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_cold_cache.py +0 -0
  403. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_command_registry.py +0 -0
  404. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_compact_tool.py +0 -0
  405. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_config.py +0 -0
  406. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_config_manifest.py +0 -0
  407. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_configuration.py +0 -0
  408. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_configuration_resolution.py +0 -0
  409. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_configuration_resolver.py +0 -0
  410. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_context_doctor.py +0 -0
  411. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_cursor_style.py +0 -0
  412. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_debug.py +0 -0
  413. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_debug_buffer.py +0 -0
  414. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_diff_utils.py +0 -0
  415. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_doctor.py +0 -0
  416. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_editor.py +0 -0
  417. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_end_to_end.py +0 -0
  418. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_env_vars.py +0 -0
  419. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_event_bus.py +0 -0
  420. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_exception_handling.py +0 -0
  421. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_extension_api.py +0 -0
  422. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_extension_cli_trust.py +0 -0
  423. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_extension_config_manifest.py +0 -0
  424. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_extension_discovery.py +0 -0
  425. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_extension_display.py +0 -0
  426. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_extension_host_runtime.py +0 -0
  427. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_extension_hosting.py +0 -0
  428. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_extension_runtime.py +0 -0
  429. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_extra_skills_dirs.py +0 -0
  430. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_extras_info.py +0 -0
  431. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_file_ops.py +0 -0
  432. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_formatting.py +0 -0
  433. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_git.py +0 -0
  434. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_glm_5p2_profile.py +0 -0
  435. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_goal_criteria_client.py +0 -0
  436. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_goal_rubric.py +0 -0
  437. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_goal_state_limits.py +0 -0
  438. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_goal_state_notice.py +0 -0
  439. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_goal_state_persistence.py +0 -0
  440. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_goal_tools.py +0 -0
  441. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_hatch_build.py +0 -0
  442. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_hooks.py +0 -0
  443. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_imports.py +0 -0
  444. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_input_parsing.py +0 -0
  445. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_install_command.py +0 -0
  446. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_invocation.py +0 -0
  447. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
  448. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_json_types.py +0 -0
  449. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_local_context.py +0 -0
  450. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_main.py +0 -0
  451. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_main_acp_mode.py +0 -0
  452. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_main_args.py +0 -0
  453. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_managed_tools.py +0 -0
  454. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_mcp_auth.py +0 -0
  455. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_mcp_config.py +0 -0
  456. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_mcp_disabled.py +0 -0
  457. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_mcp_lifecycle.py +0 -0
  458. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_mcp_login_service.py +0 -0
  459. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_mcp_oauth_ui.py +0 -0
  460. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_mcp_proxy.py +0 -0
  461. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_mcp_schema.py +0 -0
  462. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_mcp_tools.py +0 -0
  463. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_media_utils.py +0 -0
  464. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_memory_guard.py +0 -0
  465. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_model_config.py +0 -0
  466. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_model_retry.py +0 -0
  467. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_model_switch.py +0 -0
  468. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_notifications.py +0 -0
  469. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_offload.py +0 -0
  470. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_onboarding.py +0 -0
  471. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_openai_codex_integration.py +0 -0
  472. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_output.py +0 -0
  473. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_process_cwd_check.py +0 -0
  474. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_reasoning_effort.py +0 -0
  475. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_reliable_rubric.py +0 -0
  476. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_reload.py +0 -0
  477. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_repository_bounds.py +0 -0
  478. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_resume_compaction_recovery.py +0 -0
  479. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_rubric_cli.py +0 -0
  480. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_sandbox_config.py +0 -0
  481. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_sandbox_provider.py +0 -0
  482. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_sandbox_registry.py +0 -0
  483. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_server.py +0 -0
  484. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_server_helpers.py +0 -0
  485. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_server_manager.py +0 -0
  486. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_server_tracing.py +0 -0
  487. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_sessions.py +0 -0
  488. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_shell_allow_list.py +0 -0
  489. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_skill_invocation.py +0 -0
  490. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_startup_fast_paths.py +0 -0
  491. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_state_migration.py +0 -0
  492. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_subagents.py +0 -0
  493. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_terminal_capabilities.py +0 -0
  494. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_terminal_escape.py +0 -0
  495. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_terminal_progress_preference.py +0 -0
  496. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_terminal_stderr.py +0 -0
  497. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_textual_patches.py +0 -0
  498. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_theme.py +0 -0
  499. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_threads_resume.py +0 -0
  500. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_tool_catalog.py +0 -0
  501. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_tool_display.py +0 -0
  502. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_tracing.py +0 -0
  503. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_tracing_replicas.py +0 -0
  504. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_transcript_virtualization.py +0 -0
  505. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_ui.py +0 -0
  506. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_unicode_security.py +0 -0
  507. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_uninstall_command.py +0 -0
  508. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/test_version.py +0 -0
  509. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tools/__init__.py +0 -0
  510. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tools/test_current_thread.py +0 -0
  511. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tools/test_fetch_url.py +0 -0
  512. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tools/test_tool_arg_schemas.py +0 -0
  513. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tools/test_web_search.py +0 -0
  514. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/__init__.py +0 -0
  515. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/modals/__init__.py +0 -0
  516. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/modals/plugin_manager/__init__.py +0 -0
  517. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/modals/plugin_manager/test_structure.py +0 -0
  518. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/modals/test_cold_cache.py +0 -0
  519. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/modals/test_model_switch.py +0 -0
  520. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/modals/test_prompt_clipboard.py +0 -0
  521. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/modals/test_resume_blocked.py +0 -0
  522. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/test_key_hints.py +0 -0
  523. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/test_modal_footer_layout.py +0 -0
  524. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/test_subagent_stream.py +0 -0
  525. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/__init__.py +0 -0
  526. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_agent_selector.py +0 -0
  527. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_approval.py +0 -0
  528. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_ask_user.py +0 -0
  529. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_auth_widgets.py +0 -0
  530. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_auto_mode_notice.py +0 -0
  531. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_autocomplete.py +0 -0
  532. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_chat_input.py +0 -0
  533. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_condense_path.py +0 -0
  534. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_copy_spans.py +0 -0
  535. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_cwd_switch.py +0 -0
  536. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_diff.py +0 -0
  537. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_goal_review.py +0 -0
  538. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_history.py +0 -0
  539. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_inline_prompt.py +0 -0
  540. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_install_confirm.py +0 -0
  541. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_launch_init.py +0 -0
  542. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_links.py +0 -0
  543. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_loading.py +0 -0
  544. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_mcp_login_modal.py +0 -0
  545. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_mcp_reconnect.py +0 -0
  546. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_mcp_viewer.py +0 -0
  547. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_message_store.py +0 -0
  548. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_messages.py +0 -0
  549. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_model_selector.py +0 -0
  550. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_notification_center.py +0 -0
  551. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_notification_detail.py +0 -0
  552. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_notification_settings.py +0 -0
  553. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_prompt_search.py +0 -0
  554. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_restart_prompt.py +0 -0
  555. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_skill_trust_screen.py +0 -0
  556. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_startup_tip.py +0 -0
  557. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_subagent_panel.py +0 -0
  558. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_thread_agent_switch.py +0 -0
  559. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_tool_renderers.py +0 -0
  560. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_update_available.py +0 -0
  561. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_update_confirm.py +0 -0
  562. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_update_progress.py +0 -0
  563. {deepagents_code-0.1.72 → deepagents_code-0.1.73}/tests/unit_tests/tui/widgets/test_welcome.py +0 -0
@@ -2,6 +2,29 @@
2
2
 
3
3
  # Deep Agents Code Changelog
4
4
 
5
+ ## [0.1.73](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.72...deepagents-code==0.1.73) (2026-09-22)
6
+
7
+ ### Features
8
+
9
+ - Added cache bust timer to the footer. ([#6394](https://github.com/langchain-ai/deepagents/pull/6394))
10
+ - Added a durable Debug Console cost breakdown. ([#6246](https://github.com/langchain-ai/deepagents/pull/6246))
11
+ - Added support for copying the highlighted thread ID with `Ctrl+C`. ([#6431](https://github.com/langchain-ai/deepagents/pull/6431))
12
+
13
+ ### Bug Fixes
14
+
15
+ - Improved cost-warning behavior by showing session cost warnings in a modal and suppressing historical cost warnings when resuming. ([#6393](https://github.com/langchain-ai/deepagents/pull/6393), [#6471](https://github.com/langchain-ai/deepagents/pull/6471))
16
+ - Made thread browsing and resume flows more resilient with recoverable thread-picker resume failures, loading labels for thread details, and a clearer thread message count header. ([#6476](https://github.com/langchain-ai/deepagents/pull/6476), [#6430](https://github.com/langchain-ai/deepagents/pull/6430), [#6428](https://github.com/langchain-ai/deepagents/pull/6428))
17
+ - Removed contradictory and invalid system-prompt instructions. ([#6072](https://github.com/langchain-ai/deepagents/pull/6072))
18
+ - Preserved `ask_user` consent receipts across user turns and reconciled interrupted tool requests. ([#6307](https://github.com/langchain-ai/deepagents/pull/6307), [#6321](https://github.com/langchain-ai/deepagents/pull/6321))
19
+ - Cleaned up newly created sandboxes when setup fails. ([#6475](https://github.com/langchain-ai/deepagents/pull/6475))
20
+ - Fixed editable refreshes so they stay anchored to the correct checkout. ([#6455](https://github.com/langchain-ai/deepagents/pull/6455))
21
+ - Kept installation locks outside the uv tool directory. ([#6472](https://github.com/langchain-ai/deepagents/pull/6472))
22
+ - Improved workspace and runtime diagnostics, including separating access-policy compatibility from runtime identity. ([#6384](https://github.com/langchain-ai/deepagents/pull/6384), [#6386](https://github.com/langchain-ai/deepagents/pull/6386))
23
+ - Deduplicated mixed-ID model usage. ([#6432](https://github.com/langchain-ai/deepagents/pull/6432))
24
+ - Clarified the compaction prompt. ([#6429](https://github.com/langchain-ai/deepagents/pull/6429))
25
+ - Restricted auto classifier IDs to the review batch enum. ([#6250](https://github.com/langchain-ai/deepagents/pull/6250))
26
+ - Used UTF-8 for prompts and skill files. ([#6474](https://github.com/langchain-ai/deepagents/pull/6474))
27
+
5
28
  ## [0.1.72](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.71...deepagents-code==0.1.72) (2026-09-21)
6
29
 
7
30
  ### Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: deepagents-code
3
- Version: 0.1.72
3
+ Version: 0.1.73
4
4
  Summary: Terminal coding agent built on the Deep Agents SDK - works with any model, with persistent memory, customizable skills, subagents, and approval controls.
5
5
  Project-URL: Homepage, https://www.langchain.com/dcode
6
6
  Project-URL: Documentation, https://docs.langchain.com/oss/deepagents/code/overview
@@ -30,21 +30,21 @@ Requires-Python: <4.0,>=3.12
30
30
  Requires-Dist: aiosqlite<1.0.0,>=0.22.1
31
31
  Requires-Dist: anyio<5.0.0,>=4.14.2
32
32
  Requires-Dist: deepagents-acp<1.0.0,>=0.0.10
33
- Requires-Dist: deepagents==0.7.15
33
+ Requires-Dist: deepagents==0.7.17
34
34
  Requires-Dist: fastmcp<5.0.0,>=4.0.0b4
35
35
  Requires-Dist: filelock<3.30,>=3.29.7
36
36
  Requires-Dist: genai-prices<0.2.0,>=0.1.7
37
37
  Requires-Dist: httpx<1.0.0,>=0.28.1
38
38
  Requires-Dist: langchain-anthropic<2.0.0,>=1.7.2
39
39
  Requires-Dist: langchain-google-genai<5.0.0,>=4.4.0
40
- Requires-Dist: langchain-openai<2.0.0,>=1.6.2
40
+ Requires-Dist: langchain-openai<2.0.0,>=1.6.3
41
41
  Requires-Dist: langchain-quickjs<0.4.0,>=0.3.4
42
42
  Requires-Dist: langchain<2.0.0,>=1.4.2
43
43
  Requires-Dist: langgraph-checkpoint-sqlite<4.0.0,>=3.1.1
44
44
  Requires-Dist: langgraph-cli[inmem]<1.0.0,>=0.4.31
45
45
  Requires-Dist: langgraph-runtime-inmem<1.0.0,>=0.34.1
46
- Requires-Dist: langgraph-sdk<1.0.0,>=0.4.4
47
- Requires-Dist: langsmith[sandbox]>=0.13.0
46
+ Requires-Dist: langgraph-sdk<1.0.0,>=0.4.5
47
+ Requires-Dist: langsmith[sandbox]>=0.14.0
48
48
  Requires-Dist: markdownify<2.0.0,>=1.2.3
49
49
  Requires-Dist: mcp<3.0.0,>=2.0.0
50
50
  Requires-Dist: packaging>=26.2
@@ -67,11 +67,11 @@ Requires-Dist: langchain-agentcore-codeinterpreter<1.0.0,>=0.0.5; extra == 'agen
67
67
  Provides-Extra: all-providers
68
68
  Requires-Dist: aiohttp<3.15.0,>=3.14.3; extra == 'all-providers'
69
69
  Requires-Dist: langchain-anthropic<2.0.0,>=1.7.2; extra == 'all-providers'
70
- Requires-Dist: langchain-aws<2.0.0,>=1.7.8; extra == 'all-providers'
70
+ Requires-Dist: langchain-aws<2.0.0,>=1.7.9; extra == 'all-providers'
71
71
  Requires-Dist: langchain-baseten<1.0.0,>=0.2.4; extra == 'all-providers'
72
72
  Requires-Dist: langchain-cohere<1.0.0,>=0.6.0; extra == 'all-providers'
73
- Requires-Dist: langchain-deepseek<2.0.0,>=1.1.0; extra == 'all-providers'
74
- Requires-Dist: langchain-fireworks<2.0.0,>=1.6.1; extra == 'all-providers'
73
+ Requires-Dist: langchain-deepseek<2.0.0,>=1.1.1; extra == 'all-providers'
74
+ Requires-Dist: langchain-fireworks<2.0.0,>=1.6.2; extra == 'all-providers'
75
75
  Requires-Dist: langchain-google-genai<5.0.0,>=4.4.0; extra == 'all-providers'
76
76
  Requires-Dist: langchain-google-vertexai<4.0.0,>=3.2.4; extra == 'all-providers'
77
77
  Requires-Dist: langchain-groq<2.0.0,>=1.1.3; extra == 'all-providers'
@@ -82,8 +82,8 @@ Requires-Dist: langchain-meta<2.0.0,>=0.5.0; extra == 'all-providers'
82
82
  Requires-Dist: langchain-mistralai<2.0.0,>=1.1.6; extra == 'all-providers'
83
83
  Requires-Dist: langchain-nvidia-ai-endpoints<2.0.0,>=1.4.3; extra == 'all-providers'
84
84
  Requires-Dist: langchain-ollama<2.0.0,>=1.1.0; extra == 'all-providers'
85
- Requires-Dist: langchain-openai<2.0.0,>=1.6.2; extra == 'all-providers'
86
- Requires-Dist: langchain-openrouter<2.0.0,>=0.2.8; extra == 'all-providers'
85
+ Requires-Dist: langchain-openai<2.0.0,>=1.6.3; extra == 'all-providers'
86
+ Requires-Dist: langchain-openrouter<2.0.0,>=0.2.9; extra == 'all-providers'
87
87
  Requires-Dist: langchain-perplexity<2.0.0,>=1.4.1; extra == 'all-providers'
88
88
  Requires-Dist: langchain-together<2.0.0,>=0.4.0; extra == 'all-providers'
89
89
  Requires-Dist: langchain-xai<2.0.0,>=1.3.0; extra == 'all-providers'
@@ -98,15 +98,15 @@ Requires-Dist: langchain-anthropic<2.0.0,>=1.7.2; extra == 'anthropic'
98
98
  Provides-Extra: baseten
99
99
  Requires-Dist: langchain-baseten<1.0.0,>=0.2.4; extra == 'baseten'
100
100
  Provides-Extra: bedrock
101
- Requires-Dist: langchain-aws<2.0.0,>=1.7.8; extra == 'bedrock'
101
+ Requires-Dist: langchain-aws<2.0.0,>=1.7.9; extra == 'bedrock'
102
102
  Provides-Extra: cohere
103
103
  Requires-Dist: langchain-cohere<1.0.0,>=0.6.0; extra == 'cohere'
104
104
  Provides-Extra: daytona
105
105
  Requires-Dist: langchain-daytona>=0.0.7; extra == 'daytona'
106
106
  Provides-Extra: deepseek
107
- Requires-Dist: langchain-deepseek<2.0.0,>=1.1.0; extra == 'deepseek'
107
+ Requires-Dist: langchain-deepseek<2.0.0,>=1.1.1; extra == 'deepseek'
108
108
  Provides-Extra: fireworks
109
- Requires-Dist: langchain-fireworks<2.0.0,>=1.6.1; extra == 'fireworks'
109
+ Requires-Dist: langchain-fireworks<2.0.0,>=1.6.2; extra == 'fireworks'
110
110
  Provides-Extra: google-genai
111
111
  Requires-Dist: langchain-google-genai<5.0.0,>=4.4.0; extra == 'google-genai'
112
112
  Provides-Extra: groq
@@ -132,9 +132,9 @@ Requires-Dist: langchain-nvidia-ai-endpoints<2.0.0,>=1.4.3; extra == 'nvidia'
132
132
  Provides-Extra: ollama
133
133
  Requires-Dist: langchain-ollama<2.0.0,>=1.1.0; extra == 'ollama'
134
134
  Provides-Extra: openai
135
- Requires-Dist: langchain-openai<2.0.0,>=1.6.2; extra == 'openai'
135
+ Requires-Dist: langchain-openai<2.0.0,>=1.6.3; extra == 'openai'
136
136
  Provides-Extra: openrouter
137
- Requires-Dist: langchain-openrouter<2.0.0,>=0.2.8; extra == 'openrouter'
137
+ Requires-Dist: langchain-openrouter<2.0.0,>=0.2.9; extra == 'openrouter'
138
138
  Provides-Extra: perplexity
139
139
  Requires-Dist: langchain-perplexity<2.0.0,>=1.4.1; extra == 'perplexity'
140
140
  Provides-Extra: quickjs
@@ -1,3 +1,3 @@
1
1
  """Generated at build time. Do not edit or commit."""
2
2
 
3
- BUILD_COMMIT = "a764619"
3
+ BUILD_COMMIT = "d5a1896"
@@ -363,13 +363,16 @@ def _refresh_args(uv_path: str) -> list[str]:
363
363
  root would execute instead of the legitimate binary.
364
364
 
365
365
  Returns:
366
- Arguments for the user-approved `uv pip install` process.
366
+ Arguments for the user-approved `uv pip install` process, with uv's
367
+ configuration discovery anchored to the editable checkout.
367
368
  """
368
369
  checkout = _checkout_root()
369
370
  args = [
370
371
  uv_path,
371
372
  "pip",
372
373
  "install",
374
+ "--directory",
375
+ str(checkout),
373
376
  "--python",
374
377
  sys.executable,
375
378
  "-e",
@@ -861,7 +861,12 @@ def _installation_paths() -> InstallationPaths:
861
861
  """
862
862
  root = _normalize_absolute(Path(sys.prefix), what="sys.prefix")
863
863
  resources = root / "share" / "deepagents-code"
864
- locks = root.parent / f".{root.name}.deepagents-code-locks"
864
+ # uv enumerates every directory beside the tool environment as a package.
865
+ # Keep persistent locks beside that container instead, outside the environment
866
+ # uv replaces on upgrade. Mirror this in install.sh's acquire_install_lock.
867
+ locks = (
868
+ root.parent.parent / f".{root.parent.name}.{root.name}.deepagents-code-locks"
869
+ )
865
870
  return InstallationPaths(
866
871
  root=root,
867
872
  managed_bin_dir=resources / "bin",
@@ -79,6 +79,62 @@ execute one directory's configuration against another directory's trust
79
79
  decision.
80
80
  """
81
81
 
82
+ MODEL_COMPATIBLE_FIELDS = frozenset(
83
+ {
84
+ "auto_classifier_model",
85
+ "cli_max_retries",
86
+ "model",
87
+ "rubric_model",
88
+ "summarization_model",
89
+ }
90
+ )
91
+ """Cosmetic model settings that do not affect durable access-policy compat.
92
+
93
+ Changing which model serves a bound thread — or the retry budget or auxiliary
94
+ grader/classifier models — does not change what the thread is *allowed* to do
95
+ (trust, tool, sandbox, and approval policy are unchanged). These fields are
96
+ therefore excluded from the policy fingerprint, so a model switch does not
97
+ invalidate a durable binding. They remain part of the runtime fingerprint so
98
+ the runtime rebuilds. `None` and an empty/unset value are normalized as
99
+ equivalent here.
100
+ """
101
+
102
+ RUNTIME_ONLY_FIELDS = frozenset(
103
+ {
104
+ "assistant_id",
105
+ "model_params",
106
+ "profile_overrides",
107
+ "recursion_limit",
108
+ "rubric_max_iterations",
109
+ "system_prompt",
110
+ }
111
+ )
112
+ """Runtime-identity fields that are not durable access policy.
113
+
114
+ These shape *how* the runtime executes (model kwargs, prompt, step budget,
115
+ graph id) but are not the trust/tool/sandbox/approval policy a binding guards.
116
+ They are fingerprinted into the runtime identity (so changing them rebuilds the
117
+ runtime) yet never persisted or reported — `model_params`, `profile_overrides`,
118
+ and `system_prompt` can carry secrets and prompt material.
119
+ """
120
+
121
+ WORKSPACE_IDENTITY_FIELDS = frozenset({"cwd", "project_root"})
122
+ """Fields that name *which* workspace a binding is for.
123
+
124
+ Workspace identity is part of durable access-policy compatibility: a binding
125
+ is meaningless if it can be replayed against a different directory. These are
126
+ compared exactly (canonical paths) and are never normalized away.
127
+ """
128
+
129
+
130
+ def _classified_fields() -> frozenset[str]:
131
+ """Return every field the policy/runtime split accounts for.
132
+
133
+ Returns:
134
+ The union of all classification sets plus workspace identity.
135
+ """
136
+ return MODEL_COMPATIBLE_FIELDS | RUNTIME_ONLY_FIELDS | WORKSPACE_IDENTITY_FIELDS
137
+
82
138
 
83
139
  def _same_workspace_project(first: str | None, second: str) -> bool:
84
140
  """Whether two paths name the same project directory.
@@ -636,8 +692,34 @@ class ServerConfig:
636
692
  return replace(self, trust_project_extensions=False)
637
693
  return self
638
694
 
639
- def workspace_fingerprint(self) -> str:
640
- """Fingerprint the resolved runtime config except workspace identity.
695
+ def policy_fingerprint(self) -> str:
696
+ """Fingerprint durable access policy plus workspace identity.
697
+
698
+ Covers the trust/tool/sandbox/approval payload (the
699
+ `to_workspace_payload()` keys) and the workspace's `cwd`/`project_root`.
700
+ Cosmetic model settings (`MODEL_COMPATIBLE_FIELDS`) are excluded so a
701
+ model switch does not invalidate a durable binding; runtime-only fields
702
+ (`RUNTIME_ONLY_FIELDS`) are excluded because they are not persisted.
703
+
704
+ Returns:
705
+ The canonical SHA-256 fingerprint.
706
+ """
707
+ from deepagents_code.workspace import canonical_fingerprint
708
+
709
+ return canonical_fingerprint(
710
+ {
711
+ "cwd": self.cwd,
712
+ "policy": self.to_workspace_payload(),
713
+ "project_root": self.project_root,
714
+ }
715
+ )
716
+
717
+ def runtime_fingerprint(self) -> str:
718
+ """Fingerprint the full runtime identity, including model settings.
719
+
720
+ Any change to model, model params, prompt, policy, or runtime fields
721
+ yields a different value, so the runtime cache can rebuild on any of
722
+ them while the binding only guards the policy fingerprint.
641
723
 
642
724
  Returns:
643
725
  The canonical SHA-256 fingerprint.
@@ -649,6 +731,16 @@ class ServerConfig:
649
731
 
650
732
  return canonical_fingerprint(values)
651
733
 
734
+ def workspace_fingerprint(self) -> str:
735
+ """Fingerprint the resolved runtime config except workspace identity.
736
+
737
+ Retained for compatibility; equivalent to `runtime_fingerprint()`.
738
+
739
+ Returns:
740
+ The canonical SHA-256 fingerprint.
741
+ """
742
+ return self.runtime_fingerprint()
743
+
652
744
  def __post_init__(self) -> None:
653
745
  """Normalize fields and validate invariants.
654
746
 
@@ -1015,3 +1107,38 @@ def _normalize_path(
1015
1107
  "Ensure the path exists and is accessible."
1016
1108
  )
1017
1109
  raise ValueError(msg) from exc
1110
+
1111
+
1112
+ def classified_config_fields() -> dict[str, str]:
1113
+ """Classify every `ServerConfig` field for the policy/runtime split.
1114
+
1115
+ Every dataclass field must land in exactly one bucket so the fingerprint
1116
+ split cannot silently drop a setting. A field missing from a bucket is a
1117
+ programming error and fails closed (raises) rather than being treated as
1118
+ either policy or runtime by default.
1119
+
1120
+ Returns:
1121
+ A mapping of field name to one of `"model"`, `"runtime"`,
1122
+ `"identity"`, or `"policy"`.
1123
+
1124
+ Raises:
1125
+ RuntimeError: If a `ServerConfig` field is not classified.
1126
+ """
1127
+ import dataclasses
1128
+
1129
+ policy_fields = set(ServerConfig().to_workspace_payload())
1130
+ classification: dict[str, str] = {}
1131
+ for field_info in dataclasses.fields(ServerConfig):
1132
+ name = field_info.name
1133
+ if name in MODEL_COMPATIBLE_FIELDS:
1134
+ classification[name] = "model"
1135
+ elif name in RUNTIME_ONLY_FIELDS:
1136
+ classification[name] = "runtime"
1137
+ elif name in WORKSPACE_IDENTITY_FIELDS:
1138
+ classification[name] = "identity"
1139
+ elif name in policy_fields:
1140
+ classification[name] = "policy"
1141
+ else:
1142
+ msg = f"ServerConfig field {name!r} is not classified"
1143
+ raise RuntimeError(msg)
1144
+ return classification
@@ -14,6 +14,7 @@ from __future__ import annotations
14
14
 
15
15
  import logging
16
16
  import math
17
+ import re
17
18
  import sys
18
19
  from collections.abc import Hashable, Mapping
19
20
  from dataclasses import dataclass, field, replace
@@ -176,22 +177,24 @@ class RecordedUsage:
176
177
  """
177
178
 
178
179
 
179
- UsageLedgerKey = str | tuple[Hashable, str]
180
- """Key of the recorded-request ledger: a message ID, optionally scoped.
180
+ @dataclass(frozen=True, slots=True)
181
+ class ModelInvocationKey:
182
+ """Stable identity of one model invocation in the usage ledger."""
181
183
 
182
- A bare message-ID string keys requests recorded without an attempt scope
183
- (the legacy behavior). When a caller passes `attempt_scope` to
184
- `record_message_usage`/`record_model_usage_event`, the key is
185
- `(attempt_scope, message_id)` instead, so a retry that reuses the provider's
186
- message ID is a separate request while chunks of one attempt still merge.
187
- Callers that retain this ledger across retries should use this widened key type.
184
+ invocation_id: str
185
+
186
+
187
+ @dataclass(frozen=True, slots=True)
188
+ class MessageUsageKey:
189
+ """Message identity, optionally scoped to one model attempt."""
190
+
191
+ message_id: str
192
+ attempt_scope: Hashable | None = None
193
+
194
+
195
+ UsageLedgerKey = ModelInvocationKey | MessageUsageKey
196
+ """Model run identities and message aliases for recorded requests."""
188
197
 
189
- The two shapes coexist in one ledger, so de-duplication cannot rely on the
190
- key alone: an attempt scope lives for one model call, while a HITL resume pass
191
- replays messages with no scope open. `finalize_recorded_requests` closes that
192
- gap by projecting every scoped key down to its bare message ID at each round
193
- boundary -- see its docstring.
194
- """
195
198
 
196
199
  ModelStatsKey = tuple[str, str]
197
200
  """Per-model dict key: the `(provider, model_name)` pair.
@@ -453,67 +456,67 @@ class RecordedRequest:
453
456
  round. A later chunk for a finalized request is a replay, not a revision.
454
457
  """
455
458
 
459
+ message_ids: frozenset[str] = frozenset()
460
+ """Provider and framework message IDs observed for this invocation."""
456
461
 
457
- def finalize_recorded_requests(
458
- recorded_requests: dict[UsageLedgerKey, RecordedRequest],
459
- ) -> None:
460
- """Close every request in a ledger that outlives its stream round.
461
-
462
- A chunked request is left open between chunks so later ones can revise it.
463
- That is only correct *within* one round: when a consumer reuses its ledger
464
- across HITL resume passes, the replayed chunks of an already-recorded
465
- request would otherwise merge a second time and double its tokens and cost.
466
- Closing the ledger at each round boundary makes the replay indistinguishable
467
- from the stray-chunk case `record_message_usage` already rejects.
468
-
469
- Attempt-scoped keys need one extra step. A scope identifies one model
470
- attempt and is closed when that attempt ends, so the replay on the next
471
- resume pass arrives with no scope and keys by the bare message ID -- which
472
- would miss the `(attempt_scope, message_id)` entry entirely and count the
473
- whole request a second time. Project each scoped entry down to its bare
474
- message ID as well, so the replay finds a finalized row whichever shape it
475
- keys by. Later attempts overwrite earlier ones, leaving the values from the
476
- attempt that actually succeeded; the projected row exists only to reject
477
- replays, so its counts are never added to `stats` again.
462
+ ledger_key: UsageLedgerKey | None = None
463
+ """Canonical ledger entry, promoted when a model run identity is learned."""
478
464
 
479
- Args:
480
- recorded_requests: Ledger to close. Mutated in place.
481
- """
482
- for request_id, recorded in list(recorded_requests.items()):
483
- closed = recorded if recorded.finalized else replace(recorded, finalized=True)
484
- recorded_requests[request_id] = closed
485
- if isinstance(request_id, tuple):
486
- recorded_requests[request_id[1]] = closed
465
+ request_bucket: str | None = None
466
+ """Stable provisional bucket even when a legacy record gains a run identity."""
487
467
 
468
+ invocation_id: str | None = None
469
+ """Strong run identity, when supplied by either delivery path."""
488
470
 
489
- def _provisional_bucket_key(request_id: UsageLedgerKey | None) -> str | None:
490
- """Return a string key naming the request a provisional delta belongs to.
471
+ aliases: frozenset[UsageLedgerKey] = frozenset()
472
+ """Scoped identities pointing to this canonical record."""
491
473
 
492
- The consumer keys a pool of provisional dollars by this value, so it must
493
- separate exactly what the ledger separates. An attempt-scoped key therefore
494
- keeps its scope: two attempts that reuse one provider message ID are
495
- distinct requests, and collapsing them to the bare ID would let one
496
- attempt's late retraction draw on the other attempt's deposit.
497
474
 
498
- Scope cannot change under a request while it still reports deltas. A chunk
499
- or completion whose record is already finalized is rejected before any
500
- delta is built, and `finalize_recorded_requests` closes every entry at the
501
- end of a stream round -- so one request's deltas all carry one scope, and
502
- the key stays stable for as long as the pool holds its money.
475
+ def finalize_recorded_requests(
476
+ recorded_requests: dict[UsageLedgerKey, RecordedRequest],
477
+ ) -> None:
478
+ """Finalize canonical records and expose message aliases for unscoped replay."""
479
+ for request_id, recorded in list(recorded_requests.items()):
480
+ if request_id != recorded.ledger_key:
481
+ continue
482
+ closed = replace(recorded, finalized=True)
483
+ for alias in closed.aliases:
484
+ if recorded_requests.get(alias) is recorded:
485
+ recorded_requests[alias] = closed
486
+ for message_id in closed.message_ids:
487
+ recorded_requests[MessageUsageKey(message_id)] = closed
503
488
 
504
- Args:
505
- request_id: Ledger key for the request, or `None` when the message
506
- carried no usable ID.
507
489
 
508
- Returns:
509
- An opaque bucket key, or `None` when there is no ledger key to name.
510
- """
490
+ def _provisional_bucket_key(request_id: UsageLedgerKey | None) -> str | None:
491
+ """Return the initial provisional bucket, retained when run identity improves."""
511
492
  if request_id is None:
512
493
  return None
513
- if isinstance(request_id, tuple):
514
- attempt_scope, message_id = request_id
515
- return f"{attempt_scope!r}\x00{message_id}"
516
- return request_id
494
+ if isinstance(request_id, ModelInvocationKey):
495
+ return repr(request_id.invocation_id)
496
+ if request_id.attempt_scope is not None:
497
+ return repr((request_id.attempt_scope, request_id.message_id))
498
+ return request_id.message_id
499
+
500
+
501
+ def _usage_ledger_key(
502
+ recorded_requests: dict[UsageLedgerKey, RecordedRequest],
503
+ message_id: str | None,
504
+ attempt_scope: Hashable | None,
505
+ invocation_id: str | None,
506
+ ) -> tuple[UsageLedgerKey | None, frozenset[UsageLedgerKey]]:
507
+ """Return a canonical key and compatible scoped aliases, never across runs."""
508
+ message_key = MessageUsageKey(message_id, attempt_scope) if message_id else None
509
+ run_key = ModelInvocationKey(invocation_id) if invocation_id else None
510
+ aliases = frozenset(key for key in (run_key, message_key) if key is not None)
511
+ for key in (run_key, message_key):
512
+ previous = recorded_requests.get(key) if key is not None else None
513
+ if previous is not None and (
514
+ not invocation_id
515
+ or not previous.invocation_id
516
+ or previous.invocation_id == invocation_id
517
+ ):
518
+ return previous.ledger_key, aliases
519
+ return run_key or message_key, aliases
517
520
 
518
521
 
519
522
  def _names_a_model(message: object) -> bool:
@@ -783,6 +786,7 @@ def _move_request_to_named_model(
783
786
  cost_usd=cost_usd,
784
787
  usage_metadata=previous.usage_metadata,
785
788
  finalized=previous.finalized,
789
+ message_ids=previous.message_ids,
786
790
  )
787
791
  return _cost_delta(
788
792
  previous.cost_usd,
@@ -887,6 +891,12 @@ def _finalize_from_completed(
887
891
  cost_usd=cost_usd,
888
892
  usage_metadata=usage,
889
893
  finalized=True,
894
+ message_ids=previous.message_ids
895
+ | (
896
+ frozenset({message_id})
897
+ if (message_id := getattr(message, "id", None))
898
+ else frozenset()
899
+ ),
890
900
  )
891
901
  return RecordedUsage(
892
902
  input_tokens=input_count - previous.input_tokens,
@@ -913,6 +923,7 @@ def record_message_usage(
913
923
  kind: UsageKind = "assistant",
914
924
  recorded_requests: dict[UsageLedgerKey, RecordedRequest] | None = None,
915
925
  attempt_scope: Hashable | None = None,
926
+ invocation_id: str | None = None,
916
927
  ) -> RecordedUsage | None:
917
928
  """Record usage attached to one streamed model message.
918
929
 
@@ -947,13 +958,12 @@ def record_message_usage(
947
958
  this specific request, when available.
948
959
  kind: Request class used by the type breakdown.
949
960
  recorded_requests: Ledger of requests this stream consumer has already
950
- recorded, keyed by message ID -- or by `(attempt_scope, message_id)`
951
- when `attempt_scope` is set. Mutated in place.
952
- attempt_scope: Identity of the attempt that produced this message, or
953
- `None` for legacy unscoped recording. Retries of one logical request
954
- can reuse the provider's message ID; scoping keeps each attempt's
955
- usage separate, while chunks and corrections of one attempt (same
956
- scope, same ID) still merge into a single request.
961
+ recorded, keyed by stable invocation identity when available and by
962
+ message ID otherwise. Mutated in place.
963
+ attempt_scope: Lifecycle identity of the attempt that produced this
964
+ message. Keeps retries distinct when no model run ID is available.
965
+ invocation_id: LangChain model run ID shared by streaming and callback
966
+ deliveries for this invocation. Preferred over provider message IDs.
957
967
 
958
968
  Returns:
959
969
  The tokens and cost *this message* contributed, or `None` when it has no
@@ -966,18 +976,89 @@ def record_message_usage(
966
976
  if not isinstance(usage, Mapping) or not usage:
967
977
  return None
968
978
 
969
- # Imported here, not at module scope: this module is deliberately free of
970
- # heavy top-level dependencies (see the module docstring).
971
- from langchain_core.messages import AIMessageChunk
979
+ from deepagents_code.cost_tracking import _MODEL_INVOCATION_METADATA_KEY
972
980
 
973
981
  if recorded_requests is None:
974
982
  recorded_requests = {}
975
- message_id = getattr(message, "id", None)
976
- request_id: UsageLedgerKey | None = (
977
- message_id if isinstance(message_id, str) and message_id else None
983
+ raw_message_id = getattr(message, "id", None)
984
+ message_id = (
985
+ raw_message_id if isinstance(raw_message_id, str) and raw_message_id else None
986
+ )
987
+ metadata_id = (request_metadata or {}).get(_MODEL_INVOCATION_METADATA_KEY)
988
+ invocation_id = invocation_id or (
989
+ metadata_id if isinstance(metadata_id, str) and metadata_id else None
990
+ )
991
+ if not invocation_id and message_id and message_id.startswith("lc_run--"):
992
+ # Non-streaming generations append an index to the model run UUID.
993
+ # Preserve the existing inference for IDs without a generation suffix.
994
+ match = re.fullmatch(
995
+ r"lc_run--([0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12})"
996
+ r"(?:-\d+)?",
997
+ message_id,
998
+ )
999
+ invocation_id = match[1] if match else message_id.removeprefix("lc_run--")
1000
+ request_id, aliases = _usage_ledger_key(
1001
+ recorded_requests, message_id, attempt_scope, invocation_id
978
1002
  )
979
- if request_id is not None and attempt_scope is not None:
980
- request_id = (attempt_scope, request_id)
1003
+ previous = recorded_requests.get(request_id) if request_id is not None else None
1004
+ request_bucket = (
1005
+ previous.request_bucket if previous else _provisional_bucket_key(request_id)
1006
+ )
1007
+ if previous is not None and invocation_id:
1008
+ request_id = ModelInvocationKey(invocation_id)
1009
+ recorded_requests[request_id] = previous
1010
+ result = _record_message_usage(
1011
+ stats,
1012
+ message,
1013
+ fallback_model=fallback_model,
1014
+ fallback_provider=fallback_provider,
1015
+ request_metadata=request_metadata,
1016
+ kind=kind,
1017
+ recorded_requests=recorded_requests,
1018
+ request_id=request_id,
1019
+ )
1020
+ if request_id is not None and (updated := recorded_requests.get(request_id)):
1021
+ aliases |= (
1022
+ frozenset(
1023
+ alias
1024
+ for alias in previous.aliases
1025
+ if recorded_requests.get(alias) is previous
1026
+ )
1027
+ if previous
1028
+ else frozenset()
1029
+ )
1030
+ updated = replace(
1031
+ updated,
1032
+ ledger_key=request_id,
1033
+ request_bucket=request_bucket,
1034
+ invocation_id=invocation_id
1035
+ or (previous.invocation_id if previous else None),
1036
+ aliases=aliases | {request_id},
1037
+ message_ids=updated.message_ids | ({message_id} if message_id else set()),
1038
+ )
1039
+ for alias in updated.aliases:
1040
+ recorded_requests[alias] = updated
1041
+ return replace(result, request_id=request_bucket) if result else None
1042
+
1043
+
1044
+ def _record_message_usage(
1045
+ stats: SessionStats,
1046
+ message: object,
1047
+ *,
1048
+ fallback_model: str,
1049
+ fallback_provider: str,
1050
+ request_metadata: Mapping[str, Any] | None,
1051
+ kind: UsageKind,
1052
+ recorded_requests: dict[UsageLedgerKey, RecordedRequest],
1053
+ request_id: UsageLedgerKey | None,
1054
+ ) -> RecordedUsage | None:
1055
+ """Return the usage delta applied to the resolved canonical request."""
1056
+ usage = getattr(message, "usage_metadata", None)
1057
+ if not isinstance(usage, Mapping) or not usage:
1058
+ return None
1059
+
1060
+ from langchain_core.messages import AIMessageChunk
1061
+
981
1062
  is_chunk = isinstance(message, AIMessageChunk)
982
1063
  if request_id is not None and request_id in recorded_requests and not is_chunk:
983
1064
  previous = recorded_requests[request_id]
@@ -1102,6 +1183,7 @@ def record_message_usage(
1102
1183
  cost_usd=cost_usd,
1103
1184
  usage_metadata=accumulated_usage,
1104
1185
  finalized=not is_chunk,
1186
+ message_ids=previous.message_ids if previous else frozenset(),
1105
1187
  )
1106
1188
  # Provisional pricing needs this message's delta, while the context display
1107
1189
  # needs the request's running token total after folding the message in.
@@ -1176,6 +1258,7 @@ def record_model_usage_event(
1176
1258
  )
1177
1259
  return None
1178
1260
  request_id = data.get("request_id")
1261
+ invocation_id = data.get("invocation_id")
1179
1262
  thread_id = data.get("thread_id")
1180
1263
  scope = data.get("scope")
1181
1264
  usage = data.get("usage_metadata")
@@ -1183,6 +1266,7 @@ def record_model_usage_event(
1183
1266
  if (
1184
1267
  not isinstance(request_id, str)
1185
1268
  or not request_id
1269
+ or (invocation_id is not None and not isinstance(invocation_id, str))
1186
1270
  or not isinstance(thread_id, str)
1187
1271
  or not thread_id
1188
1272
  or not isinstance(scope, str)
@@ -1220,6 +1304,7 @@ def record_model_usage_event(
1220
1304
  kind="subagent",
1221
1305
  recorded_requests=recorded_requests,
1222
1306
  attempt_scope=attempt_scope,
1307
+ invocation_id=invocation_id or None,
1223
1308
  )
1224
1309
 
1225
1310