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
@@ -0,0 +1,142 @@
1
+ import byzerllm
2
+ from typing import Union, List, Optional
3
+
4
+ from .schema import LLMModel
5
+
6
+
7
+ class LLMFactory:
8
+ """LLM 实例化工厂"""
9
+
10
+ @staticmethod
11
+ def create_llm(model: LLMModel, product_mode: str) -> Union[byzerllm.ByzerLLM, byzerllm.SimpleByzerLLM]:
12
+ """
13
+ 根据模型配置和产品模式创建 LLM 实例
14
+
15
+ Args:
16
+ model: LLM 模型配置
17
+ product_mode: 产品模式 ("pro" 或 "lite")
18
+
19
+ Returns:
20
+ 配置好的 byzerllm 客户端实例
21
+
22
+ Raises:
23
+ ValueError: 当模型未配置 API 密钥时
24
+ """
25
+ # 检查是否有 API 密钥
26
+ api_key = model.get_api_key()
27
+ if not api_key:
28
+ raise ValueError(f"Model {model.name} has no API key configured")
29
+
30
+ if product_mode == "pro":
31
+ # Pro 模式:使用 ByzerLLM.from_default_model
32
+ return byzerllm.ByzerLLM.from_default_model(model.name)
33
+
34
+ elif product_mode == "lite":
35
+ # Lite 模式:使用 SimpleByzerLLM
36
+ target_llm = byzerllm.SimpleByzerLLM(default_model_name=model.name)
37
+
38
+ # 部署配置
39
+ infer_params = {
40
+ "saas.base_url": model.base_url,
41
+ "saas.api_key": api_key,
42
+ "saas.model": model.model_name,
43
+ "saas.is_reasoning": model.is_reasoning,
44
+ "saas.max_output_tokens": model.max_output_tokens
45
+ }
46
+
47
+ target_llm.deploy(
48
+ model_path="",
49
+ pretrained_model_type=model.model_type,
50
+ udf_name=model.name,
51
+ infer_params=infer_params
52
+ )
53
+
54
+ return target_llm
55
+
56
+ else:
57
+ raise ValueError(f"Unsupported product mode: {product_mode}")
58
+
59
+ @staticmethod
60
+ def create_llm_from_names(model_names: str, models: List[LLMModel], product_mode: str) -> Optional[Union[byzerllm.ByzerLLM, byzerllm.SimpleByzerLLM]]:
61
+ """
62
+ 根据模型名称列表创建 LLM 实例(返回第一个可用的)
63
+
64
+ Args:
65
+ model_names: 逗号分隔的模型名称列表
66
+ models: 可用的模型列表
67
+ product_mode: 产品模式
68
+
69
+ Returns:
70
+ 第一个成功创建的 LLM 实例,如果都失败则返回 None
71
+
72
+ Raises:
73
+ ValueError: 当所有模型都无法创建时,包含详细的错误信息
74
+ """
75
+ # 处理模型名称列表
76
+ if "," in model_names:
77
+ names = [name.strip() for name in model_names.split(",")]
78
+ else:
79
+ names = [model_names.strip()]
80
+
81
+ # 收集错误信息
82
+ errors = []
83
+
84
+ # 查找并创建第一个可用的模型
85
+ for name in names:
86
+ # 在模型列表中查找
87
+ model = next((m for m in models if m.name == name), None)
88
+ if not model:
89
+ errors.append(f"Model '{name}' not found")
90
+ continue
91
+
92
+ try:
93
+ return LLMFactory.create_llm(model, product_mode)
94
+ except ValueError as e:
95
+ errors.append(f"Model '{name}': {str(e)}")
96
+ continue
97
+
98
+ # 如果所有模型都失败了,抛出包含所有错误信息的异常
99
+ if errors:
100
+ error_msg = f"Failed to create LLM instance for models: {model_names}\n" + "\n".join(f" - {error}" for error in errors)
101
+ raise ValueError(error_msg)
102
+
103
+ # 如果没有找到任何模型(理论上不应该到这里)
104
+ raise ValueError(f"No available models found: {model_names}")
105
+
106
+ @staticmethod
107
+ def get_llm_names(llm: Union[byzerllm.ByzerLLM, byzerllm.SimpleByzerLLM, str, List],
108
+ target_model_type: Optional[str] = None) -> List[str]:
109
+ """
110
+ 获取 LLM 的模型名称列表
111
+
112
+ Args:
113
+ llm: LLM 实例或模型名称
114
+ target_model_type: 目标模型类型(可选)
115
+
116
+ Returns:
117
+ 模型名称列表
118
+ """
119
+ if target_model_type is None:
120
+ if isinstance(llm, list):
121
+ return [_llm.default_model_name for _llm in llm if hasattr(_llm, 'default_model_name') and _llm.default_model_name]
122
+ elif isinstance(llm, str):
123
+ return llm.split(",") if llm else []
124
+ return [llm.default_model_name] if hasattr(llm, 'default_model_name') and llm.default_model_name else []
125
+
126
+ # 处理有 target_model_type 的情况
127
+ if not isinstance(llm, (str, list)) and hasattr(llm, 'get_sub_client'):
128
+ llms = llm.get_sub_client(target_model_type)
129
+
130
+ if llms is None:
131
+ # 回退到默认处理
132
+ if isinstance(llm, list):
133
+ return [_llm.default_model_name for _llm in llm if hasattr(_llm, 'default_model_name') and _llm.default_model_name]
134
+ return [llm.default_model_name] if hasattr(llm, 'default_model_name') and llm.default_model_name else []
135
+ elif isinstance(llms, list):
136
+ return [_llm.default_model_name for _llm in llms if hasattr(_llm, 'default_model_name') and _llm.default_model_name]
137
+ elif isinstance(llms, str) and llms:
138
+ return llms.split(",")
139
+ else:
140
+ return [llms.default_model_name] if hasattr(llms, 'default_model_name') and llms.default_model_name else []
141
+
142
+ return []
@@ -0,0 +1,264 @@
1
+ import byzerllm
2
+ from typing import Union, List, Optional, Dict
3
+
4
+ from .schema import LLMModel
5
+ from .registry import ModelRegistry
6
+ from .factory import LLMFactory
7
+ from .pricing import PricingManager
8
+
9
+
10
+ class LLMManager:
11
+ """大语言模型管理器,统一管理所有 LLM 的配置、实例化和操作"""
12
+
13
+ def __init__(self, models_json_path: Optional[str] = None):
14
+ """
15
+ 初始化 LLM 管理器
16
+
17
+ Args:
18
+ models_json_path: 模型配置文件路径,默认为 ~/.auto-coder/keys/models.json
19
+ """
20
+ self.registry = ModelRegistry(models_json_path)
21
+ self.pricing = PricingManager(self.registry)
22
+ # 立即加载模型以初始化缓存
23
+ self.registry.load()
24
+
25
+ def get_model(self, name: str) -> Optional[LLMModel]:
26
+ """
27
+ 获取模型配置信息
28
+
29
+ Args:
30
+ name: 模型名称
31
+
32
+ Returns:
33
+ LLMModel 对象,如果不存在则返回 None
34
+ """
35
+ return self.registry.get(name)
36
+
37
+ def get_all_models(self) -> Dict[str, LLMModel]:
38
+ """获取所有模型配置"""
39
+ return self.registry.get_all()
40
+
41
+ def get_model_info(self, name: str, product_mode: str) -> Optional[Dict]:
42
+ """
43
+ 获取模型信息(兼容旧版本接口)
44
+
45
+ Args:
46
+ name: 模型名称
47
+ product_mode: 产品模式(pro 或 lite)
48
+
49
+ Returns:
50
+ 模型信息字典,如果不存在则返回 None
51
+ """
52
+ if product_mode == "pro":
53
+ # Pro 模式下直接返回 None(与原实现保持一致)
54
+ return None
55
+
56
+ model = self.get_model(name)
57
+ if not model:
58
+ return None
59
+
60
+ # 转换为字典格式,保持兼容性
61
+ return {
62
+ "name": model.name,
63
+ "description": model.description,
64
+ "model_name": model.model_name,
65
+ "model_type": model.model_type,
66
+ "base_url": model.base_url,
67
+ "provider": model.provider,
68
+ "api_key": model.get_api_key(),
69
+ "is_reasoning": model.is_reasoning,
70
+ "input_price": model.input_price,
71
+ "output_price": model.output_price,
72
+ "max_output_tokens": model.max_output_tokens,
73
+ "context_window": model.context_window
74
+ }
75
+
76
+ def get_single_llm(self, model_names: str, product_mode: str) -> Optional[Union[byzerllm.ByzerLLM, byzerllm.SimpleByzerLLM]]:
77
+ """
78
+ 根据模型名称和产品模式获取 LLM 实例
79
+
80
+ Args:
81
+ model_names: 逗号分隔的模型名称列表
82
+ product_mode: 产品模式(pro 或 lite)
83
+
84
+ Returns:
85
+ 配置好的 LLM 实例
86
+
87
+ Raises:
88
+ ValueError: 当所有指定的模型都无法创建时,包含详细的错误信息
89
+ """
90
+ models = list(self.registry.get_all().values())
91
+ return LLMFactory.create_llm_from_names(model_names, models, product_mode)
92
+
93
+ def get_llm_names(self, llm: Union[byzerllm.ByzerLLM, byzerllm.SimpleByzerLLM, str, List],
94
+ target_model_type: Optional[str] = None) -> List[str]:
95
+ """
96
+ 获取 LLM 的模型名称列表
97
+
98
+ Args:
99
+ llm: LLM 实例或模型名称
100
+ target_model_type: 目标模型类型(可选)
101
+
102
+ Returns:
103
+ 模型名称列表
104
+ """
105
+ return LLMFactory.get_llm_names(llm, target_model_type)
106
+
107
+ def add_models(self, models: List[Union[LLMModel, Dict]]) -> None:
108
+ """
109
+ 批量添加模型
110
+
111
+ Args:
112
+ models: 模型列表,可以是 LLMModel 对象或字典
113
+ """
114
+ for model_data in models:
115
+ if isinstance(model_data, dict):
116
+ # 如果是字典,转换为 LLMModel,设置 base_keys_dir
117
+ model_data_with_keys_dir = model_data.copy()
118
+ model_data_with_keys_dir["base_keys_dir"] = str(self.registry.models_json_path.parent)
119
+ model = LLMModel(**model_data_with_keys_dir)
120
+ else:
121
+ model = model_data
122
+ # 确保已有的 LLMModel 对象也设置了 base_keys_dir
123
+ if not model.base_keys_dir:
124
+ model.base_keys_dir = str(self.registry.models_json_path.parent)
125
+
126
+ # 保存 api_key 的副本(如果有的话)
127
+ api_key_to_save = model.api_key
128
+
129
+ # 如果有 api_key,设置 api_key_path(如果没有的话)
130
+ if api_key_to_save and not model.api_key_path:
131
+ model.api_key_path = model.name.replace("/", "_")
132
+
133
+ # 清除内存中的 api_key,以便正确保存到文件
134
+ model.api_key = None
135
+
136
+ # 首先添加模型配置
137
+ self.registry.add_or_update(model)
138
+
139
+ # 如果有 api_key,再保存密钥
140
+ if api_key_to_save and model.api_key_path:
141
+ # 使用文件锁保存密钥到文件
142
+ api_key_file = self.registry.models_json_path.parent / model.api_key_path
143
+ self.registry._ensure_dir()
144
+
145
+ # 导入文件锁上下文管理器
146
+ from filelock import FileLock
147
+
148
+ with FileLock(self.registry._get_lock_path(api_key_file), timeout=5):
149
+ with open(api_key_file, 'w', encoding='utf-8') as f:
150
+ f.write(api_key_to_save.strip())
151
+
152
+ def update_model_with_api_key(self, name: str, api_key: str) -> bool:
153
+ """
154
+ 更新模型的 API 密钥
155
+
156
+ Args:
157
+ name: 模型名称
158
+ api_key: API 密钥
159
+
160
+ Returns:
161
+ 是否成功更新
162
+ """
163
+ return self.registry.save_api_key(name, api_key)
164
+
165
+ def update_model(self, name: str, model_data: Dict) -> Optional[LLMModel]:
166
+ """
167
+ 更新模型信息
168
+
169
+ Args:
170
+ name: 要更新的模型名称
171
+ model_data: 包含新信息的字典
172
+
173
+ Returns:
174
+ 更新后的模型,如果未找到则返回 None
175
+ """
176
+ model = self.registry.get(name)
177
+ if not model:
178
+ return None
179
+
180
+ # 更新字段
181
+ if "description" in model_data:
182
+ model.description = model_data["description"]
183
+ if "model_name" in model_data:
184
+ model.model_name = model_data["model_name"]
185
+ if "model_type" in model_data:
186
+ model.model_type = model_data["model_type"]
187
+ if "base_url" in model_data:
188
+ model.base_url = model_data["base_url"]
189
+ if "provider" in model_data:
190
+ model.provider = model_data["provider"]
191
+ if "is_reasoning" in model_data:
192
+ model.is_reasoning = model_data["is_reasoning"]
193
+ if "input_price" in model_data:
194
+ model.input_price = float(model_data["input_price"])
195
+ if "output_price" in model_data:
196
+ model.output_price = float(model_data["output_price"])
197
+ if "max_output_tokens" in model_data:
198
+ model.max_output_tokens = int(model_data["max_output_tokens"])
199
+ if "context_window" in model_data:
200
+ model.context_window = int(model_data["context_window"])
201
+
202
+ # 保存更新
203
+ self.registry.add_or_update(model)
204
+
205
+ # 如果提供了 API 密钥,单独处理
206
+ if "api_key" in model_data and model_data["api_key"]:
207
+ self.update_model_with_api_key(name, model_data["api_key"])
208
+
209
+ return model
210
+
211
+ def has_key(self, name: str) -> bool:
212
+ """
213
+ 检查模型是否已配置密钥
214
+
215
+ Args:
216
+ name: 模型名称
217
+
218
+ Returns:
219
+ 是否已配置密钥
220
+ """
221
+ model = self.get_model(name)
222
+ return model.has_api_key if model else False
223
+
224
+ def check_model_exists(self, name: str) -> bool:
225
+ """
226
+ 检查模型是否存在
227
+
228
+ Args:
229
+ name: 模型名称
230
+
231
+ Returns:
232
+ 是否存在
233
+ """
234
+ return self.get_model(name) is not None
235
+
236
+ # 价格管理相关方法
237
+ def update_input_price(self, name: str, price: float) -> bool:
238
+ """更新模型输入价格"""
239
+ return self.pricing.update_input_price(name, price)
240
+
241
+ def update_output_price(self, name: str, price: float) -> bool:
242
+ """更新模型输出价格"""
243
+ return self.pricing.update_output_price(name, price)
244
+
245
+ def update_price(self, name: str, input_price: Optional[float] = None,
246
+ output_price: Optional[float] = None) -> bool:
247
+ """同时更新输入和输出价格"""
248
+ return self.pricing.update_prices(name, input_price, output_price)
249
+
250
+ def get_cost_estimate(self, name: str, input_tokens: int, output_tokens: int) -> Optional[float]:
251
+ """估算使用成本"""
252
+ return self.pricing.get_cost_estimate(name, input_tokens, output_tokens)
253
+
254
+ def remove_model(self, name: str) -> bool:
255
+ """
256
+ 删除模型
257
+
258
+ Args:
259
+ name: 模型名称
260
+
261
+ Returns:
262
+ 是否成功删除
263
+ """
264
+ return self.registry.remove_model(name)
@@ -0,0 +1,121 @@
1
+ from typing import Optional
2
+
3
+ from .schema import LLMModel
4
+ from .registry import ModelRegistry
5
+
6
+
7
+ class PricingManager:
8
+ """模型价格管理器"""
9
+
10
+ def __init__(self, registry: ModelRegistry):
11
+ self.registry = registry
12
+
13
+ def update_input_price(self, name: str, price: float) -> bool:
14
+ """
15
+ 更新模型输入价格
16
+
17
+ Args:
18
+ name: 模型名称
19
+ price: 新的输入价格(美元/百万tokens),必须大于等于0
20
+
21
+ Returns:
22
+ bool: 是否成功更新
23
+
24
+ Raises:
25
+ ValueError: 如果价格为负数
26
+ """
27
+ if price < 0:
28
+ raise ValueError("价格不能为负数")
29
+
30
+ model = self.registry.get(name)
31
+ if not model:
32
+ return False
33
+
34
+ model.input_price = float(price)
35
+ self.registry.add_or_update(model)
36
+ return True
37
+
38
+ def update_output_price(self, name: str, price: float) -> bool:
39
+ """
40
+ 更新模型输出价格
41
+
42
+ Args:
43
+ name: 模型名称
44
+ price: 新的输出价格(美元/百万tokens),必须大于等于0
45
+
46
+ Returns:
47
+ bool: 是否成功更新
48
+
49
+ Raises:
50
+ ValueError: 如果价格为负数
51
+ """
52
+ if price < 0:
53
+ raise ValueError("价格不能为负数")
54
+
55
+ model = self.registry.get(name)
56
+ if not model:
57
+ return False
58
+
59
+ model.output_price = float(price)
60
+ self.registry.add_or_update(model)
61
+ return True
62
+
63
+ def update_prices(self, name: str, input_price: Optional[float] = None,
64
+ output_price: Optional[float] = None) -> bool:
65
+ """
66
+ 同时更新输入和输出价格
67
+
68
+ Args:
69
+ name: 模型名称
70
+ input_price: 新的输入价格(可选)
71
+ output_price: 新的输出价格(可选)
72
+
73
+ Returns:
74
+ bool: 是否成功更新
75
+
76
+ Raises:
77
+ ValueError: 如果任一价格为负数
78
+ """
79
+ if input_price is not None and input_price < 0:
80
+ raise ValueError("输入价格不能为负数")
81
+ if output_price is not None and output_price < 0:
82
+ raise ValueError("输出价格不能为负数")
83
+
84
+ model = self.registry.get(name)
85
+ if not model:
86
+ return False
87
+
88
+ updated = False
89
+ if input_price is not None:
90
+ model.input_price = float(input_price)
91
+ updated = True
92
+ if output_price is not None:
93
+ model.output_price = float(output_price)
94
+ updated = True
95
+
96
+ if updated:
97
+ self.registry.add_or_update(model)
98
+
99
+ return updated
100
+
101
+ def get_cost_estimate(self, name: str, input_tokens: int, output_tokens: int) -> Optional[float]:
102
+ """
103
+ 估算使用成本
104
+
105
+ Args:
106
+ name: 模型名称
107
+ input_tokens: 输入 token 数量
108
+ output_tokens: 输出 token 数量
109
+
110
+ Returns:
111
+ 估算的总成本(美元),如果模型不存在则返回 None
112
+ """
113
+ model = self.registry.get(name)
114
+ if not model:
115
+ return None
116
+
117
+ # 计算成本:价格单位是 美元/百万tokens
118
+ input_cost = (input_tokens / 1_000_000) * model.input_price
119
+ output_cost = (output_tokens / 1_000_000) * model.output_price
120
+
121
+ return input_cost + output_cost