auto-coder 0.1.400__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-0.1.400.dist-info → auto_coder-2.0.0.dist-info}/WHEEL +1 -1
- {auto_coder-0.1.400.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 +25 -4
- 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 +1029 -2310
- 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 +1021 -372
- autocoder/chat_auto_coder_lang.py +23 -732
- autocoder/commands/auto_command.py +26 -9
- 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/file_monitor/test_file_monitor.py +307 -0
- autocoder/common/git_utils.py +51 -10
- 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 +746 -0
- autocoder/common/{context_pruner.py → pruner/context_pruner.py} +137 -40
- 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/{conversation_pruner.py → pruner/conversation_pruner.py} +26 -6
- autocoder/common/pruner/test_agentic_conversation_pruner.py +784 -0
- autocoder/common/pruner/test_context_pruner.py +546 -0
- 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/__init__.py +15 -0
- autocoder/common/tokens/counter.py +44 -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 +2729 -2052
- autocoder/common/v2/agent/agentic_edit_change_manager.py +474 -0
- autocoder/common/v2/agent/agentic_edit_tools/__init__.py +43 -2
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_list_tool_resolver.py +279 -0
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_read_tool_resolver.py +40 -0
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +52 -0
- autocoder/common/v2/agent/agentic_edit_tools/ask_followup_question_tool_resolver.py +8 -0
- 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 +565 -30
- 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 +244 -51
- 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 +409 -140
- 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 +209 -194
- autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +135 -0
- autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +328 -0
- 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 +386 -10
- autocoder/common/v2/agent/runner/__init__.py +31 -0
- autocoder/common/v2/agent/runner/base_runner.py +92 -0
- autocoder/common/v2/agent/runner/file_based_event_runner.py +217 -0
- autocoder/common/v2/agent/runner/sdk_runner.py +182 -0
- autocoder/common/v2/agent/runner/terminal_runner.py +396 -0
- autocoder/common/v2/agent/runner/tool_display.py +589 -0
- 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 +117 -125
- autocoder/{agent → index/filter}/agentic_filter.py +323 -334
- 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 +156 -37
- 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/run_context.py +9 -0
- autocoder/sdk/__init__.py +50 -161
- 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 +158 -170
- autocoder/sdk/cli/options.py +95 -22
- autocoder/sdk/constants.py +139 -51
- autocoder/sdk/core/auto_coder_core.py +484 -267
- autocoder/sdk/core/bridge.py +298 -118
- 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-0.1.400.dist-info/METADATA +0 -396
- auto_coder-0.1.400.dist-info/RECORD +0 -425
- auto_coder-0.1.400.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/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-0.1.400.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
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import yaml
|
|
3
3
|
import hashlib
|
|
4
|
-
import git
|
|
5
4
|
from typing import List, Dict, Tuple, Optional, Union, Any
|
|
6
5
|
from loguru import logger
|
|
7
6
|
from autocoder.common.git_utils import get_repo
|
|
@@ -9,6 +8,16 @@ from autocoder.common.printer import Printer
|
|
|
9
8
|
import byzerllm
|
|
10
9
|
from autocoder.common import git_utils
|
|
11
10
|
|
|
11
|
+
# 延迟导入git模块,避免启动时的导入错误
|
|
12
|
+
def _get_git_module():
|
|
13
|
+
"""延迟导入git模块"""
|
|
14
|
+
try:
|
|
15
|
+
import git
|
|
16
|
+
return git, True
|
|
17
|
+
except ImportError as e:
|
|
18
|
+
logger.warning(f"Git module not available: {e}. Some git features will be disabled.")
|
|
19
|
+
return None, False
|
|
20
|
+
|
|
12
21
|
class ActionYmlFileManager:
|
|
13
22
|
"""
|
|
14
23
|
Actions 目录文件操作工具类,用于抽象和管理 actions 目录下的 YAML 文件操作。
|
|
@@ -226,12 +235,9 @@ class ActionYmlFileManager:
|
|
|
226
235
|
|
|
227
236
|
try:
|
|
228
237
|
with open(yaml_path, 'w', encoding='utf-8') as f:
|
|
229
|
-
yaml.dump(content, f, allow_unicode=True, default_flow_style=False)
|
|
230
|
-
self.printer.print_in_terminal("yaml_update_success", style="green", yaml_file=yaml_path)
|
|
238
|
+
yaml.dump(content, f, allow_unicode=True, default_flow_style=False)
|
|
231
239
|
return True
|
|
232
|
-
except Exception as e:
|
|
233
|
-
self.printer.print_in_terminal("yaml_save_error", style="red",
|
|
234
|
-
yaml_file=yaml_path, error=str(e))
|
|
240
|
+
except Exception as e:
|
|
235
241
|
return False
|
|
236
242
|
|
|
237
243
|
def update_yaml_field(self, file_name: str, field: str, value: Any) -> bool:
|
|
@@ -365,9 +371,14 @@ class ActionYmlFileManager:
|
|
|
365
371
|
return [(query, urls, {})]
|
|
366
372
|
|
|
367
373
|
changes = {}
|
|
374
|
+
git_module, git_available = _get_git_module()
|
|
375
|
+
if not git_available:
|
|
376
|
+
self.printer.print_in_terminal("git_not_available", style="yellow")
|
|
377
|
+
return [(query, urls, {})]
|
|
378
|
+
|
|
368
379
|
try:
|
|
369
|
-
repo =
|
|
370
|
-
commit =repo.commit(commit_id)
|
|
380
|
+
repo = git_module.Repo(self.source_dir)
|
|
381
|
+
commit = repo.commit(commit_id)
|
|
371
382
|
if commit.parents:
|
|
372
383
|
parent = commit.parents[0]
|
|
373
384
|
# 获取所有文件的前后内容
|
|
@@ -379,7 +390,7 @@ class ActionYmlFileManager:
|
|
|
379
390
|
try:
|
|
380
391
|
if diff_item.a_blob:
|
|
381
392
|
before_content = repo.git.show(f"{parent.hexsha}:{file_path}")
|
|
382
|
-
except
|
|
393
|
+
except git_module.exc.GitCommandError:
|
|
383
394
|
pass # 文件可能是新增的
|
|
384
395
|
|
|
385
396
|
# 获取变更后内容
|
|
@@ -387,15 +398,16 @@ class ActionYmlFileManager:
|
|
|
387
398
|
try:
|
|
388
399
|
if diff_item.b_blob:
|
|
389
400
|
after_content = repo.git.show(f"{commit.hexsha}:{file_path}")
|
|
390
|
-
except
|
|
401
|
+
except git_module.exc.GitCommandError:
|
|
391
402
|
pass # 文件可能被删除
|
|
392
403
|
|
|
393
404
|
changes[file_path] = (before_content, after_content)
|
|
394
405
|
break
|
|
395
|
-
except git.exc.GitCommandError as e:
|
|
396
|
-
self.printer.print_in_terminal("git_command_error", style="red", error=str(e))
|
|
397
406
|
except Exception as e:
|
|
398
|
-
|
|
407
|
+
if git_module and hasattr(git_module.exc, 'GitCommandError') and isinstance(e, git_module.exc.GitCommandError):
|
|
408
|
+
self.printer.print_in_terminal("git_command_error", style="red", error=str(e))
|
|
409
|
+
else:
|
|
410
|
+
self.printer.print_in_terminal("get_commit_changes_error", style="red", error=str(e))
|
|
399
411
|
|
|
400
412
|
return [(query, urls, changes)]
|
|
401
413
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Agent Events Module
|
|
3
|
+
|
|
4
|
+
A comprehensive event handling system for auto-coder agents with support for
|
|
5
|
+
event emission, subscription, filtering, and processing.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .types import (
|
|
9
|
+
EventType,
|
|
10
|
+
EventMessage,
|
|
11
|
+
EventHandler,
|
|
12
|
+
EventListener,
|
|
13
|
+
EventMetrics,
|
|
14
|
+
EventEmitterConfig,
|
|
15
|
+
EventContext
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
from .event_factory import EventFactory
|
|
19
|
+
from .agent_event_emitter import AgentEventEmitter
|
|
20
|
+
from .utils import (
|
|
21
|
+
create_event_system,
|
|
22
|
+
create_pre_tool_use_event,
|
|
23
|
+
create_post_tool_use_event,
|
|
24
|
+
create_error_occurred_event,
|
|
25
|
+
create_conversation_start_event,
|
|
26
|
+
create_conversation_end_event,
|
|
27
|
+
create_custom_event
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
__all__ = [
|
|
31
|
+
# Types
|
|
32
|
+
'EventType',
|
|
33
|
+
'EventMessage',
|
|
34
|
+
'EventHandler',
|
|
35
|
+
'EventListener',
|
|
36
|
+
'EventMetrics',
|
|
37
|
+
'EventEmitterConfig',
|
|
38
|
+
'EventContext',
|
|
39
|
+
|
|
40
|
+
# Core classes
|
|
41
|
+
'EventFactory',
|
|
42
|
+
'AgentEventEmitter',
|
|
43
|
+
|
|
44
|
+
# Utility functions
|
|
45
|
+
'create_event_system',
|
|
46
|
+
'create_pre_tool_use_event',
|
|
47
|
+
'create_post_tool_use_event',
|
|
48
|
+
'create_error_occurred_event',
|
|
49
|
+
'create_conversation_start_event',
|
|
50
|
+
'create_conversation_end_event',
|
|
51
|
+
'create_custom_event'
|
|
52
|
+
]
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Core event emitter for agent events with support for filtering, metrics, and error handling.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import time
|
|
7
|
+
from collections import defaultdict
|
|
8
|
+
from typing import Dict, List, Optional, Set, Callable
|
|
9
|
+
from loguru import logger
|
|
10
|
+
|
|
11
|
+
from autocoder.common.async_utils import AsyncSyncMixin, run_async_in_sync
|
|
12
|
+
from .types import (
|
|
13
|
+
EventMessage, EventType, EventHandler, EventListener,
|
|
14
|
+
EventMetrics, EventEmitterConfig, EventFilter
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class AgentEventEmitter(AsyncSyncMixin):
|
|
19
|
+
"""
|
|
20
|
+
Core event emitter for agent events.
|
|
21
|
+
|
|
22
|
+
Provides both async and sync methods for all operations.
|
|
23
|
+
Sync methods are automatically generated with a '_sync' suffix.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(self, config: Optional[EventEmitterConfig] = None):
|
|
27
|
+
"""Initialize the event emitter."""
|
|
28
|
+
self.config = config or EventEmitterConfig()
|
|
29
|
+
self._listeners: Dict[EventType, List[EventListener]] = defaultdict(list)
|
|
30
|
+
self._metrics = EventMetrics()
|
|
31
|
+
self._lock = asyncio.Lock()
|
|
32
|
+
|
|
33
|
+
def on(self, event_type: EventType, handler: EventHandler) -> None:
|
|
34
|
+
"""Register an event handler for the specified event type."""
|
|
35
|
+
self.add_listener(event_type, handler)
|
|
36
|
+
|
|
37
|
+
def once(self, event_type: EventType, handler: EventHandler) -> None:
|
|
38
|
+
"""Register a one-time event handler."""
|
|
39
|
+
self.add_listener(event_type, handler, once=True)
|
|
40
|
+
|
|
41
|
+
def off(self, event_type: EventType, handler: EventHandler) -> bool:
|
|
42
|
+
"""Remove an event handler."""
|
|
43
|
+
listeners = self._listeners.get(event_type, [])
|
|
44
|
+
for i, listener in enumerate(listeners):
|
|
45
|
+
if listener.handler == handler:
|
|
46
|
+
del listeners[i]
|
|
47
|
+
self._metrics.total_handlers -= 1
|
|
48
|
+
return True
|
|
49
|
+
return False
|
|
50
|
+
|
|
51
|
+
def add_listener(self, event_type: EventType, handler: EventHandler,
|
|
52
|
+
filter: Optional[EventFilter] = None, once: bool = False) -> None:
|
|
53
|
+
"""Add an event listener with advanced options."""
|
|
54
|
+
if len(self._listeners[event_type]) >= self.config.max_listeners:
|
|
55
|
+
logger.warning(f"Max listeners ({self.config.max_listeners}) reached for {event_type}")
|
|
56
|
+
return
|
|
57
|
+
|
|
58
|
+
listener = EventListener(handler=handler, filter=filter, once=once)
|
|
59
|
+
self._listeners[event_type].append(listener)
|
|
60
|
+
self._metrics.total_handlers += 1
|
|
61
|
+
|
|
62
|
+
if self.config.enable_logging:
|
|
63
|
+
logger.info(f"Added listener for {event_type} (once={once}, filtered={filter is not None})")
|
|
64
|
+
|
|
65
|
+
def remove_listener(self, event_type: EventType, handler: EventHandler) -> bool:
|
|
66
|
+
"""Remove a specific event listener."""
|
|
67
|
+
return self.off(event_type, handler)
|
|
68
|
+
|
|
69
|
+
def remove_all_listeners(self, event_type: Optional[EventType] = None) -> None:
|
|
70
|
+
"""Remove all listeners for a specific event type or all events."""
|
|
71
|
+
if event_type:
|
|
72
|
+
count = len(self._listeners.get(event_type, []))
|
|
73
|
+
self._listeners[event_type] = []
|
|
74
|
+
self._metrics.total_handlers -= count
|
|
75
|
+
else:
|
|
76
|
+
total_removed = sum(len(listeners) for listeners in self._listeners.values())
|
|
77
|
+
self._listeners.clear()
|
|
78
|
+
self._metrics.total_handlers -= total_removed
|
|
79
|
+
|
|
80
|
+
if self.config.enable_logging:
|
|
81
|
+
logger.info(f"Removed all listeners for {event_type or 'all events'}")
|
|
82
|
+
|
|
83
|
+
def listener_count(self, event_type: EventType) -> int:
|
|
84
|
+
"""Get the number of listeners for an event type."""
|
|
85
|
+
return len(self._listeners.get(event_type, []))
|
|
86
|
+
|
|
87
|
+
async def emit(self, event_message: EventMessage) -> None:
|
|
88
|
+
"""Emit an event to all registered handlers."""
|
|
89
|
+
start_time = time.time()
|
|
90
|
+
event_type = event_message.event_type
|
|
91
|
+
|
|
92
|
+
if self.config.enable_logging:
|
|
93
|
+
logger.info(f"Emitting event: {event_type} ({event_message.event_id})")
|
|
94
|
+
|
|
95
|
+
# Get listeners for this event type (copy to avoid modification during iteration)
|
|
96
|
+
listeners = self._listeners.get(event_type, []).copy()
|
|
97
|
+
|
|
98
|
+
# Track listeners to remove (once handlers)
|
|
99
|
+
to_remove = []
|
|
100
|
+
|
|
101
|
+
# Process each listener
|
|
102
|
+
for listener in listeners:
|
|
103
|
+
try:
|
|
104
|
+
# Apply filter if present
|
|
105
|
+
if listener.filter and not listener.filter(event_message):
|
|
106
|
+
continue
|
|
107
|
+
|
|
108
|
+
# Execute handler
|
|
109
|
+
await listener.handler(event_message)
|
|
110
|
+
|
|
111
|
+
# Mark once handlers for removal
|
|
112
|
+
if listener.once:
|
|
113
|
+
to_remove.append((event_type, listener))
|
|
114
|
+
|
|
115
|
+
except Exception as e:
|
|
116
|
+
self._metrics.error_count += 1
|
|
117
|
+
error_msg = f"Error in event handler for {event_type}: {e}"
|
|
118
|
+
logger.error(error_msg)
|
|
119
|
+
|
|
120
|
+
if self.config.error_handler:
|
|
121
|
+
try:
|
|
122
|
+
self.config.error_handler(e, event_type)
|
|
123
|
+
except Exception as handler_error:
|
|
124
|
+
logger.error(f"Error in error handler: {handler_error}")
|
|
125
|
+
|
|
126
|
+
# Remove once handlers
|
|
127
|
+
async with self._lock:
|
|
128
|
+
for event_type_remove, listener_remove in to_remove:
|
|
129
|
+
try:
|
|
130
|
+
self._listeners[event_type_remove].remove(listener_remove)
|
|
131
|
+
self._metrics.total_handlers -= 1
|
|
132
|
+
except ValueError:
|
|
133
|
+
pass # Already removed
|
|
134
|
+
|
|
135
|
+
# Process with hook manager if available
|
|
136
|
+
if self.config.hook_manager:
|
|
137
|
+
try:
|
|
138
|
+
# Hook manager process_event is always async, so we await it
|
|
139
|
+
await self.config.hook_manager.process_event(event_message)
|
|
140
|
+
except Exception as e:
|
|
141
|
+
logger.error(f"Error in hook manager: {e}")
|
|
142
|
+
|
|
143
|
+
# Update metrics
|
|
144
|
+
processing_time = time.time() - start_time
|
|
145
|
+
self._metrics.total_events += 1
|
|
146
|
+
self._metrics.total_processing_time += processing_time
|
|
147
|
+
|
|
148
|
+
# Update handler count metrics
|
|
149
|
+
event_type_str = event_type.value
|
|
150
|
+
self._metrics.handler_counts[event_type_str] = self._metrics.handler_counts.get(event_type_str, 0) + len(listeners)
|
|
151
|
+
|
|
152
|
+
if self.config.enable_logging:
|
|
153
|
+
logger.info(f"Event {event_type} processed in {processing_time:.3f}s")
|
|
154
|
+
|
|
155
|
+
# The emit_sync method is automatically provided by AsyncSyncMixin
|
|
156
|
+
|
|
157
|
+
async def wait_for_event(self, event_type: EventType, timeout: Optional[float] = None,
|
|
158
|
+
filter: Optional[EventFilter] = None) -> Optional[EventMessage]:
|
|
159
|
+
"""Wait for a specific event to be emitted."""
|
|
160
|
+
future = asyncio.Future()
|
|
161
|
+
|
|
162
|
+
async def handler(event_message: EventMessage):
|
|
163
|
+
if not future.done():
|
|
164
|
+
future.set_result(event_message)
|
|
165
|
+
|
|
166
|
+
# Add temporary listener
|
|
167
|
+
self.add_listener(event_type, handler, filter=filter, once=True)
|
|
168
|
+
|
|
169
|
+
try:
|
|
170
|
+
if timeout:
|
|
171
|
+
return await asyncio.wait_for(future, timeout=timeout)
|
|
172
|
+
else:
|
|
173
|
+
return await future
|
|
174
|
+
except asyncio.TimeoutError:
|
|
175
|
+
# Remove the listener if timeout occurs
|
|
176
|
+
self.off(event_type, handler)
|
|
177
|
+
return None
|
|
178
|
+
|
|
179
|
+
def get_metrics(self) -> EventMetrics:
|
|
180
|
+
"""Get event processing metrics."""
|
|
181
|
+
return self._metrics
|
|
182
|
+
|
|
183
|
+
def reset_metrics(self) -> None:
|
|
184
|
+
"""Reset event processing metrics."""
|
|
185
|
+
self._metrics = EventMetrics()
|
|
186
|
+
|
|
187
|
+
def list_event_types(self) -> List[EventType]:
|
|
188
|
+
"""Get all event types that have listeners."""
|
|
189
|
+
return list(self._listeners.keys())
|
|
190
|
+
|
|
191
|
+
def get_listeners(self, event_type: EventType) -> List[EventListener]:
|
|
192
|
+
"""Get all listeners for a specific event type."""
|
|
193
|
+
return self._listeners.get(event_type, []).copy()
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Event Factory for creating typed events with proper context management.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import time
|
|
6
|
+
from typing import Dict, Any, Optional
|
|
7
|
+
from .types import EventMessage, EventType, EventContext
|
|
8
|
+
|
|
9
|
+
class EventFactory:
|
|
10
|
+
"""Factory for creating typed events with context management."""
|
|
11
|
+
|
|
12
|
+
def __init__(self, default_context: Optional[EventContext] = None):
|
|
13
|
+
"""Initialize factory with optional default context."""
|
|
14
|
+
self.default_context = default_context
|
|
15
|
+
|
|
16
|
+
@classmethod
|
|
17
|
+
def create_with_context(cls, context: EventContext) -> 'EventFactory':
|
|
18
|
+
"""Create a factory with default context."""
|
|
19
|
+
return cls(default_context=context)
|
|
20
|
+
|
|
21
|
+
def set_default_context(self, context: EventContext) -> None:
|
|
22
|
+
"""Set default context for all events created by this factory."""
|
|
23
|
+
self.default_context = context
|
|
24
|
+
|
|
25
|
+
def _create_event(self, event_type: EventType, content: Dict[str, Any],
|
|
26
|
+
context: Optional[EventContext] = None) -> EventMessage:
|
|
27
|
+
"""Create an event with proper context inheritance."""
|
|
28
|
+
# Merge contexts - specific context overrides default
|
|
29
|
+
final_context = self.default_context
|
|
30
|
+
if context:
|
|
31
|
+
if final_context:
|
|
32
|
+
# Merge contexts
|
|
33
|
+
final_context = EventContext(
|
|
34
|
+
agent_id=context.agent_id or final_context.agent_id,
|
|
35
|
+
conversation_id=context.conversation_id or final_context.conversation_id,
|
|
36
|
+
metadata={**(final_context.metadata or {}), **(context.metadata or {})}
|
|
37
|
+
)
|
|
38
|
+
else:
|
|
39
|
+
final_context = context
|
|
40
|
+
|
|
41
|
+
return EventMessage(
|
|
42
|
+
event_type=event_type,
|
|
43
|
+
content=content,
|
|
44
|
+
context=final_context
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
def create_pre_tool_use_event(self, tool_name: str, tool_input: Dict[str, Any],
|
|
48
|
+
context: Optional[EventContext] = None) -> EventMessage:
|
|
49
|
+
"""Create a PreToolUse event."""
|
|
50
|
+
content = {
|
|
51
|
+
'tool_name': tool_name,
|
|
52
|
+
'tool_input': tool_input,
|
|
53
|
+
'timestamp': time.time()
|
|
54
|
+
}
|
|
55
|
+
return self._create_event(EventType.PRE_TOOL_USE, content, context)
|
|
56
|
+
|
|
57
|
+
def create_post_tool_use_event(self, tool_name: str, tool_input: Dict[str, Any],
|
|
58
|
+
tool_output: Any, success: bool,
|
|
59
|
+
execution_time_ms: Optional[float] = None,
|
|
60
|
+
context: Optional[EventContext] = None) -> EventMessage:
|
|
61
|
+
"""Create a PostToolUse event."""
|
|
62
|
+
content = {
|
|
63
|
+
'tool_name': tool_name,
|
|
64
|
+
'tool_input': tool_input,
|
|
65
|
+
'tool_output': tool_output,
|
|
66
|
+
'success': success,
|
|
67
|
+
'timestamp': time.time()
|
|
68
|
+
}
|
|
69
|
+
if execution_time_ms is not None:
|
|
70
|
+
content['execution_time_ms'] = execution_time_ms
|
|
71
|
+
|
|
72
|
+
return self._create_event(EventType.POST_TOOL_USE, content, context)
|
|
73
|
+
|
|
74
|
+
def create_error_occurred_event(self, error_type: str, error_message: str,
|
|
75
|
+
tool_name: Optional[str] = None,
|
|
76
|
+
stack_trace: Optional[str] = None,
|
|
77
|
+
context: Optional[EventContext] = None) -> EventMessage:
|
|
78
|
+
"""Create an ErrorOccurred event."""
|
|
79
|
+
content = {
|
|
80
|
+
'error_type': error_type,
|
|
81
|
+
'error_message': error_message,
|
|
82
|
+
'timestamp': time.time()
|
|
83
|
+
}
|
|
84
|
+
if tool_name:
|
|
85
|
+
content['tool_name'] = tool_name
|
|
86
|
+
if stack_trace:
|
|
87
|
+
content['stack_trace'] = stack_trace
|
|
88
|
+
|
|
89
|
+
return self._create_event(EventType.ERROR_OCCURRED, content, context)
|
|
90
|
+
|
|
91
|
+
def create_conversation_start_event(self, message_count: int = 0,
|
|
92
|
+
conversation_id: Optional[str] = None,
|
|
93
|
+
context: Optional[EventContext] = None) -> EventMessage:
|
|
94
|
+
"""Create a ConversationStart event."""
|
|
95
|
+
content = {
|
|
96
|
+
'message_count': message_count,
|
|
97
|
+
'timestamp': time.time()
|
|
98
|
+
}
|
|
99
|
+
if conversation_id:
|
|
100
|
+
content['conversation_id'] = conversation_id
|
|
101
|
+
|
|
102
|
+
return self._create_event(EventType.CONVERSATION_START, content, context)
|
|
103
|
+
|
|
104
|
+
def create_conversation_end_event(self, did_complete_task: bool,
|
|
105
|
+
iteration_count: int = 0,
|
|
106
|
+
conversation_id: Optional[str] = None,
|
|
107
|
+
context: Optional[EventContext] = None) -> EventMessage:
|
|
108
|
+
"""Create a ConversationEnd event."""
|
|
109
|
+
content = {
|
|
110
|
+
'did_complete_task': did_complete_task,
|
|
111
|
+
'iteration_count': iteration_count,
|
|
112
|
+
'timestamp': time.time()
|
|
113
|
+
}
|
|
114
|
+
if conversation_id:
|
|
115
|
+
content['conversation_id'] = conversation_id
|
|
116
|
+
|
|
117
|
+
return self._create_event(EventType.CONVERSATION_END, content, context)
|
|
118
|
+
|
|
119
|
+
def create_tool_execution_event(self, tool_name: str, progress: float = 0.0,
|
|
120
|
+
status: str = "running",
|
|
121
|
+
context: Optional[EventContext] = None) -> EventMessage:
|
|
122
|
+
"""Create a ToolExecution event."""
|
|
123
|
+
content = {
|
|
124
|
+
'tool_name': tool_name,
|
|
125
|
+
'progress': progress,
|
|
126
|
+
'status': status,
|
|
127
|
+
'timestamp': time.time()
|
|
128
|
+
}
|
|
129
|
+
return self._create_event(EventType.TOOL_EXECUTION, content, context)
|
|
130
|
+
|
|
131
|
+
def create_tool_request_approval_event(self, tool_name: str,
|
|
132
|
+
tool_input: Dict[str, Any],
|
|
133
|
+
reason: str = "",
|
|
134
|
+
context: Optional[EventContext] = None) -> EventMessage:
|
|
135
|
+
"""Create a ToolRequestApproval event."""
|
|
136
|
+
content = {
|
|
137
|
+
'tool_name': tool_name,
|
|
138
|
+
'tool_input': tool_input,
|
|
139
|
+
'reason': reason,
|
|
140
|
+
'timestamp': time.time()
|
|
141
|
+
}
|
|
142
|
+
return self._create_event(EventType.TOOL_REQUEST_APPROVAL, content, context)
|
|
143
|
+
|
|
144
|
+
def create_mode_change_event(self, old_mode: str, new_mode: str,
|
|
145
|
+
context: Optional[EventContext] = None) -> EventMessage:
|
|
146
|
+
"""Create a ModeChange event."""
|
|
147
|
+
content = {
|
|
148
|
+
'old_mode': old_mode,
|
|
149
|
+
'new_mode': new_mode,
|
|
150
|
+
'timestamp': time.time()
|
|
151
|
+
}
|
|
152
|
+
return self._create_event(EventType.MODE_CHANGE, content, context)
|
|
153
|
+
|
|
154
|
+
def create_token_count_info_event(self, input_tokens: int, output_tokens: int,
|
|
155
|
+
total_tokens: int, model: Optional[str] = None,
|
|
156
|
+
context: Optional[EventContext] = None) -> EventMessage:
|
|
157
|
+
"""Create a TokenCountInfo event."""
|
|
158
|
+
content = {
|
|
159
|
+
'input_tokens': input_tokens,
|
|
160
|
+
'output_tokens': output_tokens,
|
|
161
|
+
'total_tokens': total_tokens,
|
|
162
|
+
'timestamp': time.time()
|
|
163
|
+
}
|
|
164
|
+
if model:
|
|
165
|
+
content['model'] = model
|
|
166
|
+
|
|
167
|
+
return self._create_event(EventType.TOKEN_COUNT_INFO, content, context)
|
|
168
|
+
|
|
169
|
+
def create_custom_event(self, event_name: str, data: Dict[str, Any],
|
|
170
|
+
context: Optional[EventContext] = None) -> EventMessage:
|
|
171
|
+
"""Create a custom event."""
|
|
172
|
+
content = {
|
|
173
|
+
'event_name': event_name,
|
|
174
|
+
'data': data,
|
|
175
|
+
'timestamp': time.time()
|
|
176
|
+
}
|
|
177
|
+
return self._create_event(EventType.CUSTOM_EVENT, content, context)
|