auto-coder 0.1.289__tar.gz → 0.1.290__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 (202) hide show
  1. {auto_coder-0.1.289 → auto_coder-0.1.290}/PKG-INFO +2 -2
  2. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/auto_coder.egg-info/PKG-INFO +2 -2
  3. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/auto_coder.egg-info/SOURCES.txt +3 -0
  4. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/auto_coder.egg-info/requires.txt +1 -1
  5. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/auto_coder_rag.py +10 -0
  6. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/__init__.py +4 -0
  7. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/api_server.py +48 -0
  8. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/cache/byzer_storage_cache.py +254 -44
  9. auto_coder-0.1.290/src/autocoder/rag/cache/cache_result_merge.py +265 -0
  10. auto_coder-0.1.290/src/autocoder/rag/cache/file_monitor_cache.py +259 -0
  11. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/cache/local_byzer_storage_cache.py +286 -58
  12. auto_coder-0.1.290/src/autocoder/rag/cache/rag_file_meta.py +494 -0
  13. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/cache/simple_cache.py +67 -3
  14. auto_coder-0.1.290/src/autocoder/rag/conversation_to_queries.py +139 -0
  15. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/long_context_rag.py +9 -3
  16. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/qa_conversation_strategy.py +21 -10
  17. auto_coder-0.1.290/src/autocoder/version.py +1 -0
  18. auto_coder-0.1.289/src/autocoder/rag/cache/file_monitor_cache.py +0 -146
  19. auto_coder-0.1.289/src/autocoder/version.py +0 -1
  20. {auto_coder-0.1.289 → auto_coder-0.1.290}/LICENSE +0 -0
  21. {auto_coder-0.1.289 → auto_coder-0.1.290}/README.md +0 -0
  22. {auto_coder-0.1.289 → auto_coder-0.1.290}/setup.cfg +0 -0
  23. {auto_coder-0.1.289 → auto_coder-0.1.290}/setup.py +0 -0
  24. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/auto_coder.egg-info/dependency_links.txt +0 -0
  25. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/auto_coder.egg-info/entry_points.txt +0 -0
  26. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/auto_coder.egg-info/top_level.txt +0 -0
  27. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/__init__.py +0 -0
  28. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/agent/__init__.py +0 -0
  29. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/agent/auto_demand_organizer.py +0 -0
  30. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/agent/auto_filegroup.py +0 -0
  31. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/agent/auto_guess_query.py +0 -0
  32. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/agent/auto_learn_from_commit.py +0 -0
  33. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/agent/auto_review_commit.py +0 -0
  34. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/agent/auto_tool.py +0 -0
  35. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/agent/coder.py +0 -0
  36. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/agent/designer.py +0 -0
  37. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/agent/planner.py +0 -0
  38. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/agent/project_reader.py +0 -0
  39. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/auto_coder.py +0 -0
  40. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/auto_coder_rag_client_mcp.py +0 -0
  41. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/auto_coder_rag_mcp.py +0 -0
  42. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/auto_coder_runner.py +0 -0
  43. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/auto_coder_server.py +0 -0
  44. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/benchmark.py +0 -0
  45. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/chat/__init__.py +0 -0
  46. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/chat_auto_coder.py +0 -0
  47. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/chat_auto_coder_lang.py +0 -0
  48. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/command_args.py +0 -0
  49. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/commands/__init__.py +0 -0
  50. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/commands/auto_command.py +0 -0
  51. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/commands/auto_web.py +0 -0
  52. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/commands/tools.py +0 -0
  53. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/JupyterClient.py +0 -0
  54. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/ShellClient.py +0 -0
  55. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/anything2images.py +0 -0
  56. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/anything2img.py +0 -0
  57. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/audio.py +0 -0
  58. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/auto_coder_lang.py +0 -0
  59. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/auto_configure.py +0 -0
  60. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/buildin_tokenizer.py +0 -0
  61. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/chunk_validation.py +0 -0
  62. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/cleaner.py +0 -0
  63. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/code_auto_execute.py +0 -0
  64. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/code_auto_generate.py +0 -0
  65. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/code_auto_generate_diff.py +0 -0
  66. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/code_auto_generate_editblock.py +0 -0
  67. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/code_auto_generate_strict_diff.py +0 -0
  68. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/code_auto_merge.py +0 -0
  69. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/code_auto_merge_diff.py +0 -0
  70. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/code_auto_merge_editblock.py +0 -0
  71. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/code_auto_merge_strict_diff.py +0 -0
  72. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/code_modification_ranker.py +0 -0
  73. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/command_completer.py +0 -0
  74. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/command_generator.py +0 -0
  75. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/command_templates.py +0 -0
  76. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/computer_use.py +0 -0
  77. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/conf_import_export.py +0 -0
  78. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/conf_validator.py +0 -0
  79. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/const.py +0 -0
  80. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/context_pruner.py +0 -0
  81. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/conversation_pruner.py +0 -0
  82. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/files.py +0 -0
  83. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/git_utils.py +0 -0
  84. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/global_cancel.py +0 -0
  85. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/image_to_page.py +0 -0
  86. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/index_import_export.py +0 -0
  87. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/interpreter.py +0 -0
  88. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/llm_rerank.py +0 -0
  89. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/mcp_hub.py +0 -0
  90. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/mcp_server.py +0 -0
  91. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/mcp_servers/__init__.py +0 -0
  92. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/mcp_servers/mcp_server_perplexity.py +0 -0
  93. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/mcp_tools.py +0 -0
  94. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/memory_manager.py +0 -0
  95. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/model_speed_test.py +0 -0
  96. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/printer.py +0 -0
  97. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/recall_validation.py +0 -0
  98. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/result_manager.py +0 -0
  99. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/screenshots.py +0 -0
  100. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/search.py +0 -0
  101. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/search_replace.py +0 -0
  102. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/shells.py +0 -0
  103. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/stats_panel.py +0 -0
  104. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/sys_prompt.py +0 -0
  105. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/text.py +0 -0
  106. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/types.py +0 -0
  107. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/common/utils_code_auto_generate.py +0 -0
  108. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/data/byzerllm.md +0 -0
  109. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/data/tokenizer.json +0 -0
  110. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/db/__init__.py +0 -0
  111. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/db/store.py +0 -0
  112. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/dispacher/__init__.py +0 -0
  113. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/dispacher/actions/__init__.py +0 -0
  114. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/dispacher/actions/action.py +0 -0
  115. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/dispacher/actions/copilot.py +0 -0
  116. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/dispacher/actions/plugins/__init__.py +0 -0
  117. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/dispacher/actions/plugins/action_regex_project.py +0 -0
  118. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/dispacher/actions/plugins/action_translate.py +0 -0
  119. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/index/__init__.py +0 -0
  120. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/index/entry.py +0 -0
  121. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/index/filter/__init__.py +0 -0
  122. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/index/filter/normal_filter.py +0 -0
  123. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/index/filter/quick_filter.py +0 -0
  124. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/index/for_command.py +0 -0
  125. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/index/index.py +0 -0
  126. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/index/symbols_utils.py +0 -0
  127. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/index/types.py +0 -0
  128. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/lang.py +0 -0
  129. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/models.py +0 -0
  130. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/plugins/__init__.py +0 -0
  131. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/plugins/dynamic_completion_example.py +0 -0
  132. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/plugins/git_helper_plugin.py +0 -0
  133. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/plugins/sample_plugin.py +0 -0
  134. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/plugins/token_helper_plugin.py +0 -0
  135. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/plugins/utils.py +0 -0
  136. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/privacy/__init__.py +0 -0
  137. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/privacy/model_filter.py +0 -0
  138. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/pyproject/__init__.py +0 -0
  139. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/__init__.py +0 -0
  140. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/cache/__init__.py +0 -0
  141. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/cache/base_cache.py +0 -0
  142. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/doc_filter.py +0 -0
  143. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/document_retriever.py +0 -0
  144. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/lang.py +0 -0
  145. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/llm_wrapper.py +0 -0
  146. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/loaders/__init__.py +0 -0
  147. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/loaders/docx_loader.py +0 -0
  148. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/loaders/excel_loader.py +0 -0
  149. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/loaders/pdf_loader.py +0 -0
  150. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/loaders/ppt_loader.py +0 -0
  151. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/rag_config.py +0 -0
  152. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/rag_entry.py +0 -0
  153. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/raw_rag.py +0 -0
  154. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/relevant_utils.py +0 -0
  155. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/searchable.py +0 -0
  156. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/simple_directory_reader.py +0 -0
  157. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/simple_rag.py +0 -0
  158. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/stream_event/__init__.py +0 -0
  159. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/stream_event/event_writer.py +0 -0
  160. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/stream_event/types.py +0 -0
  161. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/token_checker.py +0 -0
  162. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/token_counter.py +0 -0
  163. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/token_limiter.py +0 -0
  164. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/token_limiter_utils.py +0 -0
  165. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/types.py +0 -0
  166. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/utils.py +0 -0
  167. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/rag/variable_holder.py +0 -0
  168. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/regexproject/__init__.py +0 -0
  169. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/suffixproject/__init__.py +0 -0
  170. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/tsproject/__init__.py +0 -0
  171. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/__init__.py +0 -0
  172. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/_markitdown.py +0 -0
  173. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/auto_coder_utils/__init__.py +0 -0
  174. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/auto_coder_utils/chat_stream_out.py +0 -0
  175. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/auto_project_type.py +0 -0
  176. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/chat_auto_coder_utils/__init__.py +0 -0
  177. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/conversation_store.py +0 -0
  178. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/llm_client_interceptors.py +0 -0
  179. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/llms.py +0 -0
  180. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/log_capture.py +0 -0
  181. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/model_provider_selector.py +0 -0
  182. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/multi_turn.py +0 -0
  183. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/operate_config_api.py +0 -0
  184. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/print_table.py +0 -0
  185. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/project_structure.py +0 -0
  186. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/queue_communicate.py +0 -0
  187. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/request_event_queue.py +0 -0
  188. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/request_queue.py +0 -0
  189. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/rest.py +0 -0
  190. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/stream_thinking.py +0 -0
  191. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/tests.py +0 -0
  192. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/thread_utils.py +0 -0
  193. {auto_coder-0.1.289 → auto_coder-0.1.290}/src/autocoder/utils/types.py +0 -0
  194. {auto_coder-0.1.289 → auto_coder-0.1.290}/tests/test_action_regex_project.py +0 -0
  195. {auto_coder-0.1.289 → auto_coder-0.1.290}/tests/test_chat_auto_coder.py +0 -0
  196. {auto_coder-0.1.289 → auto_coder-0.1.290}/tests/test_code_auto_merge_editblock.py +0 -0
  197. {auto_coder-0.1.289 → auto_coder-0.1.290}/tests/test_command_completer.py +0 -0
  198. {auto_coder-0.1.289 → auto_coder-0.1.290}/tests/test_planner.py +0 -0
  199. {auto_coder-0.1.289 → auto_coder-0.1.290}/tests/test_plugins.py +0 -0
  200. {auto_coder-0.1.289 → auto_coder-0.1.290}/tests/test_privacy.py +0 -0
  201. {auto_coder-0.1.289 → auto_coder-0.1.290}/tests/test_queue_communicate.py +0 -0
  202. {auto_coder-0.1.289 → auto_coder-0.1.290}/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.289
