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,558 @@
1
+ """
2
+ WebSearchTool Module
3
+
4
+ This module implements the WebSearchTool and WebSearchToolResolver classes
5
+ for providing web search functionality based on Firecrawl, Metaso, or BochaAI
6
+ within the BaseAgent framework.
7
+ """
8
+
9
+ import os
10
+ import traceback
11
+ import json
12
+ from typing import Dict, Any, List, Optional
13
+
14
+ import byzerllm
15
+ from loguru import logger
16
+ from numpy import log
17
+
18
+ from autocoder.agent.base_agentic.types import BaseTool, ToolResult
19
+ from autocoder.agent.base_agentic.tool_registry import ToolRegistry
20
+ from autocoder.agent.base_agentic.tools.base_tool_resolver import BaseToolResolver
21
+ from autocoder.agent.base_agentic.types import ToolDescription, ToolExample
22
+ from autocoder.rag.tools.metaso_sdk import MetasoClient
23
+ from autocoder.rag.tools.bochaai_sdk import BochaAIClient
24
+
25
+
26
+ class WebSearchTool(BaseTool):
27
+ """Web search tool using Firecrawl, Metaso, or BochaAI for web search"""
28
+ query: str # Search query
29
+ limit: Optional[int] = 5 # Return result count limit
30
+ sources: Optional[str] = None # Search source types, comma-separated: web,news,images
31
+ scrape_options: Optional[str] = None # Scraping options, JSON string format
32
+ location: Optional[str] = None # Search location
33
+ tbs: Optional[str] = None # Time filter parameters
34
+
35
+
36
+ class WebSearchToolResolver(BaseToolResolver):
37
+ """Web search tool resolver that implements search logic"""
38
+
39
+ def __init__(self, agent, tool, args):
40
+ super().__init__(agent, tool, args)
41
+ self.tool: WebSearchTool = tool
42
+
43
+ def _search_with_bochaai(self) -> ToolResult:
44
+ """Search using BochaAI"""
45
+ try:
46
+ # Check if BochaAI API key is provided
47
+ api_key = getattr(self.args, 'bochaai_api_key', None) or os.getenv('BOCHAAI_API_KEY')
48
+ if not api_key:
49
+ return ToolResult(
50
+ success=False,
51
+ message="BochaAI API key not provided, please set --bochaai_api_key parameter or BOCHAAI_API_KEY environment variable",
52
+ content=[]
53
+ )
54
+
55
+ # Initialize BochaAI client
56
+ client = BochaAIClient(api_key=api_key)
57
+
58
+ # Prepare search parameters
59
+ freshness = "noLimit" # Default no time limit
60
+ if self.tool.tbs:
61
+ # Map time filter parameters
62
+ tbs_mapping = {
63
+ "d": "oneDay",
64
+ "w": "oneWeek",
65
+ "m": "oneMonth",
66
+ "y": "oneYear"
67
+ }
68
+ freshness = tbs_mapping.get(self.tool.tbs, "noLimit")
69
+
70
+ # Parse scrape_options to get additional parameters
71
+ include_summary = False
72
+ include_sites = None
73
+ exclude_sites = None
74
+ if self.tool.scrape_options:
75
+ try:
76
+ scrape_opts = json.loads(self.tool.scrape_options)
77
+ include_summary = scrape_opts.get('include_summary', False) or scrape_opts.get('summary', False)
78
+ include_sites = scrape_opts.get('include_sites')
79
+ exclude_sites = scrape_opts.get('exclude_sites')
80
+ except json.JSONDecodeError:
81
+ pass
82
+
83
+ # Execute search
84
+ logger.info(f"Performing web search using BochaAI, query: {self.tool.query}")
85
+ result = client.search(
86
+ query=self.tool.query,
87
+ count=self.tool.limit,
88
+ freshness=freshness,
89
+ summary=include_summary,
90
+ include=include_sites,
91
+ exclude=exclude_sites
92
+ )
93
+
94
+ if not result.success:
95
+ return ToolResult(
96
+ success=False,
97
+ message=f"BochaAI search failed: {result.error}",
98
+ content=[]
99
+ )
100
+
101
+ # Format search results
102
+ search_results = []
103
+
104
+ # Process web results
105
+ for webpage in result.webpages:
106
+ result_item = {
107
+ "type": "web",
108
+ "title": webpage.name,
109
+ "url": webpage.url,
110
+ "description": webpage.snippet,
111
+ "provider": "bochaai"
112
+ }
113
+
114
+ if webpage.summary:
115
+ result_item["summary"] = webpage.summary
116
+ if webpage.date_published:
117
+ result_item["date"] = webpage.date_published
118
+ if webpage.site_name:
119
+ result_item["site_name"] = webpage.site_name
120
+ if webpage.site_icon:
121
+ result_item["site_icon"] = webpage.site_icon
122
+
123
+ search_results.append(result_item)
124
+
125
+ # Process image results (if needed)
126
+ if self.tool.sources and "images" in self.tool.sources:
127
+ for image in result.images:
128
+ image_item = {
129
+ "type": "image",
130
+ "url": image.content_url,
131
+ "thumbnail_url": image.thumbnail_url,
132
+ "host_page_url": image.host_page_url,
133
+ "width": image.width,
134
+ "height": image.height,
135
+ "provider": "bochaai"
136
+ }
137
+ if image.name:
138
+ image_item["title"] = image.name
139
+ search_results.append(image_item)
140
+
141
+ return ToolResult(
142
+ success=True,
143
+ message=f"Successfully found {len(search_results)} results (using BochaAI)",
144
+ content=search_results
145
+ )
146
+
147
+ except Exception as e:
148
+ logger.error(f"BochaAI search failed: {str(e)}")
149
+ return ToolResult(
150
+ success=False,
151
+ message=f"BochaAI search failed: {str(e)}",
152
+ content=traceback.format_exc()
153
+ )
154
+
155
+ def _search_with_metaso(self) -> ToolResult:
156
+ """Search using Metaso"""
157
+ try:
158
+ # Check if Metaso API key is provided
159
+ api_key = getattr(self.args, 'metaso_api_key', None) or os.getenv('METASO_API_KEY')
160
+ if not api_key:
161
+ return ToolResult(
162
+ success=False,
163
+ message="Metaso API key not provided, please set --metaso_api_key parameter or METASO_API_KEY environment variable",
164
+ content=[]
165
+ )
166
+
167
+ # Initialize Metaso client
168
+ client = MetasoClient(api_key=api_key)
169
+
170
+ # Prepare search parameters
171
+ scope = "webpage" # Default search web pages
172
+ if self.tool.sources:
173
+ # Map sources to Metaso's scope
174
+ sources_list = [s.strip().lower() for s in self.tool.sources.split(',')]
175
+ if "news" in sources_list:
176
+ scope = "news"
177
+ # Metaso does not support images search yet, keep default webpage
178
+
179
+ # Parse scrape_options to get additional parameters
180
+ include_summary = False
181
+ include_raw_content = False
182
+ if self.tool.scrape_options:
183
+ try:
184
+ scrape_opts = json.loads(self.tool.scrape_options)
185
+ include_summary = scrape_opts.get('include_summary', False)
186
+ include_raw_content = scrape_opts.get('include_raw_content', False)
187
+ except json.JSONDecodeError:
188
+ pass
189
+
190
+ # Execute search
191
+ logger.info(f"Performing web search using Metaso, query: {self.tool.query}")
192
+ result = client.search(
193
+ query=self.tool.query,
194
+ scope=scope,
195
+ size=self.tool.limit,
196
+ include_summary=include_summary,
197
+ include_raw_content=include_raw_content
198
+ )
199
+
200
+ if not result.success:
201
+ return ToolResult(
202
+ success=False,
203
+ message=f"Metaso search failed: {result.error}",
204
+ content=[]
205
+ )
206
+
207
+ # Format search results
208
+ search_results = []
209
+ for webpage in result.webpages:
210
+ result_item = {
211
+ "type": "web",
212
+ "title": webpage.title,
213
+ "url": webpage.link,
214
+ "description": webpage.snippet,
215
+ "position": webpage.position,
216
+ "score": webpage.score,
217
+ "provider": "metaso"
218
+ }
219
+
220
+ if webpage.date:
221
+ result_item["date"] = webpage.date
222
+ if webpage.authors:
223
+ result_item["authors"] = webpage.authors
224
+
225
+ search_results.append(result_item)
226
+
227
+ return ToolResult(
228
+ success=True,
229
+ message=f"Successfully found {len(search_results)} results (using Metaso)",
230
+ content=search_results
231
+ )
232
+
233
+ except Exception as e:
234
+ logger.error(f"Metaso search failed: {str(e)}")
235
+ return ToolResult(
236
+ success=False,
237
+ message=f"Metaso search failed: {str(e)}",
238
+ content=traceback.format_exc()
239
+ )
240
+
241
+ def _search_with_firecrawl(self) -> ToolResult:
242
+ """Search using Firecrawl"""
243
+ try:
244
+ # Check if Firecrawl API key is provided
245
+ api_key = getattr(self.args, 'firecrawl_api_key', None) or os.getenv('FIRECRAWL_API_KEY')
246
+ if not api_key:
247
+ return ToolResult(
248
+ success=False,
249
+ message="Firecrawl API key not provided, please set --firecrawl_api_key parameter or FIRECRAWL_API_KEY environment variable",
250
+ content=[]
251
+ )
252
+
253
+ # Import Firecrawl SDK
254
+ try:
255
+ from firecrawl import Firecrawl
256
+ except ImportError:
257
+ return ToolResult(
258
+ success=False,
259
+ message="Firecrawl SDK not installed, please run: pip install firecrawl-py",
260
+ content=[]
261
+ )
262
+
263
+ # Initialize Firecrawl client
264
+ firecrawl = Firecrawl(api_key=api_key)
265
+
266
+ # Prepare search parameters
267
+ search_params = {
268
+ "query": self.tool.query,
269
+ "limit": self.tool.limit
270
+ }
271
+
272
+ # Add optional parameters
273
+ if self.tool.sources:
274
+ # Parse comma-separated sources string
275
+ sources_list = [s.strip() for s in self.tool.sources.split(',') if s.strip()]
276
+ search_params["sources"] = sources_list
277
+ if self.tool.scrape_options:
278
+ # Parse JSON format scrape_options string
279
+ try:
280
+ scrape_options_dict = json.loads(self.tool.scrape_options)
281
+ search_params["scrape_options"] = scrape_options_dict
282
+ except json.JSONDecodeError as e:
283
+ logger.warning(f"scrape_options JSON parsing failed: {e}, ignoring this parameter")
284
+ if self.tool.location:
285
+ search_params["location"] = self.tool.location
286
+ if self.tool.tbs:
287
+ search_params["tbs"] = self.tool.tbs
288
+
289
+ # Execute search
290
+ logger.info(f"Starting web search, query: {self.tool.query}")
291
+ results = firecrawl.search(**search_params)
292
+
293
+ # Check result type and success status
294
+ if not results:
295
+ return ToolResult(
296
+ success=False,
297
+ message="No results returned",
298
+ content=[]
299
+ )
300
+
301
+ # New version firecrawl returns SearchData object with different structure
302
+ if hasattr(results, 'success') and not results.success:
303
+ error_msg = getattr(results, 'error', 'Unknown error')
304
+ return ToolResult(
305
+ success=False,
306
+ message=f"Search failed: {error_msg}",
307
+ content=[]
308
+ )
309
+
310
+ # Format search results
311
+ search_results = []
312
+ # New version firecrawl returned data might be attribute instead of dict key
313
+ if hasattr(results, 'data'):
314
+ data = results.data
315
+ else:
316
+ data = results.get('data', {}) if hasattr(results, 'get') else {}
317
+
318
+ # If data is empty, log information for debugging
319
+ if not data or (isinstance(data, dict) and not data):
320
+ logger.info("Search returned empty data, possibly due to API quota limit or service status issues")
321
+
322
+ # Process web results - new version might be directly in data, not in data.web
323
+ web_results = []
324
+ if hasattr(data, 'web'):
325
+ web_results = data.web
326
+ elif isinstance(data, dict) and 'web' in data:
327
+ web_results = data['web']
328
+ elif isinstance(data, list):
329
+ # Might directly return result list
330
+ web_results = data
331
+
332
+ if web_results:
333
+ for item in web_results:
334
+ # Handle possible object or dictionary format
335
+ title = getattr(item, 'title', None) or (item.get('title', '') if hasattr(item, 'get') else '')
336
+ url = getattr(item, 'url', None) or (item.get('url', '') if hasattr(item, 'get') else '')
337
+ description = getattr(item, 'description', None) or (item.get('description', '') if hasattr(item, 'get') else '')
338
+ position = getattr(item, 'position', None) or (item.get('position', 0) if hasattr(item, 'get') else 0)
339
+
340
+ result_item = {
341
+ "type": "web",
342
+ "title": title,
343
+ "url": url,
344
+ "description": description,
345
+ "position": position
346
+ }
347
+
348
+ # If there is scraped content, add to results
349
+ markdown = getattr(item, 'markdown', None) or (item.get('markdown') if hasattr(item, 'get') else None)
350
+ if markdown:
351
+ result_item['content'] = markdown
352
+
353
+ links = getattr(item, 'links', None) or (item.get('links') if hasattr(item, 'get') else None)
354
+ if links:
355
+ result_item['links'] = links
356
+
357
+ metadata = getattr(item, 'metadata', None) or (item.get('metadata') if hasattr(item, 'get') else None)
358
+ if metadata:
359
+ result_item['metadata'] = metadata
360
+
361
+ search_results.append(result_item)
362
+
363
+ # Process news results
364
+ if 'news' in data:
365
+ for item in data['news']:
366
+ result_item = {
367
+ "type": "news",
368
+ "title": item.get('title', ''),
369
+ "url": item.get('url', ''),
370
+ "snippet": item.get('snippet', ''),
371
+ "date": item.get('date', ''),
372
+ "position": item.get('position', 0)
373
+ }
374
+ search_results.append(result_item)
375
+
376
+ # Process image results
377
+ if 'images' in data:
378
+ for item in data['images']:
379
+ result_item = {
380
+ "type": "image",
381
+ "title": item.get('title', ''),
382
+ "imageUrl": item.get('imageUrl', ''),
383
+ "url": item.get('url', ''),
384
+ "imageWidth": item.get('imageWidth', 0),
385
+ "imageHeight": item.get('imageHeight', 0),
386
+ "position": item.get('position', 0)
387
+ }
388
+ search_results.append(result_item)
389
+
390
+ return ToolResult(
391
+ success=True,
392
+ message=f"Successfully found {len(search_results)} results (using Firecrawl)",
393
+ content=search_results
394
+ )
395
+
396
+ except Exception as e:
397
+ logger.error(f"Firecrawl search failed: {str(e)}")
398
+ return ToolResult(
399
+ success=False,
400
+ message=f"Firecrawl search failed: {str(e)}",
401
+ content=traceback.format_exc()
402
+ )
403
+
404
+ def resolve(self) -> ToolResult:
405
+ """Implement web search tool resolution logic"""
406
+ try:
407
+ # Determine which provider to use
408
+ arg_bochaai_key = self.args.bochaai_api_key
409
+ bochaai_key = arg_bochaai_key
410
+
411
+ arg_metaso_key = self.args.metaso_api_key
412
+ metaso_key = arg_metaso_key
413
+
414
+ arg_firecrawl_key = self.args.firecrawl_api_key
415
+ firecrawl_key = arg_firecrawl_key
416
+
417
+ # Check if any API key is configured
418
+ if not any([bochaai_key, metaso_key, firecrawl_key]):
419
+ # No API key configured, guide to use search engines and curl
420
+ search_query = self.tool.query.replace(' ', '+')
421
+
422
+ # Build search suggestions
423
+ search_suggestions = []
424
+ search_suggestions.append(f"# Use search engines for web search")
425
+ search_suggestions.append(f"# 1. Google Search:")
426
+ search_suggestions.append(f"# Visit: https://www.google.com/search?q={search_query}")
427
+ search_suggestions.append(f"")
428
+ search_suggestions.append(f"# 2. DuckDuckGo Search:")
429
+ search_suggestions.append(f"# Visit: https://duckduckgo.com/?q={search_query}")
430
+ search_suggestions.append(f"")
431
+ search_suggestions.append(f"# 3. Use curl to get search result pages (need to handle anti-crawling mechanisms):")
432
+ search_suggestions.append(f"curl -s -L -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' 'https://www.google.com/search?q={search_query}'")
433
+ search_suggestions.append(f"")
434
+ search_suggestions.append(f"# 4. If you know specific websites, search them directly:")
435
+ search_suggestions.append(f"curl -s -L 'https://example.com/search?q={search_query}'")
436
+
437
+ if self.tool.sources:
438
+ search_suggestions.append(f"")
439
+ search_suggestions.append(f"# Specified search type: {self.tool.sources}")
440
+ if "news" in self.tool.sources:
441
+ search_suggestions.append(f"# For news search, visit: https://news.google.com/search?q={search_query}")
442
+ if "images" in self.tool.sources:
443
+ search_suggestions.append(f"# For image search, visit: https://www.google.com/search?tbm=isch&q={search_query}")
444
+
445
+ if self.tool.location:
446
+ search_suggestions.append(f"")
447
+ search_suggestions.append(f"# Geographic location restriction: {self.tool.location}")
448
+ search_suggestions.append(f"# You can add location keywords to search")
449
+
450
+ if self.tool.tbs:
451
+ search_suggestions.append(f"")
452
+ search_suggestions.append(f"# Time filter: {self.tool.tbs}")
453
+ search_suggestions.append(f"# Google search can use time filter options in the tools menu")
454
+
455
+ suggestion_text = "\n".join(search_suggestions)
456
+
457
+ return ToolResult(
458
+ success=False,
459
+ message=f"No web search API key configured (BochaAI, Metaso, Firecrawl).",
460
+ content={}
461
+ )
462
+
463
+ # Determine provider priority: BochaAI > Metaso > Firecrawl
464
+ provider = None
465
+ selected_key_name = None
466
+ selected_key_value = None
467
+ if bochaai_key:
468
+ provider = "bochaai"
469
+ selected_key_name = "bochaai_api_key" if arg_bochaai_key else "BOCHAAI_API_KEY"
470
+ selected_key_value = bochaai_key
471
+ elif metaso_key:
472
+ provider = "metaso"
473
+ selected_key_name = "metaso_api_key" if arg_metaso_key else "METASO_API_KEY"
474
+ selected_key_value = metaso_key
475
+ elif firecrawl_key:
476
+ provider = "firecrawl"
477
+ selected_key_name = "firecrawl_api_key" if arg_firecrawl_key else "FIRECRAWL_API_KEY"
478
+ selected_key_value = firecrawl_key
479
+
480
+ key_prefix = (selected_key_value[:10] if selected_key_value else "")
481
+ logger.info(f"Using search provider: {provider}, key_name: {selected_key_name}, key_prefix: {key_prefix}")
482
+
483
+ if provider == "bochaai":
484
+ return self._search_with_bochaai()
485
+ elif provider == "metaso":
486
+ return self._search_with_metaso()
487
+ elif provider == "firecrawl":
488
+ return self._search_with_firecrawl()
489
+
490
+ # This situation should not happen theoretically
491
+ return ToolResult(
492
+ success=False,
493
+ message="Internal error: Unable to determine search provider",
494
+ content=[]
495
+ )
496
+
497
+ except Exception as e:
498
+ logger.error(f"Web search tool execution failed: {str(e)}")
499
+ return ToolResult(
500
+ success=False,
501
+ message=f"Web search tool execution failed: {str(e)}",
502
+ content=traceback.format_exc()
503
+ )
504
+
505
+
506
+ class WebSearchToolDescGenerator:
507
+ def __init__(self, params: Dict[str, Any]):
508
+ self.params = params
509
+
510
+ @byzerllm.prompt()
511
+ def web_search_description(self) -> Dict:
512
+ """
513
+ Description: Request to perform web search using Firecrawl, Metaso or BochaAI API. Use this when you need to search for current web content, news, or images to gather information for completing your task. This tool supports multiple search sources and can optionally scrape the full content of search result pages. You can use web_crawl to fetch the url of the search result pages.
514
+ Parameters:
515
+ - query: (required) The search query string to search for
516
+ - limit: (optional) Maximum number of results to return (default: 5)
517
+ - sources: (optional) Comma-separated search source types, e.g., "web", "news", "images", "web,news"
518
+ - scrape_options: (optional) Additional scraping options as JSON string, e.g., '{"formats": ["markdown"], "include_summary": true, "include_sites": "example.com", "exclude_sites": "bad.com"}'
519
+ - location: (optional) Geographic location to focus the search (Firecrawl only)
520
+ - tbs: (optional) Time-based search parameters for filtering results (Firecrawl/BochaAI)
521
+ Usage:
522
+ <web_search>
523
+ <query>Your search query here</query>
524
+ <limit>5</limit>
525
+ <sources>web</sources>
526
+ </web_search>
527
+ """
528
+ return self.params
529
+
530
+
531
+ def register_web_search_tool():
532
+ """Register web search tool"""
533
+ desc_gen = WebSearchToolDescGenerator({})
534
+
535
+ # 准备工具描述
536
+ description = ToolDescription(
537
+ description=desc_gen.web_search_description.prompt()
538
+ )
539
+
540
+ # 准备工具示例
541
+ example = ToolExample(
542
+ title="Web search tool usage example",
543
+ body="""<web_search>
544
+ <query>Python RAG system implementation</query>
545
+ <limit>3</limit>
546
+ <sources>web</sources>
547
+ </web_search>"""
548
+ )
549
+
550
+ # 注册工具
551
+ ToolRegistry.register_tool(
552
+ tool_tag="web_search", # XML标签名
553
+ tool_cls=WebSearchTool, # 工具类
554
+ resolver_cls=WebSearchToolResolver, # 解析器类
555
+ description=description, # 工具描述
556
+ example=example, # 工具示例
557
+ use_guideline="Use this tool to search for web content across different sources (web pages, news, images). It can optionally scrape complete content from search results. Ideal for gathering current information from the internet to help complete tasks that require up-to-date data." # 使用指南
558
+ )
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Web 工具使用示例
4
+
5
+ 这个文件展示了如何使用 WebSearchTool 和 WebCrawlTool 进行网页搜索和爬取。
6
+ 注意:需要设置 FIRECRAWL_API_KEY 环境变量或在启动服务时使用 --firecrawl_api_key 参数。
7
+ """
8
+
9
+ def web_search_example():
10
+ """
11
+ 网页搜索工具使用示例
12
+
13
+ 在 Agent 对话中可以这样使用:
14
+ """
15
+ example_xml = """
16
+ <web_search>
17
+ <query>Python RAG系统实现最佳实践</query>
18
+ <limit>5</limit>
19
+ <sources>["web"]</sources>
20
+ </web_search>
21
+ """
22
+
23
+ print("Web Search Tool 使用示例:")
24
+ print(example_xml)
25
+ print()
26
+
27
+ # 搜索新闻的示例
28
+ news_example = """
29
+ <web_search>
30
+ <query>人工智能最新发展</query>
31
+ <limit>3</limit>
32
+ <sources>["news"]</sources>
33
+ <location>China</location>
34
+ <tbs>qdr:d</tbs>
35
+ </web_search>
36
+ """
37
+
38
+ print("搜索新闻示例:")
39
+ print(news_example)
40
+ print()
41
+
42
+ # 搜索图片的示例
43
+ image_example = """
44
+ <web_search>
45
+ <query>机器学习架构图 imagesize:1920x1080</query>
46
+ <limit>5</limit>
47
+ <sources>["images"]</sources>
48
+ </web_search>
49
+ """
50
+
51
+ print("搜索图片示例:")
52
+ print(image_example)
53
+ print()
54
+
55
+
56
+ def web_crawl_example():
57
+ """
58
+ 网页爬取工具使用示例
59
+
60
+ 在 Agent 对话中可以这样使用:
61
+ """
62
+ example_xml = """
63
+ <web_crawl>
64
+ <url>https://docs.python.org/3/tutorial/</url>
65
+ <limit>10</limit>
66
+ <scrape_options>{"formats": ["markdown", "links"]}</scrape_options>
67
+ <max_depth>2</max_depth>
68
+ </web_crawl>
69
+ """
70
+
71
+ print("Web Crawl Tool 使用示例:")
72
+ print(example_xml)
73
+ print()
74
+
75
+ # 爬取特定路径的示例
76
+ specific_paths_example = """
77
+ <web_crawl>
78
+ <url>https://example.com</url>
79
+ <limit>5</limit>
80
+ <include_paths>["/docs/", "/api/"]</include_paths>
81
+ <exclude_paths>["/admin/", "/private/"]</exclude_paths>
82
+ </web_crawl>
83
+ """
84
+
85
+ print("爬取特定路径示例:")
86
+ print(specific_paths_example)
87
+ print()
88
+
89
+
90
+ def setup_instructions():
91
+ """
92
+ 设置说明
93
+ """
94
+ print("=== Firecrawl Web 工具设置说明 ===")
95
+ print()
96
+ print("1. 安装 Firecrawl SDK:")
97
+ print(" pip install firecrawl-py")
98
+ print()
99
+ print("2. 获取 Firecrawl API Key:")
100
+ print(" - 访问 https://firecrawl.dev/ 注册账号")
101
+ print(" - 获取 API Key")
102
+ print()
103
+ print("3. 配置 API Key:")
104
+ print(" 方式 1: 设置环境变量")
105
+ print(" export FIRECRAWL_API_KEY=your_api_key_here")
106
+ print()
107
+ print(" 方式 2: 启动服务时指定参数")
108
+ print(" auto-coder.rag serve --firecrawl_api_key your_api_key_here")
109
+ print()
110
+ print("4. 工具功能说明:")
111
+ print(" - WebSearchTool: 搜索网页、新闻、图片")
112
+ print(" - WebCrawlTool: 深度爬取网站内容")
113
+ print()
114
+
115
+
116
+ if __name__ == "__main__":
117
+ setup_instructions()
118
+ web_search_example()
119
+ web_crawl_example()