auto-coder 1.0.0__py3-none-any.whl → 2.0.0__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.0.dist-info/LICENSE +158 -0
- auto_coder-2.0.0.dist-info/METADATA +558 -0
- auto_coder-2.0.0.dist-info/RECORD +795 -0
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.0.dist-info}/WHEEL +1 -1
- {auto_coder-1.0.0.dist-info → auto_coder-2.0.0.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 +73 -59
- autocoder/auto_coder.py +31 -40
- autocoder/auto_coder_rag.py +11 -1084
- autocoder/auto_coder_runner.py +970 -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 +401 -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 +288 -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 +349 -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 +1051 -0
- autocoder/default_project/__init__.py +501 -0
- autocoder/dispacher/__init__.py +4 -12
- autocoder/dispacher/actions/action.py +165 -7
- autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
- autocoder/index/entry.py +116 -124
- 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 +932 -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 +489 -0
- autocoder/workflow_agents/loader.py +737 -0
- autocoder/workflow_agents/runner.py +267 -0
- autocoder/workflow_agents/types.py +172 -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.0.dist-info}/top_level.txt +0 -0
- /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Todo manager data models.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import time
|
|
6
|
+
import uuid
|
|
7
|
+
from typing import Union, Dict, List, Optional, Any
|
|
8
|
+
from dataclasses import dataclass, field
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class Todo:
|
|
13
|
+
"""Todo item data model"""
|
|
14
|
+
|
|
15
|
+
content: str
|
|
16
|
+
todo_id: str = field(default_factory=lambda: str(uuid.uuid4())[:8])
|
|
17
|
+
status: str = "pending"
|
|
18
|
+
priority: str = "medium"
|
|
19
|
+
created_at: float = field(default_factory=time.time)
|
|
20
|
+
updated_at: float = field(default_factory=time.time)
|
|
21
|
+
notes: Optional[str] = None
|
|
22
|
+
dependencies: Optional[List[str]] = None
|
|
23
|
+
|
|
24
|
+
def __post_init__(self):
|
|
25
|
+
"""Data validation"""
|
|
26
|
+
self._validate()
|
|
27
|
+
|
|
28
|
+
def _validate(self):
|
|
29
|
+
"""Validate todo data"""
|
|
30
|
+
# Validate content
|
|
31
|
+
if not self.content or (isinstance(self.content, str) and len(self.content.strip()) == 0):
|
|
32
|
+
raise ValueError("Todo content cannot be empty")
|
|
33
|
+
|
|
34
|
+
# Validate status
|
|
35
|
+
valid_statuses = ["pending", "in_progress", "completed", "cancelled"]
|
|
36
|
+
if self.status not in valid_statuses:
|
|
37
|
+
raise ValueError(f"Invalid status: {self.status}, valid statuses: {valid_statuses}")
|
|
38
|
+
|
|
39
|
+
# Validate priority
|
|
40
|
+
valid_priorities = ["low", "medium", "high"]
|
|
41
|
+
if self.priority not in valid_priorities:
|
|
42
|
+
raise ValueError(f"Invalid priority: {self.priority}, valid priorities: {valid_priorities}")
|
|
43
|
+
|
|
44
|
+
# Validate timestamps
|
|
45
|
+
if not isinstance(self.created_at, (int, float)) or self.created_at <= 0:
|
|
46
|
+
raise ValueError("Invalid created_at timestamp")
|
|
47
|
+
|
|
48
|
+
if not isinstance(self.updated_at, (int, float)) or self.updated_at < self.created_at:
|
|
49
|
+
raise ValueError("Invalid updated_at timestamp")
|
|
50
|
+
|
|
51
|
+
# Validate todo ID
|
|
52
|
+
if not isinstance(self.todo_id, str) or len(self.todo_id) == 0:
|
|
53
|
+
raise ValueError("Todo ID cannot be empty")
|
|
54
|
+
|
|
55
|
+
def update_status(self, status: str):
|
|
56
|
+
"""Update todo status"""
|
|
57
|
+
valid_statuses = ["pending", "in_progress", "completed", "cancelled"]
|
|
58
|
+
if status not in valid_statuses:
|
|
59
|
+
raise ValueError(f"Invalid status: {status}")
|
|
60
|
+
|
|
61
|
+
self.status = status
|
|
62
|
+
self.updated_at = time.time()
|
|
63
|
+
|
|
64
|
+
def update_content(self, content: str):
|
|
65
|
+
"""Update todo content"""
|
|
66
|
+
if not content or len(content.strip()) == 0:
|
|
67
|
+
raise ValueError("Todo content cannot be empty")
|
|
68
|
+
|
|
69
|
+
self.content = content
|
|
70
|
+
self.updated_at = time.time()
|
|
71
|
+
|
|
72
|
+
def update_priority(self, priority: str):
|
|
73
|
+
"""Update todo priority"""
|
|
74
|
+
valid_priorities = ["low", "medium", "high"]
|
|
75
|
+
if priority not in valid_priorities:
|
|
76
|
+
raise ValueError(f"Invalid priority: {priority}")
|
|
77
|
+
|
|
78
|
+
self.priority = priority
|
|
79
|
+
self.updated_at = time.time()
|
|
80
|
+
|
|
81
|
+
def add_notes(self, notes: str):
|
|
82
|
+
"""Add or update notes"""
|
|
83
|
+
self.notes = notes
|
|
84
|
+
self.updated_at = time.time()
|
|
85
|
+
|
|
86
|
+
def add_dependency(self, todo_id: str):
|
|
87
|
+
"""Add a dependency to another todo"""
|
|
88
|
+
if self.dependencies is None:
|
|
89
|
+
self.dependencies = []
|
|
90
|
+
|
|
91
|
+
if todo_id not in self.dependencies:
|
|
92
|
+
self.dependencies.append(todo_id)
|
|
93
|
+
self.updated_at = time.time()
|
|
94
|
+
|
|
95
|
+
def remove_dependency(self, todo_id: str):
|
|
96
|
+
"""Remove a dependency"""
|
|
97
|
+
if self.dependencies and todo_id in self.dependencies:
|
|
98
|
+
self.dependencies.remove(todo_id)
|
|
99
|
+
self.updated_at = time.time()
|
|
100
|
+
|
|
101
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
102
|
+
"""Serialize to dictionary"""
|
|
103
|
+
return {
|
|
104
|
+
"todo_id": self.todo_id,
|
|
105
|
+
"content": self.content,
|
|
106
|
+
"status": self.status,
|
|
107
|
+
"priority": self.priority,
|
|
108
|
+
"created_at": self.created_at,
|
|
109
|
+
"updated_at": self.updated_at,
|
|
110
|
+
"notes": self.notes,
|
|
111
|
+
"dependencies": self.dependencies
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@classmethod
|
|
115
|
+
def from_dict(cls, data: Dict[str, Any]) -> "Todo":
|
|
116
|
+
"""Deserialize from dictionary"""
|
|
117
|
+
return cls(
|
|
118
|
+
todo_id=data["todo_id"],
|
|
119
|
+
content=data["content"],
|
|
120
|
+
status=data.get("status", "pending"),
|
|
121
|
+
priority=data.get("priority", "medium"),
|
|
122
|
+
created_at=data["created_at"],
|
|
123
|
+
updated_at=data["updated_at"],
|
|
124
|
+
notes=data.get("notes"),
|
|
125
|
+
dependencies=data.get("dependencies")
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
@dataclass
|
|
130
|
+
class TodoList:
|
|
131
|
+
"""Todo list data model for a conversation"""
|
|
132
|
+
|
|
133
|
+
conversation_id: str
|
|
134
|
+
todos: List[Dict[str, Any]] = field(default_factory=list)
|
|
135
|
+
created_at: float = field(default_factory=time.time)
|
|
136
|
+
updated_at: float = field(default_factory=time.time)
|
|
137
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
138
|
+
|
|
139
|
+
def __post_init__(self):
|
|
140
|
+
"""Data validation"""
|
|
141
|
+
self._validate()
|
|
142
|
+
|
|
143
|
+
def _validate(self):
|
|
144
|
+
"""Validate todo list data"""
|
|
145
|
+
# Validate conversation ID
|
|
146
|
+
if not isinstance(self.conversation_id, str) or len(self.conversation_id) == 0:
|
|
147
|
+
raise ValueError("Conversation ID cannot be empty")
|
|
148
|
+
|
|
149
|
+
# Validate timestamps
|
|
150
|
+
if not isinstance(self.created_at, (int, float)) or self.created_at <= 0:
|
|
151
|
+
raise ValueError("Invalid created_at timestamp")
|
|
152
|
+
|
|
153
|
+
if not isinstance(self.updated_at, (int, float)) or self.updated_at < self.created_at:
|
|
154
|
+
raise ValueError("Invalid updated_at timestamp")
|
|
155
|
+
|
|
156
|
+
# Validate todos list
|
|
157
|
+
if not isinstance(self.todos, list):
|
|
158
|
+
raise ValueError("Todos must be a list")
|
|
159
|
+
|
|
160
|
+
def add_todo(self, todo: Todo):
|
|
161
|
+
"""Add a todo to the list"""
|
|
162
|
+
self.todos.append(todo.to_dict())
|
|
163
|
+
self.updated_at = time.time()
|
|
164
|
+
|
|
165
|
+
def remove_todo(self, todo_id: str) -> bool:
|
|
166
|
+
"""Remove a todo from the list"""
|
|
167
|
+
for i, todo_data in enumerate(self.todos):
|
|
168
|
+
if todo_data.get("todo_id") == todo_id:
|
|
169
|
+
del self.todos[i]
|
|
170
|
+
self.updated_at = time.time()
|
|
171
|
+
return True
|
|
172
|
+
return False
|
|
173
|
+
|
|
174
|
+
def get_todo(self, todo_id: str) -> Optional[Dict[str, Any]]:
|
|
175
|
+
"""Get a todo from the list"""
|
|
176
|
+
for todo_data in self.todos:
|
|
177
|
+
if todo_data.get("todo_id") == todo_id:
|
|
178
|
+
return todo_data
|
|
179
|
+
return None
|
|
180
|
+
|
|
181
|
+
def update_todo(self, todo_id: str, **kwargs) -> bool:
|
|
182
|
+
"""Update a todo in the list"""
|
|
183
|
+
for todo_data in self.todos:
|
|
184
|
+
if todo_data.get("todo_id") == todo_id:
|
|
185
|
+
# Update fields
|
|
186
|
+
for key, value in kwargs.items():
|
|
187
|
+
if key in ["content", "status", "priority", "notes", "dependencies"]:
|
|
188
|
+
todo_data[key] = value
|
|
189
|
+
|
|
190
|
+
todo_data["updated_at"] = time.time()
|
|
191
|
+
self.updated_at = time.time()
|
|
192
|
+
return True
|
|
193
|
+
return False
|
|
194
|
+
|
|
195
|
+
def get_todos_by_status(self, status: str) -> List[Dict[str, Any]]:
|
|
196
|
+
"""Get todos by status"""
|
|
197
|
+
return [todo for todo in self.todos if todo.get("status") == status]
|
|
198
|
+
|
|
199
|
+
def get_todos_by_priority(self, priority: str) -> List[Dict[str, Any]]:
|
|
200
|
+
"""Get todos by priority"""
|
|
201
|
+
return [todo for todo in self.todos if todo.get("priority") == priority]
|
|
202
|
+
|
|
203
|
+
def get_statistics(self) -> Dict[str, int]:
|
|
204
|
+
"""Get todo statistics"""
|
|
205
|
+
stats = {
|
|
206
|
+
"total": len(self.todos),
|
|
207
|
+
"pending": 0,
|
|
208
|
+
"in_progress": 0,
|
|
209
|
+
"completed": 0,
|
|
210
|
+
"cancelled": 0
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
for todo in self.todos:
|
|
214
|
+
status = todo.get("status", "pending")
|
|
215
|
+
if status in stats:
|
|
216
|
+
stats[status] += 1
|
|
217
|
+
|
|
218
|
+
return stats
|
|
219
|
+
|
|
220
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
221
|
+
"""Serialize to dictionary"""
|
|
222
|
+
return {
|
|
223
|
+
"conversation_id": self.conversation_id,
|
|
224
|
+
"todos": self.todos,
|
|
225
|
+
"created_at": self.created_at,
|
|
226
|
+
"updated_at": self.updated_at,
|
|
227
|
+
"metadata": self.metadata
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
@classmethod
|
|
231
|
+
def from_dict(cls, data: Dict[str, Any]) -> "TodoList":
|
|
232
|
+
"""Deserialize from dictionary"""
|
|
233
|
+
return cls(
|
|
234
|
+
conversation_id=data["conversation_id"],
|
|
235
|
+
todos=data.get("todos", []),
|
|
236
|
+
created_at=data["created_at"],
|
|
237
|
+
updated_at=data["updated_at"],
|
|
238
|
+
metadata=data.get("metadata")
|
|
239
|
+
)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Storage module for todo management.
|
|
3
|
+
|
|
4
|
+
This module provides storage functionality for todos and todo lists,
|
|
5
|
+
with support for file-based storage and extensible storage backends.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .base_storage import BaseStorage
|
|
9
|
+
from .file_storage import FileStorage
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
'BaseStorage',
|
|
13
|
+
'FileStorage'
|
|
14
|
+
]
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base storage interface for todo management.
|
|
3
|
+
|
|
4
|
+
This module defines the abstract base class for all storage implementations,
|
|
5
|
+
providing a consistent interface for todo and todo list operations.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from abc import ABC, abstractmethod
|
|
9
|
+
from typing import Optional, Dict, Any, List
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BaseStorage(ABC):
|
|
13
|
+
"""Abstract base class for todo storage implementations."""
|
|
14
|
+
|
|
15
|
+
@abstractmethod
|
|
16
|
+
def save_todo_list(self, conversation_id: str, todo_list_data: Dict[str, Any]) -> bool:
|
|
17
|
+
"""
|
|
18
|
+
Save a todo list to storage.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
conversation_id: The conversation ID
|
|
22
|
+
todo_list_data: The todo list data to save
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
True if save was successful, False otherwise
|
|
26
|
+
"""
|
|
27
|
+
pass
|
|
28
|
+
|
|
29
|
+
@abstractmethod
|
|
30
|
+
def load_todo_list(self, conversation_id: str) -> Optional[Dict[str, Any]]:
|
|
31
|
+
"""
|
|
32
|
+
Load a todo list from storage.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
conversation_id: The conversation ID
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
Todo list data or None if not found
|
|
39
|
+
"""
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
@abstractmethod
|
|
43
|
+
def delete_todo_list(self, conversation_id: str) -> bool:
|
|
44
|
+
"""
|
|
45
|
+
Delete a todo list from storage.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
conversation_id: The conversation ID
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
True if deletion was successful, False otherwise
|
|
52
|
+
"""
|
|
53
|
+
pass
|
|
54
|
+
|
|
55
|
+
@abstractmethod
|
|
56
|
+
def todo_list_exists(self, conversation_id: str) -> bool:
|
|
57
|
+
"""
|
|
58
|
+
Check if a todo list exists in storage.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
conversation_id: The conversation ID
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
True if todo list exists, False otherwise
|
|
65
|
+
"""
|
|
66
|
+
pass
|
|
67
|
+
|
|
68
|
+
@abstractmethod
|
|
69
|
+
def list_conversation_ids(self) -> List[str]:
|
|
70
|
+
"""
|
|
71
|
+
List all conversation IDs that have todo lists.
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
List of conversation IDs
|
|
75
|
+
"""
|
|
76
|
+
pass
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"""
|
|
2
|
+
File-based storage implementation for todo lists.
|
|
3
|
+
|
|
4
|
+
This module provides a file system storage implementation for todo lists,
|
|
5
|
+
storing each conversation's todos as a separate JSON file.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import json
|
|
10
|
+
import tempfile
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Optional, Dict, Any, List
|
|
13
|
+
from loguru import logger
|
|
14
|
+
|
|
15
|
+
from .base_storage import BaseStorage
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class FileStorage(BaseStorage):
|
|
19
|
+
"""File-based storage implementation for todo lists."""
|
|
20
|
+
|
|
21
|
+
def __init__(self, storage_path: str):
|
|
22
|
+
"""
|
|
23
|
+
Initialize file storage.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
storage_path: Base path for todo storage
|
|
27
|
+
"""
|
|
28
|
+
self.storage_path = Path(storage_path)
|
|
29
|
+
self._ensure_storage_directory()
|
|
30
|
+
|
|
31
|
+
def _ensure_storage_directory(self):
|
|
32
|
+
"""Ensure storage directory exists."""
|
|
33
|
+
self.storage_path.mkdir(parents=True, exist_ok=True)
|
|
34
|
+
|
|
35
|
+
def _get_todo_list_file_path(self, conversation_id: str) -> Path:
|
|
36
|
+
"""
|
|
37
|
+
Get file path for a conversation's todo list.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
conversation_id: The conversation ID
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
Path to the todo list file
|
|
44
|
+
"""
|
|
45
|
+
# Sanitize conversation ID for file system
|
|
46
|
+
safe_id = self._sanitize_filename(conversation_id)
|
|
47
|
+
return self.storage_path / f"{safe_id}.json"
|
|
48
|
+
|
|
49
|
+
def _sanitize_filename(self, filename: str) -> str:
|
|
50
|
+
"""
|
|
51
|
+
Sanitize filename to be safe for file system.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
filename: Original filename
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
Sanitized filename
|
|
58
|
+
"""
|
|
59
|
+
# Replace unsafe characters with underscores
|
|
60
|
+
unsafe_chars = '<>:"/\\|?*'
|
|
61
|
+
safe_name = filename
|
|
62
|
+
for char in unsafe_chars:
|
|
63
|
+
safe_name = safe_name.replace(char, '_')
|
|
64
|
+
|
|
65
|
+
# Limit length
|
|
66
|
+
if len(safe_name) > 200:
|
|
67
|
+
safe_name = safe_name[:200]
|
|
68
|
+
|
|
69
|
+
return safe_name
|
|
70
|
+
|
|
71
|
+
def _validate_todo_list_data(self, todo_list_data: Dict[str, Any]) -> bool:
|
|
72
|
+
"""
|
|
73
|
+
Validate todo list data structure.
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
todo_list_data: Todo list data to validate
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
True if valid, False otherwise
|
|
80
|
+
"""
|
|
81
|
+
required_fields = ['conversation_id', 'todos', 'created_at', 'updated_at']
|
|
82
|
+
|
|
83
|
+
for field in required_fields:
|
|
84
|
+
if field not in todo_list_data:
|
|
85
|
+
logger.error(f"Todo list validation failed: missing field '{field}'")
|
|
86
|
+
return False
|
|
87
|
+
|
|
88
|
+
if not isinstance(todo_list_data['todos'], list):
|
|
89
|
+
logger.error("Todo list validation failed: 'todos' must be a list")
|
|
90
|
+
return False
|
|
91
|
+
|
|
92
|
+
return True
|
|
93
|
+
|
|
94
|
+
def _atomic_write_file(self, file_path: Path, data: Dict[str, Any]) -> bool:
|
|
95
|
+
"""
|
|
96
|
+
Atomically write data to file.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
file_path: Target file path
|
|
100
|
+
data: Data to write
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
True if write was successful, False otherwise
|
|
104
|
+
"""
|
|
105
|
+
try:
|
|
106
|
+
# Write to temporary file first
|
|
107
|
+
temp_fd, temp_path = tempfile.mkstemp(
|
|
108
|
+
suffix='.tmp',
|
|
109
|
+
dir=file_path.parent,
|
|
110
|
+
prefix=f'{file_path.stem}_'
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
with os.fdopen(temp_fd, 'w', encoding='utf-8') as f:
|
|
115
|
+
json.dump(data, f, indent=2, ensure_ascii=False)
|
|
116
|
+
|
|
117
|
+
# Atomic move
|
|
118
|
+
Path(temp_path).replace(file_path)
|
|
119
|
+
return True
|
|
120
|
+
|
|
121
|
+
except Exception:
|
|
122
|
+
# Clean up temp file on error
|
|
123
|
+
try:
|
|
124
|
+
os.unlink(temp_path)
|
|
125
|
+
except:
|
|
126
|
+
pass
|
|
127
|
+
raise
|
|
128
|
+
|
|
129
|
+
except Exception as e:
|
|
130
|
+
logger.error(f"Failed to write file atomically {file_path}: {e}")
|
|
131
|
+
return False
|
|
132
|
+
|
|
133
|
+
def save_todo_list(self, conversation_id: str, todo_list_data: Dict[str, Any]) -> bool:
|
|
134
|
+
"""
|
|
135
|
+
Save a todo list to storage.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
conversation_id: The conversation ID
|
|
139
|
+
todo_list_data: The todo list data to save
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
True if save was successful, False otherwise
|
|
143
|
+
"""
|
|
144
|
+
try:
|
|
145
|
+
# Validate data
|
|
146
|
+
if not self._validate_todo_list_data(todo_list_data):
|
|
147
|
+
return False
|
|
148
|
+
|
|
149
|
+
# Get file path
|
|
150
|
+
file_path = self._get_todo_list_file_path(conversation_id)
|
|
151
|
+
|
|
152
|
+
# Atomic write
|
|
153
|
+
success = self._atomic_write_file(file_path, todo_list_data)
|
|
154
|
+
|
|
155
|
+
if success:
|
|
156
|
+
logger.debug(f"Successfully saved todo list for conversation {conversation_id}")
|
|
157
|
+
else:
|
|
158
|
+
logger.error(f"Failed to save todo list for conversation {conversation_id}")
|
|
159
|
+
|
|
160
|
+
return success
|
|
161
|
+
|
|
162
|
+
except Exception as e:
|
|
163
|
+
logger.error(f"Error saving todo list for conversation {conversation_id}: {e}")
|
|
164
|
+
return False
|
|
165
|
+
|
|
166
|
+
def load_todo_list(self, conversation_id: str) -> Optional[Dict[str, Any]]:
|
|
167
|
+
"""
|
|
168
|
+
Load a todo list from storage.
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
conversation_id: The conversation ID
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
Todo list data or None if not found
|
|
175
|
+
"""
|
|
176
|
+
try:
|
|
177
|
+
file_path = self._get_todo_list_file_path(conversation_id)
|
|
178
|
+
|
|
179
|
+
if not file_path.exists():
|
|
180
|
+
logger.debug(f"Todo list file not found for conversation {conversation_id}")
|
|
181
|
+
return None
|
|
182
|
+
|
|
183
|
+
with open(file_path, 'r', encoding='utf-8') as f:
|
|
184
|
+
data = json.load(f)
|
|
185
|
+
|
|
186
|
+
# Validate loaded data
|
|
187
|
+
if not self._validate_todo_list_data(data):
|
|
188
|
+
logger.error(f"Invalid todo list data for conversation {conversation_id}")
|
|
189
|
+
return None
|
|
190
|
+
|
|
191
|
+
logger.debug(f"Successfully loaded todo list for conversation {conversation_id}")
|
|
192
|
+
return data
|
|
193
|
+
|
|
194
|
+
except json.JSONDecodeError as e:
|
|
195
|
+
logger.error(f"Invalid JSON in todo list file for conversation {conversation_id}: {e}")
|
|
196
|
+
return None
|
|
197
|
+
except Exception as e:
|
|
198
|
+
logger.error(f"Error loading todo list for conversation {conversation_id}: {e}")
|
|
199
|
+
return None
|
|
200
|
+
|
|
201
|
+
def delete_todo_list(self, conversation_id: str) -> bool:
|
|
202
|
+
"""
|
|
203
|
+
Delete a todo list from storage.
|
|
204
|
+
|
|
205
|
+
Args:
|
|
206
|
+
conversation_id: The conversation ID
|
|
207
|
+
|
|
208
|
+
Returns:
|
|
209
|
+
True if deletion was successful, False otherwise
|
|
210
|
+
"""
|
|
211
|
+
try:
|
|
212
|
+
file_path = self._get_todo_list_file_path(conversation_id)
|
|
213
|
+
|
|
214
|
+
if file_path.exists():
|
|
215
|
+
file_path.unlink()
|
|
216
|
+
logger.debug(f"Successfully deleted todo list for conversation {conversation_id}")
|
|
217
|
+
return True
|
|
218
|
+
else:
|
|
219
|
+
logger.debug(f"Todo list file not found for conversation {conversation_id} (already deleted)")
|
|
220
|
+
return True
|
|
221
|
+
|
|
222
|
+
except Exception as e:
|
|
223
|
+
logger.error(f"Error deleting todo list for conversation {conversation_id}: {e}")
|
|
224
|
+
return False
|
|
225
|
+
|
|
226
|
+
def todo_list_exists(self, conversation_id: str) -> bool:
|
|
227
|
+
"""
|
|
228
|
+
Check if a todo list exists in storage.
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
conversation_id: The conversation ID
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
True if todo list exists, False otherwise
|
|
235
|
+
"""
|
|
236
|
+
try:
|
|
237
|
+
file_path = self._get_todo_list_file_path(conversation_id)
|
|
238
|
+
return file_path.exists()
|
|
239
|
+
except Exception as e:
|
|
240
|
+
logger.error(f"Error checking todo list existence for conversation {conversation_id}: {e}")
|
|
241
|
+
return False
|
|
242
|
+
|
|
243
|
+
def list_conversation_ids(self) -> List[str]:
|
|
244
|
+
"""
|
|
245
|
+
List all conversation IDs that have todo lists.
|
|
246
|
+
|
|
247
|
+
Returns:
|
|
248
|
+
List of conversation IDs
|
|
249
|
+
"""
|
|
250
|
+
try:
|
|
251
|
+
conversation_ids = []
|
|
252
|
+
|
|
253
|
+
if not self.storage_path.exists():
|
|
254
|
+
return conversation_ids
|
|
255
|
+
|
|
256
|
+
for file_path in self.storage_path.glob("*.json"):
|
|
257
|
+
# Extract conversation ID from filename
|
|
258
|
+
conversation_id = file_path.stem
|
|
259
|
+
|
|
260
|
+
# Try to load and validate the file
|
|
261
|
+
try:
|
|
262
|
+
with open(file_path, 'r', encoding='utf-8') as f:
|
|
263
|
+
data = json.load(f)
|
|
264
|
+
|
|
265
|
+
if self._validate_todo_list_data(data):
|
|
266
|
+
# Use the conversation ID from the file content
|
|
267
|
+
actual_id = data.get('conversation_id', conversation_id)
|
|
268
|
+
conversation_ids.append(actual_id)
|
|
269
|
+
|
|
270
|
+
except Exception as e:
|
|
271
|
+
logger.warning(f"Skipping invalid todo list file {file_path}: {e}")
|
|
272
|
+
continue
|
|
273
|
+
|
|
274
|
+
return conversation_ids
|
|
275
|
+
|
|
276
|
+
except Exception as e:
|
|
277
|
+
logger.error(f"Error listing conversation IDs: {e}")
|
|
278
|
+
return []
|
|
@@ -4,6 +4,7 @@ from typing import List, Dict, Optional, Union, Callable
|
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
import time
|
|
6
6
|
import re
|
|
7
|
+
import importlib.resources as resources
|
|
7
8
|
|
|
8
9
|
from autocoder.rag.variable_holder import VariableHolder
|
|
9
10
|
from .models import TokenResult, DirectoryTokenResult
|
|
@@ -30,9 +31,30 @@ class TokenCounter:
|
|
|
30
31
|
self.parallel = parallel
|
|
31
32
|
self.max_workers = max_workers
|
|
32
33
|
|
|
33
|
-
# 确保 tokenizer
|
|
34
|
+
# 确保 tokenizer 已经加载,如果没有则自动初始化
|
|
35
|
+
self._ensure_tokenizer_initialized()
|
|
36
|
+
|
|
37
|
+
def _ensure_tokenizer_initialized(self):
|
|
38
|
+
"""
|
|
39
|
+
确保 tokenizer 已经初始化,如果没有则自动初始化
|
|
40
|
+
"""
|
|
34
41
|
if VariableHolder.TOKENIZER_MODEL is None:
|
|
35
|
-
|
|
42
|
+
self._initialize_tokenizer()
|
|
43
|
+
|
|
44
|
+
def _initialize_tokenizer(self):
|
|
45
|
+
"""
|
|
46
|
+
初始化 tokenizer,参考 auto_coder_runner.py 中的 load_tokenizer 实现
|
|
47
|
+
"""
|
|
48
|
+
try:
|
|
49
|
+
from tokenizers import Tokenizer
|
|
50
|
+
tokenizer_path = str(resources.files("autocoder") / "data" / "tokenizer.json")
|
|
51
|
+
VariableHolder.TOKENIZER_PATH = tokenizer_path
|
|
52
|
+
VariableHolder.TOKENIZER_MODEL = Tokenizer.from_file(tokenizer_path)
|
|
53
|
+
except (FileNotFoundError, ImportError) as e:
|
|
54
|
+
raise RuntimeError(
|
|
55
|
+
f"Failed to initialize tokenizer: {str(e)}. "
|
|
56
|
+
f"Make sure tokenizer.json exists in the autocoder package data directory."
|
|
57
|
+
)
|
|
36
58
|
|
|
37
59
|
def count_file(self, file_path: str) -> TokenResult:
|
|
38
60
|
"""
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tools Manager Module
|
|
3
|
+
|
|
4
|
+
动态加载和管理 .autocodertools 目录中的工具命令文件的模块。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .manager import ToolsManager
|
|
8
|
+
from .models import ToolCommand, ToolsLoadResult
|
|
9
|
+
from .utils import extract_tool_help, is_tool_command_file
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"ToolsManager",
|
|
13
|
+
"ToolCommand",
|
|
14
|
+
"ToolsLoadResult",
|
|
15
|
+
"extract_tool_help",
|
|
16
|
+
"is_tool_command_file"
|
|
17
|
+
]
|