3
+ Version: 0.1.290
4
4
  Summary: AutoCoder: AutoCoder
5
5
  Author: allwefantasy
6
6
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
@@ -26,7 +26,7 @@ Requires-Dist: tabulate
26
26
  Requires-Dist: jupyter_client
27
27
  Requires-Dist: prompt-toolkit
28
28
  Requires-Dist: tokenizers
29
- Requires-Dist: byzerllm[saas]>=0.1.171
29
+ Requires-Dist: byzerllm[saas]>=0.1.174
30
30
  Requires-Dist: patch
31
31
  Requires-Dist: diff_match_patch
32
32
  Requires-Dist: GitPython
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: auto-coder
3
- Version: 0.1.289
3
+ Version: 0.1.290
4
4
  Summary: AutoCoder: AutoCoder
5
5
  Author: allwefantasy
6
6
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
@@ -26,7 +26,7 @@ Requires-Dist: tabulate
26
26
  Requires-Dist: jupyter_client
27
27
  Requires-Dist: prompt-toolkit
28
28
  Requires-Dist: tokenizers
29
- Requires-Dist: byzerllm[saas]>=0.1.171
29
+ Requires-Dist: byzerllm[saas]>=0.1.174
30
30
  Requires-Dist: patch
31
31
  Requires-Dist: diff_match_patch
