tunacode-cli 0.0.44__tar.gz → 0.0.45__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.

Potentially problematic release.


This version of tunacode-cli might be problematic. Click here for more details.

Files changed (236) hide show
  1. {tunacode_cli-0.0.44/src/tunacode_cli.egg-info → tunacode_cli-0.0.45}/PKG-INFO +1 -3
  2. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/pyproject.toml +1 -3
  3. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/cli/repl.py +13 -5
  4. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/configuration/defaults.py +0 -1
  5. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/constants.py +1 -1
  6. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/agents/main.py +3 -72
  7. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/recursive/aggregator.py +2 -2
  8. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/recursive/decomposer.py +1 -1
  9. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/recursive/executor.py +11 -8
  10. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/ui/panels.py +9 -2
  11. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45/src/tunacode_cli.egg-info}/PKG-INFO +1 -3
  12. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode_cli.egg-info/SOURCES.txt +0 -5
  13. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode_cli.egg-info/requires.txt +0 -2
  14. tunacode_cli-0.0.45/tests/characterization/repl/test_repl_initialization.py +114 -0
  15. tunacode_cli-0.0.44/src/tunacode/core/agents/dspy_integration.py +0 -223
  16. tunacode_cli-0.0.44/src/tunacode/core/agents/dspy_tunacode.py +0 -458
  17. tunacode_cli-0.0.44/src/tunacode/prompts/dspy_task_planning.md +0 -45
  18. tunacode_cli-0.0.44/src/tunacode/prompts/dspy_tool_selection.md +0 -58
  19. tunacode_cli-0.0.44/tests/characterization/repl/test_repl_initialization.py +0 -59
  20. tunacode_cli-0.0.44/tests/test_dspy_integration.py +0 -127
  21. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/CLAUDE.md +0 -0
  22. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/LICENSE +0 -0
  23. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/MANIFEST.in +0 -0
  24. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/README.md +0 -0
  25. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/TUNACODE.md +0 -0
  26. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/setup.cfg +0 -0
  27. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/setup.py +0 -0
  28. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/__init__.py +0 -0
  29. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/cli/__init__.py +0 -0
  30. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/cli/commands/__init__.py +0 -0
  31. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/cli/commands/base.py +0 -0
  32. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/cli/commands/implementations/__init__.py +0 -0
  33. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/cli/commands/implementations/conversation.py +0 -0
  34. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/cli/commands/implementations/debug.py +0 -0
  35. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/cli/commands/implementations/development.py +0 -0
  36. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/cli/commands/implementations/model.py +0 -0
  37. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/cli/commands/implementations/system.py +0 -0
  38. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/cli/commands/implementations/todo.py +0 -0
  39. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/cli/commands/registry.py +0 -0
  40. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/cli/main.py +0 -0
  41. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/configuration/__init__.py +0 -0
  42. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/configuration/models.py +0 -0
  43. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/configuration/settings.py +0 -0
  44. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/context.py +0 -0
  45. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/__init__.py +0 -0
  46. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/agents/__init__.py +0 -0
  47. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/agents/utils.py +0 -0
  48. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/background/__init__.py +0 -0
  49. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/background/manager.py +0 -0
  50. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/code_index.py +0 -0
  51. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/llm/__init__.py +0 -0
  52. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/recursive/__init__.py +0 -0
  53. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/recursive/budget.py +0 -0
  54. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/recursive/hierarchy.py +0 -0
  55. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/setup/__init__.py +0 -0
  56. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/setup/agent_setup.py +0 -0
  57. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/setup/base.py +0 -0
  58. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/setup/config_setup.py +0 -0
  59. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/setup/coordinator.py +0 -0
  60. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/setup/environment_setup.py +0 -0
  61. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/setup/git_safety_setup.py +0 -0
  62. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/state.py +0 -0
  63. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/token_usage/api_response_parser.py +0 -0
  64. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/token_usage/cost_calculator.py +0 -0
  65. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/token_usage/usage_tracker.py +0 -0
  66. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/core/tool_handler.py +0 -0
  67. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/exceptions.py +0 -0
  68. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/prompts/system.md +0 -0
  69. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/py.typed +0 -0
  70. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/services/__init__.py +0 -0
  71. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/services/mcp.py +0 -0
  72. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/setup.py +0 -0
  73. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/tools/__init__.py +0 -0
  74. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/tools/base.py +0 -0
  75. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/tools/bash.py +0 -0
  76. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/tools/glob.py +0 -0
  77. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/tools/grep.py +0 -0
  78. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/tools/list_dir.py +0 -0
  79. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/tools/read_file.py +0 -0
  80. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/tools/read_file_async_poc.py +0 -0
  81. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/tools/run_command.py +0 -0
  82. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/tools/todo.py +0 -0
  83. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/tools/update_file.py +0 -0
  84. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/tools/write_file.py +0 -0
  85. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/types.py +0 -0
  86. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/ui/__init__.py +0 -0
  87. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/ui/completers.py +0 -0
  88. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/ui/console.py +0 -0
  89. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/ui/constants.py +0 -0
  90. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/ui/decorators.py +0 -0
  91. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/ui/input.py +0 -0
  92. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/ui/keybindings.py +0 -0
  93. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/ui/lexers.py +0 -0
  94. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/ui/output.py +0 -0
  95. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/ui/prompt_manager.py +0 -0
  96. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/ui/recursive_progress.py +0 -0
  97. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/ui/tool_ui.py +0 -0
  98. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/ui/utils.py +0 -0
  99. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/ui/validators.py +0 -0
  100. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/utils/__init__.py +0 -0
  101. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/utils/bm25.py +0 -0
  102. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/utils/diff_utils.py +0 -0
  103. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/utils/file_utils.py +0 -0
  104. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/utils/import_cache.py +0 -0
  105. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/utils/message_utils.py +0 -0
  106. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/utils/retry.py +0 -0
  107. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/utils/ripgrep.py +0 -0
  108. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/utils/security.py +0 -0
  109. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/utils/system.py +0 -0
  110. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/utils/text_utils.py +0 -0
  111. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/utils/token_counter.py +0 -0
  112. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode/utils/user_configuration.py +0 -0
  113. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode_cli.egg-info/dependency_links.txt +0 -0
  114. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode_cli.egg-info/entry_points.txt +0 -0
  115. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/src/tunacode_cli.egg-info/top_level.txt +0 -0
  116. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/agent/__init__.py +0 -0
  117. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/agent/conftest.py +0 -0
  118. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/agent/test_agent_creation.py +0 -0
  119. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/agent/test_json_tool_parsing.py +0 -0
  120. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/agent/test_process_node.py +0 -0
  121. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/agent/test_process_request.py +0 -0
  122. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/agent/test_tool_message_patching.py +0 -0
  123. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/background/test_background_edge_cases.py +0 -0
  124. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/background/test_cleanup.py +0 -0
  125. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/background/test_task_cancellation.py +0 -0
  126. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/background/test_task_creation.py +0 -0
  127. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/background/test_task_execution.py +0 -0
  128. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/code_index/test_cache_management.py +0 -0
  129. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/code_index/test_file_scanning.py +0 -0
  130. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/code_index/test_index_building.py +0 -0
  131. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/code_index/test_search_operations.py +0 -0
  132. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/code_index/test_symbol_extraction.py +0 -0
  133. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/commands/__init__.py +0 -0
  134. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/commands/test_init_command.py +0 -0
  135. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/conftest.py +0 -0
  136. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/context/__init__.py +0 -0
  137. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/context/test_context_acceptance.py +0 -0
  138. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/context/test_context_integration.py +0 -0
  139. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/context/test_context_loading.py +0 -0
  140. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/context/test_tunacode_logging.py +0 -0
  141. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/repl/test_command_parsing.py +0 -0
  142. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/repl/test_error_handling.py +0 -0
  143. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/repl/test_input_handling.py +0 -0
  144. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/repl/test_keyboard_interrupts.py +0 -0
  145. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/repl/test_multiline_input.py +0 -0
  146. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/repl/test_output_display_logic.py +0 -0
  147. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/repl/test_session_flow.py +0 -0
  148. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/services/test_error_recovery.py +0 -0
  149. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/services/test_llm_routing.py +0 -0
  150. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/services/test_mcp_integration.py +0 -0
  151. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/services/test_service_lifecycle.py +0 -0
  152. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/state/test_agent_tracking.py +0 -0
  153. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/state/test_message_history.py +0 -0
  154. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/state/test_permissions.py +0 -0
  155. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/state/test_session_management.py +0 -0
  156. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/state/test_state_initialization.py +0 -0
  157. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/state/test_user_config.py +0 -0
  158. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/test_characterization_commands.py +0 -0
  159. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/ui/test_async_ui.py +0 -0
  160. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/ui/test_console_output.py +0 -0
  161. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/ui/test_diff_display.py +0 -0
  162. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/ui/test_prompt_rendering.py +0 -0
  163. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/ui/test_tool_confirmations.py +0 -0
  164. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/utils/conftest.py +0 -0
  165. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/utils/test_expand_file_refs.py +0 -0
  166. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/utils/test_file_operations.py +0 -0
  167. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/utils/test_git_commands.py +0 -0
  168. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/utils/test_token_counting.py +0 -0
  169. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/characterization/utils/test_utils_edge_cases.py +0 -0
  170. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/conftest.py +0 -0
  171. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/crud/test_core_file_operations.py +0 -0
  172. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/fixtures/__init__.py +0 -0
  173. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/fixtures/file_operations.py +0 -0
  174. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/integration/test_error_recovery_flow.py +0 -0
  175. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/integration/test_full_session_flow.py +0 -0
  176. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/integration/test_mcp_tool_flow.py +0 -0
  177. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/integration/test_multi_tool_operations.py +0 -0
  178. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/integration/test_performance_scenarios.py +0 -0
  179. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/integration/test_usage_tracking_integration.py +0 -0
  180. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_actual_parallelism.py +0 -0
  181. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_agent_initialization.py +0 -0
  182. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_agent_output_formatting.py +0 -0
  183. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_api_response_parser.py +0 -0
  184. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_background_manager.py +0 -0
  185. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_characterization_agent_main.py +0 -0
  186. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_characterization_bash.py +0 -0
  187. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_characterization_commands_system.py +0 -0
  188. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_characterization_glob.py +0 -0
  189. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_characterization_grep.py +0 -0
  190. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_characterization_grep_performance.py +0 -0
  191. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_characterization_iteration_limits.py +0 -0
  192. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_characterization_list_dir.py +0 -0
  193. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_characterization_read_file.py +0 -0
  194. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_characterization_repl_utils.py +0 -0
  195. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_characterization_run_command.py +0 -0
  196. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_characterization_setup_system.py +0 -0
  197. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_characterization_tool_ui_behavior.py +0 -0
  198. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_characterization_update_file.py +0 -0
  199. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_characterization_utilities.py +0 -0
  200. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_characterization_write_file.py +0 -0
  201. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_cli_command_flow.py +0 -0
  202. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_cli_file_operations_integration.py +0 -0
  203. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_config_directory_creation.py +0 -0
  204. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_config_setup_async.py +0 -0
  205. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_cost_calculator.py +0 -0
  206. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_enhanced_visual_feedback.py +0 -0
  207. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_fallback_responses.py +0 -0
  208. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_fast_glob_search.py +0 -0
  209. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_file_operations_edge_cases.py +0 -0
  210. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_file_operations_stress.py +0 -0
  211. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_file_reference_context_tracking.py +0 -0
  212. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_file_reference_expansion.py +0 -0
  213. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_grep_fast_glob.py +0 -0
  214. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_grep_legacy_compat.py +0 -0
  215. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_grep_timeout.py +0 -0
  216. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_json_retry.py +0 -0
  217. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_json_tool_parsing.py +0 -0
  218. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_list_dir.py +0 -0
  219. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_parallel_execution_demo.py +0 -0
  220. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_parallel_execution_freeze_fix.py +0 -0
  221. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_parallel_execution_integration.py +0 -0
  222. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_parallel_read_only_tools.py +0 -0
  223. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_parallel_tool_execution.py +0 -0
  224. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_prompt_changes_validation.py +0 -0
  225. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_read_only_confirmation.py +0 -0
  226. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_security.py +0 -0
  227. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_streaming_panel_tool_confirmation.py +0 -0
  228. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_streaming_spinner_conflict.py +0 -0
  229. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_todo_functionality.py +0 -0
  230. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_tool_batching_retry.py +0 -0
  231. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_tool_categorization.py +0 -0
  232. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_tool_combinations.py +0 -0
  233. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_tool_handler_ui_messages.py +0 -0
  234. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_update_command.py +0 -0
  235. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/test_visual_parallel_feedback.py +0 -0
  236. {tunacode_cli-0.0.44 → tunacode_cli-0.0.45}/tests/unit/test_recursive_executor.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tunacode-cli
