auto-coder 1.0.0__py3-none-any.whl → 2.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of auto-coder might be problematic. Click here for more details.

Files changed (574) hide show
  1. auto_coder-2.0.1.dist-info/LICENSE +158 -0
  2. auto_coder-2.0.1.dist-info/METADATA +558 -0
  3. auto_coder-2.0.1.dist-info/RECORD +795 -0
  4. {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.dist-info}/WHEEL +1 -1
  5. {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.dist-info}/entry_points.txt +3 -3
  6. autocoder/__init__.py +31 -0
  7. autocoder/agent/auto_filegroup.py +32 -13
  8. autocoder/agent/auto_learn_from_commit.py +9 -1
  9. autocoder/agent/base_agentic/__init__.py +3 -0
  10. autocoder/agent/base_agentic/agent_hub.py +1 -1
  11. autocoder/agent/base_agentic/base_agent.py +235 -136
  12. autocoder/agent/base_agentic/default_tools.py +119 -118
  13. autocoder/agent/base_agentic/test_base_agent.py +1 -1
  14. autocoder/agent/base_agentic/tool_registry.py +32 -20
  15. autocoder/agent/base_agentic/tools/read_file_tool_resolver.py +24 -3
  16. autocoder/agent/base_agentic/tools/write_to_file_tool_resolver.py +24 -11
  17. autocoder/agent/base_agentic/types.py +42 -0
  18. autocoder/agent/entry_command_agent/chat.py +77 -73
  19. autocoder/auto_coder.py +31 -40
  20. autocoder/auto_coder_rag.py +11 -1084
  21. autocoder/auto_coder_runner.py +962 -2345
  22. autocoder/auto_coder_terminal.py +26 -0
  23. autocoder/auto_coder_terminal_v3.py +190 -0
  24. autocoder/chat/conf_command.py +224 -124
  25. autocoder/chat/models_command.py +361 -299
  26. autocoder/chat/rules_command.py +79 -31
  27. autocoder/chat_auto_coder.py +988 -398
  28. autocoder/chat_auto_coder_lang.py +23 -732
  29. autocoder/commands/auto_command.py +25 -8
  30. autocoder/commands/auto_web.py +1 -1
  31. autocoder/commands/tools.py +44 -44
  32. autocoder/common/__init__.py +150 -128
  33. autocoder/common/ac_style_command_parser/__init__.py +39 -2
  34. autocoder/common/ac_style_command_parser/config.py +422 -0
  35. autocoder/common/ac_style_command_parser/parser.py +292 -78
  36. autocoder/common/ac_style_command_parser/test_parser.py +241 -16
  37. autocoder/common/ac_style_command_parser/test_typed_parser.py +342 -0
  38. autocoder/common/ac_style_command_parser/typed_parser.py +653 -0
  39. autocoder/common/action_yml_file_manager.py +25 -13
  40. autocoder/common/agent_events/__init__.py +52 -0
  41. autocoder/common/agent_events/agent_event_emitter.py +193 -0
  42. autocoder/common/agent_events/event_factory.py +177 -0
  43. autocoder/common/agent_events/examples.py +307 -0
  44. autocoder/common/agent_events/types.py +113 -0
  45. autocoder/common/agent_events/utils.py +68 -0
  46. autocoder/common/agent_hooks/__init__.py +44 -0
  47. autocoder/common/agent_hooks/examples.py +582 -0
  48. autocoder/common/agent_hooks/hook_executor.py +217 -0
  49. autocoder/common/agent_hooks/hook_manager.py +288 -0
  50. autocoder/common/agent_hooks/types.py +133 -0
  51. autocoder/common/agent_hooks/utils.py +99 -0
  52. autocoder/common/agent_query_queue/queue_executor.py +324 -0
  53. autocoder/common/agent_query_queue/queue_manager.py +325 -0
  54. autocoder/common/agents/__init__.py +11 -0
  55. autocoder/common/agents/agent_manager.py +323 -0
  56. autocoder/common/agents/agent_parser.py +189 -0
  57. autocoder/common/agents/example_usage.py +344 -0
  58. autocoder/common/agents/integration_example.py +330 -0
  59. autocoder/common/agents/test_agent_parser.py +545 -0
  60. autocoder/common/async_utils.py +101 -0
  61. autocoder/common/auto_coder_lang.py +23 -972
  62. autocoder/common/autocoderargs_parser/__init__.py +14 -0
  63. autocoder/common/autocoderargs_parser/parser.py +184 -0
  64. autocoder/common/autocoderargs_parser/tests/__init__.py +1 -0
  65. autocoder/common/autocoderargs_parser/tests/test_args_parser.py +235 -0
  66. autocoder/common/autocoderargs_parser/tests/test_token_parser.py +195 -0
  67. autocoder/common/autocoderargs_parser/token_parser.py +290 -0
  68. autocoder/common/buildin_tokenizer.py +2 -4
  69. autocoder/common/code_auto_generate.py +149 -74
  70. autocoder/common/code_auto_generate_diff.py +163 -70
  71. autocoder/common/code_auto_generate_editblock.py +179 -89
  72. autocoder/common/code_auto_generate_strict_diff.py +167 -72
  73. autocoder/common/code_auto_merge_editblock.py +13 -6
  74. autocoder/common/code_modification_ranker.py +1 -1
  75. autocoder/common/command_completer.py +3 -3
  76. autocoder/common/command_file_manager/manager.py +183 -47
  77. autocoder/common/command_file_manager/test_command_file_manager.py +507 -0
  78. autocoder/common/command_templates.py +1 -1
  79. autocoder/common/conf_utils.py +2 -4
  80. autocoder/common/conversations/config.py +11 -3
  81. autocoder/common/conversations/get_conversation_manager.py +100 -2
  82. autocoder/common/conversations/llm_stats_models.py +264 -0
  83. autocoder/common/conversations/manager.py +112 -28
  84. autocoder/common/conversations/models.py +16 -2
  85. autocoder/common/conversations/storage/index_manager.py +134 -10
  86. autocoder/common/core_config/__init__.py +63 -0
  87. autocoder/common/core_config/agentic_mode_manager.py +109 -0
  88. autocoder/common/core_config/base_manager.py +123 -0
  89. autocoder/common/core_config/compatibility.py +151 -0
  90. autocoder/common/core_config/config_manager.py +156 -0
  91. autocoder/common/core_config/conversation_manager.py +31 -0
  92. autocoder/common/core_config/exclude_manager.py +72 -0
  93. autocoder/common/core_config/file_manager.py +177 -0
  94. autocoder/common/core_config/human_as_model_manager.py +129 -0
  95. autocoder/common/core_config/lib_manager.py +54 -0
  96. autocoder/common/core_config/main_manager.py +81 -0
  97. autocoder/common/core_config/mode_manager.py +126 -0
  98. autocoder/common/core_config/models.py +70 -0
  99. autocoder/common/core_config/test_memory_manager.py +1056 -0
  100. autocoder/common/env_manager.py +282 -0
  101. autocoder/common/env_manager_usage_example.py +211 -0
  102. autocoder/common/file_checkpoint/conversation_checkpoint.py +19 -19
  103. autocoder/common/file_checkpoint/manager.py +264 -48
  104. autocoder/common/file_checkpoint/test_backup.py +1 -18
  105. autocoder/common/file_checkpoint/test_manager.py +270 -1
  106. autocoder/common/file_checkpoint/test_store.py +1 -17
  107. autocoder/common/file_handler/__init__.py +23 -0
  108. autocoder/common/file_handler/active_context_handler.py +159 -0
  109. autocoder/common/file_handler/add_files_handler.py +409 -0
  110. autocoder/common/file_handler/chat_handler.py +180 -0
  111. autocoder/common/file_handler/coding_handler.py +409 -0
  112. autocoder/common/file_handler/commit_handler.py +200 -0
  113. autocoder/common/file_handler/lib_handler.py +156 -0
  114. autocoder/common/file_handler/list_files_handler.py +111 -0
  115. autocoder/common/file_handler/mcp_handler.py +268 -0
  116. autocoder/common/file_handler/models_handler.py +493 -0
  117. autocoder/common/file_handler/remove_files_handler.py +172 -0
  118. autocoder/common/git_utils.py +44 -8
  119. autocoder/common/global_cancel.py +15 -6
  120. autocoder/common/ignorefiles/test_ignore_file_utils.py +1 -1
  121. autocoder/common/international/__init__.py +31 -0
  122. autocoder/common/international/demo_international.py +92 -0
  123. autocoder/common/international/message_manager.py +157 -0
  124. autocoder/common/international/messages/__init__.py +56 -0
  125. autocoder/common/international/messages/async_command_messages.py +507 -0
  126. autocoder/common/international/messages/auto_coder_messages.py +2208 -0
  127. autocoder/common/international/messages/chat_auto_coder_messages.py +1547 -0
  128. autocoder/common/international/messages/command_help_messages.py +986 -0
  129. autocoder/common/international/messages/conversation_command_messages.py +191 -0
  130. autocoder/common/international/messages/git_helper_plugin_messages.py +159 -0
  131. autocoder/common/international/messages/queue_command_messages.py +751 -0
  132. autocoder/common/international/messages/rules_command_messages.py +77 -0
  133. autocoder/common/international/messages/sdk_messages.py +1707 -0
  134. autocoder/common/international/messages/token_helper_plugin_messages.py +361 -0
  135. autocoder/common/international/messages/tool_display_messages.py +1212 -0
  136. autocoder/common/international/messages/workflow_exception_messages.py +473 -0
  137. autocoder/common/international/test_international.py +612 -0
  138. autocoder/common/linter_core/__init__.py +28 -0
  139. autocoder/common/linter_core/base_linter.py +61 -0
  140. autocoder/common/linter_core/config_loader.py +271 -0
  141. autocoder/common/linter_core/formatters/__init__.py +0 -0
  142. autocoder/common/linter_core/formatters/base_formatter.py +38 -0
  143. autocoder/common/linter_core/formatters/raw_formatter.py +17 -0
  144. autocoder/common/linter_core/linter.py +166 -0
  145. autocoder/common/linter_core/linter_factory.py +216 -0
  146. autocoder/common/linter_core/linter_manager.py +333 -0
  147. autocoder/common/linter_core/linters/__init__.py +9 -0
  148. autocoder/common/linter_core/linters/java_linter.py +342 -0
  149. autocoder/common/linter_core/linters/python_linter.py +115 -0
  150. autocoder/common/linter_core/linters/typescript_linter.py +119 -0
  151. autocoder/common/linter_core/models/__init__.py +7 -0
  152. autocoder/common/linter_core/models/lint_result.py +91 -0
  153. autocoder/common/linter_core/models.py +33 -0
  154. autocoder/common/linter_core/tests/__init__.py +3 -0
  155. autocoder/common/linter_core/tests/test_config_loader.py +323 -0
  156. autocoder/common/linter_core/tests/test_config_loading.py +308 -0
  157. autocoder/common/linter_core/tests/test_factory_manager.py +234 -0
  158. autocoder/common/linter_core/tests/test_formatters.py +147 -0
  159. autocoder/common/linter_core/tests/test_integration.py +317 -0
  160. autocoder/common/linter_core/tests/test_java_linter.py +496 -0
  161. autocoder/common/linter_core/tests/test_linters.py +265 -0
  162. autocoder/common/linter_core/tests/test_models.py +81 -0
  163. autocoder/common/linter_core/tests/verify_config_loading.py +296 -0
  164. autocoder/common/linter_core/tests/verify_fixes.py +183 -0
  165. autocoder/common/llm_friendly_package/__init__.py +31 -0
  166. autocoder/common/llm_friendly_package/base_manager.py +102 -0
  167. autocoder/common/llm_friendly_package/docs_manager.py +121 -0
  168. autocoder/common/llm_friendly_package/library_manager.py +171 -0
  169. autocoder/common/{llm_friendly_package.py → llm_friendly_package/main_manager.py} +204 -231
  170. autocoder/common/llm_friendly_package/models.py +40 -0
  171. autocoder/common/llm_friendly_package/test_llm_friendly_package.py +536 -0
  172. autocoder/common/llms/__init__.py +15 -0
  173. autocoder/common/llms/demo_error_handling.py +85 -0
  174. autocoder/common/llms/factory.py +142 -0
  175. autocoder/common/llms/manager.py +264 -0
  176. autocoder/common/llms/pricing.py +121 -0
  177. autocoder/common/llms/registry.py +316 -0
  178. autocoder/common/llms/schema.py +77 -0
  179. autocoder/common/llms/simple_demo.py +45 -0
  180. autocoder/common/llms/test_quick_model.py +116 -0
  181. autocoder/common/llms/test_remove_functionality.py +182 -0
  182. autocoder/common/llms/tests/__init__.py +1 -0
  183. autocoder/common/llms/tests/test_manager.py +330 -0
  184. autocoder/common/llms/tests/test_registry.py +364 -0
  185. autocoder/common/mcp_tools/__init__.py +62 -0
  186. autocoder/common/{mcp_tools.py → mcp_tools/executor.py} +49 -40
  187. autocoder/common/{mcp_hub.py → mcp_tools/hub.py} +42 -68
  188. autocoder/common/{mcp_server_install.py → mcp_tools/installer.py} +16 -28
  189. autocoder/common/{mcp_server.py → mcp_tools/server.py} +176 -48
  190. autocoder/common/mcp_tools/test_keyboard_interrupt.py +93 -0
  191. autocoder/common/mcp_tools/test_mcp_tools.py +391 -0
  192. autocoder/common/{mcp_server_types.py → mcp_tools/types.py} +121 -48
  193. autocoder/common/mcp_tools/verify_functionality.py +202 -0
  194. autocoder/common/model_speed_tester.py +32 -26
  195. autocoder/common/priority_directory_finder/__init__.py +142 -0
  196. autocoder/common/priority_directory_finder/examples.py +230 -0
  197. autocoder/common/priority_directory_finder/finder.py +283 -0
  198. autocoder/common/priority_directory_finder/models.py +236 -0
  199. autocoder/common/priority_directory_finder/test_priority_directory_finder.py +431 -0
  200. autocoder/common/project_scanner/__init__.py +18 -0
  201. autocoder/common/project_scanner/compat.py +77 -0
  202. autocoder/common/project_scanner/scanner.py +436 -0
  203. autocoder/common/project_tracker/__init__.py +27 -0
  204. autocoder/common/project_tracker/api.py +228 -0
  205. autocoder/common/project_tracker/demo.py +272 -0
  206. autocoder/common/project_tracker/tracker.py +487 -0
  207. autocoder/common/project_tracker/types.py +53 -0
  208. autocoder/common/pruner/__init__.py +67 -0
  209. autocoder/common/pruner/agentic_conversation_pruner.py +651 -102
  210. autocoder/common/pruner/conversation_message_ids_api.py +386 -0
  211. autocoder/common/pruner/conversation_message_ids_manager.py +347 -0
  212. autocoder/common/pruner/conversation_message_ids_pruner.py +473 -0
  213. autocoder/common/pruner/conversation_normalizer.py +347 -0
  214. autocoder/common/pruner/conversation_pruner.py +26 -6
  215. autocoder/common/pruner/test_agentic_conversation_pruner.py +554 -112
  216. autocoder/common/pruner/test_conversation_normalizer.py +502 -0
  217. autocoder/common/pruner/test_tool_content_detector.py +324 -0
  218. autocoder/common/pruner/tool_content_detector.py +227 -0
  219. autocoder/common/pruner/tools/__init__.py +18 -0
  220. autocoder/common/pruner/tools/query_message_ids.py +264 -0
  221. autocoder/common/pruner/tools/test_agentic_pruning_logic.py +432 -0
  222. autocoder/common/pruner/tools/test_message_ids_pruning_only.py +192 -0
  223. autocoder/common/pull_requests/__init__.py +9 -1
  224. autocoder/common/pull_requests/utils.py +122 -1
  225. autocoder/common/rag_manager/rag_manager.py +36 -40
  226. autocoder/common/rulefiles/__init__.py +53 -1
  227. autocoder/common/rulefiles/api.py +250 -0
  228. autocoder/common/rulefiles/core/__init__.py +14 -0
  229. autocoder/common/rulefiles/core/manager.py +241 -0
  230. autocoder/common/rulefiles/core/selector.py +805 -0
  231. autocoder/common/rulefiles/models/__init__.py +20 -0
  232. autocoder/common/rulefiles/models/index.py +16 -0
  233. autocoder/common/rulefiles/models/init_rule.py +18 -0
  234. autocoder/common/rulefiles/models/rule_file.py +18 -0
  235. autocoder/common/rulefiles/models/rule_relevance.py +14 -0
  236. autocoder/common/rulefiles/models/summary.py +16 -0
  237. autocoder/common/rulefiles/test_rulefiles.py +776 -0
  238. autocoder/common/rulefiles/utils/__init__.py +34 -0
  239. autocoder/common/rulefiles/utils/monitor.py +86 -0
  240. autocoder/common/rulefiles/utils/parser.py +230 -0
  241. autocoder/common/save_formatted_log.py +67 -10
  242. autocoder/common/search_replace.py +8 -1
  243. autocoder/common/search_replace_patch/__init__.py +24 -0
  244. autocoder/common/search_replace_patch/base.py +115 -0
  245. autocoder/common/search_replace_patch/manager.py +248 -0
  246. autocoder/common/search_replace_patch/patch_replacer.py +304 -0
  247. autocoder/common/search_replace_patch/similarity_replacer.py +306 -0
  248. autocoder/common/search_replace_patch/string_replacer.py +181 -0
  249. autocoder/common/search_replace_patch/tests/__init__.py +3 -0
  250. autocoder/common/search_replace_patch/tests/run_tests.py +126 -0
  251. autocoder/common/search_replace_patch/tests/test_base.py +188 -0
  252. autocoder/common/search_replace_patch/tests/test_empty_line_insert.py +233 -0
  253. autocoder/common/search_replace_patch/tests/test_integration.py +389 -0
  254. autocoder/common/search_replace_patch/tests/test_manager.py +351 -0
  255. autocoder/common/search_replace_patch/tests/test_patch_replacer.py +316 -0
  256. autocoder/common/search_replace_patch/tests/test_regex_replacer.py +306 -0
  257. autocoder/common/search_replace_patch/tests/test_similarity_replacer.py +384 -0
  258. autocoder/common/shell_commands/__init__.py +197 -0
  259. autocoder/common/shell_commands/background_process_notifier.py +346 -0
  260. autocoder/common/shell_commands/command_executor.py +1127 -0
  261. autocoder/common/shell_commands/error_recovery.py +541 -0
  262. autocoder/common/shell_commands/exceptions.py +120 -0
  263. autocoder/common/shell_commands/interactive_executor.py +476 -0
  264. autocoder/common/shell_commands/interactive_pexpect_process.py +623 -0
  265. autocoder/common/shell_commands/interactive_process.py +744 -0
  266. autocoder/common/shell_commands/interactive_session_manager.py +1014 -0
  267. autocoder/common/shell_commands/monitoring.py +529 -0
  268. autocoder/common/shell_commands/process_cleanup.py +386 -0
  269. autocoder/common/shell_commands/process_manager.py +606 -0
  270. autocoder/common/shell_commands/test_interactive_pexpect_process.py +281 -0
  271. autocoder/common/shell_commands/tests/__init__.py +6 -0
  272. autocoder/common/shell_commands/tests/conftest.py +118 -0
  273. autocoder/common/shell_commands/tests/test_background_process_notifier.py +703 -0
  274. autocoder/common/shell_commands/tests/test_command_executor.py +448 -0
  275. autocoder/common/shell_commands/tests/test_error_recovery.py +305 -0
  276. autocoder/common/shell_commands/tests/test_exceptions.py +299 -0
  277. autocoder/common/shell_commands/tests/test_execute_batch.py +588 -0
  278. autocoder/common/shell_commands/tests/test_indented_batch_commands.py +244 -0
  279. autocoder/common/shell_commands/tests/test_integration.py +664 -0
  280. autocoder/common/shell_commands/tests/test_monitoring.py +546 -0
  281. autocoder/common/shell_commands/tests/test_performance.py +632 -0
  282. autocoder/common/shell_commands/tests/test_process_cleanup.py +397 -0
  283. autocoder/common/shell_commands/tests/test_process_manager.py +606 -0
  284. autocoder/common/shell_commands/tests/test_timeout_config.py +343 -0
  285. autocoder/common/shell_commands/tests/test_timeout_manager.py +520 -0
  286. autocoder/common/shell_commands/timeout_config.py +315 -0
  287. autocoder/common/shell_commands/timeout_manager.py +352 -0
  288. autocoder/common/terminal_paste/__init__.py +14 -0
  289. autocoder/common/terminal_paste/demo.py +145 -0
  290. autocoder/common/terminal_paste/demo_paste_functionality.py +95 -0
  291. autocoder/common/terminal_paste/paste_handler.py +200 -0
  292. autocoder/common/terminal_paste/paste_manager.py +118 -0
  293. autocoder/common/terminal_paste/tests/__init__.py +1 -0
  294. autocoder/common/terminal_paste/tests/test_paste_handler.py +182 -0
  295. autocoder/common/terminal_paste/tests/test_paste_manager.py +126 -0
  296. autocoder/common/terminal_paste/utils.py +163 -0
  297. autocoder/common/test_autocoder_args.py +232 -0
  298. autocoder/common/test_env_manager.py +173 -0
  299. autocoder/common/test_env_manager_integration.py +159 -0
  300. autocoder/common/text_similarity/__init__.py +9 -0
  301. autocoder/common/text_similarity/demo.py +216 -0
  302. autocoder/common/text_similarity/examples.py +266 -0
  303. autocoder/common/text_similarity/test_text_similarity.py +306 -0
  304. autocoder/common/text_similarity/text_similarity.py +194 -0
  305. autocoder/common/text_similarity/utils.py +125 -0
  306. autocoder/common/todos/__init__.py +61 -0
  307. autocoder/common/todos/cache/__init__.py +16 -0
  308. autocoder/common/todos/cache/base_cache.py +89 -0
  309. autocoder/common/todos/cache/cache_manager.py +228 -0
  310. autocoder/common/todos/cache/memory_cache.py +225 -0
  311. autocoder/common/todos/config.py +155 -0
  312. autocoder/common/todos/exceptions.py +35 -0
  313. autocoder/common/todos/get_todo_manager.py +161 -0
  314. autocoder/common/todos/manager.py +537 -0
  315. autocoder/common/todos/models.py +239 -0
  316. autocoder/common/todos/storage/__init__.py +14 -0
  317. autocoder/common/todos/storage/base_storage.py +76 -0
  318. autocoder/common/todos/storage/file_storage.py +278 -0
  319. autocoder/common/tokens/counter.py +24 -2
  320. autocoder/common/tools_manager/__init__.py +17 -0
  321. autocoder/common/tools_manager/examples.py +162 -0
  322. autocoder/common/tools_manager/manager.py +385 -0
  323. autocoder/common/tools_manager/models.py +39 -0
  324. autocoder/common/tools_manager/test_tools_manager.py +303 -0
  325. autocoder/common/tools_manager/utils.py +191 -0
  326. autocoder/common/v2/agent/agentic_callbacks.py +270 -0
  327. autocoder/common/v2/agent/agentic_edit.py +2699 -1856
  328. autocoder/common/v2/agent/agentic_edit_change_manager.py +474 -0
  329. autocoder/common/v2/agent/agentic_edit_tools/__init__.py +35 -1
  330. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_list_tool_resolver.py +279 -0
  331. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +10 -1
  332. autocoder/common/v2/agent/agentic_edit_tools/background_task_tool_resolver.py +1167 -0
  333. autocoder/common/v2/agent/agentic_edit_tools/base_tool_resolver.py +2 -2
  334. autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_read_tool_resolver.py +214 -0
  335. autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_write_tool_resolver.py +299 -0
  336. autocoder/common/v2/agent/agentic_edit_tools/count_tokens_tool_resolver.py +290 -0
  337. autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +564 -29
  338. autocoder/common/v2/agent/agentic_edit_tools/execute_workflow_tool_resolver.py +485 -0
  339. autocoder/common/v2/agent/agentic_edit_tools/extract_to_text_tool_resolver.py +225 -0
  340. autocoder/common/v2/agent/agentic_edit_tools/lint_report.py +79 -0
  341. autocoder/common/v2/agent/agentic_edit_tools/linter_config_models.py +343 -0
  342. autocoder/common/v2/agent/agentic_edit_tools/linter_enabled_tool_resolver.py +189 -0
  343. autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py +169 -101
  344. autocoder/common/v2/agent/agentic_edit_tools/load_extra_document_tool_resolver.py +356 -0
  345. autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +243 -50
  346. autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py +667 -147
  347. autocoder/common/v2/agent/agentic_edit_tools/run_named_subagents_tool_resolver.py +691 -0
  348. autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +410 -86
  349. autocoder/common/v2/agent/agentic_edit_tools/session_interactive_tool_resolver.py +115 -0
  350. autocoder/common/v2/agent/agentic_edit_tools/session_start_tool_resolver.py +190 -0
  351. autocoder/common/v2/agent/agentic_edit_tools/session_stop_tool_resolver.py +76 -0
  352. autocoder/common/v2/agent/agentic_edit_tools/test_write_to_file_tool_resolver.py +207 -192
  353. autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +80 -63
  354. autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +237 -233
  355. autocoder/common/v2/agent/agentic_edit_tools/use_mcp_tool_resolver.py +2 -2
  356. autocoder/common/v2/agent/agentic_edit_tools/web_crawl_tool_resolver.py +557 -0
  357. autocoder/common/v2/agent/agentic_edit_tools/web_search_tool_resolver.py +600 -0
  358. autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py +56 -121
  359. autocoder/common/v2/agent/agentic_edit_types.py +343 -9
  360. autocoder/common/v2/agent/runner/__init__.py +3 -3
  361. autocoder/common/v2/agent/runner/base_runner.py +12 -26
  362. autocoder/common/v2/agent/runner/{event_runner.py → file_based_event_runner.py} +3 -2
  363. autocoder/common/v2/agent/runner/sdk_runner.py +150 -8
  364. autocoder/common/v2/agent/runner/terminal_runner.py +170 -57
  365. autocoder/common/v2/agent/runner/tool_display.py +557 -159
  366. autocoder/common/v2/agent/test_agentic_callbacks.py +265 -0
  367. autocoder/common/v2/agent/test_agentic_edit.py +194 -0
  368. autocoder/common/v2/agent/tool_caller/__init__.py +24 -0
  369. autocoder/common/v2/agent/tool_caller/default_tool_resolver_map.py +135 -0
  370. autocoder/common/v2/agent/tool_caller/integration_test.py +172 -0
  371. autocoder/common/v2/agent/tool_caller/plugins/__init__.py +14 -0
  372. autocoder/common/v2/agent/tool_caller/plugins/base_plugin.py +126 -0
  373. autocoder/common/v2/agent/tool_caller/plugins/examples/__init__.py +13 -0
  374. autocoder/common/v2/agent/tool_caller/plugins/examples/logging_plugin.py +164 -0
  375. autocoder/common/v2/agent/tool_caller/plugins/examples/security_filter_plugin.py +198 -0
  376. autocoder/common/v2/agent/tool_caller/plugins/plugin_interface.py +141 -0
  377. autocoder/common/v2/agent/tool_caller/test_tool_caller.py +278 -0
  378. autocoder/common/v2/agent/tool_caller/tool_call_plugin_manager.py +331 -0
  379. autocoder/common/v2/agent/tool_caller/tool_caller.py +337 -0
  380. autocoder/common/v2/agent/tool_caller/usage_example.py +193 -0
  381. autocoder/common/v2/code_agentic_editblock_manager.py +4 -4
  382. autocoder/common/v2/code_auto_generate.py +136 -78
  383. autocoder/common/v2/code_auto_generate_diff.py +135 -79
  384. autocoder/common/v2/code_auto_generate_editblock.py +174 -99
  385. autocoder/common/v2/code_auto_generate_strict_diff.py +151 -71
  386. autocoder/common/v2/code_auto_merge.py +1 -1
  387. autocoder/common/v2/code_auto_merge_editblock.py +13 -1
  388. autocoder/common/v2/code_diff_manager.py +3 -3
  389. autocoder/common/v2/code_editblock_manager.py +4 -14
  390. autocoder/common/v2/code_manager.py +1 -1
  391. autocoder/common/v2/code_strict_diff_manager.py +2 -2
  392. autocoder/common/wrap_llm_hint/__init__.py +10 -0
  393. autocoder/common/wrap_llm_hint/test_wrap_llm_hint.py +1067 -0
  394. autocoder/common/wrap_llm_hint/utils.py +432 -0
  395. autocoder/common/wrap_llm_hint/wrap_llm_hint.py +323 -0
  396. autocoder/completer/__init__.py +8 -0
  397. autocoder/completer/command_completer_v2.py +1094 -0
  398. autocoder/default_project/__init__.py +501 -0
  399. autocoder/dispacher/__init__.py +4 -12
  400. autocoder/dispacher/actions/action.py +400 -129
  401. autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
  402. autocoder/index/entry.py +117 -125
  403. autocoder/{agent → index/filter}/agentic_filter.py +322 -333
  404. autocoder/index/filter/normal_filter.py +5 -11
  405. autocoder/index/filter/quick_filter.py +1 -1
  406. autocoder/index/index.py +36 -9
  407. autocoder/index/tests/__init__.py +1 -0
  408. autocoder/index/tests/run_tests.py +195 -0
  409. autocoder/index/tests/test_entry.py +303 -0
  410. autocoder/index/tests/test_index_manager.py +314 -0
  411. autocoder/index/tests/test_module_integration.py +300 -0
  412. autocoder/index/tests/test_symbols_utils.py +183 -0
  413. autocoder/inner/__init__.py +4 -0
  414. autocoder/inner/agentic.py +923 -0
  415. autocoder/inner/async_command_handler.py +992 -0
  416. autocoder/inner/conversation_command_handlers.py +623 -0
  417. autocoder/inner/merge_command_handler.py +213 -0
  418. autocoder/inner/queue_command_handler.py +684 -0
  419. autocoder/models.py +95 -266
  420. autocoder/plugins/git_helper_plugin.py +31 -29
  421. autocoder/plugins/token_helper_plugin.py +65 -46
  422. autocoder/pyproject/__init__.py +32 -29
  423. autocoder/rag/agentic_rag.py +215 -75
  424. autocoder/rag/cache/simple_cache.py +1 -2
  425. autocoder/rag/loaders/image_loader.py +1 -1
  426. autocoder/rag/long_context_rag.py +42 -26
  427. autocoder/rag/qa_conversation_strategy.py +1 -1
  428. autocoder/rag/terminal/__init__.py +17 -0
  429. autocoder/rag/terminal/args.py +581 -0
  430. autocoder/rag/terminal/bootstrap.py +61 -0
  431. autocoder/rag/terminal/command_handlers.py +653 -0
  432. autocoder/rag/terminal/formatters/__init__.py +20 -0
  433. autocoder/rag/terminal/formatters/base.py +70 -0
  434. autocoder/rag/terminal/formatters/json_format.py +66 -0
  435. autocoder/rag/terminal/formatters/stream_json.py +95 -0
  436. autocoder/rag/terminal/formatters/text.py +28 -0
  437. autocoder/rag/terminal/init.py +120 -0
  438. autocoder/rag/terminal/utils.py +106 -0
  439. autocoder/rag/test_agentic_rag.py +389 -0
  440. autocoder/rag/test_doc_filter.py +3 -3
  441. autocoder/rag/test_long_context_rag.py +1 -1
  442. autocoder/rag/test_token_limiter.py +517 -10
  443. autocoder/rag/token_counter.py +3 -0
  444. autocoder/rag/token_limiter.py +19 -15
  445. autocoder/rag/tools/__init__.py +26 -2
  446. autocoder/rag/tools/bochaai_example.py +343 -0
  447. autocoder/rag/tools/bochaai_sdk.py +541 -0
  448. autocoder/rag/tools/metaso_example.py +268 -0
  449. autocoder/rag/tools/metaso_sdk.py +417 -0
  450. autocoder/rag/tools/recall_tool.py +28 -7
  451. autocoder/rag/tools/run_integration_tests.py +204 -0
  452. autocoder/rag/tools/test_all_providers.py +318 -0
  453. autocoder/rag/tools/test_bochaai_integration.py +482 -0
  454. autocoder/rag/tools/test_final_integration.py +215 -0
  455. autocoder/rag/tools/test_metaso_integration.py +424 -0
  456. autocoder/rag/tools/test_metaso_real.py +171 -0
  457. autocoder/rag/tools/test_web_crawl_tool.py +639 -0
  458. autocoder/rag/tools/test_web_search_tool.py +509 -0
  459. autocoder/rag/tools/todo_read_tool.py +202 -0
  460. autocoder/rag/tools/todo_write_tool.py +412 -0
  461. autocoder/rag/tools/web_crawl_tool.py +634 -0
  462. autocoder/rag/tools/web_search_tool.py +558 -0
  463. autocoder/rag/tools/web_tools_example.py +119 -0
  464. autocoder/rag/types.py +16 -0
  465. autocoder/rag/variable_holder.py +4 -2
  466. autocoder/rags.py +86 -79
  467. autocoder/regexproject/__init__.py +23 -21
  468. autocoder/sdk/__init__.py +46 -190
  469. autocoder/sdk/api.py +370 -0
  470. autocoder/sdk/async_runner/__init__.py +26 -0
  471. autocoder/sdk/async_runner/async_executor.py +650 -0
  472. autocoder/sdk/async_runner/async_handler.py +356 -0
  473. autocoder/sdk/async_runner/markdown_processor.py +595 -0
  474. autocoder/sdk/async_runner/task_metadata.py +284 -0
  475. autocoder/sdk/async_runner/worktree_manager.py +438 -0
  476. autocoder/sdk/cli/__init__.py +2 -5
  477. autocoder/sdk/cli/formatters.py +28 -204
  478. autocoder/sdk/cli/handlers.py +77 -44
  479. autocoder/sdk/cli/main.py +154 -171
  480. autocoder/sdk/cli/options.py +95 -22
  481. autocoder/sdk/constants.py +139 -51
  482. autocoder/sdk/core/auto_coder_core.py +484 -109
  483. autocoder/sdk/core/bridge.py +297 -115
  484. autocoder/sdk/exceptions.py +18 -12
  485. autocoder/sdk/formatters/__init__.py +19 -0
  486. autocoder/sdk/formatters/input.py +64 -0
  487. autocoder/sdk/formatters/output.py +247 -0
  488. autocoder/sdk/formatters/stream.py +54 -0
  489. autocoder/sdk/models/__init__.py +6 -5
  490. autocoder/sdk/models/options.py +55 -18
  491. autocoder/sdk/utils/formatters.py +27 -195
  492. autocoder/suffixproject/__init__.py +28 -25
  493. autocoder/terminal/__init__.py +14 -0
  494. autocoder/terminal/app.py +454 -0
  495. autocoder/terminal/args.py +32 -0
  496. autocoder/terminal/bootstrap.py +178 -0
  497. autocoder/terminal/command_processor.py +521 -0
  498. autocoder/terminal/command_registry.py +57 -0
  499. autocoder/terminal/help.py +97 -0
  500. autocoder/terminal/tasks/__init__.py +5 -0
  501. autocoder/terminal/tasks/background.py +77 -0
  502. autocoder/terminal/tasks/task_event.py +70 -0
  503. autocoder/terminal/ui/__init__.py +13 -0
  504. autocoder/terminal/ui/completer.py +268 -0
  505. autocoder/terminal/ui/keybindings.py +75 -0
  506. autocoder/terminal/ui/session.py +41 -0
  507. autocoder/terminal/ui/toolbar.py +64 -0
  508. autocoder/terminal/utils/__init__.py +13 -0
  509. autocoder/terminal/utils/errors.py +18 -0
  510. autocoder/terminal/utils/paths.py +19 -0
  511. autocoder/terminal/utils/shell.py +43 -0
  512. autocoder/terminal_v3/__init__.py +10 -0
  513. autocoder/terminal_v3/app.py +201 -0
  514. autocoder/terminal_v3/handlers/__init__.py +5 -0
  515. autocoder/terminal_v3/handlers/command_handler.py +131 -0
  516. autocoder/terminal_v3/models/__init__.py +6 -0
  517. autocoder/terminal_v3/models/conversation_buffer.py +214 -0
  518. autocoder/terminal_v3/models/message.py +50 -0
  519. autocoder/terminal_v3/models/tool_display.py +247 -0
  520. autocoder/terminal_v3/ui/__init__.py +7 -0
  521. autocoder/terminal_v3/ui/keybindings.py +56 -0
  522. autocoder/terminal_v3/ui/layout.py +141 -0
  523. autocoder/terminal_v3/ui/styles.py +43 -0
  524. autocoder/tsproject/__init__.py +23 -23
  525. autocoder/utils/auto_coder_utils/chat_stream_out.py +1 -1
  526. autocoder/utils/llms.py +88 -80
  527. autocoder/utils/math_utils.py +101 -0
  528. autocoder/utils/model_provider_selector.py +16 -4
  529. autocoder/utils/operate_config_api.py +33 -5
  530. autocoder/utils/thread_utils.py +2 -2
  531. autocoder/version.py +4 -2
  532. autocoder/workflow_agents/__init__.py +84 -0
  533. autocoder/workflow_agents/agent.py +143 -0
  534. autocoder/workflow_agents/exceptions.py +573 -0
  535. autocoder/workflow_agents/executor.py +665 -0
  536. autocoder/workflow_agents/loader.py +749 -0
  537. autocoder/workflow_agents/runner.py +267 -0
  538. autocoder/workflow_agents/types.py +173 -0
  539. autocoder/workflow_agents/utils.py +434 -0
  540. autocoder/workflow_agents/workflow_manager.py +211 -0
  541. auto_coder-1.0.0.dist-info/METADATA +0 -396
  542. auto_coder-1.0.0.dist-info/RECORD +0 -442
  543. auto_coder-1.0.0.dist-info/licenses/LICENSE +0 -201
  544. autocoder/auto_coder_server.py +0 -672
  545. autocoder/benchmark.py +0 -138
  546. autocoder/common/ac_style_command_parser/example.py +0 -7
  547. autocoder/common/cleaner.py +0 -31
  548. autocoder/common/command_completer_v2.py +0 -615
  549. autocoder/common/context_pruner.py +0 -477
  550. autocoder/common/conversation_pruner.py +0 -132
  551. autocoder/common/directory_cache/__init__.py +0 -1
  552. autocoder/common/directory_cache/cache.py +0 -192
  553. autocoder/common/directory_cache/test_cache.py +0 -190
  554. autocoder/common/file_checkpoint/examples.py +0 -217
  555. autocoder/common/llm_friendly_package_example.py +0 -138
  556. autocoder/common/llm_friendly_package_test.py +0 -63
  557. autocoder/common/pull_requests/test_module.py +0 -1
  558. autocoder/common/rulefiles/autocoderrules_utils.py +0 -484
  559. autocoder/common/text.py +0 -30
  560. autocoder/common/v2/agent/agentic_edit_tools/list_package_info_tool_resolver.py +0 -42
  561. autocoder/common/v2/agent/agentic_edit_tools/test_execute_command_tool_resolver.py +0 -70
  562. autocoder/common/v2/agent/agentic_edit_tools/test_search_files_tool_resolver.py +0 -163
  563. autocoder/common/v2/agent/agentic_tool_display.py +0 -183
  564. autocoder/plugins/dynamic_completion_example.py +0 -148
  565. autocoder/plugins/sample_plugin.py +0 -160
  566. autocoder/sdk/cli/__main__.py +0 -26
  567. autocoder/sdk/cli/completion_wrapper.py +0 -38
  568. autocoder/sdk/cli/install_completion.py +0 -301
  569. autocoder/sdk/models/messages.py +0 -209
  570. autocoder/sdk/session/__init__.py +0 -32
  571. autocoder/sdk/session/session.py +0 -106
  572. autocoder/sdk/session/session_manager.py +0 -56
  573. {auto_coder-1.0.0.dist-info → auto_coder-2.0.1.dist-info}/top_level.txt +0 -0
  574. /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
