auto-coder 1.0.0__py3-none-any.whl → 2.0.0__py3-none-any.whl

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 auto-coder might be problematic. Click here for more details.

Files changed (574) hide show
  1. auto_coder-2.0.0.dist-info/LICENSE +158 -0
  2. auto_coder-2.0.0.dist-info/METADATA +558 -0
  3. auto_coder-2.0.0.dist-info/RECORD +795 -0
  4. {auto_coder-1.0.0.dist-info → auto_coder-2.0.0.dist-info}/WHEEL +1 -1
  5. {auto_coder-1.0.0.dist-info → auto_coder-2.0.0.dist-info}/entry_points.txt +3 -3
  6. autocoder/__init__.py +31 -0
  7. autocoder/agent/auto_filegroup.py +32 -13
  8. autocoder/agent/auto_learn_from_commit.py +9 -1
  9. autocoder/agent/base_agentic/__init__.py +3 -0
  10. autocoder/agent/base_agentic/agent_hub.py +1 -1
  11. autocoder/agent/base_agentic/base_agent.py +235 -136
  12. autocoder/agent/base_agentic/default_tools.py +119 -118
  13. autocoder/agent/base_agentic/test_base_agent.py +1 -1
  14. autocoder/agent/base_agentic/tool_registry.py +32 -20
  15. autocoder/agent/base_agentic/tools/read_file_tool_resolver.py +24 -3
  16. autocoder/agent/base_agentic/tools/write_to_file_tool_resolver.py +24 -11
  17. autocoder/agent/base_agentic/types.py +42 -0
  18. autocoder/agent/entry_command_agent/chat.py +73 -59
  19. autocoder/auto_coder.py +31 -40
  20. autocoder/auto_coder_rag.py +11 -1084
  21. autocoder/auto_coder_runner.py +970 -2345
  22. autocoder/auto_coder_terminal.py +26 -0
  23. autocoder/auto_coder_terminal_v3.py +190 -0
  24. autocoder/chat/conf_command.py +224 -124
  25. autocoder/chat/models_command.py +361 -299
  26. autocoder/chat/rules_command.py +79 -31
  27. autocoder/chat_auto_coder.py +988 -398
  28. autocoder/chat_auto_coder_lang.py +23 -732
  29. autocoder/commands/auto_command.py +25 -8
  30. autocoder/commands/auto_web.py +1 -1
  31. autocoder/commands/tools.py +44 -44
  32. autocoder/common/__init__.py +150 -128
  33. autocoder/common/ac_style_command_parser/__init__.py +39 -2
  34. autocoder/common/ac_style_command_parser/config.py +422 -0
  35. autocoder/common/ac_style_command_parser/parser.py +292 -78
  36. autocoder/common/ac_style_command_parser/test_parser.py +241 -16
  37. autocoder/common/ac_style_command_parser/test_typed_parser.py +342 -0
  38. autocoder/common/ac_style_command_parser/typed_parser.py +653 -0
  39. autocoder/common/action_yml_file_manager.py +25 -13
  40. autocoder/common/agent_events/__init__.py +52 -0
  41. autocoder/common/agent_events/agent_event_emitter.py +193 -0
  42. autocoder/common/agent_events/event_factory.py +177 -0
  43. autocoder/common/agent_events/examples.py +307 -0
  44. autocoder/common/agent_events/types.py +113 -0
  45. autocoder/common/agent_events/utils.py +68 -0
  46. autocoder/common/agent_hooks/__init__.py +44 -0
  47. autocoder/common/agent_hooks/examples.py +582 -0
  48. autocoder/common/agent_hooks/hook_executor.py +217 -0
  49. autocoder/common/agent_hooks/hook_manager.py +288 -0
  50. autocoder/common/agent_hooks/types.py +133 -0
  51. autocoder/common/agent_hooks/utils.py +99 -0
  52. autocoder/common/agent_query_queue/queue_executor.py +324 -0
  53. autocoder/common/agent_query_queue/queue_manager.py +325 -0
  54. autocoder/common/agents/__init__.py +11 -0
  55. autocoder/common/agents/agent_manager.py +323 -0
  56. autocoder/common/agents/agent_parser.py +189 -0
  57. autocoder/common/agents/example_usage.py +344 -0
  58. autocoder/common/agents/integration_example.py +330 -0
  59. autocoder/common/agents/test_agent_parser.py +545 -0
  60. autocoder/common/async_utils.py +101 -0
  61. autocoder/common/auto_coder_lang.py +23 -972
  62. autocoder/common/autocoderargs_parser/__init__.py +14 -0
  63. autocoder/common/autocoderargs_parser/parser.py +184 -0
  64. autocoder/common/autocoderargs_parser/tests/__init__.py +1 -0
  65. autocoder/common/autocoderargs_parser/tests/test_args_parser.py +235 -0
  66. autocoder/common/autocoderargs_parser/tests/test_token_parser.py +195 -0
  67. autocoder/common/autocoderargs_parser/token_parser.py +290 -0
  68. autocoder/common/buildin_tokenizer.py +2 -4
  69. autocoder/common/code_auto_generate.py +149 -74
  70. autocoder/common/code_auto_generate_diff.py +163 -70
  71. autocoder/common/code_auto_generate_editblock.py +179 -89
  72. autocoder/common/code_auto_generate_strict_diff.py +167 -72
  73. autocoder/common/code_auto_merge_editblock.py +13 -6
  74. autocoder/common/code_modification_ranker.py +1 -1
  75. autocoder/common/command_completer.py +3 -3
  76. autocoder/common/command_file_manager/manager.py +183 -47
  77. autocoder/common/command_file_manager/test_command_file_manager.py +507 -0
  78. autocoder/common/command_templates.py +1 -1
  79. autocoder/common/conf_utils.py +2 -4
  80. autocoder/common/conversations/config.py +11 -3
  81. autocoder/common/conversations/get_conversation_manager.py +100 -2
  82. autocoder/common/conversations/llm_stats_models.py +264 -0
  83. autocoder/common/conversations/manager.py +112 -28
  84. autocoder/common/conversations/models.py +16 -2
  85. autocoder/common/conversations/storage/index_manager.py +134 -10
  86. autocoder/common/core_config/__init__.py +63 -0
  87. autocoder/common/core_config/agentic_mode_manager.py +109 -0
  88. autocoder/common/core_config/base_manager.py +123 -0
  89. autocoder/common/core_config/compatibility.py +151 -0
  90. autocoder/common/core_config/config_manager.py +156 -0
  91. autocoder/common/core_config/conversation_manager.py +31 -0
  92. autocoder/common/core_config/exclude_manager.py +72 -0
  93. autocoder/common/core_config/file_manager.py +177 -0
  94. autocoder/common/core_config/human_as_model_manager.py +129 -0
  95. autocoder/common/core_config/lib_manager.py +54 -0
  96. autocoder/common/core_config/main_manager.py +81 -0
  97. autocoder/common/core_config/mode_manager.py +126 -0
  98. autocoder/common/core_config/models.py +70 -0
  99. autocoder/common/core_config/test_memory_manager.py +1056 -0
  100. autocoder/common/env_manager.py +282 -0
  101. autocoder/common/env_manager_usage_example.py +211 -0
  102. autocoder/common/file_checkpoint/conversation_checkpoint.py +19 -19
  103. autocoder/common/file_checkpoint/manager.py +264 -48
  104. autocoder/common/file_checkpoint/test_backup.py +1 -18
  105. autocoder/common/file_checkpoint/test_manager.py +270 -1
  106. autocoder/common/file_checkpoint/test_store.py +1 -17
  107. autocoder/common/file_handler/__init__.py +23 -0
  108. autocoder/common/file_handler/active_context_handler.py +159 -0
  109. autocoder/common/file_handler/add_files_handler.py +409 -0
  110. autocoder/common/file_handler/chat_handler.py +180 -0
  111. autocoder/common/file_handler/coding_handler.py +401 -0
  112. autocoder/common/file_handler/commit_handler.py +200 -0
  113. autocoder/common/file_handler/lib_handler.py +156 -0
  114. autocoder/common/file_handler/list_files_handler.py +111 -0
  115. autocoder/common/file_handler/mcp_handler.py +268 -0
  116. autocoder/common/file_handler/models_handler.py +493 -0
  117. autocoder/common/file_handler/remove_files_handler.py +172 -0
  118. autocoder/common/git_utils.py +44 -8
  119. autocoder/common/global_cancel.py +15 -6
  120. autocoder/common/ignorefiles/test_ignore_file_utils.py +1 -1
  121. autocoder/common/international/__init__.py +31 -0
  122. autocoder/common/international/demo_international.py +92 -0
  123. autocoder/common/international/message_manager.py +157 -0
  124. autocoder/common/international/messages/__init__.py +56 -0
  125. autocoder/common/international/messages/async_command_messages.py +507 -0
  126. autocoder/common/international/messages/auto_coder_messages.py +2208 -0
  127. autocoder/common/international/messages/chat_auto_coder_messages.py +1547 -0
  128. autocoder/common/international/messages/command_help_messages.py +986 -0
  129. autocoder/common/international/messages/conversation_command_messages.py +191 -0
  130. autocoder/common/international/messages/git_helper_plugin_messages.py +159 -0
  131. autocoder/common/international/messages/queue_command_messages.py +751 -0
  132. autocoder/common/international/messages/rules_command_messages.py +77 -0
  133. autocoder/common/international/messages/sdk_messages.py +1707 -0
  134. autocoder/common/international/messages/token_helper_plugin_messages.py +361 -0
  135. autocoder/common/international/messages/tool_display_messages.py +1212 -0
  136. autocoder/common/international/messages/workflow_exception_messages.py +473 -0
  137. autocoder/common/international/test_international.py +612 -0
  138. autocoder/common/linter_core/__init__.py +28 -0
  139. autocoder/common/linter_core/base_linter.py +61 -0
  140. autocoder/common/linter_core/config_loader.py +271 -0
  141. autocoder/common/linter_core/formatters/__init__.py +0 -0
  142. autocoder/common/linter_core/formatters/base_formatter.py +38 -0
  143. autocoder/common/linter_core/formatters/raw_formatter.py +17 -0
  144. autocoder/common/linter_core/linter.py +166 -0
  145. autocoder/common/linter_core/linter_factory.py +216 -0
  146. autocoder/common/linter_core/linter_manager.py +333 -0
  147. autocoder/common/linter_core/linters/__init__.py +9 -0
  148. autocoder/common/linter_core/linters/java_linter.py +342 -0
  149. autocoder/common/linter_core/linters/python_linter.py +115 -0
  150. autocoder/common/linter_core/linters/typescript_linter.py +119 -0
  151. autocoder/common/linter_core/models/__init__.py +7 -0
  152. autocoder/common/linter_core/models/lint_result.py +91 -0
  153. autocoder/common/linter_core/models.py +33 -0
  154. autocoder/common/linter_core/tests/__init__.py +3 -0
  155. autocoder/common/linter_core/tests/test_config_loader.py +323 -0
  156. autocoder/common/linter_core/tests/test_config_loading.py +308 -0
  157. autocoder/common/linter_core/tests/test_factory_manager.py +234 -0
  158. autocoder/common/linter_core/tests/test_formatters.py +147 -0
  159. autocoder/common/linter_core/tests/test_integration.py +317 -0
  160. autocoder/common/linter_core/tests/test_java_linter.py +496 -0
  161. autocoder/common/linter_core/tests/test_linters.py +265 -0
  162. autocoder/common/linter_core/tests/test_models.py +81 -0
  163. autocoder/common/linter_core/tests/verify_config_loading.py +296 -0
  164. autocoder/common/linter_core/tests/verify_fixes.py +183 -0
  165. autocoder/common/llm_friendly_package/__init__.py +31 -0
  166. autocoder/common/llm_friendly_package/base_manager.py +102 -0
  167. autocoder/common/llm_friendly_package/docs_manager.py +121 -0
  168. autocoder/common/llm_friendly_package/library_manager.py +171 -0
  169. autocoder/common/{llm_friendly_package.py → llm_friendly_package/main_manager.py} +204 -231
  170. autocoder/common/llm_friendly_package/models.py +40 -0
  171. autocoder/common/llm_friendly_package/test_llm_friendly_package.py +536 -0
  172. autocoder/common/llms/__init__.py +15 -0
  173. autocoder/common/llms/demo_error_handling.py +85 -0
  174. autocoder/common/llms/factory.py +142 -0
  175. autocoder/common/llms/manager.py +264 -0
  176. autocoder/common/llms/pricing.py +121 -0
  177. autocoder/common/llms/registry.py +288 -0
  178. autocoder/common/llms/schema.py +77 -0
  179. autocoder/common/llms/simple_demo.py +45 -0
  180. autocoder/common/llms/test_quick_model.py +116 -0
  181. autocoder/common/llms/test_remove_functionality.py +182 -0
  182. autocoder/common/llms/tests/__init__.py +1 -0
  183. autocoder/common/llms/tests/test_manager.py +330 -0
  184. autocoder/common/llms/tests/test_registry.py +364 -0
  185. autocoder/common/mcp_tools/__init__.py +62 -0
  186. autocoder/common/{mcp_tools.py → mcp_tools/executor.py} +49 -40
  187. autocoder/common/{mcp_hub.py → mcp_tools/hub.py} +42 -68
  188. autocoder/common/{mcp_server_install.py → mcp_tools/installer.py} +16 -28
  189. autocoder/common/{mcp_server.py → mcp_tools/server.py} +176 -48
  190. autocoder/common/mcp_tools/test_keyboard_interrupt.py +93 -0
  191. autocoder/common/mcp_tools/test_mcp_tools.py +391 -0
  192. autocoder/common/{mcp_server_types.py → mcp_tools/types.py} +121 -48
  193. autocoder/common/mcp_tools/verify_functionality.py +202 -0
  194. autocoder/common/model_speed_tester.py +32 -26
  195. autocoder/common/priority_directory_finder/__init__.py +142 -0
  196. autocoder/common/priority_directory_finder/examples.py +230 -0
  197. autocoder/common/priority_directory_finder/finder.py +283 -0
  198. autocoder/common/priority_directory_finder/models.py +236 -0
  199. autocoder/common/priority_directory_finder/test_priority_directory_finder.py +431 -0
  200. autocoder/common/project_scanner/__init__.py +18 -0
  201. autocoder/common/project_scanner/compat.py +77 -0
  202. autocoder/common/project_scanner/scanner.py +436 -0
  203. autocoder/common/project_tracker/__init__.py +27 -0
  204. autocoder/common/project_tracker/api.py +228 -0
  205. autocoder/common/project_tracker/demo.py +272 -0
  206. autocoder/common/project_tracker/tracker.py +487 -0
  207. autocoder/common/project_tracker/types.py +53 -0
  208. autocoder/common/pruner/__init__.py +67 -0
  209. autocoder/common/pruner/agentic_conversation_pruner.py +651 -102
  210. autocoder/common/pruner/conversation_message_ids_api.py +386 -0
  211. autocoder/common/pruner/conversation_message_ids_manager.py +347 -0
  212. autocoder/common/pruner/conversation_message_ids_pruner.py +473 -0
  213. autocoder/common/pruner/conversation_normalizer.py +347 -0
  214. autocoder/common/pruner/conversation_pruner.py +26 -6
  215. autocoder/common/pruner/test_agentic_conversation_pruner.py +554 -112
  216. autocoder/common/pruner/test_conversation_normalizer.py +502 -0
  217. autocoder/common/pruner/test_tool_content_detector.py +324 -0
  218. autocoder/common/pruner/tool_content_detector.py +227 -0
  219. autocoder/common/pruner/tools/__init__.py +18 -0
  220. autocoder/common/pruner/tools/query_message_ids.py +264 -0
  221. autocoder/common/pruner/tools/test_agentic_pruning_logic.py +432 -0
  222. autocoder/common/pruner/tools/test_message_ids_pruning_only.py +192 -0
  223. autocoder/common/pull_requests/__init__.py +9 -1
  224. autocoder/common/pull_requests/utils.py +122 -1
  225. autocoder/common/rag_manager/rag_manager.py +36 -40
  226. autocoder/common/rulefiles/__init__.py +53 -1
  227. autocoder/common/rulefiles/api.py +250 -0
  228. autocoder/common/rulefiles/core/__init__.py +14 -0
  229. autocoder/common/rulefiles/core/manager.py +241 -0
  230. autocoder/common/rulefiles/core/selector.py +805 -0
  231. autocoder/common/rulefiles/models/__init__.py +20 -0
  232. autocoder/common/rulefiles/models/index.py +16 -0
  233. autocoder/common/rulefiles/models/init_rule.py +18 -0
  234. autocoder/common/rulefiles/models/rule_file.py +18 -0
  235. autocoder/common/rulefiles/models/rule_relevance.py +14 -0
  236. autocoder/common/rulefiles/models/summary.py +16 -0
  237. autocoder/common/rulefiles/test_rulefiles.py +776 -0
  238. autocoder/common/rulefiles/utils/__init__.py +34 -0
  239. autocoder/common/rulefiles/utils/monitor.py +86 -0
  240. autocoder/common/rulefiles/utils/parser.py +230 -0
  241. autocoder/common/save_formatted_log.py +67 -10
  242. autocoder/common/search_replace.py +8 -1
  243. autocoder/common/search_replace_patch/__init__.py +24 -0
  244. autocoder/common/search_replace_patch/base.py +115 -0
  245. autocoder/common/search_replace_patch/manager.py +248 -0
  246. autocoder/common/search_replace_patch/patch_replacer.py +304 -0
  247. autocoder/common/search_replace_patch/similarity_replacer.py +306 -0
  248. autocoder/common/search_replace_patch/string_replacer.py +181 -0
  249. autocoder/common/search_replace_patch/tests/__init__.py +3 -0
  250. autocoder/common/search_replace_patch/tests/run_tests.py +126 -0
  251. autocoder/common/search_replace_patch/tests/test_base.py +188 -0
  252. autocoder/common/search_replace_patch/tests/test_empty_line_insert.py +233 -0
  253. autocoder/common/search_replace_patch/tests/test_integration.py +389 -0
  254. autocoder/common/search_replace_patch/tests/test_manager.py +351 -0
  255. autocoder/common/search_replace_patch/tests/test_patch_replacer.py +316 -0
  256. autocoder/common/search_replace_patch/tests/test_regex_replacer.py +306 -0
  257. autocoder/common/search_replace_patch/tests/test_similarity_replacer.py +384 -0
  258. autocoder/common/shell_commands/__init__.py +197 -0
  259. autocoder/common/shell_commands/background_process_notifier.py +346 -0
  260. autocoder/common/shell_commands/command_executor.py +1127 -0
  261. autocoder/common/shell_commands/error_recovery.py +541 -0
  262. autocoder/common/shell_commands/exceptions.py +120 -0
  263. autocoder/common/shell_commands/interactive_executor.py +476 -0
  264. autocoder/common/shell_commands/interactive_pexpect_process.py +623 -0
  265. autocoder/common/shell_commands/interactive_process.py +744 -0
  266. autocoder/common/shell_commands/interactive_session_manager.py +1014 -0
  267. autocoder/common/shell_commands/monitoring.py +529 -0
  268. autocoder/common/shell_commands/process_cleanup.py +386 -0
  269. autocoder/common/shell_commands/process_manager.py +606 -0
  270. autocoder/common/shell_commands/test_interactive_pexpect_process.py +281 -0
  271. autocoder/common/shell_commands/tests/__init__.py +6 -0
  272. autocoder/common/shell_commands/tests/conftest.py +118 -0
  273. autocoder/common/shell_commands/tests/test_background_process_notifier.py +703 -0
  274. autocoder/common/shell_commands/tests/test_command_executor.py +448 -0
  275. autocoder/common/shell_commands/tests/test_error_recovery.py +305 -0
  276. autocoder/common/shell_commands/tests/test_exceptions.py +299 -0
  277. autocoder/common/shell_commands/tests/test_execute_batch.py +588 -0
  278. autocoder/common/shell_commands/tests/test_indented_batch_commands.py +244 -0
  279. autocoder/common/shell_commands/tests/test_integration.py +664 -0
  280. autocoder/common/shell_commands/tests/test_monitoring.py +546 -0
  281. autocoder/common/shell_commands/tests/test_performance.py +632 -0
  282. autocoder/common/shell_commands/tests/test_process_cleanup.py +397 -0
  283. autocoder/common/shell_commands/tests/test_process_manager.py +606 -0
  284. autocoder/common/shell_commands/tests/test_timeout_config.py +343 -0
  285. autocoder/common/shell_commands/tests/test_timeout_manager.py +520 -0
  286. autocoder/common/shell_commands/timeout_config.py +315 -0
  287. autocoder/common/shell_commands/timeout_manager.py +352 -0
  288. autocoder/common/terminal_paste/__init__.py +14 -0
  289. autocoder/common/terminal_paste/demo.py +145 -0
  290. autocoder/common/terminal_paste/demo_paste_functionality.py +95 -0
  291. autocoder/common/terminal_paste/paste_handler.py +200 -0
  292. autocoder/common/terminal_paste/paste_manager.py +118 -0
  293. autocoder/common/terminal_paste/tests/__init__.py +1 -0
  294. autocoder/common/terminal_paste/tests/test_paste_handler.py +182 -0
  295. autocoder/common/terminal_paste/tests/test_paste_manager.py +126 -0
  296. autocoder/common/terminal_paste/utils.py +163 -0
  297. autocoder/common/test_autocoder_args.py +232 -0
  298. autocoder/common/test_env_manager.py +173 -0
  299. autocoder/common/test_env_manager_integration.py +159 -0
  300. autocoder/common/text_similarity/__init__.py +9 -0
  301. autocoder/common/text_similarity/demo.py +216 -0
  302. autocoder/common/text_similarity/examples.py +266 -0
  303. autocoder/common/text_similarity/test_text_similarity.py +306 -0
  304. autocoder/common/text_similarity/text_similarity.py +194 -0
  305. autocoder/common/text_similarity/utils.py +125 -0
  306. autocoder/common/todos/__init__.py +61 -0
  307. autocoder/common/todos/cache/__init__.py +16 -0
  308. autocoder/common/todos/cache/base_cache.py +89 -0
  309. autocoder/common/todos/cache/cache_manager.py +228 -0
  310. autocoder/common/todos/cache/memory_cache.py +225 -0
  311. autocoder/common/todos/config.py +155 -0
  312. autocoder/common/todos/exceptions.py +35 -0
  313. autocoder/common/todos/get_todo_manager.py +161 -0
  314. autocoder/common/todos/manager.py +537 -0
  315. autocoder/common/todos/models.py +239 -0
  316. autocoder/common/todos/storage/__init__.py +14 -0
  317. autocoder/common/todos/storage/base_storage.py +76 -0
  318. autocoder/common/todos/storage/file_storage.py +278 -0
  319. autocoder/common/tokens/counter.py +24 -2
  320. autocoder/common/tools_manager/__init__.py +17 -0
  321. autocoder/common/tools_manager/examples.py +162 -0
  322. autocoder/common/tools_manager/manager.py +385 -0
  323. autocoder/common/tools_manager/models.py +39 -0
  324. autocoder/common/tools_manager/test_tools_manager.py +303 -0
  325. autocoder/common/tools_manager/utils.py +191 -0
  326. autocoder/common/v2/agent/agentic_callbacks.py +270 -0
  327. autocoder/common/v2/agent/agentic_edit.py +2699 -1856
  328. autocoder/common/v2/agent/agentic_edit_change_manager.py +474 -0
  329. autocoder/common/v2/agent/agentic_edit_tools/__init__.py +35 -1
  330. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_list_tool_resolver.py +279 -0
  331. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +10 -1
  332. autocoder/common/v2/agent/agentic_edit_tools/background_task_tool_resolver.py +1167 -0
  333. autocoder/common/v2/agent/agentic_edit_tools/base_tool_resolver.py +2 -2
  334. autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_read_tool_resolver.py +214 -0
  335. autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_write_tool_resolver.py +299 -0
  336. autocoder/common/v2/agent/agentic_edit_tools/count_tokens_tool_resolver.py +290 -0
  337. autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +564 -29
  338. autocoder/common/v2/agent/agentic_edit_tools/execute_workflow_tool_resolver.py +485 -0
  339. autocoder/common/v2/agent/agentic_edit_tools/extract_to_text_tool_resolver.py +225 -0
  340. autocoder/common/v2/agent/agentic_edit_tools/lint_report.py +79 -0
  341. autocoder/common/v2/agent/agentic_edit_tools/linter_config_models.py +343 -0
  342. autocoder/common/v2/agent/agentic_edit_tools/linter_enabled_tool_resolver.py +189 -0
  343. autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py +169 -101
  344. autocoder/common/v2/agent/agentic_edit_tools/load_extra_document_tool_resolver.py +349 -0
  345. autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +243 -50
  346. autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py +667 -147
  347. autocoder/common/v2/agent/agentic_edit_tools/run_named_subagents_tool_resolver.py +691 -0
  348. autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +410 -86
  349. autocoder/common/v2/agent/agentic_edit_tools/session_interactive_tool_resolver.py +115 -0
  350. autocoder/common/v2/agent/agentic_edit_tools/session_start_tool_resolver.py +190 -0
  351. autocoder/common/v2/agent/agentic_edit_tools/session_stop_tool_resolver.py +76 -0
  352. autocoder/common/v2/agent/agentic_edit_tools/test_write_to_file_tool_resolver.py +207 -192
  353. autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +80 -63
  354. autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +237 -233
  355. autocoder/common/v2/agent/agentic_edit_tools/use_mcp_tool_resolver.py +2 -2
  356. autocoder/common/v2/agent/agentic_edit_tools/web_crawl_tool_resolver.py +557 -0
  357. autocoder/common/v2/agent/agentic_edit_tools/web_search_tool_resolver.py +600 -0
  358. autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py +56 -121
  359. autocoder/common/v2/agent/agentic_edit_types.py +343 -9
  360. autocoder/common/v2/agent/runner/__init__.py +3 -3
  361. autocoder/common/v2/agent/runner/base_runner.py +12 -26
  362. autocoder/common/v2/agent/runner/{event_runner.py → file_based_event_runner.py} +3 -2
  363. autocoder/common/v2/agent/runner/sdk_runner.py +150 -8
  364. autocoder/common/v2/agent/runner/terminal_runner.py +170 -57
  365. autocoder/common/v2/agent/runner/tool_display.py +557 -159
  366. autocoder/common/v2/agent/test_agentic_callbacks.py +265 -0
  367. autocoder/common/v2/agent/test_agentic_edit.py +194 -0
  368. autocoder/common/v2/agent/tool_caller/__init__.py +24 -0
  369. autocoder/common/v2/agent/tool_caller/default_tool_resolver_map.py +135 -0
  370. autocoder/common/v2/agent/tool_caller/integration_test.py +172 -0
  371. autocoder/common/v2/agent/tool_caller/plugins/__init__.py +14 -0
  372. autocoder/common/v2/agent/tool_caller/plugins/base_plugin.py +126 -0
  373. autocoder/common/v2/agent/tool_caller/plugins/examples/__init__.py +13 -0
  374. autocoder/common/v2/agent/tool_caller/plugins/examples/logging_plugin.py +164 -0
  375. autocoder/common/v2/agent/tool_caller/plugins/examples/security_filter_plugin.py +198 -0
  376. autocoder/common/v2/agent/tool_caller/plugins/plugin_interface.py +141 -0
  377. autocoder/common/v2/agent/tool_caller/test_tool_caller.py +278 -0
  378. autocoder/common/v2/agent/tool_caller/tool_call_plugin_manager.py +331 -0
  379. autocoder/common/v2/agent/tool_caller/tool_caller.py +337 -0
  380. autocoder/common/v2/agent/tool_caller/usage_example.py +193 -0
  381. autocoder/common/v2/code_agentic_editblock_manager.py +4 -4
  382. autocoder/common/v2/code_auto_generate.py +136 -78
  383. autocoder/common/v2/code_auto_generate_diff.py +135 -79
  384. autocoder/common/v2/code_auto_generate_editblock.py +174 -99
  385. autocoder/common/v2/code_auto_generate_strict_diff.py +151 -71
  386. autocoder/common/v2/code_auto_merge.py +1 -1
  387. autocoder/common/v2/code_auto_merge_editblock.py +13 -1
  388. autocoder/common/v2/code_diff_manager.py +3 -3
  389. autocoder/common/v2/code_editblock_manager.py +4 -14
  390. autocoder/common/v2/code_manager.py +1 -1
  391. autocoder/common/v2/code_strict_diff_manager.py +2 -2
  392. autocoder/common/wrap_llm_hint/__init__.py +10 -0
  393. autocoder/common/wrap_llm_hint/test_wrap_llm_hint.py +1067 -0
  394. autocoder/common/wrap_llm_hint/utils.py +432 -0
  395. autocoder/common/wrap_llm_hint/wrap_llm_hint.py +323 -0
  396. autocoder/completer/__init__.py +8 -0
  397. autocoder/completer/command_completer_v2.py +1051 -0
  398. autocoder/default_project/__init__.py +501 -0
  399. autocoder/dispacher/__init__.py +4 -12
  400. autocoder/dispacher/actions/action.py +165 -7
  401. autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
  402. autocoder/index/entry.py +116 -124
  403. autocoder/{agent → index/filter}/agentic_filter.py +322 -333
  404. autocoder/index/filter/normal_filter.py +5 -11
  405. autocoder/index/filter/quick_filter.py +1 -1
  406. autocoder/index/index.py +36 -9
  407. autocoder/index/tests/__init__.py +1 -0
  408. autocoder/index/tests/run_tests.py +195 -0
  409. autocoder/index/tests/test_entry.py +303 -0
  410. autocoder/index/tests/test_index_manager.py +314 -0
  411. autocoder/index/tests/test_module_integration.py +300 -0
  412. autocoder/index/tests/test_symbols_utils.py +183 -0
  413. autocoder/inner/__init__.py +4 -0
  414. autocoder/inner/agentic.py +932 -0
  415. autocoder/inner/async_command_handler.py +992 -0
  416. autocoder/inner/conversation_command_handlers.py +623 -0
  417. autocoder/inner/merge_command_handler.py +213 -0
  418. autocoder/inner/queue_command_handler.py +684 -0
  419. autocoder/models.py +95 -266
  420. autocoder/plugins/git_helper_plugin.py +31 -29
  421. autocoder/plugins/token_helper_plugin.py +65 -46
  422. autocoder/pyproject/__init__.py +32 -29
  423. autocoder/rag/agentic_rag.py +215 -75
  424. autocoder/rag/cache/simple_cache.py +1 -2
  425. autocoder/rag/loaders/image_loader.py +1 -1
  426. autocoder/rag/long_context_rag.py +42 -26
  427. autocoder/rag/qa_conversation_strategy.py +1 -1
  428. autocoder/rag/terminal/__init__.py +17 -0
  429. autocoder/rag/terminal/args.py +581 -0
  430. autocoder/rag/terminal/bootstrap.py +61 -0
  431. autocoder/rag/terminal/command_handlers.py +653 -0
  432. autocoder/rag/terminal/formatters/__init__.py +20 -0
  433. autocoder/rag/terminal/formatters/base.py +70 -0
  434. autocoder/rag/terminal/formatters/json_format.py +66 -0
  435. autocoder/rag/terminal/formatters/stream_json.py +95 -0
  436. autocoder/rag/terminal/formatters/text.py +28 -0
  437. autocoder/rag/terminal/init.py +120 -0
  438. autocoder/rag/terminal/utils.py +106 -0
  439. autocoder/rag/test_agentic_rag.py +389 -0
  440. autocoder/rag/test_doc_filter.py +3 -3
  441. autocoder/rag/test_long_context_rag.py +1 -1
  442. autocoder/rag/test_token_limiter.py +517 -10
  443. autocoder/rag/token_counter.py +3 -0
  444. autocoder/rag/token_limiter.py +19 -15
  445. autocoder/rag/tools/__init__.py +26 -2
  446. autocoder/rag/tools/bochaai_example.py +343 -0
  447. autocoder/rag/tools/bochaai_sdk.py +541 -0
  448. autocoder/rag/tools/metaso_example.py +268 -0
  449. autocoder/rag/tools/metaso_sdk.py +417 -0
  450. autocoder/rag/tools/recall_tool.py +28 -7
  451. autocoder/rag/tools/run_integration_tests.py +204 -0
  452. autocoder/rag/tools/test_all_providers.py +318 -0
  453. autocoder/rag/tools/test_bochaai_integration.py +482 -0
  454. autocoder/rag/tools/test_final_integration.py +215 -0
  455. autocoder/rag/tools/test_metaso_integration.py +424 -0
  456. autocoder/rag/tools/test_metaso_real.py +171 -0
  457. autocoder/rag/tools/test_web_crawl_tool.py +639 -0
  458. autocoder/rag/tools/test_web_search_tool.py +509 -0
  459. autocoder/rag/tools/todo_read_tool.py +202 -0
  460. autocoder/rag/tools/todo_write_tool.py +412 -0
  461. autocoder/rag/tools/web_crawl_tool.py +634 -0
  462. autocoder/rag/tools/web_search_tool.py +558 -0
  463. autocoder/rag/tools/web_tools_example.py +119 -0
  464. autocoder/rag/types.py +16 -0
  465. autocoder/rag/variable_holder.py +4 -2
  466. autocoder/rags.py +86 -79
  467. autocoder/regexproject/__init__.py +23 -21
  468. autocoder/sdk/__init__.py +46 -190
  469. autocoder/sdk/api.py +370 -0
  470. autocoder/sdk/async_runner/__init__.py +26 -0
  471. autocoder/sdk/async_runner/async_executor.py +650 -0
  472. autocoder/sdk/async_runner/async_handler.py +356 -0
  473. autocoder/sdk/async_runner/markdown_processor.py +595 -0
  474. autocoder/sdk/async_runner/task_metadata.py +284 -0
  475. autocoder/sdk/async_runner/worktree_manager.py +438 -0
  476. autocoder/sdk/cli/__init__.py +2 -5
  477. autocoder/sdk/cli/formatters.py +28 -204
  478. autocoder/sdk/cli/handlers.py +77 -44
  479. autocoder/sdk/cli/main.py +154 -171
  480. autocoder/sdk/cli/options.py +95 -22
  481. autocoder/sdk/constants.py +139 -51
  482. autocoder/sdk/core/auto_coder_core.py +484 -109
  483. autocoder/sdk/core/bridge.py +297 -115
  484. autocoder/sdk/exceptions.py +18 -12
  485. autocoder/sdk/formatters/__init__.py +19 -0
  486. autocoder/sdk/formatters/input.py +64 -0
  487. autocoder/sdk/formatters/output.py +247 -0
  488. autocoder/sdk/formatters/stream.py +54 -0
  489. autocoder/sdk/models/__init__.py +6 -5
  490. autocoder/sdk/models/options.py +55 -18
  491. autocoder/sdk/utils/formatters.py +27 -195
  492. autocoder/suffixproject/__init__.py +28 -25
  493. autocoder/terminal/__init__.py +14 -0
  494. autocoder/terminal/app.py +454 -0
  495. autocoder/terminal/args.py +32 -0
  496. autocoder/terminal/bootstrap.py +178 -0
  497. autocoder/terminal/command_processor.py +521 -0
  498. autocoder/terminal/command_registry.py +57 -0
  499. autocoder/terminal/help.py +97 -0
  500. autocoder/terminal/tasks/__init__.py +5 -0
  501. autocoder/terminal/tasks/background.py +77 -0
  502. autocoder/terminal/tasks/task_event.py +70 -0
  503. autocoder/terminal/ui/__init__.py +13 -0
  504. autocoder/terminal/ui/completer.py +268 -0
  505. autocoder/terminal/ui/keybindings.py +75 -0
  506. autocoder/terminal/ui/session.py +41 -0
  507. autocoder/terminal/ui/toolbar.py +64 -0
  508. autocoder/terminal/utils/__init__.py +13 -0
  509. autocoder/terminal/utils/errors.py +18 -0
  510. autocoder/terminal/utils/paths.py +19 -0
  511. autocoder/terminal/utils/shell.py +43 -0
  512. autocoder/terminal_v3/__init__.py +10 -0
  513. autocoder/terminal_v3/app.py +201 -0
  514. autocoder/terminal_v3/handlers/__init__.py +5 -0
  515. autocoder/terminal_v3/handlers/command_handler.py +131 -0
  516. autocoder/terminal_v3/models/__init__.py +6 -0
  517. autocoder/terminal_v3/models/conversation_buffer.py +214 -0
  518. autocoder/terminal_v3/models/message.py +50 -0
  519. autocoder/terminal_v3/models/tool_display.py +247 -0
  520. autocoder/terminal_v3/ui/__init__.py +7 -0
  521. autocoder/terminal_v3/ui/keybindings.py +56 -0
  522. autocoder/terminal_v3/ui/layout.py +141 -0
  523. autocoder/terminal_v3/ui/styles.py +43 -0
  524. autocoder/tsproject/__init__.py +23 -23
  525. autocoder/utils/auto_coder_utils/chat_stream_out.py +1 -1
  526. autocoder/utils/llms.py +88 -80
  527. autocoder/utils/math_utils.py +101 -0
  528. autocoder/utils/model_provider_selector.py +16 -4
  529. autocoder/utils/operate_config_api.py +33 -5
  530. autocoder/utils/thread_utils.py +2 -2
  531. autocoder/version.py +4 -2
  532. autocoder/workflow_agents/__init__.py +84 -0
  533. autocoder/workflow_agents/agent.py +143 -0
  534. autocoder/workflow_agents/exceptions.py +573 -0
  535. autocoder/workflow_agents/executor.py +489 -0
  536. autocoder/workflow_agents/loader.py +737 -0
  537. autocoder/workflow_agents/runner.py +267 -0
  538. autocoder/workflow_agents/types.py +172 -0
  539. autocoder/workflow_agents/utils.py +434 -0
  540. autocoder/workflow_agents/workflow_manager.py +211 -0
  541. auto_coder-1.0.0.dist-info/METADATA +0 -396
  542. auto_coder-1.0.0.dist-info/RECORD +0 -442
  543. auto_coder-1.0.0.dist-info/licenses/LICENSE +0 -201
  544. autocoder/auto_coder_server.py +0 -672
  545. autocoder/benchmark.py +0 -138
  546. autocoder/common/ac_style_command_parser/example.py +0 -7
  547. autocoder/common/cleaner.py +0 -31
  548. autocoder/common/command_completer_v2.py +0 -615
  549. autocoder/common/context_pruner.py +0 -477
  550. autocoder/common/conversation_pruner.py +0 -132
  551. autocoder/common/directory_cache/__init__.py +0 -1
  552. autocoder/common/directory_cache/cache.py +0 -192
  553. autocoder/common/directory_cache/test_cache.py +0 -190
  554. autocoder/common/file_checkpoint/examples.py +0 -217
  555. autocoder/common/llm_friendly_package_example.py +0 -138
  556. autocoder/common/llm_friendly_package_test.py +0 -63
  557. autocoder/common/pull_requests/test_module.py +0 -1
  558. autocoder/common/rulefiles/autocoderrules_utils.py +0 -484
  559. autocoder/common/text.py +0 -30
  560. autocoder/common/v2/agent/agentic_edit_tools/list_package_info_tool_resolver.py +0 -42
  561. autocoder/common/v2/agent/agentic_edit_tools/test_execute_command_tool_resolver.py +0 -70
  562. autocoder/common/v2/agent/agentic_edit_tools/test_search_files_tool_resolver.py +0 -163
  563. autocoder/common/v2/agent/agentic_tool_display.py +0 -183
  564. autocoder/plugins/dynamic_completion_example.py +0 -148
  565. autocoder/plugins/sample_plugin.py +0 -160
  566. autocoder/sdk/cli/__main__.py +0 -26
  567. autocoder/sdk/cli/completion_wrapper.py +0 -38
  568. autocoder/sdk/cli/install_completion.py +0 -301
  569. autocoder/sdk/models/messages.py +0 -209
  570. autocoder/sdk/session/__init__.py +0 -32
  571. autocoder/sdk/session/session.py +0 -106
  572. autocoder/sdk/session/session_manager.py +0 -56
  573. {auto_coder-1.0.0.dist-info → auto_coder-2.0.0.dist-info}/top_level.txt +0 -0
  574. /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
