tunacode-cli 0.0.41__tar.gz → 0.0.42__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.41 → tunacode_cli-0.0.42}/CLAUDE.md +4 -0
  2. {tunacode_cli-0.0.41/src/tunacode_cli.egg-info → tunacode_cli-0.0.42}/PKG-INFO +3 -1
  3. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/pyproject.toml +3 -1
  4. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/cli/repl.py +8 -4
  5. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/configuration/defaults.py +1 -0
  6. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/constants.py +6 -1
  7. tunacode_cli-0.0.42/src/tunacode/core/agents/dspy_integration.py +223 -0
  8. tunacode_cli-0.0.42/src/tunacode/core/agents/dspy_tunacode.py +458 -0
  9. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/core/agents/main.py +130 -3
  10. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/core/agents/utils.py +54 -6
  11. tunacode_cli-0.0.42/src/tunacode/core/recursive/__init__.py +18 -0
  12. tunacode_cli-0.0.42/src/tunacode/core/recursive/aggregator.py +467 -0
  13. tunacode_cli-0.0.42/src/tunacode/core/recursive/budget.py +414 -0
  14. tunacode_cli-0.0.42/src/tunacode/core/recursive/decomposer.py +398 -0
  15. tunacode_cli-0.0.42/src/tunacode/core/recursive/executor.py +467 -0
  16. tunacode_cli-0.0.42/src/tunacode/core/recursive/hierarchy.py +487 -0
  17. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/core/state.py +41 -0
  18. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/exceptions.py +23 -0
  19. tunacode_cli-0.0.42/src/tunacode/prompts/dspy_task_planning.md +45 -0
  20. tunacode_cli-0.0.42/src/tunacode/prompts/dspy_tool_selection.md +58 -0
  21. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/ui/console.py +1 -1
  22. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/ui/output.py +2 -1
  23. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/ui/panels.py +4 -1
  24. tunacode_cli-0.0.42/src/tunacode/ui/recursive_progress.py +380 -0
  25. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/ui/tool_ui.py +24 -6
  26. tunacode_cli-0.0.42/src/tunacode/ui/utils.py +3 -0
  27. tunacode_cli-0.0.42/src/tunacode/utils/retry.py +163 -0
  28. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42/src/tunacode_cli.egg-info}/PKG-INFO +3 -1
  29. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode_cli.egg-info/SOURCES.txt +17 -1
  30. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode_cli.egg-info/requires.txt +2 -0
  31. tunacode_cli-0.0.42/tests/test_dspy_integration.py +127 -0
  32. tunacode_cli-0.0.42/tests/test_json_retry.py +230 -0
  33. tunacode_cli-0.0.42/tests/test_tool_batching_retry.py +287 -0
  34. tunacode_cli-0.0.42/tests/unit/test_recursive_executor.py +218 -0
  35. tunacode_cli-0.0.41/src/tunacode/ui/utils.py +0 -3
  36. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/LICENSE +0 -0
  37. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/MANIFEST.in +0 -0
  38. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/README.md +0 -0
  39. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/TUNACODE.md +0 -0
  40. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/setup.cfg +0 -0
  41. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/setup.py +0 -0
  42. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/__init__.py +0 -0
  43. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/cli/__init__.py +0 -0
  44. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/cli/commands/__init__.py +0 -0
  45. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/cli/commands/base.py +0 -0
  46. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/cli/commands/implementations/__init__.py +0 -0
  47. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/cli/commands/implementations/conversation.py +0 -0
  48. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/cli/commands/implementations/debug.py +0 -0
  49. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/cli/commands/implementations/development.py +0 -0
  50. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/cli/commands/implementations/model.py +0 -0
  51. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/cli/commands/implementations/system.py +0 -0
  52. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/cli/commands/implementations/todo.py +0 -0
  53. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/cli/commands/registry.py +0 -0
  54. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/cli/main.py +0 -0
  55. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/configuration/__init__.py +0 -0
  56. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/configuration/models.py +0 -0
  57. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/configuration/settings.py +0 -0
  58. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/context.py +0 -0
  59. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/core/__init__.py +0 -0
  60. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/core/agents/__init__.py +0 -0
  61. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/core/background/__init__.py +0 -0
  62. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/core/background/manager.py +0 -0
  63. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/core/code_index.py +0 -0
  64. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/core/llm/__init__.py +0 -0
  65. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/core/setup/__init__.py +0 -0
  66. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/core/setup/agent_setup.py +0 -0
  67. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/core/setup/base.py +0 -0
  68. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/core/setup/config_setup.py +0 -0
  69. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/core/setup/coordinator.py +0 -0
  70. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/core/setup/environment_setup.py +0 -0
  71. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/core/setup/git_safety_setup.py +0 -0
  72. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/core/token_usage/api_response_parser.py +0 -0
  73. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/core/token_usage/cost_calculator.py +0 -0
  74. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/core/token_usage/usage_tracker.py +0 -0
  75. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/core/tool_handler.py +0 -0
  76. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/prompts/system.md +0 -0
  77. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/py.typed +0 -0
  78. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/services/__init__.py +0 -0
  79. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/services/mcp.py +0 -0
  80. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/setup.py +0 -0
  81. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/tools/__init__.py +0 -0
  82. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/tools/base.py +0 -0
  83. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/tools/bash.py +0 -0
  84. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/tools/glob.py +0 -0
  85. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/tools/grep.py +0 -0
  86. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/tools/list_dir.py +0 -0
  87. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/tools/read_file.py +0 -0
  88. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/tools/read_file_async_poc.py +0 -0
  89. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/tools/run_command.py +0 -0
  90. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/tools/todo.py +0 -0
  91. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/tools/update_file.py +0 -0
  92. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/tools/write_file.py +0 -0
  93. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/types.py +0 -0
  94. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/ui/__init__.py +0 -0
  95. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/ui/completers.py +0 -0
  96. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/ui/constants.py +0 -0
  97. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/ui/decorators.py +0 -0
  98. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/ui/input.py +0 -0
  99. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/ui/keybindings.py +0 -0
  100. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/ui/lexers.py +0 -0
  101. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/ui/prompt_manager.py +0 -0
  102. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/ui/validators.py +0 -0
  103. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/utils/__init__.py +0 -0
  104. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/utils/bm25.py +0 -0
  105. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/utils/diff_utils.py +0 -0
  106. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/utils/file_utils.py +0 -0
  107. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/utils/import_cache.py +0 -0
  108. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/utils/message_utils.py +0 -0
  109. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/utils/ripgrep.py +0 -0
  110. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/utils/security.py +0 -0
  111. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/utils/system.py +0 -0
  112. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/utils/text_utils.py +0 -0
  113. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/utils/token_counter.py +0 -0
  114. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode/utils/user_configuration.py +0 -0
  115. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode_cli.egg-info/dependency_links.txt +0 -0
  116. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode_cli.egg-info/entry_points.txt +0 -0
  117. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/src/tunacode_cli.egg-info/top_level.txt +0 -0
  118. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/agent/__init__.py +0 -0
  119. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/agent/conftest.py +0 -0
  120. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/agent/test_agent_creation.py +0 -0
  121. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/agent/test_json_tool_parsing.py +0 -0
  122. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/agent/test_process_node.py +0 -0
  123. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/agent/test_process_request.py +0 -0
  124. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/agent/test_tool_message_patching.py +0 -0
  125. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/background/test_background_edge_cases.py +0 -0
  126. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/background/test_cleanup.py +0 -0
  127. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/background/test_task_cancellation.py +0 -0
  128. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/background/test_task_creation.py +0 -0
  129. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/background/test_task_execution.py +0 -0
  130. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/code_index/test_cache_management.py +0 -0
  131. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/code_index/test_file_scanning.py +0 -0
  132. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/code_index/test_index_building.py +0 -0
  133. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/code_index/test_search_operations.py +0 -0
  134. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/code_index/test_symbol_extraction.py +0 -0
  135. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/commands/__init__.py +0 -0
  136. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/commands/test_init_command.py +0 -0
  137. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/conftest.py +0 -0
  138. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/context/__init__.py +0 -0
  139. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/context/test_context_acceptance.py +0 -0
  140. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/context/test_context_integration.py +0 -0
  141. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/context/test_context_loading.py +0 -0
  142. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/context/test_tunacode_logging.py +0 -0
  143. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/repl/test_command_parsing.py +0 -0
  144. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/repl/test_error_handling.py +0 -0
  145. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/repl/test_input_handling.py +0 -0
  146. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/repl/test_keyboard_interrupts.py +0 -0
  147. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/repl/test_multiline_input.py +0 -0
  148. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/repl/test_output_display_logic.py +0 -0
  149. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/repl/test_repl_initialization.py +0 -0
  150. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/repl/test_session_flow.py +0 -0
  151. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/services/test_error_recovery.py +0 -0
  152. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/services/test_llm_routing.py +0 -0
  153. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/services/test_mcp_integration.py +0 -0
  154. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/services/test_service_lifecycle.py +0 -0
  155. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/state/test_agent_tracking.py +0 -0
  156. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/state/test_message_history.py +0 -0
  157. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/state/test_permissions.py +0 -0
  158. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/state/test_session_management.py +0 -0
  159. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/state/test_state_initialization.py +0 -0
  160. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/state/test_user_config.py +0 -0
  161. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/test_characterization_commands.py +0 -0
  162. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/ui/test_async_ui.py +0 -0
  163. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/ui/test_console_output.py +0 -0
  164. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/ui/test_diff_display.py +0 -0
  165. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/ui/test_prompt_rendering.py +0 -0
  166. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/ui/test_tool_confirmations.py +0 -0
  167. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/utils/conftest.py +0 -0
  168. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/utils/test_expand_file_refs.py +0 -0
  169. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/utils/test_file_operations.py +0 -0
  170. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/utils/test_git_commands.py +0 -0
  171. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/utils/test_token_counting.py +0 -0
  172. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/characterization/utils/test_utils_edge_cases.py +0 -0
  173. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/conftest.py +0 -0
  174. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/crud/test_core_file_operations.py +0 -0
  175. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/fixtures/__init__.py +0 -0
  176. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/fixtures/file_operations.py +0 -0
  177. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/integration/test_error_recovery_flow.py +0 -0
  178. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/integration/test_full_session_flow.py +0 -0
  179. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/integration/test_mcp_tool_flow.py +0 -0
  180. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/integration/test_multi_tool_operations.py +0 -0
  181. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/integration/test_performance_scenarios.py +0 -0
  182. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/integration/test_usage_tracking_integration.py +0 -0
  183. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_actual_parallelism.py +0 -0
  184. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_agent_initialization.py +0 -0
  185. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_agent_output_formatting.py +0 -0
  186. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_api_response_parser.py +0 -0
  187. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_background_manager.py +0 -0
  188. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_characterization_agent_main.py +0 -0
  189. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_characterization_bash.py +0 -0
  190. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_characterization_commands_system.py +0 -0
  191. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_characterization_glob.py +0 -0
  192. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_characterization_grep.py +0 -0
  193. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_characterization_grep_performance.py +0 -0
  194. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_characterization_iteration_limits.py +0 -0
  195. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_characterization_list_dir.py +0 -0
  196. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_characterization_read_file.py +0 -0
  197. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_characterization_repl_utils.py +0 -0
  198. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_characterization_run_command.py +0 -0
  199. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_characterization_setup_system.py +0 -0
  200. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_characterization_tool_ui_behavior.py +0 -0
  201. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_characterization_update_file.py +0 -0
  202. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_characterization_utilities.py +0 -0
  203. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_characterization_write_file.py +0 -0
  204. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_cli_command_flow.py +0 -0
  205. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_cli_file_operations_integration.py +0 -0
  206. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_config_directory_creation.py +0 -0
  207. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_config_setup_async.py +0 -0
  208. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_cost_calculator.py +0 -0
  209. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_enhanced_visual_feedback.py +0 -0
  210. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_fallback_responses.py +0 -0
  211. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_fast_glob_search.py +0 -0
  212. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_file_operations_edge_cases.py +0 -0
  213. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_file_operations_stress.py +0 -0
  214. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_file_reference_context_tracking.py +0 -0
  215. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_file_reference_expansion.py +0 -0
  216. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_grep_fast_glob.py +0 -0
  217. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_grep_legacy_compat.py +0 -0
  218. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_grep_timeout.py +0 -0
  219. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_json_tool_parsing.py +0 -0
  220. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_list_dir.py +0 -0
  221. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_parallel_execution_demo.py +0 -0
  222. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_parallel_execution_freeze_fix.py +0 -0
  223. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_parallel_execution_integration.py +0 -0
  224. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_parallel_read_only_tools.py +0 -0
  225. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_parallel_tool_execution.py +0 -0
  226. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_prompt_changes_validation.py +0 -0
  227. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_read_only_confirmation.py +0 -0
  228. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_security.py +0 -0
  229. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_streaming_panel_tool_confirmation.py +0 -0
  230. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_streaming_spinner_conflict.py +0 -0
  231. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_todo_functionality.py +0 -0
  232. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_tool_categorization.py +0 -0
  233. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_tool_combinations.py +0 -0
  234. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_tool_handler_ui_messages.py +0 -0
  235. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_update_command.py +0 -0
  236. {tunacode_cli-0.0.41 → tunacode_cli-0.0.42}/tests/test_visual_parallel_feedback.py +0 -0