32
32
  Requires-Dist: GitPython
@@ -124,6 +124,7 @@ src/autocoder/privacy/model_filter.py
124
124
  src/autocoder/pyproject/__init__.py
125
125
  src/autocoder/rag/__init__.py
126
126
  src/autocoder/rag/api_server.py
127
+ src/autocoder/rag/conversation_to_queries.py
127
128
  src/autocoder/rag/doc_filter.py
128
129
  src/autocoder/rag/document_retriever.py
129
130
  src/autocoder/rag/lang.py
@@ -147,8 +148,10 @@ src/autocoder/rag/variable_holder.py
147
148
  src/autocoder/rag/cache/__init__.py
148
149
  src/autocoder/rag/cache/base_cache.py
149
150
  src/autocoder/rag/cache/byzer_storage_cache.py
151
+ src/autocoder/rag/cache/cache_result_merge.py
150
152
  src/autocoder/rag/cache/file_monitor_cache.py
151
153
  src/autocoder/rag/cache/local_byzer_storage_cache.py
154
+ src/autocoder/rag/cache/rag_file_meta.py
152
155
  src/autocoder/rag/cache/simple_cache.py
153
156
  src/autocoder/rag/loaders/__init__.py
154
157
  src/autocoder/rag/loaders/docx_loader.py
@@ -16,7 +16,7 @@ tabulate
16
16
  jupyter_client
17
17
  prompt-toolkit
18
18
  tokenizers
19
- byzerllm[saas]>=0.1.171
19
+ byzerllm[saas]>=0.1.174
20
20
  patch
21
21
  diff_match_patch
22
22
  GitPython
@@ -262,6 +262,7 @@ def main(input_args: Optional[List[str]] = None):
262
262
  serve_parser.add_argument("--source_dir", default=".", help="")
263
263
  serve_parser.add_argument("--host", default="", help="")
264
264
  serve_parser.add_argument("--port", type=int, default=8000, help="")
265
+ serve_parser.add_argument("--workers", type=int, default=4, help="")
265
266
  serve_parser.add_argument("--uvicorn_log_level", default="info", help="")
266
267
  serve_parser.add_argument("--allow_credentials", action="store_true", help="")
267
268
  serve_parser.add_argument("--allowed_origins", default=["*"], help="")
@@ -274,6 +275,7 @@ def main(input_args: Optional[List[str]] = None):
274
275
  serve_parser.add_argument("--ssl_certfile", default="", help="")
275
276
  serve_parser.add_argument("--response_role", default="assistant", help="")
276
277
  serve_parser.add_argument("--doc_dir", default="", help="")
278
+ serve_parser.add_argument("--enable_local_image_host", action="store_true", help=" enable local image host for local Chat app")
277
279
  serve_parser.add_argument("--tokenizer_path", default=tokenizer_path, help="")
278
280
  serve_parser.add_argument(
279
281
  "--collections", default="", help="Collection name for indexing"
@@ -516,6 +518,14 @@ def main(input_args: Optional[List[str]] = None):
516
518
  if hasattr(args, arg)
517
519
  }
518
520
  )
521
+ # 设置本地图床的地址
522
+ if args.enable_local_image_host:
523
+ host = server_args.host or "127.0.0.1"
524
+ if host == "0.0.0.0":
525
+ host = "127.0.0.1"
526
+ port = str(server_args.port)
527
+ auto_coder_args.local_image_host = f"{host}:{port}"
528
+
519
529
 
520
530
  # Generate unique name for RAG build if doc_dir exists
521
531
  if server_args.doc_dir:
@@ -296,6 +296,10 @@ class AutoCoderArgs(pydantic.BaseModel):
296
296
  rag_params_max_tokens: Optional[int] = 4096
297
297
  rag_doc_filter_relevance: Optional[int] = 5
298
298
  rag_context_window_limit: Optional[int] = 120000
299
+ # rag 本地图床地址
300
+ local_image_host: Optional[str] = ""
301
+ rag_recall_max_queries: Optional[int] = 5
302
+
299
303
 
300
304
  # 回答用户问题时,使用哪种对话历史策略
301
305
  # single_round: 单轮对话
@@ -1,10 +1,14 @@
1
1
  import os
2
2
  import time
3
+ import aiofiles
3
4
  import uvicorn
4
5
  from fastapi import Request
5
6
  from fastapi import FastAPI
6
7
  from fastapi.middleware.cors import CORSMiddleware
7
8
  from fastapi.responses import JSONResponse, StreamingResponse, Response
9
+ from fastapi import HTTPException
10
+ import mimetypes
11
+ from urllib.parse import unquote
8
12
 
9
13
  from byzerllm.log import init_logger
10
14
  from byzerllm.utils import random_uuid
@@ -165,9 +169,52 @@ async def embed(body: EmbeddingCompletionRequest):
165
169
  id=embedding_id
166
170
  )
167
171
 
172
+ @router_app.get("/static/{full_path:path}")
173
+ async def serve_image(full_path: str, request: Request):
174
+
175
+ allowed_file_type = ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp']
176
+
177
+ if any(full_path.endswith(ext) for ext in allowed_file_type):
178
+ try:
179
+ # 获取文件的完整路径,并进行URL解码
180
+ file_path = unquote(full_path)
181
+ # 使用 os.path.normpath 来标准化路径,自动处理不同操作系统的路径分隔符
182
+ file_path = os.path.normpath(file_path)
183
+ if not os.path.isabs(file_path):
184
+ file_path = os.path.join("/", file_path)
185
+
186
+ # 检查文件是否存在
187
+ if not os.path.exists(file_path):
188
+ raise FileNotFoundError(f"File not found: {file_path}")
189
+
190
+ # 异步读取文件内容
191
+ async with aiofiles.open(file_path, "rb") as f:
192
+ content = await f.read()
193
+
194
+ # 获取文件的 MIME 类型
195
+ content_type = mimetypes.guess_type(file_path)[0]
196
+ if not content_type:
197
+ content_type = "application/octet-stream"
198
+
199
+ # 返回文件内容
200
+ return Response(content=content, media_type=content_type)
201
+ except FileNotFoundError as e:
202
+ logger.error(f"Image not found: {str(e)}")
203
+ raise HTTPException(status_code=404, detail=f"Image not found: {str(e)}")
204
+ except PermissionError as e:
205
+ logger.error(f"Permission denied: {str(e)}")
206
+ raise HTTPException(status_code=403, detail=f"Permission denied: {str(e)}")
207
+ except Exception as e:
208
+ logger.error(f"Error serving image: {str(e)}")
209
+ raise HTTPException(status_code=500, detail=f"Error serving image: {str(e)}")
210
+
211
+ # 如果路径中没有图片, 返回 404
212
+ raise HTTPException(status_code=404, detail="Only images are supported")
213
+
168
214
  class ServerArgs(BaseModel):
169
215
  host: str = None
170
216
  port: int = 8000
217
+ workers: int = 4
171
218
  uvicorn_log_level: str = "info"
172
219
  allow_credentials: bool = False
173
220
  allowed_origins: List[str] = ["*"]
@@ -227,6 +274,7 @@ def serve(llm:ByzerLLM, args: ServerArgs):
227
274
  prompt_template=args.prompt_template
228
275
  )
229
276
 
277
+ # 如果使用workers>1或reload=True,必须使用导入字符串而不是应用实例
230
278
  uvicorn.run(
231
279
  router_app,
232
280
  host=args.host,
@@ -28,6 +28,8 @@ import platform
28
28
  import hashlib
29
29
  from typing import Union
30
30
  from pydantic import BaseModel
31
+ from autocoder.rag.cache.cache_result_merge import CacheResultMerger, MergeStrategy
32
+ import time
31
33
 
32
34
  if platform.system() != "Windows":
33
35
  import fcntl
@@ -64,6 +66,69 @@ class ByzerStorageCache(BaseCacheManager):
64
66
  required_exts,
65
67
  extra_params: Optional[AutoCoderArgs] = None,
66
68
  ):
69
+ """
70
+ 初始化基于云端 Byzer Storage 的 RAG 缓存管理器。
71
+
72
+ 参数:
73
+ path: 需要索引的代码库根目录
74
+ ignore_spec: 指定哪些文件/目录应被忽略的规则
75
+ required_exts: 需要处理的文件扩展名列表
76
+ extra_params: 额外的配置参数,包含向量索引相关设置
77
+
78
+ 缓存结构 (self.cache):
79
+ self.cache 是一个字典,键为文件路径,值为 CacheItem 对象:
80
+ {
81
+ "file_path1": CacheItem(
82
+ file_path: str, # 文件的绝对路径
83
+ relative_path: str, # 相对于项目根目录的路径
84
+ content: List[Dict], # 文件内容的结构化表示,每个元素是 SourceCode 对象的序列化
85
+ modify_time: float, # 文件最后修改时间的时间戳
86
+ md5: str # 文件内容的 MD5 哈希值,用于检测变更
87
+ ),
88
+ "file_path2": CacheItem(...),
89
+ ...
90
+ }
91
+
92
+ 这个缓存有两层存储:
93
+ 1. 本地文件缓存: 保存在项目根目录的 .cache/byzer_storage_speedup.jsonl 文件中
94
+ - 用于跟踪文件变更和快速加载
95
+ - 使用 JSONL 格式存储,每行是一个 CacheItem 的 JSON 表示
96
+
97
+ 2. 云端 Byzer Storage 向量数据库:
98
+ - 存储文件内容的分块和向量嵌入
99
+ - 每个文件被分割成大小为 chunk_size 的文本块
100
+ - 每个块都会生成向量嵌入,用于语义搜索
101
+ - 存储结构包含: 文件路径、内容块、原始内容、向量嵌入、修改时间
102
+
103
+ 源代码处理流程:
104
+ 在缓存更新过程中使用了两个关键函数:
105
+
106
+ 1. process_file_in_multi_process: 在多进程环境中处理文件
107
+ - 参数: file_info (文件信息元组)
108
+ - 返回值: List[SourceCode] 或 None
109
+ - 用途: 在初始构建缓存时并行处理多个文件
110
+
111
+ 2. process_file_local: 在当前进程中处理单个文件
112
+ - 参数: file_path (文件路径)
113
+ - 返回值: List[SourceCode] 或 None
114
+ - 用途: 在检测到文件更新时处理单个文件
115
+
116
+ 文件处理后,会:
117
+ 1. 更新内存中的缓存 (self.cache)
118
+ 2. 将缓存持久化到本地文件
119
+ 3. 将内容分块并更新到 Byzer Storage 向量数据库
120
+
121
+ 更新机制:
122
+ - 通过单独的线程异步处理文件变更
123
+ - 使用 MD5 哈希值检测文件是否发生变化
124
+ - 支持文件添加、更新和删除事件
125
+ - 使用向量数据库进行语义检索,支持相似度搜索
126
+
127
+ 与 LocalByzerStorageCache 的区别:
128
+ - 使用云端 ByzerStorage 而非本地存储
129
+ - 适用于需要远程访问和共享索引的场景
130
+ - 支持大规模分布式检索和更高级的查询功能
131
+ """
67
132
  self.path = path
68
133
  self.ignore_spec = ignore_spec
69
134
  self.required_exts = required_exts
@@ -185,7 +250,7 @@ class ByzerStorageCache(BaseCacheManager):
185
250
 
186
251
  def build_cache(self):
187
252
  """Build the cache by reading files and storing in Byzer Storage"""
188
- logger.info(f"Building cache for path: {self.path}")
253
+ logger.info(f"[BUILD CACHE] Starting cache build for path: {self.path}")
189
254
 
190
255
  files_to_process = []
191
256
  for file_info in self.get_all_files():
@@ -195,11 +260,15 @@ class ByzerStorageCache(BaseCacheManager):
195
260
  ):
196
261
  files_to_process.append(file_info)
197
262
 
263
+ logger.info(f"[BUILD CACHE] Found {len(files_to_process)} files to process")
198
264
  if not files_to_process:
265
+ logger.info("[BUILD CACHE] No files to process, cache build completed")
199
266
  return
200
267
 
201
268
  from autocoder.rag.token_counter import initialize_tokenizer
202
269
 
270
+ logger.info("[BUILD CACHE] Starting parallel file processing...")
271
+ start_time = time.time()
203
272
  with Pool(
204
273
  processes=os.cpu_count(),
205
274
  initializer=initialize_tokenizer,
@@ -209,6 +278,8 @@ class ByzerStorageCache(BaseCacheManager):
209
278
  for file_info in files_to_process:
210
279
  target_files_to_process.append(self.fileinfo_to_tuple(file_info))
211
280
  results = pool.map(process_file_in_multi_process, target_files_to_process)
281
+ processing_time = time.time() - start_time
282
+ logger.info(f"[BUILD CACHE] File processing completed, time elapsed: {processing_time:.2f}s")
212
283
 
213
284
  items = []
214
285
  for file_info, result in zip(files_to_process, results):
@@ -222,109 +293,176 @@ class ByzerStorageCache(BaseCacheManager):
222
293
  )
223
294
 
224
295
  for doc in content:
225
- logger.info(f"Processing file: {doc.module_name}")
296
+ logger.info(f"[BUILD CACHE] Processing file: {doc.module_name}")
226
297
  doc.module_name
227
298
  chunks = self._chunk_text(doc.source_code, self.chunk_size)
299
+ logger.info(f"[BUILD CACHE] File {doc.module_name} chunking completed, total chunks: {len(chunks)}")
228
300
  for chunk_idx, chunk in enumerate(chunks):
229
301
  chunk_item = {
230
302
  "_id": f"{doc.module_name}_{chunk_idx}",
231
303
  "file_path": file_info.file_path,
232
- "content": chunk,
233
- "raw_content": chunk,
234
- "vector": chunk,
304
+ "content": chunk[0:self.chunk_size*2],
305
+ "raw_content": chunk[0:self.chunk_size*2],
306
+ "vector": chunk[0:self.chunk_size*2],
235
307
  "mtime": file_info.modify_time,
236
308
  }
237
309
  items.append(chunk_item)
238
310
 
239
311
  # Save to local cache
240
- logger.info("Saving cache to local file")
312
+ logger.info("[BUILD CACHE] Saving cache to local file")
241
313
  self.write_cache()
242
314
 
243
315
  if items:
244
- logger.info("Clear cache from Byzer Storage")
316
+ logger.info("[BUILD CACHE] Clearing existing cache from Byzer Storage")
245
317
  self.storage.truncate_table()
246
- logger.info("Save new cache to Byzer Storage")
247
- max_workers = 5
248
- chunk_size = max(1, len(items) // max_workers)
249
- item_chunks = [items[i:i + chunk_size] for i in range(0, len(items), chunk_size)]
318
+ logger.info(f"[BUILD CACHE] Preparing to write to Byzer Storage, total chunks: {len(items)}, total files: {len(files_to_process)}")
319
+
320
+ # Use a fixed optimal batch size instead of dividing by worker count
321
+ batch_size = 100 # Optimal batch size for Byzer Storage
322
+ item_batches = [items[i:i + batch_size] for i in range(0, len(items), batch_size)]
250
323
 
251
- total_chunks = len(item_chunks)
252
- completed_chunks = 0
324
+ total_batches = len(item_batches)
325
+ completed_batches = 0
253
326
 
254
- logger.info(f"Progress: {0}/{total_chunks} chunks completed")
327
+ logger.info(f"[BUILD CACHE] Starting to write to Byzer Storage using {batch_size} items per batch, "
328
+ f"total batches: {total_batches}")
329
+ start_time = time.time()
330
+
331
+ # Use more workers to process the smaller batches efficiently
332
+ max_workers = min(10, total_batches) # Cap at 10 workers or total batch count
333
+ logger.info(f"[BUILD CACHE] Using {max_workers} parallel workers for processing")
255
334
 
256
335
  with ThreadPoolExecutor(max_workers=max_workers) as executor:
257
336
  futures = []
258
- for chunk in item_chunks:
337
+ # Submit all batches to the executor upfront (non-blocking)
338
+ for batch in item_batches:
259
339
  futures.append(
260
340
  executor.submit(
261
341
  lambda x: self.storage.write_builder().add_items(
262
342
  x, vector_fields=["vector"], search_fields=["content"]
263
343
  ).execute(),
264
- chunk
344
+ batch
265
345
  )
266
346
  )
267
- # Wait for all futures to complete
347
+ # Wait for futures to complete
268
348
  for future in as_completed(futures):
269
349
  try:
270
350
  future.result()
271
- completed_chunks += 1
272
- logger.info(f"Progress: {completed_chunks}/{total_chunks} chunks completed")
351
+ completed_batches += 1
352
+ elapsed = time.time() - start_time
353
+ estimated_total = elapsed / completed_batches * total_batches if completed_batches > 0 else 0
354
+ remaining = estimated_total - elapsed
355
+
356
+ # Only log progress at reasonable intervals to reduce log spam
357
+ if completed_batches == 1 or completed_batches == total_batches or completed_batches % max(1, total_batches // 10) == 0:
358
+ logger.info(
359
+ f"[BUILD CACHE] Progress: {completed_batches}/{total_batches} batches completed "
360
+ f"({(completed_batches/total_batches*100):.1f}%) "
361
+ f"Estimated time remaining: {remaining:.1f}s"
362
+ )
273
363
  except Exception as e:
274
- logger.error(f"Error in saving chunk: {str(e)}")
364
+ logger.error(f"[BUILD CACHE] Error saving batch: {str(e)}")
365
+ # Add more detailed error information
366
+ logger.error(f"[BUILD CACHE] Error details: batch size: {len(batch) if 'batch' in locals() else 'unknown'}")
275
367
 
368
+ total_time = time.time() - start_time
369
+ logger.info(f"[BUILD CACHE] All chunks written, total time: {total_time:.2f}s")
276
370
  self.storage.commit()
371
+ logger.info("[BUILD CACHE] Changes committed to Byzer Storage")
277
372
 
278
373
  def update_storage(self, file_info: FileInfo, is_delete: bool):
374
+ """
375
+ Updates file content in the Byzer Storage vector database.
376
+
377
+ Parameters:
378
+ file_info: FileInfo object containing file path, relative path, modify time, and MD5 hash
379
+ is_delete: Whether this is a delete operation, True means all records for this file will be removed
380
+ """
381
+ logger.info(f"[UPDATE STORAGE] Starting update for file: {file_info.file_path}, is delete: {is_delete}")
382
+
279
383
  query = self.storage.query_builder()
280
384
  query.and_filter().add_condition("file_path", file_info.file_path).build()
281
385
  results = query.execute()
282
386
  if results:
387
+ logger.info(f"[UPDATE STORAGE] Deleting existing records from Byzer Storage: {len(results)} records")
283
388
  for result in results:
284
389
  self.storage.delete_by_ids([result["_id"]])
285
390
  items = []
286
391
 
287
392
  if not is_delete:
393
+ logger.info(f"[UPDATE STORAGE] Getting file content from cache and preparing update")
288
394
  content = [
289
395
  SourceCode.model_validate(doc)
290
396
  for doc in self.cache[file_info.file_path].content
291
397
  ]
292
398
  modify_time = self.cache[file_info.file_path].modify_time
293
399
  for doc in content:
294
- logger.info(f"Processing file: {doc.module_name}")
400
+ logger.info(f"[UPDATE STORAGE] Processing file: {doc.module_name}")
295
401
  doc.module_name
296
402
  chunks = self._chunk_text(doc.source_code, self.chunk_size)
403
+ logger.info(f"[UPDATE STORAGE] File {doc.module_name} chunking completed, total chunks: {len(chunks)}")
297
404
  for chunk_idx, chunk in enumerate(chunks):
298
405
  chunk_item = {
299
406
  "_id": f"{doc.module_name}_{chunk_idx}",
300
407
  "file_path": file_info.file_path,
301
- "content": chunk,
302
- "raw_content": chunk,
303
- "vector": chunk,
408
+ "content": chunk[0:self.chunk_size*2],
409
+ "raw_content": chunk[0:self.chunk_size*2],
410
+ "vector": chunk[0:self.chunk_size*2],
304
411
  "mtime": modify_time,
305
412
  }
306
413
  items.append(chunk_item)
307
414
  if items:
308
- self.storage.write_builder().add_items(
309
- items, vector_fields=["vector"], search_fields=["content"]
310
- ).execute()
415
+ logger.info(f"[UPDATE STORAGE] Starting to write {len(items)} chunks to Byzer Storage")
416
+ start_time = time.time()
417
+
418
+ # Use optimal batch size for larger updates
419
+ batch_size = 100
420
+ if len(items) > batch_size:
421
+ logger.info(f"[UPDATE STORAGE] Using batched writes with {batch_size} items per batch")
422
+ batches = [items[i:i + batch_size] for i in range(0, len(items), batch_size)]
423
+ total_batches = len(batches)
424
+
425
+ for i, batch in enumerate(batches):
426
+ self.storage.write_builder().add_items(
427
+ batch, vector_fields=["vector"], search_fields=["content"]
428
+ ).execute()
429
+ logger.info(f"[UPDATE STORAGE] Progress: {i+1}/{total_batches} batches written")
430
+ else:
431
+ # For small item counts, just use a single write operation
432
+ self.storage.write_builder().add_items(
433
+ items, vector_fields=["vector"], search_fields=["content"]
434
+ ).execute()
435
+
311
436
  self.storage.commit()
437
+ elapsed = time.time() - start_time
438
+ logger.info(f"[UPDATE STORAGE] Write completed, time elapsed: {elapsed:.2f}s")
439
+ else:
440
+ logger.info(f"[UPDATE STORAGE] No content to write")
312
441
 
313
442
  def process_queue(self):
443
+ if not self.queue:
444
+ logger.info("[QUEUE PROCESSING] Queue is empty, nothing to process")
445
+ return
446
+
447
+ logger.info(f"[QUEUE PROCESSING] Starting queue processing, queue length: {len(self.queue)}")
448
+ start_time = time.time()
449
+
314
450
  while self.queue:
315
451
  file_list = self.queue.pop(0)
316
452
  if isinstance(file_list, DeleteEvent):
453
+ logger.info(f"[QUEUE PROCESSING] Processing delete event, total files: {len(file_list.file_paths)}")
317
454
  for item in file_list.file_paths:
318
- logger.info(f"{item} is detected to be removed")
455
+ logger.info(f"[QUEUE PROCESSING] Processing file deletion: {item}")
319
456
  del self.cache[item]
320
- # 创建一个临时的 FileInfo 对象
457
+ # Create a temporary FileInfo object
321
458
  file_info = FileInfo(file_path=item, relative_path="", modify_time=0, file_md5="")
322
459
  self.update_storage(file_info, is_delete=True)
323
460
 
324
461
  elif isinstance(file_list, AddOrUpdateEvent):
462
+ logger.info(f"[QUEUE PROCESSING] Processing add/update event, total files: {len(file_list.file_infos)}")
325
463
  for file_info in file_list.file_infos:
326
- logger.info(f"{file_info.file_path} is detected to be updated")
327
- # 处理文件并创建 CacheItem
464
+ logger.info(f"[QUEUE PROCESSING] Processing file update: {file_info.file_path}")
465
+ # Process file and create CacheItem
328
466
  content = process_file_local(self.fileinfo_to_tuple(file_info))
329
467
  self.cache[file_info.file_path] = CacheItem(
330
468
  file_path=file_info.file_path,
@@ -335,9 +473,14 @@ class ByzerStorageCache(BaseCacheManager):
335
473
  )
336
474
  self.update_storage(file_info, is_delete=False)
337
475
  self.write_cache()
476
+
477
+ elapsed = time.time() - start_time
478
+ logger.info(f"[QUEUE PROCESSING] Queue processing completed, time elapsed: {elapsed:.2f}s")
338
479
 
339
480
  def trigger_update(self):
340
- logger.info("检查文件是否有更新.....")
481
+ logger.info("[TRIGGER UPDATE] Starting file update check...")
482
+ start_time = time.time()
483
+
341
484
  files_to_process = []
342
485
  current_files = set()
343
486
  for file_info in self.get_all_files():
@@ -349,26 +492,26 @@ class ByzerStorageCache(BaseCacheManager):
349
492
  files_to_process.append(file_info)
350
493
 
351
494
  deleted_files = set(self.cache.keys()) - current_files
352
- logger.info(f"files_to_process: {files_to_process}")
353
- logger.info(f"deleted_files: {deleted_files}")
495
+
496
+ logger.info(f"[TRIGGER UPDATE] Files to process: {len(files_to_process)}")
497
+ logger.info(f"[TRIGGER UPDATE] Files deleted: {len(deleted_files)}")
498
+
354
499
  if deleted_files:
500
+ logger.info(f"[TRIGGER UPDATE] Adding delete event to queue")
355
501
  with self.lock:
356
502
  self.queue.append(DeleteEvent(file_paths=deleted_files))
357
503
  if files_to_process:
504
+ logger.info(f"[TRIGGER UPDATE] Adding update event to queue")
358
505
  with self.lock:
359
506
  self.queue.append(AddOrUpdateEvent(file_infos=files_to_process))
507
+
508
+ elapsed = time.time() - start_time
509
+ logger.info(f"[TRIGGER UPDATE] Check completed, time elapsed: {elapsed:.2f}s")
360
510
 
361
- def get_cache(self, options: Dict[str, Any]) -> Dict[str, Dict]:
511
+ def get_single_cache(self, query: str,options: Dict[str, Any]) -> Dict[str, Dict]:
362
512
  """Search cached documents using query"""
363
-
364
- self.trigger_update()
365
-
366
- if options is None or "query" not in options:
367
- return {file_path: self.cache[file_path].model_dump() for file_path in self.cache}
368
-
369
- query = options.get("query", "")
370
513
  total_tokens = 0
371
-
514
+ logger.info(f"查询缓存 query: {query}")
372
515
  # Build query with both vector search and text search
373
516
  query_builder = self.storage.query_builder()
374
517
  query_builder.set_limit(100000)
@@ -383,6 +526,14 @@ class ByzerStorageCache(BaseCacheManager):
383
526
 
384
527
  results = query_builder.execute()
385
528
 
529
+ return results
530
+
531
+
532
+ def _process_search_results(self, results):
533
+ """处理搜索结果,提取文件路径并构建结果字典"""
534
+ # 记录被处理的总tokens数
535
+ total_tokens = 0
536
+
386
537
  # Group results by file_path and reconstruct documents while preserving order
387
538
  # 这里还可以有排序优化,综合考虑一篇内容出现的次数以及排序位置
388
539
  file_paths = []
@@ -400,11 +551,70 @@ class ByzerStorageCache(BaseCacheManager):
400
551
  cached_data = self.cache[file_path]
401
552
  for doc in cached_data.content:
402
553
  if total_tokens + doc["tokens"] > self.max_output_tokens:
554
+ logger.info(f"用户tokens设置为:{self.max_output_tokens},累计tokens: {total_tokens} 当前文件: {file_path} tokens: {doc['tokens']},数据条数变化: {len(results)} -> {len(result)}")
403
555
  return result
404
556
  total_tokens += doc["tokens"]
405
557
  result[file_path] = cached_data.model_dump()
406
-
558
+
559
+ logger.info(f"用户tokens设置为:{self.max_output_tokens},累计tokens: {total_tokens},数据条数变化: {len(results)} -> {len(result)}")
407
560
  return result
561
+
562
+
563
+ def get_cache(self, options: Dict[str, Any]) -> Dict[str, Dict]:
564
+ """
565
+ 获取缓存中的文档信息
566
+
567
+ 如果options中包含query,则根据query搜索;否则返回所有缓存
568
+ """
569
+ # options是一个词典,词典的key是搜索参数,value是具体值
570
+
571
+ # 触发更新
572
+ self.trigger_update()
573
+
574
+ if options is None or "queries" not in options:
575
+ return {file_path: self.cache[file_path].model_dump() for file_path in self.cache}
576
+
577
+ queries = options.get("queries", [])
578
+
579
+ # 如果没有查询或只有一个查询,使用原来的方法
580
+ if not queries:
581
+ return {file_path: self.cache[file_path].model_dump() for file_path in self.cache}
582
+ elif len(queries) == 1:
583
+ results = self.get_single_cache(queries[0], options)
584
+ return self._process_search_results(results)
585
+
586
+ # 获取合并策略
587
+ merge_strategy_name = options.get("merge_strategy", MergeStrategy.WEIGHTED_RANK.value)
588
+ try:
589
+ merge_strategy = MergeStrategy(merge_strategy_name)
590
+ except ValueError:
591
+ logger.warning(f"未知的合并策略: {merge_strategy_name},使用默认策略")
592
+ merge_strategy = MergeStrategy.WEIGHTED_RANK
593
+
594
+ # 限制最大结果数
595
+ max_results = options.get("max_results", None)
596
+ merger = CacheResultMerger(max_results=max_results)
597
+
598
+ # 并发处理多个查询
599
+ query_results = []
600
+ with ThreadPoolExecutor(max_workers=min(len(queries), 10)) as executor:
601
+ future_to_query = {executor.submit(self.get_single_cache, query, options): query for query in queries}
602
+ for future in as_completed(future_to_query):
603
+ query = future_to_query[future]
604
+ try:
605
+ query_result = future.result()
606
+ logger.info(f"查询 '{query}' 返回 {len(query_result)} 条结果")
607
+ query_results.append((query, query_result))
608
+ except Exception as e:
609
+ logger.error(f"处理查询 '{query}' 时出错: {str(e)}")
610
+
611
+ logger.info(f"所有查询共返回 {sum(len(r) for _, r in query_results)} 条结果")
612
+ logger.info(f"使用合并策略: {merge_strategy}")
613
+
614
+ # 使用策略合并结果
615
+ merged_results = merger.merge(query_results, strategy=merge_strategy)
616
+
617
+ return self._process_search_results(merged_results)
408
618
 
409
619
 
410
620