3
- Version: 0.0.44
3
+ Version: 0.0.45
4
4
  Summary: Your agentic CLI developer.
5
5
  Author-email: larock22 <noreply@github.com>
6
6
  License-Expression: MIT
@@ -25,8 +25,6 @@ Requires-Dist: pydantic-ai[logfire]==0.2.6
25
25
  Requires-Dist: pygments==2.19.1
26
26
  Requires-Dist: rich==14.0.0
27
27
  Requires-Dist: tiktoken>=0.5.2
28
- Requires-Dist: dspy-ai>=0.1.0
29
- Requires-Dist: python-dotenv>=1.0.0
30
28
  Provides-Extra: dev
31
29
  Requires-Dist: build; extra == "dev"
32
30
  Requires-Dist: ruff; extra == "dev"
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tunacode-cli"
7
- version = "0.0.44"
7
+ version = "0.0.45"
8
8
  description = "Your agentic CLI developer."
9
9
  keywords = ["cli", "agent", "development", "automation"]
10
10
  readme = "README.md"
@@ -31,8 +31,6 @@ dependencies = [
31
31
  "pygments==2.19.1",
32
32
  "rich==14.0.0",
33
33
  "tiktoken>=0.5.2",
34
- "dspy-ai>=0.1.0",
35
- "python-dotenv>=1.0.0",
36
34
  ]