@@ -4,10 +4,10 @@ from autocoder.common.v2.agent.agentic_edit_types import TodoWriteTool, ToolResu
4
4
  from loguru import logger
5
5
  import typing
6
6
  from autocoder.common import AutoCoderArgs
7
- import os
8
- import json
9
- import uuid
10
- from datetime import datetime
7
+
8
+ # Import the new todos module
9
+ from autocoder.common.todos.get_todo_manager import get_todo_manager
10
+ from autocoder.common.todos.exceptions import TodoManagerError, TodoNotFoundError
11
11
 
12
12
  if typing.TYPE_CHECKING:
13
13
  from autocoder.common.v2.agent.agentic_edit import AgenticEdit
@@ -18,191 +18,134 @@ class TodoWriteToolResolver(BaseToolResolver):
18
18
  super().__init__(agent, tool, args)
19
19
  self.tool: TodoWriteTool = tool # For type hinting
20
20
 
21
- def _get_todo_file_path(self) -> str:
22
- """Get the path to the todo file for this session."""
23
- source_dir = self.args.source_dir or "."
24
- todo_dir = os.path.join(source_dir, ".auto-coder", "todos")
25
- os.makedirs(todo_dir, exist_ok=True)
26
- return os.path.join(todo_dir, "current_session.json")
27
-
28
- def _load_todos(self) -> Dict[str, Any]:
29
- """Load todos from the session file."""
30
- todo_file = self._get_todo_file_path()
31
- if not os.path.exists(todo_file):
32
- return {
33
- "created_at": datetime.now().isoformat(),
34
- "updated_at": datetime.now().isoformat(),
35
- "todos": []
36
- }
37
-
38
- try:
39
- with open(todo_file, 'r', encoding='utf-8') as f:
40
- return json.load(f)
41
- except Exception as e:
42
- logger.warning(f"Failed to load todos: {e}")
43
- return {
44
- "created_at": datetime.now().isoformat(),
45
- "updated_at": datetime.now().isoformat(),
46
- "todos": []
47
- }
48
-
49
- def _save_todos(self, data: Dict[str, Any]) -> bool:
50
- """Save todos to the session file."""
51
- try:
52
- todo_file = self._get_todo_file_path()
53
- data["updated_at"] = datetime.now().isoformat()
54
-
55
- with open(todo_file, 'w', encoding='utf-8') as f:
56
- json.dump(data, f, ensure_ascii=False, indent=2)
57
- return True
58
- except Exception as e:
59
- logger.error(f"Failed to save todos: {e}")
60
- return False
61
-
62
- def _generate_todo_id(self) -> str:
63
- """Generate a unique ID for a todo item."""
64
- return str(uuid.uuid4())[:8]
65
-
66
- def _find_todo_by_id(self, todos: List[Dict[str, Any]], task_id: str) -> Optional[Dict[str, Any]]:
67
- """Find a todo item by ID."""
68
- for todo in todos:
69
- if todo.get('id') == task_id:
70
- return todo
71
- return None
72
-
73
- def _create_todo_list(self, content: str) -> List[Dict[str, Any]]:
74
- """Create a new todo list from content."""
75
- import re
76
-
77
- todos = []
78
-
79
- # First, try to parse <task> tags
80
- task_pattern = r'<task>(.*?)</task>'
81
- task_matches = re.findall(task_pattern, content, re.DOTALL)
82
-
83
- if task_matches:
84
- # Found <task> tags, use them
85
- for task_content in task_matches:
86
- task_content = task_content.strip()
87
- if task_content:
88
- todo = {
89
- "id": self._generate_todo_id(),
90
- "content": task_content,
91
- "status": "pending",
92
- "priority": self.tool.priority or "medium",
93
- "created_at": datetime.now().isoformat(),
94
- "updated_at": datetime.now().isoformat()
95
- }
96
-
97
- if self.tool.notes:
98
- todo["notes"] = self.tool.notes
99
-
100
- todos.append(todo)
101
- else:
102
- # Fallback to original line-by-line parsing
103
- lines = content.strip().split('\n')
104
-
105
- for line in lines:
106
- line = line.strip()
107
- if not line:
108
- continue
109
-
110
- # Remove common prefixes like "1.", "- ", "* ", etc.
111
- line = line.lstrip('0123456789.- *\t')
112
-
113
- if line:
114
- todo = {
115
- "id": self._generate_todo_id(),
116
- "content": line,
117
- "status": "pending",
118
- "priority": self.tool.priority or "medium",
119
- "created_at": datetime.now().isoformat(),
120
- "updated_at": datetime.now().isoformat()
121
- }
122
-
123
- if self.tool.notes:
124
- todo["notes"] = self.tool.notes
125
-
126
- todos.append(todo)
127
-
128
- return todos
129
-
130
- def _add_single_task(self, todos: List[Dict[str, Any]], content: str) -> Dict[str, Any]:
131
- """Add a single task to the existing todo list."""
132
- import re
133
-
134
- # Check if content contains <task> tags
135
- task_pattern = r'<task>(.*?)</task>'
136
- task_matches = re.findall(task_pattern, content, re.DOTALL)
137
-
138
- if task_matches:
139
- # If <task> tags found, use the first one
140
- task_content = task_matches[0].strip()
141
- else:
142
- # Use the content as-is
143
- task_content = content.strip()
144
-
145
- todo = {
146
- "id": self._generate_todo_id(),
147
- "content": task_content,
148
- "status": self.tool.status or "pending",
149
- "priority": self.tool.priority or "medium",
150
- "created_at": datetime.now().isoformat(),
151
- "updated_at": datetime.now().isoformat()
152
- }
153
-
154
- if self.tool.notes:
155
- todo["notes"] = self.tool.notes
156
-
157
- todos.append(todo)
158
- return todo
159
-
160
- def _update_task(self, todo: Dict[str, Any]) -> None:
161
- """Update an existing task."""
162
- if self.tool.content:
163
- todo["content"] = self.tool.content
164
- if self.tool.status:
165
- todo["status"] = self.tool.status
166
- if self.tool.priority:
167
- todo["priority"] = self.tool.priority
168
- if self.tool.notes:
169
- todo["notes"] = self.tool.notes
170
-
171
- todo["updated_at"] = datetime.now().isoformat()
172
-
21
+ # Initialize todo manager
22
+ self.todo_manager = get_todo_manager()
23
+
173
24
  def _format_todo_response(self, todos: List[Dict[str, Any]], action_performed: str) -> str:
174
25
  """Format the response message after todo operations."""
175
26
  if not todos:
176
27
  return f"Operation completed: {action_performed}"
177
-
178
- # Show the latest todos
179
- recent_todos = todos[-3:] if len(todos) > 3 else todos
180
-
181
- output = [f"✅ Operation completed: {action_performed}\n"]
182
-
28
+
29
+ output = [f"Operation completed: {action_performed}\n"]
30
+
183
31
  if action_performed.startswith("Created"):
32
+ # For creation operations, show newly created tasks
184
33
  output.append("📝 Newly created todos:")
185
- for todo in recent_todos:
186
- priority_icon = {"high": "🔴", "medium": "🟡", "low": "🟢"}.get(todo.get('priority', 'medium'), "⚪")
187
- status_icon = {"pending": "⏳", "in_progress": "🔄", "completed": "✅"}.get(todo.get('status', 'pending'), "")
188
- output.append(f" {priority_icon} {status_icon} [{todo['id']}] {todo['content']}")
189
-
190
- elif action_performed.startswith("Updated") or action_performed.startswith("Marked"):
191
- output.append("📝 Updated todos:")
192
- for todo in recent_todos:
193
- priority_icon = {"high": "🔴", "medium": "🟡", "low": "🟢"}.get(todo.get('priority', 'medium'), "⚪")
194
- status_icon = {"pending": "⏳", "in_progress": "🔄", "completed": "✅"}.get(todo.get('status', 'pending'), "⏳")
195
- output.append(f" {priority_icon} {status_icon} [{todo['id']}] {todo['content']}")
196
-
197
- total_todos = len(todos)
198
- pending_count = len([t for t in todos if t.get('status') == 'pending'])
199
- in_progress_count = len([t for t in todos if t.get('status') == 'in_progress'])
200
- completed_count = len([t for t in todos if t.get('status') == 'completed'])
201
-
202
- output.append(f"\n📊 Current summary: Total {total_todos} items | Pending {pending_count} | In Progress {in_progress_count} | Completed {completed_count}")
203
-
34
+ for todo in todos:
35
+ priority_icon = {"high": "🔴", "medium": "🟡", "low": "🟢"}.get(
36
+ todo.get('priority', 'medium'), "")
37
+ status_icon = {"pending": "⏳", "in_progress": "🔄", "completed": "✅"}.get(
38
+ todo.get('status', 'pending'), "⏳")
39
+ todo_id = todo.get('todo_id', 'MISSING_ID')
40
+ todo_content = todo.get('content', 'Missing content')
41
+
42
+ # Log any todos with missing IDs
43
+ if todo_id == 'MISSING_ID':
44
+ logger.error(f"Found todo with missing ID: {todo}")
45
+
46
+ output.append(
47
+ f" {priority_icon} {status_icon} [{todo_id}] {todo_content}")
48
+
49
+ total_todos = len(todos)
50
+ pending_count = len(
51
+ [t for t in todos if t.get('status') == 'pending'])
52
+ in_progress_count = len(
53
+ [t for t in todos if t.get('status') == 'in_progress'])
54
+ completed_count = len(
55
+ [t for t in todos if t.get('status') == 'completed'])
56
+
57
+ output.append(
58
+ f"\n📊 Current summary: Total {total_todos} items | Pending {pending_count} | In Progress {in_progress_count} | Completed {completed_count}")
59
+ else:
60
+ # For update operations, show complete TODO list
61
+ output.append(self._format_full_todo_list())
62
+
204
63
  return "\n".join(output)
