auto-coder 0.1.280__tar.gz → 0.1.281__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 (186) hide show
  1. {auto_coder-0.1.280 → auto_coder-0.1.281}/PKG-INFO +1 -1
  2. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/auto_coder.egg-info/PKG-INFO +1 -1
  3. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/auto_coder.py +2 -1
  4. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/context_pruner.py +168 -206
  5. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/index/entry.py +1 -1
  6. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/long_context_rag.py +1 -0
  7. auto_coder-0.1.281/src/autocoder/version.py +1 -0
  8. auto_coder-0.1.280/src/autocoder/version.py +0 -1
  9. {auto_coder-0.1.280 → auto_coder-0.1.281}/LICENSE +0 -0
  10. {auto_coder-0.1.280 → auto_coder-0.1.281}/README.md +0 -0
  11. {auto_coder-0.1.280 → auto_coder-0.1.281}/setup.cfg +0 -0
  12. {auto_coder-0.1.280 → auto_coder-0.1.281}/setup.py +0 -0
  13. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/auto_coder.egg-info/SOURCES.txt +0 -0
  14. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/auto_coder.egg-info/dependency_links.txt +0 -0
  15. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/auto_coder.egg-info/entry_points.txt +0 -0
  16. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/auto_coder.egg-info/requires.txt +0 -0
  17. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/auto_coder.egg-info/top_level.txt +0 -0
  18. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/__init__.py +0 -0
  19. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/agent/__init__.py +0 -0
  20. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/agent/auto_demand_organizer.py +0 -0
  21. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/agent/auto_filegroup.py +0 -0
  22. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/agent/auto_guess_query.py +0 -0
  23. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/agent/auto_learn_from_commit.py +0 -0
  24. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/agent/auto_review_commit.py +0 -0
  25. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/agent/auto_tool.py +0 -0
  26. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/agent/coder.py +0 -0
  27. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/agent/designer.py +0 -0
  28. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/agent/planner.py +0 -0
  29. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/agent/project_reader.py +0 -0
  30. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/auto_coder_rag.py +0 -0
  31. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/auto_coder_rag_client_mcp.py +0 -0
  32. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/auto_coder_rag_mcp.py +0 -0
  33. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/auto_coder_runner.py +0 -0
  34. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/auto_coder_server.py +0 -0
  35. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/benchmark.py +0 -0
  36. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/chat/__init__.py +0 -0
  37. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/chat_auto_coder.py +0 -0
  38. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/chat_auto_coder_lang.py +0 -0
  39. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/command_args.py +0 -0
  40. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/commands/__init__.py +0 -0
  41. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/commands/auto_command.py +0 -0
  42. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/commands/tools.py +0 -0
  43. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/JupyterClient.py +0 -0
  44. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/ShellClient.py +0 -0
  45. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/__init__.py +0 -0
  46. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/anything2images.py +0 -0
  47. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/anything2img.py +0 -0
  48. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/audio.py +0 -0
  49. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/auto_coder_lang.py +0 -0
  50. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/auto_configure.py +0 -0
  51. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/buildin_tokenizer.py +0 -0
  52. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/chunk_validation.py +0 -0
  53. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/cleaner.py +0 -0
  54. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/code_auto_execute.py +0 -0
  55. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/code_auto_generate.py +0 -0
  56. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/code_auto_generate_diff.py +0 -0
  57. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/code_auto_generate_editblock.py +0 -0
  58. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/code_auto_generate_strict_diff.py +0 -0
  59. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/code_auto_merge.py +0 -0
  60. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/code_auto_merge_diff.py +0 -0
  61. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/code_auto_merge_editblock.py +0 -0
  62. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/code_auto_merge_strict_diff.py +0 -0
  63. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/code_modification_ranker.py +0 -0
  64. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/command_completer.py +0 -0
  65. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/command_generator.py +0 -0
  66. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/command_templates.py +0 -0
  67. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/conf_import_export.py +0 -0
  68. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/conf_validator.py +0 -0
  69. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/const.py +0 -0
  70. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/conversation_pruner.py +0 -0
  71. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/files.py +0 -0
  72. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/git_utils.py +0 -0
  73. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/global_cancel.py +0 -0
  74. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/image_to_page.py +0 -0
  75. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/index_import_export.py +0 -0
  76. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/interpreter.py +0 -0
  77. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/llm_rerank.py +0 -0
  78. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/mcp_hub.py +0 -0
  79. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/mcp_server.py +0 -0
  80. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/mcp_servers/__init__.py +0 -0
  81. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/mcp_servers/mcp_server_perplexity.py +0 -0
  82. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/mcp_tools.py +0 -0
  83. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/memory_manager.py +0 -0
  84. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/model_speed_test.py +0 -0
  85. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/printer.py +0 -0
  86. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/recall_validation.py +0 -0
  87. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/result_manager.py +0 -0
  88. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/screenshots.py +0 -0
  89. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/search.py +0 -0
  90. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/search_replace.py +0 -0
  91. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/shells.py +0 -0
  92. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/stats_panel.py +0 -0
  93. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/sys_prompt.py +0 -0
  94. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/text.py +0 -0
  95. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/types.py +0 -0
  96. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/common/utils_code_auto_generate.py +0 -0
  97. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/data/byzerllm.md +0 -0
  98. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/data/tokenizer.json +0 -0
  99. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/db/__init__.py +0 -0
  100. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/db/store.py +0 -0
  101. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/dispacher/__init__.py +0 -0
  102. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/dispacher/actions/__init__.py +0 -0
  103. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/dispacher/actions/action.py +0 -0
  104. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/dispacher/actions/copilot.py +0 -0
  105. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/dispacher/actions/plugins/__init__.py +0 -0
  106. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/dispacher/actions/plugins/action_regex_project.py +0 -0
  107. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/dispacher/actions/plugins/action_translate.py +0 -0
  108. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/index/__init__.py +0 -0
  109. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/index/filter/__init__.py +0 -0
  110. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/index/filter/normal_filter.py +0 -0
  111. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/index/filter/quick_filter.py +0 -0
  112. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/index/for_command.py +0 -0
  113. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/index/index.py +0 -0
  114. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/index/symbols_utils.py +0 -0
  115. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/index/types.py +0 -0
  116. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/lang.py +0 -0
  117. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/models.py +0 -0
  118. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/privacy/__init__.py +0 -0
  119. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/privacy/model_filter.py +0 -0
  120. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/pyproject/__init__.py +0 -0
  121. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/__init__.py +0 -0
  122. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/api_server.py +0 -0
  123. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/cache/__init__.py +0 -0
  124. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/cache/base_cache.py +0 -0
  125. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/cache/byzer_storage_cache.py +0 -0
  126. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/cache/file_monitor_cache.py +0 -0
  127. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/cache/simple_cache.py +0 -0
  128. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/doc_filter.py +0 -0
  129. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/document_retriever.py +0 -0
  130. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/lang.py +0 -0
  131. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/llm_wrapper.py +0 -0
  132. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/loaders/__init__.py +0 -0
  133. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/loaders/docx_loader.py +0 -0
  134. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/loaders/excel_loader.py +0 -0
  135. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/loaders/pdf_loader.py +0 -0
  136. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/loaders/ppt_loader.py +0 -0
  137. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/rag_config.py +0 -0
  138. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/rag_entry.py +0 -0
  139. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/raw_rag.py +0 -0
  140. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/relevant_utils.py +0 -0
  141. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/simple_directory_reader.py +0 -0
  142. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/simple_rag.py +0 -0
  143. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/stream_event/__init__.py +0 -0
  144. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/stream_event/event_writer.py +0 -0
  145. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/stream_event/types.py +0 -0
  146. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/token_checker.py +0 -0
  147. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/token_counter.py +0 -0
  148. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/token_limiter.py +0 -0
  149. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/token_limiter_utils.py +0 -0
  150. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/types.py +0 -0
  151. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/utils.py +0 -0
  152. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/rag/variable_holder.py +0 -0
  153. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/regexproject/__init__.py +0 -0
  154. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/suffixproject/__init__.py +0 -0
  155. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/tsproject/__init__.py +0 -0
  156. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/__init__.py +0 -0
  157. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/_markitdown.py +0 -0
  158. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/auto_coder_utils/__init__.py +0 -0
  159. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/auto_coder_utils/chat_stream_out.py +0 -0
  160. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/auto_project_type.py +0 -0
  161. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/chat_auto_coder_utils/__init__.py +0 -0
  162. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/conversation_store.py +0 -0
  163. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/llm_client_interceptors.py +0 -0
  164. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/llms.py +0 -0
  165. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/log_capture.py +0 -0
  166. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/model_provider_selector.py +0 -0
  167. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/multi_turn.py +0 -0
  168. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/operate_config_api.py +0 -0
  169. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/print_table.py +0 -0
  170. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/project_structure.py +0 -0
  171. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/queue_communicate.py +0 -0
  172. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/request_event_queue.py +0 -0
  173. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/request_queue.py +0 -0
  174. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/rest.py +0 -0
  175. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/stream_thinking.py +0 -0
  176. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/tests.py +0 -0
  177. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/thread_utils.py +0 -0
  178. {auto_coder-0.1.280 → auto_coder-0.1.281}/src/autocoder/utils/types.py +0 -0
  179. {auto_coder-0.1.280 → auto_coder-0.1.281}/tests/test_action_regex_project.py +0 -0
  180. {auto_coder-0.1.280 → auto_coder-0.1.281}/tests/test_chat_auto_coder.py +0 -0
  181. {auto_coder-0.1.280 → auto_coder-0.1.281}/tests/test_code_auto_merge_editblock.py +0 -0
  182. {auto_coder-0.1.280 → auto_coder-0.1.281}/tests/test_command_completer.py +0 -0
  183. {auto_coder-0.1.280 → auto_coder-0.1.281}/tests/test_planner.py +0 -0
  184. {auto_coder-0.1.280 → auto_coder-0.1.281}/tests/test_privacy.py +0 -0
  185. {auto_coder-0.1.280 → auto_coder-0.1.281}/tests/test_queue_communicate.py +0 -0
  186. {auto_coder-0.1.280 → auto_coder-0.1.281}/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.280
3
+ Version: 0.1.281
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.280
3
+ Version: 0.1.281
4
4
  Summary: AutoCoder: AutoCoder
5
5
  Author: allwefantasy
6
6
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
@@ -1345,7 +1345,8 @@ def main(input_args: Optional[List[str]] = None):
1345
1345
  v = learner.learn_from_commit(query=args.query,conversations=loaded_conversations)
1346
1346
  else:
1347
1347
  # 预估token数量
1348
- estimated_input_tokens = count_tokens(json.dumps(loaded_conversations, ensure_ascii=False))
1348
+ dumped_conversations = json.dumps(loaded_conversations, ensure_ascii=False)
1349
+ estimated_input_tokens = count_tokens(dumped_conversations)
1349
1350
  printer = Printer()
1350
1351
  printer.print_in_terminal("estimated_chat_input_tokens", style="yellow",
1351
1352
  estimated_input_tokens=estimated_input_tokens
@@ -4,7 +4,7 @@ from pathlib import Path
4
4
  import json
5
5
  from loguru import logger
6
6
  from autocoder.rag.token_counter import count_tokens
7
- from autocoder.common import AutoCoderArgs,SourceCode
7
+ from autocoder.common import AutoCoderArgs, SourceCode
8
8
  from byzerllm.utils.client.code_utils import extract_code
9
9
  from autocoder.index.types import VerifyFileRelevance
10
10
  import byzerllm
@@ -13,6 +13,7 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
13
13
  from autocoder.common.printer import Printer
14
14
  from autocoder.common.auto_coder_lang import get_message_with_format
15
15
 
16
+
16
17
  class PruneContext:
17
18
  def __init__(self, max_tokens: int, args: AutoCoderArgs, llm: Union[byzerllm.ByzerLLM, byzerllm.SimpleByzerLLM]):
18
19
  self.max_tokens = max_tokens
@@ -22,12 +23,12 @@ class PruneContext:
22
23
 
23
24
  def _split_content_with_sliding_window(self, content: str, window_size=100, overlap=20) -> List[Tuple[int, int, str]]:
24
25
  """使用滑动窗口分割大文件内容,返回包含行号信息的文本块
25
-
26
+
26
27
  Args:
27
28
  content: 要分割的文件内容
28
29
  window_size: 每个窗口包含的行数
29
30
  overlap: 相邻窗口的重叠行数
30
-
31
+
31
32
  Returns:
32
33
  List[Tuple[int, int, str]]: 返回元组列表,每个元组包含:
33
34
  - 起始行号(从1开始),在原始文件的绝对行号
@@ -38,107 +39,58 @@ class PruneContext:
38
39
  lines = content.splitlines()
39
40
  chunks = []
40
41
  start = 0
41
-
42
+
42
43
  while start < len(lines):
43
44
  # 计算当前窗口的结束位置
44
45
  end = min(start + window_size, len(lines))
45
-
46
+
46
47
  # 计算实际的起始位置(考虑重叠)
47
48
  actual_start = max(0, start - overlap)
48
-
49
+
49
50
  # 提取当前窗口的行
50
51
  chunk_lines = lines[actual_start:end]
51
-
52
+
52
53
  # 为每一行添加行号
53
54
  # 行号从actual_start+1开始,保持与原文件的绝对行号一致
54
55
  chunk_content = "\n".join([
55
56
  f"{i+1} {line}" for i, line in enumerate(chunk_lines, start=actual_start)
56
57
  ])
57
-
58
+
58
59
  # 保存分块信息:(起始行号, 结束行号, 带行号的内容)
59
60
  # 行号从1开始计数
60
61
  chunks.append((actual_start + 1, end, chunk_content))
61
-
62
+
62
63
  # 移动到下一个窗口的起始位置
63
64
  # 减去overlap确保窗口重叠
64
65
  start += (window_size - overlap)
65
-
66
- return chunks
67
-
68
- def _merge_overlapping_snippets(self, snippets: List[dict]) -> List[dict]:
69
- """合并重叠或相邻的代码片段
70
-
71
- Args:
72
- snippets: 代码片段列表,每个片段是包含start_line和end_line的字典
73
-
74
- Returns:
75
- List[dict]: 合并后的代码片段列表
76
-
77
- 示例:
78
- 输入: [
79
- {"start_line": 1, "end_line": 5},
80
- {"start_line": 4, "end_line": 8},
81
- {"start_line": 10, "end_line": 12}
82
- ]
83
- 输出: [
84
- {"start_line": 1, "end_line": 8},
85
- {"start_line": 10, "end_line": 12}
86
- ]
87
- """
88
- if not snippets:
89
- return []
90
-
91
- # 按起始行排序
92
- sorted_snippets = sorted(snippets, key=lambda x: x["start_line"])
93
-
94
- merged = [sorted_snippets[0]]
95
-
96
- for current in sorted_snippets[1:]:
97
- last = merged[-1]
98
-
99
- # 判断是否需要合并:
100
- # 1. 如果当前片段的起始行小于等于上一个片段的结束行+1
101
- # 2. +1是为了合并相邻的片段,比如1-5和6-8应该合并为1-8
102
- if current["start_line"] <= last["end_line"] + 1:
103
- # 合并区间:
104
- # - 起始行取两者最小值
105
- # - 结束行取两者最大值
106
- merged[-1] = {
107
- "start_line": min(last["start_line"], current["start_line"]),
108
- "end_line": max(last["end_line"], current["end_line"])
109
- }
110
- else:
111
- # 如果不重叠且不相邻,则作为新片段添加
112
- merged.append(current)
113
66
 
114
- return merged
115
-
67
+ return chunks
68
+
116
69
 
117
- def _delete_overflow_files(self, file_paths: List[str]) -> List[SourceCode]:
70
+ def _delete_overflow_files(self, file_sources: List[SourceCode]) -> List[SourceCode]:
118
71
  """直接删除超出 token 限制的文件"""
119
72
  total_tokens = 0
120
73
  selected_files = []
121
74
  token_count = 0
122
- for file_path in file_paths:
123
- try:
124
- with open(file_path, "r", encoding="utf-8") as f:
125
- content = f.read()
126
- token_count = count_tokens(content)
127
- if total_tokens + token_count <= self.max_tokens:
128
- total_tokens += token_count
129
- print(f"{file_path} {token_count} {content}")
130
- selected_files.append(SourceCode(module_name=file_path,source_code=content,tokens=token_count))
131
- else:
132
- break
75
+ for file_source in file_sources:
76
+ try:
77
+ token_count = file_source.tokens
78
+ if token_count <= 0:
79
+ token_count = count_tokens(file_source.source_code)
80
+
81
+ if total_tokens + token_count <= self.max_tokens:
82
+ total_tokens += token_count
83
+ print(f"{file_source.module_name} {token_count}")
84
+ selected_files.append(file_source)
85
+ else:
86
+ break
133
87
  except Exception as e:
134
- logger.error(f"Failed to read file {file_path}: {e}")
135
- selected_files.append(SourceCode(module_name=file_path,source_code=content,tokens=token_count))
88
+ logger.error(f"Failed to read file {file_source.module_name}: {e}")
89
+ selected_files.append(file_source)
136
90
 
137
91
  return selected_files
138
-
139
-
140
92
 
141
- def _extract_code_snippets(self, file_paths: List[str], conversations: List[Dict[str, str]]) -> List[SourceCode]:
93
+ def _extract_code_snippets(self, file_sources: List[SourceCode], conversations: List[Dict[str, str]]) -> List[SourceCode]:
142
94
  """抽取关键代码片段策略"""
143
95
  token_count = 0
144
96
  selected_files = []
@@ -236,108 +188,111 @@ class PruneContext:
236
188
 
237
189
  输出格式:
238
190
  严格的JSON数组,不包含其他文字或解释。
239
-
191
+
240
192
  ```json
241
193
  [
242
194
  {"start_line": 第一个代码段的起始行号, "end_line": 第一个代码段的结束行号},
243
195
  {"start_line": 第二个代码段的起始行号, "end_line": 第二个代码段的结束行号}
244
196
  ]
245
197
  ```
246
-
198
+
247
199
  """
248
-
249
200
 
250
- for file_path in file_paths:
251
- try:
252
- with open(file_path, "r", encoding="utf-8") as f:
253
- content = f.read()
254
-
255
- # 完整文件优先
256
- tokens = count_tokens(content)
257
- if token_count + tokens <= full_file_tokens:
258
- selected_files.append(SourceCode(module_name=file_path,source_code=content,tokens=tokens))
259
- token_count += tokens
201
+ for file_source in file_sources:
202
+ try:
203
+ # 完整文件优先
204
+ tokens = file_source.tokens
205
+ if token_count + tokens <= full_file_tokens:
206
+ selected_files.append(SourceCode(
207
+ module_name=file_source.module_name, source_code=file_source.source_code, tokens=tokens))
208
+ token_count += tokens
209
+ continue
210
+
211
+ # 如果单个文件太大,那么先按滑动窗口分割,然后对窗口抽取代码片段
212
+ if tokens > self.max_tokens:
213
+ self.printer.print_in_terminal(
214
+ "file_sliding_window_processing", file_path=file_source.module_name, tokens=tokens)
215
+
216
+ chunks = self._split_content_with_sliding_window(file_source.source_code,
217
+ self.args.context_prune_sliding_window_size,
218
+ self.args.context_prune_sliding_window_overlap)
219
+ all_snippets = []
220
+ for chunk_start, chunk_end, chunk_content in chunks:
221
+ extracted = extract_code_snippets.with_llm(self.llm).run(
222
+ conversations=conversations,
223
+ content=chunk_content,
224
+ is_partial_content=True
225
+ )
226
+ if extracted:
227
+ json_str = extract_code(extracted)[0][1]
228
+ snippets = json.loads(json_str)
229
+
230
+ # 获取到的本来就是在原始文件里的绝对行号
231
+ # 后续在构建代码片段内容时,会为了适配数组操作修改行号,这里无需处理
232
+ adjusted_snippets = [{
233
+ "start_line": snippet["start_line"],
234
+ "end_line": snippet["end_line"]
235
+ } for snippet in snippets]
236
+ all_snippets.extend(adjusted_snippets)
237
+ merged_snippets = self._merge_overlapping_snippets(
238
+ all_snippets)
239
+ content_snippets = self._build_snippet_content(
240
+ file_source.module_name, file_source.source_code, merged_snippets)
241
+ snippet_tokens = count_tokens(content_snippets)
242
+ if token_count + snippet_tokens <= self.max_tokens:
243
+ selected_files.append(SourceCode(
244
+ module_name=file_source.module_name, source_code=content_snippets, tokens=snippet_tokens))
245
+ token_count += snippet_tokens
246
+ self.printer.print_in_terminal("file_snippet_procesed", file_path=file_source.module_name,
247
+ total_tokens=token_count,
248
+ tokens=tokens,
249
+ snippet_tokens=snippet_tokens)
260
250
  continue
261
-
262
- ## 如果单个文件太大,那么先按滑动窗口分割,然后对窗口抽取代码片段
263
- if tokens > self.max_tokens:
264
- self.printer.print_in_terminal("file_sliding_window_processing", file_path=file_path, tokens=tokens)
265
- chunks = self._split_content_with_sliding_window(content,
266
- self.args.context_prune_sliding_window_size,
267
- self.args.context_prune_sliding_window_overlap)
268
- all_snippets = []
269
- for chunk_start, chunk_end, chunk_content in chunks:
270
- extracted = extract_code_snippets.with_llm(self.llm).run(
271
- conversations=conversations,
272
- content=chunk_content,
273
- is_partial_content=True
274
- )
275
- if extracted:
276
- json_str = extract_code(extracted)[0][1]
277
- snippets = json.loads(json_str)
278
-
279
- # 获取到的本来就是在原始文件里的绝对行号
280
- # 后续在构建代码片段内容时,会为了适配数组操作修改行号,这里无需处理
281
- adjusted_snippets = [{
282
- "start_line": snippet["start_line"],
283
- "end_line": snippet["end_line"]
284
- } for snippet in snippets]
285
- all_snippets.extend(adjusted_snippets)
286
- merged_snippets = self._merge_overlapping_snippets(all_snippets)
287
- content_snippets = self._build_snippet_content(file_path, content, merged_snippets)
288
- snippet_tokens = count_tokens(content_snippets)
289
- if token_count + snippet_tokens <= self.max_tokens:
290
- selected_files.append(SourceCode(module_name=file_path,source_code=content_snippets,tokens=snippet_tokens))
291
- token_count += snippet_tokens
292
- self.printer.print_in_terminal("file_snippet_procesed", file_path=file_path,
293
- total_tokens=token_count,
294
- tokens=tokens,
295
- snippet_tokens=snippet_tokens)
296
- continue
297
- else:
298
- break
299
-
300
- # 抽取关键片段
301
- lines = content.splitlines()
302
- new_content = ""
303
-
304
- ## 将文件内容按行编号
305
- for index,line in enumerate(lines):
306
- new_content += f"{index+1} {line}\n"
307
-
308
- ## 抽取代码片段
309
- self.printer.print_in_terminal("file_snippet_processing", file_path=file_path)
310
- extracted = extract_code_snippets.with_llm(self.llm).run(
311
- conversations=conversations,
312
- content=new_content
313
- )
314
-
315
- ## 构建代码片段内容
316
- if extracted:
317
- json_str = extract_code(extracted)[0][1]
318
- snippets = json.loads(json_str)
319
- content_snippets = self._build_snippet_content(file_path, content, snippets)
320
-
321
- snippet_tokens = count_tokens(content_snippets)
322
- if token_count + snippet_tokens <= self.max_tokens:
323
- selected_files.append(SourceCode(module_name=file_path,
324
- source_code=content_snippets,
325
- tokens=snippet_tokens))
326
- token_count += snippet_tokens
327
- self.printer.print_in_terminal("file_snippet_procesed", file_path=file_path,
328
- total_tokens = token_count,
329
- tokens=tokens,
330
- snippet_tokens=snippet_tokens)
331
- else:
332
- break
251
+ else:
252
+ break
253
+
254
+ # 抽取关键片段
255
+ lines = file_source.source_code.splitlines()
256
+ new_content = ""
257
+
258
+ # 将文件内容按行编号
259
+ for index, line in enumerate(lines):
260
+ new_content += f"{index+1} {line}\n"
261
+
262
+ # 抽取代码片段
263
+ self.printer.print_in_terminal(
264
+ "file_snippet_processing", file_path=file_source.module_name)
265
+ extracted = extract_code_snippets.with_llm(self.llm).run(
266
+ conversations=conversations,
267
+ content=new_content
268
+ )
269
+
270
+ # 构建代码片段内容
271
+ if extracted:
272
+ json_str = extract_code(extracted)[0][1]
273
+ snippets = json.loads(json_str)
274
+ content_snippets = self._build_snippet_content(
275
+ file_source.module_name, file_source.source_code, snippets)
276
+
277
+ snippet_tokens = count_tokens(content_snippets)
278
+ if token_count + snippet_tokens <= self.max_tokens:
279
+ selected_files.append(SourceCode(module_name=file_source.module_name,
280
+ source_code=content_snippets,
281
+ tokens=snippet_tokens))
282
+ token_count += snippet_tokens
283
+ self.printer.print_in_terminal("file_snippet_procesed", file_path=file_source.module_name,
284
+ total_tokens=token_count,
285
+ tokens=tokens,
286
+ snippet_tokens=snippet_tokens)
287
+ else:
288
+ break
333
289
  except Exception as e:
334
- logger.error(f"Failed to process {file_path}: {e}")
290
+ logger.error(f"Failed to process {file_source.module_name}: {e}")
335
291
  continue
336
292
 
337
293
  return selected_files
338
-
339
294
 
340
- def _merge_overlapping_snippets(self, snippets: List[dict]) -> List[dict]:
295
+ def _merge_overlapping_snippets(self, snippets: List[dict]) -> List[dict]:
341
296
  if not snippets:
342
297
  return []
343
298
 
@@ -367,27 +322,29 @@ class PruneContext:
367
322
  for snippet in snippets:
368
323
  start = max(0, snippet["start_line"] - 1)
369
324
  end = min(len(lines), snippet["end_line"])
370
- content.append(f"# Lines {start+1}-{end} ({snippet.get('reason','')})")
325
+ content.append(
326
+ f"# Lines {start+1}-{end} ({snippet.get('reason','')})")
371
327
  content.extend(lines[start:end])
372
328
 
373
329
  return header + "\n".join(content)
374
330
 
375
331
  def handle_overflow(
376
332
  self,
377
- file_paths: List[str],
333
+ file_sources: List[SourceCode],
378
334
  conversations: List[Dict[str, str]],
379
- strategy: str = "score"
335
+ strategy: str = "score"
380
336
  ) -> List[SourceCode]:
381
337
  """
382
338
  处理超出 token 限制的文件
383
- :param file_paths: 要处理的文件路径列表
339
+ :param file_sources: 要处理的文件
384
340
  :param conversations: 对话上下文(用于提取策略)
385
341
  :param strategy: 处理策略 (delete/extract/score)
386
342
  """
387
- total_tokens,sources = self._count_tokens(file_paths)
343
+ file_paths = [file_source.module_name for file_source in file_sources]
344
+ total_tokens, sources = self._count_tokens(file_sources=file_sources)
388
345
  if total_tokens <= self.max_tokens:
389
346
  return sources
390
-
347
+
391
348
  self.printer.print_in_terminal(
392
349
  "context_pruning_reason",
393
350
  total_tokens=total_tokens,
@@ -396,9 +353,9 @@ class PruneContext:
396
353
  )
397
354
 
398
355
  self.printer.print_in_terminal(
399
- "sorted_files_message",
400
- files=file_paths
401
- )
356
+ "sorted_files_message",
357
+ files=file_paths
358
+ )
402
359
 
403
360
  self.printer.print_in_terminal(
404
361
  "context_pruning_start",
@@ -407,35 +364,42 @@ class PruneContext:
407
364
  strategy=strategy
408
365
  )
409
366
 
410
- if strategy == "score":
411
- return self._score_and_filter_files(file_paths, conversations)
367
+ if strategy == "score":
368
+ return self._score_and_filter_files(sources, conversations)
412
369
  if strategy == "delete":
413
- return self._delete_overflow_files(file_paths)
370
+ return self._delete_overflow_files(sources)
414
371
  elif strategy == "extract":
415
- return self._extract_code_snippets(file_paths, conversations)
372
+ return self._extract_code_snippets(sources, conversations)
416
373
  else:
417
374
  raise ValueError(f"无效策略: {strategy}. 可选值: delete/extract/score")
418
375
 
419
- def _count_tokens(self, file_paths: List[str]) -> int:
376
+ def _count_tokens(self, file_sources: List[SourceCode]) -> int:
420
377
  """计算文件总token数"""
421
378
  total_tokens = 0
422
379
  sources = []
423
- for file_path in file_paths:
380
+ for file_source in file_sources:
424
381
  try:
425
- with open(file_path, "r", encoding="utf-8") as f:
426
- content = f.read()
427
- sources.append(SourceCode(module_name=file_path,source_code=content,tokens=count_tokens(content)))
428
- total_tokens += count_tokens(content)
382
+ if file_source.tokens > 0:
383
+ tokens = file_source.tokens
384
+ total_tokens += file_source.tokens
385
+ else:
386
+ tokens = count_tokens(file_source.source_code)
387
+ total_tokens += tokens
388
+
389
+ sources.append(SourceCode(module_name=file_source.module_name,
390
+ source_code=file_source.source_code, tokens=tokens))
391
+
429
392
  except Exception as e:
430
- logger.error(f"Failed to read file {file_path}: {e}")
431
- total_tokens += 0
432
- return total_tokens,sources
393
+ logger.error(f"Failed to count tokens for {file_source.module_name}: {e}")
394
+ sources.append(SourceCode(module_name=file_source.module_name,
395
+ source_code=file_source.source_code, tokens=0))
396
+ return total_tokens, sources
433
397
 
434
- def _score_and_filter_files(self, file_paths: List[str], conversations: List[Dict[str, str]]) -> List[SourceCode]:
398
+ def _score_and_filter_files(self, file_sources: List[SourceCode], conversations: List[Dict[str, str]]) -> List[SourceCode]:
435
399
  """根据文件相关性评分过滤文件,直到token数大于max_tokens 停止追加"""
436
400
  selected_files = []
437
401
  total_tokens = 0
438
- scored_files = []
402
+ scored_files = []
439
403
 
440
404
  @byzerllm.prompt()
441
405
  def verify_file_relevance(file_content: str, conversations: List[Dict[str, str]]) -> str:
@@ -463,30 +427,28 @@ class PruneContext:
463
427
  ```
464
428
  """
465
429
 
466
- def _score_file(file_path: str) -> dict:
467
- try:
468
- with open(file_path, "r", encoding="utf-8") as f:
469
- content = f.read()
470
- tokens = count_tokens(content)
471
- result = verify_file_relevance.with_llm(self.llm).with_return_type(VerifyFileRelevance).run(
472
- file_content=content,
473
- conversations=conversations
474
- )
475
- return {
476
- "file_path": file_path,
477
- "score": result.relevant_score,
478
- "tokens": tokens,
479
- "content": content
480
- }
430
+ def _score_file(file_source: SourceCode) -> dict:
431
+ try:
432
+ result = verify_file_relevance.with_llm(self.llm).with_return_type(VerifyFileRelevance).run(
433
+ file_content=file_source.source_code,
434
+ conversations=conversations
435
+ )
436
+ return {
437
+ "file_path": file_source.module_name,
438
+ "score": result.relevant_score,
439
+ "tokens": file_source.tokens,
440
+ "content": file_source.source_code
441
+ }
481
442
  except Exception as e:
482
- logger.error(f"Failed to score file {file_path}: {e}")
443
+ logger.error(f"Failed to score file {file_source.module_name}: {e}")
483
444
  return None
484
445
 
485
446
  # 使用线程池并行打分
486
447
  with ThreadPoolExecutor() as executor:
487
- futures = [executor.submit(_score_file, file_path) for file_path in file_paths]
448
+ futures = [executor.submit(_score_file, file_source)
449
+ for file_source in file_sources]
488
450
  for future in as_completed(futures):
489
- result = future.result()
451
+ result = future.result()
490
452
  if result:
491
453
  self.printer.print_str_in_terminal(
492
454
  get_message_with_format(
@@ -293,7 +293,7 @@ def build_index_and_filter_files(
293
293
  # 根据 sorted_file_paths 重新排序 temp_sources
294
294
  temp_sources.sort(key=lambda x: sorted_file_paths.index(x.module_name) if x.module_name in sorted_file_paths else len(sorted_file_paths))
295
295
 
296
- pruned_files = context_pruner.handle_overflow([source.module_name for source in temp_sources], [{"role":"user","content":args.query}], args.context_prune_strategy)
296
+ pruned_files = context_pruner.handle_overflow(temp_sources, [{"role":"user","content":args.query}], args.context_prune_strategy)
297
297
  source_code_list.sources = pruned_files
298
298
 
299
299
 
@@ -844,6 +844,7 @@ class LongContextRAG:
844
844
  chunk[1].generated_tokens_count = rag_stat.recall_stat.total_generated_tokens + \
845
845
  rag_stat.chunk_stat.total_generated_tokens + \
846
846
  rag_stat.answer_stat.total_generated_tokens
847
+
847
848
  yield chunk
848
849
 
849
850
  self._print_rag_stats(rag_stat)
@@ -0,0 +1 @@
1
+ __version__ = "0.1.281"
@@ -1 +0,0 @@
1
- __version__ = "0.1.280"
File without changes
File without changes
File without changes
File without changes