tunacode-cli 0.0.47__tar.gz → 0.0.48__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.47/src/tunacode_cli.egg-info → tunacode_cli-0.0.48}/PKG-INFO +3 -3
  2. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/README.md +2 -2
  3. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/pyproject.toml +1 -1
  4. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/cli/main.py +0 -4
  5. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/cli/repl.py +7 -14
  6. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/configuration/defaults.py +1 -0
  7. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/constants.py +1 -6
  8. tunacode_cli-0.0.48/src/tunacode/core/agents/dspy_integration.py +223 -0
  9. tunacode_cli-0.0.48/src/tunacode/core/agents/dspy_tunacode.py +458 -0
  10. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/core/agents/main.py +237 -311
  11. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/core/agents/utils.py +6 -54
  12. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/core/state.py +0 -41
  13. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/exceptions.py +0 -23
  14. tunacode_cli-0.0.48/src/tunacode/prompts/dspy_task_planning.md +45 -0
  15. tunacode_cli-0.0.48/src/tunacode/prompts/dspy_tool_selection.md +58 -0
  16. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/ui/input.py +1 -2
  17. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/ui/keybindings.py +1 -17
  18. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/ui/panels.py +2 -9
  19. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/utils/token_counter.py +2 -1
  20. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48/src/tunacode_cli.egg-info}/PKG-INFO +3 -3
  21. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode_cli.egg-info/SOURCES.txt +6 -12
  22. tunacode_cli-0.0.48/tests/characterization/repl/test_repl_initialization.py +59 -0
  23. tunacode_cli-0.0.48/tests/test_dspy_integration.py +127 -0
  24. tunacode_cli-0.0.47/src/tunacode/core/recursive/__init__.py +0 -18
  25. tunacode_cli-0.0.47/src/tunacode/core/recursive/aggregator.py +0 -467
  26. tunacode_cli-0.0.47/src/tunacode/core/recursive/budget.py +0 -414
  27. tunacode_cli-0.0.47/src/tunacode/core/recursive/decomposer.py +0 -398
  28. tunacode_cli-0.0.47/src/tunacode/core/recursive/executor.py +0 -470
  29. tunacode_cli-0.0.47/src/tunacode/core/recursive/hierarchy.py +0 -487
  30. tunacode_cli-0.0.47/src/tunacode/ui/recursive_progress.py +0 -380
  31. tunacode_cli-0.0.47/src/tunacode/utils/retry.py +0 -163
  32. tunacode_cli-0.0.47/tests/characterization/repl/test_repl_initialization.py +0 -114
  33. tunacode_cli-0.0.47/tests/test_json_retry.py +0 -230
  34. tunacode_cli-0.0.47/tests/test_tool_batching_retry.py +0 -287
  35. tunacode_cli-0.0.47/tests/unit/test_recursive_executor.py +0 -218
  36. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/CLAUDE.md +0 -0
  37. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/LICENSE +0 -0
  38. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/MANIFEST.in +0 -0
  39. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/TUNACODE.md +0 -0
  40. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/setup.cfg +0 -0
  41. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/setup.py +0 -0
  42. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/__init__.py +0 -0
  43. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/cli/__init__.py +0 -0
  44. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/cli/commands/__init__.py +0 -0
  45. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/cli/commands/base.py +0 -0
  46. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/cli/commands/implementations/__init__.py +0 -0
  47. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/cli/commands/implementations/conversation.py +0 -0
  48. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/cli/commands/implementations/debug.py +0 -0
  49. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/cli/commands/implementations/development.py +0 -0
  50. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/cli/commands/implementations/model.py +0 -0
  51. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/cli/commands/implementations/system.py +0 -0
  52. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/cli/commands/implementations/todo.py +0 -0
  53. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/cli/commands/registry.py +0 -0
  54. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/configuration/__init__.py +0 -0
  55. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/configuration/models.py +0 -0
  56. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/configuration/settings.py +0 -0
  57. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/context.py +0 -0
  58. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/core/__init__.py +0 -0
  59. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/core/agents/__init__.py +0 -0
  60. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/core/background/__init__.py +0 -0
  61. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/core/background/manager.py +0 -0
  62. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/core/code_index.py +0 -0
  63. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/core/llm/__init__.py +0 -0
  64. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/core/setup/__init__.py +0 -0
  65. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/core/setup/agent_setup.py +0 -0
  66. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/core/setup/base.py +0 -0
  67. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/core/setup/config_setup.py +0 -0
  68. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/core/setup/coordinator.py +0 -0
  69. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/core/setup/environment_setup.py +0 -0
  70. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/core/setup/git_safety_setup.py +0 -0
  71. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/core/token_usage/api_response_parser.py +0 -0
  72. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/core/token_usage/cost_calculator.py +0 -0
  73. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/core/token_usage/usage_tracker.py +0 -0
  74. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/core/tool_handler.py +0 -0
  75. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/prompts/system.md +0 -0
  76. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/py.typed +0 -0
  77. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/services/__init__.py +0 -0
  78. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/services/mcp.py +0 -0
  79. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/setup.py +0 -0
  80. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/tools/__init__.py +0 -0
  81. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/tools/base.py +0 -0
  82. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/tools/bash.py +0 -0
  83. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/tools/glob.py +0 -0
  84. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/tools/grep.py +0 -0
  85. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/tools/list_dir.py +0 -0
  86. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/tools/read_file.py +0 -0
  87. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/tools/read_file_async_poc.py +0 -0
  88. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/tools/run_command.py +0 -0
  89. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/tools/todo.py +0 -0
  90. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/tools/update_file.py +0 -0
  91. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/tools/write_file.py +0 -0
  92. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/types.py +0 -0
  93. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/ui/__init__.py +0 -0
  94. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/ui/completers.py +0 -0
  95. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/ui/console.py +0 -0
  96. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/ui/constants.py +0 -0
  97. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/ui/decorators.py +0 -0
  98. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/ui/lexers.py +0 -0
  99. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/ui/output.py +0 -0
  100. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/ui/prompt_manager.py +0 -0
  101. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/ui/tool_ui.py +0 -0
  102. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/ui/utils.py +0 -0
  103. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/ui/validators.py +0 -0
  104. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/utils/__init__.py +0 -0
  105. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/utils/bm25.py +0 -0
  106. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/utils/diff_utils.py +0 -0
  107. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/utils/file_utils.py +0 -0
  108. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/utils/import_cache.py +0 -0
  109. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/utils/message_utils.py +0 -0
  110. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/utils/ripgrep.py +0 -0
  111. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/utils/security.py +0 -0
  112. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/utils/system.py +0 -0
  113. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/utils/text_utils.py +0 -0
  114. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode/utils/user_configuration.py +0 -0
  115. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode_cli.egg-info/dependency_links.txt +0 -0
  116. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode_cli.egg-info/entry_points.txt +0 -0
  117. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode_cli.egg-info/requires.txt +0 -0
  118. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/src/tunacode_cli.egg-info/top_level.txt +0 -0
  119. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/agent/__init__.py +0 -0
  120. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/agent/conftest.py +0 -0
  121. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/agent/test_agent_creation.py +0 -0
  122. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/agent/test_json_tool_parsing.py +0 -0
  123. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/agent/test_process_node.py +0 -0
  124. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/agent/test_process_request.py +0 -0
  125. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/agent/test_tool_message_patching.py +0 -0
  126. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/background/test_background_edge_cases.py +0 -0
  127. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/background/test_cleanup.py +0 -0
  128. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/background/test_task_cancellation.py +0 -0
  129. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/background/test_task_creation.py +0 -0
  130. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/background/test_task_execution.py +0 -0
  131. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/code_index/test_cache_management.py +0 -0
  132. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/code_index/test_file_scanning.py +0 -0
  133. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/code_index/test_index_building.py +0 -0
  134. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/code_index/test_search_operations.py +0 -0
  135. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/code_index/test_symbol_extraction.py +0 -0
  136. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/commands/__init__.py +0 -0
  137. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/commands/test_init_command.py +0 -0
  138. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/conftest.py +0 -0
  139. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/context/__init__.py +0 -0
  140. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/context/test_context_acceptance.py +0 -0
  141. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/context/test_context_integration.py +0 -0
  142. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/context/test_context_loading.py +0 -0
  143. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/context/test_tunacode_logging.py +0 -0
  144. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/repl/test_command_parsing.py +0 -0
  145. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/repl/test_error_handling.py +0 -0
  146. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/repl/test_input_handling.py +0 -0
  147. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/repl/test_keyboard_interrupts.py +0 -0
  148. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/repl/test_multiline_input.py +0 -0
  149. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/repl/test_output_display_logic.py +0 -0
  150. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/repl/test_session_flow.py +0 -0
  151. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/services/test_error_recovery.py +0 -0
  152. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/services/test_llm_routing.py +0 -0
  153. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/services/test_mcp_integration.py +0 -0
  154. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/services/test_service_lifecycle.py +0 -0
  155. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/state/test_agent_tracking.py +0 -0
  156. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/state/test_message_history.py +0 -0
  157. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/state/test_permissions.py +0 -0
  158. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/state/test_session_management.py +0 -0
  159. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/state/test_state_initialization.py +0 -0
  160. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/state/test_user_config.py +0 -0
  161. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/test_characterization_commands.py +0 -0
  162. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/ui/test_async_ui.py +0 -0
  163. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/ui/test_console_output.py +0 -0
  164. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/ui/test_diff_display.py +0 -0
  165. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/ui/test_prompt_rendering.py +0 -0
  166. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/ui/test_tool_confirmations.py +0 -0
  167. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/utils/conftest.py +0 -0
  168. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/utils/test_expand_file_refs.py +0 -0
  169. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/utils/test_file_operations.py +0 -0
  170. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/utils/test_git_commands.py +0 -0
  171. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/utils/test_token_counting.py +0 -0
  172. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/characterization/utils/test_utils_edge_cases.py +0 -0
  173. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/conftest.py +0 -0
  174. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/crud/test_core_file_operations.py +0 -0
  175. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/fixtures/__init__.py +0 -0
  176. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/fixtures/file_operations.py +0 -0
  177. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/integration/test_error_recovery_flow.py +0 -0
  178. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/integration/test_full_session_flow.py +0 -0
  179. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/integration/test_mcp_tool_flow.py +0 -0
  180. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/integration/test_multi_tool_operations.py +0 -0
  181. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/integration/test_performance_scenarios.py +0 -0
  182. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/integration/test_usage_tracking_integration.py +0 -0
  183. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_actual_parallelism.py +0 -0
  184. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_agent_initialization.py +0 -0
  185. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_agent_output_formatting.py +0 -0
  186. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_api_response_parser.py +0 -0
  187. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_background_manager.py +0 -0
  188. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_characterization_agent_main.py +0 -0
  189. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_characterization_bash.py +0 -0
  190. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_characterization_commands_system.py +0 -0
  191. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_characterization_glob.py +0 -0
  192. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_characterization_grep.py +0 -0
  193. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_characterization_grep_performance.py +0 -0
  194. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_characterization_iteration_limits.py +0 -0
  195. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_characterization_list_dir.py +0 -0
  196. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_characterization_read_file.py +0 -0
  197. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_characterization_repl_utils.py +0 -0
  198. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_characterization_run_command.py +0 -0
  199. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_characterization_setup_system.py +0 -0
  200. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_characterization_tool_ui_behavior.py +0 -0
  201. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_characterization_update_file.py +0 -0
  202. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_characterization_utilities.py +0 -0
  203. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_characterization_write_file.py +0 -0
  204. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_cli_command_flow.py +0 -0
  205. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_cli_file_operations_integration.py +0 -0
  206. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_config_directory_creation.py +0 -0
  207. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_config_setup_async.py +0 -0
  208. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_cost_calculator.py +0 -0
  209. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_enhanced_visual_feedback.py +0 -0
  210. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_fallback_responses.py +0 -0
  211. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_fast_glob_search.py +0 -0
  212. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_file_operations_edge_cases.py +0 -0
  213. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_file_operations_stress.py +0 -0
  214. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_file_reference_context_tracking.py +0 -0
  215. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_file_reference_expansion.py +0 -0
  216. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_grep_fast_glob.py +0 -0
  217. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_grep_legacy_compat.py +0 -0
  218. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_grep_timeout.py +0 -0
  219. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_json_tool_parsing.py +0 -0
  220. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_list_dir.py +0 -0
  221. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_parallel_execution_demo.py +0 -0
  222. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_parallel_execution_freeze_fix.py +0 -0
  223. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_parallel_execution_integration.py +0 -0
  224. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_parallel_read_only_tools.py +0 -0
  225. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_parallel_tool_execution.py +0 -0
  226. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_prompt_changes_validation.py +0 -0
  227. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_read_only_confirmation.py +0 -0
  228. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_security.py +0 -0
  229. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_streaming_panel_tool_confirmation.py +0 -0
  230. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_streaming_spinner_conflict.py +0 -0
  231. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_todo_functionality.py +0 -0
  232. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_tool_categorization.py +0 -0
  233. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_tool_combinations.py +0 -0
  234. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_tool_handler_ui_messages.py +0 -0
  235. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_update_command.py +0 -0
  236. {tunacode_cli-0.0.47 → tunacode_cli-0.0.48}/tests/test_visual_parallel_feedback.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tunacode-cli
