auto-coder 0.1.269__tar.gz → 0.1.270__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.
- {auto_coder-0.1.269 → auto_coder-0.1.270}/PKG-INFO +1 -1
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/auto_coder.egg-info/PKG-INFO +1 -1
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/auto_coder.egg-info/SOURCES.txt +1 -0
- auto_coder-0.1.270/src/autocoder/agent/auto_learn_from_commit.py +209 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/auto_coder.py +4 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/auto_coder_runner.py +26 -14
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/auto_coder_lang.py +17 -4
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/code_modification_ranker.py +55 -11
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/context_pruner.py +30 -3
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/index/entry.py +4 -2
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/index/index.py +1 -1
- auto_coder-0.1.270/src/autocoder/version.py +1 -0
- auto_coder-0.1.269/src/autocoder/version.py +0 -1
- {auto_coder-0.1.269 → auto_coder-0.1.270}/LICENSE +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/README.md +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/setup.cfg +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/setup.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/auto_coder.egg-info/dependency_links.txt +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/auto_coder.egg-info/entry_points.txt +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/auto_coder.egg-info/requires.txt +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/auto_coder.egg-info/top_level.txt +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/agent/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/agent/auto_demand_organizer.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/agent/auto_filegroup.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/agent/auto_guess_query.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/agent/auto_review_commit.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/agent/auto_tool.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/agent/coder.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/agent/designer.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/agent/planner.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/agent/project_reader.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/auto_coder_rag.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/auto_coder_rag_client_mcp.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/auto_coder_rag_mcp.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/auto_coder_server.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/benchmark.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/chat/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/chat_auto_coder.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/chat_auto_coder_lang.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/command_args.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/commands/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/commands/auto_command.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/commands/tools.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/JupyterClient.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/ShellClient.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/anything2images.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/anything2img.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/audio.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/auto_configure.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/buildin_tokenizer.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/chunk_validation.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/cleaner.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/code_auto_execute.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/code_auto_generate.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/code_auto_generate_diff.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/code_auto_generate_editblock.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/code_auto_generate_strict_diff.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/code_auto_merge.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/code_auto_merge_diff.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/code_auto_merge_editblock.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/code_auto_merge_strict_diff.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/command_completer.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/command_generator.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/command_templates.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/conf_import_export.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/conf_validator.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/const.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/conversation_pruner.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/files.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/git_utils.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/global_cancel.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/image_to_page.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/index_import_export.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/interpreter.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/llm_rerank.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/mcp_hub.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/mcp_server.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/mcp_servers/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/mcp_servers/mcp_server_perplexity.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/mcp_tools.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/memory_manager.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/model_speed_test.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/printer.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/recall_validation.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/result_manager.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/screenshots.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/search.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/search_replace.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/shells.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/stats_panel.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/sys_prompt.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/text.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/types.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/common/utils_code_auto_generate.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/data/byzerllm.md +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/data/tokenizer.json +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/db/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/db/store.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/dispacher/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/dispacher/actions/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/dispacher/actions/action.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/dispacher/actions/copilot.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/dispacher/actions/plugins/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/dispacher/actions/plugins/action_regex_project.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/dispacher/actions/plugins/action_translate.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/index/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/index/filter/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/index/filter/normal_filter.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/index/filter/quick_filter.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/index/for_command.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/index/symbols_utils.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/index/types.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/lang.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/models.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/privacy/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/privacy/model_filter.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/pyproject/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/api_server.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/cache/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/cache/base_cache.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/cache/byzer_storage_cache.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/cache/file_monitor_cache.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/cache/simple_cache.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/doc_filter.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/document_retriever.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/llm_wrapper.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/loaders/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/loaders/docx_loader.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/loaders/excel_loader.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/loaders/pdf_loader.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/loaders/ppt_loader.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/long_context_rag.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/rag_config.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/rag_entry.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/raw_rag.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/relevant_utils.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/simple_directory_reader.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/simple_rag.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/stream_event/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/stream_event/event_writer.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/stream_event/types.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/token_checker.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/token_counter.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/token_limiter.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/types.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/utils.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/rag/variable_holder.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/regexproject/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/suffixproject/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/tsproject/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/_markitdown.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/auto_coder_utils/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/auto_coder_utils/chat_stream_out.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/auto_project_type.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/chat_auto_coder_utils/__init__.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/conversation_store.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/llm_client_interceptors.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/llms.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/log_capture.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/model_provider_selector.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/multi_turn.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/operate_config_api.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/print_table.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/project_structure.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/queue_communicate.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/request_event_queue.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/request_queue.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/rest.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/tests.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/thread_utils.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/src/autocoder/utils/types.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/tests/test_action_regex_project.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/tests/test_chat_auto_coder.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/tests/test_code_auto_merge_editblock.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/tests/test_command_completer.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/tests/test_planner.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/tests/test_privacy.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/tests/test_queue_communicate.py +0 -0
- {auto_coder-0.1.269 → auto_coder-0.1.270}/tests/test_symbols_utils.py +0 -0
|
@@ -25,6 +25,7 @@ src/autocoder/agent/__init__.py
|
|
|
25
25
|
src/autocoder/agent/auto_demand_organizer.py
|
|
26
26
|
src/autocoder/agent/auto_filegroup.py
|
|
27
27
|
src/autocoder/agent/auto_guess_query.py
|
|
28
|
+
src/autocoder/agent/auto_learn_from_commit.py
|
|
28
29
|
src/autocoder/agent/auto_review_commit.py
|
|
29
30
|
src/autocoder/agent/auto_tool.py
|
|
30
31
|
src/autocoder/agent/coder.py
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
from typing import Generator, List, Dict, Union, Tuple, Optional
|
|
2
|
+
import os
|
|
3
|
+
import yaml
|
|
4
|
+
import byzerllm
|
|
5
|
+
import pydantic
|
|
6
|
+
import git
|
|
7
|
+
from rich.console import Console
|
|
8
|
+
from autocoder.common.printer import Printer
|
|
9
|
+
from autocoder.common import AutoCoderArgs
|
|
10
|
+
from autocoder.common.utils_code_auto_generate import stream_chat_with_continue
|
|
11
|
+
import hashlib
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def load_yaml_config(yaml_file: str) -> Dict:
|
|
15
|
+
"""加载YAML配置文件"""
|
|
16
|
+
try:
|
|
17
|
+
with open(yaml_file, 'r', encoding='utf-8') as f:
|
|
18
|
+
return yaml.safe_load(f)
|
|
19
|
+
except Exception as e:
|
|
20
|
+
printer = Printer()
|
|
21
|
+
printer.print_in_terminal("yaml_load_error", style="red", yaml_file=yaml_file, error=str(e))
|
|
22
|
+
return {}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class AutoLearnFromCommit:
|
|
26
|
+
def __init__(self, llm: Union[byzerllm.ByzerLLM,byzerllm.SimpleByzerLLM],
|
|
27
|
+
args:AutoCoderArgs,
|
|
28
|
+
skip_diff: bool = False,
|
|
29
|
+
console: Optional[Console] = None):
|
|
30
|
+
"""
|
|
31
|
+
初始化 AutoLearnFromCommit
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
llm: ByzerLLM 实例,用于代码学习
|
|
35
|
+
project_dir: 项目根目录
|
|
36
|
+
skip_diff: 是否跳过获取 diff 信息
|
|
37
|
+
"""
|
|
38
|
+
self.project_dir = args.source_dir
|
|
39
|
+
self.actions_dir = os.path.join(args.source_dir, "actions")
|
|
40
|
+
self.llm = llm
|
|
41
|
+
self.skip_diff = skip_diff
|
|
42
|
+
self.console = console or Console()
|
|
43
|
+
|
|
44
|
+
@byzerllm.prompt()
|
|
45
|
+
def learn(self, querie_with_urls_and_changes: List[Tuple[str, List[str], Dict[str, Tuple[str, str]]]], query: str) -> Generator[str,None,None]:
|
|
46
|
+
"""
|
|
47
|
+
请根据下面的代码变更,总结出通用的代码调整模式,以帮助实现类似的需求。
|
|
48
|
+
|
|
49
|
+
下面用户对本次的目标以及你需要总结的要求:
|
|
50
|
+
<goal>
|
|
51
|
+
{{ query }}
|
|
52
|
+
</goal>
|
|
53
|
+
|
|
54
|
+
下面是本次提交的代码变更:
|
|
55
|
+
<changes>
|
|
56
|
+
{% for query,urls,changes in querie_with_urls_and_changes %}
|
|
57
|
+
## 原始的任务需求
|
|
58
|
+
{{ query }}
|
|
59
|
+
|
|
60
|
+
修改的文件:
|
|
61
|
+
{% for url in urls %}
|
|
62
|
+
- {{ url }}
|
|
63
|
+
{% endfor %}
|
|
64
|
+
|
|
65
|
+
代码变更:
|
|
66
|
+
{% for file_path, (before, after) in changes.items() %}
|
|
67
|
+
##File: {{ file_path }}
|
|
68
|
+
##修改前:
|
|
69
|
+
|
|
70
|
+
{{ before or "New file" }}
|
|
71
|
+
|
|
72
|
+
##File: {{ file_path }}
|
|
73
|
+
##修改后:
|
|
74
|
+
|
|
75
|
+
{{ after or "File deleted" }}
|
|
76
|
+
|
|
77
|
+
{% endfor %}
|
|
78
|
+
{% endfor %}
|
|
79
|
+
</changes>
|
|
80
|
+
|
|
81
|
+
请总结以下内容:
|
|
82
|
+
1. 代码调整模式:描述为了实现这个目标,通常需要对代码做出哪些通用调整
|
|
83
|
+
2. 关键修改点:指出本次提交中最关键或最具代表性的修改点
|
|
84
|
+
3. 潜在扩展:基于这些修改,未来类似需求可能需要进行哪些扩展
|
|
85
|
+
4. 注意事项:在实现类似功能时需要注意哪些问题
|
|
86
|
+
|
|
87
|
+
总结要求:
|
|
88
|
+
1. 总结应该抽象化,不要局限于具体实现细节
|
|
89
|
+
2. 对于每个模式都应该提供明确的适用场景
|
|
90
|
+
3. 应该考虑代码的可维护性和可扩展性
|
|
91
|
+
4. 应该指出在不同技术栈或框架下的通用性
|
|
92
|
+
"""
|
|
93
|
+
pass
|
|
94
|
+
|
|
95
|
+
def parse_history_tasks(self) -> List[Dict]:
|
|
96
|
+
"""
|
|
97
|
+
解析历史任务信息
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
List[Dict]: 每个字典包含一个历史任务的信息
|
|
101
|
+
"""
|
|
102
|
+
# 获取所有YAML文件
|
|
103
|
+
action_files = [
|
|
104
|
+
f for f in os.listdir(self.actions_dir)
|
|
105
|
+
if f[:3].isdigit() and "_" in f and f.endswith('.yml')
|
|
106
|
+
]
|
|
107
|
+
|
|
108
|
+
# 按序号排序
|
|
109
|
+
def get_seq(name):
|
|
110
|
+
return int(name.split("_")[0])
|
|
111
|
+
|
|
112
|
+
# 获取最新的action文件列表
|
|
113
|
+
action_files = sorted(action_files, key=get_seq)
|
|
114
|
+
action_files.reverse()
|
|
115
|
+
|
|
116
|
+
action_file = action_files[0]
|
|
117
|
+
|
|
118
|
+
querie_with_urls_and_changes = []
|
|
119
|
+
repo = git.Repo(self.project_dir)
|
|
120
|
+
|
|
121
|
+
# 收集所有query、urls和对应的文件变化
|
|
122
|
+
for yaml_file in [action_file]:
|
|
123
|
+
yaml_path = os.path.join(self.actions_dir, yaml_file)
|
|
124
|
+
config = load_yaml_config(yaml_path)
|
|
125
|
+
|
|
126
|
+
if not config:
|
|
127
|
+
continue
|
|
128
|
+
|
|
129
|
+
query = config.get('query', '')
|
|
130
|
+
urls = config.get('urls', [])
|
|
131
|
+
|
|
132
|
+
if query:
|
|
133
|
+
changes = {}
|
|
134
|
+
if not self.skip_diff:
|
|
135
|
+
# 计算文件的MD5用于匹配commit
|
|
136
|
+
with open(yaml_path, 'r', encoding='utf-8') as f:
|
|
137
|
+
yaml_content = f.read()
|
|
138
|
+
file_md5 = hashlib.md5(yaml_content.encode("utf-8")).hexdigest()
|
|
139
|
+
response_id = f"auto_coder_{yaml_file}_{file_md5}"
|
|
140
|
+
# 查找对应的commit
|
|
141
|
+
try:
|
|
142
|
+
for commit in repo.iter_commits():
|
|
143
|
+
if response_id in commit.message:
|
|
144
|
+
if commit.parents:
|
|
145
|
+
parent = commit.parents[0]
|
|
146
|
+
# 获取所有文件的前后内容
|
|
147
|
+
for diff_item in parent.diff(commit):
|
|
148
|
+
file_path = diff_item.a_path if diff_item.a_path else diff_item.b_path
|
|
149
|
+
|
|
150
|
+
# 获取变更前内容
|
|
151
|
+
before_content = None
|
|
152
|
+
try:
|
|
153
|
+
if diff_item.a_blob:
|
|
154
|
+
before_content = repo.git.show(f"{parent.hexsha}:{file_path}")
|
|
155
|
+
except git.exc.GitCommandError:
|
|
156
|
+
pass # 文件可能是新增的
|
|
157
|
+
|
|
158
|
+
# 获取变更后内容
|
|
159
|
+
after_content = None
|
|
160
|
+
try:
|
|
161
|
+
if diff_item.b_blob:
|
|
162
|
+
after_content = repo.git.show(f"{commit.hexsha}:{file_path}")
|
|
163
|
+
except git.exc.GitCommandError:
|
|
164
|
+
pass # 文件可能被删除
|
|
165
|
+
|
|
166
|
+
changes[file_path] = (before_content, after_content)
|
|
167
|
+
break
|
|
168
|
+
except git.exc.GitCommandError as e:
|
|
169
|
+
printer = Printer()
|
|
170
|
+
printer.print_in_terminal("git_command_error", style="red", error=str(e))
|
|
171
|
+
except Exception as e:
|
|
172
|
+
printer = Printer()
|
|
173
|
+
printer.print_in_terminal("get_commit_changes_error", style="red", error=str(e))
|
|
174
|
+
|
|
175
|
+
querie_with_urls_and_changes.append((query, urls, changes))
|
|
176
|
+
|
|
177
|
+
return querie_with_urls_and_changes
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def learn_from_commit(self,query: str, conversations: List[Dict]) -> Generator[str,None,None]:
|
|
181
|
+
"""
|
|
182
|
+
从最新的代码提交中学习通用模式
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
Optional[Generator]: 学习结果生成器,如果出错则返回None
|
|
186
|
+
"""
|
|
187
|
+
printer = Printer()
|
|
188
|
+
# 获取最新的提交信息
|
|
189
|
+
changes = self.parse_history_tasks()
|
|
190
|
+
if not changes:
|
|
191
|
+
printer.print_in_terminal("no_latest_commit", style="red")
|
|
192
|
+
return None
|
|
193
|
+
|
|
194
|
+
# 调用LLM进行代码学习
|
|
195
|
+
try:
|
|
196
|
+
# 获取 prompt 内容
|
|
197
|
+
query = self.learn.prompt(changes, query)
|
|
198
|
+
new_conversations = conversations.copy()[0:-1]
|
|
199
|
+
new_conversations.append({"role": "user", "content": query})
|
|
200
|
+
# 构造对话消息
|
|
201
|
+
v = stream_chat_with_continue(
|
|
202
|
+
llm=self.llm,
|
|
203
|
+
conversations=new_conversations,
|
|
204
|
+
llm_config={}
|
|
205
|
+
)
|
|
206
|
+
return v
|
|
207
|
+
except Exception as e:
|
|
208
|
+
printer.print_in_terminal("code_learn_error", style="red", error=str(e))
|
|
209
|
+
return None
|
|
@@ -1339,6 +1339,10 @@ def main(input_args: Optional[List[str]] = None):
|
|
|
1339
1339
|
from autocoder.agent.auto_review_commit import AutoReviewCommit
|
|
1340
1340
|
reviewer = AutoReviewCommit(llm=chat_llm, args=args)
|
|
1341
1341
|
v = reviewer.review_commit(query=args.query,conversations=loaded_conversations)
|
|
1342
|
+
elif "learn_from_commit" in args.action:
|
|
1343
|
+
from autocoder.agent.auto_learn_from_commit import AutoLearnFromCommit
|
|
1344
|
+
learner = AutoLearnFromCommit(llm=chat_llm, args=args)
|
|
1345
|
+
v = learner.learn_from_commit(query=args.query,conversations=loaded_conversations)
|
|
1342
1346
|
else:
|
|
1343
1347
|
# 预估token数量
|
|
1344
1348
|
estimated_input_tokens = count_tokens(json.dumps(loaded_conversations, ensure_ascii=False))
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
from itertools import product
|
|
2
|
+
from rich.console import Console
|
|
3
|
+
from rich.panel import Panel
|
|
2
4
|
from prompt_toolkit.formatted_text import HTML
|
|
3
5
|
from prompt_toolkit.shortcuts import radiolist_dialog
|
|
4
6
|
from prompt_toolkit import prompt
|
|
@@ -646,21 +648,28 @@ def revert():
|
|
|
646
648
|
with redirect_stdout() as output:
|
|
647
649
|
auto_coder_main(["revert", "--file", file_path])
|
|
648
650
|
s = output.getvalue()
|
|
649
|
-
|
|
651
|
+
|
|
652
|
+
console = Console()
|
|
653
|
+
panel = Panel(
|
|
654
|
+
Markdown(s),
|
|
655
|
+
title="Revert Result",
|
|
656
|
+
border_style="green" if "Successfully reverted changes" in s else "red",
|
|
657
|
+
padding=(1, 2),
|
|
658
|
+
expand=False
|
|
659
|
+
)
|
|
660
|
+
console.print(panel)
|
|
661
|
+
|
|
650
662
|
if "Successfully reverted changes" in s:
|
|
651
663
|
result_manager.append(content=s, meta={"action": "revert","success":False, "input":{
|
|
652
664
|
}})
|
|
653
|
-
|
|
654
|
-
"Reverted the last chat action successfully. Remove the yaml file {file_path}"
|
|
655
|
-
)
|
|
665
|
+
|
|
656
666
|
os.remove(file_path)
|
|
657
667
|
else:
|
|
658
668
|
result_manager.append(content=s, meta={"action": "revert","success":False, "input":{
|
|
659
669
|
}})
|
|
660
670
|
else:
|
|
661
671
|
result_manager.append(content="No previous chat action found to revert.", meta={"action": "revert","success":False, "input":{
|
|
662
|
-
}})
|
|
663
|
-
print("No previous chat action found to revert.")
|
|
672
|
+
}})
|
|
664
673
|
|
|
665
674
|
|
|
666
675
|
def add_files(args: List[str]):
|
|
@@ -1155,6 +1164,7 @@ def mcp(query: str):
|
|
|
1155
1164
|
"silence": conf.get("silence", "true") == "true",
|
|
1156
1165
|
"include_project_structure": conf.get("include_project_structure", "true")
|
|
1157
1166
|
== "true",
|
|
1167
|
+
"exclude_files": memory.get("exclude_files", []),
|
|
1158
1168
|
}
|
|
1159
1169
|
for key, value in conf.items():
|
|
1160
1170
|
converted_value = convert_config_value(key, value)
|
|
@@ -1224,6 +1234,7 @@ def code_next(query: str):
|
|
|
1224
1234
|
"silence": conf.get("silence", "true") == "true",
|
|
1225
1235
|
"include_project_structure": conf.get("include_project_structure", "true")
|
|
1226
1236
|
== "true",
|
|
1237
|
+
"exclude_files": memory.get("exclude_files", []),
|
|
1227
1238
|
}
|
|
1228
1239
|
for key, value in conf.items():
|
|
1229
1240
|
converted_value = convert_config_value(key, value)
|
|
@@ -1595,6 +1606,9 @@ def chat(query: str):
|
|
|
1595
1606
|
if "/review" in query and "/commit" in query:
|
|
1596
1607
|
yaml_config["action"].append("review_commit")
|
|
1597
1608
|
query = query.replace("/review", "", 1).replace("/commit", "", 1).strip()
|
|
1609
|
+
elif "/learn" in query:
|
|
1610
|
+
yaml_config["action"].append("learn_from_commit")
|
|
1611
|
+
query = query.replace("/learn", "", 1).strip()
|
|
1598
1612
|
else:
|
|
1599
1613
|
is_review = query.strip().startswith("/review")
|
|
1600
1614
|
if is_review:
|
|
@@ -2283,6 +2297,7 @@ def index_build():
|
|
|
2283
2297
|
conf = memory.get("conf", {})
|
|
2284
2298
|
yaml_config = {
|
|
2285
2299
|
"include_file": ["./base/base.yml"],
|
|
2300
|
+
"exclude_files": memory.get("exclude_files", []),
|
|
2286
2301
|
}
|
|
2287
2302
|
|
|
2288
2303
|
for key, value in conf.items():
|
|
@@ -2295,10 +2310,8 @@ def index_build():
|
|
|
2295
2310
|
|
|
2296
2311
|
with open(yaml_file, "w",encoding="utf-8") as f:
|
|
2297
2312
|
f.write(yaml_content)
|
|
2298
|
-
try:
|
|
2299
|
-
|
|
2300
|
-
auto_coder_main(["index", "--file", yaml_file])
|
|
2301
|
-
print(output.getvalue(), flush=True)
|
|
2313
|
+
try:
|
|
2314
|
+
auto_coder_main(["index", "--file", yaml_file])
|
|
2302
2315
|
completer.refresh_files()
|
|
2303
2316
|
finally:
|
|
2304
2317
|
os.remove(yaml_file)
|
|
@@ -2315,6 +2328,7 @@ def get_final_config()->AutoCoderArgs:
|
|
|
2315
2328
|
"silence": conf.get("silence", "true") == "true",
|
|
2316
2329
|
"include_project_structure": conf.get("include_project_structure", "true")
|
|
2317
2330
|
== "true",
|
|
2331
|
+
"exclude_files": memory.get("exclude_files", []),
|
|
2318
2332
|
}
|
|
2319
2333
|
for key, value in conf.items():
|
|
2320
2334
|
converted_value = convert_config_value(key, value)
|
|
@@ -2380,10 +2394,8 @@ def index_query(query: str):
|
|
|
2380
2394
|
|
|
2381
2395
|
with open(yaml_file, "w",encoding="utf-8") as f:
|
|
2382
2396
|
f.write(yaml_content)
|
|
2383
|
-
try:
|
|
2384
|
-
|
|
2385
|
-
auto_coder_main(["index-query", "--file", yaml_file])
|
|
2386
|
-
print(output.getvalue(), flush=True)
|
|
2397
|
+
try:
|
|
2398
|
+
auto_coder_main(["index-query", "--file", yaml_file])
|
|
2387
2399
|
finally:
|
|
2388
2400
|
os.remove(yaml_file)
|
|
2389
2401
|
|
|
@@ -130,7 +130,7 @@ MESSAGES = {
|
|
|
130
130
|
"quick_filter_too_long": "⚠️ index file is too large ({{ tokens_len }}/{{ max_tokens }}). The query will be split into {{ split_size }} chunks.",
|
|
131
131
|
"quick_filter_tokens_len": "📊 Current index size: {{ tokens_len }} tokens",
|
|
132
132
|
"estimated_chat_input_tokens": "Estimated chat input tokens: {{ estimated_input_tokens }}",
|
|
133
|
-
"estimated_input_tokens_in_generate": "Estimated input tokens in generate ({{ generate_mode }}): {{ estimated_input_tokens }}",
|
|
133
|
+
"estimated_input_tokens_in_generate": "Estimated input tokens in generate ({{ generate_mode }}): {{ estimated_input_tokens }}",
|
|
134
134
|
"model_has_access_restrictions": "{{model_name}} has access restrictions, cannot use the current function",
|
|
135
135
|
"auto_command_not_found": "Auto command not found: {{command}}. Please check your input and try again.",
|
|
136
136
|
"auto_command_failed": "Auto command failed: {{error}}. Please check your input and try again.",
|
|
@@ -163,11 +163,20 @@ MESSAGES = {
|
|
|
163
163
|
"diff_blocks_title":"diff blocks",
|
|
164
164
|
"index_exclude_files_error": "index filter exclude files fail: {{ error }}",
|
|
165
165
|
"file_sliding_window_processing": "File {{ file_path }} is too large ({{ tokens }} tokens), processing with sliding window...",
|
|
166
|
-
"file_snippet_processing": "Processing file {{ file_path }} with code snippet extraction..."
|
|
166
|
+
"file_snippet_processing": "Processing file {{ file_path }} with code snippet extraction...",
|
|
167
|
+
"context_pruning_start": "⚠️ Context pruning started. Total tokens: {{ total_tokens }} (max allowed: {{ max_tokens }}). Applying strategy: {{ strategy }}.",
|
|
168
|
+
"context_pruning_reason": "Context length exceeds maximum limit ({{ total_tokens }} > {{ max_tokens }}). Pruning is required to fit within the model's context window.",
|
|
169
|
+
"rank_code_modification_title": "{{model_name}} ranking codes",
|
|
170
|
+
"sorted_files_message": "Reordered files:\n{% for file in files %}- {{ file }}\n{% endfor %}",
|
|
171
|
+
"estimated_input_tokens_in_ranking": "estimate input token {{ estimated_input_tokens }} when ranking",
|
|
172
|
+
"file_snippet_procesed": "{{ file_path }} processed with tokens: {{ tokens }} => {{ snippet_tokens }}. Current total tokens: {{ total_tokens }}",
|
|
173
|
+
|
|
167
174
|
},
|
|
168
175
|
"zh": {
|
|
169
176
|
"file_sliding_window_processing": "文件 {{ file_path }} 过大 ({{ tokens }} tokens),正在使用滑动窗口处理...",
|
|
170
177
|
"file_snippet_processing": "正在对文件 {{ file_path }} 进行代码片段提取...",
|
|
178
|
+
"context_pruning_start": "⚠️ 开始上下文剪枝。总token数: {{ total_tokens }} (最大允许: {{ max_tokens }})。正在应用策略: {{ strategy }}。",
|
|
179
|
+
"context_pruning_reason": "上下文长度超过最大限制 ({{ total_tokens }} > {{ max_tokens }})。需要进行剪枝以适配模型的上下文窗口。",
|
|
171
180
|
"file_scored_message": "文件评分: {{file_path}} - 分数: {{score}}",
|
|
172
181
|
"invalid_file_pattern": "无效的文件模式: {{file_pattern}}. 例如: regex://.*/package-lock\\.json",
|
|
173
182
|
"conf_not_found": "未找到配置文件: {{path}}",
|
|
@@ -308,7 +317,7 @@ MESSAGES = {
|
|
|
308
317
|
"quick_filter_title": "{{ model_name }} 正在分析如何筛选上下文...",
|
|
309
318
|
"quick_filter_failed": "❌ 快速过滤器失败: {{ error }}. ",
|
|
310
319
|
"estimated_chat_input_tokens": "对话输入token预估为: {{ estimated_input_tokens }}",
|
|
311
|
-
"estimated_input_tokens_in_generate": "生成代码({{ generate_mode }})预计输入token数: {{
|
|
320
|
+
"estimated_input_tokens_in_generate": "生成代码({{ generate_mode }})预计输入token数: {{ estimated_input_tokens }}",
|
|
312
321
|
"model_has_access_restrictions": "{{model_name}} 有访问限制,无法使用当前功能",
|
|
313
322
|
"auto_command_not_found": "未找到自动命令: {{command}}。请检查您的输入并重试。",
|
|
314
323
|
"auto_command_failed": "自动命令执行失败: {{error}}。请检查您的输入并重试。",
|
|
@@ -324,7 +333,11 @@ MESSAGES = {
|
|
|
324
333
|
"index_import_success": "索引导入成功: {{path}}",
|
|
325
334
|
"edits_title": "编辑块",
|
|
326
335
|
"diff_blocks_title": "差异块",
|
|
327
|
-
"index_exclude_files_error": "索引排除文件时出错: {{error}}"
|
|
336
|
+
"index_exclude_files_error": "索引排除文件时出错: {{error}}",
|
|
337
|
+
"rank_code_modification_title": "模型{{model_name}}对代码打分",
|
|
338
|
+
"sorted_files_message": "重新排序后的文件路径:\n{% for file in files %}- {{ file }}\n{% endfor %}",
|
|
339
|
+
"estimated_input_tokens_in_ranking": "排序预计输入token数: {{ estimated_input_tokens }}",
|
|
340
|
+
"file_snippet_procesed": "文件 {{ file_path }} 处理后token数: {{ tokens }} => {{ snippet_tokens }} 当前总token数: {{ total_tokens }}"
|
|
328
341
|
}}
|
|
329
342
|
|
|
330
343
|
|
|
@@ -6,11 +6,13 @@ from pydantic import BaseModel
|
|
|
6
6
|
from autocoder.common.printer import Printer
|
|
7
7
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
8
8
|
import traceback
|
|
9
|
-
from autocoder.common.utils_code_auto_generate import chat_with_continue
|
|
9
|
+
from autocoder.common.utils_code_auto_generate import chat_with_continue,stream_chat_with_continue
|
|
10
10
|
from byzerllm.utils.str2model import to_model
|
|
11
|
+
from autocoder.utils.auto_coder_utils.chat_stream_out import stream_out
|
|
11
12
|
from autocoder.utils.llms import get_llm_names, get_model_info
|
|
12
13
|
from autocoder.common.types import CodeGenerateResult, MergeCodeWithoutEffect
|
|
13
14
|
import os
|
|
15
|
+
from autocoder.rag.token_counter import count_tokens
|
|
14
16
|
|
|
15
17
|
class RankResult(BaseModel):
|
|
16
18
|
rank_result: List[int]
|
|
@@ -133,6 +135,15 @@ class CodeModificationRanker:
|
|
|
133
135
|
else:
|
|
134
136
|
raise Exception(f"Invalid rank strategy: {self.args.rank_strategy}")
|
|
135
137
|
|
|
138
|
+
# 计算 query 的 token 数量
|
|
139
|
+
token_count = count_tokens(query)
|
|
140
|
+
|
|
141
|
+
# 打印 token 统计信息
|
|
142
|
+
self.printer.print_in_terminal(
|
|
143
|
+
"estimated_input_tokens_in_ranking",
|
|
144
|
+
estimated_input_tokens=token_count
|
|
145
|
+
)
|
|
146
|
+
|
|
136
147
|
input_tokens_count = 0
|
|
137
148
|
generated_tokens_count = 0
|
|
138
149
|
try:
|
|
@@ -145,16 +156,25 @@ class CodeModificationRanker:
|
|
|
145
156
|
self.printer.print_in_terminal(
|
|
146
157
|
"ranking_start", style="blue", count=len(generate_result.contents), model_name=model_name)
|
|
147
158
|
|
|
148
|
-
for
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
159
|
+
for i in range(rank_times):
|
|
160
|
+
if i == 0:
|
|
161
|
+
futures.append(
|
|
162
|
+
executor.submit(
|
|
163
|
+
stream_chat_with_continue,
|
|
164
|
+
llm,
|
|
165
|
+
[{"role": "user", "content": query}],
|
|
166
|
+
{}
|
|
167
|
+
)
|
|
168
|
+
)
|
|
169
|
+
else:
|
|
170
|
+
futures.append(
|
|
171
|
+
executor.submit(
|
|
172
|
+
chat_with_continue,
|
|
173
|
+
llm,
|
|
174
|
+
[{"role": "user", "content": query}],
|
|
175
|
+
{}
|
|
176
|
+
)
|
|
156
177
|
)
|
|
157
|
-
)
|
|
158
178
|
|
|
159
179
|
# Collect all results
|
|
160
180
|
results = []
|
|
@@ -180,7 +200,31 @@ class CodeModificationRanker:
|
|
|
180
200
|
total_input_cost = 0.0
|
|
181
201
|
total_output_cost = 0.0
|
|
182
202
|
|
|
183
|
-
|
|
203
|
+
# 第一个future使用流式输出
|
|
204
|
+
stream_future = futures[0]
|
|
205
|
+
model_name = model_names[0]
|
|
206
|
+
stream_generator = stream_future.result()
|
|
207
|
+
full_response, last_meta = stream_out(
|
|
208
|
+
stream_generator,
|
|
209
|
+
model_name=model_name,
|
|
210
|
+
title=self.printer.get_message_from_key_with_format(
|
|
211
|
+
"rank_code_modification_title", model_name=model_name),
|
|
212
|
+
args=self.args
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
if last_meta:
|
|
216
|
+
input_tokens_count += last_meta.input_tokens_count
|
|
217
|
+
generated_tokens_count += last_meta.generated_tokens_count
|
|
218
|
+
# 计算成本
|
|
219
|
+
info = model_info_map.get(model_name, {})
|
|
220
|
+
# 计算公式:token数 * 单价 / 1000000
|
|
221
|
+
total_input_cost += (last_meta.input_tokens_count * info.get("input_cost", 0.0)) / 1000000
|
|
222
|
+
total_output_cost += (last_meta.generated_tokens_count * info.get("output_cost", 0.0)) / 1000000
|
|
223
|
+
|
|
224
|
+
v = to_model(full_response,RankResult)
|
|
225
|
+
results.append(v.rank_result)
|
|
226
|
+
|
|
227
|
+
for future, model_name in zip(futures[1:], model_names[1:]):
|
|
184
228
|
try:
|
|
185
229
|
result = future.result()
|
|
186
230
|
input_tokens_count += result.input_tokens_count
|
|
@@ -287,8 +287,12 @@ class PruneContext:
|
|
|
287
287
|
content_snippets = self._build_snippet_content(file_path, content, merged_snippets)
|
|
288
288
|
snippet_tokens = count_tokens(content_snippets)
|
|
289
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))
|
|
290
|
+
selected_files.append(SourceCode(module_name=file_path,source_code=content_snippets,tokens=snippet_tokens))
|
|
291
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)
|
|
292
296
|
continue
|
|
293
297
|
else:
|
|
294
298
|
break
|
|
@@ -315,11 +319,15 @@ class PruneContext:
|
|
|
315
319
|
content_snippets = self._build_snippet_content(file_path, content, snippets)
|
|
316
320
|
|
|
317
321
|
snippet_tokens = count_tokens(content_snippets)
|
|
318
|
-
if token_count + snippet_tokens <= self.max_tokens:
|
|
322
|
+
if token_count + snippet_tokens <= self.max_tokens:
|
|
319
323
|
selected_files.append(SourceCode(module_name=file_path,
|
|
320
324
|
source_code=content_snippets,
|
|
321
325
|
tokens=snippet_tokens))
|
|
322
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)
|
|
323
331
|
else:
|
|
324
332
|
break
|
|
325
333
|
except Exception as e:
|
|
@@ -379,7 +387,26 @@ class PruneContext:
|
|
|
379
387
|
total_tokens,sources = self._count_tokens(file_paths)
|
|
380
388
|
if total_tokens <= self.max_tokens:
|
|
381
389
|
return sources
|
|
382
|
-
|
|
390
|
+
|
|
391
|
+
self.printer.print_in_terminal(
|
|
392
|
+
"context_pruning_reason",
|
|
393
|
+
total_tokens=total_tokens,
|
|
394
|
+
max_tokens=self.max_tokens,
|
|
395
|
+
style="yellow"
|
|
396
|
+
)
|
|
397
|
+
|
|
398
|
+
self.printer.print_in_terminal(
|
|
399
|
+
"sorted_files_message",
|
|
400
|
+
files=file_paths
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
self.printer.print_in_terminal(
|
|
404
|
+
"context_pruning_start",
|
|
405
|
+
total_tokens=total_tokens,
|
|
406
|
+
max_tokens=self.max_tokens,
|
|
407
|
+
strategy=strategy
|
|
408
|
+
)
|
|
409
|
+
|
|
383
410
|
if strategy == "score":
|
|
384
411
|
return self._score_and_filter_files(file_paths, conversations)
|
|
385
412
|
if strategy == "delete":
|
|
@@ -291,10 +291,12 @@ def build_index_and_filter_files(
|
|
|
291
291
|
# 提取排序后的文件路径列表
|
|
292
292
|
sorted_file_paths = [file_path for _, file_path in position_file_pairs]
|
|
293
293
|
# 根据 sorted_file_paths 重新排序 temp_sources
|
|
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
|
-
|
|
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
|
+
|
|
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
297
|
source_code_list.sources = pruned_files
|
|
297
298
|
|
|
299
|
+
|
|
298
300
|
if args.request_id and not args.skip_events:
|
|
299
301
|
queue_communicate.send_event(
|
|
300
302
|
request_id=args.request_id,
|
|
@@ -400,7 +400,7 @@ class IndexManager:
|
|
|
400
400
|
|
|
401
401
|
# 删除被排除的文件
|
|
402
402
|
try:
|
|
403
|
-
exclude_patterns = self.parse_exclude_files(self.args.exclude_files)
|
|
403
|
+
exclude_patterns = self.parse_exclude_files(self.args.exclude_files)
|
|
404
404
|
for file_path in index_data:
|
|
405
405
|
if self.filter_exclude_files(file_path, exclude_patterns):
|
|
406
406
|
keys_to_remove.append(file_path)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.270"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.1.269"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|