auto-coder 0.1.286__tar.gz → 0.1.288__tar.gz

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 (197) hide show
  1. {auto_coder-0.1.286 → auto_coder-0.1.288}/PKG-INFO +1 -1
  2. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/auto_coder.egg-info/PKG-INFO +1 -1
  3. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/auto_coder.egg-info/SOURCES.txt +9 -0
  4. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/auto_coder.py +2 -2
  5. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/chat_auto_coder.py +265 -82
  6. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/chat_auto_coder_lang.py +9 -5
  7. auto_coder-0.1.288/src/autocoder/commands/auto_web.py +1062 -0
  8. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/__init__.py +1 -2
  9. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/anything2img.py +113 -43
  10. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/auto_coder_lang.py +27 -0
  11. auto_coder-0.1.288/src/autocoder/common/computer_use.py +931 -0
  12. auto_coder-0.1.288/src/autocoder/plugins/__init__.py +1123 -0
  13. auto_coder-0.1.288/src/autocoder/plugins/dynamic_completion_example.py +148 -0
  14. auto_coder-0.1.288/src/autocoder/plugins/git_helper_plugin.py +252 -0
  15. auto_coder-0.1.288/src/autocoder/plugins/sample_plugin.py +160 -0
  16. auto_coder-0.1.288/src/autocoder/plugins/token_helper_plugin.py +343 -0
  17. auto_coder-0.1.288/src/autocoder/plugins/utils.py +9 -0
  18. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/relevant_utils.py +1 -1
  19. auto_coder-0.1.288/src/autocoder/version.py +1 -0
  20. auto_coder-0.1.288/tests/test_plugins.py +459 -0
  21. auto_coder-0.1.286/src/autocoder/version.py +0 -1
  22. {auto_coder-0.1.286 → auto_coder-0.1.288}/LICENSE +0 -0
  23. {auto_coder-0.1.286 → auto_coder-0.1.288}/README.md +0 -0
  24. {auto_coder-0.1.286 → auto_coder-0.1.288}/setup.cfg +0 -0
  25. {auto_coder-0.1.286 → auto_coder-0.1.288}/setup.py +0 -0
  26. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/auto_coder.egg-info/dependency_links.txt +0 -0
  27. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/auto_coder.egg-info/entry_points.txt +0 -0
  28. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/auto_coder.egg-info/requires.txt +0 -0
  29. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/auto_coder.egg-info/top_level.txt +0 -0
  30. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/__init__.py +0 -0
  31. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/agent/__init__.py +0 -0
  32. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/agent/auto_demand_organizer.py +0 -0
  33. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/agent/auto_filegroup.py +0 -0
  34. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/agent/auto_guess_query.py +0 -0
  35. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/agent/auto_learn_from_commit.py +0 -0
  36. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/agent/auto_review_commit.py +0 -0
  37. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/agent/auto_tool.py +0 -0
  38. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/agent/coder.py +0 -0
  39. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/agent/designer.py +0 -0
  40. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/agent/planner.py +0 -0
  41. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/agent/project_reader.py +0 -0
  42. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/auto_coder_rag.py +0 -0
  43. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/auto_coder_rag_client_mcp.py +0 -0
  44. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/auto_coder_rag_mcp.py +0 -0
  45. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/auto_coder_runner.py +0 -0
  46. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/auto_coder_server.py +0 -0
  47. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/benchmark.py +0 -0
  48. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/chat/__init__.py +0 -0
  49. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/command_args.py +0 -0
  50. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/commands/__init__.py +0 -0
  51. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/commands/auto_command.py +0 -0
  52. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/commands/tools.py +0 -0
  53. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/JupyterClient.py +0 -0
  54. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/ShellClient.py +0 -0
  55. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/anything2images.py +0 -0
  56. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/audio.py +0 -0
  57. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/auto_configure.py +0 -0
  58. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/buildin_tokenizer.py +0 -0
  59. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/chunk_validation.py +0 -0
  60. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/cleaner.py +0 -0
  61. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/code_auto_execute.py +0 -0
  62. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/code_auto_generate.py +0 -0
  63. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/code_auto_generate_diff.py +0 -0
  64. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/code_auto_generate_editblock.py +0 -0
  65. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/code_auto_generate_strict_diff.py +0 -0
  66. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/code_auto_merge.py +0 -0
  67. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/code_auto_merge_diff.py +0 -0
  68. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/code_auto_merge_editblock.py +0 -0
  69. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/code_auto_merge_strict_diff.py +0 -0
  70. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/code_modification_ranker.py +0 -0
  71. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/command_completer.py +0 -0
  72. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/command_generator.py +0 -0
  73. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/command_templates.py +0 -0
  74. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/conf_import_export.py +0 -0
  75. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/conf_validator.py +0 -0
  76. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/const.py +0 -0
  77. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/context_pruner.py +0 -0
  78. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/conversation_pruner.py +0 -0
  79. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/files.py +0 -0
  80. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/git_utils.py +0 -0
  81. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/global_cancel.py +0 -0
  82. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/image_to_page.py +0 -0
  83. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/index_import_export.py +0 -0
  84. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/interpreter.py +0 -0
  85. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/llm_rerank.py +0 -0
  86. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/mcp_hub.py +0 -0
  87. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/mcp_server.py +0 -0
  88. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/mcp_servers/__init__.py +0 -0
  89. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/mcp_servers/mcp_server_perplexity.py +0 -0
  90. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/mcp_tools.py +0 -0
  91. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/memory_manager.py +0 -0
  92. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/model_speed_test.py +0 -0
  93. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/printer.py +0 -0
  94. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/recall_validation.py +0 -0
  95. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/result_manager.py +0 -0
  96. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/screenshots.py +0 -0
  97. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/search.py +0 -0
  98. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/search_replace.py +0 -0
  99. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/shells.py +0 -0
  100. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/stats_panel.py +0 -0
  101. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/sys_prompt.py +0 -0
  102. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/text.py +0 -0
  103. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/types.py +0 -0
  104. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/common/utils_code_auto_generate.py +0 -0
  105. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/data/byzerllm.md +0 -0
  106. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/data/tokenizer.json +0 -0
  107. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/db/__init__.py +0 -0
  108. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/db/store.py +0 -0
  109. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/dispacher/__init__.py +0 -0
  110. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/dispacher/actions/__init__.py +0 -0
  111. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/dispacher/actions/action.py +0 -0
  112. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/dispacher/actions/copilot.py +0 -0
  113. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/dispacher/actions/plugins/__init__.py +0 -0
  114. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/dispacher/actions/plugins/action_regex_project.py +0 -0
  115. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/dispacher/actions/plugins/action_translate.py +0 -0
  116. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/index/__init__.py +0 -0
  117. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/index/entry.py +0 -0
  118. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/index/filter/__init__.py +0 -0
  119. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/index/filter/normal_filter.py +0 -0
  120. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/index/filter/quick_filter.py +0 -0
  121. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/index/for_command.py +0 -0
  122. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/index/index.py +0 -0
  123. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/index/symbols_utils.py +0 -0
  124. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/index/types.py +0 -0
  125. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/lang.py +0 -0
  126. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/models.py +0 -0
  127. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/privacy/__init__.py +0 -0
  128. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/privacy/model_filter.py +0 -0
  129. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/pyproject/__init__.py +0 -0
  130. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/__init__.py +0 -0
  131. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/api_server.py +0 -0
  132. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/cache/__init__.py +0 -0
  133. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/cache/base_cache.py +0 -0
  134. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/cache/byzer_storage_cache.py +0 -0
  135. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/cache/file_monitor_cache.py +0 -0
  136. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/cache/local_byzer_storage_cache.py +0 -0
  137. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/cache/simple_cache.py +0 -0
  138. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/doc_filter.py +0 -0
  139. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/document_retriever.py +0 -0
  140. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/lang.py +0 -0
  141. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/llm_wrapper.py +0 -0
  142. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/loaders/__init__.py +0 -0
  143. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/loaders/docx_loader.py +0 -0
  144. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/loaders/excel_loader.py +0 -0
  145. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/loaders/pdf_loader.py +0 -0
  146. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/loaders/ppt_loader.py +0 -0
  147. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/long_context_rag.py +0 -0
  148. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/qa_conversation_strategy.py +0 -0
  149. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/rag_config.py +0 -0
  150. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/rag_entry.py +0 -0
  151. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/raw_rag.py +0 -0
  152. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/simple_directory_reader.py +0 -0
  153. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/simple_rag.py +0 -0
  154. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/stream_event/__init__.py +0 -0
  155. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/stream_event/event_writer.py +0 -0
  156. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/stream_event/types.py +0 -0
  157. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/token_checker.py +0 -0
  158. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/token_counter.py +0 -0
  159. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/token_limiter.py +0 -0
  160. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/token_limiter_utils.py +0 -0
  161. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/types.py +0 -0
  162. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/utils.py +0 -0
  163. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/rag/variable_holder.py +0 -0
  164. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/regexproject/__init__.py +0 -0
  165. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/suffixproject/__init__.py +0 -0
  166. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/tsproject/__init__.py +0 -0
  167. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/__init__.py +0 -0
  168. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/_markitdown.py +0 -0
  169. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/auto_coder_utils/__init__.py +0 -0
  170. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/auto_coder_utils/chat_stream_out.py +0 -0
  171. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/auto_project_type.py +0 -0
  172. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/chat_auto_coder_utils/__init__.py +0 -0
  173. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/conversation_store.py +0 -0
  174. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/llm_client_interceptors.py +0 -0
  175. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/llms.py +0 -0
  176. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/log_capture.py +0 -0
  177. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/model_provider_selector.py +0 -0
  178. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/multi_turn.py +0 -0
  179. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/operate_config_api.py +0 -0
  180. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/print_table.py +0 -0
  181. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/project_structure.py +0 -0
  182. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/queue_communicate.py +0 -0
  183. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/request_event_queue.py +0 -0
  184. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/request_queue.py +0 -0
  185. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/rest.py +0 -0
  186. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/stream_thinking.py +0 -0
  187. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/tests.py +0 -0
  188. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/thread_utils.py +0 -0
  189. {auto_coder-0.1.286 → auto_coder-0.1.288}/src/autocoder/utils/types.py +0 -0
  190. {auto_coder-0.1.286 → auto_coder-0.1.288}/tests/test_action_regex_project.py +0 -0
  191. {auto_coder-0.1.286 → auto_coder-0.1.288}/tests/test_chat_auto_coder.py +0 -0
  192. {auto_coder-0.1.286 → auto_coder-0.1.288}/tests/test_code_auto_merge_editblock.py +0 -0
  193. {auto_coder-0.1.286 → auto_coder-0.1.288}/tests/test_command_completer.py +0 -0
  194. {auto_coder-0.1.286 → auto_coder-0.1.288}/tests/test_planner.py +0 -0
  195. {auto_coder-0.1.286 → auto_coder-0.1.288}/tests/test_privacy.py +0 -0
  196. {auto_coder-0.1.286 → auto_coder-0.1.288}/tests/test_queue_communicate.py +0 -0
  197. {auto_coder-0.1.286 → auto_coder-0.1.288}/tests/test_symbols_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: auto-coder