3
- Version: 0.0.47
3
+ Version: 0.0.48
4
4
  Summary: Your agentic CLI developer.
5
5
  Author-email: larock22 <noreply@github.com>
6
6
  License: MIT
@@ -37,7 +37,7 @@ Requires-Dist: textual-dev; extra == "dev"
37
37
  Requires-Dist: pre-commit; extra == "dev"
38
38
  Dynamic: license-file
39
39
 
40
- # TunaCode
40
+ # TunaCode CLI
41
41
 
42
42
  <div align="center">
43
43
 
@@ -48,7 +48,7 @@ Dynamic: license-file
48
48
 
49
49
  **AI-powered CLI coding assistant**
50
50
 
51
- ![TunaCode Example](assets/tunacode_example.png)
51
+ ![Demo](docs/assets/demo.gif)
52
52
 
53
53
  </div>
54
54
 
@@ -1,4 +1,4 @@
1
- # TunaCode
1
+ # TunaCode CLI
2
2
 
3
3
  <div align="center">
4
4
 
@@ -9,7 +9,7 @@
9
9
 
10
10
  **AI-powered CLI coding assistant**
11
11
 
12
- ![TunaCode Example](assets/tunacode_example.png)
12
+ ![Demo](docs/assets/demo.gif)
13
13
 
