auto-coder 0.1.303__tar.gz → 0.1.305__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.303 → auto_coder-0.1.305}/PKG-INFO +1 -1
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/auto_coder.egg-info/PKG-INFO +1 -1
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/auto_coder_runner.py +1 -1
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/chat_auto_coder.py +1 -1
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/commands/auto_command.py +1 -4
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/commands/auto_web.py +1 -9
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/auto_coder_lang.py +10 -1
- auto_coder-0.1.305/src/autocoder/common/global_cancel.py +82 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/dispacher/actions/action.py +8 -32
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/dispacher/actions/plugins/action_regex_project.py +2 -6
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/index/index.py +2 -4
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/auto_coder_utils/chat_stream_out.py +56 -11
- auto_coder-0.1.305/src/autocoder/utils/thread_utils.py +119 -0
- auto_coder-0.1.305/src/autocoder/version.py +1 -0
- auto_coder-0.1.303/src/autocoder/common/global_cancel.py +0 -21
- auto_coder-0.1.303/src/autocoder/utils/thread_utils.py +0 -210
- auto_coder-0.1.303/src/autocoder/version.py +0 -1
- {auto_coder-0.1.303 → auto_coder-0.1.305}/LICENSE +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/README.md +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/setup.cfg +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/setup.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/auto_coder.egg-info/SOURCES.txt +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/auto_coder.egg-info/dependency_links.txt +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/auto_coder.egg-info/entry_points.txt +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/auto_coder.egg-info/requires.txt +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/auto_coder.egg-info/top_level.txt +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/agent/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/agent/auto_demand_organizer.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/agent/auto_filegroup.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/agent/auto_guess_query.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/agent/auto_learn_from_commit.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/agent/auto_review_commit.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/agent/auto_tool.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/agent/coder.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/agent/designer.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/agent/planner.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/agent/project_reader.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/auto_coder.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/auto_coder_rag.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/auto_coder_server.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/benchmark.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/chat/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/chat_auto_coder_lang.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/command_args.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/command_parser.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/commands/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/commands/tools.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/JupyterClient.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/ShellClient.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/action_yml_file_manager.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/anything2images.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/anything2img.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/audio.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/auto_configure.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/buildin_tokenizer.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/chunk_validation.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/cleaner.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/code_auto_execute.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/code_auto_generate.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/code_auto_generate_diff.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/code_auto_generate_editblock.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/code_auto_generate_strict_diff.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/code_auto_merge.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/code_auto_merge_diff.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/code_auto_merge_editblock.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/code_auto_merge_strict_diff.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/code_modification_ranker.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/command_completer.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/command_generator.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/command_templates.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/computer_use.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/conf_import_export.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/conf_validator.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/const.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/context_pruner.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/conversation_pruner.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/files.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/git_utils.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/image_to_page.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/index_import_export.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/interpreter.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/llm_rerank.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/mcp_hub.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/mcp_server.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/mcp_servers/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/mcp_servers/mcp_server_gpt4o_mini_search.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/mcp_servers/mcp_server_perplexity.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/mcp_tools.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/memory_manager.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/model_speed_test.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/printer.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/recall_validation.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/result_manager.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/screenshots.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/search.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/search_replace.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/shells.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/stats_panel.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/stream_out_type.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/sys_prompt.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/text.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/types.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/common/utils_code_auto_generate.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/data/byzerllm.md +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/data/tokenizer.json +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/db/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/db/store.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/dispacher/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/dispacher/actions/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/dispacher/actions/copilot.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/dispacher/actions/plugins/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/dispacher/actions/plugins/action_translate.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/events/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/events/event_content.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/events/event_manager.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/events/event_manager_singleton.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/events/event_store.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/events/event_types.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/index/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/index/entry.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/index/filter/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/index/filter/normal_filter.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/index/filter/quick_filter.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/index/for_command.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/index/symbols_utils.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/index/types.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/lang.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/models.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/plugins/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/plugins/dynamic_completion_example.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/plugins/git_helper_plugin.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/plugins/sample_plugin.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/plugins/token_helper_plugin.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/plugins/utils.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/privacy/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/privacy/model_filter.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/pyproject/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/api_server.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/cache/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/cache/base_cache.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/cache/byzer_storage_cache.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/cache/cache_result_merge.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/cache/file_monitor_cache.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/cache/local_byzer_storage_cache.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/cache/local_duckdb_storage_cache.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/cache/rag_file_meta.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/cache/simple_cache.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/conversation_to_queries.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/doc_filter.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/document_retriever.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/lang.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/llm_wrapper.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/loaders/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/loaders/docx_loader.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/loaders/excel_loader.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/loaders/pdf_loader.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/loaders/ppt_loader.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/long_context_rag.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/qa_conversation_strategy.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/rag_config.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/rag_entry.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/raw_rag.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/relevant_utils.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/searchable.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/simple_directory_reader.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/simple_rag.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/stream_event/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/stream_event/event_writer.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/stream_event/types.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/token_checker.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/token_counter.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/token_limiter.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/token_limiter_utils.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/types.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/utils.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/rag/variable_holder.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/regexproject/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/run_context.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/suffixproject/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/tsproject/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/_markitdown.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/auto_coder_utils/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/auto_project_type.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/chat_auto_coder_utils/__init__.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/conversation_store.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/llm_client_interceptors.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/llms.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/log_capture.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/model_provider_selector.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/multi_turn.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/operate_config_api.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/print_table.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/project_structure.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/queue_communicate.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/request_event_queue.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/request_queue.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/rest.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/stream_thinking.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/tests.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/types.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/tests/test_action_regex_project.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/tests/test_action_yml_file_manager.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/tests/test_chat_auto_coder.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/tests/test_code_auto_merge_editblock.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/tests/test_command_completer.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/tests/test_planner.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/tests/test_plugins.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/tests/test_privacy.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/tests/test_queue_communicate.py +0 -0
- {auto_coder-0.1.303 → auto_coder-0.1.305}/tests/test_symbols_utils.py +0 -0
|
@@ -2594,7 +2594,7 @@ def conf_import(path: str):
|
|
|
2594
2594
|
def auto_command(query: str,extra_args: Dict[str,Any]={}):
|
|
2595
2595
|
"""处理/auto指令"""
|
|
2596
2596
|
from autocoder.commands.auto_command import CommandAutoTuner, AutoCommandRequest, CommandConfig, MemoryConfig
|
|
2597
|
-
args = get_final_config()
|
|
2597
|
+
args = get_final_config()
|
|
2598
2598
|
|
|
2599
2599
|
# 准备请求参数
|
|
2600
2600
|
request = AutoCommandRequest(
|
|
@@ -623,7 +623,7 @@ def main():
|
|
|
623
623
|
|
|
624
624
|
elif user_input.startswith("/auto"):
|
|
625
625
|
query = user_input[len("/auto") :].strip()
|
|
626
|
-
auto_command(
|
|
626
|
+
auto_command(query)
|
|
627
627
|
elif user_input.startswith("/debug"):
|
|
628
628
|
code = user_input[len("/debug") :].strip()
|
|
629
629
|
try:
|
|
@@ -500,10 +500,7 @@ class CommandAutoTuner:
|
|
|
500
500
|
result_manager = ResultManager()
|
|
501
501
|
|
|
502
502
|
while True:
|
|
503
|
-
|
|
504
|
-
printer = Printer(console)
|
|
505
|
-
printer.print_in_terminal("generation_cancelled")
|
|
506
|
-
break
|
|
503
|
+
global_cancel.check_and_raise()
|
|
507
504
|
# 执行命令
|
|
508
505
|
command = response.suggestions[0].command
|
|
509
506
|
parameters = response.suggestions[0].parameters
|
|
@@ -794,15 +794,7 @@ class AutoWebTuner:
|
|
|
794
794
|
logger.info(f"开始执行迭代 {iterations}/{max_iterations}")
|
|
795
795
|
|
|
796
796
|
# 检查是否需要取消操作
|
|
797
|
-
|
|
798
|
-
logger.info("检测到取消请求,停止操作")
|
|
799
|
-
self.printer.print_in_terminal(
|
|
800
|
-
"operation_cancelled", style="yellow")
|
|
801
|
-
return AutoWebResponse(
|
|
802
|
-
explanation="操作已取消",
|
|
803
|
-
overall_status="cancelled",
|
|
804
|
-
actions=[]
|
|
805
|
-
)
|
|
797
|
+
global_cancel.check_and_raise()
|
|
806
798
|
|
|
807
799
|
# 如果没有更多操作,认为任务完成
|
|
808
800
|
if not plan.actions:
|
|
@@ -66,6 +66,11 @@ MESSAGES = {
|
|
|
66
66
|
"index_related_files_fail": "⚠️ Failed to find related files for chunk {{ chunk_count }}",
|
|
67
67
|
"index_file_removed": "🗑️ Removed non-existent file index: {{ file_path }}",
|
|
68
68
|
"index_file_saved": "💾 Saved index file, updated {{ updated_files }} files, removed {{ removed_files }} files, input_tokens: {{ input_tokens }}, output_tokens: {{ output_tokens }}, input_cost: {{ input_cost }}, output_cost: {{ output_cost }}",
|
|
69
|
+
"task_cancelled_by_user": "Task was cancelled by user",
|
|
70
|
+
"cancellation_requested": "Cancellation requested, waiting for thread to terminate...",
|
|
71
|
+
"force_terminating_thread": "Force terminating thread after timeout",
|
|
72
|
+
"force_raising_keyboard_interrupt": "Force raising KeyboardInterrupt after timeout",
|
|
73
|
+
"thread_terminated": "Thread terminated",
|
|
69
74
|
"human_as_model_instructions": (
|
|
70
75
|
"You are now in Human as Model mode. The content has been copied to your clipboard.\n"
|
|
71
76
|
"The system is waiting for your input. When finished, enter 'EOF' on a new line to submit.\n"
|
|
@@ -156,7 +161,6 @@ MESSAGES = {
|
|
|
156
161
|
"generated_shell_script": "Generated Shell Script",
|
|
157
162
|
"confirm_execute_shell_script": "Do you want to execute this shell script?",
|
|
158
163
|
"shell_script_not_executed": "Shell script was not executed",
|
|
159
|
-
"conf_not_found": "Configuration file not found: {{path}}",
|
|
160
164
|
"index_export_success": "Index exported successfully: {{path}}",
|
|
161
165
|
"index_import_success": "Index imported successfully: {{path}}",
|
|
162
166
|
"edits_title": "edits",
|
|
@@ -279,6 +283,11 @@ MESSAGES = {
|
|
|
279
283
|
"index_related_files_fail": "⚠️ 无法为块 {{ chunk_count }} 找到相关文件",
|
|
280
284
|
"index_file_removed": "🗑️ 已移除不存在的文件索引:{{ file_path }}",
|
|
281
285
|
"index_file_saved": "💾 已保存索引文件,更新了 {{ updated_files }} 个文件,移除了 {{ removed_files }} 个文件,输入token数: {{ input_tokens }}, 输出token数: {{ output_tokens }}, 输入成本: {{ input_cost }}, 输出成本: {{ output_cost }}",
|
|
286
|
+
"task_cancelled_by_user": "任务被用户取消",
|
|
287
|
+
"cancellation_requested": "已请求取消,正在等待线程终止...",
|
|
288
|
+
"force_terminating_thread": "线程超时强制终止",
|
|
289
|
+
"force_raising_keyboard_interrupt": "超时强制抛出键盘中断异常",
|
|
290
|
+
"thread_terminated": "线程已终止",
|
|
282
291
|
"human_as_model_instructions": (
|
|
283
292
|
"您现在处于人类作为模型模式。内容已复制到您的剪贴板。\n"
|
|
284
293
|
"系统正在等待您的输入。完成后,在新行输入'EOF'提交。\n"
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import threading
|
|
2
|
+
from typing import Dict, Optional, Any
|
|
3
|
+
|
|
4
|
+
class CancelRequestedException(Exception):
|
|
5
|
+
"""当取消请求被触发时抛出的异常"""
|
|
6
|
+
def __init__(self, token: Optional[str] = None, message: str = "Operation was cancelled"):
|
|
7
|
+
self.token = token
|
|
8
|
+
self.message = message
|
|
9
|
+
super().__init__(self.message)
|
|
10
|
+
|
|
11
|
+
class GlobalCancel:
|
|
12
|
+
def __init__(self):
|
|
13
|
+
self._global_flag = False
|
|
14
|
+
self._token_flags: Dict[str, bool] = {}
|
|
15
|
+
self._lock = threading.Lock()
|
|
16
|
+
self._context: Dict[str, Any] = {} # 存储与取消相关的上下文信息
|
|
17
|
+
|
|
18
|
+
@property
|
|
19
|
+
def requested(self) -> bool:
|
|
20
|
+
"""检查是否请求了全局取消(向后兼容)"""
|
|
21
|
+
with self._lock:
|
|
22
|
+
return self._global_flag
|
|
23
|
+
|
|
24
|
+
def is_requested(self, token: Optional[str] = None) -> bool:
|
|
25
|
+
"""检查是否请求了特定token或全局的取消"""
|
|
26
|
+
with self._lock:
|
|
27
|
+
# 全局标志总是优先
|
|
28
|
+
if self._global_flag:
|
|
29
|
+
return True
|
|
30
|
+
# 如果提供了token,检查该token的标志
|
|
31
|
+
if token is not None and token in self._token_flags:
|
|
32
|
+
return self._token_flags[token]
|
|
33
|
+
return False
|
|
34
|
+
|
|
35
|
+
def set(self, token: Optional[str] = None, context: Optional[Dict[str, Any]] = None) -> None:
|
|
36
|
+
"""设置特定token或全局的取消标志"""
|
|
37
|
+
with self._lock:
|
|
38
|
+
if token is None:
|
|
39
|
+
self._global_flag = True
|
|
40
|
+
else:
|
|
41
|
+
self._token_flags[token] = True
|
|
42
|
+
|
|
43
|
+
# 存储上下文
|
|
44
|
+
if context:
|
|
45
|
+
if token is None:
|
|
46
|
+
self._context.update(context)
|
|
47
|
+
else:
|
|
48
|
+
if "tokens" not in self._context:
|
|
49
|
+
self._context["tokens"] = {}
|
|
50
|
+
self._context["tokens"][token] = context
|
|
51
|
+
|
|
52
|
+
def reset(self, token: Optional[str] = None) -> None:
|
|
53
|
+
"""重置特定token或全局的取消标志"""
|
|
54
|
+
with self._lock:
|
|
55
|
+
if token is None:
|
|
56
|
+
# 全局重置
|
|
57
|
+
self._global_flag = False
|
|
58
|
+
self._token_flags.clear()
|
|
59
|
+
self._context.clear()
|
|
60
|
+
else:
|
|
61
|
+
# 特定token重置
|
|
62
|
+
if token in self._token_flags:
|
|
63
|
+
del self._token_flags[token]
|
|
64
|
+
if "tokens" in self._context and token in self._context["tokens"]:
|
|
65
|
+
del self._context["tokens"][token]
|
|
66
|
+
|
|
67
|
+
def get_context(self, token: Optional[str] = None) -> Dict[str, Any]:
|
|
68
|
+
"""获取与取消相关的上下文信息"""
|
|
69
|
+
with self._lock:
|
|
70
|
+
if token is None:
|
|
71
|
+
return self._context.copy()
|
|
72
|
+
if "tokens" in self._context and token in self._context["tokens"]:
|
|
73
|
+
return self._context["tokens"][token].copy()
|
|
74
|
+
return {}
|
|
75
|
+
|
|
76
|
+
def check_and_raise(self, token: Optional[str] = None) -> None:
|
|
77
|
+
"""检查是否请求了取消,如果是则抛出异常"""
|
|
78
|
+
if self.is_requested(token):
|
|
79
|
+
context = self.get_context(token)
|
|
80
|
+
raise CancelRequestedException(token, context.get("message", "Operation was cancelled"))
|
|
81
|
+
|
|
82
|
+
global_cancel = GlobalCancel()
|
|
@@ -112,10 +112,7 @@ class ActionTSProject(BaseAction):
|
|
|
112
112
|
f"Content(send to model) is {content_length} tokens, which is larger than the maximum input length {self.args.model_max_input_length}"
|
|
113
113
|
)
|
|
114
114
|
|
|
115
|
-
|
|
116
|
-
printer = Printer()
|
|
117
|
-
raise Exception(printer.get_message_from_key(
|
|
118
|
-
"generation_cancelled"))
|
|
115
|
+
global_cancel.check_and_raise()
|
|
119
116
|
|
|
120
117
|
if args.execute:
|
|
121
118
|
self.printer.print_in_terminal("code_generation_start")
|
|
@@ -181,10 +178,7 @@ class ActionTSProject(BaseAction):
|
|
|
181
178
|
action_file=self.args.file
|
|
182
179
|
).to_dict())
|
|
183
180
|
|
|
184
|
-
|
|
185
|
-
printer = Printer()
|
|
186
|
-
raise Exception(printer.get_message_from_key(
|
|
187
|
-
"generation_cancelled"))
|
|
181
|
+
global_cancel.check_and_raise()
|
|
188
182
|
|
|
189
183
|
merge_result = None
|
|
190
184
|
if args.execute and args.auto_merge:
|
|
@@ -249,10 +243,7 @@ class ActionPyScriptProject(BaseAction):
|
|
|
249
243
|
|
|
250
244
|
def process_content(self, source_code_list: SourceCodeList):
|
|
251
245
|
args = self.args
|
|
252
|
-
|
|
253
|
-
printer = Printer()
|
|
254
|
-
raise Exception(printer.get_message_from_key(
|
|
255
|
-
"generation_cancelled"))
|
|
246
|
+
global_cancel.check_and_raise()
|
|
256
247
|
|
|
257
248
|
if args.execute:
|
|
258
249
|
self.printer.print_in_terminal("code_generation_start")
|
|
@@ -318,10 +309,7 @@ class ActionPyScriptProject(BaseAction):
|
|
|
318
309
|
action_file=self.args.file
|
|
319
310
|
).to_dict())
|
|
320
311
|
|
|
321
|
-
|
|
322
|
-
printer = Printer()
|
|
323
|
-
raise Exception(printer.get_message_from_key(
|
|
324
|
-
"generation_cancelled"))
|
|
312
|
+
global_cancel.check_and_raise()
|
|
325
313
|
|
|
326
314
|
merge_result = None
|
|
327
315
|
if args.execute and args.auto_merge:
|
|
@@ -410,10 +398,7 @@ class ActionPyProject(BaseAction):
|
|
|
410
398
|
max_length=self.args.model_max_input_length
|
|
411
399
|
)
|
|
412
400
|
|
|
413
|
-
|
|
414
|
-
printer = Printer()
|
|
415
|
-
raise Exception(printer.get_message_from_key(
|
|
416
|
-
"generation_cancelled"))
|
|
401
|
+
global_cancel.check_and_raise()
|
|
417
402
|
|
|
418
403
|
if args.execute:
|
|
419
404
|
self.printer.print_in_terminal("code_generation_start")
|
|
@@ -479,10 +464,7 @@ class ActionPyProject(BaseAction):
|
|
|
479
464
|
action_file=self.args.file
|
|
480
465
|
).to_dict())
|
|
481
466
|
|
|
482
|
-
|
|
483
|
-
printer = Printer()
|
|
484
|
-
raise Exception(printer.get_message_from_key(
|
|
485
|
-
"generation_cancelled"))
|
|
467
|
+
global_cancel.check_and_raise()
|
|
486
468
|
|
|
487
469
|
merge_result = None
|
|
488
470
|
if args.execute and args.auto_merge:
|
|
@@ -563,10 +545,7 @@ class ActionSuffixProject(BaseAction):
|
|
|
563
545
|
f"Content(send to model) is {content_length} tokens, which is larger than the maximum input length {self.args.model_max_input_length}"
|
|
564
546
|
)
|
|
565
547
|
|
|
566
|
-
|
|
567
|
-
printer = Printer()
|
|
568
|
-
raise Exception(printer.get_message_from_key(
|
|
569
|
-
"generation_cancelled"))
|
|
548
|
+
global_cancel.check_and_raise()
|
|
570
549
|
|
|
571
550
|
if args.execute:
|
|
572
551
|
self.printer.print_in_terminal("code_generation_start")
|
|
@@ -631,10 +610,7 @@ class ActionSuffixProject(BaseAction):
|
|
|
631
610
|
action_file=self.args.file
|
|
632
611
|
).to_dict())
|
|
633
612
|
|
|
634
|
-
|
|
635
|
-
printer = Printer()
|
|
636
|
-
raise Exception(printer.get_message_from_key(
|
|
637
|
-
"generation_cancelled"))
|
|
613
|
+
global_cancel.check_and_raise()
|
|
638
614
|
|
|
639
615
|
merge_result = None
|
|
640
616
|
if args.execute and args.auto_merge:
|
|
@@ -66,9 +66,7 @@ class ActionRegexProject:
|
|
|
66
66
|
|
|
67
67
|
start_time = time.time()
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
printer = Printer()
|
|
71
|
-
raise Exception(printer.get_message_from_key("generation_cancelled"))
|
|
69
|
+
global_cancel.check_and_raise()
|
|
72
70
|
|
|
73
71
|
if args.execute:
|
|
74
72
|
self.printer.print_in_terminal("code_generation_start")
|
|
@@ -128,9 +126,7 @@ class ActionRegexProject:
|
|
|
128
126
|
action_file=self.args.file
|
|
129
127
|
).to_dict())
|
|
130
128
|
|
|
131
|
-
|
|
132
|
-
printer = Printer()
|
|
133
|
-
raise Exception(printer.get_message_from_key("generation_cancelled"))
|
|
129
|
+
global_cancel.check_and_raise()
|
|
134
130
|
|
|
135
131
|
merge_result = None
|
|
136
132
|
if args.execute and args.auto_merge:
|
|
@@ -296,8 +296,7 @@ class IndexManager:
|
|
|
296
296
|
return False
|
|
297
297
|
|
|
298
298
|
def build_index_for_single_source(self, source: SourceCode):
|
|
299
|
-
|
|
300
|
-
return None
|
|
299
|
+
global_cancel.check_and_raise()
|
|
301
300
|
|
|
302
301
|
file_path = source.module_name
|
|
303
302
|
if not os.path.exists(file_path):
|
|
@@ -552,8 +551,7 @@ class IndexManager:
|
|
|
552
551
|
for source in wait_to_build_files
|
|
553
552
|
]
|
|
554
553
|
for future in as_completed(futures):
|
|
555
|
-
|
|
556
|
-
break
|
|
554
|
+
global_cancel.check_and_raise()
|
|
557
555
|
result = future.result()
|
|
558
556
|
if result is not None:
|
|
559
557
|
counter += 1
|
{auto_coder-0.1.303 → auto_coder-0.1.305}/src/autocoder/utils/auto_coder_utils/chat_stream_out.py
RENAMED
|
@@ -13,7 +13,7 @@ from autocoder.utils.request_queue import request_queue
|
|
|
13
13
|
import time
|
|
14
14
|
from byzerllm.utils.types import SingleOutputMeta
|
|
15
15
|
from autocoder.common import AutoCoderArgs
|
|
16
|
-
from autocoder.common.global_cancel import global_cancel
|
|
16
|
+
from autocoder.common.global_cancel import global_cancel, CancelRequestedException
|
|
17
17
|
from autocoder.events.event_manager_singleton import get_event_manager
|
|
18
18
|
from autocoder.events import event_content as EventContentCreator
|
|
19
19
|
from autocoder.events.event_types import EventMetadata
|
|
@@ -68,23 +68,35 @@ class MultiStreamRenderer:
|
|
|
68
68
|
|
|
69
69
|
def _process_stream(self,
|
|
70
70
|
stream_idx: int,
|
|
71
|
-
stream_generator: Generator[Tuple[str, Dict[str, Any]], None, None]
|
|
71
|
+
stream_generator: Generator[Tuple[str, Dict[str, Any]], None, None],
|
|
72
|
+
cancel_token: Optional[str] = None):
|
|
72
73
|
"""Process a single stream in a separate thread"""
|
|
73
74
|
stream = self.streams[stream_idx]
|
|
74
75
|
try:
|
|
75
76
|
for content, meta in stream_generator:
|
|
77
|
+
try:
|
|
78
|
+
# 使用新的异常机制检查取消请求
|
|
79
|
+
global_cancel.check_and_raise(cancel_token)
|
|
80
|
+
except CancelRequestedException:
|
|
81
|
+
break
|
|
82
|
+
|
|
76
83
|
if content:
|
|
77
84
|
stream.update(content)
|
|
85
|
+
except CancelRequestedException:
|
|
86
|
+
# 处理取消异常
|
|
87
|
+
stream.update("\n\n**Operation was cancelled**")
|
|
78
88
|
finally:
|
|
79
89
|
stream.complete()
|
|
80
90
|
|
|
81
91
|
def render_streams(self,
|
|
82
|
-
stream_generators: List[Generator[Tuple[str, Dict[str, Any]], None, None]]
|
|
92
|
+
stream_generators: List[Generator[Tuple[str, Dict[str, Any]], None, None]],
|
|
93
|
+
cancel_token: Optional[str] = None) -> List[str]:
|
|
83
94
|
"""
|
|
84
95
|
Render multiple streams simultaneously
|
|
85
96
|
|
|
86
97
|
Args:
|
|
87
98
|
stream_generators: List of stream generators to render
|
|
99
|
+
cancel_token: Optional cancellation token
|
|
88
100
|
|
|
89
101
|
Returns:
|
|
90
102
|
List of final content from each stream
|
|
@@ -94,7 +106,7 @@ class MultiStreamRenderer:
|
|
|
94
106
|
# Start processing threads
|
|
95
107
|
threads = []
|
|
96
108
|
for i, generator in enumerate(stream_generators):
|
|
97
|
-
thread = Thread(target=self._process_stream, args=(i, generator))
|
|
109
|
+
thread = Thread(target=self._process_stream, args=(i, generator, cancel_token))
|
|
98
110
|
thread.daemon = True
|
|
99
111
|
thread.start()
|
|
100
112
|
threads.append(thread)
|
|
@@ -102,6 +114,13 @@ class MultiStreamRenderer:
|
|
|
102
114
|
try:
|
|
103
115
|
with Live(self.layout, console=self.console, refresh_per_second=10) as live:
|
|
104
116
|
while any(not stream.is_complete for stream in self.streams):
|
|
117
|
+
try:
|
|
118
|
+
# 使用新的异常机制检查取消请求
|
|
119
|
+
global_cancel.check_and_raise(cancel_token)
|
|
120
|
+
except CancelRequestedException:
|
|
121
|
+
print("\nCancelling streams...")
|
|
122
|
+
break
|
|
123
|
+
|
|
105
124
|
# Update all panels
|
|
106
125
|
for i, stream in enumerate(self.streams):
|
|
107
126
|
panel = Panel(
|
|
@@ -116,7 +135,11 @@ class MultiStreamRenderer:
|
|
|
116
135
|
time.sleep(0.1) # Prevent excessive CPU usage
|
|
117
136
|
|
|
118
137
|
except KeyboardInterrupt:
|
|
138
|
+
# 键盘中断时设置取消标志
|
|
139
|
+
global_cancel.set(cancel_token, {"message": "Keyboard interrupt"})
|
|
119
140
|
print("\nStopping streams...")
|
|
141
|
+
except CancelRequestedException:
|
|
142
|
+
print("\nCancelling streams...")
|
|
120
143
|
|
|
121
144
|
# Wait for all threads to complete
|
|
122
145
|
for thread in threads:
|
|
@@ -128,7 +151,8 @@ def multi_stream_out(
|
|
|
128
151
|
stream_generators: List[Generator[Tuple[str, Dict[str, Any]], None, None]],
|
|
129
152
|
titles: List[str],
|
|
130
153
|
layout: str = "horizontal",
|
|
131
|
-
console: Optional[Console] = None
|
|
154
|
+
console: Optional[Console] = None,
|
|
155
|
+
cancel_token: Optional[str] = None
|
|
132
156
|
) -> List[str]:
|
|
133
157
|
"""
|
|
134
158
|
Render multiple streams with Rich
|
|
@@ -138,12 +162,13 @@ def multi_stream_out(
|
|
|
138
162
|
titles: List of titles for each stream
|
|
139
163
|
layout: "horizontal" or "vertical"
|
|
140
164
|
console: Optional Rich console instance
|
|
165
|
+
cancel_token: Optional cancellation token
|
|
141
166
|
|
|
142
167
|
Returns:
|
|
143
168
|
List of final content from each stream
|
|
144
169
|
"""
|
|
145
170
|
renderer = MultiStreamRenderer(titles, layout, console)
|
|
146
|
-
return renderer.render_streams(stream_generators)
|
|
171
|
+
return renderer.render_streams(stream_generators, cancel_token)
|
|
147
172
|
|
|
148
173
|
|
|
149
174
|
def stream_out(
|
|
@@ -155,7 +180,8 @@ def stream_out(
|
|
|
155
180
|
final_title: Optional[str] = None,
|
|
156
181
|
args: Optional[AutoCoderArgs] = None,
|
|
157
182
|
display_func: Optional[Callable] = None,
|
|
158
|
-
extra_meta: Dict[str, Any] = {}
|
|
183
|
+
extra_meta: Dict[str, Any] = {},
|
|
184
|
+
cancel_token: Optional[str] = None
|
|
159
185
|
) -> Tuple[str, Optional[SingleOutputMeta]]:
|
|
160
186
|
"""
|
|
161
187
|
处理流式输出事件并在终端中展示
|
|
@@ -167,6 +193,9 @@ def stream_out(
|
|
|
167
193
|
model_name: 模型名称
|
|
168
194
|
title: 面板标题,如果没有提供则使用默认值
|
|
169
195
|
args: AutoCoderArgs对象
|
|
196
|
+
display_func: 可选的显示函数
|
|
197
|
+
extra_meta: 额外的元数据
|
|
198
|
+
cancel_token: 可选的取消令牌
|
|
170
199
|
Returns:
|
|
171
200
|
Tuple[str, Dict[SingleOutputMeta]]: 返回完整的响应内容和最后的元数据
|
|
172
201
|
"""
|
|
@@ -197,10 +226,8 @@ def stream_out(
|
|
|
197
226
|
console=console
|
|
198
227
|
) as live:
|
|
199
228
|
for res in stream_generator:
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
printer.print_in_terminal("generation_cancelled")
|
|
203
|
-
break
|
|
229
|
+
global_cancel.check_and_raise(cancel_token)
|
|
230
|
+
|
|
204
231
|
last_meta = res[1]
|
|
205
232
|
content = res[0]
|
|
206
233
|
|
|
@@ -312,6 +339,24 @@ def stream_out(
|
|
|
312
339
|
)
|
|
313
340
|
)
|
|
314
341
|
|
|
342
|
+
except CancelRequestedException as cancel_exc:
|
|
343
|
+
# 捕获取消异常,显示取消信息
|
|
344
|
+
console.print(Panel(
|
|
345
|
+
"Generation was cancelled",
|
|
346
|
+
title=f"Cancelled[ {panel_title} ]",
|
|
347
|
+
border_style="yellow"
|
|
348
|
+
))
|
|
349
|
+
|
|
350
|
+
if request_id and request_queue:
|
|
351
|
+
request_queue.add_request(
|
|
352
|
+
request_id,
|
|
353
|
+
RequestValue(
|
|
354
|
+
value=StreamValue(value=["Operation was cancelled"]),
|
|
355
|
+
status=RequestOption.FAILED
|
|
356
|
+
),
|
|
357
|
+
)
|
|
358
|
+
raise cancel_exc
|
|
359
|
+
|
|
315
360
|
except Exception as e:
|
|
316
361
|
console.print(Panel(
|
|
317
362
|
f"Error: {str(e)}",
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
from functools import wraps
|
|
2
|
+
from typing import Any, Optional, Dict, Callable
|
|
3
|
+
import threading
|
|
4
|
+
import time
|
|
5
|
+
from autocoder.common.global_cancel import global_cancel, CancelRequestedException
|
|
6
|
+
from autocoder.common.printer import Printer
|
|
7
|
+
from autocoder.common.auto_coder_lang import get_message, get_message_with_format
|
|
8
|
+
from autocoder.events.event_manager_singleton import get_event_manager
|
|
9
|
+
from autocoder.events import event_content as EventContentCreator
|
|
10
|
+
from autocoder.events.event_types import EventMetadata
|
|
11
|
+
|
|
12
|
+
printer = Printer()
|
|
13
|
+
|
|
14
|
+
def run_in_raw_thread(token: Optional[str] = None, context: Optional[Dict[str, Any]] = None):
|
|
15
|
+
"""A decorator that runs a function in a separate thread and handles exceptions.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
token (Optional[str]): Optional cancellation token for this specific thread
|
|
19
|
+
context (Optional[Dict[str, Any]]): Optional context information for cancellation
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
A wrapper function that executes the decorated function in a thread
|
|
23
|
+
|
|
24
|
+
The decorator will:
|
|
25
|
+
1. Run the function in a separate thread
|
|
26
|
+
2. Handle KeyboardInterrupt properly
|
|
27
|
+
3. Propagate exceptions from the thread
|
|
28
|
+
4. Support function arguments
|
|
29
|
+
5. Preserve function metadata
|
|
30
|
+
6. Support token-based cancellation
|
|
31
|
+
7. Provide context information for cancellation
|
|
32
|
+
"""
|
|
33
|
+
def decorator(func: Callable):
|
|
34
|
+
|
|
35
|
+
@wraps(func)
|
|
36
|
+
def wrapper(*args, **kwargs):
|
|
37
|
+
# Store thread results
|
|
38
|
+
result = []
|
|
39
|
+
exception_raised = [None] # 存储工作线程中的异常
|
|
40
|
+
thread_token = token
|
|
41
|
+
thread_context = context or {}
|
|
42
|
+
thread_terminated = threading.Event() # 用于标记线程是否已终止
|
|
43
|
+
|
|
44
|
+
def worker():
|
|
45
|
+
try:
|
|
46
|
+
# 执行用户函数
|
|
47
|
+
ret = func(*args, **kwargs)
|
|
48
|
+
result.append(ret)
|
|
49
|
+
except CancelRequestedException as e:
|
|
50
|
+
# 处理取消异常
|
|
51
|
+
printer.print_in_terminal("generation_cancelled")
|
|
52
|
+
exception_raised[0] = e
|
|
53
|
+
except Exception as e:
|
|
54
|
+
# 存储其他异常
|
|
55
|
+
exception_raised[0] = e
|
|
56
|
+
finally:
|
|
57
|
+
# 无论如何执行完毕后,重置取消标志并标记线程已终止
|
|
58
|
+
global_cancel.reset(thread_token)
|
|
59
|
+
thread_terminated.set()
|
|
60
|
+
|
|
61
|
+
# Create and start thread with a meaningful name
|
|
62
|
+
thread = threading.Thread(target=worker, name=f"{func.__name__}_thread")
|
|
63
|
+
thread.daemon = True # Make thread daemon so it doesn't prevent program exit
|
|
64
|
+
|
|
65
|
+
try:
|
|
66
|
+
thread.start()
|
|
67
|
+
|
|
68
|
+
# Poll thread status with timeout to allow for interruption
|
|
69
|
+
cancelled_by_keyboard = False
|
|
70
|
+
max_wait_time = 30 # 最大等待时间(秒)
|
|
71
|
+
wait_start_time = time.time()
|
|
72
|
+
|
|
73
|
+
while thread.is_alive():
|
|
74
|
+
# 每次等待较短时间,以便能够及时响应中断
|
|
75
|
+
thread.join(0.1)
|
|
76
|
+
|
|
77
|
+
# 检查是否已经超过最大等待时间(仅适用于已取消的情况)
|
|
78
|
+
elapsed_time = time.time() - wait_start_time
|
|
79
|
+
if cancelled_by_keyboard and elapsed_time > max_wait_time:
|
|
80
|
+
printer.print_in_terminal("force_terminating_thread")
|
|
81
|
+
break
|
|
82
|
+
|
|
83
|
+
# 检查线程间的取消请求
|
|
84
|
+
if global_cancel.is_requested(thread_token):
|
|
85
|
+
# 传播取消请求到工作线程
|
|
86
|
+
raise CancelRequestedException(thread_token)
|
|
87
|
+
|
|
88
|
+
# 如果工作线程出现了异常,在主线程中重新抛出
|
|
89
|
+
if exception_raised[0] is not None:
|
|
90
|
+
raise exception_raised[0]
|
|
91
|
+
|
|
92
|
+
# 返回结果
|
|
93
|
+
return result[0] if result else None
|
|
94
|
+
|
|
95
|
+
except KeyboardInterrupt:
|
|
96
|
+
# 设置取消标志
|
|
97
|
+
cancel_context = {"message": get_message("task_cancelled_by_user"), "source": "keyboard_interrupt"}
|
|
98
|
+
cancel_context.update(thread_context)
|
|
99
|
+
global_cancel.set(thread_token, cancel_context)
|
|
100
|
+
printer.print_in_terminal("cancellation_requested")
|
|
101
|
+
|
|
102
|
+
# 标记为键盘中断取消
|
|
103
|
+
cancelled_by_keyboard = True
|
|
104
|
+
wait_start_time = time.time()
|
|
105
|
+
|
|
106
|
+
# 等待线程终止或检测到取消
|
|
107
|
+
while thread.is_alive() and not thread_terminated.is_set():
|
|
108
|
+
thread.join(0.5)
|
|
109
|
+
elapsed_time = time.time() - wait_start_time
|
|
110
|
+
if elapsed_time > max_wait_time:
|
|
111
|
+
printer.print_in_terminal("force_raising_keyboard_interrupt")
|
|
112
|
+
break
|
|
113
|
+
|
|
114
|
+
# 如果线程已终止且有异常,优先抛出该异常
|
|
115
|
+
if exception_raised[0] is not None:
|
|
116
|
+
raise exception_raised[0]
|
|
117
|
+
|
|
118
|
+
return wrapper
|
|
119
|
+
return decorator
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.305"
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import threading
|
|
2
|
-
|
|
3
|
-
class GlobalCancel:
|
|
4
|
-
def __init__(self):
|
|
5
|
-
self._flag = False
|
|
6
|
-
self._lock = threading.Lock()
|
|
7
|
-
|
|
8
|
-
@property
|
|
9
|
-
def requested(self):
|
|
10
|
-
with self._lock:
|
|
11
|
-
return self._flag
|
|
12
|
-
|
|
13
|
-
def set(self):
|
|
14
|
-
with self._lock:
|
|
15
|
-
self._flag = True
|
|
16
|
-
|
|
17
|
-
def reset(self):
|
|
18
|
-
with self._lock:
|
|
19
|
-
self._flag = False
|
|
20
|
-
|
|
21
|
-
global_cancel = GlobalCancel()
|