3
- Version: 0.1.286
3
+ Version: 0.1.288
4
4
  Summary: AutoCoder: AutoCoder
5
5
  Author: allwefantasy
6
6
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: auto-coder
3
- Version: 0.1.286
3
+ Version: 0.1.288
4
4
  Summary: AutoCoder: AutoCoder
5
5
  Author: allwefantasy
6
6
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
@@ -35,6 +35,7 @@ src/autocoder/agent/project_reader.py
35
35
  src/autocoder/chat/__init__.py
36
36
  src/autocoder/commands/__init__.py
37
37
  src/autocoder/commands/auto_command.py
38
+ src/autocoder/commands/auto_web.py
38
39
  src/autocoder/commands/tools.py
39
40
  src/autocoder/common/JupyterClient.py
40
41
  src/autocoder/common/ShellClient.py
@@ -60,6 +61,7 @@ src/autocoder/common/code_modification_ranker.py
60
61
  src/autocoder/common/command_completer.py
61
62
  src/autocoder/common/command_generator.py
62
63
  src/autocoder/common/command_templates.py
64
+ src/autocoder/common/computer_use.py
63
65
  src/autocoder/common/conf_import_export.py
64
66
  src/autocoder/common/conf_validator.py
65
67
  src/autocoder/common/const.py