37
35
 
38
36
  [project.scripts]
@@ -385,9 +385,13 @@ async def repl(state_manager: StateManager):
385
385
 
386
386
  state_manager.session.update_token_count()
387
387
  context_display = get_context_window_display(state_manager.session.total_tokens, max_tokens)
388
- await ui.muted(f"• Model: {model_name} • {context_display}")
389
- await ui.success("Ready to assist")
390
- await ui.line()
388
+
389
+ # Only show startup info if thoughts are enabled or on first run
390
+ if state_manager.session.show_thoughts or not hasattr(state_manager.session, "_startup_shown"):
391
+ await ui.muted(f"• Model: {model_name} • {context_display}")
392
+ await ui.success("Ready to assist")
393
+ await ui.line()
394
+ state_manager.session._startup_shown = True
391
395
 
392
396
  instance = agent.get_or_create_agent(state_manager.session.current_model, state_manager)
393
397
 
@@ -465,7 +469,11 @@ async def repl(state_manager: StateManager):
465
469
  context_display = get_context_window_display(
466
470
  state_manager.session.total_tokens, state_manager.session.max_tokens
467
471
  )
468
- await ui.muted(f"• Model: {state_manager.session.current_model} {context_display}")
472
+ # Only show model/context info if thoughts are enabled
473
+ if state_manager.session.show_thoughts:
474
+ await ui.muted(
475
+ f"• Model: {state_manager.session.current_model} • {context_display}"
476
+ )
469
477
 
