auto-coder 0.1.400__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 (579) 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-0.1.400.dist-info → auto_coder-2.0.0.dist-info}/WHEEL +1 -1
  5. {auto_coder-0.1.400.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 +25 -4
  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 +1029 -2310
  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 +1021 -372
  28. autocoder/chat_auto_coder_lang.py +23 -732
  29. autocoder/commands/auto_command.py +26 -9
  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/file_monitor/test_file_monitor.py +307 -0
  119. autocoder/common/git_utils.py +51 -10
  120. autocoder/common/global_cancel.py +15 -6
  121. autocoder/common/ignorefiles/test_ignore_file_utils.py +1 -1
  122. autocoder/common/international/__init__.py +31 -0
  123. autocoder/common/international/demo_international.py +92 -0
  124. autocoder/common/international/message_manager.py +157 -0
  125. autocoder/common/international/messages/__init__.py +56 -0
  126. autocoder/common/international/messages/async_command_messages.py +507 -0
  127. autocoder/common/international/messages/auto_coder_messages.py +2208 -0
  128. autocoder/common/international/messages/chat_auto_coder_messages.py +1547 -0
  129. autocoder/common/international/messages/command_help_messages.py +986 -0
  130. autocoder/common/international/messages/conversation_command_messages.py +191 -0
  131. autocoder/common/international/messages/git_helper_plugin_messages.py +159 -0
  132. autocoder/common/international/messages/queue_command_messages.py +751 -0
  133. autocoder/common/international/messages/rules_command_messages.py +77 -0
  134. autocoder/common/international/messages/sdk_messages.py +1707 -0
  135. autocoder/common/international/messages/token_helper_plugin_messages.py +361 -0
  136. autocoder/common/international/messages/tool_display_messages.py +1212 -0
  137. autocoder/common/international/messages/workflow_exception_messages.py +473 -0
  138. autocoder/common/international/test_international.py +612 -0
  139. autocoder/common/linter_core/__init__.py +28 -0
  140. autocoder/common/linter_core/base_linter.py +61 -0
  141. autocoder/common/linter_core/config_loader.py +271 -0
  142. autocoder/common/linter_core/formatters/__init__.py +0 -0
  143. autocoder/common/linter_core/formatters/base_formatter.py +38 -0
  144. autocoder/common/linter_core/formatters/raw_formatter.py +17 -0
  145. autocoder/common/linter_core/linter.py +166 -0
  146. autocoder/common/linter_core/linter_factory.py +216 -0
  147. autocoder/common/linter_core/linter_manager.py +333 -0
  148. autocoder/common/linter_core/linters/__init__.py +9 -0
  149. autocoder/common/linter_core/linters/java_linter.py +342 -0
  150. autocoder/common/linter_core/linters/python_linter.py +115 -0
  151. autocoder/common/linter_core/linters/typescript_linter.py +119 -0
  152. autocoder/common/linter_core/models/__init__.py +7 -0
  153. autocoder/common/linter_core/models/lint_result.py +91 -0
  154. autocoder/common/linter_core/models.py +33 -0
  155. autocoder/common/linter_core/tests/__init__.py +3 -0
  156. autocoder/common/linter_core/tests/test_config_loader.py +323 -0
  157. autocoder/common/linter_core/tests/test_config_loading.py +308 -0
  158. autocoder/common/linter_core/tests/test_factory_manager.py +234 -0
  159. autocoder/common/linter_core/tests/test_formatters.py +147 -0
  160. autocoder/common/linter_core/tests/test_integration.py +317 -0
  161. autocoder/common/linter_core/tests/test_java_linter.py +496 -0
  162. autocoder/common/linter_core/tests/test_linters.py +265 -0
  163. autocoder/common/linter_core/tests/test_models.py +81 -0
  164. autocoder/common/linter_core/tests/verify_config_loading.py +296 -0
  165. autocoder/common/linter_core/tests/verify_fixes.py +183 -0
  166. autocoder/common/llm_friendly_package/__init__.py +31 -0
  167. autocoder/common/llm_friendly_package/base_manager.py +102 -0
  168. autocoder/common/llm_friendly_package/docs_manager.py +121 -0
  169. autocoder/common/llm_friendly_package/library_manager.py +171 -0
  170. autocoder/common/{llm_friendly_package.py → llm_friendly_package/main_manager.py} +204 -231
  171. autocoder/common/llm_friendly_package/models.py +40 -0
  172. autocoder/common/llm_friendly_package/test_llm_friendly_package.py +536 -0
  173. autocoder/common/llms/__init__.py +15 -0
  174. autocoder/common/llms/demo_error_handling.py +85 -0
  175. autocoder/common/llms/factory.py +142 -0
  176. autocoder/common/llms/manager.py +264 -0
  177. autocoder/common/llms/pricing.py +121 -0
  178. autocoder/common/llms/registry.py +288 -0
  179. autocoder/common/llms/schema.py +77 -0
  180. autocoder/common/llms/simple_demo.py +45 -0
  181. autocoder/common/llms/test_quick_model.py +116 -0
  182. autocoder/common/llms/test_remove_functionality.py +182 -0
  183. autocoder/common/llms/tests/__init__.py +1 -0
  184. autocoder/common/llms/tests/test_manager.py +330 -0
  185. autocoder/common/llms/tests/test_registry.py +364 -0
  186. autocoder/common/mcp_tools/__init__.py +62 -0
  187. autocoder/common/{mcp_tools.py → mcp_tools/executor.py} +49 -40
  188. autocoder/common/{mcp_hub.py → mcp_tools/hub.py} +42 -68
  189. autocoder/common/{mcp_server_install.py → mcp_tools/installer.py} +16 -28
  190. autocoder/common/{mcp_server.py → mcp_tools/server.py} +176 -48
  191. autocoder/common/mcp_tools/test_keyboard_interrupt.py +93 -0
  192. autocoder/common/mcp_tools/test_mcp_tools.py +391 -0
  193. autocoder/common/{mcp_server_types.py → mcp_tools/types.py} +121 -48
  194. autocoder/common/mcp_tools/verify_functionality.py +202 -0
  195. autocoder/common/model_speed_tester.py +32 -26
  196. autocoder/common/priority_directory_finder/__init__.py +142 -0
  197. autocoder/common/priority_directory_finder/examples.py +230 -0
  198. autocoder/common/priority_directory_finder/finder.py +283 -0
  199. autocoder/common/priority_directory_finder/models.py +236 -0
  200. autocoder/common/priority_directory_finder/test_priority_directory_finder.py +431 -0
  201. autocoder/common/project_scanner/__init__.py +18 -0
  202. autocoder/common/project_scanner/compat.py +77 -0
  203. autocoder/common/project_scanner/scanner.py +436 -0
  204. autocoder/common/project_tracker/__init__.py +27 -0
  205. autocoder/common/project_tracker/api.py +228 -0
  206. autocoder/common/project_tracker/demo.py +272 -0
  207. autocoder/common/project_tracker/tracker.py +487 -0
  208. autocoder/common/project_tracker/types.py +53 -0
  209. autocoder/common/pruner/__init__.py +67 -0
  210. autocoder/common/pruner/agentic_conversation_pruner.py +746 -0
  211. autocoder/common/{context_pruner.py → pruner/context_pruner.py} +137 -40
  212. autocoder/common/pruner/conversation_message_ids_api.py +386 -0
  213. autocoder/common/pruner/conversation_message_ids_manager.py +347 -0
  214. autocoder/common/pruner/conversation_message_ids_pruner.py +473 -0
  215. autocoder/common/pruner/conversation_normalizer.py +347 -0
  216. autocoder/common/{conversation_pruner.py → pruner/conversation_pruner.py} +26 -6
  217. autocoder/common/pruner/test_agentic_conversation_pruner.py +784 -0
  218. autocoder/common/pruner/test_context_pruner.py +546 -0
  219. autocoder/common/pruner/test_conversation_normalizer.py +502 -0
  220. autocoder/common/pruner/test_tool_content_detector.py +324 -0
  221. autocoder/common/pruner/tool_content_detector.py +227 -0
  222. autocoder/common/pruner/tools/__init__.py +18 -0
  223. autocoder/common/pruner/tools/query_message_ids.py +264 -0
  224. autocoder/common/pruner/tools/test_agentic_pruning_logic.py +432 -0
  225. autocoder/common/pruner/tools/test_message_ids_pruning_only.py +192 -0
  226. autocoder/common/pull_requests/__init__.py +9 -1
  227. autocoder/common/pull_requests/utils.py +122 -1
  228. autocoder/common/rag_manager/rag_manager.py +36 -40
  229. autocoder/common/rulefiles/__init__.py +53 -1
  230. autocoder/common/rulefiles/api.py +250 -0
  231. autocoder/common/rulefiles/core/__init__.py +14 -0
  232. autocoder/common/rulefiles/core/manager.py +241 -0
  233. autocoder/common/rulefiles/core/selector.py +805 -0
  234. autocoder/common/rulefiles/models/__init__.py +20 -0
  235. autocoder/common/rulefiles/models/index.py +16 -0
  236. autocoder/common/rulefiles/models/init_rule.py +18 -0
  237. autocoder/common/rulefiles/models/rule_file.py +18 -0
  238. autocoder/common/rulefiles/models/rule_relevance.py +14 -0
  239. autocoder/common/rulefiles/models/summary.py +16 -0
  240. autocoder/common/rulefiles/test_rulefiles.py +776 -0
  241. autocoder/common/rulefiles/utils/__init__.py +34 -0
  242. autocoder/common/rulefiles/utils/monitor.py +86 -0
  243. autocoder/common/rulefiles/utils/parser.py +230 -0
  244. autocoder/common/save_formatted_log.py +67 -10
  245. autocoder/common/search_replace.py +8 -1
  246. autocoder/common/search_replace_patch/__init__.py +24 -0
  247. autocoder/common/search_replace_patch/base.py +115 -0
  248. autocoder/common/search_replace_patch/manager.py +248 -0
  249. autocoder/common/search_replace_patch/patch_replacer.py +304 -0
  250. autocoder/common/search_replace_patch/similarity_replacer.py +306 -0
  251. autocoder/common/search_replace_patch/string_replacer.py +181 -0
  252. autocoder/common/search_replace_patch/tests/__init__.py +3 -0
  253. autocoder/common/search_replace_patch/tests/run_tests.py +126 -0
  254. autocoder/common/search_replace_patch/tests/test_base.py +188 -0
  255. autocoder/common/search_replace_patch/tests/test_empty_line_insert.py +233 -0
  256. autocoder/common/search_replace_patch/tests/test_integration.py +389 -0
  257. autocoder/common/search_replace_patch/tests/test_manager.py +351 -0
  258. autocoder/common/search_replace_patch/tests/test_patch_replacer.py +316 -0
  259. autocoder/common/search_replace_patch/tests/test_regex_replacer.py +306 -0
  260. autocoder/common/search_replace_patch/tests/test_similarity_replacer.py +384 -0
  261. autocoder/common/shell_commands/__init__.py +197 -0
  262. autocoder/common/shell_commands/background_process_notifier.py +346 -0
  263. autocoder/common/shell_commands/command_executor.py +1127 -0
  264. autocoder/common/shell_commands/error_recovery.py +541 -0
  265. autocoder/common/shell_commands/exceptions.py +120 -0
  266. autocoder/common/shell_commands/interactive_executor.py +476 -0
  267. autocoder/common/shell_commands/interactive_pexpect_process.py +623 -0
  268. autocoder/common/shell_commands/interactive_process.py +744 -0
  269. autocoder/common/shell_commands/interactive_session_manager.py +1014 -0
  270. autocoder/common/shell_commands/monitoring.py +529 -0
  271. autocoder/common/shell_commands/process_cleanup.py +386 -0
  272. autocoder/common/shell_commands/process_manager.py +606 -0
  273. autocoder/common/shell_commands/test_interactive_pexpect_process.py +281 -0
  274. autocoder/common/shell_commands/tests/__init__.py +6 -0
  275. autocoder/common/shell_commands/tests/conftest.py +118 -0
  276. autocoder/common/shell_commands/tests/test_background_process_notifier.py +703 -0
  277. autocoder/common/shell_commands/tests/test_command_executor.py +448 -0
  278. autocoder/common/shell_commands/tests/test_error_recovery.py +305 -0
  279. autocoder/common/shell_commands/tests/test_exceptions.py +299 -0
  280. autocoder/common/shell_commands/tests/test_execute_batch.py +588 -0
  281. autocoder/common/shell_commands/tests/test_indented_batch_commands.py +244 -0
  282. autocoder/common/shell_commands/tests/test_integration.py +664 -0
  283. autocoder/common/shell_commands/tests/test_monitoring.py +546 -0
  284. autocoder/common/shell_commands/tests/test_performance.py +632 -0
  285. autocoder/common/shell_commands/tests/test_process_cleanup.py +397 -0
  286. autocoder/common/shell_commands/tests/test_process_manager.py +606 -0
  287. autocoder/common/shell_commands/tests/test_timeout_config.py +343 -0
  288. autocoder/common/shell_commands/tests/test_timeout_manager.py +520 -0
  289. autocoder/common/shell_commands/timeout_config.py +315 -0
  290. autocoder/common/shell_commands/timeout_manager.py +352 -0
  291. autocoder/common/terminal_paste/__init__.py +14 -0
  292. autocoder/common/terminal_paste/demo.py +145 -0
  293. autocoder/common/terminal_paste/demo_paste_functionality.py +95 -0
  294. autocoder/common/terminal_paste/paste_handler.py +200 -0
  295. autocoder/common/terminal_paste/paste_manager.py +118 -0
  296. autocoder/common/terminal_paste/tests/__init__.py +1 -0
  297. autocoder/common/terminal_paste/tests/test_paste_handler.py +182 -0
  298. autocoder/common/terminal_paste/tests/test_paste_manager.py +126 -0
  299. autocoder/common/terminal_paste/utils.py +163 -0
  300. autocoder/common/test_autocoder_args.py +232 -0
  301. autocoder/common/test_env_manager.py +173 -0
  302. autocoder/common/test_env_manager_integration.py +159 -0
  303. autocoder/common/text_similarity/__init__.py +9 -0
  304. autocoder/common/text_similarity/demo.py +216 -0
  305. autocoder/common/text_similarity/examples.py +266 -0
  306. autocoder/common/text_similarity/test_text_similarity.py +306 -0
  307. autocoder/common/text_similarity/text_similarity.py +194 -0
  308. autocoder/common/text_similarity/utils.py +125 -0
  309. autocoder/common/todos/__init__.py +61 -0
  310. autocoder/common/todos/cache/__init__.py +16 -0
  311. autocoder/common/todos/cache/base_cache.py +89 -0
  312. autocoder/common/todos/cache/cache_manager.py +228 -0
  313. autocoder/common/todos/cache/memory_cache.py +225 -0
  314. autocoder/common/todos/config.py +155 -0
  315. autocoder/common/todos/exceptions.py +35 -0
  316. autocoder/common/todos/get_todo_manager.py +161 -0
  317. autocoder/common/todos/manager.py +537 -0
  318. autocoder/common/todos/models.py +239 -0
  319. autocoder/common/todos/storage/__init__.py +14 -0
  320. autocoder/common/todos/storage/base_storage.py +76 -0
  321. autocoder/common/todos/storage/file_storage.py +278 -0
  322. autocoder/common/tokens/__init__.py +15 -0
  323. autocoder/common/tokens/counter.py +44 -2
  324. autocoder/common/tools_manager/__init__.py +17 -0
  325. autocoder/common/tools_manager/examples.py +162 -0
  326. autocoder/common/tools_manager/manager.py +385 -0
  327. autocoder/common/tools_manager/models.py +39 -0
  328. autocoder/common/tools_manager/test_tools_manager.py +303 -0
  329. autocoder/common/tools_manager/utils.py +191 -0
  330. autocoder/common/v2/agent/agentic_callbacks.py +270 -0
  331. autocoder/common/v2/agent/agentic_edit.py +2729 -2052
  332. autocoder/common/v2/agent/agentic_edit_change_manager.py +474 -0
  333. autocoder/common/v2/agent/agentic_edit_tools/__init__.py +43 -2
  334. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_list_tool_resolver.py +279 -0
  335. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_read_tool_resolver.py +40 -0
  336. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +52 -0
  337. autocoder/common/v2/agent/agentic_edit_tools/ask_followup_question_tool_resolver.py +8 -0
  338. autocoder/common/v2/agent/agentic_edit_tools/background_task_tool_resolver.py +1167 -0
  339. autocoder/common/v2/agent/agentic_edit_tools/base_tool_resolver.py +2 -2
  340. autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_read_tool_resolver.py +214 -0
  341. autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_write_tool_resolver.py +299 -0
  342. autocoder/common/v2/agent/agentic_edit_tools/count_tokens_tool_resolver.py +290 -0
  343. autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +565 -30
  344. autocoder/common/v2/agent/agentic_edit_tools/execute_workflow_tool_resolver.py +485 -0
  345. autocoder/common/v2/agent/agentic_edit_tools/extract_to_text_tool_resolver.py +225 -0
  346. autocoder/common/v2/agent/agentic_edit_tools/lint_report.py +79 -0
  347. autocoder/common/v2/agent/agentic_edit_tools/linter_config_models.py +343 -0
  348. autocoder/common/v2/agent/agentic_edit_tools/linter_enabled_tool_resolver.py +189 -0
  349. autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py +169 -101
  350. autocoder/common/v2/agent/agentic_edit_tools/load_extra_document_tool_resolver.py +349 -0
  351. autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +244 -51
  352. autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py +667 -147
  353. autocoder/common/v2/agent/agentic_edit_tools/run_named_subagents_tool_resolver.py +691 -0
  354. autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +409 -140
  355. autocoder/common/v2/agent/agentic_edit_tools/session_interactive_tool_resolver.py +115 -0
  356. autocoder/common/v2/agent/agentic_edit_tools/session_start_tool_resolver.py +190 -0
  357. autocoder/common/v2/agent/agentic_edit_tools/session_stop_tool_resolver.py +76 -0
  358. autocoder/common/v2/agent/agentic_edit_tools/test_write_to_file_tool_resolver.py +209 -194
  359. autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +135 -0
  360. autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +328 -0
  361. autocoder/common/v2/agent/agentic_edit_tools/use_mcp_tool_resolver.py +2 -2
  362. autocoder/common/v2/agent/agentic_edit_tools/web_crawl_tool_resolver.py +557 -0
  363. autocoder/common/v2/agent/agentic_edit_tools/web_search_tool_resolver.py +600 -0
  364. autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py +56 -121
  365. autocoder/common/v2/agent/agentic_edit_types.py +386 -10
  366. autocoder/common/v2/agent/runner/__init__.py +31 -0
  367. autocoder/common/v2/agent/runner/base_runner.py +92 -0
  368. autocoder/common/v2/agent/runner/file_based_event_runner.py +217 -0
  369. autocoder/common/v2/agent/runner/sdk_runner.py +182 -0
  370. autocoder/common/v2/agent/runner/terminal_runner.py +396 -0
  371. autocoder/common/v2/agent/runner/tool_display.py +589 -0
  372. autocoder/common/v2/agent/test_agentic_callbacks.py +265 -0
  373. autocoder/common/v2/agent/test_agentic_edit.py +194 -0
  374. autocoder/common/v2/agent/tool_caller/__init__.py +24 -0
  375. autocoder/common/v2/agent/tool_caller/default_tool_resolver_map.py +135 -0
  376. autocoder/common/v2/agent/tool_caller/integration_test.py +172 -0
  377. autocoder/common/v2/agent/tool_caller/plugins/__init__.py +14 -0
  378. autocoder/common/v2/agent/tool_caller/plugins/base_plugin.py +126 -0
  379. autocoder/common/v2/agent/tool_caller/plugins/examples/__init__.py +13 -0
  380. autocoder/common/v2/agent/tool_caller/plugins/examples/logging_plugin.py +164 -0
  381. autocoder/common/v2/agent/tool_caller/plugins/examples/security_filter_plugin.py +198 -0
  382. autocoder/common/v2/agent/tool_caller/plugins/plugin_interface.py +141 -0
  383. autocoder/common/v2/agent/tool_caller/test_tool_caller.py +278 -0
  384. autocoder/common/v2/agent/tool_caller/tool_call_plugin_manager.py +331 -0
  385. autocoder/common/v2/agent/tool_caller/tool_caller.py +337 -0
  386. autocoder/common/v2/agent/tool_caller/usage_example.py +193 -0
  387. autocoder/common/v2/code_agentic_editblock_manager.py +4 -4
  388. autocoder/common/v2/code_auto_generate.py +136 -78
  389. autocoder/common/v2/code_auto_generate_diff.py +135 -79
  390. autocoder/common/v2/code_auto_generate_editblock.py +174 -99
  391. autocoder/common/v2/code_auto_generate_strict_diff.py +151 -71
  392. autocoder/common/v2/code_auto_merge.py +1 -1
  393. autocoder/common/v2/code_auto_merge_editblock.py +13 -1
  394. autocoder/common/v2/code_diff_manager.py +3 -3
  395. autocoder/common/v2/code_editblock_manager.py +4 -14
  396. autocoder/common/v2/code_manager.py +1 -1
  397. autocoder/common/v2/code_strict_diff_manager.py +2 -2
  398. autocoder/common/wrap_llm_hint/__init__.py +10 -0
  399. autocoder/common/wrap_llm_hint/test_wrap_llm_hint.py +1067 -0
  400. autocoder/common/wrap_llm_hint/utils.py +432 -0
  401. autocoder/common/wrap_llm_hint/wrap_llm_hint.py +323 -0
  402. autocoder/completer/__init__.py +8 -0
  403. autocoder/completer/command_completer_v2.py +1051 -0
  404. autocoder/default_project/__init__.py +501 -0
  405. autocoder/dispacher/__init__.py +4 -12
  406. autocoder/dispacher/actions/action.py +165 -7
  407. autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
  408. autocoder/index/entry.py +117 -125
  409. autocoder/{agent → index/filter}/agentic_filter.py +323 -334
  410. autocoder/index/filter/normal_filter.py +5 -11
  411. autocoder/index/filter/quick_filter.py +1 -1
  412. autocoder/index/index.py +36 -9
  413. autocoder/index/tests/__init__.py +1 -0
  414. autocoder/index/tests/run_tests.py +195 -0
  415. autocoder/index/tests/test_entry.py +303 -0
  416. autocoder/index/tests/test_index_manager.py +314 -0
  417. autocoder/index/tests/test_module_integration.py +300 -0
  418. autocoder/index/tests/test_symbols_utils.py +183 -0
  419. autocoder/inner/__init__.py +4 -0
  420. autocoder/inner/agentic.py +932 -0
  421. autocoder/inner/async_command_handler.py +992 -0
  422. autocoder/inner/conversation_command_handlers.py +623 -0
  423. autocoder/inner/merge_command_handler.py +213 -0
  424. autocoder/inner/queue_command_handler.py +684 -0
  425. autocoder/models.py +95 -266
  426. autocoder/plugins/git_helper_plugin.py +31 -29
  427. autocoder/plugins/token_helper_plugin.py +156 -37
  428. autocoder/pyproject/__init__.py +32 -29
  429. autocoder/rag/agentic_rag.py +215 -75
  430. autocoder/rag/cache/simple_cache.py +1 -2
  431. autocoder/rag/loaders/image_loader.py +1 -1
  432. autocoder/rag/long_context_rag.py +42 -26
  433. autocoder/rag/qa_conversation_strategy.py +1 -1
  434. autocoder/rag/terminal/__init__.py +17 -0
  435. autocoder/rag/terminal/args.py +581 -0
  436. autocoder/rag/terminal/bootstrap.py +61 -0
  437. autocoder/rag/terminal/command_handlers.py +653 -0
  438. autocoder/rag/terminal/formatters/__init__.py +20 -0
  439. autocoder/rag/terminal/formatters/base.py +70 -0
  440. autocoder/rag/terminal/formatters/json_format.py +66 -0
  441. autocoder/rag/terminal/formatters/stream_json.py +95 -0
  442. autocoder/rag/terminal/formatters/text.py +28 -0
  443. autocoder/rag/terminal/init.py +120 -0
  444. autocoder/rag/terminal/utils.py +106 -0
  445. autocoder/rag/test_agentic_rag.py +389 -0
  446. autocoder/rag/test_doc_filter.py +3 -3
  447. autocoder/rag/test_long_context_rag.py +1 -1
  448. autocoder/rag/test_token_limiter.py +517 -10
  449. autocoder/rag/token_counter.py +3 -0
  450. autocoder/rag/token_limiter.py +19 -15
  451. autocoder/rag/tools/__init__.py +26 -2
  452. autocoder/rag/tools/bochaai_example.py +343 -0
  453. autocoder/rag/tools/bochaai_sdk.py +541 -0
  454. autocoder/rag/tools/metaso_example.py +268 -0
  455. autocoder/rag/tools/metaso_sdk.py +417 -0
  456. autocoder/rag/tools/recall_tool.py +28 -7
  457. autocoder/rag/tools/run_integration_tests.py +204 -0
  458. autocoder/rag/tools/test_all_providers.py +318 -0
  459. autocoder/rag/tools/test_bochaai_integration.py +482 -0
  460. autocoder/rag/tools/test_final_integration.py +215 -0
  461. autocoder/rag/tools/test_metaso_integration.py +424 -0
  462. autocoder/rag/tools/test_metaso_real.py +171 -0
  463. autocoder/rag/tools/test_web_crawl_tool.py +639 -0
  464. autocoder/rag/tools/test_web_search_tool.py +509 -0
  465. autocoder/rag/tools/todo_read_tool.py +202 -0
  466. autocoder/rag/tools/todo_write_tool.py +412 -0
  467. autocoder/rag/tools/web_crawl_tool.py +634 -0
  468. autocoder/rag/tools/web_search_tool.py +558 -0
  469. autocoder/rag/tools/web_tools_example.py +119 -0
  470. autocoder/rag/types.py +16 -0
  471. autocoder/rag/variable_holder.py +4 -2
  472. autocoder/rags.py +86 -79
  473. autocoder/regexproject/__init__.py +23 -21
  474. autocoder/run_context.py +9 -0
  475. autocoder/sdk/__init__.py +50 -161
  476. autocoder/sdk/api.py +370 -0
  477. autocoder/sdk/async_runner/__init__.py +26 -0
  478. autocoder/sdk/async_runner/async_executor.py +650 -0
  479. autocoder/sdk/async_runner/async_handler.py +356 -0
  480. autocoder/sdk/async_runner/markdown_processor.py +595 -0
  481. autocoder/sdk/async_runner/task_metadata.py +284 -0
  482. autocoder/sdk/async_runner/worktree_manager.py +438 -0
  483. autocoder/sdk/cli/__init__.py +2 -5
  484. autocoder/sdk/cli/formatters.py +28 -204
  485. autocoder/sdk/cli/handlers.py +77 -44
  486. autocoder/sdk/cli/main.py +158 -170
  487. autocoder/sdk/cli/options.py +95 -22
  488. autocoder/sdk/constants.py +139 -51
  489. autocoder/sdk/core/auto_coder_core.py +484 -267
  490. autocoder/sdk/core/bridge.py +298 -118
  491. autocoder/sdk/exceptions.py +18 -12
  492. autocoder/sdk/formatters/__init__.py +19 -0
  493. autocoder/sdk/formatters/input.py +64 -0
  494. autocoder/sdk/formatters/output.py +247 -0
  495. autocoder/sdk/formatters/stream.py +54 -0
  496. autocoder/sdk/models/__init__.py +6 -5
  497. autocoder/sdk/models/options.py +55 -18
  498. autocoder/sdk/utils/formatters.py +27 -195
  499. autocoder/suffixproject/__init__.py +28 -25
  500. autocoder/terminal/__init__.py +14 -0
  501. autocoder/terminal/app.py +454 -0
  502. autocoder/terminal/args.py +32 -0
  503. autocoder/terminal/bootstrap.py +178 -0
  504. autocoder/terminal/command_processor.py +521 -0
  505. autocoder/terminal/command_registry.py +57 -0
  506. autocoder/terminal/help.py +97 -0
  507. autocoder/terminal/tasks/__init__.py +5 -0
  508. autocoder/terminal/tasks/background.py +77 -0
  509. autocoder/terminal/tasks/task_event.py +70 -0
  510. autocoder/terminal/ui/__init__.py +13 -0
  511. autocoder/terminal/ui/completer.py +268 -0
  512. autocoder/terminal/ui/keybindings.py +75 -0
  513. autocoder/terminal/ui/session.py +41 -0
  514. autocoder/terminal/ui/toolbar.py +64 -0
  515. autocoder/terminal/utils/__init__.py +13 -0
  516. autocoder/terminal/utils/errors.py +18 -0
  517. autocoder/terminal/utils/paths.py +19 -0
  518. autocoder/terminal/utils/shell.py +43 -0
  519. autocoder/terminal_v3/__init__.py +10 -0
  520. autocoder/terminal_v3/app.py +201 -0
  521. autocoder/terminal_v3/handlers/__init__.py +5 -0
  522. autocoder/terminal_v3/handlers/command_handler.py +131 -0
  523. autocoder/terminal_v3/models/__init__.py +6 -0
  524. autocoder/terminal_v3/models/conversation_buffer.py +214 -0
  525. autocoder/terminal_v3/models/message.py +50 -0
  526. autocoder/terminal_v3/models/tool_display.py +247 -0
  527. autocoder/terminal_v3/ui/__init__.py +7 -0
  528. autocoder/terminal_v3/ui/keybindings.py +56 -0
  529. autocoder/terminal_v3/ui/layout.py +141 -0
  530. autocoder/terminal_v3/ui/styles.py +43 -0
  531. autocoder/tsproject/__init__.py +23 -23
  532. autocoder/utils/auto_coder_utils/chat_stream_out.py +1 -1
  533. autocoder/utils/llms.py +88 -80
  534. autocoder/utils/math_utils.py +101 -0
  535. autocoder/utils/model_provider_selector.py +16 -4
  536. autocoder/utils/operate_config_api.py +33 -5
  537. autocoder/utils/thread_utils.py +2 -2
  538. autocoder/version.py +4 -2
  539. autocoder/workflow_agents/__init__.py +84 -0
  540. autocoder/workflow_agents/agent.py +143 -0
  541. autocoder/workflow_agents/exceptions.py +573 -0
  542. autocoder/workflow_agents/executor.py +489 -0
  543. autocoder/workflow_agents/loader.py +737 -0
  544. autocoder/workflow_agents/runner.py +267 -0
  545. autocoder/workflow_agents/types.py +172 -0
  546. autocoder/workflow_agents/utils.py +434 -0
  547. autocoder/workflow_agents/workflow_manager.py +211 -0
  548. auto_coder-0.1.400.dist-info/METADATA +0 -396
  549. auto_coder-0.1.400.dist-info/RECORD +0 -425
  550. auto_coder-0.1.400.dist-info/licenses/LICENSE +0 -201
  551. autocoder/auto_coder_server.py +0 -672
  552. autocoder/benchmark.py +0 -138
  553. autocoder/common/ac_style_command_parser/example.py +0 -7
  554. autocoder/common/cleaner.py +0 -31
  555. autocoder/common/command_completer_v2.py +0 -615
  556. autocoder/common/directory_cache/__init__.py +0 -1
  557. autocoder/common/directory_cache/cache.py +0 -192
  558. autocoder/common/directory_cache/test_cache.py +0 -190
  559. autocoder/common/file_checkpoint/examples.py +0 -217
  560. autocoder/common/llm_friendly_package_example.py +0 -138
  561. autocoder/common/llm_friendly_package_test.py +0 -63
  562. autocoder/common/pull_requests/test_module.py +0 -1
  563. autocoder/common/rulefiles/autocoderrules_utils.py +0 -484
  564. autocoder/common/text.py +0 -30
  565. autocoder/common/v2/agent/agentic_edit_tools/list_package_info_tool_resolver.py +0 -42
  566. autocoder/common/v2/agent/agentic_edit_tools/test_execute_command_tool_resolver.py +0 -70
  567. autocoder/common/v2/agent/agentic_edit_tools/test_search_files_tool_resolver.py +0 -163
  568. autocoder/common/v2/agent/agentic_tool_display.py +0 -183
  569. autocoder/plugins/dynamic_completion_example.py +0 -148
  570. autocoder/plugins/sample_plugin.py +0 -160
  571. autocoder/sdk/cli/__main__.py +0 -26
  572. autocoder/sdk/cli/completion_wrapper.py +0 -38
  573. autocoder/sdk/cli/install_completion.py +0 -301
  574. autocoder/sdk/models/messages.py +0 -209
  575. autocoder/sdk/session/__init__.py +0 -32
  576. autocoder/sdk/session/session.py +0 -106
  577. autocoder/sdk/session/session_manager.py +0 -56
  578. {auto_coder-0.1.400.dist-info → auto_coder-2.0.0.dist-info}/top_level.txt +0 -0
  579. /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
@@ -0,0 +1,324 @@
1
+ import pytest
2
+ from .tool_content_detector import ToolContentDetector
3
+
4
+
5
+ class TestToolContentDetector:
6
+ """测试 ToolContentDetector 类的各种功能"""
7
+
8
+ def setup_method(self):
9
+ """每个测试方法前的设置"""
10
+ self.detector = ToolContentDetector()
11
+
12
+ def test_init(self):
13
+ """测试初始化"""
14
+ detector = ToolContentDetector()
15
+ assert detector.replacement_message == "Content cleared to save tokens"
16
+ assert len(detector.supported_tools) == 2
17
+ assert "write_to_file" in detector.supported_tools
18
+ assert "replace_in_file" in detector.supported_tools
19
+
20
+ def test_init_with_custom_message(self):
21
+ """测试自定义替换消息的初始化"""
22
+ custom_message = "Custom replacement message"
23
+ detector = ToolContentDetector(replacement_message=custom_message)
24
+ assert detector.replacement_message == custom_message
25
+
26
+ def test_detect_tool_call_write_to_file(self):
27
+ """测试检测 write_to_file 工具调用"""
28
+ content = """Some text before
29
+ <write_to_file>
30
+ <path>test.py</path>
31
+ <content>
32
+ def hello():
33
+ print("Hello, World!")
34
+ </content>
35
+ </write_to_file>
36
+ Some text after"""
37
+
38
+ result = self.detector.detect_tool_call(content)
39
+ assert result is not None
40
+ assert result['tool_name'] == 'write_to_file'
41
+ assert 'def hello():' in result['content_inner']
42
+ assert result['start_pos'] > 0
43
+ assert result['end_pos'] > result['start_pos']
44
+
45
+ def test_detect_tool_call_replace_in_file(self):
46
+ """测试检测 replace_in_file 工具调用"""
47
+ content = """Some text before
48
+ <replace_in_file>
49
+ <path>test.py</path>
50
+ <diff>
51
+ - old_function()
52
+ + new_function()
53
+ </diff>
54
+ </replace_in_file>
55
+ Some text after"""
56
+
57
+ result = self.detector.detect_tool_call(content)
58
+ assert result is not None
59
+ assert result['tool_name'] == 'replace_in_file'
60
+ assert 'old_function()' in result['content_inner']
61
+ assert 'new_function()' in result['content_inner']
62
+
63
+ def test_detect_tool_call_case_insensitive(self):
64
+ """测试大小写不敏感的工具调用检测"""
65
+ content = """
66
+ <WRITE_TO_FILE>
67
+ <path>test.py</path>
68
+ <CONTENT>
69
+ print("test")
70
+ </CONTENT>
71
+ </WRITE_TO_FILE>"""
72
+
73
+ result = self.detector.detect_tool_call(content)
74
+ assert result is not None
75
+ assert result['tool_name'] == 'write_to_file'
76
+
77
+ def test_detect_tool_call_no_tool(self):
78
+ """测试不包含工具调用的内容"""
79
+ content = "This is just plain text without any tool calls."
80
+ result = self.detector.detect_tool_call(content)
81
+ assert result is None
82
+
83
+ def test_detect_tool_call_empty_content(self):
84
+ """测试空内容"""
85
+ result = self.detector.detect_tool_call("")
86
+ assert result is None
87
+
88
+ result = self.detector.detect_tool_call(None)
89
+ assert result is None
90
+
91
+ def test_detect_tool_call_incomplete_tool(self):
92
+ """测试不完整的工具调用"""
93
+ content = "<write_to_file><path>test.py</path>"
94
+ result = self.detector.detect_tool_call(content)
95
+ assert result is None
96
+
97
+ def test_replace_tool_content_short_content(self):
98
+ """测试替换短内容(不应该替换)"""
99
+ content = """
100
+ <write_to_file>
101
+ <path>test.py</path>
102
+ <content>
103
+ print("short")
104
+ </content>
105
+ </write_to_file>"""
106
+
107
+ new_content, replaced = self.detector.replace_tool_content(content, max_content_length=500)
108
+ assert not replaced
109
+ assert new_content == content
110
+
111
+ def test_replace_tool_content_long_content(self):
112
+ """测试替换长内容"""
113
+ long_code = "def test():\n " + "print('line')\n " * 50
114
+ content = f"""
115
+ <write_to_file>
116
+ <path>test.py</path>
117
+ <content>
118
+ {long_code}
119
+ </content>
120
+ </write_to_file>"""
121
+
122
+ new_content, replaced = self.detector.replace_tool_content(content, max_content_length=100)
123
+ assert replaced
124
+ assert "Content cleared to save tokens" in new_content
125
+ assert long_code not in new_content
126
+ assert "<write_to_file>" in new_content
127
+ assert "</write_to_file>" in new_content
128
+
129
+ def test_replace_tool_content_replace_in_file(self):
130
+ """测试替换 replace_in_file 中的长内容"""
131
+ long_diff = "- old_line\n+ new_line\n" * 50
132
+ content = f"""
133
+ <replace_in_file>
134
+ <path>test.py</path>
135
+ <diff>
136
+ {long_diff}
137
+ </diff>
138
+ </replace_in_file>"""
139
+
140
+ new_content, replaced = self.detector.replace_tool_content(content, max_content_length=100)
141
+ assert replaced
142
+ assert "Content cleared to save tokens" in new_content
143
+ assert long_diff not in new_content
144
+ assert "<diff>" in new_content
145
+ assert "</diff>" in new_content
146
+
147
+ def test_replace_tool_content_no_tool(self):
148
+ """测试替换不包含工具调用的内容"""
149
+ content = "This is just plain text."
150
+ new_content, replaced = self.detector.replace_tool_content(content)
151
+ assert not replaced
152
+ assert new_content == content
153
+
154
+ def test_get_tool_content_stats_with_tool(self):
155
+ """测试获取包含工具调用的统计信息"""
156
+ content = """Some prefix
157
+ <write_to_file>
158
+ <path>test.py</path>
159
+ <content>
160
+ def hello():
161
+ print("Hello!")
162
+ </content>
163
+ </write_to_file>
164
+ Some suffix"""
165
+
166
+ stats = self.detector.get_tool_content_stats(content)
167
+ assert stats['has_tool_call'] is True
168
+ assert stats['tool_name'] == 'write_to_file'
169
+ assert stats['total_length'] == len(content)
170
+ assert stats['tool_content_length'] > 0
171
+ assert stats['prefix_length'] > 0
172
+ assert stats['suffix_length'] > 0
173
+
174
+ def test_get_tool_content_stats_no_tool(self):
175
+ """测试获取不包含工具调用的统计信息"""
176
+ content = "This is just plain text."
177
+ stats = self.detector.get_tool_content_stats(content)
178
+ assert stats['has_tool_call'] is False
179
+ assert stats['total_length'] == len(content)
180
+
181
+ def test_get_tool_content_stats_empty(self):
182
+ """测试获取空内容的统计信息"""
183
+ stats = self.detector.get_tool_content_stats("")
184
+ assert stats['has_tool_call'] is False
185
+ assert stats['total_length'] == 0
186
+
187
+ def test_is_tool_call_content_true(self):
188
+ """测试判断包含工具调用的内容"""
189
+ content = """
190
+ <write_to_file>
191
+ <path>test.py</path>
192
+ <content>print("test")</content>
193
+ </write_to_file>"""
194
+
195
+ assert self.detector.is_tool_call_content(content) is True
196
+
197
+ def test_is_tool_call_content_false(self):
198
+ """测试判断不包含工具调用的内容"""
199
+ content = "This is just plain text."
200
+ assert self.detector.is_tool_call_content(content) is False
201
+
202
+ def test_extract_tool_content_write_to_file(self):
203
+ """测试提取 write_to_file 的内容"""
204
+ content = """
205
+ <write_to_file>
206
+ <path>test.py</path>
207
+ <content>
208
+ def hello():
209
+ print("Hello!")
210
+ </content>
211
+ </write_to_file>"""
212
+
213
+ extracted = self.detector.extract_tool_content(content)
214
+ assert extracted is not None
215
+ assert "def hello():" in extracted
216
+ assert 'print("Hello!")' in extracted
217
+
218
+ def test_extract_tool_content_replace_in_file(self):
219
+ """测试提取 replace_in_file 的内容"""
220
+ content = """
221
+ <replace_in_file>
222
+ <path>test.py</path>
223
+ <diff>
224
+ - old_function()
225
+ + new_function()
226
+ </diff>
227
+ </replace_in_file>"""
228
+
229
+ extracted = self.detector.extract_tool_content(content)
230
+ assert extracted is not None
231
+ assert "old_function()" in extracted
232
+ assert "new_function()" in extracted
233
+
234
+ def test_extract_tool_content_no_tool(self):
235
+ """测试提取不包含工具调用的内容"""
236
+ content = "This is just plain text."
237
+ extracted = self.detector.extract_tool_content(content)
238
+ assert extracted is None
239
+
240
+ def test_get_supported_tools(self):
241
+ """测试获取支持的工具列表"""
242
+ tools = self.detector.get_supported_tools()
243
+ assert isinstance(tools, list)
244
+ assert len(tools) == 2
245
+ assert "write_to_file" in tools
246
+ assert "replace_in_file" in tools
247
+
248
+ def test_multiple_tool_calls(self):
249
+ """测试包含多个工具调用的内容(应该只检测第一个)"""
250
+ content = """
251
+ <write_to_file>
252
+ <path>test1.py</path>
253
+ <content>print("first")</content>
254
+ </write_to_file>
255
+
256
+ <write_to_file>
257
+ <path>test2.py</path>
258
+ <content>print("second")</content>
259
+ </write_to_file>"""
260
+
261
+ result = self.detector.detect_tool_call(content)
262
+ assert result is not None
263
+ assert result['tool_name'] == 'write_to_file'
264
+ assert 'print("first")' in result['content_inner']
265
+
266
+ def test_nested_tags(self):
267
+ """测试嵌套标签的处理"""
268
+ content = """
269
+ <write_to_file>
270
+ <path>test.py</path>
271
+ <content>
272
+ <div>
273
+ <p>This is HTML content</p>
274
+ </div>
275
+ </content>
276
+ </write_to_file>"""
277
+
278
+ result = self.detector.detect_tool_call(content)
279
+ assert result is not None
280
+ assert "<div>" in result['content_inner']
281
+ assert "<p>This is HTML content</p>" in result['content_inner']
282
+
283
+ def test_multiline_content(self):
284
+ """测试多行内容的处理"""
285
+ content = """
286
+ <write_to_file>
287
+ <path>test.py</path>
288
+ <content>
289
+ class TestClass:
290
+ def __init__(self):
291
+ self.value = 42
292
+
293
+ def method(self):
294
+ return self.value
295
+ </content>
296
+ </write_to_file>"""
297
+
298
+ result = self.detector.detect_tool_call(content)
299
+ assert result is not None
300
+ assert "class TestClass:" in result['content_inner']
301
+ assert "def __init__(self):" in result['content_inner']
302
+ assert "def method(self):" in result['content_inner']
303
+
304
+ def test_content_with_special_characters(self):
305
+ """测试包含特殊字符的内容"""
306
+ content = """
307
+ <write_to_file>
308
+ <path>test.py</path>
309
+ <content>
310
+ # This is a comment with special chars: !@#$%^&*()
311
+ print("String with 'quotes' and \"double quotes\"")
312
+ regex = r"[a-zA-Z0-9]+"
313
+ </content>
314
+ </write_to_file>"""
315
+
316
+ result = self.detector.detect_tool_call(content)
317
+ assert result is not None
318
+ assert "!@#$%^&*()" in result['content_inner']
319
+ assert "'quotes'" in result['content_inner'] # 修复:查找单引号包围的quotes
320
+ assert r'[a-zA-Z0-9]+' in result['content_inner']
321
+
322
+
323
+ if __name__ == "__main__":
324
+ pytest.main([__file__, "-v"])
@@ -0,0 +1,227 @@
1
+ import re
2
+ from typing import Optional, Tuple, Dict, Any
3
+ from loguru import logger
4
+
5
+
6
+ class ToolContentDetector:
7
+ """
8
+ 工具内容检测器,用于识别和处理工具调用内容,特别是处理包含大量内容的工具调用。
9
+
10
+ 主要功能:
11
+ 1. 检测content是否包含工具调用(write_to_file, replace_in_file等)
12
+ 2. 替换工具调用中的大量内容部分,以减少token使用
13
+ """
14
+
15
+ def __init__(self, replacement_message: str = "Content cleared to save tokens"):
16
+ """
17
+ 初始化工具内容检测器
18
+
19
+ Args:
20
+ replacement_message: 替换大量内容时使用的消息
21
+ """
22
+ self.replacement_message = replacement_message
23
+
24
+ # 支持的工具列表
25
+ self.supported_tools = [
26
+ 'write_to_file',
27
+ 'replace_in_file'
28
+ ]
29
+
30
+ # 为每个工具定义正则表达式模式
31
+ self.tool_patterns = {
32
+ 'write_to_file': {
33
+ 'start': r'<write_to_file>',
34
+ 'end': r'</write_to_file>',
35
+ 'content_pattern': r'<content>(.*?)</content>',
36
+ 'content_start': r'<content>',
37
+ 'content_end': r'</content>'
38
+ },
39
+ 'replace_in_file': {
40
+ 'start': r'<replace_in_file>',
41
+ 'end': r'</replace_in_file>',
42
+ 'content_pattern': r'<diff>(.*?)</diff>',
43
+ 'content_start': r'<diff>',
44
+ 'content_end': r'</diff>'
45
+ }
46
+ }
47
+
48
+ def detect_tool_call(self, content: Optional[str]) -> Optional[Dict[str, Any]]:
49
+ """
50
+ 检测content是否包含工具调用
51
+
52
+ Args:
53
+ content: 要检测的内容
54
+
55
+ Returns:
56
+ Dict包含工具信息,如果没有检测到工具调用则返回None
57
+ 返回格式: {
58
+ 'tool_name': str,
59
+ 'start_pos': int,
60
+ 'end_pos': int,
61
+ 'full_match': str,
62
+ 'content_start': int,
63
+ 'content_end': int,
64
+ 'content_match': str
65
+ }
66
+ """
67
+ if not content:
68
+ return None
69
+
70
+ for tool_name in self.supported_tools:
71
+ pattern_info = self.tool_patterns[tool_name]
72
+
73
+ # 检查是否包含工具调用的开始和结束标签
74
+ start_pattern = pattern_info['start']
75
+ end_pattern = pattern_info['end']
76
+
77
+ start_match = re.search(start_pattern, content, re.IGNORECASE)
78
+ if not start_match:
79
+ continue
80
+
81
+ # 从start_match位置开始查找结束标签
82
+ start_pos = start_match.start()
83
+ remaining_content = content[start_pos:]
84
+
85
+ end_match = re.search(end_pattern, remaining_content, re.IGNORECASE)
86
+ if not end_match:
87
+ continue
88
+
89
+ end_pos = start_pos + end_match.end()
90
+ full_tool_match = content[start_pos:end_pos]
91
+
92
+ # 查找content/diff部分
93
+ content_pattern = pattern_info['content_pattern']
94
+ content_match = re.search(content_pattern, full_tool_match, re.DOTALL | re.IGNORECASE)
95
+
96
+ if content_match:
97
+ # 找到完整的工具调用
98
+ return {
99
+ 'tool_name': tool_name,
100
+ 'start_pos': start_pos,
101
+ 'end_pos': end_pos,
102
+ 'full_match': full_tool_match,
103
+ 'content_start': start_pos + content_match.start(),
104
+ 'content_end': start_pos + content_match.end(),
105
+ 'content_match': content_match.group(0),
106
+ 'content_inner': content_match.group(1)
107
+ }
108
+
109
+ return None
110
+
111
+ def replace_tool_content(self, content: Optional[str], max_content_length: int = 500) -> Tuple[str, bool]:
112
+ """
113
+ 替换工具调用中的大量内容
114
+
115
+ Args:
116
+ content: 原始内容
117
+ max_content_length: 内容超过这个长度时才进行替换
118
+
119
+ Returns:
120
+ Tuple[替换后的内容, 是否进行了替换]
121
+ """
122
+ if not content:
123
+ return content or "", False
124
+
125
+ tool_info = self.detect_tool_call(content)
126
+ if not tool_info:
127
+ return content, False
128
+
129
+ # 检查content部分的长度
130
+ content_inner = tool_info['content_inner']
131
+ if len(content_inner) <= max_content_length:
132
+ return content, False
133
+
134
+ # 构造替换后的内容
135
+ tool_name = tool_info['tool_name']
136
+ pattern_info = self.tool_patterns[tool_name]
137
+
138
+ # 生成替换的内容标签
139
+ if tool_name == 'write_to_file':
140
+ replacement_content = f"<content>{self.replacement_message}</content>"
141
+ elif tool_name == 'replace_in_file':
142
+ replacement_content = f"<diff>{self.replacement_message}</diff>"
143
+ else:
144
+ replacement_content = f"<content>{self.replacement_message}</content>"
145
+
146
+ # 替换原内容
147
+ new_content = (
148
+ content[:tool_info['start_pos']] +
149
+ content[tool_info['start_pos']:tool_info['content_start']] +
150
+ replacement_content +
151
+ content[tool_info['content_end']:tool_info['end_pos']] +
152
+ content[tool_info['end_pos']:]
153
+ )
154
+
155
+ logger.info(f"Replaced {tool_name} content: {len(content_inner)} chars -> {len(self.replacement_message)} chars")
156
+
157
+ return new_content, True
158
+
159
+ def get_tool_content_stats(self, content: Optional[str]) -> Dict[str, Any]:
160
+ """
161
+ 获取工具调用内容的统计信息
162
+
163
+ Args:
164
+ content: 要分析的内容
165
+
166
+ Returns:
167
+ Dict包含统计信息
168
+ """
169
+ if not content:
170
+ return {
171
+ 'has_tool_call': False,
172
+ 'total_length': 0
173
+ }
174
+
175
+ tool_info = self.detect_tool_call(content)
176
+ if not tool_info:
177
+ return {
178
+ 'has_tool_call': False,
179
+ 'total_length': len(content)
180
+ }
181
+
182
+ return {
183
+ 'has_tool_call': True,
184
+ 'tool_name': tool_info['tool_name'],
185
+ 'total_length': len(content),
186
+ 'tool_content_length': len(tool_info['content_inner']),
187
+ 'tool_full_length': len(tool_info['full_match']),
188
+ 'prefix_length': tool_info['start_pos'],
189
+ 'suffix_length': len(content) - tool_info['end_pos']
190
+ }
191
+
192
+ def is_tool_call_content(self, content: Optional[str]) -> bool:
193
+ """
194
+ 简单判断content是否包含工具调用
195
+
196
+ Args:
197
+ content: 要检测的内容
198
+
199
+ Returns:
200
+ bool: 是否包含工具调用
201
+ """
202
+ return self.detect_tool_call(content) is not None
203
+
204
+ def extract_tool_content(self, content: Optional[str]) -> Optional[str]:
205
+ """
206
+ 提取工具调用中的内容部分
207
+
208
+ Args:
209
+ content: 原始内容
210
+
211
+ Returns:
212
+ 工具调用中的内容部分,如果没有工具调用则返回None
213
+ """
214
+ tool_info = self.detect_tool_call(content)
215
+ if not tool_info:
216
+ return None
217
+
218
+ return tool_info['content_inner']
219
+
220
+ def get_supported_tools(self) -> list:
221
+ """
222
+ 获取支持的工具列表
223
+
224
+ Returns:
225
+ 支持的工具名称列表
226
+ """
227
+ return self.supported_tools.copy()
@@ -0,0 +1,18 @@
1
+ """
2
+ Pruner Tools Module
3
+
4
+ This module provides command-line tools for managing and querying pruner-related data.
5
+ """
6
+
7
+ # Import main functions for programmatic use
8
+ from .query_message_ids import (
9
+ query_conversation_message_ids,
10
+ list_all_conversations,
11
+ export_all_configs
12
+ )
13
+
14
+ __all__ = [
15
+ "query_conversation_message_ids",
16
+ "list_all_conversations",
17
+ "export_all_configs"
18
+ ]