@@ -111,6 +113,12 @@ src/autocoder/index/types.py
111
113
  src/autocoder/index/filter/__init__.py
112
114
  src/autocoder/index/filter/normal_filter.py
113
115
  src/autocoder/index/filter/quick_filter.py
116
+ src/autocoder/plugins/__init__.py
117
+ src/autocoder/plugins/dynamic_completion_example.py
118
+ src/autocoder/plugins/git_helper_plugin.py
119
+ src/autocoder/plugins/sample_plugin.py
120
+ src/autocoder/plugins/token_helper_plugin.py
121
+ src/autocoder/plugins/utils.py
114
122
  src/autocoder/privacy/__init__.py
115
123
  src/autocoder/privacy/model_filter.py
116
124
  src/autocoder/pyproject/__init__.py
@@ -180,6 +188,7 @@ tests/test_chat_auto_coder.py
180
188
  tests/test_code_auto_merge_editblock.py
181
189
  tests/test_command_completer.py
182
190
  tests/test_planner.py
191
+ tests/test_plugins.py
183
192
  tests/test_privacy.py
184
193
  tests/test_queue_communicate.py
185
194
  tests/test_symbols_utils.py
@@ -1321,8 +1321,8 @@ def main(input_args: Optional[List[str]] = None):
1321
1321
  args.enable_rag_context = False
1322
1322
  rag = RAGFactory.get_rag(llm=chat_llm, args=args, path="")
1323
1323
  response = rag.stream_chat_oai(
1324
- conversations=[{"role": "user", "content": args.query}])[0]
1325
- v = ([item, None] for item in response)
1324
+ conversations=loaded_conversations)[0]
1325
+ v = (item for item in response)
1326
1326
 
1327
1327
  elif "mcp" in args.action:
1328
1328
  from autocoder.common.mcp_server import get_mcp_server, McpRequest, McpInstallRequest, McpRemoveRequest, McpListRequest, McpListRunningRequest, McpRefreshRequest
@@ -1,5 +1,3 @@
1
-
2
-
3
1
  import argparse
4
2
  import os
5
3
  from prompt_toolkit import PromptSession
@@ -10,13 +8,15 @@ from prompt_toolkit.styles import Style
10
8
  from autocoder.version import __version__
11
9
  from autocoder.chat_auto_coder_lang import get_message
