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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of auto-coder might be problematic. Click here for more details.

Files changed (574) hide show
  1. auto_coder-2.0.1.dist-info/LICENSE +158 -0
  2. auto_coder-2.0.1.dist-info/METADATA +558 -0
  3. auto_coder-2.0.1.dist-info/RECORD +795 -0
  4. {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.dist-info}/WHEEL +1 -1
  5. {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.dist-info}/entry_points.txt +3 -3
  6. autocoder/__init__.py +31 -0
  7. autocoder/agent/auto_filegroup.py +32 -13
  8. autocoder/agent/auto_learn_from_commit.py +9 -1
  9. autocoder/agent/base_agentic/__init__.py +3 -0
  10. autocoder/agent/base_agentic/agent_hub.py +1 -1
  11. autocoder/agent/base_agentic/base_agent.py +235 -136
  12. autocoder/agent/base_agentic/default_tools.py +119 -118
  13. autocoder/agent/base_agentic/test_base_agent.py +1 -1
  14. autocoder/agent/base_agentic/tool_registry.py +32 -20
  15. autocoder/agent/base_agentic/tools/read_file_tool_resolver.py +24 -3
  16. autocoder/agent/base_agentic/tools/write_to_file_tool_resolver.py +24 -11
  17. autocoder/agent/base_agentic/types.py +42 -0
  18. autocoder/agent/entry_command_agent/chat.py +77 -73
  19. autocoder/auto_coder.py +31 -40
  20. autocoder/auto_coder_rag.py +11 -1084
  21. autocoder/auto_coder_runner.py +962 -2345
  22. autocoder/auto_coder_terminal.py +26 -0
  23. autocoder/auto_coder_terminal_v3.py +190 -0
  24. autocoder/chat/conf_command.py +224 -124
  25. autocoder/chat/models_command.py +361 -299
  26. autocoder/chat/rules_command.py +79 -31
  27. autocoder/chat_auto_coder.py +988 -398
  28. autocoder/chat_auto_coder_lang.py +23 -732
  29. autocoder/commands/auto_command.py +25 -8
  30. autocoder/commands/auto_web.py +1 -1
  31. autocoder/commands/tools.py +44 -44
  32. autocoder/common/__init__.py +150 -128
  33. autocoder/common/ac_style_command_parser/__init__.py +39 -2
  34. autocoder/common/ac_style_command_parser/config.py +422 -0
  35. autocoder/common/ac_style_command_parser/parser.py +292 -78
  36. autocoder/common/ac_style_command_parser/test_parser.py +241 -16
  37. autocoder/common/ac_style_command_parser/test_typed_parser.py +342 -0
  38. autocoder/common/ac_style_command_parser/typed_parser.py +653 -0
  39. autocoder/common/action_yml_file_manager.py +25 -13
  40. autocoder/common/agent_events/__init__.py +52 -0
  41. autocoder/common/agent_events/agent_event_emitter.py +193 -0
  42. autocoder/common/agent_events/event_factory.py +177 -0
  43. autocoder/common/agent_events/examples.py +307 -0
  44. autocoder/common/agent_events/types.py +113 -0
  45. autocoder/common/agent_events/utils.py +68 -0
  46. autocoder/common/agent_hooks/__init__.py +44 -0
  47. autocoder/common/agent_hooks/examples.py +582 -0
  48. autocoder/common/agent_hooks/hook_executor.py +217 -0
  49. autocoder/common/agent_hooks/hook_manager.py +288 -0
  50. autocoder/common/agent_hooks/types.py +133 -0
  51. autocoder/common/agent_hooks/utils.py +99 -0
  52. autocoder/common/agent_query_queue/queue_executor.py +324 -0
  53. autocoder/common/agent_query_queue/queue_manager.py +325 -0
  54. autocoder/common/agents/__init__.py +11 -0
  55. autocoder/common/agents/agent_manager.py +323 -0
  56. autocoder/common/agents/agent_parser.py +189 -0
  57. autocoder/common/agents/example_usage.py +344 -0
  58. autocoder/common/agents/integration_example.py +330 -0
  59. autocoder/common/agents/test_agent_parser.py +545 -0
  60. autocoder/common/async_utils.py +101 -0
  61. autocoder/common/auto_coder_lang.py +23 -972
  62. autocoder/common/autocoderargs_parser/__init__.py +14 -0
  63. autocoder/common/autocoderargs_parser/parser.py +184 -0
  64. autocoder/common/autocoderargs_parser/tests/__init__.py +1 -0
  65. autocoder/common/autocoderargs_parser/tests/test_args_parser.py +235 -0
  66. autocoder/common/autocoderargs_parser/tests/test_token_parser.py +195 -0
  67. autocoder/common/autocoderargs_parser/token_parser.py +290 -0
  68. autocoder/common/buildin_tokenizer.py +2 -4
  69. autocoder/common/code_auto_generate.py +149 -74
  70. autocoder/common/code_auto_generate_diff.py +163 -70
  71. autocoder/common/code_auto_generate_editblock.py +179 -89
  72. autocoder/common/code_auto_generate_strict_diff.py +167 -72
  73. autocoder/common/code_auto_merge_editblock.py +13 -6
  74. autocoder/common/code_modification_ranker.py +1 -1
  75. autocoder/common/command_completer.py +3 -3
  76. autocoder/common/command_file_manager/manager.py +183 -47
  77. autocoder/common/command_file_manager/test_command_file_manager.py +507 -0
  78. autocoder/common/command_templates.py +1 -1
  79. autocoder/common/conf_utils.py +2 -4
  80. autocoder/common/conversations/config.py +11 -3
  81. autocoder/common/conversations/get_conversation_manager.py +100 -2
  82. autocoder/common/conversations/llm_stats_models.py +264 -0
  83. autocoder/common/conversations/manager.py +112 -28
  84. autocoder/common/conversations/models.py +16 -2
  85. autocoder/common/conversations/storage/index_manager.py +134 -10
  86. autocoder/common/core_config/__init__.py +63 -0
  87. autocoder/common/core_config/agentic_mode_manager.py +109 -0
  88. autocoder/common/core_config/base_manager.py +123 -0
  89. autocoder/common/core_config/compatibility.py +151 -0
  90. autocoder/common/core_config/config_manager.py +156 -0
  91. autocoder/common/core_config/conversation_manager.py +31 -0
  92. autocoder/common/core_config/exclude_manager.py +72 -0
  93. autocoder/common/core_config/file_manager.py +177 -0
  94. autocoder/common/core_config/human_as_model_manager.py +129 -0
  95. autocoder/common/core_config/lib_manager.py +54 -0
  96. autocoder/common/core_config/main_manager.py +81 -0
  97. autocoder/common/core_config/mode_manager.py +126 -0
  98. autocoder/common/core_config/models.py +70 -0
  99. autocoder/common/core_config/test_memory_manager.py +1056 -0
  100. autocoder/common/env_manager.py +282 -0
  101. autocoder/common/env_manager_usage_example.py +211 -0
  102. autocoder/common/file_checkpoint/conversation_checkpoint.py +19 -19
  103. autocoder/common/file_checkpoint/manager.py +264 -48
  104. autocoder/common/file_checkpoint/test_backup.py +1 -18
  105. autocoder/common/file_checkpoint/test_manager.py +270 -1
  106. autocoder/common/file_checkpoint/test_store.py +1 -17
  107. autocoder/common/file_handler/__init__.py +23 -0
  108. autocoder/common/file_handler/active_context_handler.py +159 -0
  109. autocoder/common/file_handler/add_files_handler.py +409 -0
  110. autocoder/common/file_handler/chat_handler.py +180 -0
  111. autocoder/common/file_handler/coding_handler.py +409 -0
  112. autocoder/common/file_handler/commit_handler.py +200 -0
  113. autocoder/common/file_handler/lib_handler.py +156 -0
  114. autocoder/common/file_handler/list_files_handler.py +111 -0
  115. autocoder/common/file_handler/mcp_handler.py +268 -0
  116. autocoder/common/file_handler/models_handler.py +493 -0
  117. autocoder/common/file_handler/remove_files_handler.py +172 -0
  118. autocoder/common/git_utils.py +44 -8
  119. autocoder/common/global_cancel.py +15 -6
  120. autocoder/common/ignorefiles/test_ignore_file_utils.py +1 -1
  121. autocoder/common/international/__init__.py +31 -0
  122. autocoder/common/international/demo_international.py +92 -0
  123. autocoder/common/international/message_manager.py +157 -0
  124. autocoder/common/international/messages/__init__.py +56 -0
  125. autocoder/common/international/messages/async_command_messages.py +507 -0
  126. autocoder/common/international/messages/auto_coder_messages.py +2208 -0
  127. autocoder/common/international/messages/chat_auto_coder_messages.py +1547 -0
  128. autocoder/common/international/messages/command_help_messages.py +986 -0
  129. autocoder/common/international/messages/conversation_command_messages.py +191 -0
  130. autocoder/common/international/messages/git_helper_plugin_messages.py +159 -0
  131. autocoder/common/international/messages/queue_command_messages.py +751 -0
  132. autocoder/common/international/messages/rules_command_messages.py +77 -0
  133. autocoder/common/international/messages/sdk_messages.py +1707 -0
  134. autocoder/common/international/messages/token_helper_plugin_messages.py +361 -0
  135. autocoder/common/international/messages/tool_display_messages.py +1212 -0
  136. autocoder/common/international/messages/workflow_exception_messages.py +473 -0
  137. autocoder/common/international/test_international.py +612 -0
  138. autocoder/common/linter_core/__init__.py +28 -0
  139. autocoder/common/linter_core/base_linter.py +61 -0
  140. autocoder/common/linter_core/config_loader.py +271 -0
  141. autocoder/common/linter_core/formatters/__init__.py +0 -0
  142. autocoder/common/linter_core/formatters/base_formatter.py +38 -0
  143. autocoder/common/linter_core/formatters/raw_formatter.py +17 -0
  144. autocoder/common/linter_core/linter.py +166 -0
  145. autocoder/common/linter_core/linter_factory.py +216 -0
  146. autocoder/common/linter_core/linter_manager.py +333 -0
  147. autocoder/common/linter_core/linters/__init__.py +9 -0
  148. autocoder/common/linter_core/linters/java_linter.py +342 -0
  149. autocoder/common/linter_core/linters/python_linter.py +115 -0
  150. autocoder/common/linter_core/linters/typescript_linter.py +119 -0
  151. autocoder/common/linter_core/models/__init__.py +7 -0
  152. autocoder/common/linter_core/models/lint_result.py +91 -0
  153. autocoder/common/linter_core/models.py +33 -0
  154. autocoder/common/linter_core/tests/__init__.py +3 -0
  155. autocoder/common/linter_core/tests/test_config_loader.py +323 -0
  156. autocoder/common/linter_core/tests/test_config_loading.py +308 -0
  157. autocoder/common/linter_core/tests/test_factory_manager.py +234 -0
  158. autocoder/common/linter_core/tests/test_formatters.py +147 -0
  159. autocoder/common/linter_core/tests/test_integration.py +317 -0
  160. autocoder/common/linter_core/tests/test_java_linter.py +496 -0
  161. autocoder/common/linter_core/tests/test_linters.py +265 -0
  162. autocoder/common/linter_core/tests/test_models.py +81 -0
  163. autocoder/common/linter_core/tests/verify_config_loading.py +296 -0
  164. autocoder/common/linter_core/tests/verify_fixes.py +183 -0
  165. autocoder/common/llm_friendly_package/__init__.py +31 -0
  166. autocoder/common/llm_friendly_package/base_manager.py +102 -0
  167. autocoder/common/llm_friendly_package/docs_manager.py +121 -0
  168. autocoder/common/llm_friendly_package/library_manager.py +171 -0
  169. autocoder/common/{llm_friendly_package.py → llm_friendly_package/main_manager.py} +204 -231
  170. autocoder/common/llm_friendly_package/models.py +40 -0
  171. autocoder/common/llm_friendly_package/test_llm_friendly_package.py +536 -0
  172. autocoder/common/llms/__init__.py +15 -0
  173. autocoder/common/llms/demo_error_handling.py +85 -0
  174. autocoder/common/llms/factory.py +142 -0
  175. autocoder/common/llms/manager.py +264 -0
  176. autocoder/common/llms/pricing.py +121 -0
  177. autocoder/common/llms/registry.py +316 -0
  178. autocoder/common/llms/schema.py +77 -0
  179. autocoder/common/llms/simple_demo.py +45 -0
  180. autocoder/common/llms/test_quick_model.py +116 -0
  181. autocoder/common/llms/test_remove_functionality.py +182 -0
  182. autocoder/common/llms/tests/__init__.py +1 -0
  183. autocoder/common/llms/tests/test_manager.py +330 -0
  184. autocoder/common/llms/tests/test_registry.py +364 -0
  185. autocoder/common/mcp_tools/__init__.py +62 -0
  186. autocoder/common/{mcp_tools.py → mcp_tools/executor.py} +49 -40
  187. autocoder/common/{mcp_hub.py → mcp_tools/hub.py} +42 -68
  188. autocoder/common/{mcp_server_install.py → mcp_tools/installer.py} +16 -28
  189. autocoder/common/{mcp_server.py → mcp_tools/server.py} +176 -48
  190. autocoder/common/mcp_tools/test_keyboard_interrupt.py +93 -0
  191. autocoder/common/mcp_tools/test_mcp_tools.py +391 -0
  192. autocoder/common/{mcp_server_types.py → mcp_tools/types.py} +121 -48
  193. autocoder/common/mcp_tools/verify_functionality.py +202 -0
  194. autocoder/common/model_speed_tester.py +32 -26
  195. autocoder/common/priority_directory_finder/__init__.py +142 -0
  196. autocoder/common/priority_directory_finder/examples.py +230 -0
  197. autocoder/common/priority_directory_finder/finder.py +283 -0
  198. autocoder/common/priority_directory_finder/models.py +236 -0
  199. autocoder/common/priority_directory_finder/test_priority_directory_finder.py +431 -0
  200. autocoder/common/project_scanner/__init__.py +18 -0
  201. autocoder/common/project_scanner/compat.py +77 -0
  202. autocoder/common/project_scanner/scanner.py +436 -0
  203. autocoder/common/project_tracker/__init__.py +27 -0
  204. autocoder/common/project_tracker/api.py +228 -0
  205. autocoder/common/project_tracker/demo.py +272 -0
  206. autocoder/common/project_tracker/tracker.py +487 -0
  207. autocoder/common/project_tracker/types.py +53 -0
  208. autocoder/common/pruner/__init__.py +67 -0
  209. autocoder/common/pruner/agentic_conversation_pruner.py +651 -102
  210. autocoder/common/pruner/conversation_message_ids_api.py +386 -0
  211. autocoder/common/pruner/conversation_message_ids_manager.py +347 -0
  212. autocoder/common/pruner/conversation_message_ids_pruner.py +473 -0
  213. autocoder/common/pruner/conversation_normalizer.py +347 -0
  214. autocoder/common/pruner/conversation_pruner.py +26 -6
  215. autocoder/common/pruner/test_agentic_conversation_pruner.py +554 -112
  216. autocoder/common/pruner/test_conversation_normalizer.py +502 -0
  217. autocoder/common/pruner/test_tool_content_detector.py +324 -0
  218. autocoder/common/pruner/tool_content_detector.py +227 -0
  219. autocoder/common/pruner/tools/__init__.py +18 -0
  220. autocoder/common/pruner/tools/query_message_ids.py +264 -0
  221. autocoder/common/pruner/tools/test_agentic_pruning_logic.py +432 -0
  222. autocoder/common/pruner/tools/test_message_ids_pruning_only.py +192 -0
  223. autocoder/common/pull_requests/__init__.py +9 -1
  224. autocoder/common/pull_requests/utils.py +122 -1
  225. autocoder/common/rag_manager/rag_manager.py +36 -40
  226. autocoder/common/rulefiles/__init__.py +53 -1
  227. autocoder/common/rulefiles/api.py +250 -0
  228. autocoder/common/rulefiles/core/__init__.py +14 -0
  229. autocoder/common/rulefiles/core/manager.py +241 -0
  230. autocoder/common/rulefiles/core/selector.py +805 -0
  231. autocoder/common/rulefiles/models/__init__.py +20 -0
  232. autocoder/common/rulefiles/models/index.py +16 -0
  233. autocoder/common/rulefiles/models/init_rule.py +18 -0
  234. autocoder/common/rulefiles/models/rule_file.py +18 -0
  235. autocoder/common/rulefiles/models/rule_relevance.py +14 -0
  236. autocoder/common/rulefiles/models/summary.py +16 -0
  237. autocoder/common/rulefiles/test_rulefiles.py +776 -0
  238. autocoder/common/rulefiles/utils/__init__.py +34 -0
  239. autocoder/common/rulefiles/utils/monitor.py +86 -0
  240. autocoder/common/rulefiles/utils/parser.py +230 -0
  241. autocoder/common/save_formatted_log.py +67 -10
  242. autocoder/common/search_replace.py +8 -1
  243. autocoder/common/search_replace_patch/__init__.py +24 -0
  244. autocoder/common/search_replace_patch/base.py +115 -0
  245. autocoder/common/search_replace_patch/manager.py +248 -0
  246. autocoder/common/search_replace_patch/patch_replacer.py +304 -0
  247. autocoder/common/search_replace_patch/similarity_replacer.py +306 -0
  248. autocoder/common/search_replace_patch/string_replacer.py +181 -0
  249. autocoder/common/search_replace_patch/tests/__init__.py +3 -0
  250. autocoder/common/search_replace_patch/tests/run_tests.py +126 -0
  251. autocoder/common/search_replace_patch/tests/test_base.py +188 -0
  252. autocoder/common/search_replace_patch/tests/test_empty_line_insert.py +233 -0
  253. autocoder/common/search_replace_patch/tests/test_integration.py +389 -0
  254. autocoder/common/search_replace_patch/tests/test_manager.py +351 -0
  255. autocoder/common/search_replace_patch/tests/test_patch_replacer.py +316 -0
  256. autocoder/common/search_replace_patch/tests/test_regex_replacer.py +306 -0
  257. autocoder/common/search_replace_patch/tests/test_similarity_replacer.py +384 -0
  258. autocoder/common/shell_commands/__init__.py +197 -0
  259. autocoder/common/shell_commands/background_process_notifier.py +346 -0
  260. autocoder/common/shell_commands/command_executor.py +1127 -0
  261. autocoder/common/shell_commands/error_recovery.py +541 -0
  262. autocoder/common/shell_commands/exceptions.py +120 -0
  263. autocoder/common/shell_commands/interactive_executor.py +476 -0
  264. autocoder/common/shell_commands/interactive_pexpect_process.py +623 -0
  265. autocoder/common/shell_commands/interactive_process.py +744 -0
  266. autocoder/common/shell_commands/interactive_session_manager.py +1014 -0
  267. autocoder/common/shell_commands/monitoring.py +529 -0
  268. autocoder/common/shell_commands/process_cleanup.py +386 -0
  269. autocoder/common/shell_commands/process_manager.py +606 -0
  270. autocoder/common/shell_commands/test_interactive_pexpect_process.py +281 -0
  271. autocoder/common/shell_commands/tests/__init__.py +6 -0
  272. autocoder/common/shell_commands/tests/conftest.py +118 -0
  273. autocoder/common/shell_commands/tests/test_background_process_notifier.py +703 -0
  274. autocoder/common/shell_commands/tests/test_command_executor.py +448 -0
  275. autocoder/common/shell_commands/tests/test_error_recovery.py +305 -0
  276. autocoder/common/shell_commands/tests/test_exceptions.py +299 -0
  277. autocoder/common/shell_commands/tests/test_execute_batch.py +588 -0
  278. autocoder/common/shell_commands/tests/test_indented_batch_commands.py +244 -0
  279. autocoder/common/shell_commands/tests/test_integration.py +664 -0
  280. autocoder/common/shell_commands/tests/test_monitoring.py +546 -0
  281. autocoder/common/shell_commands/tests/test_performance.py +632 -0
  282. autocoder/common/shell_commands/tests/test_process_cleanup.py +397 -0
  283. autocoder/common/shell_commands/tests/test_process_manager.py +606 -0
  284. autocoder/common/shell_commands/tests/test_timeout_config.py +343 -0
  285. autocoder/common/shell_commands/tests/test_timeout_manager.py +520 -0
  286. autocoder/common/shell_commands/timeout_config.py +315 -0
  287. autocoder/common/shell_commands/timeout_manager.py +352 -0
  288. autocoder/common/terminal_paste/__init__.py +14 -0
  289. autocoder/common/terminal_paste/demo.py +145 -0
  290. autocoder/common/terminal_paste/demo_paste_functionality.py +95 -0
  291. autocoder/common/terminal_paste/paste_handler.py +200 -0
  292. autocoder/common/terminal_paste/paste_manager.py +118 -0
  293. autocoder/common/terminal_paste/tests/__init__.py +1 -0
  294. autocoder/common/terminal_paste/tests/test_paste_handler.py +182 -0
  295. autocoder/common/terminal_paste/tests/test_paste_manager.py +126 -0
  296. autocoder/common/terminal_paste/utils.py +163 -0
  297. autocoder/common/test_autocoder_args.py +232 -0
  298. autocoder/common/test_env_manager.py +173 -0
  299. autocoder/common/test_env_manager_integration.py +159 -0
  300. autocoder/common/text_similarity/__init__.py +9 -0
  301. autocoder/common/text_similarity/demo.py +216 -0
  302. autocoder/common/text_similarity/examples.py +266 -0
  303. autocoder/common/text_similarity/test_text_similarity.py +306 -0
  304. autocoder/common/text_similarity/text_similarity.py +194 -0
  305. autocoder/common/text_similarity/utils.py +125 -0
  306. autocoder/common/todos/__init__.py +61 -0
  307. autocoder/common/todos/cache/__init__.py +16 -0
  308. autocoder/common/todos/cache/base_cache.py +89 -0
  309. autocoder/common/todos/cache/cache_manager.py +228 -0
  310. autocoder/common/todos/cache/memory_cache.py +225 -0
  311. autocoder/common/todos/config.py +155 -0
  312. autocoder/common/todos/exceptions.py +35 -0
  313. autocoder/common/todos/get_todo_manager.py +161 -0
  314. autocoder/common/todos/manager.py +537 -0
  315. autocoder/common/todos/models.py +239 -0
  316. autocoder/common/todos/storage/__init__.py +14 -0
  317. autocoder/common/todos/storage/base_storage.py +76 -0
  318. autocoder/common/todos/storage/file_storage.py +278 -0
  319. autocoder/common/tokens/counter.py +24 -2
  320. autocoder/common/tools_manager/__init__.py +17 -0
  321. autocoder/common/tools_manager/examples.py +162 -0
  322. autocoder/common/tools_manager/manager.py +385 -0
  323. autocoder/common/tools_manager/models.py +39 -0
  324. autocoder/common/tools_manager/test_tools_manager.py +303 -0
  325. autocoder/common/tools_manager/utils.py +191 -0
  326. autocoder/common/v2/agent/agentic_callbacks.py +270 -0
  327. autocoder/common/v2/agent/agentic_edit.py +2699 -1856
  328. autocoder/common/v2/agent/agentic_edit_change_manager.py +474 -0
  329. autocoder/common/v2/agent/agentic_edit_tools/__init__.py +35 -1
  330. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_list_tool_resolver.py +279 -0
  331. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +10 -1
  332. autocoder/common/v2/agent/agentic_edit_tools/background_task_tool_resolver.py +1167 -0
  333. autocoder/common/v2/agent/agentic_edit_tools/base_tool_resolver.py +2 -2
  334. autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_read_tool_resolver.py +214 -0
  335. autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_write_tool_resolver.py +299 -0
  336. autocoder/common/v2/agent/agentic_edit_tools/count_tokens_tool_resolver.py +290 -0
  337. autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +564 -29
  338. autocoder/common/v2/agent/agentic_edit_tools/execute_workflow_tool_resolver.py +485 -0
  339. autocoder/common/v2/agent/agentic_edit_tools/extract_to_text_tool_resolver.py +225 -0
  340. autocoder/common/v2/agent/agentic_edit_tools/lint_report.py +79 -0
  341. autocoder/common/v2/agent/agentic_edit_tools/linter_config_models.py +343 -0
  342. autocoder/common/v2/agent/agentic_edit_tools/linter_enabled_tool_resolver.py +189 -0
  343. autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py +169 -101
  344. autocoder/common/v2/agent/agentic_edit_tools/load_extra_document_tool_resolver.py +356 -0
  345. autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +243 -50
  346. autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py +667 -147
  347. autocoder/common/v2/agent/agentic_edit_tools/run_named_subagents_tool_resolver.py +691 -0
  348. autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +410 -86
  349. autocoder/common/v2/agent/agentic_edit_tools/session_interactive_tool_resolver.py +115 -0
  350. autocoder/common/v2/agent/agentic_edit_tools/session_start_tool_resolver.py +190 -0
  351. autocoder/common/v2/agent/agentic_edit_tools/session_stop_tool_resolver.py +76 -0
  352. autocoder/common/v2/agent/agentic_edit_tools/test_write_to_file_tool_resolver.py +207 -192
  353. autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +80 -63
  354. autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +237 -233
  355. autocoder/common/v2/agent/agentic_edit_tools/use_mcp_tool_resolver.py +2 -2
  356. autocoder/common/v2/agent/agentic_edit_tools/web_crawl_tool_resolver.py +557 -0
  357. autocoder/common/v2/agent/agentic_edit_tools/web_search_tool_resolver.py +600 -0
  358. autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py +56 -121
  359. autocoder/common/v2/agent/agentic_edit_types.py +343 -9
  360. autocoder/common/v2/agent/runner/__init__.py +3 -3
  361. autocoder/common/v2/agent/runner/base_runner.py +12 -26
  362. autocoder/common/v2/agent/runner/{event_runner.py → file_based_event_runner.py} +3 -2
  363. autocoder/common/v2/agent/runner/sdk_runner.py +150 -8
  364. autocoder/common/v2/agent/runner/terminal_runner.py +170 -57
  365. autocoder/common/v2/agent/runner/tool_display.py +557 -159
  366. autocoder/common/v2/agent/test_agentic_callbacks.py +265 -0
  367. autocoder/common/v2/agent/test_agentic_edit.py +194 -0
  368. autocoder/common/v2/agent/tool_caller/__init__.py +24 -0
  369. autocoder/common/v2/agent/tool_caller/default_tool_resolver_map.py +135 -0
  370. autocoder/common/v2/agent/tool_caller/integration_test.py +172 -0
  371. autocoder/common/v2/agent/tool_caller/plugins/__init__.py +14 -0
  372. autocoder/common/v2/agent/tool_caller/plugins/base_plugin.py +126 -0
  373. autocoder/common/v2/agent/tool_caller/plugins/examples/__init__.py +13 -0
  374. autocoder/common/v2/agent/tool_caller/plugins/examples/logging_plugin.py +164 -0
  375. autocoder/common/v2/agent/tool_caller/plugins/examples/security_filter_plugin.py +198 -0
  376. autocoder/common/v2/agent/tool_caller/plugins/plugin_interface.py +141 -0
  377. autocoder/common/v2/agent/tool_caller/test_tool_caller.py +278 -0
  378. autocoder/common/v2/agent/tool_caller/tool_call_plugin_manager.py +331 -0
  379. autocoder/common/v2/agent/tool_caller/tool_caller.py +337 -0
  380. autocoder/common/v2/agent/tool_caller/usage_example.py +193 -0
  381. autocoder/common/v2/code_agentic_editblock_manager.py +4 -4
  382. autocoder/common/v2/code_auto_generate.py +136 -78
  383. autocoder/common/v2/code_auto_generate_diff.py +135 -79
  384. autocoder/common/v2/code_auto_generate_editblock.py +174 -99
  385. autocoder/common/v2/code_auto_generate_strict_diff.py +151 -71
  386. autocoder/common/v2/code_auto_merge.py +1 -1
  387. autocoder/common/v2/code_auto_merge_editblock.py +13 -1
  388. autocoder/common/v2/code_diff_manager.py +3 -3
  389. autocoder/common/v2/code_editblock_manager.py +4 -14
  390. autocoder/common/v2/code_manager.py +1 -1
  391. autocoder/common/v2/code_strict_diff_manager.py +2 -2
  392. autocoder/common/wrap_llm_hint/__init__.py +10 -0
  393. autocoder/common/wrap_llm_hint/test_wrap_llm_hint.py +1067 -0
  394. autocoder/common/wrap_llm_hint/utils.py +432 -0
  395. autocoder/common/wrap_llm_hint/wrap_llm_hint.py +323 -0
  396. autocoder/completer/__init__.py +8 -0
  397. autocoder/completer/command_completer_v2.py +1094 -0
  398. autocoder/default_project/__init__.py +501 -0
  399. autocoder/dispacher/__init__.py +4 -12
  400. autocoder/dispacher/actions/action.py +400 -129
  401. autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
  402. autocoder/index/entry.py +117 -125
  403. autocoder/{agent → index/filter}/agentic_filter.py +322 -333
  404. autocoder/index/filter/normal_filter.py +5 -11
  405. autocoder/index/filter/quick_filter.py +1 -1
  406. autocoder/index/index.py +36 -9
  407. autocoder/index/tests/__init__.py +1 -0
  408. autocoder/index/tests/run_tests.py +195 -0
  409. autocoder/index/tests/test_entry.py +303 -0
  410. autocoder/index/tests/test_index_manager.py +314 -0
  411. autocoder/index/tests/test_module_integration.py +300 -0
  412. autocoder/index/tests/test_symbols_utils.py +183 -0
  413. autocoder/inner/__init__.py +4 -0
  414. autocoder/inner/agentic.py +923 -0
  415. autocoder/inner/async_command_handler.py +992 -0
  416. autocoder/inner/conversation_command_handlers.py +623 -0
  417. autocoder/inner/merge_command_handler.py +213 -0
  418. autocoder/inner/queue_command_handler.py +684 -0
  419. autocoder/models.py +95 -266
  420. autocoder/plugins/git_helper_plugin.py +31 -29
  421. autocoder/plugins/token_helper_plugin.py +65 -46
  422. autocoder/pyproject/__init__.py +32 -29
  423. autocoder/rag/agentic_rag.py +215 -75
  424. autocoder/rag/cache/simple_cache.py +1 -2
  425. autocoder/rag/loaders/image_loader.py +1 -1
  426. autocoder/rag/long_context_rag.py +42 -26
  427. autocoder/rag/qa_conversation_strategy.py +1 -1
  428. autocoder/rag/terminal/__init__.py +17 -0
  429. autocoder/rag/terminal/args.py +581 -0
  430. autocoder/rag/terminal/bootstrap.py +61 -0
  431. autocoder/rag/terminal/command_handlers.py +653 -0
  432. autocoder/rag/terminal/formatters/__init__.py +20 -0
  433. autocoder/rag/terminal/formatters/base.py +70 -0
  434. autocoder/rag/terminal/formatters/json_format.py +66 -0
  435. autocoder/rag/terminal/formatters/stream_json.py +95 -0
  436. autocoder/rag/terminal/formatters/text.py +28 -0
  437. autocoder/rag/terminal/init.py +120 -0
  438. autocoder/rag/terminal/utils.py +106 -0
  439. autocoder/rag/test_agentic_rag.py +389 -0
  440. autocoder/rag/test_doc_filter.py +3 -3
  441. autocoder/rag/test_long_context_rag.py +1 -1
  442. autocoder/rag/test_token_limiter.py +517 -10
  443. autocoder/rag/token_counter.py +3 -0
  444. autocoder/rag/token_limiter.py +19 -15
  445. autocoder/rag/tools/__init__.py +26 -2
  446. autocoder/rag/tools/bochaai_example.py +343 -0
  447. autocoder/rag/tools/bochaai_sdk.py +541 -0
  448. autocoder/rag/tools/metaso_example.py +268 -0
  449. autocoder/rag/tools/metaso_sdk.py +417 -0
  450. autocoder/rag/tools/recall_tool.py +28 -7
  451. autocoder/rag/tools/run_integration_tests.py +204 -0
  452. autocoder/rag/tools/test_all_providers.py +318 -0
  453. autocoder/rag/tools/test_bochaai_integration.py +482 -0
  454. autocoder/rag/tools/test_final_integration.py +215 -0
  455. autocoder/rag/tools/test_metaso_integration.py +424 -0
  456. autocoder/rag/tools/test_metaso_real.py +171 -0
  457. autocoder/rag/tools/test_web_crawl_tool.py +639 -0
  458. autocoder/rag/tools/test_web_search_tool.py +509 -0
  459. autocoder/rag/tools/todo_read_tool.py +202 -0
  460. autocoder/rag/tools/todo_write_tool.py +412 -0
  461. autocoder/rag/tools/web_crawl_tool.py +634 -0
  462. autocoder/rag/tools/web_search_tool.py +558 -0
  463. autocoder/rag/tools/web_tools_example.py +119 -0
  464. autocoder/rag/types.py +16 -0
  465. autocoder/rag/variable_holder.py +4 -2
  466. autocoder/rags.py +86 -79
  467. autocoder/regexproject/__init__.py +23 -21
  468. autocoder/sdk/__init__.py +46 -190
  469. autocoder/sdk/api.py +370 -0
  470. autocoder/sdk/async_runner/__init__.py +26 -0
  471. autocoder/sdk/async_runner/async_executor.py +650 -0
  472. autocoder/sdk/async_runner/async_handler.py +356 -0
  473. autocoder/sdk/async_runner/markdown_processor.py +595 -0
  474. autocoder/sdk/async_runner/task_metadata.py +284 -0
  475. autocoder/sdk/async_runner/worktree_manager.py +438 -0
  476. autocoder/sdk/cli/__init__.py +2 -5
  477. autocoder/sdk/cli/formatters.py +28 -204
  478. autocoder/sdk/cli/handlers.py +77 -44
  479. autocoder/sdk/cli/main.py +154 -171
  480. autocoder/sdk/cli/options.py +95 -22
  481. autocoder/sdk/constants.py +139 -51
  482. autocoder/sdk/core/auto_coder_core.py +484 -109
  483. autocoder/sdk/core/bridge.py +297 -115
  484. autocoder/sdk/exceptions.py +18 -12
  485. autocoder/sdk/formatters/__init__.py +19 -0
  486. autocoder/sdk/formatters/input.py +64 -0
  487. autocoder/sdk/formatters/output.py +247 -0
  488. autocoder/sdk/formatters/stream.py +54 -0
  489. autocoder/sdk/models/__init__.py +6 -5
  490. autocoder/sdk/models/options.py +55 -18
  491. autocoder/sdk/utils/formatters.py +27 -195
  492. autocoder/suffixproject/__init__.py +28 -25
  493. autocoder/terminal/__init__.py +14 -0
  494. autocoder/terminal/app.py +454 -0
  495. autocoder/terminal/args.py +32 -0
  496. autocoder/terminal/bootstrap.py +178 -0
  497. autocoder/terminal/command_processor.py +521 -0
  498. autocoder/terminal/command_registry.py +57 -0
  499. autocoder/terminal/help.py +97 -0
  500. autocoder/terminal/tasks/__init__.py +5 -0
  501. autocoder/terminal/tasks/background.py +77 -0
  502. autocoder/terminal/tasks/task_event.py +70 -0
  503. autocoder/terminal/ui/__init__.py +13 -0
  504. autocoder/terminal/ui/completer.py +268 -0
  505. autocoder/terminal/ui/keybindings.py +75 -0
  506. autocoder/terminal/ui/session.py +41 -0
  507. autocoder/terminal/ui/toolbar.py +64 -0
  508. autocoder/terminal/utils/__init__.py +13 -0
  509. autocoder/terminal/utils/errors.py +18 -0
  510. autocoder/terminal/utils/paths.py +19 -0
  511. autocoder/terminal/utils/shell.py +43 -0
  512. autocoder/terminal_v3/__init__.py +10 -0
  513. autocoder/terminal_v3/app.py +201 -0
  514. autocoder/terminal_v3/handlers/__init__.py +5 -0
  515. autocoder/terminal_v3/handlers/command_handler.py +131 -0
  516. autocoder/terminal_v3/models/__init__.py +6 -0
  517. autocoder/terminal_v3/models/conversation_buffer.py +214 -0
  518. autocoder/terminal_v3/models/message.py +50 -0
  519. autocoder/terminal_v3/models/tool_display.py +247 -0
  520. autocoder/terminal_v3/ui/__init__.py +7 -0
  521. autocoder/terminal_v3/ui/keybindings.py +56 -0
  522. autocoder/terminal_v3/ui/layout.py +141 -0
  523. autocoder/terminal_v3/ui/styles.py +43 -0
  524. autocoder/tsproject/__init__.py +23 -23
  525. autocoder/utils/auto_coder_utils/chat_stream_out.py +1 -1
  526. autocoder/utils/llms.py +88 -80
  527. autocoder/utils/math_utils.py +101 -0
  528. autocoder/utils/model_provider_selector.py +16 -4
  529. autocoder/utils/operate_config_api.py +33 -5
  530. autocoder/utils/thread_utils.py +2 -2
  531. autocoder/version.py +4 -2
  532. autocoder/workflow_agents/__init__.py +84 -0
  533. autocoder/workflow_agents/agent.py +143 -0
  534. autocoder/workflow_agents/exceptions.py +573 -0
  535. autocoder/workflow_agents/executor.py +665 -0
  536. autocoder/workflow_agents/loader.py +749 -0
  537. autocoder/workflow_agents/runner.py +267 -0
  538. autocoder/workflow_agents/types.py +173 -0
  539. autocoder/workflow_agents/utils.py +434 -0
  540. autocoder/workflow_agents/workflow_manager.py +211 -0
  541. auto_coder-1.0.0.dist-info/METADATA +0 -396
  542. auto_coder-1.0.0.dist-info/RECORD +0 -442
  543. auto_coder-1.0.0.dist-info/licenses/LICENSE +0 -201
  544. autocoder/auto_coder_server.py +0 -672
  545. autocoder/benchmark.py +0 -138
  546. autocoder/common/ac_style_command_parser/example.py +0 -7
  547. autocoder/common/cleaner.py +0 -31
  548. autocoder/common/command_completer_v2.py +0 -615
  549. autocoder/common/context_pruner.py +0 -477
  550. autocoder/common/conversation_pruner.py +0 -132
  551. autocoder/common/directory_cache/__init__.py +0 -1
  552. autocoder/common/directory_cache/cache.py +0 -192
  553. autocoder/common/directory_cache/test_cache.py +0 -190
  554. autocoder/common/file_checkpoint/examples.py +0 -217
  555. autocoder/common/llm_friendly_package_example.py +0 -138
  556. autocoder/common/llm_friendly_package_test.py +0 -63
  557. autocoder/common/pull_requests/test_module.py +0 -1
  558. autocoder/common/rulefiles/autocoderrules_utils.py +0 -484
  559. autocoder/common/text.py +0 -30
  560. autocoder/common/v2/agent/agentic_edit_tools/list_package_info_tool_resolver.py +0 -42
  561. autocoder/common/v2/agent/agentic_edit_tools/test_execute_command_tool_resolver.py +0 -70
  562. autocoder/common/v2/agent/agentic_edit_tools/test_search_files_tool_resolver.py +0 -163
  563. autocoder/common/v2/agent/agentic_tool_display.py +0 -183
  564. autocoder/plugins/dynamic_completion_example.py +0 -148
  565. autocoder/plugins/sample_plugin.py +0 -160
  566. autocoder/sdk/cli/__main__.py +0 -26
  567. autocoder/sdk/cli/completion_wrapper.py +0 -38
  568. autocoder/sdk/cli/install_completion.py +0 -301
  569. autocoder/sdk/models/messages.py +0 -209
  570. autocoder/sdk/session/__init__.py +0 -32
  571. autocoder/sdk/session/session.py +0 -106
  572. autocoder/sdk/session/session_manager.py +0 -56
  573. {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.dist-info}/top_level.txt +0 -0
  574. /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
