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
@@ -1,4 +1,5 @@
1
1
  import re
2
+ from collections import OrderedDict
2
3
  from typing import Dict, List, Tuple, Any, Optional
3
4
 
4
5
 
@@ -19,15 +20,15 @@ class CommandParser:
19
20
  """
20
21
 
21
22
  def __init__(self):
22
- # 匹配命令的正则表达式 - 必须是以/开头,后跟单词字符,且不能后跟/或.
23
+ # 匹配命令的正则表达式 - 必须是以/开头,后跟单词字符或连字符,且后面必须是空白字符或字符串结尾
23
24
  # (?<!\S) 确保命令前是字符串开头或空白字符
24
- self.command_pattern = r'(?<!\S)/(\w+)(?!/|\.)'
25
+ self.command_pattern = r'(?<!\S)/([\w-]+)(?=\s|$)'
25
26
  # 匹配键值对参数的正则表达式,支持带引号的值(包括三重引号)
26
27
  self.key_value_pattern = r'(\w+)=(?:\'\'\'([^\']*?)\'\'\'|"""([^"]*?)"""|"([^"]*?)"|\'([^\']*?)\'|([^\s"\']*))(?:\s|$)'
27
28
  # 匹配路径模式的正则表达式
28
29
  self.path_pattern = r'/\w+(?:/[^/\s]+)+'
29
30
 
30
- def parse(self, query: str) -> Dict[str, Any]:
31
+ def parse(self, query: str) -> OrderedDict[str, Any]:
31
32
  """
32
33
  解析命令行格式的查询字符串,返回命令和参数的字典。
33
34
 
@@ -35,7 +36,7 @@ class CommandParser:
35
36
  query: 命令行格式的查询字符串
36
37
 
37
38
  返回:
38
- Dict[str, Any]: 命令和参数的字典,格式为:
39
+ OrderedDict[str, Any]: 命令和参数的有序字典,格式为:
39
40
  {
40
41
  'command1': {
41
42
  'args': ['arg1', 'arg2'],
@@ -48,23 +49,42 @@ class CommandParser:
48
49
  }
49
50
  """
50
51
  if not query or not query.strip():
51
- return {}
52
+ return OrderedDict()
52
53
 
53
- # 预处理:标记路径参数,避免被识别为命令
54
54
  processed_query = query
55
- path_matches = re.finditer(self.path_pattern, query)
56
55
  placeholders = {}
56
+ placeholder_counter = 0
57
57
 
58
- for i, match in enumerate(path_matches):
58
+ # 预处理1:标记引号内容,避免引号内的命令被识别
59
+ quote_patterns = [
60
+ r'\'\'\'([^\']*?)\'\'\'', # 三重单引号
61
+ r'"""([^"]*?)"""', # 三重双引号
62
+ r'"([^"]*?)"', # 双引号
63
+ r'\'([^\']*?)\'' # 单引号
64
+ ]
65
+
66
+ for pattern in quote_patterns:
67
+ for match in re.finditer(pattern, processed_query):
68
+ quoted_content = match.group(0)
69
+ placeholder = f"__QUOTE_PLACEHOLDER_{placeholder_counter}__"
70
+ placeholders[placeholder] = quoted_content
71
+ processed_query = processed_query.replace(quoted_content, placeholder, 1)
72
+ placeholder_counter += 1
73
+
74
+ # 预处理2:标记路径参数,避免被识别为命令
75
+ path_matches = re.finditer(self.path_pattern, processed_query)
76
+
77
+ for match in path_matches:
59
78
  path = match.group(0)
60
- placeholder = f"__PATH_PLACEHOLDER_{i}__"
79
+ placeholder = f"__PATH_PLACEHOLDER_{placeholder_counter}__"
61
80
  placeholders[placeholder] = path
62
81
  processed_query = processed_query.replace(path, placeholder, 1)
82
+ placeholder_counter += 1
63
83
 
64
84
  # 找出所有命令
65
85
  commands = re.findall(self.command_pattern, processed_query)
66
86
  if not commands:
67
- return {}
87
+ return OrderedDict()
68
88
 
69
89
  # 将查询字符串按命令分割