470
478
  if action == "restart":
471
479
  await repl(state_manager)
@@ -480,7 +488,7 @@ async def repl(state_manager: StateManager):
480
488
  total_cost = float(session_total.get("cost", 0) or 0)
481
489
 
482
490
  # Only show summary if we have actual token usage
483
- if total_tokens > 0 or total_cost > 0:
491
+ if state_manager.session.show_thoughts and (total_tokens > 0 or total_cost > 0):
484
492
  summary = (
485
493
  f"\n[bold cyan]TunaCode Session Summary[/bold cyan]\n"
486
494
  f" - Total Tokens: {total_tokens:,}\n"
@@ -24,7 +24,6 @@ DEFAULT_USER_CONFIG: UserConfig = {
24
24
  "fallback_response": True,
25
25
  "fallback_verbosity": "normal", # Options: minimal, normal, detailed
26
26
  "context_window_size": 200000,
27
- "use_dspy_optimization": True, # Enable DSPy tool selection optimization
28
27
  },
29
28
  "mcpServers": {},
30
29
  }
@@ -7,7 +7,7 @@ Centralizes all magic strings, UI text, error messages, and application constant
7
7
 
8
8
  # Application info
9
9
  APP_NAME = "TunaCode"
10
- APP_VERSION = "0.0.44"
10
+ APP_VERSION = "0.0.45"
11
11
 
12
12
  # File patterns
13
13
  GUIDE_FILE_PATTERN = "{name}.md"
@@ -30,7 +30,6 @@ except ImportError:
30
30
  STREAMING_AVAILABLE = False
31
31
 
32
32
  from tunacode.constants import READ_ONLY_TOOLS
33
- from tunacode.core.agents.dspy_integration import DSPyIntegration
34
33
  from tunacode.core.recursive import RecursiveTaskExecutor
35
34
  from tunacode.core.state import StateManager
36
35
  from tunacode.core.token_usage.api_response_parser import ApiResponseParser
@@ -519,18 +518,6 @@ def get_or_create_agent(model: ModelName, state_manager: StateManager) -> Pydant
519
518
  # Use a default system prompt if neither file exists
520
519
  system_prompt = "You are a helpful AI assistant for software development tasks."
521
520
 
522
- # Enhance with DSPy optimization if enabled
523
- use_dspy = state_manager.session.user_config.get("settings", {}).get(
524
- "use_dspy_optimization", True
525
- )
526
- if use_dspy:
527
- try:
528
- dspy_integration = DSPyIntegration(state_manager)
529
- system_prompt = dspy_integration.enhance_system_prompt(system_prompt)
530
- logger.info("Enhanced system prompt with DSPy optimizations")
531
- except Exception as e:
532
- logger.warning(f"Failed to enhance prompt with DSPy: {e}")
533
-
534
521
  # Load TUNACODE.md context
535
522
  # Use sync version of get_code_style to avoid nested event loop issues
536
523
  try:
@@ -773,13 +760,6 @@ async def process_request(
773
760
  "fallback_response", True
774
761
  )
775
762
 
776
- # Check if DSPy optimization is enabled and if this is a complex task
777
- use_dspy = state_manager.session.user_config.get("settings", {}).get(
778
- "use_dspy_optimization", True
779
- )
780
- dspy_integration = None
781
- task_breakdown = None
782
-
783
763
  # Check if recursive execution is enabled
784
764
  use_recursive = state_manager.session.user_config.get("settings", {}).get(
785
765
  "use_recursive_execution", True
@@ -788,39 +768,6 @@ async def process_request(
788
768
  "recursive_complexity_threshold", 0.7
789
769
  )
790
770
 
791
- if use_dspy:
792
- try:
793
- dspy_integration = DSPyIntegration(state_manager)
794
-
795
- # Check if this is a complex task that needs planning
796
- if dspy_integration.should_use_task_planner(message):
797
- task_breakdown = dspy_integration.get_task_breakdown(message)
798
- if task_breakdown and task_breakdown.get("requires_todo"):
799
- # Auto-create todos for complex tasks
800
- from tunacode.tools.todo import TodoTool
801
-
802
- todo_tool = TodoTool(state_manager=state_manager)
803
-
804
- if state_manager.session.show_thoughts:
805
- from tunacode.ui import console as ui
806
-
807
- await ui.muted("DSPy: Detected complex task - creating todo list")
808
-
809
- # Create todos from subtasks
810
- todos = []
811
- for subtask in task_breakdown["subtasks"][:5]: # Limit to first 5
812
- todos.append(
813
- {
814
- "content": subtask["task"],
815
- "priority": subtask.get("priority", "medium"),
816
- }
817
- )
818
-
819
- if todos:
820
- await todo_tool._execute(action="add_multiple", todos=todos)
821
- except Exception as e:
822
- logger.warning(f"DSPy task planning failed: {e}")
823
-
824
771
  # Check if recursive execution should be used
825
772
  if use_recursive and state_manager.session.current_recursion_depth == 0:
826
773
  try:
@@ -853,25 +800,9 @@ async def process_request(
853
800
  request=message, parent_task_id=None, depth=0
854
801
  )
855
802
 
856
- # Create AgentRun response
857
- from datetime import datetime
858
-
859
- if success:
860
- return AgentRun(
861
- messages=[{"role": "assistant", "content": str(result)}],
862
- timestamp=datetime.now(),
863
- model=model,
864
- iterations=1,
865
- status="success",
866
- )
867
- else:
868
- return AgentRun(
869
- messages=[{"role": "assistant", "content": f"Task failed: {error}"}],
870
- timestamp=datetime.now(),
871
- model=model,
872
- iterations=1,
873
- status="error",
874
- )
803
+ # For now, fall back to normal execution
804
+ # TODO: Properly integrate recursive execution results
805
+ pass
875
806
  except Exception as e:
876
807
  logger.warning(f"Recursive execution failed, falling back to normal: {e}")
877
808
  # Continue with normal execution
@@ -39,7 +39,7 @@ class TaskResult:
39
39
 
40
40
  task_id: str
41
41
  task_title: str
42
- result_data: Any
42
+ result_data: object
43
43
  status: str # completed, failed, partial
44
44
  timestamp: datetime = field(default_factory=datetime.now)
45
45
  error: Optional[str] = None
@@ -50,7 +50,7 @@ class TaskResult:
50
50
  class AggregatedResult:
51
51
  """Aggregated result from multiple tasks."""
52
52
 
53
- primary_result: Any
53
+ primary_result: object
54
54
  task_results: List[TaskResult]
55
55
  strategy_used: AggregationStrategy
56
56
  conflicts_resolved: int = 0
@@ -73,7 +73,7 @@ class TaskDecomposer:
73
73
  # Get the main agent
74
74
  agent = self.state_manager.session.agents.get("main")
75
75
  if not agent:
76
- logger.warning("Main agent not available, using heuristic decomposition")
76
+ logger.debug("Main agent not available, using heuristic decomposition")
77
77
  return self._heuristic_decomposition(task_description)
78
78
 
79
79
  # Build context-aware prompt
@@ -32,7 +32,7 @@ class TaskNode:
32
32
  iteration_budget: int = 10
33
33
  subtasks: List["TaskNode"] = field(default_factory=list)
34
34
  status: str = "pending" # pending, in_progress, completed, failed
35
- result: Optional[Any] = None
35
+ result: Optional[object] = None
36
36
  error: Optional[str] = None
37
37
  context: Dict[str, Any] = field(default_factory=dict)
38
38
  depth: int = 0
@@ -128,15 +128,17 @@ class RecursiveTaskExecutor:
128
128
  and depth < self.max_depth - 1
129
129
  ):