@@ -0,0 +1,546 @@
1
+ """
2
+ Tests for monitoring functionality.
3
+
4
+ This module tests the monitoring capabilities used in shell command execution.
5
+ """
6
+
7
+ import pytest
8
+ import time
9
+ from datetime import datetime
10
+ from unittest.mock import Mock, patch
11
+
12
+ from autocoder.common.shell_commands.monitoring import (
13
+ CommandExecutionLogger,
14
+ PerformanceMonitor,
15
+ CommandExecutionMetrics,
16
+ get_logger,
17
+ get_global_monitor,
18
+ reset_global_instances
19
+ )
20
+ from autocoder.common.shell_commands.exceptions import (
21
+ CommandExecutionError,
22
+ CommandTimeoutError
23
+ )
24
+
25
+
26
+ class TestCommandExecutionMetrics:
27
+ """Test cases for CommandExecutionMetrics class."""
28
+
29
+ def test_initialization(self):
30
+ """Test metrics initialization."""
31
+ command = "echo hello"
32
+ start_time = datetime.now()
33
+
34
+ metrics = CommandExecutionMetrics(command, start_time)
35
+
36
+ assert metrics.command == command
37
+ assert metrics.start_time == start_time
38
+ assert metrics.end_time is None
39
+ assert metrics.duration is None
40
+ assert metrics.exit_code is None
41
+ assert metrics.timeout is None
42
+ assert metrics.timed_out is False
43
+ assert metrics.pid is None
44
+ assert metrics.output_length == 0
45
+ assert metrics.error_count == 0
46
+ assert metrics.recovery_attempts == 0
47
+
48
+ def test_finalize_with_default_end_time(self):
49
+ """Test metrics finalization with default end time."""
50
+ command = "echo hello"
51
+ start_time = datetime.now()
52
+
53
+ metrics = CommandExecutionMetrics(command, start_time)
54
+
55
+ # Wait a bit to ensure duration is measurable
56
+ time.sleep(0.001)
57
+
58
+ metrics.finalize()
59
+
60
+ assert metrics.end_time is not None
61
+ assert metrics.duration is not None
62
+ assert metrics.duration > 0
63
+ assert metrics.end_time > start_time
64
+
65
+ def test_finalize_with_custom_end_time(self):
66
+ """Test metrics finalization with custom end time."""
67
+ command = "echo hello"
68
+ start_time = datetime.now()
69
+ end_time = datetime.now()
70
+
71
+ metrics = CommandExecutionMetrics(command, start_time)
72
+ metrics.finalize(end_time)
73
+
74
+ assert metrics.end_time == end_time
75
+ assert metrics.duration is not None
76
+ assert metrics.duration >= 0
77
+
78
+ def test_string_representation(self):
79
+ """Test string representation of metrics."""
80
+ command = "echo hello"
81
+ start_time = datetime.now()
82
+
83
+ metrics = CommandExecutionMetrics(command, start_time)
84
+ metrics.exit_code = 0
85
+ metrics.duration = 1.5
86
+
87
+ str_repr = str(metrics)
88
+ assert command in str_repr
89
+ assert "0" in str_repr # exit code
90
+ assert "1.5" in str_repr # duration
91
+
92
+ def test_metrics_with_timeout(self):
93
+ """Test metrics with timeout information."""
94
+ command = "sleep 10"
95
+ start_time = datetime.now()
96
+
97
+ metrics = CommandExecutionMetrics(command, start_time)
98
+ metrics.timeout = 5.0
99
+ metrics.timed_out = True
100
+ metrics.pid = 1234
101
+
102
+ assert metrics.timeout == 5.0
103
+ assert metrics.timed_out is True
104
+ assert metrics.pid == 1234
105
+
106
+ def test_metrics_with_error_tracking(self):
107
+ """Test metrics with error tracking."""
108
+ command = "failing_command"
109
+ start_time = datetime.now()
110
+
111
+ metrics = CommandExecutionMetrics(command, start_time)
112
+ metrics.error_count = 2
113
+ metrics.recovery_attempts = 3
114
+
115
+ assert metrics.error_count == 2
116
+ assert metrics.recovery_attempts == 3
117
+
118
+
119
+ class TestCommandExecutionLogger:
120
+ """Test cases for CommandExecutionLogger class."""
121
+
122
+ def test_initialization(self):
123
+ """Test logger initialization."""
124
+ logger = CommandExecutionLogger(verbose=True)
125
+ assert logger.verbose is True
126
+
127
+ def test_log_command_start(self):
128
+ """Test logging command start."""
129
+ logger = CommandExecutionLogger(verbose=False)
130
+
131
+ metrics = logger.log_command_start("echo hello", 5.0, 1234, "/tmp")
132
+
133
+ assert metrics.command == "echo hello"
134
+ assert metrics.timeout == 5.0
135
+ assert metrics.pid == 1234
136
+ assert metrics.start_time is not None
137
+
138
+ def test_log_command_start_without_optional_params(self):
139
+ """Test logging command start without optional parameters."""
140
+ logger = CommandExecutionLogger()
141
+
142
+ metrics = logger.log_command_start("test command")
143
+
144
+ assert metrics.command == "test command"
145
+ assert metrics.timeout is None
146
+ assert metrics.pid is None
147
+
148
+ def test_log_command_complete_success(self):
149
+ """Test logging successful command completion."""
150
+ logger = CommandExecutionLogger()
151
+
152
+ metrics = CommandExecutionMetrics("test command", datetime.now())
153
+ metrics.pid = 1234
154
+
155
+ logger.log_command_complete(metrics, 0, "output text")
156
+
157
+ assert metrics.exit_code == 0
158
+ assert metrics.output_length == len("output text")
159
+ assert metrics.end_time is not None
160
+ assert metrics.duration is not None
161
+
162
+ def test_log_command_complete_failure(self):
163
+ """Test logging failed command completion."""
164
+ logger = CommandExecutionLogger()
165
+
166
+ metrics = CommandExecutionMetrics("test command", datetime.now())
167
+ metrics.pid = 1234
168
+
169
+ error = CommandExecutionError("Command failed")
170
+ logger.log_command_complete(metrics, 1, "", error)
171
+
172
+ assert metrics.exit_code == 1
173
+ assert metrics.output_length == 0
174
+ assert metrics.error_count == 1
175
+ assert metrics.end_time is not None
176
+
177
+ def test_log_command_complete_timeout(self):
178
+ """Test logging command timeout."""
179
+ logger = CommandExecutionLogger()
180
+
181
+ metrics = CommandExecutionMetrics("sleep 10", datetime.now())
182
+ metrics.pid = 1234
183
+ metrics.timeout = 5.0
184
+
185
+ timeout_error = CommandTimeoutError("sleep 10", 5.0, 1234)
186
+ logger.log_command_complete(metrics, -1, "", timeout_error)
187
+
188
+ assert metrics.exit_code == -1
189
+ assert metrics.timed_out is True
190
+ assert metrics.error_count == 1
191
+
192
+ def test_get_execution_history(self):
193
+ """Test getting command execution history."""
194
+ logger = CommandExecutionLogger()
195
+
196
+ # Log a few commands
197
+ metrics1 = logger.log_command_start("echo 1")
198
+ logger.log_command_complete(metrics1, 0, "output1")
199
+
200
+ metrics2 = logger.log_command_start("echo 2")
201
+ logger.log_command_complete(metrics2, 0, "output2")
202
+
203
+ history = logger.get_execution_history()
204
+
205
+ assert len(history) == 2
206
+ assert history[0].command == "echo 1"
207
+ assert history[1].command == "echo 2"
208
+
209
+ def test_get_summary_stats(self):
210
+ """Test getting summary statistics."""
211
+ logger = CommandExecutionLogger()
212
+
213
+ # Log successful command
214
+ metrics1 = logger.log_command_start("echo success")
215
+ logger.log_command_complete(metrics1, 0, "output")
216
+
217
+ # Log failed command
218
+ metrics2 = logger.log_command_start("false")
219
+ logger.log_command_complete(metrics2, 1, "")
220
+
221
+ # Log timeout command
222
+ metrics3 = logger.log_command_start("sleep 10")
223
+ metrics3.timeout = 5.0
224
+ timeout_error = CommandTimeoutError("sleep 10", 5.0, 1234)
225
+ logger.log_command_complete(metrics3, -1, "", timeout_error)
226
+
227
+ stats = logger.get_summary_stats()
228
+
229
+ assert stats['total_commands'] == 3
230
+ assert stats['completed_commands'] == 3
231
+ assert stats['successful_commands'] == 1
232
+ assert stats['failed_commands'] == 1
233
+ assert stats['timed_out_commands'] == 1
234
+ assert stats['success_rate'] == 1/3
235
+ assert stats['timeout_rate'] == 1/3
236
+
237
+
238
+ class TestPerformanceMonitor:
239
+ """Test cases for PerformanceMonitor class."""
240
+
241
+ def test_initialization(self):
242
+ """Test monitor initialization."""
243
+ monitor = PerformanceMonitor()
244
+ assert len(monitor.metrics_history) == 0
245
+ assert len(monitor.performance_alerts) == 0
246
+
247
+ def test_record_execution(self):
248
+ """Test recording command execution."""
249
+ monitor = PerformanceMonitor()
250
+
251
+ metrics = CommandExecutionMetrics("echo test", datetime.now())
252
+ metrics.exit_code = 0
253
+ metrics.duration = 1.5
254
+
255
+ monitor.record_execution(metrics)
256
+
257
+ recent_metrics = monitor.get_recent_metrics(1)
258
+ assert len(recent_metrics) == 1
259
+ assert recent_metrics[0].command == "echo test"
260
+ assert recent_metrics[0].duration == 1.5
261
+
262
+ def test_record_execution_performance_alert(self):
263
+ """Test recording execution that triggers performance alert."""
264
+ monitor = PerformanceMonitor()
265
+
266
+ # Create a slow command
267
+ metrics = CommandExecutionMetrics("slow_command", datetime.now())
268
+ metrics.duration = 30.0 # Very slow command
269
+ metrics.exit_code = 0
270
+
271
+ monitor.record_execution(metrics)
272
+
273
+ alerts = monitor.get_alerts(1)
274
+ assert len(alerts) >= 0 # May or may not trigger alert depending on implementation
275
+
276
+ def test_record_execution_timeout_alert(self):
277
+ """Test recording execution that triggers timeout alert."""
278
+ monitor = PerformanceMonitor()
279
+
280
+ metrics = CommandExecutionMetrics("timeout_command", datetime.now())
281
+ metrics.timed_out = True
282
+ metrics.timeout = 5.0
283
+
284
+ monitor.record_execution(metrics)
285
+
286
+ alerts = monitor.get_alerts(1)
287
+ assert len(alerts) >= 0 # May or may not trigger alert depending on implementation
288
+
289
+ def test_record_execution_error_alert(self):
290
+ """Test recording execution that triggers error alert."""
291
+ monitor = PerformanceMonitor()
292
+
293
+ metrics = CommandExecutionMetrics("error_command", datetime.now())
294
+ metrics.exit_code = 1
295
+ metrics.error_count = 1
296
+
297
+ monitor.record_execution(metrics)
298
+
299
+ alerts = monitor.get_alerts(1)
300
+ assert len(alerts) >= 0 # May or may not trigger alert depending on implementation
301
+
302
+ def test_get_recent_metrics(self):
303
+ """Test getting recent metrics."""
304
+ monitor = PerformanceMonitor()
305
+
306
+ # Record multiple executions
307
+ for i in range(5):
308
+ metrics = CommandExecutionMetrics(f"echo {i}", datetime.now())
309
+ metrics.exit_code = 0
310
+ monitor.record_execution(metrics)
311
+
312
+ recent = monitor.get_recent_metrics(3)
313
+ assert len(recent) == 3
314
+ # Check that we get some of the recent commands
315
+ assert any(f"echo {i}" in m.command for m in recent for i in range(2, 5))
316
+
317
+ def test_get_command_stats(self):
318
+ """Test getting command statistics."""
319
+ monitor = PerformanceMonitor()
320
+
321
+ # Record multiple echo commands
322
+ for i in range(3):
323
+ metrics = CommandExecutionMetrics(f"echo {i}", datetime.now())
324
+ metrics.exit_code = 0
325
+ metrics.duration = 1.0 + i * 0.5
326
+ monitor.record_execution(metrics)
327
+
328
+ # Record a different command
329
+ metrics = CommandExecutionMetrics("ls", datetime.now())
330
+ metrics.exit_code = 0
331
+ metrics.duration = 0.5
332
+ monitor.record_execution(metrics)
333
+
334
+ echo_stats = monitor.get_command_stats("echo")
335
+ assert echo_stats['total_executions'] == 3
336
+ assert echo_stats['completed_executions'] == 3
337
+ assert echo_stats['successful_executions'] == 3
338
+ assert echo_stats['success_rate'] == 1.0
339
+ assert echo_stats['average_duration'] == 1.5 # (1.0 + 1.5 + 2.0) / 3
340
+
341
+ def test_get_performance_summary(self):
342
+ """Test getting performance summary."""
343
+ monitor = PerformanceMonitor()
344
+
345
+ # Record some commands
346
+ for i in range(5):
347
+ metrics = CommandExecutionMetrics(f"echo {i}", datetime.now())
348
+ metrics.exit_code = 0 if i < 3 else 1
349
+ metrics.duration = 1.0
350
+ monitor.record_execution(metrics)
351
+
352
+ summary = monitor.get_performance_summary()
353
+
354
+ assert summary['total_commands'] == 5
355
+ assert summary['recent_commands'] == 5
356
+ assert summary['success_rate'] == 0.6 # 3/5
357
+ assert summary['timeout_rate'] == 0.0
358
+ assert summary['average_duration'] == 1.0
359
+
360
+
361
+ class TestGlobalMonitoringInstances:
362
+ """Test cases for global monitoring instances."""
363
+
364
+ def test_get_global_logger(self):
365
+ """Test getting global logger instance."""
366
+ logger1 = get_logger()
367
+ logger2 = get_logger()
368
+
369
+ assert logger1 is logger2 # Should be the same instance
370
+ assert isinstance(logger1, CommandExecutionLogger)
371
+
372
+ def test_get_global_monitor(self):
373
+ """Test getting global monitor instance."""
374
+ monitor1 = get_global_monitor()
375
+ monitor2 = get_global_monitor()
376
+
377
+ assert monitor1 is monitor2 # Should be the same instance
378
+ assert isinstance(monitor1, PerformanceMonitor)
379
+
380
+ def test_reset_global_instances(self):
381
+ """Test resetting global instances."""
382
+ logger1 = get_logger()
383
+ monitor1 = get_global_monitor()
384
+
385
+ reset_global_instances()
386
+
387
+ logger2 = get_logger()
388
+ monitor2 = get_global_monitor()
389
+
390
+ assert logger1 is not logger2 # Should be different instances
391
+ assert monitor1 is not monitor2
392
+
393
+ def test_global_logger_with_verbose_flag(self):
394
+ """Test global logger with verbose flag."""
395
+ logger = get_logger(verbose=True)
396
+ assert logger.verbose is True
397
+
398
+ # Reset and test with verbose=False
399
+ reset_global_instances()
400
+ logger = get_logger(verbose=False)
401
+ assert logger.verbose is False
402
+
403
+
404
+ class TestMonitoringIntegration:
405
+ """Test cases for monitoring integration scenarios."""
406
+
407
+ def test_logger_monitor_integration(self):
408
+ """Test integration between logger and monitor."""
409
+ logger = CommandExecutionLogger()
410
+ monitor = PerformanceMonitor()
411
+
412
+ # Log command execution
413
+ metrics = logger.log_command_start("echo test", 5.0, 1234)
414
+ logger.log_command_complete(metrics, 0, "output")
415
+
416
+ # Record in monitor
417
+ monitor.record_execution(metrics)
418
+
419
+ # Verify both have the execution recorded
420
+ history = logger.get_execution_history()
421
+ recent = monitor.get_recent_metrics(1)
422
+
423
+ assert len(history) == 1
424
+ assert len(recent) == 1
425
+ assert history[0].command == recent[0].command
426
+
427
+ def test_monitoring_with_errors(self):
428
+ """Test monitoring with error conditions."""
429
+ logger = CommandExecutionLogger()
430
+ monitor = PerformanceMonitor()
431
+
432
+ # Log failed command
433
+ metrics = logger.log_command_start("false")
434
+ error = CommandExecutionError("Command failed")
435
+ logger.log_command_complete(metrics, 1, "", error)
436
+
437
+ monitor.record_execution(metrics)
438
+
439
+ # Check statistics
440
+ stats = logger.get_summary_stats()
441
+ alerts = monitor.get_alerts(1)
442
+
443
+ assert stats['failed_commands'] == 1
444
+ assert len(alerts) >= 0 # May or may not trigger alert
445
+
446
+ def test_monitoring_with_timeout(self):
447
+ """Test monitoring with timeout conditions."""
448
+ logger = CommandExecutionLogger()
449
+ monitor = PerformanceMonitor()
450
+
451
+ # Log timeout command
452
+ metrics = logger.log_command_start("sleep 10")
453
+ metrics.timeout = 5.0
454
+ timeout_error = CommandTimeoutError("sleep 10", 5.0, 1234)
455
+ logger.log_command_complete(metrics, -1, "", timeout_error)
456
+
457
+ monitor.record_execution(metrics)
458
+
459
+ # Check statistics
460
+ stats = logger.get_summary_stats()
461
+ alerts = monitor.get_alerts(1)
462
+
463
+ assert stats['timed_out_commands'] == 1
464
+ assert len(alerts) >= 0 # May or may not trigger alert
465
+
466
+
467
+ class TestMonitoringEdgeCases:
468
+ """Test cases for monitoring edge cases."""
469
+
470
+ def test_empty_command_logging(self):
471
+ """Test logging with empty command."""
472
+ logger = CommandExecutionLogger()
473
+
474
+ metrics = logger.log_command_start("")
475
+ logger.log_command_complete(metrics, 0, "")
476
+
477
+ assert metrics.command == ""
478
+ assert metrics.exit_code == 0
479
+
480
+ def test_very_long_command_logging(self):
481
+ """Test logging with very long command."""
482
+ logger = CommandExecutionLogger()
483
+
484
+ long_command = "echo " + "a" * 1000
485
+ metrics = logger.log_command_start(long_command)
486
+ logger.log_command_complete(metrics, 0, "output")
487
+
488
+ assert metrics.command == long_command
489
+ assert len(metrics.command) > 1000
490
+
491
+ def test_negative_duration_handling(self):
492
+ """Test handling of negative duration."""
493
+ monitor = PerformanceMonitor()
494
+
495
+ metrics = CommandExecutionMetrics("echo test", datetime.now())
496
+ metrics.duration = -1.0 # Invalid duration
497
+
498
+ # Should handle gracefully
499
+ monitor.record_execution(metrics)
500
+
501
+ recent = monitor.get_recent_metrics(1)
502
+ assert len(recent) == 1
503
+
504
+ def test_error_values_handling(self):
505
+ """Test handling of error values in metrics."""
506
+ logger = CommandExecutionLogger()
507
+
508
+ metrics = logger.log_command_start("echo test")
509
+ # Set valid exit code and output
510
+ logger.log_command_complete(metrics, 0, "output")
511
+
512
+ assert metrics.exit_code == 0
513
+ assert metrics.output_length == len("output")
514
+
515
+ def test_concurrent_monitoring(self):
516
+ """Test concurrent access to monitoring instances."""
517
+ import threading
518
+
519
+ logger = get_logger()
520
+ monitor = get_global_monitor()
521
+
522
+ results = []
523
+
524
+ def log_command(i):
525
+ metrics = logger.log_command_start(f"echo {i}")
526
+ logger.log_command_complete(metrics, 0, f"output {i}")
527
+ monitor.record_execution(metrics)
528
+ results.append(i)
529
+
530
+ threads = []
531
+ for i in range(5):
532
+ thread = threading.Thread(target=log_command, args=(i,))
533
+ threads.append(thread)
534
+ thread.start()
535
+
536
+ for thread in threads:
537
+ thread.join()
538
+
539
+ # All commands should be logged
540
+ assert len(results) == 5
541
+ assert len(logger.get_execution_history()) == 5
542
+ assert len(monitor.get_recent_metrics(5)) == 5
543
+
544
+
545
+ if __name__ == "__main__":
546
+ pytest.main([__file__, "-v"])