205
64
 
65
+ def _format_full_todo_list(self) -> str:
66
+ """Format the complete todo list using the same format as todo_read_tool_resolver."""
67
+ try:
68
+ # Get all todos from the current conversation
69
+ conversation_id = self.agent.conversation_config.conversation_id if self.agent else None
70
+ all_todos = self.todo_manager.get_todos(conversation_id=conversation_id)
71
+
72
+ if not all_todos:
73
+ return "No todos found for current conversation."
74
+
75
+ output = []
76
+ output.append("=== Current Conversation Todo List ===\n")
77
+
78
+ # Status emoji mapping
79
+ status_emoji = {
80
+ 'pending': '⏳',
81
+ 'in_progress': '🔄',
82
+ 'completed': '✅',
83
+ 'cancelled': '❌'
84
+ }
85
+
86
+ # Priority icon mapping
87
+ priority_icon = {
88
+ 'high': '🔴',
89
+ 'medium': '🟡',
90
+ 'low': '🟢'
91
+ }
92
+
93
+ # Display todos in a single list with status markers
94
+ for idx, todo in enumerate(all_todos, 1):
95
+ status = todo.get('status', 'pending')
96
+ priority = todo.get('priority', 'medium')
97
+ todo_id = todo.get('todo_id', 'MISSING_ID')
98
+ todo_content = todo.get('content', 'Missing content')
99
+
100
+ # Log any todos with missing IDs
101
+ if todo_id == 'MISSING_ID':
102
+ logger.error(
103
+ f"Found todo with missing ID in full list: {todo}")
104
+
105
+ # Get status emoji and priority icon
106
+ status_mark = status_emoji.get(status, '❓')
107
+ priority_mark = priority_icon.get(priority, '⚪')
108
+
109
+ # Format each todo item
110
+ output.append(
111
+ f"{idx}. {status_mark} {priority_mark} [{todo_id}] {todo_content}")
112
+
113
+ # Add notes if present
114
+ if todo.get('notes'):
115
+ output.append(f" └─ 📝 {todo['notes']}")
116
+
117
+ # Add dependencies if present
118
+ if todo.get('dependencies'):
119
+ deps = ', '.join(todo['dependencies'])
120
+ output.append(f" └─ 🔗 Depends on: {deps}")
121
+
122
+ output.append("")
123
+
124
+ # Add summary statistics
125
+ conversation_id = self.agent.conversation_config.conversation_id if self.agent else None
126
+ stats = self.todo_manager.get_statistics(conversation_id=conversation_id)
127
+ total = stats.get('total', 0)
128
+ status_counts = {
129
+ 'pending': stats.get('pending', 0),
130
+ 'in_progress': stats.get('in_progress', 0),
131
+ 'completed': stats.get('completed', 0),
132
+ 'cancelled': stats.get('cancelled', 0)
133
+ }
134
+
135
+ summary_parts = [f"Total: {total}"]
136
+ for status, emoji in status_emoji.items():
137
+ if status in status_counts and status_counts[status] > 0:
138
+ summary_parts.append(
139
+ f"{emoji} {status.replace('_', ' ').title()}: {status_counts[status]}")
140
+
141
+ output.append("📊 Summary: " + " | ".join(summary_parts))
142
+
143
+ return "\n".join(output)
144
+
145
+ except Exception as e:
146
+ logger.error(f"Failed to format full todo list: {e}")
147
+ return "Error retrieving todo list."
148
+
206
149
  def resolve(self) -> ToolResult:
207
150
  """
208
151
  Create and manage a structured task list based on the action specified.
@@ -210,11 +153,7 @@ class TodoWriteToolResolver(BaseToolResolver):
210
153
  try:
211
154
  action = self.tool.action.lower()
212
155
  logger.info(f"Performing todo action: {action}")
213
-
214
- # Load existing todos
215
- data = self._load_todos()
216
- todos = data["todos"]
217
-
156
+
218
157
  if action == "create":
219
158
  if not self.tool.content:
220
159
  return ToolResult(
@@ -222,25 +161,40 @@ class TodoWriteToolResolver(BaseToolResolver):
222
161
  message="Error: Content is required for creating todos.",
223
162
  content=None
224
163
  )
225
-
226
- # Clear existing todos and create new ones
227
- new_todos = self._create_todo_list(self.tool.content)
228
- data["todos"] = new_todos
229
-
230
- if self._save_todos(data):
231
- response = self._format_todo_response(new_todos, f"Created {len(new_todos)} new todo items")
164
+
165
+ # Create new todos using the todo manager
166
+ try:
167
+ conversation_id = self.agent.conversation_config.conversation_id if self.agent else None
168
+ todo_ids = self.todo_manager.create_todos(
169
+ content=self.tool.content,
170
+ conversation_id=conversation_id,
171
+ priority=self.tool.priority or "medium",
172
+ notes=self.tool.notes
173
+ )
174
+
175
+ # Get the created todos for display
176
+ created_todos = []
177
+ conversation_id = self.agent.conversation_config.conversation_id if self.agent else None
178
+ all_todos = self.todo_manager.get_todos(conversation_id=conversation_id)
179
+ for todo in all_todos:
180
+ if todo.get('todo_id') in todo_ids:
181
+ created_todos.append(todo)
182
+
183
+ response = self._format_todo_response(
184
+ created_todos, f"Created {len(todo_ids)} new todo items")
232
185
  return ToolResult(
233
186
  success=True,
234
187
  message="Todo list created successfully.",
235
188
  content=response
236
189
  )
237
- else:
190
+
191
+ except TodoManagerError as e:
238
192
  return ToolResult(
239
193
  success=False,
240
- message="Failed to save todo list.",
194
+ message=f"Failed to create todos: {str(e)}",
241
195
  content=None
242
196
  )
243
-
197
+
244
198
  elif action == "add_task":
245
199
  if not self.tool.content:
246
200
  return ToolResult(
@@ -248,23 +202,41 @@ class TodoWriteToolResolver(BaseToolResolver):
248
202
  message="Error: Content is required for adding a task.",
249
203
  content=None
250
204
  )
251
-
252
- new_todo = self._add_single_task(todos, self.tool.content)
253
-
254
- if self._save_todos(data):
255
- response = self._format_todo_response([new_todo], f"Added new task: {new_todo['content']}")
205
+
206
+ try:
207
+ conversation_id = self.agent.conversation_config.conversation_id if self.agent else None
208
+ todo_id = self.todo_manager.add_todo(
209
+ content=self.tool.content,
210
+ conversation_id=conversation_id,
211
+ status=self.tool.status or "pending",
212
+ priority=self.tool.priority or "medium",
213
+ notes=self.tool.notes
214
+ )
215
+
216
+ # Get the created todo for display
217
+ conversation_id = self.agent.conversation_config.conversation_id if self.agent else None
218
+ all_todos = self.todo_manager.get_todos(conversation_id=conversation_id)
219
+ new_todo = next((t for t in all_todos if t.get('todo_id') == todo_id), None)
220
+
221
+ if new_todo:
222
+ response = self._format_todo_response(
223
+ [new_todo], f"Added new task: {new_todo['content']}")
224
+ else:
225
+ response = f"Added new task with ID: {todo_id}"
226
+
256
227
  return ToolResult(
257
228
  success=True,
258
229
  message="Task added successfully.",
259
230
  content=response
260
231
  )
261
- else:
232
+
233
+ except TodoManagerError as e:
262
234
  return ToolResult(
263
235
  success=False,
264
- message="Failed to save new task.",
236
+ message=f"Failed to add task: {str(e)}",
265
237
  content=None
266
238
  )
267
-
239
+
268
240
  elif action in ["update", "mark_progress", "mark_completed"]:
269
241
  if not self.tool.task_id:
270
242
  return ToolResult(
@@ -272,53 +244,85 @@ class TodoWriteToolResolver(BaseToolResolver):
272
244
  message="Error: Task ID is required for update operations.",
273
245
  content=None
274
246
  )
275
-
276
- todo = self._find_todo_by_id(todos, self.tool.task_id)
277
- if not todo:
247
+
248
+ try:
249
+ # Prepare update parameters
250
+ update_kwargs = {}
251
+ action_msg = ""
252
+
253
+ if action == "mark_progress":
254
+ update_kwargs['status'] = "in_progress"
255
+ action_msg = "Marked task as in progress"
256
+ elif action == "mark_completed":
257
+ update_kwargs['status'] = "completed"
258
+ action_msg = "Marked task as completed"
259
+ else: # update
260
+ if self.tool.content:
261
+ update_kwargs['content'] = self.tool.content
262
+ if self.tool.status:
263
+ update_kwargs['status'] = self.tool.status
264
+ if self.tool.priority:
265
+ update_kwargs['priority'] = self.tool.priority
266
+ if self.tool.notes:
267
+ update_kwargs['notes'] = self.tool.notes
268
+ action_msg = "Updated task"
269
+
270
+ # Update the todo
271
+ conversation_id = self.agent.conversation_config.conversation_id if self.agent else None
272
+ success = self.todo_manager.update_todo(
273
+ todo_id=self.tool.task_id,
274
+ conversation_id=conversation_id,
275
+ **update_kwargs
276
+ )
277
+
278
+ if success:
279
+ # Get the updated todo for display
280
+ conversation_id = self.agent.conversation_config.conversation_id if self.agent else None
281
+ all_todos = self.todo_manager.get_todos(conversation_id=conversation_id)
282
+ updated_todo = next((t for t in all_todos if t.get('todo_id') == self.tool.task_id), None)
283
+
284
+ if updated_todo:
285
+ full_action_msg = f"{action_msg}: {updated_todo['content']}"
286
+ response = self._format_todo_response([updated_todo], full_action_msg)
287
+ else:
288
+ response = f"{action_msg} with ID: {self.tool.task_id}"
289
+
290
+ return ToolResult(
291
+ success=True,
292
+ message="Task updated successfully.",
293
+ content=response
294
+ )
295
+ else:
296
+ return ToolResult(
297
+ success=False,
298
+ message=f"Task with ID '{self.tool.task_id}' not found.",
299
+ content=None
300
+ )
301
+
302
+ except TodoNotFoundError:
278
303
  return ToolResult(
279
304
  success=False,
280
305
  message=f"Error: Task with ID '{self.tool.task_id}' not found.",
281
306
  content=None
282
307
  )
283
-
284
- # Apply specific action
285
- if action == "mark_progress":
286
- todo["status"] = "in_progress"
287
- todo["updated_at"] = datetime.now().isoformat()
288
- action_msg = f"Marked task as in progress: {todo['content']}"
289
- elif action == "mark_completed":
290
- todo["status"] = "completed"
291
- todo["updated_at"] = datetime.now().isoformat()
292
- action_msg = f"Marked task as completed: {todo['content']}"
293
- else: # update
294
- self._update_task(todo)
295
- action_msg = f"Updated task: {todo['content']}"
296
-
297
- if self._save_todos(data):
298
- response = self._format_todo_response([todo], action_msg)
299
- return ToolResult(
300
- success=True,
301
- message="Task updated successfully.",
302
- content=response
303
- )
304
- else:
308
+ except TodoManagerError as e:
305
309
  return ToolResult(
306
310
  success=False,
307
- message="Failed to save task update.",
311
+ message=f"Failed to update task: {str(e)}",
308
312
  content=None
309
313
  )
310
-
314
+
311
315
  else:
312
316
  return ToolResult(
313
317
  success=False,
314
318
  message=f"Error: Unknown action '{action}'. Supported actions: create, add_task, update, mark_progress, mark_completed.",
315
319
  content=None
316
320
  )
317
-
321
+
318
322
  except Exception as e:
319
323
  logger.error(f"Error in todo write operation: {e}")
320
324
  return ToolResult(
321
325
  success=False,
322
326
  message=f"Failed to perform todo operation: {str(e)}",
323
327
  content=None
324
- )
328
+ )
@@ -1,10 +1,10 @@
1
1
  from typing import Dict, Any, Optional
2
2
  import typing
3
3
  from autocoder.common import AutoCoderArgs
4
- from autocoder.common.mcp_server_types import McpRequest
5
4
  from autocoder.common.v2.agent.agentic_edit_tools.base_tool_resolver import BaseToolResolver
6
5
  from autocoder.common.v2.agent.agentic_edit_types import UseMcpTool, ToolResult # Import ToolResult from types
7
- from autocoder.common.mcp_server import get_mcp_server
6
+ from autocoder.common.mcp_tools.types import McpRequest
7
+ from autocoder.common.mcp_tools.server import get_mcp_server
8
8
  from loguru import logger
9
9
 
10
10
  if typing.TYPE_CHECKING: