auto-coder 1.0.0__py3-none-any.whl → 2.0.1__py3-none-any.whl
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-2.0.1.dist-info/LICENSE +158 -0
- auto_coder-2.0.1.dist-info/METADATA +558 -0
- auto_coder-2.0.1.dist-info/RECORD +795 -0
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.dist-info}/WHEEL +1 -1
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.dist-info}/entry_points.txt +3 -3
- autocoder/__init__.py +31 -0
- autocoder/agent/auto_filegroup.py +32 -13
- autocoder/agent/auto_learn_from_commit.py +9 -1
- autocoder/agent/base_agentic/__init__.py +3 -0
- autocoder/agent/base_agentic/agent_hub.py +1 -1
- autocoder/agent/base_agentic/base_agent.py +235 -136
- autocoder/agent/base_agentic/default_tools.py +119 -118
- autocoder/agent/base_agentic/test_base_agent.py +1 -1
- autocoder/agent/base_agentic/tool_registry.py +32 -20
- autocoder/agent/base_agentic/tools/read_file_tool_resolver.py +24 -3
- autocoder/agent/base_agentic/tools/write_to_file_tool_resolver.py +24 -11
- autocoder/agent/base_agentic/types.py +42 -0
- autocoder/agent/entry_command_agent/chat.py +77 -73
- autocoder/auto_coder.py +31 -40
- autocoder/auto_coder_rag.py +11 -1084
- autocoder/auto_coder_runner.py +962 -2345
- autocoder/auto_coder_terminal.py +26 -0
- autocoder/auto_coder_terminal_v3.py +190 -0
- autocoder/chat/conf_command.py +224 -124
- autocoder/chat/models_command.py +361 -299
- autocoder/chat/rules_command.py +79 -31
- autocoder/chat_auto_coder.py +988 -398
- autocoder/chat_auto_coder_lang.py +23 -732
- autocoder/commands/auto_command.py +25 -8
- autocoder/commands/auto_web.py +1 -1
- autocoder/commands/tools.py +44 -44
- autocoder/common/__init__.py +150 -128
- autocoder/common/ac_style_command_parser/__init__.py +39 -2
- autocoder/common/ac_style_command_parser/config.py +422 -0
- autocoder/common/ac_style_command_parser/parser.py +292 -78
- autocoder/common/ac_style_command_parser/test_parser.py +241 -16
- autocoder/common/ac_style_command_parser/test_typed_parser.py +342 -0
- autocoder/common/ac_style_command_parser/typed_parser.py +653 -0
- autocoder/common/action_yml_file_manager.py +25 -13
- autocoder/common/agent_events/__init__.py +52 -0
- autocoder/common/agent_events/agent_event_emitter.py +193 -0
- autocoder/common/agent_events/event_factory.py +177 -0
- autocoder/common/agent_events/examples.py +307 -0
- autocoder/common/agent_events/types.py +113 -0
- autocoder/common/agent_events/utils.py +68 -0
- autocoder/common/agent_hooks/__init__.py +44 -0
- autocoder/common/agent_hooks/examples.py +582 -0
- autocoder/common/agent_hooks/hook_executor.py +217 -0
- autocoder/common/agent_hooks/hook_manager.py +288 -0
- autocoder/common/agent_hooks/types.py +133 -0
- autocoder/common/agent_hooks/utils.py +99 -0
- autocoder/common/agent_query_queue/queue_executor.py +324 -0
- autocoder/common/agent_query_queue/queue_manager.py +325 -0
- autocoder/common/agents/__init__.py +11 -0
- autocoder/common/agents/agent_manager.py +323 -0
- autocoder/common/agents/agent_parser.py +189 -0
- autocoder/common/agents/example_usage.py +344 -0
- autocoder/common/agents/integration_example.py +330 -0
- autocoder/common/agents/test_agent_parser.py +545 -0
- autocoder/common/async_utils.py +101 -0
- autocoder/common/auto_coder_lang.py +23 -972
- autocoder/common/autocoderargs_parser/__init__.py +14 -0
- autocoder/common/autocoderargs_parser/parser.py +184 -0
- autocoder/common/autocoderargs_parser/tests/__init__.py +1 -0
- autocoder/common/autocoderargs_parser/tests/test_args_parser.py +235 -0
- autocoder/common/autocoderargs_parser/tests/test_token_parser.py +195 -0
- autocoder/common/autocoderargs_parser/token_parser.py +290 -0
- autocoder/common/buildin_tokenizer.py +2 -4
- autocoder/common/code_auto_generate.py +149 -74
- autocoder/common/code_auto_generate_diff.py +163 -70
- autocoder/common/code_auto_generate_editblock.py +179 -89
- autocoder/common/code_auto_generate_strict_diff.py +167 -72
- autocoder/common/code_auto_merge_editblock.py +13 -6
- autocoder/common/code_modification_ranker.py +1 -1
- autocoder/common/command_completer.py +3 -3
- autocoder/common/command_file_manager/manager.py +183 -47
- autocoder/common/command_file_manager/test_command_file_manager.py +507 -0
- autocoder/common/command_templates.py +1 -1
- autocoder/common/conf_utils.py +2 -4
- autocoder/common/conversations/config.py +11 -3
- autocoder/common/conversations/get_conversation_manager.py +100 -2
- autocoder/common/conversations/llm_stats_models.py +264 -0
- autocoder/common/conversations/manager.py +112 -28
- autocoder/common/conversations/models.py +16 -2
- autocoder/common/conversations/storage/index_manager.py +134 -10
- autocoder/common/core_config/__init__.py +63 -0
- autocoder/common/core_config/agentic_mode_manager.py +109 -0
- autocoder/common/core_config/base_manager.py +123 -0
- autocoder/common/core_config/compatibility.py +151 -0
- autocoder/common/core_config/config_manager.py +156 -0
- autocoder/common/core_config/conversation_manager.py +31 -0
- autocoder/common/core_config/exclude_manager.py +72 -0
- autocoder/common/core_config/file_manager.py +177 -0
- autocoder/common/core_config/human_as_model_manager.py +129 -0
- autocoder/common/core_config/lib_manager.py +54 -0
- autocoder/common/core_config/main_manager.py +81 -0
- autocoder/common/core_config/mode_manager.py +126 -0
- autocoder/common/core_config/models.py +70 -0
- autocoder/common/core_config/test_memory_manager.py +1056 -0
- autocoder/common/env_manager.py +282 -0
- autocoder/common/env_manager_usage_example.py +211 -0
- autocoder/common/file_checkpoint/conversation_checkpoint.py +19 -19
- autocoder/common/file_checkpoint/manager.py +264 -48
- autocoder/common/file_checkpoint/test_backup.py +1 -18
- autocoder/common/file_checkpoint/test_manager.py +270 -1
- autocoder/common/file_checkpoint/test_store.py +1 -17
- autocoder/common/file_handler/__init__.py +23 -0
- autocoder/common/file_handler/active_context_handler.py +159 -0
- autocoder/common/file_handler/add_files_handler.py +409 -0
- autocoder/common/file_handler/chat_handler.py +180 -0
- autocoder/common/file_handler/coding_handler.py +409 -0
- autocoder/common/file_handler/commit_handler.py +200 -0
- autocoder/common/file_handler/lib_handler.py +156 -0
- autocoder/common/file_handler/list_files_handler.py +111 -0
- autocoder/common/file_handler/mcp_handler.py +268 -0
- autocoder/common/file_handler/models_handler.py +493 -0
- autocoder/common/file_handler/remove_files_handler.py +172 -0
- autocoder/common/git_utils.py +44 -8
- autocoder/common/global_cancel.py +15 -6
- autocoder/common/ignorefiles/test_ignore_file_utils.py +1 -1
- autocoder/common/international/__init__.py +31 -0
- autocoder/common/international/demo_international.py +92 -0
- autocoder/common/international/message_manager.py +157 -0
- autocoder/common/international/messages/__init__.py +56 -0
- autocoder/common/international/messages/async_command_messages.py +507 -0
- autocoder/common/international/messages/auto_coder_messages.py +2208 -0
- autocoder/common/international/messages/chat_auto_coder_messages.py +1547 -0
- autocoder/common/international/messages/command_help_messages.py +986 -0
- autocoder/common/international/messages/conversation_command_messages.py +191 -0
- autocoder/common/international/messages/git_helper_plugin_messages.py +159 -0
- autocoder/common/international/messages/queue_command_messages.py +751 -0
- autocoder/common/international/messages/rules_command_messages.py +77 -0
- autocoder/common/international/messages/sdk_messages.py +1707 -0
- autocoder/common/international/messages/token_helper_plugin_messages.py +361 -0
- autocoder/common/international/messages/tool_display_messages.py +1212 -0
- autocoder/common/international/messages/workflow_exception_messages.py +473 -0
- autocoder/common/international/test_international.py +612 -0
- autocoder/common/linter_core/__init__.py +28 -0
- autocoder/common/linter_core/base_linter.py +61 -0
- autocoder/common/linter_core/config_loader.py +271 -0
- autocoder/common/linter_core/formatters/__init__.py +0 -0
- autocoder/common/linter_core/formatters/base_formatter.py +38 -0
- autocoder/common/linter_core/formatters/raw_formatter.py +17 -0
- autocoder/common/linter_core/linter.py +166 -0
- autocoder/common/linter_core/linter_factory.py +216 -0
- autocoder/common/linter_core/linter_manager.py +333 -0
- autocoder/common/linter_core/linters/__init__.py +9 -0
- autocoder/common/linter_core/linters/java_linter.py +342 -0
- autocoder/common/linter_core/linters/python_linter.py +115 -0
- autocoder/common/linter_core/linters/typescript_linter.py +119 -0
- autocoder/common/linter_core/models/__init__.py +7 -0
- autocoder/common/linter_core/models/lint_result.py +91 -0
- autocoder/common/linter_core/models.py +33 -0
- autocoder/common/linter_core/tests/__init__.py +3 -0
- autocoder/common/linter_core/tests/test_config_loader.py +323 -0
- autocoder/common/linter_core/tests/test_config_loading.py +308 -0
- autocoder/common/linter_core/tests/test_factory_manager.py +234 -0
- autocoder/common/linter_core/tests/test_formatters.py +147 -0
- autocoder/common/linter_core/tests/test_integration.py +317 -0
- autocoder/common/linter_core/tests/test_java_linter.py +496 -0
- autocoder/common/linter_core/tests/test_linters.py +265 -0
- autocoder/common/linter_core/tests/test_models.py +81 -0
- autocoder/common/linter_core/tests/verify_config_loading.py +296 -0
- autocoder/common/linter_core/tests/verify_fixes.py +183 -0
- autocoder/common/llm_friendly_package/__init__.py +31 -0
- autocoder/common/llm_friendly_package/base_manager.py +102 -0
- autocoder/common/llm_friendly_package/docs_manager.py +121 -0
- autocoder/common/llm_friendly_package/library_manager.py +171 -0
- autocoder/common/{llm_friendly_package.py → llm_friendly_package/main_manager.py} +204 -231
- autocoder/common/llm_friendly_package/models.py +40 -0
- autocoder/common/llm_friendly_package/test_llm_friendly_package.py +536 -0
- autocoder/common/llms/__init__.py +15 -0
- autocoder/common/llms/demo_error_handling.py +85 -0
- autocoder/common/llms/factory.py +142 -0
- autocoder/common/llms/manager.py +264 -0
- autocoder/common/llms/pricing.py +121 -0
- autocoder/common/llms/registry.py +316 -0
- autocoder/common/llms/schema.py +77 -0
- autocoder/common/llms/simple_demo.py +45 -0
- autocoder/common/llms/test_quick_model.py +116 -0
- autocoder/common/llms/test_remove_functionality.py +182 -0
- autocoder/common/llms/tests/__init__.py +1 -0
- autocoder/common/llms/tests/test_manager.py +330 -0
- autocoder/common/llms/tests/test_registry.py +364 -0
- autocoder/common/mcp_tools/__init__.py +62 -0
- autocoder/common/{mcp_tools.py → mcp_tools/executor.py} +49 -40
- autocoder/common/{mcp_hub.py → mcp_tools/hub.py} +42 -68
- autocoder/common/{mcp_server_install.py → mcp_tools/installer.py} +16 -28
- autocoder/common/{mcp_server.py → mcp_tools/server.py} +176 -48
- autocoder/common/mcp_tools/test_keyboard_interrupt.py +93 -0
- autocoder/common/mcp_tools/test_mcp_tools.py +391 -0
- autocoder/common/{mcp_server_types.py → mcp_tools/types.py} +121 -48
- autocoder/common/mcp_tools/verify_functionality.py +202 -0
- autocoder/common/model_speed_tester.py +32 -26
- autocoder/common/priority_directory_finder/__init__.py +142 -0
- autocoder/common/priority_directory_finder/examples.py +230 -0
- autocoder/common/priority_directory_finder/finder.py +283 -0
- autocoder/common/priority_directory_finder/models.py +236 -0
- autocoder/common/priority_directory_finder/test_priority_directory_finder.py +431 -0
- autocoder/common/project_scanner/__init__.py +18 -0
- autocoder/common/project_scanner/compat.py +77 -0
- autocoder/common/project_scanner/scanner.py +436 -0
- autocoder/common/project_tracker/__init__.py +27 -0
- autocoder/common/project_tracker/api.py +228 -0
- autocoder/common/project_tracker/demo.py +272 -0
- autocoder/common/project_tracker/tracker.py +487 -0
- autocoder/common/project_tracker/types.py +53 -0
- autocoder/common/pruner/__init__.py +67 -0
- autocoder/common/pruner/agentic_conversation_pruner.py +651 -102
- autocoder/common/pruner/conversation_message_ids_api.py +386 -0
- autocoder/common/pruner/conversation_message_ids_manager.py +347 -0
- autocoder/common/pruner/conversation_message_ids_pruner.py +473 -0
- autocoder/common/pruner/conversation_normalizer.py +347 -0
- autocoder/common/pruner/conversation_pruner.py +26 -6
- autocoder/common/pruner/test_agentic_conversation_pruner.py +554 -112
- autocoder/common/pruner/test_conversation_normalizer.py +502 -0
- autocoder/common/pruner/test_tool_content_detector.py +324 -0
- autocoder/common/pruner/tool_content_detector.py +227 -0
- autocoder/common/pruner/tools/__init__.py +18 -0
- autocoder/common/pruner/tools/query_message_ids.py +264 -0
- autocoder/common/pruner/tools/test_agentic_pruning_logic.py +432 -0
- autocoder/common/pruner/tools/test_message_ids_pruning_only.py +192 -0
- autocoder/common/pull_requests/__init__.py +9 -1
- autocoder/common/pull_requests/utils.py +122 -1
- autocoder/common/rag_manager/rag_manager.py +36 -40
- autocoder/common/rulefiles/__init__.py +53 -1
- autocoder/common/rulefiles/api.py +250 -0
- autocoder/common/rulefiles/core/__init__.py +14 -0
- autocoder/common/rulefiles/core/manager.py +241 -0
- autocoder/common/rulefiles/core/selector.py +805 -0
- autocoder/common/rulefiles/models/__init__.py +20 -0
- autocoder/common/rulefiles/models/index.py +16 -0
- autocoder/common/rulefiles/models/init_rule.py +18 -0
- autocoder/common/rulefiles/models/rule_file.py +18 -0
- autocoder/common/rulefiles/models/rule_relevance.py +14 -0
- autocoder/common/rulefiles/models/summary.py +16 -0
- autocoder/common/rulefiles/test_rulefiles.py +776 -0
- autocoder/common/rulefiles/utils/__init__.py +34 -0
- autocoder/common/rulefiles/utils/monitor.py +86 -0
- autocoder/common/rulefiles/utils/parser.py +230 -0
- autocoder/common/save_formatted_log.py +67 -10
- autocoder/common/search_replace.py +8 -1
- autocoder/common/search_replace_patch/__init__.py +24 -0
- autocoder/common/search_replace_patch/base.py +115 -0
- autocoder/common/search_replace_patch/manager.py +248 -0
- autocoder/common/search_replace_patch/patch_replacer.py +304 -0
- autocoder/common/search_replace_patch/similarity_replacer.py +306 -0
- autocoder/common/search_replace_patch/string_replacer.py +181 -0
- autocoder/common/search_replace_patch/tests/__init__.py +3 -0
- autocoder/common/search_replace_patch/tests/run_tests.py +126 -0
- autocoder/common/search_replace_patch/tests/test_base.py +188 -0
- autocoder/common/search_replace_patch/tests/test_empty_line_insert.py +233 -0
- autocoder/common/search_replace_patch/tests/test_integration.py +389 -0
- autocoder/common/search_replace_patch/tests/test_manager.py +351 -0
- autocoder/common/search_replace_patch/tests/test_patch_replacer.py +316 -0
- autocoder/common/search_replace_patch/tests/test_regex_replacer.py +306 -0
- autocoder/common/search_replace_patch/tests/test_similarity_replacer.py +384 -0
- autocoder/common/shell_commands/__init__.py +197 -0
- autocoder/common/shell_commands/background_process_notifier.py +346 -0
- autocoder/common/shell_commands/command_executor.py +1127 -0
- autocoder/common/shell_commands/error_recovery.py +541 -0
- autocoder/common/shell_commands/exceptions.py +120 -0
- autocoder/common/shell_commands/interactive_executor.py +476 -0
- autocoder/common/shell_commands/interactive_pexpect_process.py +623 -0
- autocoder/common/shell_commands/interactive_process.py +744 -0
- autocoder/common/shell_commands/interactive_session_manager.py +1014 -0
- autocoder/common/shell_commands/monitoring.py +529 -0
- autocoder/common/shell_commands/process_cleanup.py +386 -0
- autocoder/common/shell_commands/process_manager.py +606 -0
- autocoder/common/shell_commands/test_interactive_pexpect_process.py +281 -0
- autocoder/common/shell_commands/tests/__init__.py +6 -0
- autocoder/common/shell_commands/tests/conftest.py +118 -0
- autocoder/common/shell_commands/tests/test_background_process_notifier.py +703 -0
- autocoder/common/shell_commands/tests/test_command_executor.py +448 -0
- autocoder/common/shell_commands/tests/test_error_recovery.py +305 -0
- autocoder/common/shell_commands/tests/test_exceptions.py +299 -0
- autocoder/common/shell_commands/tests/test_execute_batch.py +588 -0
- autocoder/common/shell_commands/tests/test_indented_batch_commands.py +244 -0
- autocoder/common/shell_commands/tests/test_integration.py +664 -0
- autocoder/common/shell_commands/tests/test_monitoring.py +546 -0
- autocoder/common/shell_commands/tests/test_performance.py +632 -0
- autocoder/common/shell_commands/tests/test_process_cleanup.py +397 -0
- autocoder/common/shell_commands/tests/test_process_manager.py +606 -0
- autocoder/common/shell_commands/tests/test_timeout_config.py +343 -0
- autocoder/common/shell_commands/tests/test_timeout_manager.py +520 -0
- autocoder/common/shell_commands/timeout_config.py +315 -0
- autocoder/common/shell_commands/timeout_manager.py +352 -0
- autocoder/common/terminal_paste/__init__.py +14 -0
- autocoder/common/terminal_paste/demo.py +145 -0
- autocoder/common/terminal_paste/demo_paste_functionality.py +95 -0
- autocoder/common/terminal_paste/paste_handler.py +200 -0
- autocoder/common/terminal_paste/paste_manager.py +118 -0
- autocoder/common/terminal_paste/tests/__init__.py +1 -0
- autocoder/common/terminal_paste/tests/test_paste_handler.py +182 -0
- autocoder/common/terminal_paste/tests/test_paste_manager.py +126 -0
- autocoder/common/terminal_paste/utils.py +163 -0
- autocoder/common/test_autocoder_args.py +232 -0
- autocoder/common/test_env_manager.py +173 -0
- autocoder/common/test_env_manager_integration.py +159 -0
- autocoder/common/text_similarity/__init__.py +9 -0
- autocoder/common/text_similarity/demo.py +216 -0
- autocoder/common/text_similarity/examples.py +266 -0
- autocoder/common/text_similarity/test_text_similarity.py +306 -0
- autocoder/common/text_similarity/text_similarity.py +194 -0
- autocoder/common/text_similarity/utils.py +125 -0
- autocoder/common/todos/__init__.py +61 -0
- autocoder/common/todos/cache/__init__.py +16 -0
- autocoder/common/todos/cache/base_cache.py +89 -0
- autocoder/common/todos/cache/cache_manager.py +228 -0
- autocoder/common/todos/cache/memory_cache.py +225 -0
- autocoder/common/todos/config.py +155 -0
- autocoder/common/todos/exceptions.py +35 -0
- autocoder/common/todos/get_todo_manager.py +161 -0
- autocoder/common/todos/manager.py +537 -0
- autocoder/common/todos/models.py +239 -0
- autocoder/common/todos/storage/__init__.py +14 -0
- autocoder/common/todos/storage/base_storage.py +76 -0
- autocoder/common/todos/storage/file_storage.py +278 -0
- autocoder/common/tokens/counter.py +24 -2
- autocoder/common/tools_manager/__init__.py +17 -0
- autocoder/common/tools_manager/examples.py +162 -0
- autocoder/common/tools_manager/manager.py +385 -0
- autocoder/common/tools_manager/models.py +39 -0
- autocoder/common/tools_manager/test_tools_manager.py +303 -0
- autocoder/common/tools_manager/utils.py +191 -0
- autocoder/common/v2/agent/agentic_callbacks.py +270 -0
- autocoder/common/v2/agent/agentic_edit.py +2699 -1856
- autocoder/common/v2/agent/agentic_edit_change_manager.py +474 -0
- autocoder/common/v2/agent/agentic_edit_tools/__init__.py +35 -1
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_list_tool_resolver.py +279 -0
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +10 -1
- autocoder/common/v2/agent/agentic_edit_tools/background_task_tool_resolver.py +1167 -0
- autocoder/common/v2/agent/agentic_edit_tools/base_tool_resolver.py +2 -2
- autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_read_tool_resolver.py +214 -0
- autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_write_tool_resolver.py +299 -0
- autocoder/common/v2/agent/agentic_edit_tools/count_tokens_tool_resolver.py +290 -0
- autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +564 -29
- autocoder/common/v2/agent/agentic_edit_tools/execute_workflow_tool_resolver.py +485 -0
- autocoder/common/v2/agent/agentic_edit_tools/extract_to_text_tool_resolver.py +225 -0
- autocoder/common/v2/agent/agentic_edit_tools/lint_report.py +79 -0
- autocoder/common/v2/agent/agentic_edit_tools/linter_config_models.py +343 -0
- autocoder/common/v2/agent/agentic_edit_tools/linter_enabled_tool_resolver.py +189 -0
- autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py +169 -101
- autocoder/common/v2/agent/agentic_edit_tools/load_extra_document_tool_resolver.py +356 -0
- autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +243 -50
- autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py +667 -147
- autocoder/common/v2/agent/agentic_edit_tools/run_named_subagents_tool_resolver.py +691 -0
- autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +410 -86
- autocoder/common/v2/agent/agentic_edit_tools/session_interactive_tool_resolver.py +115 -0
- autocoder/common/v2/agent/agentic_edit_tools/session_start_tool_resolver.py +190 -0
- autocoder/common/v2/agent/agentic_edit_tools/session_stop_tool_resolver.py +76 -0
- autocoder/common/v2/agent/agentic_edit_tools/test_write_to_file_tool_resolver.py +207 -192
- autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +80 -63
- autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +237 -233
- autocoder/common/v2/agent/agentic_edit_tools/use_mcp_tool_resolver.py +2 -2
- autocoder/common/v2/agent/agentic_edit_tools/web_crawl_tool_resolver.py +557 -0
- autocoder/common/v2/agent/agentic_edit_tools/web_search_tool_resolver.py +600 -0
- autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py +56 -121
- autocoder/common/v2/agent/agentic_edit_types.py +343 -9
- autocoder/common/v2/agent/runner/__init__.py +3 -3
- autocoder/common/v2/agent/runner/base_runner.py +12 -26
- autocoder/common/v2/agent/runner/{event_runner.py → file_based_event_runner.py} +3 -2
- autocoder/common/v2/agent/runner/sdk_runner.py +150 -8
- autocoder/common/v2/agent/runner/terminal_runner.py +170 -57
- autocoder/common/v2/agent/runner/tool_display.py +557 -159
- autocoder/common/v2/agent/test_agentic_callbacks.py +265 -0
- autocoder/common/v2/agent/test_agentic_edit.py +194 -0
- autocoder/common/v2/agent/tool_caller/__init__.py +24 -0
- autocoder/common/v2/agent/tool_caller/default_tool_resolver_map.py +135 -0
- autocoder/common/v2/agent/tool_caller/integration_test.py +172 -0
- autocoder/common/v2/agent/tool_caller/plugins/__init__.py +14 -0
- autocoder/common/v2/agent/tool_caller/plugins/base_plugin.py +126 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/__init__.py +13 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/logging_plugin.py +164 -0
- autocoder/common/v2/agent/tool_caller/plugins/examples/security_filter_plugin.py +198 -0
- autocoder/common/v2/agent/tool_caller/plugins/plugin_interface.py +141 -0
- autocoder/common/v2/agent/tool_caller/test_tool_caller.py +278 -0
- autocoder/common/v2/agent/tool_caller/tool_call_plugin_manager.py +331 -0
- autocoder/common/v2/agent/tool_caller/tool_caller.py +337 -0
- autocoder/common/v2/agent/tool_caller/usage_example.py +193 -0
- autocoder/common/v2/code_agentic_editblock_manager.py +4 -4
- autocoder/common/v2/code_auto_generate.py +136 -78
- autocoder/common/v2/code_auto_generate_diff.py +135 -79
- autocoder/common/v2/code_auto_generate_editblock.py +174 -99
- autocoder/common/v2/code_auto_generate_strict_diff.py +151 -71
- autocoder/common/v2/code_auto_merge.py +1 -1
- autocoder/common/v2/code_auto_merge_editblock.py +13 -1
- autocoder/common/v2/code_diff_manager.py +3 -3
- autocoder/common/v2/code_editblock_manager.py +4 -14
- autocoder/common/v2/code_manager.py +1 -1
- autocoder/common/v2/code_strict_diff_manager.py +2 -2
- autocoder/common/wrap_llm_hint/__init__.py +10 -0
- autocoder/common/wrap_llm_hint/test_wrap_llm_hint.py +1067 -0
- autocoder/common/wrap_llm_hint/utils.py +432 -0
- autocoder/common/wrap_llm_hint/wrap_llm_hint.py +323 -0
- autocoder/completer/__init__.py +8 -0
- autocoder/completer/command_completer_v2.py +1094 -0
- autocoder/default_project/__init__.py +501 -0
- autocoder/dispacher/__init__.py +4 -12
- autocoder/dispacher/actions/action.py +400 -129
- autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
- autocoder/index/entry.py +117 -125
- autocoder/{agent → index/filter}/agentic_filter.py +322 -333
- autocoder/index/filter/normal_filter.py +5 -11
- autocoder/index/filter/quick_filter.py +1 -1
- autocoder/index/index.py +36 -9
- autocoder/index/tests/__init__.py +1 -0
- autocoder/index/tests/run_tests.py +195 -0
- autocoder/index/tests/test_entry.py +303 -0
- autocoder/index/tests/test_index_manager.py +314 -0
- autocoder/index/tests/test_module_integration.py +300 -0
- autocoder/index/tests/test_symbols_utils.py +183 -0
- autocoder/inner/__init__.py +4 -0
- autocoder/inner/agentic.py +923 -0
- autocoder/inner/async_command_handler.py +992 -0
- autocoder/inner/conversation_command_handlers.py +623 -0
- autocoder/inner/merge_command_handler.py +213 -0
- autocoder/inner/queue_command_handler.py +684 -0
- autocoder/models.py +95 -266
- autocoder/plugins/git_helper_plugin.py +31 -29
- autocoder/plugins/token_helper_plugin.py +65 -46
- autocoder/pyproject/__init__.py +32 -29
- autocoder/rag/agentic_rag.py +215 -75
- autocoder/rag/cache/simple_cache.py +1 -2
- autocoder/rag/loaders/image_loader.py +1 -1
- autocoder/rag/long_context_rag.py +42 -26
- autocoder/rag/qa_conversation_strategy.py +1 -1
- autocoder/rag/terminal/__init__.py +17 -0
- autocoder/rag/terminal/args.py +581 -0
- autocoder/rag/terminal/bootstrap.py +61 -0
- autocoder/rag/terminal/command_handlers.py +653 -0
- autocoder/rag/terminal/formatters/__init__.py +20 -0
- autocoder/rag/terminal/formatters/base.py +70 -0
- autocoder/rag/terminal/formatters/json_format.py +66 -0
- autocoder/rag/terminal/formatters/stream_json.py +95 -0
- autocoder/rag/terminal/formatters/text.py +28 -0
- autocoder/rag/terminal/init.py +120 -0
- autocoder/rag/terminal/utils.py +106 -0
- autocoder/rag/test_agentic_rag.py +389 -0
- autocoder/rag/test_doc_filter.py +3 -3
- autocoder/rag/test_long_context_rag.py +1 -1
- autocoder/rag/test_token_limiter.py +517 -10
- autocoder/rag/token_counter.py +3 -0
- autocoder/rag/token_limiter.py +19 -15
- autocoder/rag/tools/__init__.py +26 -2
- autocoder/rag/tools/bochaai_example.py +343 -0
- autocoder/rag/tools/bochaai_sdk.py +541 -0
- autocoder/rag/tools/metaso_example.py +268 -0
- autocoder/rag/tools/metaso_sdk.py +417 -0
- autocoder/rag/tools/recall_tool.py +28 -7
- autocoder/rag/tools/run_integration_tests.py +204 -0
- autocoder/rag/tools/test_all_providers.py +318 -0
- autocoder/rag/tools/test_bochaai_integration.py +482 -0
- autocoder/rag/tools/test_final_integration.py +215 -0
- autocoder/rag/tools/test_metaso_integration.py +424 -0
- autocoder/rag/tools/test_metaso_real.py +171 -0
- autocoder/rag/tools/test_web_crawl_tool.py +639 -0
- autocoder/rag/tools/test_web_search_tool.py +509 -0
- autocoder/rag/tools/todo_read_tool.py +202 -0
- autocoder/rag/tools/todo_write_tool.py +412 -0
- autocoder/rag/tools/web_crawl_tool.py +634 -0
- autocoder/rag/tools/web_search_tool.py +558 -0
- autocoder/rag/tools/web_tools_example.py +119 -0
- autocoder/rag/types.py +16 -0
- autocoder/rag/variable_holder.py +4 -2
- autocoder/rags.py +86 -79
- autocoder/regexproject/__init__.py +23 -21
- autocoder/sdk/__init__.py +46 -190
- autocoder/sdk/api.py +370 -0
- autocoder/sdk/async_runner/__init__.py +26 -0
- autocoder/sdk/async_runner/async_executor.py +650 -0
- autocoder/sdk/async_runner/async_handler.py +356 -0
- autocoder/sdk/async_runner/markdown_processor.py +595 -0
- autocoder/sdk/async_runner/task_metadata.py +284 -0
- autocoder/sdk/async_runner/worktree_manager.py +438 -0
- autocoder/sdk/cli/__init__.py +2 -5
- autocoder/sdk/cli/formatters.py +28 -204
- autocoder/sdk/cli/handlers.py +77 -44
- autocoder/sdk/cli/main.py +154 -171
- autocoder/sdk/cli/options.py +95 -22
- autocoder/sdk/constants.py +139 -51
- autocoder/sdk/core/auto_coder_core.py +484 -109
- autocoder/sdk/core/bridge.py +297 -115
- autocoder/sdk/exceptions.py +18 -12
- autocoder/sdk/formatters/__init__.py +19 -0
- autocoder/sdk/formatters/input.py +64 -0
- autocoder/sdk/formatters/output.py +247 -0
- autocoder/sdk/formatters/stream.py +54 -0
- autocoder/sdk/models/__init__.py +6 -5
- autocoder/sdk/models/options.py +55 -18
- autocoder/sdk/utils/formatters.py +27 -195
- autocoder/suffixproject/__init__.py +28 -25
- autocoder/terminal/__init__.py +14 -0
- autocoder/terminal/app.py +454 -0
- autocoder/terminal/args.py +32 -0
- autocoder/terminal/bootstrap.py +178 -0
- autocoder/terminal/command_processor.py +521 -0
- autocoder/terminal/command_registry.py +57 -0
- autocoder/terminal/help.py +97 -0
- autocoder/terminal/tasks/__init__.py +5 -0
- autocoder/terminal/tasks/background.py +77 -0
- autocoder/terminal/tasks/task_event.py +70 -0
- autocoder/terminal/ui/__init__.py +13 -0
- autocoder/terminal/ui/completer.py +268 -0
- autocoder/terminal/ui/keybindings.py +75 -0
- autocoder/terminal/ui/session.py +41 -0
- autocoder/terminal/ui/toolbar.py +64 -0
- autocoder/terminal/utils/__init__.py +13 -0
- autocoder/terminal/utils/errors.py +18 -0
- autocoder/terminal/utils/paths.py +19 -0
- autocoder/terminal/utils/shell.py +43 -0
- autocoder/terminal_v3/__init__.py +10 -0
- autocoder/terminal_v3/app.py +201 -0
- autocoder/terminal_v3/handlers/__init__.py +5 -0
- autocoder/terminal_v3/handlers/command_handler.py +131 -0
- autocoder/terminal_v3/models/__init__.py +6 -0
- autocoder/terminal_v3/models/conversation_buffer.py +214 -0
- autocoder/terminal_v3/models/message.py +50 -0
- autocoder/terminal_v3/models/tool_display.py +247 -0
- autocoder/terminal_v3/ui/__init__.py +7 -0
- autocoder/terminal_v3/ui/keybindings.py +56 -0
- autocoder/terminal_v3/ui/layout.py +141 -0
- autocoder/terminal_v3/ui/styles.py +43 -0
- autocoder/tsproject/__init__.py +23 -23
- autocoder/utils/auto_coder_utils/chat_stream_out.py +1 -1
- autocoder/utils/llms.py +88 -80
- autocoder/utils/math_utils.py +101 -0
- autocoder/utils/model_provider_selector.py +16 -4
- autocoder/utils/operate_config_api.py +33 -5
- autocoder/utils/thread_utils.py +2 -2
- autocoder/version.py +4 -2
- autocoder/workflow_agents/__init__.py +84 -0
- autocoder/workflow_agents/agent.py +143 -0
- autocoder/workflow_agents/exceptions.py +573 -0
- autocoder/workflow_agents/executor.py +665 -0
- autocoder/workflow_agents/loader.py +749 -0
- autocoder/workflow_agents/runner.py +267 -0
- autocoder/workflow_agents/types.py +173 -0
- autocoder/workflow_agents/utils.py +434 -0
- autocoder/workflow_agents/workflow_manager.py +211 -0
- auto_coder-1.0.0.dist-info/METADATA +0 -396
- auto_coder-1.0.0.dist-info/RECORD +0 -442
- auto_coder-1.0.0.dist-info/licenses/LICENSE +0 -201
- autocoder/auto_coder_server.py +0 -672
- autocoder/benchmark.py +0 -138
- autocoder/common/ac_style_command_parser/example.py +0 -7
- autocoder/common/cleaner.py +0 -31
- autocoder/common/command_completer_v2.py +0 -615
- autocoder/common/context_pruner.py +0 -477
- autocoder/common/conversation_pruner.py +0 -132
- autocoder/common/directory_cache/__init__.py +0 -1
- autocoder/common/directory_cache/cache.py +0 -192
- autocoder/common/directory_cache/test_cache.py +0 -190
- autocoder/common/file_checkpoint/examples.py +0 -217
- autocoder/common/llm_friendly_package_example.py +0 -138
- autocoder/common/llm_friendly_package_test.py +0 -63
- autocoder/common/pull_requests/test_module.py +0 -1
- autocoder/common/rulefiles/autocoderrules_utils.py +0 -484
- autocoder/common/text.py +0 -30
- autocoder/common/v2/agent/agentic_edit_tools/list_package_info_tool_resolver.py +0 -42
- autocoder/common/v2/agent/agentic_edit_tools/test_execute_command_tool_resolver.py +0 -70
- autocoder/common/v2/agent/agentic_edit_tools/test_search_files_tool_resolver.py +0 -163
- autocoder/common/v2/agent/agentic_tool_display.py +0 -183
- autocoder/plugins/dynamic_completion_example.py +0 -148
- autocoder/plugins/sample_plugin.py +0 -160
- autocoder/sdk/cli/__main__.py +0 -26
- autocoder/sdk/cli/completion_wrapper.py +0 -38
- autocoder/sdk/cli/install_completion.py +0 -301
- autocoder/sdk/models/messages.py +0 -209
- autocoder/sdk/session/__init__.py +0 -32
- autocoder/sdk/session/session.py +0 -106
- autocoder/sdk/session/session_manager.py +0 -56
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.dist-info}/top_level.txt +0 -0
- /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
|
@@ -1,615 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import shlex
|
|
3
|
-
from typing import Callable, Dict, Any, List, Iterable, Optional
|
|
4
|
-
|
|
5
|
-
import pydantic
|
|
6
|
-
from pydantic import BaseModel, SkipValidation
|
|
7
|
-
from prompt_toolkit.completion import Completer, Completion, CompleteEvent
|
|
8
|
-
from prompt_toolkit.document import Document
|
|
9
|
-
|
|
10
|
-
from autocoder.common import AutoCoderArgs
|
|
11
|
-
from autocoder.common.command_completer import FileSystemModel, MemoryConfig # Reuse models
|
|
12
|
-
from autocoder import models as models_module
|
|
13
|
-
|
|
14
|
-
# Define command structure in a more structured way if needed,
|
|
15
|
-
# but primarily rely on handlers for logic.
|
|
16
|
-
COMMAND_HIERARCHY = {
|
|
17
|
-
"/add_files": {"/group": {"/add": {}, "/drop": {}, "/reset": {}, "/set": {}}, "/refresh": {}},
|
|
18
|
-
"/remove_files": {"/all": {}},
|
|
19
|
-
"/conf": {"/drop": {}, "/export": {}, "/import": {}, "/get": {}}, # Added list/get for clarity
|
|
20
|
-
"/coding": {"/apply": {}, "/next": {}},
|
|
21
|
-
"/chat": {"/new": {}, "/save": {}, "/copy": {}, "/mcp": {}, "/rag": {}, "/review": {}, "/learn": {}, "/no_context": {}},
|
|
22
|
-
"/mcp": {"/add": {}, "/remove": {}, "/list": {}, "/list_running": {}, "/refresh": {}, "/info": {}},
|
|
23
|
-
"/lib": {"/add": {}, "/remove": {}, "/list": {}, "/set-proxy": {}, "/refresh": {}, "/get": {}},
|
|
24
|
-
"/models": {"/chat": {}, "/add": {}, "/add_model": {}, "/remove": {}, "/list": {}, "/speed": {}, "/speed-test": {}, "/input_price": {}, "/output_price": {}, "/activate": {}},
|
|
25
|
-
"/auto": {"/new": {}, "/resume": {}, "/list": {},"/command":{}},
|
|
26
|
-
"/shell": {"/chat": {}},
|
|
27
|
-
"/active_context": {"/list": {}, "/run": {}},
|
|
28
|
-
"/index": {"/query": {}, "/build": {}, "/export": {}, "/import": {}},
|
|
29
|
-
"/exclude_files": {"/list": {}, "/drop": {}},
|
|
30
|
-
"/exclude_dirs": {}, # No specific subcommands shown in V1, treat as simple list
|
|
31
|
-
"/commit": {}, # No specific subcommands shown in V1
|
|
32
|
-
"/revert": {},
|
|
33
|
-
"/ask": {},
|
|
34
|
-
"/design": {"/svg": {}, "/sd": {}, "/logo": {}},
|
|
35
|
-
"/summon": {},
|
|
36
|
-
"/mode": {}, # Simple value completion
|
|
37
|
-
"/voice_input": {},
|
|
38
|
-
"/exit": {},
|
|
39
|
-
"/help": {},
|
|
40
|
-
"/list_files": {},
|
|
41
|
-
"/clear": {},
|
|
42
|
-
"/cls": {},
|
|
43
|
-
"/debug": {},
|
|
44
|
-
"/rules": {"/list": {}, "/get": {}, "/remove": {}, "/analyze": {}, "/commit": {}, "/help": {}},
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
class CommandCompleterV2(Completer):
|
|
48
|
-
"""
|
|
49
|
-
A more extensible command completer using a handler-based approach.
|
|
50
|
-
"""
|
|
51
|
-
def __init__(self, commands: List[str], file_system_model: FileSystemModel, memory_model: MemoryConfig):
|
|
52
|
-
self.base_commands = commands # Top-level commands starting with /
|
|
53
|
-
self.file_system_model = file_system_model
|
|
54
|
-
self.memory_model = memory_model
|
|
55
|
-
|
|
56
|
-
# Data stores, initialized and refreshable
|
|
57
|
-
self.all_file_names: List[str] = []
|
|
58
|
-
self.all_files: List[str] = []
|
|
59
|
-
self.all_dir_names: List[str] = []
|
|
60
|
-
self.all_files_with_dot: List[str] = []
|
|
61
|
-
self.symbol_list: List[Any] = [] # Use Any for SymbolItem structure from runner
|
|
62
|
-
self.current_file_names: List[str] = []
|
|
63
|
-
self.config_keys = list(AutoCoderArgs.model_fields.keys())
|
|
64
|
-
self.group_names: List[str] = []
|
|
65
|
-
self.lib_names: List[str] = []
|
|
66
|
-
self.model_names: List[str] = [] # Assuming models can be fetched
|
|
67
|
-
|
|
68
|
-
self.refresh_files() # Initial data load
|
|
69
|
-
self._update_dynamic_data() # Load groups, libs etc.
|
|
70
|
-
|
|
71
|
-
# Map command prefixes or patterns to handler methods
|
|
72
|
-
self.command_handlers: Dict[str, Callable] = {
|
|
73
|
-
"/": self._handle_base_command,
|
|
74
|
-
"/add_files": self._handle_add_files,
|
|
75
|
-
"/remove_files": self._handle_remove_files,
|
|
76
|
-
"/exclude_dirs": self._handle_exclude_dirs,
|
|
77
|
-
"/exclude_files": self._handle_exclude_files,
|
|
78
|
-
"/conf": self._handle_conf,
|
|
79
|
-
"/lib": self._handle_lib,
|
|
80
|
-
"/mcp": self._handle_mcp,
|
|
81
|
-
"/models": self._handle_models,
|
|
82
|
-
"/active_context": self._handle_active_context,
|
|
83
|
-
"/mode": self._handle_mode,
|
|
84
|
-
"/chat": self._handle_text_with_symbols,
|
|
85
|
-
"/coding": self._handle_text_with_symbols,
|
|
86
|
-
"/auto": self._handle_text_with_symbols,
|
|
87
|
-
"/ask": self._handle_text_with_symbols, # Treat like chat for @/@@
|
|
88
|
-
"/summon": self._handle_text_with_symbols,
|
|
89
|
-
"/design": self._handle_design,
|
|
90
|
-
"/rules": self._handle_rules,
|
|
91
|
-
# Add handlers for other commands if they need specific logic beyond @/@@
|
|
92
|
-
# Default handler for plain text or commands not explicitly handled
|
|
93
|
-
"default": self._handle_text_with_symbols,
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
def _update_dynamic_data(self):
|
|
97
|
-
"""Load or update data that changes during runtime (groups, libs, current files)."""
|
|
98
|
-
self.current_file_names = self.memory_model.get_memory_func().get("current_files", {}).get("files", [])
|
|
99
|
-
self.group_names = list(self.memory_model.get_memory_func().get("current_files", {}).get("groups", {}).keys())
|
|
100
|
-
self.lib_names = list(self.memory_model.get_memory_func().get("libs", {}).keys())
|
|
101
|
-
# In a real scenario, might fetch model names from models_module
|
|
102
|
-
try:
|
|
103
|
-
self.model_names = [m.get("name","") for m in models_module.load_models()]
|
|
104
|
-
except ImportError:
|
|
105
|
-
self.model_names = [] # Fallback if models module not available
|
|
106
|
-
|
|
107
|
-
def refresh_files(self):
|
|
108
|
-
"""Refresh file and symbol lists from the file system model."""
|
|
109
|
-
self.all_file_names = self.file_system_model.get_all_file_names_in_project()
|
|
110
|
-
self.all_files = self.file_system_model.get_all_file_in_project()
|
|
111
|
-
self.all_dir_names = self.file_system_model.get_all_dir_names_in_project()
|
|
112
|
-
self.all_files_with_dot = self.file_system_model.get_all_file_in_project_with_dot()
|
|
113
|
-
self.symbol_list = self.file_system_model.get_symbol_list()
|
|
114
|
-
self._update_dynamic_data() # Also refresh dynamic data
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
# --- Main Completion Logic ---
|
|
118
|
-
|
|
119
|
-
def get_completions(self, document: Document, complete_event: CompleteEvent) -> Iterable[Completion]:
|
|
120
|
-
text = document.text_before_cursor
|
|
121
|
-
word_before_cursor = document.get_word_before_cursor(WORD=True)
|
|
122
|
-
|
|
123
|
-
# Update dynamic data on each completion request
|
|
124
|
-
self._update_dynamic_data()
|
|
125
|
-
|
|
126
|
-
if not text.strip(): # Empty input
|
|
127
|
-
yield from self._handle_base_command(document, complete_event, word_before_cursor, text)
|
|
128
|
-
return
|
|
129
|
-
|
|
130
|
-
parts = text.split(maxsplit=1)
|
|
131
|
-
first_word = parts[0]
|
|
132
|
-
|
|
133
|
-
# 1. Handle Base Command Completion (e.g., typing "/")
|
|
134
|
-
if first_word.startswith("/") and len(parts) == 1 and not text.endswith(" "):
|
|
135
|
-
yield from self._handle_base_command(document, complete_event, word_before_cursor, text)
|
|
136
|
-
|
|
137
|
-
# 2. Dispatch to Specific Command Handlers
|
|
138
|
-
elif first_word in self.command_handlers:
|
|
139
|
-
handler = self.command_handlers[first_word]
|
|
140
|
-
yield from handler(document, complete_event, word_before_cursor, text)
|
|
141
|
-
|
|
142
|
-
# 3. Handle Special Prefixes within general text or unhandled commands
|
|
143
|
-
elif word_before_cursor.startswith("@") and not word_before_cursor.startswith("@@"):
|
|
144
|
-
yield from self._handle_at_completion(document, complete_event, word_before_cursor, text)
|
|
145
|
-
elif word_before_cursor.startswith("@@"):
|
|
146
|
-
yield from self._handle_double_at_completion(document, complete_event, word_before_cursor, text)
|
|
147
|
-
elif word_before_cursor.startswith("<"): # Potential tag completion
|
|
148
|
-
yield from self._handle_img_tag(document, complete_event, word_before_cursor, text)
|
|
149
|
-
|
|
150
|
-
# 4. Default Handler (for plain text or commands without specific handlers)
|
|
151
|
-
else:
|
|
152
|
-
handler = self.command_handlers.get("default")
|
|
153
|
-
if handler:
|
|
154
|
-
yield from handler(document, complete_event, word_before_cursor, text)
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
# --- Handler Methods ---
|
|
158
|
-
|
|
159
|
-
def _handle_base_command(self, document: Document, complete_event: CompleteEvent, word: str, text: str) -> Iterable[Completion]:
|
|
160
|
-
"""Handles completion for top-level commands starting with '/'."""
|
|
161
|
-
command_prefix = text.lstrip() # The word being typed
|
|
162
|
-
for cmd in self.base_commands:
|
|
163
|
-
if cmd.startswith(command_prefix):
|
|
164
|
-
yield Completion(cmd, start_position=-len(command_prefix))
|
|
165
|
-
|
|
166
|
-
def _handle_add_files(self, document: Document, complete_event: CompleteEvent, word: str, text: str) -> Iterable[Completion]:
|
|
167
|
-
"""Handles completions for /add_files command."""
|
|
168
|
-
args_text = text[len("/add_files"):].lstrip()
|
|
169
|
-
parts = args_text.split()
|
|
170
|
-
last_part = parts[-1] if parts and not text.endswith(" ") else ""
|
|
171
|
-
|
|
172
|
-
# Sub-command completion
|
|
173
|
-
if not args_text or (len(parts) == 1 and not text.endswith(" ")):
|
|
174
|
-
for sub_cmd in COMMAND_HIERARCHY["/add_files"]:
|
|
175
|
-
if sub_cmd.startswith(last_part):
|
|
176
|
-
yield Completion(sub_cmd, start_position=-len(last_part))
|
|
177
|
-
|
|
178
|
-
# File/Group completion based on context
|
|
179
|
-
if args_text.startswith("/group"):
|
|
180
|
-
group_args_text = args_text[len("/group"):].lstrip()
|
|
181
|
-
group_parts = group_args_text.split()
|
|
182
|
-
group_last_part = group_parts[-1] if group_parts and not text.endswith(" ") else ""
|
|
183
|
-
|
|
184
|
-
# Complete subcommands of /group
|
|
185
|
-
if not group_args_text or (len(group_parts) == 1 and not text.endswith(" ")):
|
|
186
|
-
for group_sub_cmd in COMMAND_HIERARCHY["/add_files"]["/group"]:
|
|
187
|
-
if group_sub_cmd.startswith(group_last_part):
|
|
188
|
-
yield Completion(group_sub_cmd, start_position=-len(group_last_part))
|
|
189
|
-
|
|
190
|
-
# Complete group names for /drop or direct use
|
|
191
|
-
elif group_parts and group_parts[0] in ["/drop", "/set"] or len(group_parts) >= 1 and not group_parts[0].startswith("/"):
|
|
192
|
-
current_word_for_group = group_last_part
|
|
193
|
-
# Handle comma-separated group names
|
|
194
|
-
if "," in current_word_for_group:
|
|
195
|
-
current_word_for_group = current_word_for_group.split(",")[-1]
|
|
196
|
-
|
|
197
|
-
yield from self._complete_items(current_word_for_group, self.group_names)
|
|
198
|
-
|
|
199
|
-
elif args_text.startswith("/refresh"):
|
|
200
|
-
pass # No further completion needed
|
|
201
|
-
|
|
202
|
-
# Default: File path completion
|
|
203
|
-
else:
|
|
204
|
-
yield from self._complete_file_paths(word, text)
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
def _handle_remove_files(self, document: Document, complete_event: CompleteEvent, word: str, text: str) -> Iterable[Completion]:
|
|
208
|
-
"""Handles completions for /remove_files command."""
|
|
209
|
-
# 'word' is document.get_word_before_cursor(WORD=True)
|
|
210
|
-
|
|
211
|
-
# Complete /all subcommand
|
|
212
|
-
if "/all".startswith(word):
|
|
213
|
-
yield Completion("/all", start_position=-len(word))
|
|
214
|
-
|
|
215
|
-
# Complete from current file paths (relative paths)
|
|
216
|
-
relative_current_files = [os.path.relpath(f, self.file_system_model.project_root) for f in self.current_file_names]
|
|
217
|
-
yield from self._complete_items_with_in(word, relative_current_files)
|
|
218
|
-
|
|
219
|
-
# Also complete from just the base filenames
|
|
220
|
-
current_basenames = [os.path.basename(f) for f in self.current_file_names]
|
|
221
|
-
# Avoid duplicates if basename is same as relative path (e.g., top-level file)
|
|
222
|
-
unique_basenames = [b for b in current_basenames if b not in relative_current_files]
|
|
223
|
-
yield from self._complete_items_with_in(word, unique_basenames)
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
def _handle_exclude_dirs(self, document: Document, complete_event: CompleteEvent, word: str, text: str) -> Iterable[Completion]:
|
|
227
|
-
"""Handles completions for /exclude_dirs command."""
|
|
228
|
-
args_text = text[len("/exclude_dirs"):].lstrip()
|
|
229
|
-
current_word = args_text.split(",")[-1].strip()
|
|
230
|
-
yield from self._complete_items(current_word, self.all_dir_names)
|
|
231
|
-
|
|
232
|
-
def _handle_exclude_files(self, document: Document, complete_event: CompleteEvent, word: str, text: str) -> Iterable[Completion]:
|
|
233
|
-
"""Handles completions for /exclude_files command."""
|
|
234
|
-
args_text = text[len("/exclude_files"):].lstrip()
|
|
235
|
-
parts = args_text.split()
|
|
236
|
-
last_part = parts[-1] if parts and not text.endswith(" ") else ""
|
|
237
|
-
|
|
238
|
-
if not args_text or (len(parts) == 1 and not text.endswith(" ")):
|
|
239
|
-
for sub_cmd in COMMAND_HIERARCHY["/exclude_files"]:
|
|
240
|
-
if sub_cmd.startswith(last_part):
|
|
241
|
-
yield Completion(sub_cmd, start_position=-len(last_part))
|
|
242
|
-
|
|
243
|
-
elif parts and parts[0] == "/drop":
|
|
244
|
-
current_word = last_part
|
|
245
|
-
yield from self._complete_items(current_word, self.memory_model.get_memory_func().get("exclude_files", []))
|
|
246
|
-
else:
|
|
247
|
-
# Suggest prefix for regex
|
|
248
|
-
if not last_part:
|
|
249
|
-
yield Completion("regex://", start_position=0)
|
|
250
|
-
elif "regex://".startswith(last_part):
|
|
251
|
-
yield Completion("regex://", start_position=-len(last_part))
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
def _handle_conf(self, document: Document, complete_event: CompleteEvent, word: str, text: str) -> Iterable[Completion]:
|
|
255
|
-
"""Handles completions for /conf command."""
|
|
256
|
-
args_text = text[len("/conf"):].lstrip()
|
|
257
|
-
parts = args_text.split()
|
|
258
|
-
last_part = parts[-1] if parts and not text.endswith(" ") else ""
|
|
259
|
-
# Complete subcommands like /drop, /export, /import, /list, /get
|
|
260
|
-
if not args_text or (len(parts) == 1 and not text.endswith(" ") and ":" not in text):
|
|
261
|
-
for sub_cmd in COMMAND_HIERARCHY["/conf"]:
|
|
262
|
-
if sub_cmd.startswith(last_part):
|
|
263
|
-
yield Completion(sub_cmd, start_position=-len(last_part))
|
|
264
|
-
# Also complete config keys directly
|
|
265
|
-
yield from self._complete_config_keys(last_part, add_colon=False)
|
|
266
|
-
|
|
267
|
-
# Complete config keys after /drop or /get
|
|
268
|
-
elif parts and parts[0] in ["/drop", "/get"]:
|
|
269
|
-
yield from self._complete_config_keys(last_part, add_colon=False)
|
|
270
|
-
|
|
271
|
-
# Complete file paths after /export or /import
|
|
272
|
-
elif parts and parts[0] in ["/export", "/import"]:
|
|
273
|
-
yield from self._complete_file_paths(word, text) # Use word here as it's likely the path
|
|
274
|
-
|
|
275
|
-
# Complete config keys for setting (key:value)
|
|
276
|
-
elif ":" not in last_part:
|
|
277
|
-
yield from self._complete_config_keys(last_part, add_colon=True)
|
|
278
|
-
|
|
279
|
-
# Complete values after colon
|
|
280
|
-
elif ":" in args_text:
|
|
281
|
-
key_part = args_text.split(":", 1)[0].strip()
|
|
282
|
-
value_part = args_text.split(":", 1)[1].strip() if ":" in args_text else ""
|
|
283
|
-
yield from self._complete_config_values(key_part, value_part)
|
|
284
|
-
# Example: Complete enum values or suggest file paths for path-like keys
|
|
285
|
-
pass # Placeholder for future value completions
|
|
286
|
-
|
|
287
|
-
def _complete_config_values(self, key: str, value: str) -> Iterable[Completion]:
|
|
288
|
-
"""Helper to complete configuration values based on the key."""
|
|
289
|
-
start_pos = -len(value)
|
|
290
|
-
|
|
291
|
-
# Model name completion for keys containing "model"
|
|
292
|
-
if key.endswith("_model") or key == "model":
|
|
293
|
-
# Refresh model names if they can change dynamically
|
|
294
|
-
# self.refresh_model_names()
|
|
295
|
-
for model_name in self.model_names:
|
|
296
|
-
if model_name.startswith(value) or value==":":
|
|
297
|
-
yield Completion(model_name, start_position=start_pos)
|
|
298
|
-
# If a model name matched, we might prioritize these completions.
|
|
299
|
-
# Consider returning here if model names are the only relevant values.
|
|
300
|
-
|
|
301
|
-
# Boolean value completion
|
|
302
|
-
field_info = AutoCoderArgs.model_fields.get(key)
|
|
303
|
-
if field_info and field_info.annotation == bool:
|
|
304
|
-
if "true".startswith(value): yield Completion("true", start_position=start_pos)
|
|
305
|
-
if "false".startswith(value): yield Completion("false", start_position=start_pos)
|
|
306
|
-
# If boolean matched, we might prioritize these completions.
|
|
307
|
-
# Consider returning here if boolean is the only relevant value type.
|
|
308
|
-
|
|
309
|
-
# Add more value completions based on key type or name here
|
|
310
|
-
# e.g., enums, file paths, specific string formats
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
def _handle_lib(self, document: Document, complete_event: CompleteEvent, word: str, text: str) -> Iterable[Completion]:
|
|
314
|
-
"""Handles completions for /lib command."""
|
|
315
|
-
args_text = text[len("/lib"):].lstrip()
|
|
316
|
-
parts = args_text.split()
|
|
317
|
-
last_part = parts[-1] if parts and not text.endswith(" ") else ""
|
|
318
|
-
|
|
319
|
-
# Complete subcommands
|
|
320
|
-
if not args_text or (len(parts) == 1 and not text.endswith(" ")):
|
|
321
|
-
for sub_cmd in COMMAND_HIERARCHY["/lib"]:
|
|
322
|
-
if sub_cmd.startswith(last_part):
|
|
323
|
-
yield Completion(sub_cmd, start_position=-len(last_part))
|
|
324
|
-
|
|
325
|
-
# Complete lib names for add/remove/get
|
|
326
|
-
elif parts and parts[0] in ["/add", "/remove", "/get"]:
|
|
327
|
-
yield from self._complete_items(last_part, self.lib_names)
|
|
328
|
-
|
|
329
|
-
# Complete proxy URL for set-proxy (less specific, maybe suggest http/https?)
|
|
330
|
-
elif parts and parts[0] == "/set-proxy":
|
|
331
|
-
if "http://".startswith(last_part): yield Completion("http://", start_position=-len(last_part))
|
|
332
|
-
if "https://".startswith(last_part): yield Completion("https://", start_position=-len(last_part))
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
def _handle_mcp(self, document: Document, complete_event: CompleteEvent, word: str, text: str) -> Iterable[Completion]:
|
|
336
|
-
"""Handles completions for /mcp command."""
|
|
337
|
-
args_text = text[len("/mcp"):].lstrip()
|
|
338
|
-
parts = args_text.split()
|
|
339
|
-
last_part = parts[-1] if parts and not text.endswith(" ") else ""
|
|
340
|
-
|
|
341
|
-
# Complete subcommands
|
|
342
|
-
if not args_text or (len(parts) == 1 and not text.endswith(" ")):
|
|
343
|
-
for sub_cmd in COMMAND_HIERARCHY["/mcp"]:
|
|
344
|
-
if sub_cmd.startswith(last_part):
|
|
345
|
-
yield Completion(sub_cmd, start_position=-len(last_part))
|
|
346
|
-
# Potentially complete server names after /remove, /refresh, /add if available
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
def _handle_models(self, document: Document, complete_event: CompleteEvent, word: str, text: str) -> Iterable[Completion]:
|
|
350
|
-
"""Handles completions for /models command."""
|
|
351
|
-
args_text = text[len("/models"):].lstrip()
|
|
352
|
-
parts = args_text.split()
|
|
353
|
-
last_part = parts[-1] if parts and not text.endswith(" ") else ""
|
|
354
|
-
|
|
355
|
-
# Complete subcommands
|
|
356
|
-
if not args_text or (len(parts) == 1 and not text.endswith(" ")):
|
|
357
|
-
for sub_cmd in COMMAND_HIERARCHY["/models"]:
|
|
358
|
-
if sub_cmd.startswith(last_part):
|
|
359
|
-
yield Completion(sub_cmd, start_position=-len(last_part))
|
|
360
|
-
|
|
361
|
-
# Complete model names for add/remove/speed/input_price/output_price/activate/chat
|
|
362
|
-
elif parts and parts[0] in ["/add", "/remove", "/speed", "/input_price", "/output_price", "/activate", "/chat"]:
|
|
363
|
-
yield from self._complete_items(last_part, self.model_names)
|
|
364
|
-
|
|
365
|
-
# Complete parameters for /add_model (e.g., name=, base_url=)
|
|
366
|
-
elif parts and parts[0] == "/add_model":
|
|
367
|
-
# Suggest common keys if the last part is empty or partially typed
|
|
368
|
-
common_keys = ["name=", "model_type=", "model_name=", "base_url=", "api_key_path=", "description=", "is_reasoning="]
|
|
369
|
-
yield from self._complete_items(last_part, common_keys)
|
|
370
|
-
|
|
371
|
-
elif parts and parts[0] == "/speed-test":
|
|
372
|
-
if "/long_context".startswith(last_part):
|
|
373
|
-
yield Completion("/long_context", start_position=-len(last_part))
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
def _handle_active_context(self, document: Document, complete_event: CompleteEvent, word: str, text: str) -> Iterable[Completion]:
|
|
377
|
-
"""Handles completions for /active_context command."""
|
|
378
|
-
args_text = text[len("/active_context"):].lstrip()
|
|
379
|
-
parts = args_text.split()
|
|
380
|
-
last_part = parts[-1] if parts and not text.endswith(" ") else ""
|
|
381
|
-
|
|
382
|
-
# Complete subcommands
|
|
383
|
-
if not args_text or (len(parts) == 1 and not text.endswith(" ")):
|
|
384
|
-
for sub_cmd in COMMAND_HIERARCHY["/active_context"]:
|
|
385
|
-
if sub_cmd.startswith(last_part):
|
|
386
|
-
yield Completion(sub_cmd, start_position=-len(last_part))
|
|
387
|
-
|
|
388
|
-
# Complete action file names for /run
|
|
389
|
-
elif parts and parts[0] == "/run":
|
|
390
|
-
# Assuming action files are in 'actions' dir and end with .yml
|
|
391
|
-
action_dir = "actions"
|
|
392
|
-
if os.path.isdir(action_dir):
|
|
393
|
-
try:
|
|
394
|
-
action_files = [f for f in os.listdir(action_dir) if f.endswith(".yml")]
|
|
395
|
-
yield from self._complete_items(last_part, action_files)
|
|
396
|
-
except OSError:
|
|
397
|
-
pass # Ignore if cannot list dir
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
def _handle_mode(self, document: Document, complete_event: CompleteEvent, word: str, text: str) -> Iterable[Completion]:
|
|
401
|
-
"""Handles completions for /mode command."""
|
|
402
|
-
args_text = text[len("/mode"):].lstrip()
|
|
403
|
-
modes = ["normal", "auto_detect", "voice_input"]
|
|
404
|
-
yield from self._complete_items(args_text, modes)
|
|
405
|
-
|
|
406
|
-
def _handle_design(self, document: Document, complete_event: CompleteEvent, word: str, text: str) -> Iterable[Completion]:
|
|
407
|
-
"""Handles completions for /design command."""
|
|
408
|
-
args_text = text[len("/design"):].lstrip()
|
|
409
|
-
parts = args_text.split()
|
|
410
|
-
last_part = parts[-1] if parts and not text.endswith(" ") else ""
|
|
411
|
-
|
|
412
|
-
# Complete subcommands
|
|
413
|
-
if not args_text or (len(parts) == 1 and not text.endswith(" ")):
|
|
414
|
-
for sub_cmd in COMMAND_HIERARCHY["/design"]:
|
|
415
|
-
if sub_cmd.startswith(last_part):
|
|
416
|
-
yield Completion(sub_cmd, start_position=-len(last_part))
|
|
417
|
-
|
|
418
|
-
def _handle_text_with_symbols(self, document: Document, complete_event: CompleteEvent, word: str, text: str) -> Iterable[Completion]:
|
|
419
|
-
"""Handles general text input, including @, @@, <img> tags and command-specific subcommands."""
|
|
420
|
-
# Check for command-specific subcommands first
|
|
421
|
-
parts = text.split(maxsplit=1)
|
|
422
|
-
command = parts[0]
|
|
423
|
-
if command in COMMAND_HIERARCHY:
|
|
424
|
-
args_text = parts[1] if len(parts) > 1 else ""
|
|
425
|
-
sub_parts = args_text.split()
|
|
426
|
-
last_part = sub_parts[-1] if sub_parts and not text.endswith(" ") else ""
|
|
427
|
-
|
|
428
|
-
# Complete subcommands if applicable
|
|
429
|
-
if not args_text or (len(sub_parts) == 1 and not text.endswith(" ")):
|
|
430
|
-
if isinstance(COMMAND_HIERARCHY[command], dict):
|
|
431
|
-
for sub_cmd in COMMAND_HIERARCHY[command]:
|
|
432
|
-
if sub_cmd.startswith(last_part):
|
|
433
|
-
yield Completion(sub_cmd, start_position=-len(last_part))
|
|
434
|
-
|
|
435
|
-
# Now handle @, @@, <img> regardless of command (or if no command)
|
|
436
|
-
if word.startswith("@") and not word.startswith("@@"):
|
|
437
|
-
yield from self._handle_at_completion(document, complete_event, word, text)
|
|
438
|
-
elif word.startswith("@@"):
|
|
439
|
-
yield from self._handle_double_at_completion(document, complete_event, word, text)
|
|
440
|
-
elif word.startswith("<"): # Potential tag completion
|
|
441
|
-
yield from self._handle_img_tag(document, complete_event, word, text)
|
|
442
|
-
|
|
443
|
-
def _handle_rules(self, document: Document, complete_event: CompleteEvent, word: str, text: str) -> Iterable[Completion]:
|
|
444
|
-
"""处理 /rules 命令的补全,支持子命令和规则文件路径。同时支持 @ 和 @@ 符号。"""
|
|
445
|
-
args_text = text[len("/rules"):].lstrip()
|
|
446
|
-
parts = args_text.split()
|
|
447
|
-
last_part = parts[-1] if parts and not text.endswith(" ") else ""
|
|
448
|
-
|
|
449
|
-
# 补全子命令
|
|
450
|
-
if not args_text or (len(parts) == 1 and not text.endswith(" ") and parts[0].startswith("/")):
|
|
451
|
-
for sub_cmd in COMMAND_HIERARCHY["/rules"]:
|
|
452
|
-
if sub_cmd.startswith(last_part):
|
|
453
|
-
yield Completion(sub_cmd, start_position=-len(last_part))
|
|
454
|
-
return
|
|
455
|
-
|
|
456
|
-
# 根据子命令补全参数
|
|
457
|
-
if parts and parts[0] == "/list" or parts[0] == "/get" or parts[0] == "/remove":
|
|
458
|
-
# 获取规则文件或目录补全,可以是通配符
|
|
459
|
-
# 这里可以简单地提供文件路径补全
|
|
460
|
-
yield from self._complete_file_paths(last_part, text)
|
|
461
|
-
# 也可以添加常用通配符补全
|
|
462
|
-
common_patterns = ["*.md", "*.rules", "*.txt"]
|
|
463
|
-
for pattern in common_patterns:
|
|
464
|
-
if pattern.startswith(last_part):
|
|
465
|
-
yield Completion(pattern, start_position=-len(last_part))
|
|
466
|
-
return
|
|
467
|
-
|
|
468
|
-
# 对于 /commit 子命令,补全 /query
|
|
469
|
-
if parts and parts[0] == "/commit":
|
|
470
|
-
if "/query".startswith(last_part):
|
|
471
|
-
yield Completion("/query", start_position=-len(last_part))
|
|
472
|
-
return
|
|
473
|
-
|
|
474
|
-
# 支持 @ 和 @@ 符号的补全,不管当前命令是什么
|
|
475
|
-
if word.startswith("@") and not word.startswith("@@"):
|
|
476
|
-
yield from self._handle_at_completion(document, complete_event, word, text)
|
|
477
|
-
elif word.startswith("@@"):
|
|
478
|
-
yield from self._handle_double_at_completion(document, complete_event, word, text)
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
# --- Symbol/Tag Handlers ---
|
|
482
|
-
def _handle_at_completion(self, document: Document, complete_event: CompleteEvent, word: str, text: str) -> Iterable[Completion]:
|
|
483
|
-
"""Handles completion for single '@' (file paths)."""
|
|
484
|
-
name = word[1:]
|
|
485
|
-
yield from self._complete_file_paths(name, text, is_symbol=True)
|
|
486
|
-
|
|
487
|
-
def _handle_double_at_completion(self, document: Document, complete_event: CompleteEvent, word: str, text: str) -> Iterable[Completion]:
|
|
488
|
-
"""Handles completion for double '@@' (symbols)."""
|
|
489
|
-
name = word[2:]
|
|
490
|
-
yield from self._complete_symbols(name)
|
|
491
|
-
|
|
492
|
-
def _handle_img_tag(self, document: Document, complete_event: CompleteEvent, word: str, text: str) -> Iterable[Completion]:
|
|
493
|
-
"""Handles completion for <img> tags and paths within them."""
|
|
494
|
-
image_extensions = (
|
|
495
|
-
".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".tif", ".webp",
|
|
496
|
-
".svg", ".ico", ".heic", ".heif", ".raw", ".cr2", ".nef", ".arw",
|
|
497
|
-
".dng", ".orf", ".rw2", ".pef", ".srw", ".eps", ".ai", ".psd", ".xcf",
|
|
498
|
-
)
|
|
499
|
-
|
|
500
|
-
# Basic tag completion
|
|
501
|
-
if "<img".startswith(word):
|
|
502
|
-
yield Completion("<img>", start_position=-len(word))
|
|
503
|
-
if "</img".startswith(word):
|
|
504
|
-
yield Completion("</img>", start_position=-len(word))
|
|
505
|
-
|
|
506
|
-
# Path completion inside <img> tag
|
|
507
|
-
# Find the last opening <img> tag that isn't closed yet
|
|
508
|
-
last_open_img = text.rfind("<img>")
|
|
509
|
-
last_close_img = text.rfind("</img>")
|
|
510
|
-
|
|
511
|
-
if last_open_img != -1 and (last_close_img == -1 or last_close_img < last_open_img):
|
|
512
|
-
path_prefix = text[last_open_img + len("<img>"):]
|
|
513
|
-
current_path_word = document.get_word_before_cursor(WORD=True) # Path part being typed
|
|
514
|
-
|
|
515
|
-
# Only complete if cursor is within the tag content
|
|
516
|
-
if document.cursor_position > last_open_img + len("<img>"):
|
|
517
|
-
|
|
518
|
-
search_dir = os.path.dirname(path_prefix) if os.path.dirname(path_prefix) else "."
|
|
519
|
-
file_basename = os.path.basename(current_path_word)
|
|
520
|
-
|
|
521
|
-
try:
|
|
522
|
-
if os.path.isdir(search_dir):
|
|
523
|
-
for item in os.listdir(search_dir):
|
|
524
|
-
full_path = os.path.join(search_dir, item)
|
|
525
|
-
# Suggest directories or image files matching the prefix
|
|
526
|
-
if item.startswith(file_basename):
|
|
527
|
-
if os.path.isdir(full_path):
|
|
528
|
-
relative_path = os.path.relpath(full_path, ".") # Use relative path
|
|
529
|
-
yield Completion(relative_path + os.sep, start_position=-len(current_path_word), display=item + "/")
|
|
530
|
-
elif item.lower().endswith(image_extensions):
|
|
531
|
-
relative_path = os.path.relpath(full_path, ".") # Use relative path
|
|
532
|
-
yield Completion(relative_path, start_position=-len(current_path_word), display=item)
|
|
533
|
-
except OSError:
|
|
534
|
-
pass # Ignore errors listing directories
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
# --- Helper Methods ---
|
|
538
|
-
|
|
539
|
-
def _complete_items_with_in(self, word: str, items: Iterable[str]) -> Iterable[Completion]:
|
|
540
|
-
"""Generic helper to complete a word from a list of items."""
|
|
541
|
-
for item in items:
|
|
542
|
-
if item and word in item:
|
|
543
|
-
yield Completion(item, start_position=-len(word))
|
|
544
|
-
|
|
545
|
-
def _complete_items(self, word: str, items: Iterable[str]) -> Iterable[Completion]:
|
|
546
|
-
"""Generic helper to complete a word from a list of items."""
|
|
547
|
-
if word is None:
|
|
548
|
-
word = ""
|
|
549
|
-
for item in items:
|
|
550
|
-
if item and item.startswith(word):
|
|
551
|
-
yield Completion(item, start_position=-len(word))
|
|
552
|
-
|
|
553
|
-
def _complete_config_keys(self, word: str, add_colon: bool = False) -> Iterable[Completion]:
|
|
554
|
-
"""Helper to complete configuration keys."""
|
|
555
|
-
suffix = ":" if add_colon else ""
|
|
556
|
-
for key in self.config_keys:
|
|
557
|
-
if key.startswith(word):
|
|
558
|
-
yield Completion(key + suffix, start_position=-len(word))
|
|
559
|
-
|
|
560
|
-
def _complete_file_paths(self, name: str, text: str, is_symbol: bool = False) -> Iterable[Completion]:
|
|
561
|
-
"""Helper to complete file paths (@ completion or general path)."""
|
|
562
|
-
if name is None: name = ""
|
|
563
|
-
start_pos = -len(name)
|
|
564
|
-
|
|
565
|
-
# Prioritize active files if triggered by @
|
|
566
|
-
if is_symbol:
|
|
567
|
-
for file_path in self.current_file_names:
|
|
568
|
-
rel_path = os.path.relpath(file_path, self.file_system_model.project_root)
|
|
569
|
-
display_name = self._get_display_path(file_path)
|
|
570
|
-
if name in rel_path or name in os.path.basename(file_path):
|
|
571
|
-
yield Completion(rel_path, start_position=start_pos, display=f"{display_name} (active)")
|
|
572
|
-
|
|
573
|
-
# General file path completion (relative paths with dot)
|
|
574
|
-
if name.startswith("."):
|
|
575
|
-
yield from self._complete_items(name, self.all_files_with_dot)
|
|
576
|
-
return # Don't mix with other completions if starting with .
|
|
577
|
-
|
|
578
|
-
# Complete base file names
|
|
579
|
-
yield from self._complete_items(name, self.all_file_names)
|
|
580
|
-
|
|
581
|
-
# Complete full paths (if name is part of the path)
|
|
582
|
-
for file_path in self.all_files:
|
|
583
|
-
rel_path = os.path.relpath(file_path, self.file_system_model.project_root)
|
|
584
|
-
if name and name in rel_path and file_path not in self.current_file_names: # Avoid duplicates if already shown as active
|
|
585
|
-
display_name = self._get_display_path(file_path)
|
|
586
|
-
yield Completion(rel_path, start_position=start_pos, display=display_name)
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
def _complete_symbols(self, name: str) -> Iterable[Completion]:
|
|
590
|
-
"""Helper to complete symbols (@@ completion)."""
|
|
591
|
-
if name is None: name = ""
|
|
592
|
-
start_pos = -len(name)
|
|
593
|
-
for symbol in self.symbol_list:
|
|
594
|
-
# Assuming symbol has attributes symbol_name, file_name, symbol_type
|
|
595
|
-
if name in symbol.symbol_name:
|
|
596
|
-
file_name = symbol.file_name
|
|
597
|
-
display_name = self._get_display_path(file_name)
|
|
598
|
-
display_text = f"{symbol.symbol_name} ({display_name}/{symbol.symbol_type})"
|
|
599
|
-
completion_text = f"{symbol.symbol_name} ({file_name}/{symbol.symbol_type})"
|
|
600
|
-
yield Completion(completion_text, start_position=start_pos, display=display_text)
|
|
601
|
-
|
|
602
|
-
def _get_display_path(self, file_path: str, max_parts: int = 3) -> str:
|
|
603
|
-
"""Helper to create a shorter display path."""
|
|
604
|
-
try:
|
|
605
|
-
# Use relative path for display consistency
|
|
606
|
-
rel_path = os.path.relpath(file_path, self.file_system_model.project_root)
|
|
607
|
-
parts = rel_path.split(os.sep)
|
|
608
|
-
if len(parts) > max_parts:
|
|
609
|
-
return os.path.join("...", *parts[-max_parts:])
|
|
610
|
-
return rel_path
|
|
611
|
-
except ValueError: # Handle cases where paths are not relative (e.g., different drives on Windows)
|
|
612
|
-
parts = file_path.split(os.sep)
|
|
613
|
-
if len(parts) > max_parts:
|
|
614
|
-
return os.path.join("...", *parts[-max_parts:])
|
|
615
|
-
return file_path
|