14
14
  </div>
15
15
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tunacode-cli"
7
- version = "0.0.47"
7
+ version = "0.0.48"
8
8
  description = "Your agentic CLI developer."
9
9
  keywords = ["cli", "agent", "development", "automation"]
10
10
  readme = "README.md"
@@ -5,7 +5,6 @@ Enhanced CLI entry point with better styling while staying CLI-based.
5
5
  """
6
6
 
7
7
  import asyncio
8
- import logging
9
8
 
10
9
  import typer
11
10
 
@@ -37,9 +36,6 @@ def main(
37
36
  ):
38
37
  """Start TunaCode - Your AI-powered development assistant"""
39
38
 
40
- # Configure logging to suppress INFO messages by default
41
- logging.basicConfig(level=logging.WARNING, force=True)
42
-
43
39
  async def async_main():
44
40
  if version:
45
41
  await ui.version()
@@ -344,7 +344,7 @@ async def process_request(text: str, state_manager: StateManager, output: bool =
344
344
  except CancelledError:
345
345
  await ui.muted(MSG_REQUEST_CANCELLED)
346
346
  except UserAbortError:
347
- await ui.muted(MSG_OPERATION_ABORTED_BY_USER)
347
+ await ui.muted(MSG_OPERATION_ABORTED)
348
348
  except UnexpectedModelBehavior as e:
349
349
  error_message = str(e)
350
350
  await ui.muted(error_message)
@@ -385,13 +385,9 @@ 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
-
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
388
+ await ui.muted(f"• Model: {model_name} • {context_display}")
389
+ await ui.success("Ready to assist")
390
+ await ui.line()
395
391
 
396
392
  instance = agent.get_or_create_agent(state_manager.session.current_model, state_manager)
397
393
 
@@ -463,16 +459,13 @@ async def repl(state_manager: StateManager):
463
459
  state_manager.session.current_task = get_app().create_background_task(
464
460
  process_request(line, state_manager)
465
461
  )
462
+ await state_manager.session.current_task
466
463
 
467
464
  state_manager.session.update_token_count()
468
465
  context_display = get_context_window_display(
469
466
  state_manager.session.total_tokens, state_manager.session.max_tokens
470
467
  )
471
- # Only show model/context info if thoughts are enabled
472
- if state_manager.session.show_thoughts:
473
- await ui.muted(
474
- f"• Model: {state_manager.session.current_model} • {context_display}"
475
- )
468
+ await ui.muted(f"• Model: {state_manager.session.current_model} {context_display}")
476
469
 
477
470
  if action == "restart":
478
471
  await repl(state_manager)
@@ -487,7 +480,7 @@ async def repl(state_manager: StateManager):
487
480
  total_cost = float(session_total.get("cost", 0) or 0)
488
481
 
489
482
  # Only show summary if we have actual token usage
490
- if state_manager.session.show_thoughts and (total_tokens > 0 or total_cost > 0):
483
+ if total_tokens > 0 or total_cost > 0:
491
484
  summary = (
492
485
  f"\n[bold cyan]TunaCode Session Summary[/bold cyan]\n"
493
486
  f" - Total Tokens: {total_tokens:,}\n"
@@ -24,6 +24,7 @@ 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
27
28
  },
28
29
  "mcpServers": {},
29
30
  }
@@ -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.47"
10
+ APP_VERSION = "0.0.48"
11
11
 
12
12
  # File patterns
13
13
  GUIDE_FILE_PATTERN = "{name}.md"
@@ -157,8 +157,3 @@ MAX_TODOS_PER_SESSION = 100
157
157
 
158
158
  # Maximum length for todo content
159
159
  MAX_TODO_CONTENT_LENGTH = 500
160
-
161
- # JSON parsing retry configuration
162
- JSON_PARSE_MAX_RETRIES = 10
163
- JSON_PARSE_BASE_DELAY = 0.1 # Initial delay in seconds
164
- JSON_PARSE_MAX_DELAY = 5.0 # Maximum delay in seconds
@@ -0,0 +1,223 @@
1
+ """DSPy Integration for TunaCode - Enhanced Tool Selection and Task Planning.
2
+
3
+ This module integrates DSPy's optimized prompts and tool selection logic
4
+ into TunaCode's agent system for 3x performance improvements.
5
+ """
6
+
7
+ import logging
8
+ import os
9
+ import re
10
+ from pathlib import Path
11
+ from typing import Any, Dict, List, Optional
12
+
13
+ from tunacode.core.state import StateManager
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class DSPyIntegration:
19
+ """Integrates DSPy optimization into TunaCode's agent system."""
20
+
21
+ def __init__(self, state_manager: StateManager):
22
+ self.state_manager = state_manager
23
+ self._dspy_agent = None
24
+ self._tool_selection_prompt = None
25
+ self._task_planning_prompt = None
26
+ self._load_prompts()
27
+
28
+ def _load_prompts(self):
29
+ """Load DSPy-optimized prompts from files."""
30
+ prompts_dir = Path(__file__).parent.parent.parent / "prompts"
31
+
32
+ try:
33
+ # Load tool selection prompt
34
+ tool_selection_path = prompts_dir / "dspy_tool_selection.md"
35
+ if tool_selection_path.exists():
36
+ self._tool_selection_prompt = tool_selection_path.read_text(encoding="utf-8")
37
+ logger.debug("Loaded DSPy tool selection prompt")
38
+
39
+ # Load task planning prompt
40
+ task_planning_path = prompts_dir / "dspy_task_planning.md"
41
+ if task_planning_path.exists():
42
+ self._task_planning_prompt = task_planning_path.read_text(encoding="utf-8")
43
+ logger.debug("Loaded DSPy task planning prompt")
44
+ except Exception as e:
45
+ logger.error(f"Failed to load DSPy prompts: {e}")
46
+
47
+ def get_dspy_agent(self, api_key: Optional[str] = None):
48
+ """Get or create the DSPy agent instance."""
49
+ if self._dspy_agent is None:
50
+ try:
51
+ # Import DSPy components
52
+ from tunacode.core.agents.dspy_tunacode import create_optimized_agent
53
+
54
+ # Use API key from environment or config
55
+ if not api_key:
56
+ api_key = os.getenv(
57
+ "OPENROUTER_API_KEY"
58
+ ) or self.state_manager.session.user_config.get("env", {}).get(
59
+ "OPENROUTER_API_KEY"
60
+ )
61
+
62
+ if api_key:
63
+ self._dspy_agent = create_optimized_agent(api_key)
64
+ logger.info("DSPy agent initialized successfully")
65
+ else:
66
+ logger.warning("No OpenRouter API key found for DSPy optimization")
67
+ except Exception as e:
68
+ logger.error(f"Failed to initialize DSPy agent: {e}")
69
+
70
+ return self._dspy_agent
71
+
72
+ def enhance_system_prompt(self, base_prompt: str) -> str:
73
+ """Enhance the system prompt with DSPy optimizations."""
74
+ if not self._tool_selection_prompt:
75
+ return base_prompt
76
+
77
+ # Extract the learned patterns from DSPy prompts
78
+ enhanced_sections = []
79
+
80
+ # Add DSPy tool selection insights
81
+ enhanced_sections.append("\n\n# DSPy-Optimized Tool Selection Patterns\n")
82
+ enhanced_sections.append("**Based on learned optimization patterns:**\n")
83
+ enhanced_sections.append("- Always batch 3-4 read-only tools for parallel execution")
84
+ enhanced_sections.append("- Group grep, list_dir, glob, read_file operations together")
85
+ enhanced_sections.append("- Execute write/modify operations sequentially")
86
+ enhanced_sections.append("- Use Chain of Thought reasoning for tool selection\n")
87
+
88
+ # Add specific examples from DSPy prompt
89
+ if "Example" in self._tool_selection_prompt:
90
+ enhanced_sections.append("\n## Optimal Tool Batching Examples:\n")
91
+ # Extract examples section
92
+ examples_match = re.search(
93
+ r"### Example.*?(?=###|\Z)", self._tool_selection_prompt, re.DOTALL
94
+ )
95
+ if examples_match:
96
+ enhanced_sections.append(examples_match.group(0))
97
+
98
+ return base_prompt + "".join(enhanced_sections)
99
+
100
+ def should_use_task_planner(self, user_request: str) -> bool:
101
+ """Determine if the request is complex enough for task planning."""
102
+ complex_indicators = [
103
+ "implement",
104
+ "create",
105
+ "build",
106
+ "refactor",
107
+ "add feature",
108
+ "fix all",
109
+ "update multiple",
110
+ "migrate",
111
+ "integrate",
112
+ "debug",
113
+ "optimize performance",
114
+ "authentication",
115
+ "setup",
116
+ ]
117
+
118
+ request_lower = user_request.lower()
119
+
120
+ # Check for multiple files
121
+ file_pattern = r"\b\w+\.\w+\b"
122
+ files_mentioned = len(re.findall(file_pattern, user_request)) > 2
123
+
124
+ # Check for complex keywords
125
+ has_complex_keyword = any(indicator in request_lower for indicator in complex_indicators)
126
+
127
+ # Check for multiple operations
128
+ operation_words = ["and", "then", "also", "after", "before", "plus"]
129
+ has_multiple_ops = sum(1 for word in operation_words if word in request_lower) >= 2
130
+
131
+ return files_mentioned or has_complex_keyword or has_multiple_ops
132
+
133
+ def optimize_tool_selection(
134
+ self, user_request: str, tools_to_execute: List[Dict[str, Any]]
135
+ ) -> List[List[Dict[str, Any]]]:
136
+ """Optimize tool selection using DSPy patterns.
137
+
138
+ Returns tool calls organized in optimal batches for parallel execution.
139
+ """
140
+ if not tools_to_execute:
141
+ return []
142
+
143
+ # Try to use DSPy agent if available
144
+ dspy_agent = self.get_dspy_agent()
145
+ if dspy_agent:
146
+ try:
147
+ result = dspy_agent(user_request, self.state_manager.session.cwd or ".")
148
+ if hasattr(result, "tool_batches") and result.tool_batches:
149
+ return result.tool_batches
150
+ except Exception as e:
151
+ logger.debug(f"DSPy optimization failed, using fallback: {e}")
152
+
153
+ # Fallback: Apply DSPy-learned patterns manually
154
+ return self._apply_dspy_patterns(tools_to_execute)
155
+
156
+ def _apply_dspy_patterns(self, tools: List[Dict[str, Any]]) -> List[List[Dict[str, Any]]]:
157
+ """Apply DSPy-learned batching patterns manually."""
158
+ from tunacode.constants import READ_ONLY_TOOLS
159
+
160
+ batches = []
161
+ current_batch = []
162
+
163
+ for tool in tools:
164
+ tool_name = tool.get("tool", "")
165
+
166
+ if tool_name in READ_ONLY_TOOLS:
167
+ current_batch.append(tool)
168
+ # Optimal batch size is 3-4 tools
169
+ if len(current_batch) >= 4:
170
+ batches.append(current_batch)
171
+ current_batch = []
172
+ else:
173
+ # Flush current batch if any
174
+ if current_batch:
175
+ batches.append(current_batch)
176
+ current_batch = []
177
+ # Add write/execute tool as single batch
178
+ batches.append([tool])
179
+
180
+ # Add remaining tools
181
+ if current_batch:
182
+ batches.append(current_batch)
183
+
184
+ return batches
185
+
186
+ def get_task_breakdown(self, complex_request: str) -> Optional[Dict[str, Any]]:
187
+ """Get task breakdown for complex requests using DSPy."""
188
+ dspy_agent = self.get_dspy_agent()
189
+ if not dspy_agent:
190
+ return None
191
+
192
+ try:
193
+ result = dspy_agent(complex_request, self.state_manager.session.cwd or ".")
194
+ if result.get("is_complex") and result.get("subtasks"):
195
+ return {
196
+ "subtasks": result["subtasks"],
197
+ "total_tool_calls": result.get("total_tool_calls", 0),
198
+ "requires_todo": result.get("requires_todo", False),
199
+ "parallelization_opportunities": result.get("parallelization_opportunities", 0),
200
+ }
201
+ except Exception as e:
202
+ logger.error(f"Failed to get task breakdown: {e}")
203
+
204
+ return None
205
+
206
+ def format_chain_of_thought(self, request: str, tools: List[str]) -> str:
207
+ """Format a Chain of Thought reasoning for tool selection."""
208
+ reasoning = f"Let's think step by step about '{request}':\n"
209
+
210
+ if "search" in request.lower() or "find" in request.lower():
211
+ reasoning += "1. This requires searching for information\n"
212
+ reasoning += "2. I'll use grep for content search and glob for file patterns\n"
213
+ reasoning += "3. These read-only tools can be executed in parallel\n"
214
+ elif "read" in request.lower() or "show" in request.lower():
215
+ reasoning += "1. This requires reading file contents\n"
216
+ reasoning += "2. I'll batch multiple read_file operations together\n"
217
+ reasoning += "3. All reads can happen in parallel for speed\n"
218
+ elif "fix" in request.lower() or "update" in request.lower():
219
+ reasoning += "1. First, I need to understand the current state\n"
220
+ reasoning += "2. I'll search and read relevant files in parallel\n"
221
+ reasoning += "3. Then make modifications sequentially for safety\n"
222
+
223
+ return reasoning