@@ -1,31 +1,32 @@
1
1
  import json
2
2
  import shlex
3
- import fnmatch # Add fnmatch for wildcard matching
4
- from typing import Dict, Any
3
+ import fnmatch # Add fnmatch for wildcard matching
5
4
  from rich.console import Console
6
5
  from rich.table import Table
7
- from rich.panel import Panel
8
6
  import byzerllm
9
- from typing import Generator
10
- from autocoder import models as models_module
7
+ from autocoder.common.llms import LLMManager
11
8
  from autocoder.common.printer import Printer
12
9
  from autocoder.common.result_manager import ResultManager
13
10
  from autocoder.common.model_speed_tester import render_speed_test_in_terminal
14
11
  from autocoder.utils.llms import get_single_llm
12
+ from autocoder.common.core_config import get_memory_manager
15
13
 
16
- def handle_models_command(query: str, memory: Dict[str, Any]):
17
- """
14
+
15
+ def handle_models_command(query: str):
16
+ """
18
17
  Handle /models subcommands:
19
- /models /list - List all models (default + custom)
20
- /models /add <n> <api_key> - Add model with simplified params
21
- /models /add_model name=xxx base_url=xxx ... - Add model with custom params
22
- /models /remove <n> - Remove model by name
23
- /models /chat <content> - Chat with a model
18
+ /models /list [pattern] - List all models (default + custom), optionally filter by pattern
19
+ /models provider/model_name <api_key> - Activate a model with API key
20
+ /models /add_provider name=xxx base_url=xxx ... - Add custom provider
21
+ /models /remove <name> - Remove custom model by name
22
+ /models /chat <model_name> <question> - Chat with a model
23
+ /models /speed-test [rounds] - Test model speed
24
24
  """
25
25
  console = Console()
26
- printer = Printer(console=console)
27
-
28
- product_mode = memory.get("product_mode", "lite")
26
+ printer = Printer(console=console)
27
+
28
+ memory_manager = get_memory_manager()
29
+ product_mode = memory_manager.get_config("product_mode", "lite")
29
30
  if product_mode != "lite":
30
31
  printer.print_in_terminal("models_lite_only", style="red")
31
32
  return
@@ -35,24 +36,17 @@ def handle_models_command(query: str, memory: Dict[str, Any]):
35
36
  printer.print_in_terminal("models_usage")
36
37
  return
37
38
 
38
- models_data = models_module.load_models()
39
+ # Initialize LLM Manager
40
+ llm_manager = LLMManager()
41
+
39
42
  subcmd = ""
40
43
  if "/list" in query:
41
44
  subcmd = "/list"
42
45
  query = query.replace("/list", "", 1).strip()
43
46
 
44
- if "/add_model" in query:
45
- subcmd = "/add_model"
46
- query = query.replace("/add_model", "", 1).strip()
47
-
48
- if "/add" in query:
49
- subcmd = "/add"
50
- query = query.replace("/add", "", 1).strip()
51
-
52
- # alias to /add
53
- if "/activate" in query:
54
- subcmd = "/add"
55
- query = query.replace("/activate", "", 1).strip()
47
+ if "/add_provider" in query:
48
+ subcmd = "/add_provider"
49
+ query = query.replace("/add_provider", "", 1).strip()
56
50
 
57
51
  if "/remove" in query:
58
52
  subcmd = "/remove"
@@ -64,7 +58,7 @@ def handle_models_command(query: str, memory: Dict[str, Any]):
64
58
 
65
59
  if "/speed_test" in query:
66
60
  subcmd = "/speed-test"
67
- query = query.replace("/speed_test", "", 1).strip()
61
+ query = query.replace("/speed_test", "", 1).strip()
68
62
 
69
63
  if "input_price" in query:
70
64
  subcmd = "/input_price"
@@ -72,91 +66,129 @@ def handle_models_command(query: str, memory: Dict[str, Any]):
72
66
 
73
67
  if "output_price" in query:
74
68
  subcmd = "/output_price"
75
- query = query.replace("/output_price", "", 1).strip()
69
+ query = query.replace("/output_price", "", 1).strip()
76
70
 
77
71
  if "/speed" in query:
78
72
  subcmd = "/speed"
79
73
  query = query.replace("/speed", "", 1).strip()
80
-
74
+
81
75
  if "/chat" in query:
82
76
  subcmd = "/chat"
83
77
  query = query.replace("/chat", "", 1).strip()
84
78
 
85
-
79
+ # 如果没有找到任何子命令,检查是否是简化的激活命令格式: provider/model_name <api_key>
80
+ if not subcmd and query.strip():
81
+ parts = query.strip().split()
82
+ if len(parts) >= 2 and "/" in parts[0]:
83
+ # 这是简化的激活命令
84
+ subcmd = "/activate"
85
+ else:
86
+ printer.print_in_terminal("models_usage")
87
+ return
86
88
 
87
89
  if not subcmd:
88
- printer.print_in_terminal("models_usage")
90
+ printer.print_in_terminal("models_usage")
89
91
 
90
92
  result_manager = ResultManager()
93
+
91
94
  if subcmd == "/list":
92
- pattern = query.strip() # Get the filter pattern from the query
93
- filtered_models_data = models_data
95
+ pattern = query.strip() # Get the filter pattern from the query
96
+
97
+ # Get all models from LLM Manager
98
+ all_models = llm_manager.get_all_models()
99
+ models_list = list(all_models.values())
94
100
 
95
- if pattern: # Apply filter if a pattern is provided
96
- filtered_models_data = [
97
- m for m in models_data if fnmatch.fnmatch(m.get("name", ""), pattern)
101
+ if pattern: # Apply filter if a pattern is provided
102
+ filtered_models = [
103
+ m for m in models_list if fnmatch.fnmatch(m.name, pattern)
98
104
  ]
105
+ else:
106
+ filtered_models = models_list
99
107
 
100
- if filtered_models_data:
101
- # Sort models by speed (average_speed)
102
- sorted_models = sorted(filtered_models_data, key=lambda x: float(x.get('average_speed', 0)))
103
- sorted_models.reverse()
108
+ if filtered_models:
109
+ # Sort models by provider and name
110
+ sorted_models = sorted(
111
+ filtered_models, key=lambda x: (x.provider or "", x.name)
112
+ )
104
113
 
105
114
  table = Table(
106
- title=printer.get_message_from_key("models_title") + (f" (Filtered by: '{pattern}')" if pattern else ""),
115
+ title=printer.get_message_from_key("models_title")
116
+ + (f" (Filtered by: '{pattern}')" if pattern else ""),
107
117
  expand=True,
108
- show_lines=True
118
+ show_lines=True,
119
+ )
120
+ table.add_column(
121
+ "Provider/Model", style="cyan", width=40, overflow="fold", no_wrap=False
122
+ )
123
+ table.add_column(
124
+ "Description", style="white", width=30, overflow="fold", no_wrap=False
109
125
  )
110
- table.add_column("Name", style="cyan", width=40, overflow="fold", no_wrap=False)
111
- table.add_column("Model Name", style="magenta", width=30, overflow="fold", no_wrap=False)
112
- table.add_column("Base URL", style="white", width=30, overflow="fold", no_wrap=False)
113
- table.add_column("Input Price (M)", style="magenta", width=15, overflow="fold", no_wrap=False)
114
- table.add_column("Output Price (M)", style="magenta", width=15, overflow="fold", no_wrap=False)
115
- table.add_column("Speed (s/req)", style="blue", width=15, overflow="fold", no_wrap=False)
126
+ table.add_column(
127
+ "Input Price (M)",
128
+ style="magenta",
129
+ width=15,
130
+ overflow="fold",
131
+ no_wrap=False,
132
+ )
133
+ table.add_column(
134
+ "Output Price (M)",
135
+ style="magenta",
136
+ width=15,
137
+ overflow="fold",
138
+ no_wrap=False,
139
+ )
140
+ table.add_column(
141
+ "API Key", style="blue", width=15, overflow="fold", no_wrap=False
142
+ )
143
+
116
144
  for m in sorted_models:
117
- # Check if api_key_path exists and file exists
118
- is_api_key_set = "api_key" in m
119
- name = m.get("name", "")
120
- if is_api_key_set:
121
- api_key = m.get("api_key", "").strip()
122
- if not api_key:
123
- printer.print_in_terminal("models_api_key_empty", style="yellow", name=name)
124
- name = f"{name} *"
145
+ # Check if model has API key
146
+ has_key = llm_manager.has_key(m.name)
147
+ display_name = m.name
148
+ if has_key:
149
+ display_name = f"{display_name} "
125
150
 
126
151
  table.add_row(
127
- name,
128
- m.get("model_name", ""),
129
- m.get("base_url", ""),
130
- f"{m.get('input_price', 0.0):.2f}",
131
- f"{m.get('output_price', 0.0):.2f}",
132
- f"{m.get('average_speed', 0.0):.3f}"
152
+ display_name,
153
+ m.description or "",
154
+ f"{m.input_price:.2f}",
155
+ f"{m.output_price:.2f}",
156
+ "✓" if has_key else "✗",
133
157
  )
134
158
  console.print(table)
135
- result_manager.add_result(content=json.dumps(sorted_models, ensure_ascii=False), meta={
136
- "action": "models",
137
- "input": {
138
- "query": query # Keep original query for logging
159
+
160
+ # Convert models to dict for JSON serialization
161
+ models_data = [
162
+ {
163
+ "name": m.name,
164
+ "model_name": m.model_name,
165
+ "base_url": m.base_url,
166
+ "input_price": m.input_price,
167
+ "output_price": m.output_price,
168
+ "has_api_key": llm_manager.has_key(m.name),
139
169
  }
140
- })
170
+ for m in sorted_models
171
+ ]
172
+
173
+ result_manager.add_result(
174
+ content=json.dumps(models_data, ensure_ascii=False),
175
+ meta={"action": "models", "input": {"query": query}},
176
+ )
141
177
  else:
142
178
  if pattern:
143
- # Use a specific message if filtering resulted in no models
144
- printer.print_in_terminal("models_no_models_matching_pattern", style="yellow", pattern=pattern)
145
- result_manager.add_result(content=f"No models found matching pattern: {pattern}", meta={
146
- "action": "models",
147
- "input": {
148
- "query": query
149
- }
150
- })
179
+ printer.print_in_terminal(
180
+ "models_no_models_matching_pattern", style="yellow", pattern=pattern
181
+ )
182
+ result_manager.add_result(
183
+ content=f"No models found matching pattern: {pattern}",
184
+ meta={"action": "models", "input": {"query": query}},
185
+ )
151
186
  else:
152
- # Original message if no models exist at all
153
187
  printer.print_in_terminal("models_no_models", style="yellow")
154
- result_manager.add_result(content="No models found", meta={
155
- "action": "models",
156
- "input": {
157
- "query": query
158
- }
159
- })
188
+ result_manager.add_result(
189
+ content="No models found",
190
+ meta={"action": "models", "input": {"query": query}},
191
+ )
160
192
 
161
193
  elif subcmd == "/input_price":
162
194
  args = query.strip().split()
@@ -164,37 +196,38 @@ def handle_models_command(query: str, memory: Dict[str, Any]):
164
196
  name = args[0]
165
197
  try:
166
198
  price = float(args[1])
167
- if models_module.update_model_input_price(name, price):
168
- printer.print_in_terminal("models_input_price_updated", style="green", name=name, price=price)
169
- result_manager.add_result(content=f"models_input_price_updated: {name} {price}",meta={
170
- "action": "models",
171
- "input": {
172
- "query": query
173
- }
174
- })
199
+ if llm_manager.update_input_price(name, price):
200
+ printer.print_in_terminal(
201
+ "models_input_price_updated",
202
+ style="green",
203
+ name=name,
204
+ price=price,
205
+ )
206
+ result_manager.add_result(
207
+ content=f"models_input_price_updated: {name} {price}",
208
+ meta={"action": "models", "input": {"query": query}},
209
+ )
175
210
  else:
176
- printer.print_in_terminal("models_not_found", style="red", name=name)
177
- result_manager.add_result(content=f"models_not_found: {name}",meta={
178
- "action": "models",
179
- "input": {
180
- "query": query
181
- }
182
- })
211
+ printer.print_in_terminal(
212
+ "models_not_found", style="red", name=name
213
+ )
214
+ result_manager.add_result(
215
+ content=f"models_not_found: {name}",
216
+ meta={"action": "models", "input": {"query": query}},
217
+ )
183
218
  except ValueError as e:
184
- result_manager.add_result(content=f"models_invalid_price: {str(e)}",meta={
185
- "action": "models",
186
- "input": {
187
- "query": query
188
- }
189
- })
190
- printer.print_in_terminal("models_invalid_price", style="red", error=str(e))
219
+ result_manager.add_result(
220
+ content=f"models_invalid_price: {str(e)}",
221
+ meta={"action": "models", "input": {"query": query}},
222
+ )
223
+ printer.print_in_terminal(
224
+ "models_invalid_price", style="red", error=str(e)
225
+ )
191
226
  else:
192
- result_manager.add_result(content=printer.get_message_from_key("models_input_price_usage"),meta={
193
- "action": "models",
194
- "input": {
195
- "query": query
196
- }
197
- })
227
+ result_manager.add_result(
228
+ content=printer.get_message_from_key("models_input_price_usage"),
229
+ meta={"action": "models", "input": {"query": query}},
230
+ )
198
231
  printer.print_in_terminal("models_input_price_usage", style="red")
199
232
 
200
233
  elif subcmd == "/output_price":
@@ -203,37 +236,38 @@ def handle_models_command(query: str, memory: Dict[str, Any]):
203
236
  name = args[0]
204
237
  try:
205
238
  price = float(args[1])
206
- if models_module.update_model_output_price(name, price):
207
- printer.print_in_terminal("models_output_price_updated", style="green", name=name, price=price)
208
- result_manager.add_result(content=f"models_output_price_updated: {name} {price}",meta={
209
- "action": "models",
210
- "input": {
211
- "query": query
212
- }
213
- })
239
+ if llm_manager.update_output_price(name, price):
240
+ printer.print_in_terminal(
241
+ "models_output_price_updated",
242
+ style="green",
243
+ name=name,
244
+ price=price,
245
+ )
246
+ result_manager.add_result(
247
+ content=f"models_output_price_updated: {name} {price}",
248
+ meta={"action": "models", "input": {"query": query}},
249
+ )
214
250
  else:
215
- printer.print_in_terminal("models_not_found", style="red", name=name)
216
- result_manager.add_result(content=f"models_not_found: {name}",meta={
217
- "action": "models",
218
- "input": {
219
- "query": query
220
- }
221
- })
251
+ printer.print_in_terminal(
252
+ "models_not_found", style="red", name=name
253
+ )
254
+ result_manager.add_result(
255
+ content=f"models_not_found: {name}",
256
+ meta={"action": "models", "input": {"query": query}},
257
+ )
222
258
  except ValueError as e:
223
- printer.print_in_terminal("models_invalid_price", style="red", error=str(e))
224
- result_manager.add_result(content=f"models_invalid_price: {str(e)}",meta={
225
- "action": "models",
226
- "input": {
227
- "query": query
228
- }
229
- })
259
+ printer.print_in_terminal(
260
+ "models_invalid_price", style="red", error=str(e)
261
+ )
262
+ result_manager.add_result(
263
+ content=f"models_invalid_price: {str(e)}",
264
+ meta={"action": "models", "input": {"query": query}},
265
+ )
230
266
  else:
231
- result_manager.add_result(content=printer.get_message_from_key("models_output_price_usage"),meta={
232
- "action": "models",
233
- "input": {
234
- "query": query
235
- }
236
- })
267
+ result_manager.add_result(
268
+ content=printer.get_message_from_key("models_output_price_usage"),
269
+ meta={"action": "models", "input": {"query": query}},
270
+ )
237
271
  printer.print_in_terminal("models_output_price_usage", style="red")
238
272
 
239
273
  elif subcmd == "/speed":
@@ -242,40 +276,30 @@ def handle_models_command(query: str, memory: Dict[str, Any]):
242
276
  name = args[0]
243
277
  try:
244
278
  speed = float(args[1])
245
- if models_module.update_model_speed(name, speed):
246
- printer.print_in_terminal("models_speed_updated", style="green", name=name, speed=speed)
247
- result_manager.add_result(content=f"models_speed_updated: {name} {speed}",meta={
248
- "action": "models",
249
- "input": {
250
- "query": query
251
- }
252
- })
253
- else:
254
- printer.print_in_terminal("models_not_found", style="red", name=name)
255
- result_manager.add_result(content=f"models_not_found: {name}",meta={
256
- "action": "models",
257
- "input": {
258
- "query": query
259
- }
260
- })
279
+ # Speed functionality not implemented in LLMManager yet
280
+ printer.print_in_terminal(
281
+ "models_speed_not_implemented", style="yellow"
282
+ )
283
+ result_manager.add_result(
284
+ content="Speed functionality not implemented yet",
285
+ meta={"action": "models", "input": {"query": query}},
286
+ )
261
287
  except ValueError as e:
262
- printer.print_in_terminal("models_invalid_speed", style="red", error=str(e))
263
- result_manager.add_result(content=f"models_invalid_speed: {str(e)}",meta={
264
- "action": "models",
265
- "input": {
266
- "query": query
267
- }
268
- })
288
+ printer.print_in_terminal(
289
+ "models_invalid_speed", style="red", error=str(e)
290
+ )
291
+ result_manager.add_result(
292
+ content=f"models_invalid_speed: {str(e)}",
293
+ meta={"action": "models", "input": {"query": query}},
294
+ )
269
295
  else:
270
- result_manager.add_result(content=printer.get_message_from_key("models_speed_usage"),meta={
271
- "action": "models",
272
- "input": {
273
- "query": query
274
- }
275
- })
296
+ result_manager.add_result(
297
+ content=printer.get_message_from_key("models_speed_usage"),
298
+ meta={"action": "models", "input": {"query": query}},
299
+ )
276
300
  printer.print_in_terminal("models_speed_usage", style="red")
277
301
 
278
- elif subcmd == "/speed-test":
302
+ elif subcmd == "/speed-test" or subcmd == "/check":
279
303
  test_rounds = 1 # 默认测试轮数
280
304
 
281
305
  enable_long_context = False
@@ -292,58 +316,72 @@ def handle_models_command(query: str, memory: Dict[str, Any]):
292
316
  if args and args[0].isdigit():
293
317
  test_rounds = int(args[0])
294
318
 
295
- render_speed_test_in_terminal(product_mode, test_rounds,enable_long_context=enable_long_context)
319
+ render_speed_test_in_terminal(
320
+ product_mode, test_rounds, enable_long_context=enable_long_context
321
+ )
296
322
  ## 等待优化,获取明细数据
297
- result_manager.add_result(content="models test success",meta={
298
- "action": "models",
299
- "input": {
300
- "query": query
301
- }
302
- })
303
-
304
- elif subcmd == "/add":
305
- # Support both simplified and legacy formats
306
- args = query.strip().split(" ")
307
- if len(args) == 2:
308
- # Simplified: /models /add <name> <api_key>
309
- name, api_key = args[0], args[1]
310
- result = models_module.update_model_with_api_key(name, api_key)
323
+ result_manager.add_result(
324
+ content="models test success",
325
+ meta={"action": "models", "input": {"query": query}},
326
+ )
327
+
328
+ elif subcmd == "/activate":
329
+ # 简化的激活命令: /models provider/model_name <api_key>
330
+ args = query.strip().split(" ")
331
+ if len(args) >= 2:
332
+ name, api_key = args[0], args[1]
333
+
334
+ # 检查模型是否存在于内置模型中
335
+ if not llm_manager.check_model_exists(name):
336
+ printer.print_in_terminal("models_not_found", style="red", name=name)
337
+ printer.print_in_terminal("models_not_found_hint", style="yellow")
338
+
339
+ result_manager.add_result(
340
+ content=printer.get_message_from_key_with_format(
341
+ "models_not_found", name=name
342
+ )
343
+ + printer.get_message_from_key("models_not_found_hint"),
344
+ meta={"action": "models", "input": {"query": query}},
345
+ )
346
+ return
347
+
348
+ result = llm_manager.update_model_with_api_key(name, api_key)
311
349
  if result:
312
- result_manager.add_result(content=f"models_added: {name}",meta={
313
- "action": "models",
314
- "input": {
315
- "query": query
316
- }
317
- })
350
+ result_manager.add_result(
351
+ content=f"models_activated: {name}",
352
+ meta={"action": "models", "input": {"query": query}},
353
+ )
318
354
  printer.print_in_terminal("models_added", style="green", name=name)
319
355
  else:
320
- result_manager.add_result(content=f"models_add_failed: {name}",meta={
321
- "action": "models",
322
- "input": {
323
- "query": query
324
- }
325
- })
356
+ result_manager.add_result(
357
+ content=f"models_activate_failed: {name}",
358
+ meta={"action": "models", "input": {"query": query}},
359
+ )
326
360
  printer.print_in_terminal("models_add_failed", style="red", name=name)
327
- else:
328
- models_list = "\n".join([m["name"] for m in models_module.default_models_list])
329
- printer.print_in_terminal("models_add_usage", style="red", models=models_list)
330
- result_manager.add_result(content=printer.get_message_from_key_with_format("models_add_usage",models=models_list),meta={
331
- "action": "models",
332
- "input": {
333
- "query": query
334
- }
335
- })
361
+ else:
362
+ # 参数不足时的错误提示
363
+ printer.print_in_terminal("models_activate_usage", style="red")
364
+ printer.print_in_terminal("models_activate_example", style="yellow")
365
+ printer.print_in_terminal("models_activate_list_hint", style="yellow")
366
+
367
+ result_manager.add_result(
368
+ content=printer.get_message_from_key("models_activate_usage")
369
+ + "\n"
370
+ + printer.get_message_from_key("models_activate_example")
371
+ + printer.get_message_from_key("models_activate_list_hint"),
372
+ meta={"action": "models", "input": {"query": query}},
373
+ )
336
374
 
337
- elif subcmd == "/add_model":
338
- # Parse key=value pairs: /models /add_model name=abc base_url=http://xx ...
375
+ elif subcmd == "/add_provider":
376
+ # Parse key=value pairs: /models /add_model name=abc base_url=http://xx ...
339
377
  # Collect key=value pairs
340
378
  kv_pairs = shlex.split(query)
341
379
  data_dict = {}
342
380
  for pair in kv_pairs:
343
- if '=' not in pair:
381
+ if "=" not in pair:
344
382
  printer.print_in_terminal("models_add_model_params", style="red")
345
383
  continue
346
- k, v = pair.split('=', 1)
384
+ k, v = pair.split("=", 1)
347
385
  data_dict[k.strip()] = v.strip()
348
386
 
349
387
  # Name is required
@@ -352,14 +390,16 @@ def handle_models_command(query: str, memory: Dict[str, Any]):
352
390
  return
353
391
 
354
392
  # Check duplication
355
- if any(m["name"] == data_dict["name"] for m in models_data):
356
- printer.print_in_terminal("models_add_model_exists", style="yellow", name=data_dict["name"])
357
- result_manager.add_result(content=printer.get_message_from_key_with_format("models_add_model_exists",name=data_dict["name"]),meta={
358
- "action": "models",
359
- "input": {
360
- "query": query
361
- }
362
- })
393
+ if llm_manager.check_model_exists(data_dict["name"]):
394
+ printer.print_in_terminal(
395
+ "models_add_model_exists", style="yellow", name=data_dict["name"]
396
+ )
397
+ result_manager.add_result(
398
+ content=printer.get_message_from_key_with_format(
399
+ "models_add_model_exists", name=data_dict["name"]
400
+ ),
401
+ meta={"action": "models", "input": {"query": query}},
402
+ )
363
403
  return
364
404
 
365
405
  # Create model with defaults
@@ -368,118 +408,140 @@ def handle_models_command(query: str, memory: Dict[str, Any]):
368
408
  "model_type": data_dict.get("model_type", "saas/openai"),
369
409
  "model_name": data_dict.get("model_name", data_dict["name"]),
370
410
  "base_url": data_dict.get("base_url", "https://api.openai.com/v1"),
371
- "api_key_path": data_dict.get("api_key_path", "api.openai.com"),
411
+ "provider": data_dict.get("provider", None),
412
+ "api_key_path": data_dict.get("api_key_path", ""),
372
413
  "description": data_dict.get("description", ""),
373
- "is_reasoning": data_dict.get("is_reasoning", "false") in ["true", "True", "TRUE", "1"]
414
+ "is_reasoning": data_dict.get("is_reasoning", "false")
415
+ in ["true", "True", "TRUE", "1"],
416
+ "input_price": float(data_dict.get("input_price", "0.0")),
417
+ "output_price": float(data_dict.get("output_price", "0.0")),
418
+ "context_window": int(data_dict.get("context_window", "32768")),
419
+ "max_output_tokens": int(data_dict.get("max_output_tokens", "8096")),
374
420
  }
375
421
 
376
- models_data.append(final_model)
377
- models_module.save_models(models_data)
378
- printer.print_in_terminal("models_add_model_success", style="green", name=data_dict["name"])
379
- result_manager.add_result(content=f"models_add_model_success: {data_dict['name']}",meta={
380
- "action": "models",
381
- "input": {
382
- "query": query
383
- }
384
- })
422
+ # Add API key if provided
423
+ if "api_key" in data_dict:
424
+ final_model["api_key"] = data_dict["api_key"]
425
+
426
+ llm_manager.add_models([final_model])
427
+ printer.print_in_terminal(
428
+ "models_add_model_success", style="green", name=data_dict["name"]
429
+ )
430
+ result_manager.add_result(
431
+ content=f"models_add_model_success: {data_dict['name']}",
432
+ meta={"action": "models", "input": {"query": query}},
433
+ )
385
434
 
386
435
  elif subcmd == "/remove":
387
436
  args = query.strip().split(" ")
388
437
  if len(args) < 1:
389
- printer.print_in_terminal("models_add_usage", style="red")
390
- result_manager.add_result(content=printer.get_message_from_key("models_add_usage"),meta={
391
- "action": "models",
392
- "input": {
393
- "query": query
394
- }
395
- })
438
+ printer.print_in_terminal("models_remove_usage", style="red")
439
+ result_manager.add_result(
440
+ content=printer.get_message_from_key("models_remove_usage"),
441
+ meta={"action": "models", "input": {"query": query}},
442
+ )
396
443
  return
397
444
  name = args[0]
398
- filtered_models = [m for m in models_data if m["name"] != name]
399
- if len(filtered_models) == len(models_data):
400
- printer.print_in_terminal("models_add_model_remove", style="yellow", name=name)
401
- result_manager.add_result(content=printer.get_message_from_key_with_format("models_add_model_remove",name=name),meta={
402
- "action": "models",
403
- "input": {
404
- "query": query
405
- }
406
- })
445
+ if not llm_manager.check_model_exists(name):
446
+ printer.print_in_terminal(
447
+ "models_add_model_remove", style="yellow", name=name
448
+ )
449
+ result_manager.add_result(
450
+ content=printer.get_message_from_key_with_format(
451
+ "models_add_model_remove", name=name
452
+ ),
453
+ meta={"action": "models", "input": {"query": query}},
454
+ )
407
455
  return
408
- models_module.save_models(filtered_models)
409
- printer.print_in_terminal("models_add_model_removed", style="green", name=name)
410
- result_manager.add_result(content=printer.get_message_from_key_with_format("models_add_model_removed",name=name),meta={
411
- "action": "models",
412
- "input": {
413
- "query": query
414
- }
415
- })
456
+
457
+ # 尝试删除模型
458
+ if llm_manager.remove_model(name):
459
+ printer.print_in_terminal(
460
+ "models_add_model_removed", style="green", name=name
461
+ )
462
+ result_manager.add_result(
463
+ content=printer.get_message_from_key_with_format(
464
+ "models_add_model_removed", name=name
465
+ ),
466
+ meta={"action": "models", "input": {"query": query}},
467
+ )
468
+ else:
469
+ # 删除失败,可能是默认模型
470
+ printer.print_in_terminal("models_remove_failed", style="red", name=name)
471
+ result_manager.add_result(
472
+ content=f"Failed to remove model: {name}. Cannot remove default models.",
473
+ meta={"action": "models", "input": {"query": query}},
474
+ )
475
+
416
476
  elif subcmd == "/chat":
417
477
  if not query.strip():
418
- printer.print_in_terminal("Please provide content in format: <model_name> <question>", style="yellow")
419
- result_manager.add_result(content="Please provide content in format: <model_name> <question>", meta={
420
- "action": "models",
421
- "input": {
422
- "query": query
423
- }
424
- })
478
+ printer.print_in_terminal(
479
+ "Please provide content in format: <model_name> <question>",
480
+ style="yellow",
481
+ )
482
+ result_manager.add_result(
483
+ content="Please provide content in format: <model_name> <question>",
484
+ meta={"action": "models", "input": {"query": query}},
485
+ )
425
486
  return
426
-
487
+
427
488
  # 分离模型名称和用户问题
428
- parts = query.strip().split(' ', 1) # 只在第一个空格处分割
489
+ parts = query.strip().split(" ", 1) # 只在第一个空格处分割
429
490
  if len(parts) < 2:
430
- printer.print_in_terminal("Correct format should be: <model_name> <question>, where question can contain spaces", style="yellow")
431
- result_manager.add_result(content="Correct format should be: <model_name> <question>, where question can contain spaces", meta={
432
- "action": "models",
433
- "input": {
434
- "query": query
435
- }
436
- })
491
+ printer.print_in_terminal(
492
+ "Correct format should be: <model_name> <question>, where question can contain spaces",
493
+ style="yellow",
494
+ )
495
+ result_manager.add_result(
496
+ content="Correct format should be: <model_name> <question>, where question can contain spaces",
497
+ meta={"action": "models", "input": {"query": query}},
498
+ )
437
499
  return
438
-
500
+
439
501
  model_name = parts[0]
440
502
  user_question = parts[1] # 这将包含所有剩余文本,保留空格
441
- product_mode = memory.get("product_mode", "lite")
442
-
503
+ memory_manager = get_memory_manager()
504
+ product_mode = memory_manager.get_config("product_mode", "lite")
505
+
443
506
  try:
444
507
  # Get the model
445
508
  llm = get_single_llm(model_name, product_mode=product_mode)
446
-
509
+
447
510
  @byzerllm.prompt()
448
- def chat_func(content: str) -> Generator[str, None, None]:
511
+ def chat_func(content: str) -> str:
449
512
  """
450
513
  {{ content }}
451
514
  """
452
-
515
+ return {} # type: ignore
516
+
453
517
  # Support custom llm_config parameters
454
518
  result = chat_func.with_llm(llm).run(user_question)
455
- output_text = ""
519
+ output_text = ""
456
520
  for res in result:
457
521
  output_text += res
458
522
  print(res, end="", flush=True)
459
- print("\n")
460
-
523
+ print("\n")
524
+
461
525
  # Print the result
462
-
463
- result_manager.add_result(content=output_text, meta={
464
- "action": "models",
465
- "input": {
466
- "query": query
467
- }
468
- })
526
+
527
+ result_manager.add_result(
528
+ content=output_text,
529
+ meta={"action": "models", "input": {"query": query}},
530
+ )
469
531
  except Exception as e:
470
- error_message = f"Error chatting with model: {str(e)}"
532
+ error_message = f"Error chating with model: {str(e)}"
471
533
  printer.print_str_in_terminal(error_message, style="red")
472
- result_manager.add_result(content=error_message, meta={
473
- "action": "models",
474
- "input": {
475
- "query": query
476
- }
477
- })
534
+ result_manager.add_result(
535
+ content=error_message,
536
+ meta={"action": "models", "input": {"query": query}},
537
+ )
478
538
  else:
479
- printer.print_in_terminal("models_unknown_subcmd", style="yellow", subcmd=subcmd)
480
- result_manager.add_result(content=printer.get_message_from_key_with_format("models_unknown_subcmd",subcmd=subcmd),meta={
481
- "action": "models",
482
- "input": {
483
- "query": query
484
- }
485
- })
539
+ printer.print_in_terminal(
540
+ "models_unknown_subcmd", style="yellow", subcmd=subcmd
541
+ )
542
+ result_manager.add_result(
543
+ content=printer.get_message_from_key_with_format(
544
+ "models_unknown_subcmd", subcmd=subcmd
545
+ ),
546
+ meta={"action": "models", "input": {"query": query}},
547
+ )