12
10
  from prompt_toolkit.formatted_text import FormattedText
11
+ from prompt_toolkit.completion import Completer, Completion
12
+ from autocoder.plugins import PluginManager
13
13
  from autocoder.auto_coder_runner import (
14
14
  auto_command,
15
15
  load_memory,
16
16
  save_memory,
17
- configure,
17
+ configure,
18
18
  manage_models,
19
- print_conf,
19
+ print_conf,
20
20
  exclude_dirs,
21
21
  exclude_files,
22
22
  ask,
@@ -35,23 +35,36 @@ from autocoder.auto_coder_runner import (
35
35
  mcp,
36
36
  revert,
37
37
  commit,
38
- design,
38
+ design,
39
39
  voice_input,
40
40
  chat,
41
41
  gen_and_exec_shell_command,
42
42
  execute_shell_command,
43
43
  get_mcp_server,
44
44
  completer,
45
- summon,
46
- get_memory
45
+ summon,
46
+ get_memory,
47
47
  )
48
48
 
49
+ # Create a global plugin manager
50
+ plugin_manager = PluginManager()
51
+
52
+ # Create wrapped versions of intercepted functions
53
+ original_functions = {
54
+ "ask": ask,
55
+ "coding": coding,
56
+ "chat": chat,
57
+ "design": design,
58
+ "voice_input": voice_input,
59
+ "auto_command": auto_command,
60
+ "execute_shell_command": execute_shell_command,
61
+ }
62
+
63
+
49
64
  def parse_arguments():
50
-
51
65
 
52
66
  parser = argparse.ArgumentParser(description="Chat Auto Coder")
53
- parser.add_argument("--debug", action="store_true",
54
- help="Enable debug mode")
67
+ parser.add_argument("--debug", action="store_true", help="Enable debug mode")
55
68
  parser.add_argument(
56
69
  "--quick",
57
70
  action="store_true",
@@ -103,10 +116,8 @@ def show_help():
103
116
  print(
104
117
  f" \033[94m/summon\033[0m \033[93m<query>\033[0m - \033[92m{get_message('summon_desc')}\033[0m"
105
118
  )
106
- print(
107
- f" \033[94m/revert\033[0m - \033[92m{get_message('revert_desc')}\033[0m")
108
- print(
109
- f" \033[94m/commit\033[0m - \033[92m{get_message('commit_desc')}\033[0m")
119
+ print(f" \033[94m/revert\033[0m - \033[92m{get_message('revert_desc')}\033[0m")
120
+ print(f" \033[94m/commit\033[0m - \033[92m{get_message('commit_desc')}\033[0m")
110
121
  print(
111
122
  f" \033[94m/conf\033[0m \033[93m<key>:<value>\033[0m - \033[92m{get_message('conf_desc')}\033[0m"
112
123
  )
@@ -119,8 +130,7 @@ def show_help():
119
130
  print(
120
131
  f" \033[94m/list_files\033[0m - \033[92m{get_message('list_files_desc')}\033[0m"
121
132
  )
122
- print(
123
- f" \033[94m/help\033[0m - \033[92m{get_message('help_desc')}\033[0m")
133
+ print(f" \033[94m/help\033[0m - \033[92m{get_message('help_desc')}\033[0m")
124
134
  print(
125
135
  f" \033[94m/exclude_dirs\033[0m \033[93m<dir1>,<dir2> ...\033[0m - \033[92m{get_message('exclude_dirs_desc')}\033[0m"
126
136
  )
@@ -130,14 +140,120 @@ def show_help():
130
140
  print(
131
141
  f" \033[94m/voice_input\033[0m - \033[92m{get_message('voice_input_desc')}\033[0m"
132
142
  )
133
- print(
134
- f" \033[94m/mode\033[0m - \033[92m{get_message('mode_desc')}\033[0m")
143
+ print(f" \033[94m/mode\033[0m - \033[92m{get_message('mode_desc')}\033[0m")
135
144
  print(f" \033[94m/lib\033[0m - \033[92m{get_message('lib_desc')}\033[0m")
136
145
  print(f" \033[94m/models\033[0m - \033[92m{get_message('models_desc')}\033[0m")
137
- print(
138
- f" \033[94m/exit\033[0m - \033[92m{get_message('exit_desc')}\033[0m")
146
+ print(f" \033[94m/plugins\033[0m - \033[92m{get_message('plugins_desc')}\033[0m")
147
+ print(f" \033[94m/exit\033[0m - \033[92m{get_message('exit_desc')}\033[0m")
139
148
  print()
140
149
 
150
+ # 显示插件命令
151
+ if plugin_manager.command_handlers:
152
+ print("\033[1mPlugin Commands:\033[0m")
153
+ print(" \033[94mCommand\033[0m - \033[93mDescription\033[0m")
154
+ for cmd, (_, desc, plugin_id) in plugin_manager.command_handlers.items():
155
+ plugin = plugin_manager.get_plugin(plugin_id)
156
+ print(
157
+ f" \033[94m{cmd}\033[0m - \033[92m{desc} (from {plugin.plugin_name()})\033[0m"
158
+ )
159
+ print()
160
+
161
+
162
+ class EnhancedCompleter(Completer):
163
+ """结合内置补全器和插件补全功能的增强补全器"""
164
+
165
+ def __init__(self, base_completer: Completer, plugin_manager: PluginManager):
166
+ self.base_completer: Completer = base_completer
167
+ self.plugin_manager: PluginManager = plugin_manager
168
+
169
+ def get_completions(self, document, complete_event):
170
+ # 获取当前输入的文本
171
+ text_before_cursor = document.text_before_cursor.lstrip()
172
+
173
+ # 只有当我们需要处理命令补全时才进行处理
174
+ if text_before_cursor.startswith("/"):
175
+
176
+ # 获取当前输入的命令前缀
177
+ current_input = text_before_cursor
178
+ # 检查是否需要动态补全
179
+ if " " in current_input:
180
+ # 将连续的空格替换为单个空格
181
+ _input_one_space = " ".join(current_input.split())
182
+ # 先尝试动态补全特定命令
183
+ dynamic_cmds = self.plugin_manager.get_dynamic_cmds()
184
+ for dynamic_cmd in dynamic_cmds:
185
+ if _input_one_space.startswith(dynamic_cmd):
186
+ # 使用 PluginManager 处理动态补全,通常是用于命令或子命令动态的参数值列表的补全
187
+ completions = self.plugin_manager.process_dynamic_completions(
188
+ dynamic_cmd, current_input
189
+ )
190
+ for completion_text, display_text in completions:
191
+ yield Completion(
192
+ completion_text,
193
+ start_position=0,
194
+ display=display_text,
195
+ )
196
+ return
197
+
198
+ # 如果不是特定命令,检查一般命令 + 空格的情况, 通常是用于固定的下级子命令列表的补全
199
+ cmd_parts = current_input.split(maxsplit=1)
200
+ base_cmd = cmd_parts[0]
201
+
202
+ # 获取插件命令补全
203
+ plugin_completions_dict = self.plugin_manager.get_plugin_completions()
204
+
205
+ # 如果命令存在于补全字典中,进行处理
206
+ if base_cmd in plugin_completions_dict:
207
+ yield from self._process_command_completions(
208
+ base_cmd, current_input, plugin_completions_dict[base_cmd]
209
+ )
210
+ return
211
+ # 处理直接命令补全 - 如果输入不包含空格,匹配整个命令
212
+ for command in self.plugin_manager.get_all_commands_with_prefix(current_input):
213
+ yield Completion(
214
+ command[len(current_input) :],
215
+ start_position=0,
216
+ display=command,
217
+ )
218
+
219
+ # 获取并返回基础补全器的补全
220
+ if self.base_completer:
221
+ for completion in self.base_completer.get_completions(
222
+ document, complete_event
223
+ ):
224
+ yield completion
225
+
226
+ def _process_command_completions(self, command, current_input, completions):
227
+ """处理通用命令补全"""
228
+ # 提取子命令前缀
229
+ parts = current_input.split(maxsplit=1)
230
+ cmd_prefix = ""
231
+ if len(parts) > 1:
232
+ cmd_prefix = parts[1].strip()
233
+
234
+ # 对于任何命令,当子命令前缀为空或与补全选项匹配时,都显示补全
235
+ for completion in completions:
236
+ if cmd_prefix == "" or completion.startswith(cmd_prefix):
237
+ # 只提供未输入部分作为补全
238
+ remaining_text = completion[len(cmd_prefix) :]
239
+ # 修复:设置 start_position 为 0,这样不会覆盖用户已输入的部分
240
+ start_position = 0
241
+ yield Completion(
242
+ remaining_text,
243
+ start_position=start_position,
244
+ display=completion,
245
+ )
246
+
247
+ async def get_completions_async(self, document, complete_event):
248
+ """异步获取补全内容。
249
+
250
+ 这个方法在最新版本的prompt_toolkit中是必需的,
251
+ 它简单地调用同步版本并以异步方式yield结果。
252
+ """
253
+ for completion in self.get_completions(document, complete_event):
254
+ yield completion
255
+
256
+
141
257
  ARGS = None
142
258
 
143
259
 
@@ -150,20 +266,30 @@ def main():
150
266
  ARGS.product_mode = "lite"
151
267
 
152
268
  if ARGS.pro:
153
- ARGS.product_mode = "pro"
154
-
155
- if not ARGS.quick:
156
- initialize_system(InitializeSystemRequest(
157
- product_mode=ARGS.product_mode,
158
- skip_provider_selection=ARGS.skip_provider_selection,
159
- debug=ARGS.debug,
160
- quick=ARGS.quick,
161
- lite=ARGS.lite,
162
- pro=ARGS.pro
163
- ))
269
+ ARGS.product_mode = "pro"
270
+
271
+ if not ARGS.quick:
272
+ initialize_system(
273
+ InitializeSystemRequest(
274
+ product_mode=ARGS.product_mode,
275
+ skip_provider_selection=ARGS.skip_provider_selection,
276
+ debug=ARGS.debug,
277
+ quick=ARGS.quick,
278
+ lite=ARGS.lite,
279
+ pro=ARGS.pro,
280
+ )
281
+ )
282
+
283
+ # Initialize plugin system
284
+ # Add default plugin directory into global plugin dirs
285
+ plugin_manager.load_global_plugin_dirs()
286
+ plugin_manager.add_global_plugin_directory(os.path.join(os.path.dirname(__file__), "plugins"))
287
+
288
+ # 加载保存的运行时配置
289
+ plugin_manager.load_runtime_cfg()
164
290
 
165
291
  load_memory()
166
- memory = get_memory()
292
+ memory = get_memory()
167
293
 
168
294
  configure(f"product_mode:{ARGS.product_mode}")
169
295
 
@@ -218,6 +344,9 @@ def main():
218
344
  configure(f"human_as_model:{new_status}", skip_print=True)
219
345
  event.app.invalidate()
220
346
 
347
+ # 应用插件的键盘绑定
348
+ plugin_manager.apply_keybindings(kb)
349
+
221
350
  def get_bottom_toolbar():
222
351
  if "mode" not in memory:
223
352
  memory["mode"] = "auto_detect"
@@ -225,17 +354,25 @@ def main():
225
354
  human_as_model = memory["conf"].get("human_as_model", "false")
226
355
  if mode not in MODES:
227
356
  mode = "auto_detect"
228
- pwd = os.getcwd()
357
+ pwd = os.getcwd()
229
358
  pwd_parts = pwd.split(os.sep)
230
359
  if len(pwd_parts) > 3:
231
360
  pwd = os.sep.join(pwd_parts[-3:])
232
- return f"Current Dir: {pwd} \nMode: {MODES[mode]}(ctrl+k) | Human as Model: {human_as_model}(ctrl+n) "
361
+
362
+ # Add plugin information to toolbar
363
+ plugin_info = (
364
+ f"Plugins: {len(plugin_manager.plugins)}" if plugin_manager.plugins else ""
365
+ )
366
+ return f"Current Dir: {pwd} \nMode: {MODES[mode]}(ctrl+k) | Human as Model: {human_as_model}(ctrl+n) | {plugin_info}"
367
+
368
+ # 创建一个继承Completer的增强补全器
369
+ enhanced_completer = EnhancedCompleter(completer, plugin_manager)
233
370
 
234
371
  session = PromptSession(
235
372
  history=InMemoryHistory(),
236
373
  auto_suggest=AutoSuggestFromHistory(),
237
374
  enable_history_search=False,
238
- completer=completer,
375
+ completer=enhanced_completer,
239
376
  complete_while_typing=True,
240
377
  key_bindings=kb,
241
378
  bottom_toolbar=get_bottom_toolbar,
@@ -251,6 +388,14 @@ def main():
251
388
  \033[0m"""
252
389
  )
253
390
  print("\033[1;34mType /help to see available commands.\033[0m\n")
391
+
392
+ # Add plugin information to startup message
393
+ if plugin_manager.plugins:
394
+ print("\033[1;34mLoaded Plugins:\033[0m")
395
+ for name, plugin in plugin_manager.plugins.items():
396
+ print(f" - {name} (v{plugin.version}): {plugin.description}")
397
+ print()
398
+
254
399
  show_help()
255
400
 
256
401
  style = Style.from_dict(
@@ -265,6 +410,25 @@ def main():
265
410
 
266
411
  new_prompt = ""
267
412
 
413
+ # Create wrapped versions of functions that plugins want to intercept
414
+ wrapped_functions = {}
415
+ for func_name, original_func in original_functions.items():
416
+ wrapped_functions[func_name] = plugin_manager.wrap_function(
417
+ original_func, func_name
418
+ )
419
+
420
+ # Replace original functions with wrapped versions
421
+ global ask, coding, chat, design, voice_input, auto_command, execute_shell_command
422
+ ask = wrapped_functions.get("ask", ask)
423
+ coding = wrapped_functions.get("coding", coding)
424
+ chat = wrapped_functions.get("chat", chat)
425
+ design = wrapped_functions.get("design", design)
426
+ voice_input = wrapped_functions.get("voice_input", voice_input)
427
+ auto_command = wrapped_functions.get("auto_command", auto_command)
428
+ execute_shell_command = wrapped_functions.get(
429
+ "execute_shell_command", execute_shell_command
430
+ )
431
+
268
432
  while True:
269
433
  try:
270
434
  prompt_message = [
@@ -281,8 +445,7 @@ def main():
281
445
  FormattedText(prompt_message), default=new_prompt, style=style
282
446
  )
283
447
  else:
284
- user_input = session.prompt(
285
- FormattedText(prompt_message), style=style)
448
+ user_input = session.prompt(FormattedText(prompt_message), style=style)
286
449
  new_prompt = ""
287
450
 
288
451
  if "mode" not in memory:
@@ -291,78 +454,96 @@ def main():
291
454
  # 处理 user_input 的空格
292
455
  if user_input:
293
456
  temp_user_input = user_input.lstrip() # 去掉左侧空格
294
- if temp_user_input.startswith('/'):
457
+ if temp_user_input.startswith("/"):
295
458
  user_input = temp_user_input
296
459
 
297
- if (
298
- memory["mode"] == "auto_detect"
460
+ # Check if this is a plugin command
461
+ if user_input.startswith("/"):
462
+ plugin_result = plugin_manager.process_command(user_input)
463
+ if plugin_result:
464
+ plugin_name, handler, args = plugin_result
465
+ if handler:
466
+ handler(*args)
467
+ continue
468
+
469
+ if (
470
+ memory["mode"] == "auto_detect"
299
471
  and user_input
300
472
  and not user_input.startswith("/")
301
473
  ):
302
- auto_command(ARGS,user_input)
474
+ auto_command(ARGS, user_input)
303
475
 
304
476
  elif memory["mode"] == "voice_input" and not user_input.startswith("/"):
305
477
  text = voice_input()
306
- new_prompt = "/coding " + text
478
+ if text: # Check if text is not None
479
+ new_prompt = "/coding " + text
307
480
 
308
481
  elif user_input.startswith("/voice_input"):
309
482
  text = voice_input()
310
- new_prompt = "/coding " + text
483
+ if text: # Check if text is not None
484
+ new_prompt = "/coding " + text
311
485
 
312
486
  elif user_input.startswith("/clear") or user_input.startswith("/cls"):
313
487
  print("\033c")
314
488
 
315
489
  elif user_input.startswith("/add_files"):
316
- args = user_input[len("/add_files"):].strip().split()
490
+ args = user_input[len("/add_files") :].strip().split()
317
491
  add_files(args)
318
492
  elif user_input.startswith("/remove_files"):
319
- file_names = user_input[len(
320
- "/remove_files"):].strip().split(",")
493
+ file_names = user_input[len("/remove_files") :].strip().split(",")
321
494
  remove_files(file_names)
322
495
  elif user_input.startswith("/index/query"):
323
- query = user_input[len("/index/query"):].strip()
496
+ query = user_input[len("/index/query") :].strip()
324
497
  index_query(query)
325
498
 
326
499
  elif user_input.startswith("/index/build"):
327
500
  index_build()
328
501
 
329
502
  elif user_input.startswith("/index/export"):
330
- export_path = user_input[len("/index/export"):].strip()
331
- index_export(export_path)
503
+ export_path = user_input[len("/index/export") :].strip()
504
+ index_export(export_path)
332
505
 
333
506
  elif user_input.startswith("/index/import"):
334
- import_path = user_input[len("/index/import"):].strip()
335
- index_import(import_path)
507
+ import_path = user_input[len("/index/import") :].strip()
508
+ index_import(import_path)
336
509
 
337
510
  elif user_input.startswith("/list_files"):
338
511
  list_files()
339
512
 
340
513
  elif user_input.startswith("/models"):
341
- query = user_input[len("/models"):].strip()
514
+ query = user_input[len("/models") :].strip()
342
515
  if not query:
343
516
  print("Please enter your query.")
344
517
  else:
345
- manage_models(query)
518
+ manage_models(query)
346
519
 
347
520
  elif user_input.startswith("/mode"):
348
- conf = user_input[len("/mode"):].strip()
521
+ conf = user_input[len("/mode") :].strip()
349
522
  if not conf:
350
523
  print(memory["mode"])
351
524
  else:
352
- memory["mode"] = conf
353
-
525
+ memory["mode"] = conf
526
+
354
527
  elif user_input.startswith("/conf/export"):
355
528
  from autocoder.common.conf_import_export import export_conf
356
- export_path = user_input[len("/conf/export"):].strip()
357
- export_conf(os.getcwd(), export_path)
358
-
529
+
530
+ export_path = user_input[len("/conf/export") :].strip()
531
+ export_conf(os.getcwd(), export_path)
532
+
359
533
  elif user_input.startswith("/conf/import"):
360
534
  from autocoder.common.conf_import_export import import_conf
361
- import_path = user_input[len("/conf/import"):].strip()
362
- import_conf(os.getcwd(), import_path)
363
-
535
+
536
+ import_path = user_input[len("/conf/import") :].strip()
537
+ import_conf(os.getcwd(), import_path)
538
+
539
+ elif user_input.startswith("/plugins"):
540
+ # 提取命令参数并交由 plugin_manager 处理
541
+ args = user_input[len("/plugins") :].strip().split()
542
+ result = plugin_manager.handle_plugins_command(args)
543
+ print(result, end="")
544
+
364
545
  elif user_input.startswith("/conf"):
365
- conf = user_input[len("/conf"):].strip()
546
+ conf = user_input[len("/conf") :].strip()
366
547
  if not conf:
367
548
  print_conf(memory["conf"])
368
549
  else:
@@ -370,26 +551,25 @@ def main():
370
551
  elif user_input.startswith("/revert"):
371
552
  revert()
372
553
  elif user_input.startswith("/commit"):
373
- query = user_input[len("/commit"):].strip()
554
+ query = user_input[len("/commit") :].strip()
374
555
  commit(query)
375
556
  elif user_input.startswith("/help"):
376
- query = user_input[len("/help"):].strip()
557
+ query = user_input[len("/help") :].strip()
377
558
  if not query:
378
559
  show_help()
379
560
  else:
380
561
  help(query)
381
562
 
382
563
  elif user_input.startswith("/exclude_dirs"):
383
- dir_names = user_input[len(
384
- "/exclude_dirs"):].strip().split(",")
564
+ dir_names = user_input[len("/exclude_dirs") :].strip().split(",")
385
565
  exclude_dirs(dir_names)
386
566
 
387
567
  elif user_input.startswith("/exclude_files"):
388
- query = user_input[len("/exclude_files"):].strip()
568
+ query = user_input[len("/exclude_files") :].strip()
389
569
  exclude_files(query)
390
570
 
391
571
  elif user_input.startswith("/ask"):
392
- query = user_input[len("/ask"):].strip()
572
+ query = user_input[len("/ask") :].strip()
393
573
  if not query:
394
574
  print("Please enter your question.")
395
575
  else:
@@ -399,64 +579,64 @@ def main():
399
579
  raise EOFError()
400
580
 
401
581
  elif user_input.startswith("/coding"):
402
- query = user_input[len("/coding"):].strip()
582
+ query = user_input[len("/coding") :].strip()
403
583
  if not query:
404
584
  print("\033[91mPlease enter your request.\033[0m")
405
585
  continue
406
586
  coding(query)
407
587
  elif user_input.startswith("/chat"):
408
- query = user_input[len("/chat"):].strip()
588
+ query = user_input[len("/chat") :].strip()
409
589
  if not query:
410
590
  print("\033[91mPlease enter your request.\033[0m")
411
591
  else:
412
592
  chat(query)
413
593
 
414
594
  elif user_input.startswith("/design"):
415
- query = user_input[len("/design"):].strip()
595
+ query = user_input[len("/design") :].strip()
416
596
  if not query:
417
597
  print("\033[91mPlease enter your design request.\033[0m")
418
598
  else:
419
599
  design(query)
420
600
 
421
601
  elif user_input.startswith("/summon"):
422
- query = user_input[len("/summon"):].strip()
602
+ query = user_input[len("/summon") :].strip()
423
603
  if not query:
424
604
  print("\033[91mPlease enter your request.\033[0m")
425
605
  else:
426
606
  summon(query)
427
607
 
428
608
  elif user_input.startswith("/lib"):
429
- args = user_input[len("/lib"):].strip().split()
609
+ args = user_input[len("/lib") :].strip().split()
430
610
  lib_command(args)
431
611
 
432
612
  elif user_input.startswith("/mcp"):
433
- query = user_input[len("/mcp"):].strip()
613
+ query = user_input[len("/mcp") :].strip()
434
614
  if not query:
435
615
  print("Please enter your query.")
436
616
  else:
437
617
  mcp(query)
438
618
 
439
619
  elif user_input.startswith("/auto"):
440
- query = user_input[len("/auto"):].strip()
441
- auto_command(ARGS,query)
620
+ query = user_input[len("/auto") :].strip()
621
+ auto_command(ARGS, query)
442
622
  elif user_input.startswith("/debug"):
443
- code = user_input[len("/debug"):].strip()
623
+ code = user_input[len("/debug") :].strip()
444
624
  try:
445
625
  result = eval(code)
446
626
  print(f"Debug result: {result}")
447
627
  except Exception as e:
448
- print(f"Debug error: {str(e)}")
628
+ print(f"Debug error: {str(e)}")
449
629
 
450
630
  # elif user_input.startswith("/shell"):
451
631
  else:
452
632
  command = user_input
453
- if user_input.startswith("/shell"):
454
- command = user_input[len("/shell"):].strip()
633
+ if user_input.startswith("/shell"):
634
+ command = user_input[len("/shell") :].strip()
455
635
  if not command:
456
636
  print("Please enter a shell command to execute.")
457
637
  else:
458
638
  if command.startswith("/chat"):
459
- command = command[len("/chat"):].strip()
639
+ command = command[len("/chat") :].strip()
460
640
  gen_and_exec_shell_command(command)
461
641
  else:
462
642
  execute_shell_command(command)
@@ -465,6 +645,9 @@ def main():
465
645
  continue
466
646
  except EOFError:
467
647
  try:
648
+ # Shutdown all plugins before exiting
649
+ plugin_manager.shutdown_all()
650
+
468
651
  save_memory()
469
652
  try:
470
653
  if get_mcp_server():