auto-coder 0.1.271__tar.gz → 0.1.273__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.271 → auto_coder-0.1.273}/PKG-INFO +2 -2
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/auto_coder.egg-info/PKG-INFO +2 -2
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/auto_coder.egg-info/SOURCES.txt +1 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/auto_coder.egg-info/requires.txt +1 -1
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/auto_coder_runner.py +4 -4
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/auto_coder_lang.py +2 -2
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/auto_configure.py +1 -1
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/index/filter/quick_filter.py +4 -3
- auto_coder-0.1.273/src/autocoder/rag/doc_filter.py +281 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/llm_wrapper.py +3 -1
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/loaders/docx_loader.py +1 -1
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/long_context_rag.py +196 -51
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/relevant_utils.py +12 -1
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/token_limiter.py +159 -18
- auto_coder-0.1.273/src/autocoder/rag/token_limiter_utils.py +13 -0
- auto_coder-0.1.273/src/autocoder/version.py +1 -0
- auto_coder-0.1.271/src/autocoder/rag/doc_filter.py +0 -175
- auto_coder-0.1.271/src/autocoder/version.py +0 -1
- {auto_coder-0.1.271 → auto_coder-0.1.273}/LICENSE +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/README.md +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/setup.cfg +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/setup.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/auto_coder.egg-info/dependency_links.txt +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/auto_coder.egg-info/entry_points.txt +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/auto_coder.egg-info/top_level.txt +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/agent/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/agent/auto_demand_organizer.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/agent/auto_filegroup.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/agent/auto_guess_query.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/agent/auto_learn_from_commit.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/agent/auto_review_commit.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/agent/auto_tool.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/agent/coder.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/agent/designer.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/agent/planner.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/agent/project_reader.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/auto_coder.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/auto_coder_rag.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/auto_coder_rag_client_mcp.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/auto_coder_rag_mcp.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/auto_coder_server.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/benchmark.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/chat/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/chat_auto_coder.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/chat_auto_coder_lang.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/command_args.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/commands/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/commands/auto_command.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/commands/tools.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/JupyterClient.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/ShellClient.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/anything2images.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/anything2img.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/audio.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/buildin_tokenizer.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/chunk_validation.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/cleaner.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/code_auto_execute.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/code_auto_generate.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/code_auto_generate_diff.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/code_auto_generate_editblock.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/code_auto_generate_strict_diff.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/code_auto_merge.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/code_auto_merge_diff.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/code_auto_merge_editblock.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/code_auto_merge_strict_diff.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/code_modification_ranker.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/command_completer.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/command_generator.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/command_templates.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/conf_import_export.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/conf_validator.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/const.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/context_pruner.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/conversation_pruner.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/files.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/git_utils.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/global_cancel.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/image_to_page.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/index_import_export.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/interpreter.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/llm_rerank.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/mcp_hub.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/mcp_server.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/mcp_servers/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/mcp_servers/mcp_server_perplexity.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/mcp_tools.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/memory_manager.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/model_speed_test.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/printer.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/recall_validation.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/result_manager.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/screenshots.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/search.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/search_replace.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/shells.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/stats_panel.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/sys_prompt.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/text.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/types.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/common/utils_code_auto_generate.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/data/byzerllm.md +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/data/tokenizer.json +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/db/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/db/store.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/dispacher/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/dispacher/actions/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/dispacher/actions/action.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/dispacher/actions/copilot.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/dispacher/actions/plugins/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/dispacher/actions/plugins/action_regex_project.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/dispacher/actions/plugins/action_translate.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/index/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/index/entry.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/index/filter/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/index/filter/normal_filter.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/index/for_command.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/index/index.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/index/symbols_utils.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/index/types.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/lang.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/models.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/privacy/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/privacy/model_filter.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/pyproject/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/api_server.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/cache/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/cache/base_cache.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/cache/byzer_storage_cache.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/cache/file_monitor_cache.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/cache/simple_cache.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/document_retriever.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/loaders/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/loaders/excel_loader.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/loaders/pdf_loader.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/loaders/ppt_loader.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/rag_config.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/rag_entry.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/raw_rag.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/simple_directory_reader.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/simple_rag.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/stream_event/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/stream_event/event_writer.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/stream_event/types.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/token_checker.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/token_counter.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/types.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/utils.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/rag/variable_holder.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/regexproject/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/suffixproject/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/tsproject/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/_markitdown.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/auto_coder_utils/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/auto_coder_utils/chat_stream_out.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/auto_project_type.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/chat_auto_coder_utils/__init__.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/conversation_store.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/llm_client_interceptors.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/llms.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/log_capture.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/model_provider_selector.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/multi_turn.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/operate_config_api.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/print_table.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/project_structure.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/queue_communicate.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/request_event_queue.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/request_queue.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/rest.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/tests.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/thread_utils.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/src/autocoder/utils/types.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/tests/test_action_regex_project.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/tests/test_chat_auto_coder.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/tests/test_code_auto_merge_editblock.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/tests/test_command_completer.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/tests/test_planner.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/tests/test_privacy.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/tests/test_queue_communicate.py +0 -0
- {auto_coder-0.1.271 → auto_coder-0.1.273}/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.
|
|
3
|
+
Version: 0.1.273
|
|
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.
|
|
29
|
+
Requires-Dist: byzerllm[saas]>=0.1.169
|
|
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.
|
|
3
|
+
Version: 0.1.273
|
|
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.
|
|
29
|
+
Requires-Dist: byzerllm[saas]>=0.1.169
|
|
30
30
|
Requires-Dist: patch
|
|
31
31
|
Requires-Dist: diff_match_patch
|
|
32
32
|
Requires-Dist: GitPython
|
|
@@ -129,6 +129,7 @@ src/autocoder/rag/simple_rag.py
|
|
|
129
129
|
src/autocoder/rag/token_checker.py
|
|
130
130
|
src/autocoder/rag/token_counter.py
|
|
131
131
|
src/autocoder/rag/token_limiter.py
|
|
132
|
+
src/autocoder/rag/token_limiter_utils.py
|
|
132
133
|
src/autocoder/rag/types.py
|
|
133
134
|
src/autocoder/rag/utils.py
|
|
134
135
|
src/autocoder/rag/variable_holder.py
|
|
@@ -2133,7 +2133,7 @@ def manage_models(query: str):
|
|
|
2133
2133
|
# Check duplication
|
|
2134
2134
|
if any(m["name"] == data_dict["name"] for m in models_data):
|
|
2135
2135
|
printer.print_in_terminal("models_add_model_exists", style="yellow", name=data_dict["name"])
|
|
2136
|
-
result_manager.add_result(content=printer.
|
|
2136
|
+
result_manager.add_result(content=printer.get_message_from_key_with_format("models_add_model_exists",name=data_dict["name"]),meta={
|
|
2137
2137
|
"action": "models",
|
|
2138
2138
|
"input": {
|
|
2139
2139
|
"query": query
|
|
@@ -2177,7 +2177,7 @@ def manage_models(query: str):
|
|
|
2177
2177
|
filtered_models = [m for m in models_data if m["name"] != name]
|
|
2178
2178
|
if len(filtered_models) == len(models_data):
|
|
2179
2179
|
printer.print_in_terminal("models_add_model_remove", style="yellow", name=name)
|
|
2180
|
-
result_manager.add_result(content=printer.
|
|
2180
|
+
result_manager.add_result(content=printer.get_message_from_key_with_format("models_add_model_remove",name=name),meta={
|
|
2181
2181
|
"action": "models",
|
|
2182
2182
|
"input": {
|
|
2183
2183
|
"query": query
|
|
@@ -2186,7 +2186,7 @@ def manage_models(query: str):
|
|
|
2186
2186
|
return
|
|
2187
2187
|
models_module.save_models(filtered_models)
|
|
2188
2188
|
printer.print_in_terminal("models_add_model_removed", style="green", name=name)
|
|
2189
|
-
result_manager.add_result(content=printer.
|
|
2189
|
+
result_manager.add_result(content=printer.get_message_from_key_with_format("models_add_model_removed",name=name),meta={
|
|
2190
2190
|
"action": "models",
|
|
2191
2191
|
"input": {
|
|
2192
2192
|
"query": query
|
|
@@ -2194,7 +2194,7 @@ def manage_models(query: str):
|
|
|
2194
2194
|
})
|
|
2195
2195
|
else:
|
|
2196
2196
|
printer.print_in_terminal("models_unknown_subcmd", style="yellow", subcmd=subcmd)
|
|
2197
|
-
result_manager.add_result(content=printer.
|
|
2197
|
+
result_manager.add_result(content=printer.get_message_from_key_with_format("models_unknown_subcmd",subcmd=subcmd),meta={
|
|
2198
2198
|
"action": "models",
|
|
2199
2199
|
"input": {
|
|
2200
2200
|
"query": query
|
|
@@ -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 }}): {{
|
|
133
|
+
"estimated_input_tokens_in_generate": "Estimated input tokens in generate ({{ generate_mode }}): {{ estimated_input_tokens_in_generate }}",
|
|
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.",
|
|
@@ -319,7 +319,7 @@ MESSAGES = {
|
|
|
319
319
|
"quick_filter_title": "{{ model_name }} 正在分析如何筛选上下文...",
|
|
320
320
|
"quick_filter_failed": "❌ 快速过滤器失败: {{ error }}. ",
|
|
321
321
|
"estimated_chat_input_tokens": "对话输入token预估为: {{ estimated_input_tokens }}",
|
|
322
|
-
"estimated_input_tokens_in_generate": "生成代码({{ generate_mode }})预计输入token数: {{
|
|
322
|
+
"estimated_input_tokens_in_generate": "生成代码({{ generate_mode }})预计输入token数: {{ estimated_input_tokens_in_generate }}",
|
|
323
323
|
"model_has_access_restrictions": "{{model_name}} 有访问限制,无法使用当前功能",
|
|
324
324
|
"auto_command_not_found": "未找到自动命令: {{command}}。请检查您的输入并重试。",
|
|
325
325
|
"auto_command_failed": "自动命令执行失败: {{error}}。请检查您的输入并重试。",
|
|
@@ -287,6 +287,7 @@ class QuickFilter():
|
|
|
287
287
|
当用户提一个需求的时候,我们要找到两种类型的源码文件:
|
|
288
288
|
1. 根据需求需要被修改的文件,我们叫 edited_files
|
|
289
289
|
2. 为了能够完成修改这些文件,还需要的一些额外参考文件, 我们叫 reference_files
|
|
290
|
+
3. 因为修改了 edited_files 文件,可能有一些依赖 edited_files 的文件也需要被修改,我们叫 dependent_files
|
|
290
291
|
|
|
291
292
|
现在,给定下面的索引文件:
|
|
292
293
|
|
|
@@ -315,9 +316,9 @@ class QuickFilter():
|
|
|
315
316
|
```
|
|
316
317
|
|
|
317
318
|
特别注意:
|
|
318
|
-
1. 如果用户的query里有 @文件 或者
|
|
319
|
-
2. 根据需求以及根据 @文件 或者 @@符号 找到的文件,猜测需要被修改的edited_files文件,然后尝试通过索引文件诸如导入语句等信息找到这些文件依赖的其他文件得到 reference_files。
|
|
320
|
-
3. file_list 里的文件序号,按被 @ 或者 @@ 文件,edited_files文件,reference_files文件的顺序排列。注意,reference_files 你要根据需求来猜测是否需要,过滤掉不相关的,避免返回文件数过多。
|
|
319
|
+
1. 如果用户的query里有 @文件 或者 @@符号,并且他们在索引文件中,那么被@的文件或者@@的符号必须要返回。
|
|
320
|
+
2. 根据需求以及根据 @文件 或者 @@符号 找到的文件,猜测需要被修改的edited_files文件,然后尝试通过索引文件诸如导入语句等信息找到这些文件依赖的其他文件得到 reference_files,dependent_files。
|
|
321
|
+
3. file_list 里的文件序号,按被 @ 或者 @@ 文件,edited_files文件,reference_files,dependent_files文件的顺序排列。注意,reference_files 你要根据需求来猜测是否需要,过滤掉不相关的,避免返回文件数过多。
|
|
321
322
|
4. 如果 query 里是一段历史对话,那么对话里的内容提及的文件路径必须要返回。
|
|
322
323
|
5. 如果用户需求为空,则直接返回空列表即可。
|
|
323
324
|
6. 返回的 json格式数据不允许有注释
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import time
|
|
2
|
+
from typing import List, Dict, Optional
|
|
3
|
+
from loguru import logger
|
|
4
|
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
5
|
+
|
|
6
|
+
from autocoder.rag.relevant_utils import (
|
|
7
|
+
parse_relevance,
|
|
8
|
+
FilterDoc,
|
|
9
|
+
TaskTiming,
|
|
10
|
+
DocFilterResult
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
from autocoder.common import SourceCode, AutoCoderArgs
|
|
14
|
+
from autocoder.rag.rag_config import RagConfigManager
|
|
15
|
+
from byzerllm import ByzerLLM
|
|
16
|
+
import byzerllm
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@byzerllm.prompt()
|
|
20
|
+
def _check_relevance_with_conversation(
|
|
21
|
+
conversations: List[Dict[str, str]],
|
|
22
|
+
documents: List[str],
|
|
23
|
+
filter_config: Optional[str] = None,
|
|
24
|
+
) -> str:
|
|
25
|
+
"""
|
|
26
|
+
使用以下文档和对话历史来回答问题。如果文档中没有相关信息,请说"我没有足够的信息来回答这个问题"。
|
|
27
|
+
|
|
28
|
+
文档:
|
|
29
|
+
<documents>
|
|
30
|
+
{% for doc in documents %}
|
|
31
|
+
{{ doc }}
|
|
32
|
+
{% endfor %}
|
|
33
|
+
</documents>
|
|
34
|
+
|
|
35
|
+
对话历史:
|
|
36
|
+
<conversations>
|
|
37
|
+
{% for msg in conversations %}
|
|
38
|
+
<{{ msg.role }}>: {{ msg.content }}
|
|
39
|
+
{% endfor %}
|
|
40
|
+
</conversations>
|
|
41
|
+
|
|
42
|
+
{% if filter_config %}
|
|
43
|
+
一些提示:
|
|
44
|
+
{{ filter_config }}
|
|
45
|
+
{% endif %}
|
|
46
|
+
|
|
47
|
+
请结合提供的文档以及用户对话历史,判断提供的文档是不是能和用户的最后一个问题相关。
|
|
48
|
+
如果该文档提供的知识能够和用户的问题相关,那么请回复"yes/<relevant>" 否则回复"no/<relevant>"。
|
|
49
|
+
其中, <relevant> 是你认为文档中和问题的相关度,0-10之间的数字,数字越大表示相关度越高。
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
class DocFilter:
|
|
53
|
+
def __init__(
|
|
54
|
+
self,
|
|
55
|
+
llm: ByzerLLM,
|
|
56
|
+
args: AutoCoderArgs,
|
|
57
|
+
on_ray: bool = False,
|
|
58
|
+
path: Optional[str] = None,
|
|
59
|
+
):
|
|
60
|
+
self.llm = llm
|
|
61
|
+
if self.llm.get_sub_client("recall_model"):
|
|
62
|
+
self.recall_llm = self.llm.get_sub_client("recall_model")
|
|
63
|
+
else:
|
|
64
|
+
self.recall_llm = self.llm
|
|
65
|
+
|
|
66
|
+
self.args = args
|
|
67
|
+
self.relevant_score = self.args.rag_doc_filter_relevance
|
|
68
|
+
self.on_ray = on_ray
|
|
69
|
+
self.path = path
|
|
70
|
+
|
|
71
|
+
def filter_docs(
|
|
72
|
+
self, conversations: List[Dict[str, str]], documents: List[SourceCode]
|
|
73
|
+
) -> DocFilterResult:
|
|
74
|
+
return self.filter_docs_with_threads(conversations, documents)
|
|
75
|
+
|
|
76
|
+
def filter_docs_with_threads(
|
|
77
|
+
self, conversations: List[Dict[str, str]], documents: List[SourceCode]
|
|
78
|
+
) -> DocFilterResult:
|
|
79
|
+
|
|
80
|
+
start_time = time.time()
|
|
81
|
+
logger.info(f"=== DocFilter Starting ===")
|
|
82
|
+
logger.info(
|
|
83
|
+
f"Configuration: relevance_threshold={self.relevant_score}, thread_workers={self.args.index_filter_workers or 5}")
|
|
84
|
+
|
|
85
|
+
rag_manager = RagConfigManager(path=self.path)
|
|
86
|
+
rag_config = rag_manager.load_config()
|
|
87
|
+
|
|
88
|
+
documents = list(documents)
|
|
89
|
+
logger.info(f"Filtering {len(documents)} documents...")
|
|
90
|
+
|
|
91
|
+
submitted_tasks = 0
|
|
92
|
+
completed_tasks = 0
|
|
93
|
+
relevant_count = 0
|
|
94
|
+
model_name = self.recall_llm.default_model_name or "unknown"
|
|
95
|
+
|
|
96
|
+
with ThreadPoolExecutor(
|
|
97
|
+
max_workers=self.args.index_filter_workers or 5
|
|
98
|
+
) as executor:
|
|
99
|
+
future_to_doc = {}
|
|
100
|
+
|
|
101
|
+
# 提交所有任务
|
|
102
|
+
for doc in documents:
|
|
103
|
+
submit_time = time.time()
|
|
104
|
+
submitted_tasks += 1
|
|
105
|
+
|
|
106
|
+
def _run(conversations, docs):
|
|
107
|
+
submit_time_1 = time.time()
|
|
108
|
+
meta = None
|
|
109
|
+
try:
|
|
110
|
+
llm = self.recall_llm
|
|
111
|
+
meta_holder = byzerllm.MetaHolder()
|
|
112
|
+
|
|
113
|
+
v = (
|
|
114
|
+
_check_relevance_with_conversation.with_llm(
|
|
115
|
+
llm).with_meta(meta_holder)
|
|
116
|
+
.options({"llm_config": {"max_length": 10}})
|
|
117
|
+
.run(
|
|
118
|
+
conversations=conversations,
|
|
119
|
+
documents=docs,
|
|
120
|
+
filter_config=rag_config.filter_config,
|
|
121
|
+
)
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
meta = meta_holder.get_meta_model()
|
|
125
|
+
except Exception as e:
|
|
126
|
+
logger.error(
|
|
127
|
+
f"Error in _check_relevance_with_conversation: {str(e)}"
|
|
128
|
+
)
|
|
129
|
+
return (None, submit_time_1, time.time(), meta)
|
|
130
|
+
|
|
131
|
+
end_time_2 = time.time()
|
|
132
|
+
return (v, submit_time_1, end_time_2, meta)
|
|
133
|
+
|
|
134
|
+
m = executor.submit(
|
|
135
|
+
_run,
|
|
136
|
+
conversations,
|
|
137
|
+
[f"##File: {doc.module_name}\n{doc.source_code}"],
|
|
138
|
+
)
|
|
139
|
+
future_to_doc[m] = (doc, submit_time)
|
|
140
|
+
|
|
141
|
+
logger.info(
|
|
142
|
+
f"Submitted {submitted_tasks} document filtering tasks to thread pool")
|
|
143
|
+
|
|
144
|
+
# 处理完成的任务
|
|
145
|
+
doc_filter_result = DocFilterResult(
|
|
146
|
+
docs=[],
|
|
147
|
+
raw_docs=[],
|
|
148
|
+
input_tokens_counts=[],
|
|
149
|
+
generated_tokens_counts=[],
|
|
150
|
+
durations=[],
|
|
151
|
+
model_name=model_name
|
|
152
|
+
)
|
|
153
|
+
relevant_docs = doc_filter_result.docs
|
|
154
|
+
for future in as_completed(list(future_to_doc.keys())):
|
|
155
|
+
try:
|
|
156
|
+
doc, submit_time = future_to_doc[future]
|
|
157
|
+
end_time = time.time()
|
|
158
|
+
completed_tasks += 1
|
|
159
|
+
progress_percent = (completed_tasks / len(documents)) * 100
|
|
160
|
+
|
|
161
|
+
v, submit_time_1, end_time_2, meta = future.result()
|
|
162
|
+
task_timing = TaskTiming(
|
|
163
|
+
submit_time=submit_time,
|
|
164
|
+
end_time=end_time,
|
|
165
|
+
duration=end_time - submit_time,
|
|
166
|
+
real_start_time=submit_time_1,
|
|
167
|
+
real_end_time=end_time_2,
|
|
168
|
+
real_duration=end_time_2 - submit_time_1,
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
relevance = parse_relevance(v)
|
|
172
|
+
is_relevant = relevance and relevance.relevant_score >= self.relevant_score
|
|
173
|
+
|
|
174
|
+
if is_relevant:
|
|
175
|
+
relevant_count += 1
|
|
176
|
+
status_text = f"RELEVANT (Score: {relevance.relevant_score:.1f})"
|
|
177
|
+
else:
|
|
178
|
+
score_text = f"{relevance.relevant_score:.1f}" if relevance else "N/A"
|
|
179
|
+
status_text = f"NOT RELEVANT (Score: {score_text})"
|
|
180
|
+
|
|
181
|
+
queue_time = task_timing.real_start_time - task_timing.submit_time
|
|
182
|
+
|
|
183
|
+
input_tokens_count = meta.input_tokens_count if meta else 0
|
|
184
|
+
generated_tokens_count = meta.generated_tokens_count if meta else 0
|
|
185
|
+
|
|
186
|
+
logger.info(
|
|
187
|
+
f"Document filtering [{progress_percent:.1f}%] - {completed_tasks}/{len(documents)}:"
|
|
188
|
+
f"\n - File: {doc.module_name}"
|
|
189
|
+
f"\n - Status: {status_text}"
|
|
190
|
+
f"\n - Model: {model_name}"
|
|
191
|
+
f"\n - Threshold: {self.relevant_score}"
|
|
192
|
+
f"\n - Input tokens: {input_tokens_count}"
|
|
193
|
+
f"\n - Generated tokens: {generated_tokens_count}"
|
|
194
|
+
f"\n - Timing: Duration={task_timing.duration:.2f}s, Processing={task_timing.real_duration:.2f}s, Queue={queue_time:.2f}s"
|
|
195
|
+
f"\n - Response: {v}"
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
if "rag" not in doc.metadata:
|
|
199
|
+
doc.metadata["rag"] = {}
|
|
200
|
+
doc.metadata["rag"]["recall"] = {
|
|
201
|
+
"input_tokens_count": input_tokens_count,
|
|
202
|
+
"generated_tokens_count": generated_tokens_count,
|
|
203
|
+
"recall_model": model_name,
|
|
204
|
+
"duration": task_timing.real_duration
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
doc_filter_result.input_tokens_counts.append(input_tokens_count)
|
|
208
|
+
doc_filter_result.generated_tokens_counts.append(generated_tokens_count)
|
|
209
|
+
doc_filter_result.durations.append(task_timing.real_duration)
|
|
210
|
+
|
|
211
|
+
new_filter_doc = FilterDoc(
|
|
212
|
+
source_code=doc,
|
|
213
|
+
relevance=relevance,
|
|
214
|
+
task_timing=task_timing,
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
doc_filter_result.raw_docs.append(new_filter_doc)
|
|
218
|
+
|
|
219
|
+
if is_relevant:
|
|
220
|
+
relevant_docs.append(
|
|
221
|
+
new_filter_doc
|
|
222
|
+
)
|
|
223
|
+
except Exception as exc:
|
|
224
|
+
try:
|
|
225
|
+
doc, submit_time = future_to_doc[future]
|
|
226
|
+
completed_tasks += 1
|
|
227
|
+
progress_percent = (
|
|
228
|
+
completed_tasks / len(documents)) * 100
|
|
229
|
+
logger.error(
|
|
230
|
+
f"Document filtering [{progress_percent:.1f}%] - {completed_tasks}/{len(documents)}:"
|
|
231
|
+
f"\n - File: {doc.module_name}"
|
|
232
|
+
f"\n - Error: {exc}"
|
|
233
|
+
f"\n - Duration: {time.time() - submit_time:.2f}s"
|
|
234
|
+
)
|
|
235
|
+
doc_filter_result.raw_docs.append(
|
|
236
|
+
FilterDoc(
|
|
237
|
+
source_code=doc,
|
|
238
|
+
relevance=None,
|
|
239
|
+
task_timing=TaskTiming(),
|
|
240
|
+
)
|
|
241
|
+
)
|
|
242
|
+
except Exception as e:
|
|
243
|
+
logger.error(
|
|
244
|
+
f"Document filtering error in task tracking: {exc}"
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
# Sort relevant_docs by relevance score in descending order
|
|
248
|
+
relevant_docs.sort(
|
|
249
|
+
key=lambda x: x.relevance.relevant_score, reverse=True)
|
|
250
|
+
|
|
251
|
+
total_time = time.time() - start_time
|
|
252
|
+
|
|
253
|
+
avg_processing_time = sum(
|
|
254
|
+
doc.task_timing.real_duration for doc in relevant_docs) / len(relevant_docs) if relevant_docs else 0
|
|
255
|
+
avg_queue_time = sum(doc.task_timing.real_start_time -
|
|
256
|
+
doc.task_timing.submit_time for doc in relevant_docs) / len(relevant_docs) if relevant_docs else 0
|
|
257
|
+
|
|
258
|
+
total_input_tokens = sum(doc_filter_result.input_tokens_counts)
|
|
259
|
+
total_generated_tokens = sum(doc_filter_result.generated_tokens_counts)
|
|
260
|
+
|
|
261
|
+
logger.info(
|
|
262
|
+
f"=== DocFilter Complete ==="
|
|
263
|
+
f"\n * Total time: {total_time:.2f}s"
|
|
264
|
+
f"\n * Documents processed: {completed_tasks}/{len(documents)}"
|
|
265
|
+
f"\n * Relevant documents: {relevant_count} (threshold: {self.relevant_score})"
|
|
266
|
+
f"\n * Average processing time: {avg_processing_time:.2f}s"
|
|
267
|
+
f"\n * Average queue time: {avg_queue_time:.2f}s"
|
|
268
|
+
f"\n * Total input tokens: {total_input_tokens}"
|
|
269
|
+
f"\n * Total generated tokens: {total_generated_tokens}"
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
if relevant_docs:
|
|
273
|
+
logger.info(
|
|
274
|
+
f"Top 5 relevant documents:"
|
|
275
|
+
+ "".join([f"\n * {doc.source_code.module_name} (Score: {doc.relevance.relevant_score:.1f})"
|
|
276
|
+
for doc in relevant_docs[:5]])
|
|
277
|
+
)
|
|
278
|
+
else:
|
|
279
|
+
logger.warning("No relevant documents found!")
|
|
280
|
+
|
|
281
|
+
return doc_filter_result
|
|
@@ -44,13 +44,15 @@ class LLWrapper:
|
|
|
44
44
|
res,contexts = self.rag.stream_chat_oai(conversations,llm_config=llm_config)
|
|
45
45
|
for t in res:
|
|
46
46
|
yield (t,SingleOutputMeta(0,0))
|
|
47
|
+
|
|
47
48
|
|
|
48
49
|
async def async_stream_chat_oai(self,conversations,
|
|
49
50
|
model:Optional[str]=None,
|
|
50
51
|
role_mapping=None,
|
|
51
52
|
delta_mode=False,
|
|
52
53
|
llm_config:Dict[str,Any]={}):
|
|
53
|
-
res,contexts = await asyncfy_with_semaphore(lambda: self.rag.stream_chat_oai(conversations,llm_config=llm_config))()
|
|
54
|
+
res,contexts = await asyncfy_with_semaphore(lambda: self.rag.stream_chat_oai(conversations,llm_config=llm_config))()
|
|
55
|
+
# res,contexts = await self.llm.async_stream_chat_oai(conversations,llm_config=llm_config)
|
|
54
56
|
for t in res:
|
|
55
57
|
yield (t,SingleOutputMeta(0,0))
|
|
56
58
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from io import BytesIO
|
|
2
|
-
import docx2txt
|
|
3
2
|
from autocoder.utils._markitdown import MarkItDown
|
|
4
3
|
import traceback
|
|
5
4
|
|
|
6
5
|
def extract_text_from_docx_old(docx_path):
|
|
6
|
+
import docx2txt
|
|
7
7
|
with open(docx_path, "rb") as f:
|
|
8
8
|
docx_content = f.read()
|
|
9
9
|
docx_file = BytesIO(docx_content)
|