70
90
  parts = re.split(self.command_pattern, processed_query)
@@ -72,7 +92,7 @@ class CommandParser:
72
92
  first_part = parts[0]
73
93
  parts = parts[1:]
74
94
 
75
- result = {}
95
+ result = OrderedDict()
76
96
 
77
97
  # 处理每个命令和它的参数
78
98
  for i in range(0, len(parts), 2):
@@ -81,9 +101,9 @@ class CommandParser:
81
101
  # 获取此命令的参数部分
82
102
  params_str = parts[i+1].strip() if i+1 < len(parts) else ""
83
103
 
84
- # 恢复路径参数的原始值
85
- for placeholder, path in placeholders.items():
86
- params_str = params_str.replace(placeholder, path)
104
+ # 恢复所有占位符的原始值
105
+ for placeholder, original_value in placeholders.items():
106
+ params_str = params_str.replace(placeholder, original_value)
87
107
 
88
108
  # 解析参数
89
109
  args, kwargs = self._parse_params(params_str)
@@ -99,6 +119,7 @@ class CommandParser:
99
119
  """
100
120
  解析参数字符串,区分位置参数和键值对参数。
101
121
  支持带引号(双引号或单引号)的值,引号内可以包含空格。
122
+ 保持参数的原始顺序。
102
123
 
103
124
  参数:
104
125
  params_str: 参数字符串
@@ -112,73 +133,46 @@ class CommandParser:
112
133
  if not params_str:
113
134
  return args, kwargs
114
135
 
115
- # 找出所有键值对
116
- key_value_pairs = re.findall(self.key_value_pattern, params_str)
136
+ # 使用正则表达式按顺序找出所有参数(包括引号参数和键值对)
137
+ # 这个模式会匹配:
138
+ # 1. 键值对参数(key=value格式)
139
+ # 2. 带引号的参数
140
+ # 3. 普通参数
141
+ param_pattern = r'''
142
+ (?:
143
+ # 键值对参数:key=value
144
+ (\w+)=(?:\'\'\'([^\']*?)\'\'\'|"""([^"]*?)"""|"([^"]*?)"|\'([^\']*?)\'|([^\s"\']*))
145
+ |
146
+ # 带引号的参数
147
+ (?:\'\'\'([^\']*?)\'\'\'|"""([^"]*?)"""|"([^"]*?)"|\'([^\']*?)\')
148
+ |
149
+ # 普通参数(不包含空格的)
150
+ ([^\s"\'=]+)
151
+ )
152
+ '''
117
153
 
118
- # 如果有键值对,处理它们
119
- if key_value_pairs:
120
- for match in key_value_pairs:
154
+ matches = re.findall(param_pattern, params_str, re.VERBOSE)
155
+
156
+ for match in matches:
157
+ # match有11个捕获组:
158
+ # 0: 键值对的key
159
+ # 1-5: 键值对的value(三重单引号、三重双引号、双引号、单引号、无引号)
160
+ # 6-9: 带引号的位置参数值(三重单引号、三重双引号、双引号、单引号)
161
+ # 10: 普通位置参数
162
+
163
+ if match[0]: # 这是键值对参数
121
164
  key = match[0]
122
- # 值可能在六个捕获组中的一个,取非空的那个
123
- # match[1]: 三重单引号, match[2]: 三重双引号, match[3]: 双引号, match[4]: 单引号, match[5]: 无引号
124
165
  value = match[1] or match[2] or match[3] or match[4] or match[5]
125
166
  kwargs[key] = value.strip()
167
+ else: # 这是位置参数
168
+ # 检查是带引号的参数还是普通参数
169
+ quoted_value = match[6] or match[7] or match[8] or match[9]
170
+ plain_value = match[10]
126
171
 
127
- # 替换带引号的键值对
128
- processed_params_str = params_str
129
- for match in re.finditer(self.key_value_pattern, params_str):
130
- full_match = match.group(0)
131
- processed_params_str = processed_params_str.replace(full_match, "", 1).strip()
132
-
133
- # 现在 processed_params_str 中应该只剩下位置参数
134
-
135
- # 处理带引号的位置参数(包括三重引号)
136
- quote_pattern = r'(?:\'\'\'([^\']*?)\'\'\'|"""([^"]*?)"""|"([^"]*?)"|\'([^\']*?)\')'
137
- quoted_args = re.findall(quote_pattern, processed_params_str)
138
- for quoted_arg in quoted_args:
139
- # 取非空的那个捕获组
140
- arg = quoted_arg[0] or quoted_arg[1] or quoted_arg[2] or quoted_arg[3]
141
- args.append(arg)
142
- # 从参数字符串中移除这个带引号的参数
143
- if quoted_arg[0]: # 三重单引号
144
- quoted_pattern = f"'''{arg}'''"
145
- elif quoted_arg[1]: # 三重双引号
146
- quoted_pattern = f'"""{arg}"""'
147
- elif quoted_arg[2]: # 双引号
148
- quoted_pattern = f'"{arg}"'
149
- else: # 单引号
150
- quoted_pattern = f"'{arg}'"
151
- processed_params_str = processed_params_str.replace(quoted_pattern, "", 1).strip()
152
-
153
- # 分割剩余的位置参数(不带引号的)
154
- remaining_args = [arg.strip() for arg in processed_params_str.split() if arg.strip()]
155
- args.extend(remaining_args)
156
- else:
157
- # 如果没有键值对,处理所有参数作为位置参数
158
-
159
- # 处理带引号的位置参数(包括三重引号)
160
- quote_pattern = r'(?:\'\'\'([^\']*?)\'\'\'|"""([^"]*?)"""|"([^"]*?)"|\'([^\']*?)\')'
161
- quoted_args = re.findall(quote_pattern, params_str)
162
- processed_params_str = params_str
163
-
164
- for quoted_arg in quoted_args:
165
- # 取非空的那个捕获组
166
- arg = quoted_arg[0] or quoted_arg[1] or quoted_arg[2] or quoted_arg[3]
167
- args.append(arg)
168
- # 从参数字符串中移除这个带引号的参数
169
- if quoted_arg[0]: # 三重单引号
170
- quoted_pattern = f"'''{arg}'''"
171
- elif quoted_arg[1]: # 三重双引号
172
- quoted_pattern = f'"""{arg}"""'
173
- elif quoted_arg[2]: # 双引号
174
- quoted_pattern = f'"{arg}"'
175
- else: # 单引号
176
- quoted_pattern = f"'{arg}'"
177
- processed_params_str = processed_params_str.replace(quoted_pattern, "", 1).strip()
178
-
179
- # 分割剩余的位置参数(不带引号的)
180
- remaining_args = [arg.strip() for arg in processed_params_str.split() if arg.strip()]
181
- args.extend(remaining_args)
172
+ if quoted_value:
173
+ args.append(quoted_value)
174
+ elif plain_value:
175
+ args.append(plain_value)
182
176
 
183
177
  return args, kwargs
184
178
 
@@ -197,7 +191,7 @@ class CommandParser:
197
191
  return commands.get(command)
198
192
 
199
193
 
200
- def parse_query(query: str) -> Dict[str, Any]:
194
+ def parse_query(query: str) -> OrderedDict[str, Any]:
201
195
  """
202
196
  解析命令行格式的查询字符串的便捷函数。
203
197
 
@@ -205,7 +199,7 @@ def parse_query(query: str) -> Dict[str, Any]:
205
199
  query: 命令行格式的查询字符串
206
200
 
207
201
  返回:
208
- Dict[str, Any]: 命令和参数的字典
202
+ OrderedDict[str, Any]: 命令和参数的有序字典
209
203
  """
210
204
  parser = CommandParser()
211
205
  return parser.parse(query)
@@ -261,3 +255,223 @@ def get_command_kwargs(query: str, command: str) -> Dict[str, str]:
261
255
  if command_info:
262
256
  return command_info['kwargs']
263
257
  return {}
258
+
259
+
260
+ class QueryCommand:
261
+ """
262
+ 封装解析后的命令查询结果,提供便捷的属性访问方式。
263
+
264
+ 支持通过属性访问子命令的参数,命令名中的连字符会自动转换为下划线。
265
+ 例如:/task-prefix 可以通过 obj.task_prefix 访问
266
+ """
267
+
268
+ def __init__(self, parsed_commands: OrderedDict[str, Any],
269
+ sub_commands: Optional[List[str]] = None,
270
+ last_command_takes_rest: bool = True):
271
+ """
272
+ 初始化 QueryCommand 对象。
273
+
274
+ 参数:
275
+ parsed_commands: 解析后的命令字典
276
+ sub_commands: 需要特殊处理的子命令列表
277
+ last_command_takes_rest: 如果为True,最后一个子命令只取第一个参数,
278
+ 剩余参数作为整体query
279
+ """
280
+ self._commands = parsed_commands
281
+ self._sub_commands = sub_commands or []
282
+ self._last_command_takes_rest = last_command_takes_rest
283
+ self._query = ""
284
+
285
+ # 处理子命令和剩余参数
286
+ self._process_commands()
287
+
288
+ def _process_commands(self):
289
+ """处理命令,提取子命令参数和剩余的query"""
290
+ if not self._sub_commands or not self._last_command_takes_rest:
291
+ # 如果没有指定子命令或不需要特殊处理,直接返回
292
+ return
293
+
294
+ # 找到最后一个指定的子命令在命令列表中的位置
295
+ last_sub_command_key = None
296
+ last_sub_command_position = -1
297
+
298
+ # 遍历所有解析出的命令,按顺序查找
299
+ for i, (cmd_key, cmd_info) in enumerate(self._commands.items()):
300
+ # 检查这个命令是否在子命令列表中
301
+ if cmd_key in self._sub_commands:
302
+ last_sub_command_key = cmd_key
303
+ last_sub_command_position = i
304
+ # 也检查连字符转下划线的版本
305
+ elif cmd_key.replace('-', '_') in self._sub_commands:
306
+ last_sub_command_key = cmd_key
307
+ last_sub_command_position = i
308
+ elif cmd_key.replace('_', '-') in self._sub_commands:
309
+ last_sub_command_key = cmd_key
310
+ last_sub_command_position = i
311
+
312
+ if last_sub_command_key is None:
313
+ return
314
+
315
+ # 获取最后一个子命令的信息
316
+ command_info = self._commands[last_sub_command_key]
317
+ args = command_info.get('args', [])
318
+
319
+ if len(args) > 1:
320
+ # 只保留第一个参数给命令,剩余的作为query
321
+ first_arg = args[0]
322
+ rest_args = args[1:]
323
+
324
+ # 更新命令的参数
325
+ self._commands[last_sub_command_key]['args'] = [first_arg]
326
+
327
+ # 设置query为剩余参数
328
+ self._query = " ".join(rest_args)
329
+
330
+ # 处理其他子命令,确保每个子命令只保留第一个参数
331
+ for cmd_key in list(self._commands.keys()):
332
+ if cmd_key != last_sub_command_key and (
333
+ cmd_key in self._sub_commands or
334
+ cmd_key.replace('-', '_') in self._sub_commands or
335
+ cmd_key.replace('_', '-') in self._sub_commands
336
+ ):
337
+ cmd_args = self._commands[cmd_key].get('args', [])
338
+ if len(cmd_args) > 1:
339
+ # 只保留第一个参数
340
+ self._commands[cmd_key]['args'] = [cmd_args[0]]
341
+
342
+ def __getattr__(self, name: str) -> Any:
343
+ """
344
+ 通过属性访问命令参数。
345
+
346
+ 参数:
347
+ name: 属性名(命令名,连字符会被转换为下划线)
348
+
349
+ 返回:
350
+ 如果命令存在且有参数,返回第一个参数;
351
+ 如果命令存在但没有参数,返回空字符串;
352
+ 如果命令不存在,返回None
353
+ """
354
+ if name.startswith('_'):
355
+ # 访问私有属性
356
+ raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")
357
+
358
+ # 特殊处理 query 属性
359
+ if name == 'query':
360
+ return self._query
361
+
362
+ # 尝试直接查找命令
363
+ if name in self._commands:
364
+ command_info = self._commands[name]
365
+ args = command_info.get('args', [])
366
+ kwargs = command_info.get('kwargs', {})
367
+
368
+ # 如果有键值对参数,返回键值对字典
369
+ if kwargs:
370
+ return kwargs
371
+ # 如果有位置参数,返回第一个参数
372
+ if args:
373
+ return args[0] if len(args) == 1 else args
374
+ # 命令存在但没有参数
375
+ return ""
376
+
377
+ # 尝试将下划线转换为连字符查找
378
+ hyphen_name = name.replace('_', '-')
379
+ if hyphen_name in self._commands:
380
+ command_info = self._commands[hyphen_name]
381
+ args = command_info.get('args', [])
382
+ kwargs = command_info.get('kwargs', {})
383
+
384
+ # 如果有键值对参数,返回键值对字典
385
+ if kwargs:
386
+ return kwargs
387
+ # 如果有位置参数,返回第一个参数
388
+ if args:
389
+ return args[0] if len(args) == 1 else args
390
+ # 命令存在但没有参数
391
+ return ""
392
+
393
+ # 命令不存在
394
+ return None
395
+
396
+ def has_command(self, command: str) -> bool:
397
+ """
398
+ 检查是否包含指定命令。
399
+
400
+ 参数:
401
+ command: 命令名
402
+
403
+ 返回:
404
+ bool: 如果包含命令返回True,否则返回False
405
+ """
406
+ # 检查原始命令名和转换后的命令名(双向转换)
407
+ return (command in self._commands or
408
+ command.replace('-', '_') in self._commands or
409
+ command.replace('_', '-') in self._commands)
410
+
411
+ def get_command_info(self, command: str) -> Optional[Dict[str, Any]]:
412
+ """
413
+ 获取指定命令的完整信息。
414
+
415
+ 参数:
416
+ command: 命令名
417
+
418
+ 返回:
419
+ Optional[Dict[str, Any]]: 命令信息字典,包含args和kwargs
420
+ """
421
+ if command in self._commands:
422
+ return self._commands[command]
423
+
424
+ # 尝试转换命令名
425
+ normalized_cmd = command.replace('-', '_')
426
+ if normalized_cmd in self._commands:
427
+ return self._commands[normalized_cmd]
428
+
429
+ return None
430
+
431
+ def get_all_commands(self) -> List[str]:
432
+ """
433
+ 获取所有命令名列表。
434
+
435
+ 返回:
436
+ List[str]: 命令名列表
437
+ """
438
+ return list(self._commands.keys())
439
+
440
+ def __repr__(self) -> str:
441
+ """返回对象的字符串表示"""
442
+ commands_str = ", ".join(self._commands.keys())
443
+ return f"QueryCommand(commands=[{commands_str}], query='{self._query}')"
444
+
445
+
446
+ def get_query_command(query: str,
447
+ sub_commands: Optional[List[str]] = None,
448
+ last_command_takes_rest: bool = True) -> QueryCommand:
449
+ """
450
+ 解析命令查询并返回QueryCommand对象,提供便捷的属性访问。
451
+
452
+ 这个函数特别适合处理如下场景:
453
+ /async /model gpt-4 /task-prefix mytask this is the actual query
454
+
455
+ 其中 /model 和 /task-prefix 是子命令,每个只取第一个参数,
456
+ 剩余的 "this is the actual query" 作为整体的查询内容。
457
+
458
+ 参数:
459
+ query: 命令行格式的查询字符串
460
+ sub_commands: 需要特殊处理的子命令列表,如 ["model", "task-prefix"]
461
+ last_command_takes_rest: 如果为True,最后一个子命令只取第一个参数,
462
+ 剩余参数作为整体query
463
+
464
+ 返回:
465
+ QueryCommand: 封装了解析结果的对象,支持属性访问
466
+
467
+ 使用示例:
468
+ >>> v = get_query_command("/async /model gpt-4 /task-prefix mytask hello world",
469
+ ... sub_commands=["model", "task-prefix"])
470
+ >>> v.model # 返回 "gpt-4"
471
+ >>> v.task_prefix # 返回 "mytask"
472
+ >>> v.query # 返回 "hello world"
473
+ """
474
+ parser = CommandParser()
475
+ parsed_commands = parser.parse(query)
476
+
477
+ return QueryCommand(parsed_commands, sub_commands, last_command_takes_rest)