@@ -249,3 +249,7 @@ Follow this code styling
249
249
  | 8 | **Explaining Variable** | Extract a sub-expression into a well-named variable to record intent |
250
250
  | 9 | **Explaining Constant** | Replace magic literals with symbolic constants that broadcast meaning |
251
251
  | 10 | **Explicit Parameters** | Split a routine so all inputs are passed openly, banishing hidden state or maps |
252
+
253
+ ## Task Master AI Instructions
254
+ **Import Task Master's development workflow commands and guidelines, treat as if import is in the main CLAUDE.md file.**
255
+ @./.taskmaster/CLAUDE.md
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tunacode-cli
3
- Version: 0.0.41
3
+ Version: 0.0.42
4
4
  Summary: Your agentic CLI developer.
5
5
  Author-email: larock22 <noreply@github.com>
6
6
  License-Expression: MIT
@@ -25,6 +25,8 @@ 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
28
30
  Provides-Extra: dev
29
31
  Requires-Dist: build; extra == "dev"
30
32
  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.41"
7
+ version = "0.0.42"
8
8
  description = "Your agentic CLI developer."
9
9
  keywords = ["cli", "agent", "development", "automation"]
10
10
  readme = "README.md"
@@ -31,6 +31,8 @@ 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",
34
36
  ]
35
37
 
36
38
  [project.scripts]
@@ -433,15 +433,19 @@ async def repl(state_manager: StateManager):
433
433
  capture_output=False,
434
434
  )
435
435
  if result.returncode != 0:
436
- print(f"\nCommand exited with code {result.returncode}")
436
+ ui.console.print(
437
+ f"\nCommand exited with code {result.returncode}"
438
+ )
437
439
  except CommandSecurityError as e:
438
- print(f"\nSecurity validation failed: {str(e)}")
439
- print("If you need to run this command, please ensure it's safe.")
440
+ ui.console.print(f"\nSecurity validation failed: {str(e)}")
441
+ ui.console.print(
442
+ "If you need to run this command, please ensure it's safe."
443
+ )
440
444
  else:
441
445
  shell = os.environ.get(SHELL_ENV_VAR, DEFAULT_SHELL)
442
446
  subprocess.run(shell) # Interactive shell is safe
443
447
  except Exception as e:
444
- print(f"\nShell command failed: {str(e)}")
448
+ ui.console.print(f"\nShell command failed: {str(e)}")
445
449
 
446
450
  await run_in_terminal(run_shell)
447
451
  await ui.line()
@@ -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.41"
10
+ APP_VERSION = "0.0.42"
11
11
 
12
12
  # File patterns
13
13
  GUIDE_FILE_PATTERN = "{name}.md"
@@ -157,3 +157,8 @@ 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