130
130
  # Decompose into subtasks
131
- logger.info(
132
- f"Decomposing complex task (score: {complexity_result.complexity_score:.2f})"
133
- )
131
+ if self.state_manager.session.show_thoughts:
132
+ logger.info(
133
+ f"Decomposing complex task (score: {complexity_result.complexity_score:.2f})"
134
+ )
134
135
  return await self._execute_with_decomposition(task_node, complexity_result)
135
136
  else:
136
137
  # Execute directly
137
- logger.info(
138
- f"Executing task directly (score: {complexity_result.complexity_score:.2f})"
139
- )
138
+ if self.state_manager.session.show_thoughts:
139
+ logger.info(
140
+ f"Executing task directly (score: {complexity_result.complexity_score:.2f})"
141
+ )
140
142
  return await self._execute_directly(task_node)
141
143
 
142
144
  except Exception as e:
@@ -255,7 +257,8 @@ Respond in JSON format:
255
257
  )
256
258
 
257
259
  for i, (subtask_desc, budget) in enumerate(zip(subtasks, subtask_budgets)):
258
- logger.info(f"Executing subtask {i + 1}/{len(subtasks)}: {subtask_desc[:50]}...")
260
+ if self.state_manager.session.show_thoughts:
261
+ logger.info(f"Executing subtask {i + 1}/{len(subtasks)}: {subtask_desc[:50]}...")
259
262
 
260
263
  # Create subtask context
261
264
  subtask_context = {
@@ -9,6 +9,7 @@ from rich.padding import Padding
9
9
  from rich.panel import Panel
10
10
  from rich.pretty import Pretty
11
11
  from rich.table import Table
12
+ from rich.text import Text
12
13
 
13
14
  from tunacode.configuration.models import ModelRegistry
14
15
  from tunacode.constants import (
@@ -89,9 +90,15 @@ class StreamingAgentPanel:
89
90
  # Use the UI_THINKING_MESSAGE constant instead of hardcoded text
90
91
  from tunacode.constants import UI_THINKING_MESSAGE
91
92
 
92
- markdown_content = Markdown(self.content or UI_THINKING_MESSAGE)
93
+ # If no content, show thinking message with Rich markup
94
+ if not self.content:
95
+ content_to_display = Text.from_markup(UI_THINKING_MESSAGE)
96
+ else:
97
+ # Normal content is markdown
98
+ content_to_display = Markdown(self.content)
99
+
93
100
  panel_obj = Panel(
94
- Padding(markdown_content, (0, 1, 0, 1)),
101
+ Padding(content_to_display, (0, 1, 0, 1)),
95
102
  title=f"[bold]{self.title}[/bold]",
96
103
  title_align="left",
97
104
  border_style=colors.primary,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tunacode-cli
3
- Version: 0.0.44
3
+ Version: 0.0.45
4
4
  Summary: Your agentic CLI developer.
5
5
  Author-email: larock22 <noreply@github.com>
6
6
  License-Expression: MIT
@@ -25,8 +25,6 @@ Requires-Dist: pydantic-ai[logfire]==0.2.6
25
25
  Requires-Dist: pygments==2.19.1
26
26
  Requires-Dist: rich==14.0.0
27
27
  Requires-Dist: tiktoken>=0.5.2
28
- Requires-Dist: dspy-ai>=0.1.0
29
- Requires-Dist: python-dotenv>=1.0.0
30
28
  Provides-Extra: dev
31
29
  Requires-Dist: build; extra == "dev"
32
30
  Requires-Dist: ruff; extra == "dev"
@@ -34,8 +34,6 @@ src/tunacode/core/code_index.py
34
34
  src/tunacode/core/state.py
35
35
  src/tunacode/core/tool_handler.py
36
36
  src/tunacode/core/agents/__init__.py
37
- src/tunacode/core/agents/dspy_integration.py
38
- src/tunacode/core/agents/dspy_tunacode.py
39
37
  src/tunacode/core/agents/main.py
40
38
  src/tunacode/core/agents/utils.py
41
39
  src/tunacode/core/background/__init__.py
@@ -57,8 +55,6 @@ src/tunacode/core/setup/git_safety_setup.py
57
55
  src/tunacode/core/token_usage/api_response_parser.py
58
56
  src/tunacode/core/token_usage/cost_calculator.py
59
57
  src/tunacode/core/token_usage/usage_tracker.py
60
- src/tunacode/prompts/dspy_task_planning.md
61
- src/tunacode/prompts/dspy_tool_selection.md
62
58
  src/tunacode/prompts/system.md
63
59
  src/tunacode/services/__init__.py
64
60
  src/tunacode/services/mcp.py
@@ -135,7 +131,6 @@ tests/test_cli_file_operations_integration.py
135
131
  tests/test_config_directory_creation.py
136
132
  tests/test_config_setup_async.py
137
133
  tests/test_cost_calculator.py
138
- tests/test_dspy_integration.py
139
134
  tests/test_enhanced_visual_feedback.py
140
135
  tests/test_fallback_responses.py
141
136
  tests/test_fast_glob_search.py
@@ -4,8 +4,6 @@ pydantic-ai[logfire]==0.2.6
4
4
  pygments==2.19.1
5
5
  rich==14.0.0
6
6
  tiktoken>=0.5.2
7
- dspy-ai>=0.1.0
8
- python-dotenv>=1.0.0
9
7
 
10
8
  [dev]
11
9
  build
@@ -0,0 +1,114 @@
1
+ from unittest.mock import AsyncMock, MagicMock, patch
2
+
3
+ import pytest
4
+
5
+ import tunacode.cli.repl as repl_mod
6
+ from tunacode.constants import UI_COLORS
7
+
8
+
9
+ @pytest.mark.asyncio
10
+ async def test_repl_initialization_basic(monkeypatch):
11
+ """Test REPL startup: prints model, success, and line, and initializes agent/session."""
12
+
13
+ # Mock StateManager and session
14
+ state_manager = MagicMock()
15
+ state_manager.session.current_model = "gpt-test"
16
+ state_manager.session.input_sessions = {}
17
+ state_manager.session.show_thoughts = True # Enable thoughts to see startup messages
18
+ state_manager.session.total_tokens = 0
19
+ state_manager.session.max_tokens = 200000
20
+ state_manager.session.user_config = {"context_window_size": 200000}
21
+
22
+ def mock_update_token_count():
23
+ state_manager.session.total_tokens = 100
24
+
25
+ state_manager.session.update_token_count = MagicMock(side_effect=mock_update_token_count)
26
+
27
+ # Patch UI methods
28
+ with (
29
+ patch.object(repl_mod.ui, "muted", new=AsyncMock()) as muted,
30
+ patch.object(repl_mod.ui, "success", new=AsyncMock()) as success,
31
+ patch.object(repl_mod.ui, "line", new=AsyncMock()),
32
+ patch.object(repl_mod.agent, "get_or_create_agent") as get_agent,
33
+ ):
34
+ # Mock agent instance and MCP context
35
+ agent_instance = MagicMock()
36
+ mcp_context = AsyncMock()
37
+ mcp_context.__aenter__ = AsyncMock(return_value=None)
38
+ mcp_context.__aexit__ = AsyncMock(return_value=None)
39
+ agent_instance.run_mcp_servers = MagicMock(return_value=mcp_context)
40
+ get_agent.return_value = agent_instance
41
+
42
+ # Patch the REPL loop to exit immediately
43
+ async def fake_multiline_input(*a, **kw):
44
+ return "exit"
45
+
46
+ with (
47
+ patch.object(repl_mod.ui, "multiline_input", new=fake_multiline_input),
48
+ patch.object(repl_mod.ui, "info", new=AsyncMock()) as info,
49
+ ):
50
+ await repl_mod.repl(state_manager)
51
+
52
+ # Check that startup UI was called since show_thoughts is True
53
+ muted.assert_any_await(
54
+ f"• Model: gpt-test • [b]Context:[/] [{UI_COLORS['success']}]100/200,000 (0%)[/]"
55
+ )
56
+ success.assert_awaited()
57
+ get_agent.assert_called_once_with("gpt-test", state_manager)
58
+ info.assert_awaited_with("Session ended. Happy coding!")
59
+
60
+
61
+ @pytest.mark.asyncio
62
+ async def test_repl_initialization_no_thoughts_no_startup_messages(monkeypatch):
63
+ """Test REPL startup: no startup messages shown when show_thoughts is False."""
64
+
65
+ # Mock StateManager and session
66
+ state_manager = MagicMock()
67
+ state_manager.session.current_model = "gpt-test"
68
+ state_manager.session.input_sessions = {}
69
+ state_manager.session.show_thoughts = False # Disable thoughts
70
+ state_manager.session.total_tokens = 0
71
+ state_manager.session.max_tokens = 200000
72
+ state_manager.session.user_config = {"context_window_size": 200000}
73
+ state_manager.session._startup_shown = True # Simulate not first run
74
+
75
+ def mock_update_token_count():
76
+ state_manager.session.total_tokens = 100
77
+
78
+ state_manager.session.update_token_count = MagicMock(side_effect=mock_update_token_count)
79
+
80
+ # Patch UI methods
81
+ with (
82
+ patch.object(repl_mod.ui, "muted", new=AsyncMock()) as muted,
83
+ patch.object(repl_mod.ui, "success", new=AsyncMock()) as success,
84
+ patch.object(repl_mod.ui, "line", new=AsyncMock()),
85
+ patch.object(repl_mod.agent, "get_or_create_agent") as get_agent,
86
+ ):
87
+ # Mock agent instance and MCP context
88
+ agent_instance = MagicMock()
89
+ mcp_context = AsyncMock()
90
+ mcp_context.__aenter__ = AsyncMock(return_value=None)
91
+ mcp_context.__aexit__ = AsyncMock(return_value=None)
92
+ agent_instance.run_mcp_servers = MagicMock(return_value=mcp_context)
93
+ get_agent.return_value = agent_instance
94
+
95
+ # Patch the REPL loop to exit immediately
96
+ async def fake_multiline_input(*a, **kw):
97
+ return "exit"
98
+
99
+ with (
100
+ patch.object(repl_mod.ui, "multiline_input", new=fake_multiline_input),
101
+ patch.object(repl_mod.ui, "info", new=AsyncMock()) as info,
102
+ ):
103
+ await repl_mod.repl(state_manager)
104
+
105
+ # Check that startup UI was NOT called since show_thoughts is False and not first run
106
+ assert not any("Model:" in str(call) for call in muted.await_args_list), (
107
+ "Startup model message should not be shown when show_thoughts is False"
108
+ )
109
+ assert not any("Ready to assist" in str(call) for call in success.await_args_list), (
110
+ "Startup success message should not be shown when show_thoughts is False"
111
+ )
112
+
113
+ get_agent.assert_called_once_with("gpt-test", state_manager)
114
+ info.assert_awaited_with("Session ended. Happy coding!")