tapps-agents 3.5.40__py3-none-any.whl → 3.6.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.
- tapps_agents/__init__.py +2 -2
- tapps_agents/agents/__init__.py +22 -22
- tapps_agents/agents/analyst/__init__.py +5 -5
- tapps_agents/agents/architect/__init__.py +5 -5
- tapps_agents/agents/architect/agent.py +1033 -1033
- tapps_agents/agents/architect/pattern_detector.py +75 -75
- tapps_agents/agents/cleanup/__init__.py +7 -7
- tapps_agents/agents/cleanup/agent.py +445 -445
- tapps_agents/agents/debugger/__init__.py +7 -7
- tapps_agents/agents/debugger/agent.py +310 -310
- tapps_agents/agents/debugger/error_analyzer.py +437 -437
- tapps_agents/agents/designer/__init__.py +5 -5
- tapps_agents/agents/designer/agent.py +786 -786
- tapps_agents/agents/designer/visual_designer.py +638 -638
- tapps_agents/agents/documenter/__init__.py +7 -7
- tapps_agents/agents/documenter/agent.py +531 -531
- tapps_agents/agents/documenter/doc_generator.py +472 -472
- tapps_agents/agents/documenter/doc_validator.py +393 -393
- tapps_agents/agents/documenter/framework_doc_updater.py +493 -493
- tapps_agents/agents/enhancer/__init__.py +7 -7
- tapps_agents/agents/evaluator/__init__.py +7 -7
- tapps_agents/agents/evaluator/agent.py +443 -443
- tapps_agents/agents/evaluator/priority_evaluator.py +641 -641
- tapps_agents/agents/evaluator/quality_analyzer.py +147 -147
- tapps_agents/agents/evaluator/report_generator.py +344 -344
- tapps_agents/agents/evaluator/usage_analyzer.py +192 -192
- tapps_agents/agents/evaluator/workflow_analyzer.py +189 -189
- tapps_agents/agents/implementer/__init__.py +7 -7
- tapps_agents/agents/implementer/agent.py +798 -798
- tapps_agents/agents/implementer/auto_fix.py +1119 -1119
- tapps_agents/agents/implementer/code_generator.py +73 -73
- tapps_agents/agents/improver/__init__.py +1 -1
- tapps_agents/agents/improver/agent.py +753 -753
- tapps_agents/agents/ops/__init__.py +1 -1
- tapps_agents/agents/ops/agent.py +619 -619
- tapps_agents/agents/ops/dependency_analyzer.py +600 -600
- tapps_agents/agents/orchestrator/__init__.py +5 -5
- tapps_agents/agents/orchestrator/agent.py +522 -522
- tapps_agents/agents/planner/__init__.py +7 -7
- tapps_agents/agents/planner/agent.py +1127 -1127
- tapps_agents/agents/reviewer/__init__.py +24 -24
- tapps_agents/agents/reviewer/agent.py +3513 -3513
- tapps_agents/agents/reviewer/aggregator.py +213 -213
- tapps_agents/agents/reviewer/batch_review.py +448 -448
- tapps_agents/agents/reviewer/cache.py +443 -443
- tapps_agents/agents/reviewer/context7_enhancer.py +630 -630
- tapps_agents/agents/reviewer/context_detector.py +203 -203
- tapps_agents/agents/reviewer/docker_compose_validator.py +158 -158
- tapps_agents/agents/reviewer/dockerfile_validator.py +176 -176
- tapps_agents/agents/reviewer/error_handling.py +126 -126
- tapps_agents/agents/reviewer/feedback_generator.py +490 -490
- tapps_agents/agents/reviewer/influxdb_validator.py +316 -316
- tapps_agents/agents/reviewer/issue_tracking.py +169 -169
- tapps_agents/agents/reviewer/library_detector.py +295 -295
- tapps_agents/agents/reviewer/library_patterns.py +268 -268
- tapps_agents/agents/reviewer/maintainability_scorer.py +593 -593
- tapps_agents/agents/reviewer/metric_strategies.py +276 -276
- tapps_agents/agents/reviewer/mqtt_validator.py +160 -160
- tapps_agents/agents/reviewer/output_enhancer.py +105 -105
- tapps_agents/agents/reviewer/pattern_detector.py +241 -241
- tapps_agents/agents/reviewer/performance_scorer.py +357 -357
- tapps_agents/agents/reviewer/phased_review.py +516 -516
- tapps_agents/agents/reviewer/progressive_review.py +435 -435
- tapps_agents/agents/reviewer/react_scorer.py +331 -331
- tapps_agents/agents/reviewer/score_constants.py +228 -228
- tapps_agents/agents/reviewer/score_validator.py +507 -507
- tapps_agents/agents/reviewer/scorer_registry.py +373 -373
- tapps_agents/agents/reviewer/scoring.py +1566 -1566
- tapps_agents/agents/reviewer/service_discovery.py +534 -534
- tapps_agents/agents/reviewer/tools/__init__.py +41 -41
- tapps_agents/agents/reviewer/tools/parallel_executor.py +581 -581
- tapps_agents/agents/reviewer/tools/ruff_grouping.py +250 -250
- tapps_agents/agents/reviewer/tools/scoped_mypy.py +284 -284
- tapps_agents/agents/reviewer/typescript_scorer.py +1142 -1142
- tapps_agents/agents/reviewer/validation.py +208 -208
- tapps_agents/agents/reviewer/websocket_validator.py +132 -132
- tapps_agents/agents/tester/__init__.py +7 -7
- tapps_agents/agents/tester/accessibility_auditor.py +309 -309
- tapps_agents/agents/tester/agent.py +1080 -1080
- tapps_agents/agents/tester/batch_generator.py +54 -54
- tapps_agents/agents/tester/context_learner.py +51 -51
- tapps_agents/agents/tester/coverage_analyzer.py +386 -386
- tapps_agents/agents/tester/coverage_test_generator.py +290 -290
- tapps_agents/agents/tester/debug_enhancer.py +238 -238
- tapps_agents/agents/tester/device_emulator.py +241 -241
- tapps_agents/agents/tester/integration_generator.py +62 -62
- tapps_agents/agents/tester/network_recorder.py +300 -300
- tapps_agents/agents/tester/performance_monitor.py +320 -320
- tapps_agents/agents/tester/test_fixer.py +316 -316
- tapps_agents/agents/tester/test_generator.py +632 -632
- tapps_agents/agents/tester/trace_manager.py +234 -234
- tapps_agents/agents/tester/visual_regression.py +291 -291
- tapps_agents/analysis/pattern_detector.py +36 -36
- tapps_agents/beads/hydration.py +213 -213
- tapps_agents/beads/parse.py +32 -32
- tapps_agents/beads/specs.py +206 -206
- tapps_agents/cli/__init__.py +9 -9
- tapps_agents/cli/__main__.py +8 -8
- tapps_agents/cli/base.py +478 -478
- tapps_agents/cli/command_classifier.py +72 -72
- tapps_agents/cli/commands/__init__.py +2 -2
- tapps_agents/cli/commands/analyst.py +173 -173
- tapps_agents/cli/commands/architect.py +109 -109
- tapps_agents/cli/commands/cleanup_agent.py +92 -92
- tapps_agents/cli/commands/common.py +126 -126
- tapps_agents/cli/commands/debugger.py +90 -90
- tapps_agents/cli/commands/designer.py +112 -112
- tapps_agents/cli/commands/documenter.py +136 -136
- tapps_agents/cli/commands/enhancer.py +110 -110
- tapps_agents/cli/commands/evaluator.py +255 -255
- tapps_agents/cli/commands/health.py +665 -665
- tapps_agents/cli/commands/implementer.py +301 -301
- tapps_agents/cli/commands/improver.py +91 -91
- tapps_agents/cli/commands/knowledge.py +111 -111
- tapps_agents/cli/commands/learning.py +172 -172
- tapps_agents/cli/commands/observability.py +283 -283
- tapps_agents/cli/commands/ops.py +135 -135
- tapps_agents/cli/commands/orchestrator.py +116 -116
- tapps_agents/cli/commands/planner.py +237 -237
- tapps_agents/cli/commands/reviewer.py +1872 -1872
- tapps_agents/cli/commands/status.py +285 -285
- tapps_agents/cli/commands/task.py +227 -219
- tapps_agents/cli/commands/tester.py +191 -191
- tapps_agents/cli/commands/top_level.py +3586 -3586
- tapps_agents/cli/feedback.py +936 -936
- tapps_agents/cli/formatters.py +608 -608
- tapps_agents/cli/help/__init__.py +7 -7
- tapps_agents/cli/help/static_help.py +425 -425
- tapps_agents/cli/network_detection.py +110 -110
- tapps_agents/cli/output_compactor.py +274 -274
- tapps_agents/cli/parsers/__init__.py +2 -2
- tapps_agents/cli/parsers/analyst.py +186 -186
- tapps_agents/cli/parsers/architect.py +167 -167
- tapps_agents/cli/parsers/cleanup_agent.py +228 -228
- tapps_agents/cli/parsers/debugger.py +116 -116
- tapps_agents/cli/parsers/designer.py +182 -182
- tapps_agents/cli/parsers/documenter.py +134 -134
- tapps_agents/cli/parsers/enhancer.py +113 -113
- tapps_agents/cli/parsers/evaluator.py +213 -213
- tapps_agents/cli/parsers/implementer.py +168 -168
- tapps_agents/cli/parsers/improver.py +132 -132
- tapps_agents/cli/parsers/ops.py +159 -159
- tapps_agents/cli/parsers/orchestrator.py +98 -98
- tapps_agents/cli/parsers/planner.py +145 -145
- tapps_agents/cli/parsers/reviewer.py +462 -462
- tapps_agents/cli/parsers/tester.py +124 -124
- tapps_agents/cli/progress_heartbeat.py +254 -254
- tapps_agents/cli/streaming_progress.py +336 -336
- tapps_agents/cli/utils/__init__.py +6 -6
- tapps_agents/cli/utils/agent_lifecycle.py +48 -48
- tapps_agents/cli/utils/error_formatter.py +82 -82
- tapps_agents/cli/utils/error_recovery.py +188 -188
- tapps_agents/cli/utils/output_handler.py +59 -59
- tapps_agents/cli/utils/prompt_enhancer.py +319 -319
- tapps_agents/cli/validators/__init__.py +9 -9
- tapps_agents/cli/validators/command_validator.py +81 -81
- tapps_agents/context7/__init__.py +112 -112
- tapps_agents/context7/agent_integration.py +869 -869
- tapps_agents/context7/analytics.py +382 -382
- tapps_agents/context7/analytics_dashboard.py +299 -299
- tapps_agents/context7/async_cache.py +681 -681
- tapps_agents/context7/backup_client.py +958 -958
- tapps_agents/context7/cache_locking.py +194 -194
- tapps_agents/context7/cache_metadata.py +214 -214
- tapps_agents/context7/cache_prewarm.py +488 -488
- tapps_agents/context7/cache_structure.py +168 -168
- tapps_agents/context7/cache_warming.py +604 -604
- tapps_agents/context7/circuit_breaker.py +376 -376
- tapps_agents/context7/cleanup.py +461 -461
- tapps_agents/context7/commands.py +858 -858
- tapps_agents/context7/credential_validation.py +276 -276
- tapps_agents/context7/cross_reference_resolver.py +168 -168
- tapps_agents/context7/cross_references.py +424 -424
- tapps_agents/context7/doc_manager.py +225 -225
- tapps_agents/context7/fuzzy_matcher.py +369 -369
- tapps_agents/context7/kb_cache.py +404 -404
- tapps_agents/context7/language_detector.py +219 -219
- tapps_agents/context7/library_detector.py +725 -725
- tapps_agents/context7/lookup.py +738 -738
- tapps_agents/context7/metadata.py +258 -258
- tapps_agents/context7/refresh_queue.py +300 -300
- tapps_agents/context7/security.py +373 -373
- tapps_agents/context7/staleness_policies.py +278 -278
- tapps_agents/context7/tiles_integration.py +47 -47
- tapps_agents/continuous_bug_fix/__init__.py +20 -20
- tapps_agents/continuous_bug_fix/bug_finder.py +306 -306
- tapps_agents/continuous_bug_fix/bug_fix_coordinator.py +177 -177
- tapps_agents/continuous_bug_fix/commit_manager.py +178 -178
- tapps_agents/continuous_bug_fix/continuous_bug_fixer.py +322 -322
- tapps_agents/continuous_bug_fix/proactive_bug_finder.py +285 -285
- tapps_agents/core/__init__.py +298 -298
- tapps_agents/core/adaptive_cache_config.py +432 -432
- tapps_agents/core/agent_base.py +647 -647
- tapps_agents/core/agent_cache.py +466 -466
- tapps_agents/core/agent_learning.py +1865 -1865
- tapps_agents/core/analytics_dashboard.py +563 -563
- tapps_agents/core/analytics_enhancements.py +597 -597
- tapps_agents/core/anonymization.py +274 -274
- tapps_agents/core/artifact_context_builder.py +293 -0
- tapps_agents/core/ast_parser.py +228 -228
- tapps_agents/core/async_file_ops.py +402 -402
- tapps_agents/core/best_practice_consultant.py +299 -299
- tapps_agents/core/brownfield_analyzer.py +299 -299
- tapps_agents/core/brownfield_review.py +541 -541
- tapps_agents/core/browser_controller.py +513 -513
- tapps_agents/core/capability_registry.py +418 -418
- tapps_agents/core/change_impact_analyzer.py +190 -190
- tapps_agents/core/checkpoint_manager.py +377 -377
- tapps_agents/core/code_generator.py +329 -329
- tapps_agents/core/code_validator.py +276 -276
- tapps_agents/core/command_registry.py +327 -327
- tapps_agents/core/config.py +33 -0
- tapps_agents/core/context_gathering/__init__.py +2 -2
- tapps_agents/core/context_gathering/repository_explorer.py +28 -28
- tapps_agents/core/context_intelligence/__init__.py +2 -2
- tapps_agents/core/context_intelligence/relevance_scorer.py +24 -24
- tapps_agents/core/context_intelligence/token_budget_manager.py +27 -27
- tapps_agents/core/context_manager.py +240 -240
- tapps_agents/core/cursor_feedback_monitor.py +146 -146
- tapps_agents/core/cursor_verification.py +290 -290
- tapps_agents/core/customization_loader.py +280 -280
- tapps_agents/core/customization_schema.py +260 -260
- tapps_agents/core/customization_template.py +238 -238
- tapps_agents/core/debug_logger.py +124 -124
- tapps_agents/core/design_validator.py +298 -298
- tapps_agents/core/diagram_generator.py +226 -226
- tapps_agents/core/docker_utils.py +232 -232
- tapps_agents/core/document_generator.py +617 -617
- tapps_agents/core/domain_detector.py +30 -30
- tapps_agents/core/error_envelope.py +454 -454
- tapps_agents/core/error_handler.py +270 -270
- tapps_agents/core/estimation_tracker.py +189 -189
- tapps_agents/core/eval_prompt_engine.py +116 -116
- tapps_agents/core/evaluation_base.py +119 -119
- tapps_agents/core/evaluation_models.py +320 -320
- tapps_agents/core/evaluation_orchestrator.py +225 -225
- tapps_agents/core/evaluators/__init__.py +7 -7
- tapps_agents/core/evaluators/architectural_evaluator.py +205 -205
- tapps_agents/core/evaluators/behavioral_evaluator.py +160 -160
- tapps_agents/core/evaluators/performance_profile_evaluator.py +160 -160
- tapps_agents/core/evaluators/security_posture_evaluator.py +148 -148
- tapps_agents/core/evaluators/spec_compliance_evaluator.py +181 -181
- tapps_agents/core/exceptions.py +107 -107
- tapps_agents/core/expert_config_generator.py +293 -293
- tapps_agents/core/export_schema.py +202 -202
- tapps_agents/core/external_feedback_models.py +102 -102
- tapps_agents/core/external_feedback_storage.py +213 -213
- tapps_agents/core/fallback_strategy.py +314 -314
- tapps_agents/core/feedback_analyzer.py +162 -162
- tapps_agents/core/feedback_collector.py +178 -178
- tapps_agents/core/git_operations.py +445 -445
- tapps_agents/core/hardware_profiler.py +151 -151
- tapps_agents/core/instructions.py +324 -324
- tapps_agents/core/io_guardrails.py +69 -69
- tapps_agents/core/issue_manifest.py +249 -249
- tapps_agents/core/issue_schema.py +139 -139
- tapps_agents/core/json_utils.py +128 -128
- tapps_agents/core/knowledge_graph.py +446 -446
- tapps_agents/core/language_detector.py +296 -296
- tapps_agents/core/learning_confidence.py +242 -242
- tapps_agents/core/learning_dashboard.py +246 -246
- tapps_agents/core/learning_decision.py +384 -384
- tapps_agents/core/learning_explainability.py +578 -578
- tapps_agents/core/learning_export.py +287 -287
- tapps_agents/core/learning_integration.py +228 -228
- tapps_agents/core/llm_behavior.py +232 -232
- tapps_agents/core/long_duration_support.py +786 -786
- tapps_agents/core/mcp_setup.py +106 -106
- tapps_agents/core/memory_integration.py +396 -396
- tapps_agents/core/meta_learning.py +666 -666
- tapps_agents/core/module_path_sanitizer.py +199 -199
- tapps_agents/core/multi_agent_orchestrator.py +382 -382
- tapps_agents/core/network_errors.py +125 -125
- tapps_agents/core/nfr_validator.py +336 -336
- tapps_agents/core/offline_mode.py +158 -158
- tapps_agents/core/output_contracts.py +300 -300
- tapps_agents/core/output_formatter.py +300 -300
- tapps_agents/core/path_normalizer.py +174 -174
- tapps_agents/core/path_validator.py +322 -322
- tapps_agents/core/pattern_library.py +250 -250
- tapps_agents/core/performance_benchmark.py +301 -301
- tapps_agents/core/performance_monitor.py +184 -184
- tapps_agents/core/playwright_mcp_controller.py +771 -771
- tapps_agents/core/policy_loader.py +135 -135
- tapps_agents/core/progress.py +166 -166
- tapps_agents/core/project_profile.py +354 -354
- tapps_agents/core/project_type_detector.py +454 -454
- tapps_agents/core/prompt_base.py +223 -223
- tapps_agents/core/prompt_learning/__init__.py +2 -2
- tapps_agents/core/prompt_learning/learning_loop.py +24 -24
- tapps_agents/core/prompt_learning/project_prompt_store.py +25 -25
- tapps_agents/core/prompt_learning/skills_prompt_analyzer.py +35 -35
- tapps_agents/core/prompt_optimization/__init__.py +6 -6
- tapps_agents/core/prompt_optimization/ab_tester.py +114 -114
- tapps_agents/core/prompt_optimization/correlation_analyzer.py +160 -160
- tapps_agents/core/prompt_optimization/progressive_refiner.py +129 -129
- tapps_agents/core/prompt_optimization/prompt_library.py +37 -37
- tapps_agents/core/requirements_evaluator.py +431 -431
- tapps_agents/core/resource_aware_executor.py +449 -449
- tapps_agents/core/resource_monitor.py +343 -343
- tapps_agents/core/resume_handler.py +298 -298
- tapps_agents/core/retry_handler.py +197 -197
- tapps_agents/core/review_checklists.py +479 -479
- tapps_agents/core/role_loader.py +201 -201
- tapps_agents/core/role_template_loader.py +201 -201
- tapps_agents/core/runtime_mode.py +60 -60
- tapps_agents/core/security_scanner.py +342 -342
- tapps_agents/core/skill_agent_registry.py +194 -194
- tapps_agents/core/skill_integration.py +208 -208
- tapps_agents/core/skill_loader.py +492 -492
- tapps_agents/core/skill_template.py +341 -341
- tapps_agents/core/skill_validator.py +478 -478
- tapps_agents/core/stack_analyzer.py +35 -35
- tapps_agents/core/startup.py +174 -174
- tapps_agents/core/storage_manager.py +397 -397
- tapps_agents/core/storage_models.py +166 -166
- tapps_agents/core/story_evaluator.py +410 -410
- tapps_agents/core/subprocess_utils.py +170 -170
- tapps_agents/core/task_duration.py +296 -296
- tapps_agents/core/task_memory.py +582 -582
- tapps_agents/core/task_state.py +226 -226
- tapps_agents/core/tech_stack_priorities.py +208 -208
- tapps_agents/core/temp_directory.py +194 -194
- tapps_agents/core/template_merger.py +600 -600
- tapps_agents/core/template_selector.py +280 -280
- tapps_agents/core/test_generator.py +286 -286
- tapps_agents/core/tiered_context.py +253 -253
- tapps_agents/core/token_monitor.py +345 -345
- tapps_agents/core/traceability.py +254 -254
- tapps_agents/core/trajectory_tracker.py +50 -50
- tapps_agents/core/unicode_safe.py +143 -143
- tapps_agents/core/unified_cache_config.py +170 -170
- tapps_agents/core/unified_state.py +324 -324
- tapps_agents/core/validate_cursor_setup.py +237 -237
- tapps_agents/core/validation_registry.py +136 -136
- tapps_agents/core/validators/__init__.py +4 -4
- tapps_agents/core/validators/python_validator.py +87 -87
- tapps_agents/core/verification_agent.py +90 -90
- tapps_agents/core/visual_feedback.py +644 -644
- tapps_agents/core/workflow_validator.py +197 -197
- tapps_agents/core/worktree.py +367 -367
- tapps_agents/docker/__init__.py +10 -10
- tapps_agents/docker/analyzer.py +186 -186
- tapps_agents/docker/debugger.py +229 -229
- tapps_agents/docker/error_patterns.py +216 -216
- tapps_agents/epic/__init__.py +22 -22
- tapps_agents/epic/beads_sync.py +115 -115
- tapps_agents/epic/markdown_sync.py +105 -105
- tapps_agents/epic/models.py +96 -96
- tapps_agents/experts/__init__.py +163 -163
- tapps_agents/experts/agent_integration.py +243 -243
- tapps_agents/experts/auto_generator.py +331 -331
- tapps_agents/experts/base_expert.py +536 -536
- tapps_agents/experts/builtin_registry.py +261 -261
- tapps_agents/experts/business_metrics.py +565 -565
- tapps_agents/experts/cache.py +266 -266
- tapps_agents/experts/confidence_breakdown.py +306 -306
- tapps_agents/experts/confidence_calculator.py +336 -336
- tapps_agents/experts/confidence_metrics.py +236 -236
- tapps_agents/experts/domain_config.py +311 -311
- tapps_agents/experts/domain_detector.py +550 -550
- tapps_agents/experts/domain_utils.py +84 -84
- tapps_agents/experts/expert_config.py +113 -113
- tapps_agents/experts/expert_engine.py +465 -465
- tapps_agents/experts/expert_registry.py +744 -744
- tapps_agents/experts/expert_synthesizer.py +70 -70
- tapps_agents/experts/governance.py +197 -197
- tapps_agents/experts/history_logger.py +312 -312
- tapps_agents/experts/knowledge/README.md +180 -180
- tapps_agents/experts/knowledge/accessibility/accessible-forms.md +331 -331
- tapps_agents/experts/knowledge/accessibility/aria-patterns.md +344 -344
- tapps_agents/experts/knowledge/accessibility/color-contrast.md +285 -285
- tapps_agents/experts/knowledge/accessibility/keyboard-navigation.md +332 -332
- tapps_agents/experts/knowledge/accessibility/screen-readers.md +282 -282
- tapps_agents/experts/knowledge/accessibility/semantic-html.md +355 -355
- tapps_agents/experts/knowledge/accessibility/testing-accessibility.md +369 -369
- tapps_agents/experts/knowledge/accessibility/wcag-2.1.md +296 -296
- tapps_agents/experts/knowledge/accessibility/wcag-2.2.md +211 -211
- tapps_agents/experts/knowledge/agent-learning/best-practices.md +715 -715
- tapps_agents/experts/knowledge/agent-learning/pattern-extraction.md +282 -282
- tapps_agents/experts/knowledge/agent-learning/prompt-optimization.md +320 -320
- tapps_agents/experts/knowledge/ai-frameworks/model-optimization.md +90 -90
- tapps_agents/experts/knowledge/ai-frameworks/openvino-patterns.md +260 -260
- tapps_agents/experts/knowledge/api-design-integration/api-gateway-patterns.md +309 -309
- tapps_agents/experts/knowledge/api-design-integration/api-security-patterns.md +521 -521
- tapps_agents/experts/knowledge/api-design-integration/api-versioning.md +421 -421
- tapps_agents/experts/knowledge/api-design-integration/async-protocol-patterns.md +61 -61
- tapps_agents/experts/knowledge/api-design-integration/contract-testing.md +221 -221
- tapps_agents/experts/knowledge/api-design-integration/external-api-integration.md +489 -489
- tapps_agents/experts/knowledge/api-design-integration/fastapi-patterns.md +360 -360
- tapps_agents/experts/knowledge/api-design-integration/fastapi-testing.md +262 -262
- tapps_agents/experts/knowledge/api-design-integration/graphql-patterns.md +582 -582
- tapps_agents/experts/knowledge/api-design-integration/grpc-best-practices.md +499 -499
- tapps_agents/experts/knowledge/api-design-integration/mqtt-patterns.md +455 -455
- tapps_agents/experts/knowledge/api-design-integration/rate-limiting.md +507 -507
- tapps_agents/experts/knowledge/api-design-integration/restful-api-design.md +618 -618
- tapps_agents/experts/knowledge/api-design-integration/websocket-patterns.md +480 -480
- tapps_agents/experts/knowledge/cloud-infrastructure/cloud-native-patterns.md +175 -175
- tapps_agents/experts/knowledge/cloud-infrastructure/container-health-checks.md +261 -261
- tapps_agents/experts/knowledge/cloud-infrastructure/containerization.md +222 -222
- tapps_agents/experts/knowledge/cloud-infrastructure/cost-optimization.md +122 -122
- tapps_agents/experts/knowledge/cloud-infrastructure/disaster-recovery.md +153 -153
- tapps_agents/experts/knowledge/cloud-infrastructure/dockerfile-patterns.md +285 -285
- tapps_agents/experts/knowledge/cloud-infrastructure/infrastructure-as-code.md +187 -187
- tapps_agents/experts/knowledge/cloud-infrastructure/kubernetes-patterns.md +253 -253
- tapps_agents/experts/knowledge/cloud-infrastructure/multi-cloud-strategies.md +155 -155
- tapps_agents/experts/knowledge/cloud-infrastructure/serverless-architecture.md +200 -200
- tapps_agents/experts/knowledge/code-quality-analysis/README.md +16 -16
- tapps_agents/experts/knowledge/code-quality-analysis/code-metrics.md +137 -137
- tapps_agents/experts/knowledge/code-quality-analysis/complexity-analysis.md +181 -181
- tapps_agents/experts/knowledge/code-quality-analysis/technical-debt-patterns.md +191 -191
- tapps_agents/experts/knowledge/data-privacy-compliance/anonymization.md +313 -313
- tapps_agents/experts/knowledge/data-privacy-compliance/ccpa.md +255 -255
- tapps_agents/experts/knowledge/data-privacy-compliance/consent-management.md +282 -282
- tapps_agents/experts/knowledge/data-privacy-compliance/data-minimization.md +275 -275
- tapps_agents/experts/knowledge/data-privacy-compliance/data-retention.md +297 -297
- tapps_agents/experts/knowledge/data-privacy-compliance/data-subject-rights.md +383 -383
- tapps_agents/experts/knowledge/data-privacy-compliance/encryption-privacy.md +285 -285
- tapps_agents/experts/knowledge/data-privacy-compliance/gdpr.md +344 -344
- tapps_agents/experts/knowledge/data-privacy-compliance/hipaa.md +385 -385
- tapps_agents/experts/knowledge/data-privacy-compliance/privacy-by-design.md +280 -280
- tapps_agents/experts/knowledge/database-data-management/acid-vs-cap.md +164 -164
- tapps_agents/experts/knowledge/database-data-management/backup-and-recovery.md +182 -182
- tapps_agents/experts/knowledge/database-data-management/data-modeling.md +172 -172
- tapps_agents/experts/knowledge/database-data-management/database-design.md +187 -187
- tapps_agents/experts/knowledge/database-data-management/flux-query-optimization.md +342 -342
- tapps_agents/experts/knowledge/database-data-management/influxdb-connection-patterns.md +432 -432
- tapps_agents/experts/knowledge/database-data-management/influxdb-patterns.md +442 -442
- tapps_agents/experts/knowledge/database-data-management/migration-strategies.md +216 -216
- tapps_agents/experts/knowledge/database-data-management/nosql-patterns.md +259 -259
- tapps_agents/experts/knowledge/database-data-management/scalability-patterns.md +184 -184
- tapps_agents/experts/knowledge/database-data-management/sql-optimization.md +175 -175
- tapps_agents/experts/knowledge/database-data-management/time-series-modeling.md +444 -444
- tapps_agents/experts/knowledge/development-workflow/README.md +16 -16
- tapps_agents/experts/knowledge/development-workflow/automation-best-practices.md +216 -216
- tapps_agents/experts/knowledge/development-workflow/build-strategies.md +198 -198
- tapps_agents/experts/knowledge/development-workflow/deployment-patterns.md +205 -205
- tapps_agents/experts/knowledge/development-workflow/git-workflows.md +205 -205
- tapps_agents/experts/knowledge/documentation-knowledge-management/README.md +16 -16
- tapps_agents/experts/knowledge/documentation-knowledge-management/api-documentation-patterns.md +231 -231
- tapps_agents/experts/knowledge/documentation-knowledge-management/documentation-standards.md +191 -191
- tapps_agents/experts/knowledge/documentation-knowledge-management/knowledge-management.md +171 -171
- tapps_agents/experts/knowledge/documentation-knowledge-management/technical-writing-guide.md +192 -192
- tapps_agents/experts/knowledge/observability-monitoring/alerting-patterns.md +461 -461
- tapps_agents/experts/knowledge/observability-monitoring/apm-tools.md +459 -459
- tapps_agents/experts/knowledge/observability-monitoring/distributed-tracing.md +367 -367
- tapps_agents/experts/knowledge/observability-monitoring/logging-strategies.md +478 -478
- tapps_agents/experts/knowledge/observability-monitoring/metrics-and-monitoring.md +510 -510
- tapps_agents/experts/knowledge/observability-monitoring/observability-best-practices.md +492 -492
- tapps_agents/experts/knowledge/observability-monitoring/open-telemetry.md +573 -573
- tapps_agents/experts/knowledge/observability-monitoring/slo-sli-sla.md +419 -419
- tapps_agents/experts/knowledge/performance/anti-patterns.md +284 -284
- tapps_agents/experts/knowledge/performance/api-performance.md +256 -256
- tapps_agents/experts/knowledge/performance/caching.md +327 -327
- tapps_agents/experts/knowledge/performance/database-performance.md +252 -252
- tapps_agents/experts/knowledge/performance/optimization-patterns.md +327 -327
- tapps_agents/experts/knowledge/performance/profiling.md +297 -297
- tapps_agents/experts/knowledge/performance/resource-management.md +293 -293
- tapps_agents/experts/knowledge/performance/scalability.md +306 -306
- tapps_agents/experts/knowledge/security/owasp-top10.md +209 -209
- tapps_agents/experts/knowledge/security/secure-coding-practices.md +207 -207
- tapps_agents/experts/knowledge/security/threat-modeling.md +220 -220
- tapps_agents/experts/knowledge/security/vulnerability-patterns.md +342 -342
- tapps_agents/experts/knowledge/software-architecture/docker-compose-patterns.md +314 -314
- tapps_agents/experts/knowledge/software-architecture/microservices-patterns.md +379 -379
- tapps_agents/experts/knowledge/software-architecture/service-communication.md +316 -316
- tapps_agents/experts/knowledge/testing/best-practices.md +310 -310
- tapps_agents/experts/knowledge/testing/coverage-analysis.md +293 -293
- tapps_agents/experts/knowledge/testing/mocking.md +256 -256
- tapps_agents/experts/knowledge/testing/test-automation.md +276 -276
- tapps_agents/experts/knowledge/testing/test-data.md +271 -271
- tapps_agents/experts/knowledge/testing/test-design-patterns.md +280 -280
- tapps_agents/experts/knowledge/testing/test-maintenance.md +236 -236
- tapps_agents/experts/knowledge/testing/test-strategies.md +311 -311
- tapps_agents/experts/knowledge/user-experience/information-architecture.md +325 -325
- tapps_agents/experts/knowledge/user-experience/interaction-design.md +363 -363
- tapps_agents/experts/knowledge/user-experience/prototyping.md +293 -293
- tapps_agents/experts/knowledge/user-experience/usability-heuristics.md +337 -337
- tapps_agents/experts/knowledge/user-experience/usability-testing.md +311 -311
- tapps_agents/experts/knowledge/user-experience/user-journeys.md +296 -296
- tapps_agents/experts/knowledge/user-experience/user-research.md +373 -373
- tapps_agents/experts/knowledge/user-experience/ux-principles.md +340 -340
- tapps_agents/experts/knowledge_freshness.py +321 -321
- tapps_agents/experts/knowledge_ingestion.py +438 -438
- tapps_agents/experts/knowledge_need_detector.py +93 -93
- tapps_agents/experts/knowledge_validator.py +382 -382
- tapps_agents/experts/observability.py +440 -440
- tapps_agents/experts/passive_notifier.py +238 -238
- tapps_agents/experts/proactive_orchestrator.py +32 -32
- tapps_agents/experts/rag_chunker.py +205 -205
- tapps_agents/experts/rag_embedder.py +152 -152
- tapps_agents/experts/rag_evaluation.py +299 -299
- tapps_agents/experts/rag_index.py +303 -303
- tapps_agents/experts/rag_metrics.py +293 -293
- tapps_agents/experts/rag_safety.py +263 -263
- tapps_agents/experts/report_generator.py +296 -296
- tapps_agents/experts/setup_wizard.py +441 -441
- tapps_agents/experts/simple_rag.py +431 -431
- tapps_agents/experts/vector_rag.py +354 -354
- tapps_agents/experts/weight_distributor.py +304 -304
- tapps_agents/health/__init__.py +24 -24
- tapps_agents/health/base.py +75 -75
- tapps_agents/health/checks/__init__.py +22 -22
- tapps_agents/health/checks/automation.py +127 -127
- tapps_agents/health/checks/context7_cache.py +210 -210
- tapps_agents/health/checks/environment.py +116 -116
- tapps_agents/health/checks/execution.py +170 -170
- tapps_agents/health/checks/knowledge_base.py +187 -187
- tapps_agents/health/checks/outcomes.py +324 -324
- tapps_agents/health/collector.py +280 -280
- tapps_agents/health/dashboard.py +137 -137
- tapps_agents/health/metrics.py +151 -151
- tapps_agents/health/orchestrator.py +271 -271
- tapps_agents/health/registry.py +166 -166
- tapps_agents/hooks/__init__.py +33 -33
- tapps_agents/hooks/config.py +140 -140
- tapps_agents/hooks/events.py +135 -135
- tapps_agents/hooks/executor.py +128 -128
- tapps_agents/hooks/manager.py +143 -143
- tapps_agents/integration/__init__.py +8 -8
- tapps_agents/integration/service_integrator.py +121 -121
- tapps_agents/integrations/__init__.py +10 -10
- tapps_agents/integrations/clawdbot.py +525 -525
- tapps_agents/integrations/memory_bridge.py +356 -356
- tapps_agents/mcp/__init__.py +18 -18
- tapps_agents/mcp/gateway.py +112 -112
- tapps_agents/mcp/servers/__init__.py +13 -13
- tapps_agents/mcp/servers/analysis.py +204 -204
- tapps_agents/mcp/servers/context7.py +198 -198
- tapps_agents/mcp/servers/filesystem.py +218 -218
- tapps_agents/mcp/servers/git.py +201 -201
- tapps_agents/mcp/tool_registry.py +115 -115
- tapps_agents/quality/__init__.py +54 -54
- tapps_agents/quality/coverage_analyzer.py +379 -379
- tapps_agents/quality/enforcement.py +82 -82
- tapps_agents/quality/gates/__init__.py +37 -37
- tapps_agents/quality/gates/approval_gate.py +255 -255
- tapps_agents/quality/gates/base.py +84 -84
- tapps_agents/quality/gates/exceptions.py +43 -43
- tapps_agents/quality/gates/policy_gate.py +195 -195
- tapps_agents/quality/gates/registry.py +239 -239
- tapps_agents/quality/gates/security_gate.py +156 -156
- tapps_agents/quality/quality_gates.py +369 -369
- tapps_agents/quality/secret_scanner.py +335 -335
- tapps_agents/session/__init__.py +19 -19
- tapps_agents/session/manager.py +256 -256
- tapps_agents/simple_mode/__init__.py +66 -66
- tapps_agents/simple_mode/agent_contracts.py +357 -357
- tapps_agents/simple_mode/beads_hooks.py +151 -151
- tapps_agents/simple_mode/code_snippet_handler.py +382 -382
- tapps_agents/simple_mode/documentation_manager.py +395 -395
- tapps_agents/simple_mode/documentation_reader.py +187 -187
- tapps_agents/simple_mode/file_inference.py +292 -292
- tapps_agents/simple_mode/framework_change_detector.py +268 -268
- tapps_agents/simple_mode/intent_parser.py +510 -510
- tapps_agents/simple_mode/learning_progression.py +358 -358
- tapps_agents/simple_mode/nl_handler.py +700 -700
- tapps_agents/simple_mode/onboarding.py +253 -253
- tapps_agents/simple_mode/orchestrators/__init__.py +38 -38
- tapps_agents/simple_mode/orchestrators/base.py +185 -185
- tapps_agents/simple_mode/orchestrators/breakdown_orchestrator.py +49 -49
- tapps_agents/simple_mode/orchestrators/brownfield_orchestrator.py +135 -135
- tapps_agents/simple_mode/orchestrators/build_orchestrator.py +2700 -2667
- tapps_agents/simple_mode/orchestrators/deliverable_checklist.py +349 -349
- tapps_agents/simple_mode/orchestrators/enhance_orchestrator.py +53 -53
- tapps_agents/simple_mode/orchestrators/epic_orchestrator.py +122 -122
- tapps_agents/simple_mode/orchestrators/explore_orchestrator.py +184 -184
- tapps_agents/simple_mode/orchestrators/fix_orchestrator.py +723 -723
- tapps_agents/simple_mode/orchestrators/plan_analysis_orchestrator.py +206 -206
- tapps_agents/simple_mode/orchestrators/pr_orchestrator.py +237 -237
- tapps_agents/simple_mode/orchestrators/refactor_orchestrator.py +222 -222
- tapps_agents/simple_mode/orchestrators/requirements_tracer.py +262 -262
- tapps_agents/simple_mode/orchestrators/resume_orchestrator.py +210 -210
- tapps_agents/simple_mode/orchestrators/review_orchestrator.py +161 -161
- tapps_agents/simple_mode/orchestrators/test_orchestrator.py +82 -82
- tapps_agents/simple_mode/output_aggregator.py +340 -340
- tapps_agents/simple_mode/result_formatters.py +598 -598
- tapps_agents/simple_mode/step_dependencies.py +382 -382
- tapps_agents/simple_mode/step_results.py +276 -276
- tapps_agents/simple_mode/streaming.py +388 -388
- tapps_agents/simple_mode/variations.py +129 -129
- tapps_agents/simple_mode/visual_feedback.py +238 -238
- tapps_agents/simple_mode/zero_config.py +274 -274
- tapps_agents/suggestions/__init__.py +8 -8
- tapps_agents/suggestions/inline_suggester.py +52 -52
- tapps_agents/templates/__init__.py +8 -8
- tapps_agents/templates/microservice_generator.py +274 -274
- tapps_agents/utils/env_validator.py +291 -291
- tapps_agents/workflow/__init__.py +171 -171
- tapps_agents/workflow/acceptance_verifier.py +132 -132
- tapps_agents/workflow/agent_handlers/__init__.py +41 -41
- tapps_agents/workflow/agent_handlers/analyst_handler.py +75 -75
- tapps_agents/workflow/agent_handlers/architect_handler.py +107 -107
- tapps_agents/workflow/agent_handlers/base.py +84 -84
- tapps_agents/workflow/agent_handlers/debugger_handler.py +100 -100
- tapps_agents/workflow/agent_handlers/designer_handler.py +110 -110
- tapps_agents/workflow/agent_handlers/documenter_handler.py +94 -94
- tapps_agents/workflow/agent_handlers/implementer_handler.py +235 -235
- tapps_agents/workflow/agent_handlers/ops_handler.py +62 -62
- tapps_agents/workflow/agent_handlers/orchestrator_handler.py +43 -43
- tapps_agents/workflow/agent_handlers/planner_handler.py +98 -98
- tapps_agents/workflow/agent_handlers/registry.py +119 -119
- tapps_agents/workflow/agent_handlers/reviewer_handler.py +119 -119
- tapps_agents/workflow/agent_handlers/tester_handler.py +69 -69
- tapps_agents/workflow/analytics_accessor.py +337 -337
- tapps_agents/workflow/analytics_alerts.py +416 -416
- tapps_agents/workflow/analytics_dashboard_cursor.py +281 -281
- tapps_agents/workflow/analytics_dual_write.py +103 -103
- tapps_agents/workflow/analytics_integration.py +119 -119
- tapps_agents/workflow/analytics_query_parser.py +278 -278
- tapps_agents/workflow/analytics_visualizer.py +259 -259
- tapps_agents/workflow/artifact_helper.py +204 -204
- tapps_agents/workflow/audit_logger.py +263 -263
- tapps_agents/workflow/auto_execution_config.py +340 -340
- tapps_agents/workflow/auto_progression.py +586 -586
- tapps_agents/workflow/branch_cleanup.py +349 -349
- tapps_agents/workflow/checkpoint.py +256 -256
- tapps_agents/workflow/checkpoint_manager.py +178 -178
- tapps_agents/workflow/code_artifact.py +179 -179
- tapps_agents/workflow/common_enums.py +96 -96
- tapps_agents/workflow/confirmation_handler.py +130 -130
- tapps_agents/workflow/context_analyzer.py +222 -222
- tapps_agents/workflow/context_artifact.py +230 -230
- tapps_agents/workflow/cursor_chat.py +94 -94
- tapps_agents/workflow/cursor_executor.py +2337 -2196
- tapps_agents/workflow/cursor_skill_helper.py +516 -516
- tapps_agents/workflow/dependency_resolver.py +244 -244
- tapps_agents/workflow/design_artifact.py +156 -156
- tapps_agents/workflow/detector.py +751 -751
- tapps_agents/workflow/direct_execution_fallback.py +301 -301
- tapps_agents/workflow/docs_artifact.py +168 -168
- tapps_agents/workflow/enforcer.py +389 -389
- tapps_agents/workflow/enhancement_artifact.py +142 -142
- tapps_agents/workflow/error_recovery.py +806 -806
- tapps_agents/workflow/event_bus.py +183 -183
- tapps_agents/workflow/event_log.py +612 -612
- tapps_agents/workflow/events.py +63 -63
- tapps_agents/workflow/exceptions.py +43 -43
- tapps_agents/workflow/execution_graph.py +498 -498
- tapps_agents/workflow/execution_plan.py +126 -126
- tapps_agents/workflow/file_utils.py +186 -186
- tapps_agents/workflow/gate_evaluator.py +182 -182
- tapps_agents/workflow/gate_integration.py +200 -200
- tapps_agents/workflow/graph_visualizer.py +130 -130
- tapps_agents/workflow/health_checker.py +206 -206
- tapps_agents/workflow/logging_helper.py +243 -243
- tapps_agents/workflow/manifest.py +582 -582
- tapps_agents/workflow/marker_writer.py +250 -250
- tapps_agents/workflow/message_formatter.py +188 -188
- tapps_agents/workflow/messaging.py +325 -325
- tapps_agents/workflow/metadata_models.py +91 -91
- tapps_agents/workflow/metrics_integration.py +226 -226
- tapps_agents/workflow/migration_utils.py +116 -116
- tapps_agents/workflow/models.py +148 -111
- tapps_agents/workflow/nlp_config.py +198 -198
- tapps_agents/workflow/nlp_error_handler.py +207 -207
- tapps_agents/workflow/nlp_executor.py +163 -163
- tapps_agents/workflow/nlp_parser.py +528 -528
- tapps_agents/workflow/observability_dashboard.py +451 -451
- tapps_agents/workflow/observer.py +170 -170
- tapps_agents/workflow/ops_artifact.py +257 -257
- tapps_agents/workflow/output_passing.py +214 -214
- tapps_agents/workflow/parallel_executor.py +463 -463
- tapps_agents/workflow/planning_artifact.py +179 -179
- tapps_agents/workflow/preset_loader.py +285 -285
- tapps_agents/workflow/preset_recommender.py +270 -270
- tapps_agents/workflow/progress_logger.py +145 -145
- tapps_agents/workflow/progress_manager.py +303 -303
- tapps_agents/workflow/progress_monitor.py +186 -186
- tapps_agents/workflow/progress_updates.py +423 -423
- tapps_agents/workflow/quality_artifact.py +158 -158
- tapps_agents/workflow/quality_loopback.py +101 -101
- tapps_agents/workflow/recommender.py +387 -387
- tapps_agents/workflow/remediation_loop.py +166 -166
- tapps_agents/workflow/result_aggregator.py +300 -300
- tapps_agents/workflow/review_artifact.py +185 -185
- tapps_agents/workflow/schema_validator.py +522 -522
- tapps_agents/workflow/session_handoff.py +178 -178
- tapps_agents/workflow/skill_invoker.py +648 -648
- tapps_agents/workflow/state_manager.py +756 -756
- tapps_agents/workflow/state_persistence_config.py +331 -331
- tapps_agents/workflow/status_monitor.py +449 -449
- tapps_agents/workflow/step_checkpoint.py +314 -314
- tapps_agents/workflow/step_details.py +201 -201
- tapps_agents/workflow/story_models.py +147 -147
- tapps_agents/workflow/streaming.py +416 -416
- tapps_agents/workflow/suggestion_engine.py +552 -552
- tapps_agents/workflow/testing_artifact.py +186 -186
- tapps_agents/workflow/timeline.py +158 -158
- tapps_agents/workflow/token_integration.py +209 -209
- tapps_agents/workflow/validation.py +217 -217
- tapps_agents/workflow/visual_feedback.py +391 -391
- tapps_agents/workflow/workflow_chain.py +95 -95
- tapps_agents/workflow/workflow_summary.py +219 -219
- tapps_agents/workflow/worktree_manager.py +724 -724
- {tapps_agents-3.5.40.dist-info → tapps_agents-3.6.0.dist-info}/METADATA +672 -672
- tapps_agents-3.6.0.dist-info/RECORD +758 -0
- {tapps_agents-3.5.40.dist-info → tapps_agents-3.6.0.dist-info}/licenses/LICENSE +22 -22
- tapps_agents/health/checks/outcomes.backup_20260204_064058.py +0 -324
- tapps_agents/health/checks/outcomes.backup_20260204_064256.py +0 -324
- tapps_agents/health/checks/outcomes.backup_20260204_064600.py +0 -324
- tapps_agents-3.5.40.dist-info/RECORD +0 -760
- {tapps_agents-3.5.40.dist-info → tapps_agents-3.6.0.dist-info}/WHEEL +0 -0
- {tapps_agents-3.5.40.dist-info → tapps_agents-3.6.0.dist-info}/entry_points.txt +0 -0
- {tapps_agents-3.5.40.dist-info → tapps_agents-3.6.0.dist-info}/top_level.txt +0 -0
|
@@ -1,448 +1,448 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Batch Review Workflow - Review multiple services in parallel
|
|
3
|
-
|
|
4
|
-
Phase 4.2: Batch Review Workflow
|
|
5
|
-
|
|
6
|
-
Uses asyncio.TaskGroup for parallel execution following ParallelStepExecutor patterns.
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
from __future__ import annotations
|
|
10
|
-
|
|
11
|
-
import asyncio
|
|
12
|
-
import logging
|
|
13
|
-
import sys
|
|
14
|
-
from pathlib import Path
|
|
15
|
-
from typing import Any
|
|
16
|
-
|
|
17
|
-
from pydantic import BaseModel, Field
|
|
18
|
-
|
|
19
|
-
from ...core.config import ProjectConfig
|
|
20
|
-
from ...core.language_detector import Language
|
|
21
|
-
from .agent import ReviewerAgent
|
|
22
|
-
from .service_discovery import Service
|
|
23
|
-
|
|
24
|
-
logger = logging.getLogger(__name__)
|
|
25
|
-
|
|
26
|
-
# Default timeout for service review (5 minutes)
|
|
27
|
-
DEFAULT_REVIEW_TIMEOUT = 300.0
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class ServiceReviewResult(BaseModel):
|
|
31
|
-
"""Result of reviewing a single service."""
|
|
32
|
-
|
|
33
|
-
service_name: str
|
|
34
|
-
service_path: str
|
|
35
|
-
language: str
|
|
36
|
-
passed: bool
|
|
37
|
-
overall_score: float
|
|
38
|
-
scores: dict[str, float] = Field(default_factory=dict)
|
|
39
|
-
error: str | None = None
|
|
40
|
-
review_details: dict[str, Any] = Field(default_factory=dict)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
class BatchReviewResult(BaseModel):
|
|
44
|
-
"""Result of batch review workflow."""
|
|
45
|
-
|
|
46
|
-
services_reviewed: int
|
|
47
|
-
passed: int
|
|
48
|
-
failed: int
|
|
49
|
-
average_score: float
|
|
50
|
-
results: list[ServiceReviewResult] = Field(default_factory=list)
|
|
51
|
-
errors: list[str] = Field(default_factory=list)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
class BatchReviewWorkflow:
|
|
55
|
-
"""
|
|
56
|
-
Batch review workflow for reviewing multiple services.
|
|
57
|
-
|
|
58
|
-
Phase 4.2: Batch Review Workflow
|
|
59
|
-
Uses asyncio.TaskGroup for parallel execution (Python 3.11+).
|
|
60
|
-
"""
|
|
61
|
-
|
|
62
|
-
def __init__(
|
|
63
|
-
self,
|
|
64
|
-
config: ProjectConfig | None = None,
|
|
65
|
-
project_root: Path | None = None,
|
|
66
|
-
max_parallel: int = 4,
|
|
67
|
-
review_timeout: float = DEFAULT_REVIEW_TIMEOUT,
|
|
68
|
-
):
|
|
69
|
-
"""
|
|
70
|
-
Initialize batch review workflow.
|
|
71
|
-
|
|
72
|
-
Args:
|
|
73
|
-
config: Optional project configuration
|
|
74
|
-
project_root: Optional project root directory
|
|
75
|
-
max_parallel: Maximum number of parallel reviews (default: 4)
|
|
76
|
-
review_timeout: Timeout in seconds for single service review (default: 300.0)
|
|
77
|
-
"""
|
|
78
|
-
self.config = config
|
|
79
|
-
self.project_root = project_root or Path.cwd()
|
|
80
|
-
self.max_parallel = max_parallel
|
|
81
|
-
self.review_timeout = review_timeout
|
|
82
|
-
|
|
83
|
-
async def review_services(
|
|
84
|
-
self,
|
|
85
|
-
services: list[Service],
|
|
86
|
-
parallel: bool = True,
|
|
87
|
-
include_scoring: bool = True,
|
|
88
|
-
include_llm_feedback: bool = True,
|
|
89
|
-
) -> BatchReviewResult:
|
|
90
|
-
"""
|
|
91
|
-
Review multiple services in parallel or sequentially.
|
|
92
|
-
|
|
93
|
-
Phase 4.2: Batch Review with Parallel Execution
|
|
94
|
-
|
|
95
|
-
Args:
|
|
96
|
-
services: List of Service objects to review
|
|
97
|
-
parallel: Whether to execute reviews in parallel (default: True)
|
|
98
|
-
include_scoring: Whether to include code quality scoring
|
|
99
|
-
include_llm_feedback: Whether to include LLM feedback
|
|
100
|
-
|
|
101
|
-
Returns:
|
|
102
|
-
BatchReviewResult with aggregated results
|
|
103
|
-
"""
|
|
104
|
-
if not services:
|
|
105
|
-
return BatchReviewResult(
|
|
106
|
-
services_reviewed=0,
|
|
107
|
-
passed=0,
|
|
108
|
-
failed=0,
|
|
109
|
-
average_score=0.0,
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
if parallel:
|
|
113
|
-
return await self._review_services_parallel(
|
|
114
|
-
services, include_scoring, include_llm_feedback
|
|
115
|
-
)
|
|
116
|
-
else:
|
|
117
|
-
return await self._review_services_sequential(
|
|
118
|
-
services, include_scoring, include_llm_feedback
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
async def _review_services_parallel(
|
|
122
|
-
self,
|
|
123
|
-
services: list[Service],
|
|
124
|
-
include_scoring: bool,
|
|
125
|
-
include_llm_feedback: bool,
|
|
126
|
-
) -> BatchReviewResult:
|
|
127
|
-
"""
|
|
128
|
-
Review services in parallel using asyncio.TaskGroup.
|
|
129
|
-
|
|
130
|
-
Phase 4.2: Parallel Execution with TaskGroup
|
|
131
|
-
"""
|
|
132
|
-
results: list[ServiceReviewResult] = []
|
|
133
|
-
errors: list[str] = []
|
|
134
|
-
|
|
135
|
-
# Use TaskGroup for structured concurrency (Python 3.11+)
|
|
136
|
-
if sys.version_info >= (3, 11):
|
|
137
|
-
tasks_map: dict[asyncio.Task[ServiceReviewResult], Service] = {}
|
|
138
|
-
try:
|
|
139
|
-
async with asyncio.TaskGroup() as tg:
|
|
140
|
-
# Create tasks for all services
|
|
141
|
-
for service in services:
|
|
142
|
-
task = tg.create_task(
|
|
143
|
-
self._review_single_service(
|
|
144
|
-
service, include_scoring, include_llm_feedback
|
|
145
|
-
)
|
|
146
|
-
)
|
|
147
|
-
tasks_map[task] = service
|
|
148
|
-
|
|
149
|
-
# All tasks completed successfully - collect results
|
|
150
|
-
for task, service in tasks_map.items():
|
|
151
|
-
result = await task
|
|
152
|
-
results.append(result)
|
|
153
|
-
|
|
154
|
-
except* Exception as eg: # ExceptionGroup (Python 3.11+)
|
|
155
|
-
# Handle exception group from TaskGroup
|
|
156
|
-
# TaskGroup automatically cancels all tasks if any task raises an exception
|
|
157
|
-
for task, service in tasks_map.items():
|
|
158
|
-
if task.done():
|
|
159
|
-
try:
|
|
160
|
-
result = await task
|
|
161
|
-
results.append(result)
|
|
162
|
-
except Exception as e:
|
|
163
|
-
logger.error(
|
|
164
|
-
f"Exception in completed task for service {service.name}: {e}",
|
|
165
|
-
exc_info=True,
|
|
166
|
-
)
|
|
167
|
-
errors.append(f"{service.name}: {str(e)}")
|
|
168
|
-
results.append(
|
|
169
|
-
ServiceReviewResult(
|
|
170
|
-
service_name=service.name,
|
|
171
|
-
service_path=str(service.path),
|
|
172
|
-
language=service.language.value,
|
|
173
|
-
passed=False,
|
|
174
|
-
overall_score=0.0,
|
|
175
|
-
error=str(e),
|
|
176
|
-
)
|
|
177
|
-
)
|
|
178
|
-
else:
|
|
179
|
-
# Task was cancelled by TaskGroup
|
|
180
|
-
errors.append(f"{service.name}: Task cancelled")
|
|
181
|
-
results.append(
|
|
182
|
-
ServiceReviewResult(
|
|
183
|
-
service_name=service.name,
|
|
184
|
-
service_path=str(service.path),
|
|
185
|
-
language=service.language.value,
|
|
186
|
-
passed=False,
|
|
187
|
-
overall_score=0.0,
|
|
188
|
-
error="Task cancelled due to another service's failure",
|
|
189
|
-
)
|
|
190
|
-
)
|
|
191
|
-
|
|
192
|
-
# Add exception group errors
|
|
193
|
-
for exc in eg.exceptions:
|
|
194
|
-
logger.error(f"TaskGroup exception: {exc}", exc_info=True)
|
|
195
|
-
errors.append(f"TaskGroup error: {str(exc)}")
|
|
196
|
-
else:
|
|
197
|
-
# Fallback for Python < 3.11: use asyncio.gather with semaphore
|
|
198
|
-
semaphore = asyncio.Semaphore(self.max_parallel)
|
|
199
|
-
|
|
200
|
-
async def review_with_semaphore(service: Service) -> ServiceReviewResult:
|
|
201
|
-
async with semaphore:
|
|
202
|
-
return await self._review_single_service(
|
|
203
|
-
service, include_scoring, include_llm_feedback
|
|
204
|
-
)
|
|
205
|
-
|
|
206
|
-
tasks = [review_with_semaphore(service) for service in services]
|
|
207
|
-
gathered_results = await asyncio.gather(*tasks, return_exceptions=True)
|
|
208
|
-
|
|
209
|
-
for i, result in enumerate(gathered_results):
|
|
210
|
-
if isinstance(result, Exception):
|
|
211
|
-
service = services[i]
|
|
212
|
-
logger.error(
|
|
213
|
-
f"Exception during review for service {service.name}: {result}",
|
|
214
|
-
exc_info=True,
|
|
215
|
-
)
|
|
216
|
-
errors.append(f"{service.name}: {str(result)}")
|
|
217
|
-
results.append(
|
|
218
|
-
ServiceReviewResult(
|
|
219
|
-
service_name=service.name,
|
|
220
|
-
service_path=str(service.path),
|
|
221
|
-
language=service.language.value,
|
|
222
|
-
passed=False,
|
|
223
|
-
overall_score=0.0,
|
|
224
|
-
error=str(result),
|
|
225
|
-
)
|
|
226
|
-
)
|
|
227
|
-
else:
|
|
228
|
-
results.append(result)
|
|
229
|
-
|
|
230
|
-
return self._aggregate_results(results, errors)
|
|
231
|
-
|
|
232
|
-
async def _review_services_sequential(
|
|
233
|
-
self,
|
|
234
|
-
services: list[Service],
|
|
235
|
-
include_scoring: bool,
|
|
236
|
-
include_llm_feedback: bool,
|
|
237
|
-
) -> BatchReviewResult:
|
|
238
|
-
"""Review services sequentially."""
|
|
239
|
-
results: list[ServiceReviewResult] = []
|
|
240
|
-
errors: list[str] = []
|
|
241
|
-
|
|
242
|
-
for service in services:
|
|
243
|
-
try:
|
|
244
|
-
result = await self._review_single_service(
|
|
245
|
-
service, include_scoring, include_llm_feedback
|
|
246
|
-
)
|
|
247
|
-
results.append(result)
|
|
248
|
-
except Exception as e:
|
|
249
|
-
errors.append(f"{service.name}: {str(e)}")
|
|
250
|
-
results.append(
|
|
251
|
-
ServiceReviewResult(
|
|
252
|
-
service_name=service.name,
|
|
253
|
-
service_path=str(service.path),
|
|
254
|
-
language=service.language.value,
|
|
255
|
-
passed=False,
|
|
256
|
-
overall_score=0.0,
|
|
257
|
-
error=str(e),
|
|
258
|
-
)
|
|
259
|
-
)
|
|
260
|
-
|
|
261
|
-
return self._aggregate_results(results, errors)
|
|
262
|
-
|
|
263
|
-
async def _review_single_service(
|
|
264
|
-
self,
|
|
265
|
-
service: Service,
|
|
266
|
-
include_scoring: bool,
|
|
267
|
-
include_llm_feedback: bool,
|
|
268
|
-
) -> ServiceReviewResult:
|
|
269
|
-
"""
|
|
270
|
-
Review a single service.
|
|
271
|
-
|
|
272
|
-
Args:
|
|
273
|
-
service: Service to review
|
|
274
|
-
include_scoring: Whether to include scoring
|
|
275
|
-
include_llm_feedback: Whether to include LLM feedback
|
|
276
|
-
|
|
277
|
-
Returns:
|
|
278
|
-
ServiceReviewResult
|
|
279
|
-
"""
|
|
280
|
-
# Find main files in service directory to review
|
|
281
|
-
service_path = service.path
|
|
282
|
-
main_files = self._find_main_files(service_path, service.language)
|
|
283
|
-
|
|
284
|
-
if not main_files:
|
|
285
|
-
# No files to review, return neutral result
|
|
286
|
-
return ServiceReviewResult(
|
|
287
|
-
service_name=service.name,
|
|
288
|
-
service_path=str(service_path),
|
|
289
|
-
language=service.language.value,
|
|
290
|
-
passed=True,
|
|
291
|
-
overall_score=5.0, # Neutral score
|
|
292
|
-
review_details={"message": "No code files found to review"},
|
|
293
|
-
)
|
|
294
|
-
|
|
295
|
-
# Initialize reviewer agent
|
|
296
|
-
reviewer = ReviewerAgent(config=self.config)
|
|
297
|
-
try:
|
|
298
|
-
# Review first/main file as representative
|
|
299
|
-
# TODO: Could review multiple files and aggregate
|
|
300
|
-
main_file = main_files[0]
|
|
301
|
-
|
|
302
|
-
# Add timeout to prevent hanging
|
|
303
|
-
try:
|
|
304
|
-
review_result = await asyncio.wait_for(
|
|
305
|
-
reviewer.review_file(
|
|
306
|
-
main_file,
|
|
307
|
-
include_scoring=include_scoring,
|
|
308
|
-
include_llm_feedback=include_llm_feedback,
|
|
309
|
-
),
|
|
310
|
-
timeout=self.review_timeout,
|
|
311
|
-
)
|
|
312
|
-
except asyncio.TimeoutError:
|
|
313
|
-
logger.error(
|
|
314
|
-
f"Review timeout ({self.review_timeout}s) exceeded for service {service.name}"
|
|
315
|
-
)
|
|
316
|
-
return ServiceReviewResult(
|
|
317
|
-
service_name=service.name,
|
|
318
|
-
service_path=str(service_path),
|
|
319
|
-
language=service.language.value,
|
|
320
|
-
passed=False,
|
|
321
|
-
overall_score=0.0,
|
|
322
|
-
error=f"Review timeout after {self.review_timeout} seconds",
|
|
323
|
-
)
|
|
324
|
-
|
|
325
|
-
# Extract scores
|
|
326
|
-
scores = review_result.get("scores", {})
|
|
327
|
-
overall_score = scores.get("overall_score", 0.0)
|
|
328
|
-
|
|
329
|
-
# Determine pass/fail (threshold: 70.0)
|
|
330
|
-
threshold = 70.0
|
|
331
|
-
if self.config and self.config.scoring:
|
|
332
|
-
threshold = self.config.scoring.quality_threshold
|
|
333
|
-
|
|
334
|
-
passed = overall_score >= threshold
|
|
335
|
-
|
|
336
|
-
return ServiceReviewResult(
|
|
337
|
-
service_name=service.name,
|
|
338
|
-
service_path=str(service_path),
|
|
339
|
-
language=service.language.value,
|
|
340
|
-
passed=passed,
|
|
341
|
-
overall_score=overall_score,
|
|
342
|
-
scores={
|
|
343
|
-
"complexity": scores.get("complexity_score", 0.0),
|
|
344
|
-
"security": scores.get("security_score", 0.0),
|
|
345
|
-
"maintainability": scores.get("maintainability_score", 0.0),
|
|
346
|
-
"test_coverage": scores.get("test_coverage_score", 0.0),
|
|
347
|
-
"performance": scores.get("performance_score", 0.0),
|
|
348
|
-
},
|
|
349
|
-
review_details=review_result,
|
|
350
|
-
)
|
|
351
|
-
except Exception as e:
|
|
352
|
-
logger.error(
|
|
353
|
-
f"Exception during review for service {service.name}: {e}",
|
|
354
|
-
exc_info=True,
|
|
355
|
-
)
|
|
356
|
-
return ServiceReviewResult(
|
|
357
|
-
service_name=service.name,
|
|
358
|
-
service_path=str(service_path),
|
|
359
|
-
language=service.language.value,
|
|
360
|
-
passed=False,
|
|
361
|
-
overall_score=0.0,
|
|
362
|
-
error=str(e),
|
|
363
|
-
)
|
|
364
|
-
finally:
|
|
365
|
-
await reviewer.close()
|
|
366
|
-
|
|
367
|
-
def _find_main_files(self, service_path: Path, language: Language) -> list[Path]:
|
|
368
|
-
"""
|
|
369
|
-
Find main code files to review in a service directory.
|
|
370
|
-
|
|
371
|
-
Args:
|
|
372
|
-
service_path: Path to service directory
|
|
373
|
-
language: Primary language of the service
|
|
374
|
-
|
|
375
|
-
Returns:
|
|
376
|
-
List of main file paths to review
|
|
377
|
-
"""
|
|
378
|
-
main_files = []
|
|
379
|
-
|
|
380
|
-
# Language-specific file patterns
|
|
381
|
-
if language == Language.PYTHON:
|
|
382
|
-
# Look for __init__.py, main.py, app.py, or service entry points
|
|
383
|
-
patterns = ["**/__init__.py", "**/main.py", "**/app.py", "**/*_service.py"]
|
|
384
|
-
for pattern in patterns:
|
|
385
|
-
main_files.extend(list(service_path.glob(pattern))[:5])
|
|
386
|
-
|
|
387
|
-
elif language in [Language.TYPESCRIPT, Language.JAVASCRIPT, Language.REACT]:
|
|
388
|
-
# Look for index.ts, index.tsx, main.ts, app.tsx
|
|
389
|
-
patterns = [
|
|
390
|
-
"**/index.ts",
|
|
391
|
-
"**/index.tsx",
|
|
392
|
-
"**/main.ts",
|
|
393
|
-
"**/app.tsx",
|
|
394
|
-
"**/App.tsx",
|
|
395
|
-
]
|
|
396
|
-
for pattern in patterns:
|
|
397
|
-
main_files.extend(list(service_path.glob(pattern))[:5])
|
|
398
|
-
|
|
399
|
-
# If no specific main files found, get first code file
|
|
400
|
-
if not main_files:
|
|
401
|
-
code_extensions = {
|
|
402
|
-
Language.PYTHON: ".py",
|
|
403
|
-
Language.TYPESCRIPT: ".ts",
|
|
404
|
-
Language.JAVASCRIPT: ".js",
|
|
405
|
-
Language.REACT: ".tsx",
|
|
406
|
-
}
|
|
407
|
-
ext = code_extensions.get(language, ".py")
|
|
408
|
-
main_files = list(service_path.glob(f"**/*{ext}"))[:1]
|
|
409
|
-
|
|
410
|
-
return main_files[:1] # Return first file for now
|
|
411
|
-
|
|
412
|
-
def _aggregate_results(
|
|
413
|
-
self, results: list[ServiceReviewResult], errors: list[str]
|
|
414
|
-
) -> BatchReviewResult:
|
|
415
|
-
"""
|
|
416
|
-
Aggregate individual service review results.
|
|
417
|
-
|
|
418
|
-
Args:
|
|
419
|
-
results: List of service review results
|
|
420
|
-
errors: List of error messages
|
|
421
|
-
|
|
422
|
-
Returns:
|
|
423
|
-
BatchReviewResult with aggregated statistics
|
|
424
|
-
"""
|
|
425
|
-
if not results:
|
|
426
|
-
return BatchReviewResult(
|
|
427
|
-
services_reviewed=0,
|
|
428
|
-
passed=0,
|
|
429
|
-
failed=0,
|
|
430
|
-
average_score=0.0,
|
|
431
|
-
errors=errors,
|
|
432
|
-
)
|
|
433
|
-
|
|
434
|
-
passed = sum(1 for r in results if r.passed)
|
|
435
|
-
failed = len(results) - passed
|
|
436
|
-
|
|
437
|
-
scores = [r.overall_score for r in results if r.overall_score > 0]
|
|
438
|
-
average_score = sum(scores) / len(scores) if scores else 0.0
|
|
439
|
-
|
|
440
|
-
return BatchReviewResult(
|
|
441
|
-
services_reviewed=len(results),
|
|
442
|
-
passed=passed,
|
|
443
|
-
failed=failed,
|
|
444
|
-
average_score=average_score,
|
|
445
|
-
results=results,
|
|
446
|
-
errors=errors,
|
|
447
|
-
)
|
|
448
|
-
|
|
1
|
+
"""
|
|
2
|
+
Batch Review Workflow - Review multiple services in parallel
|
|
3
|
+
|
|
4
|
+
Phase 4.2: Batch Review Workflow
|
|
5
|
+
|
|
6
|
+
Uses asyncio.TaskGroup for parallel execution following ParallelStepExecutor patterns.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import asyncio
|
|
12
|
+
import logging
|
|
13
|
+
import sys
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
from pydantic import BaseModel, Field
|
|
18
|
+
|
|
19
|
+
from ...core.config import ProjectConfig
|
|
20
|
+
from ...core.language_detector import Language
|
|
21
|
+
from .agent import ReviewerAgent
|
|
22
|
+
from .service_discovery import Service
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
# Default timeout for service review (5 minutes)
|
|
27
|
+
DEFAULT_REVIEW_TIMEOUT = 300.0
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ServiceReviewResult(BaseModel):
|
|
31
|
+
"""Result of reviewing a single service."""
|
|
32
|
+
|
|
33
|
+
service_name: str
|
|
34
|
+
service_path: str
|
|
35
|
+
language: str
|
|
36
|
+
passed: bool
|
|
37
|
+
overall_score: float
|
|
38
|
+
scores: dict[str, float] = Field(default_factory=dict)
|
|
39
|
+
error: str | None = None
|
|
40
|
+
review_details: dict[str, Any] = Field(default_factory=dict)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class BatchReviewResult(BaseModel):
|
|
44
|
+
"""Result of batch review workflow."""
|
|
45
|
+
|
|
46
|
+
services_reviewed: int
|
|
47
|
+
passed: int
|
|
48
|
+
failed: int
|
|
49
|
+
average_score: float
|
|
50
|
+
results: list[ServiceReviewResult] = Field(default_factory=list)
|
|
51
|
+
errors: list[str] = Field(default_factory=list)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class BatchReviewWorkflow:
|
|
55
|
+
"""
|
|
56
|
+
Batch review workflow for reviewing multiple services.
|
|
57
|
+
|
|
58
|
+
Phase 4.2: Batch Review Workflow
|
|
59
|
+
Uses asyncio.TaskGroup for parallel execution (Python 3.11+).
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
def __init__(
|
|
63
|
+
self,
|
|
64
|
+
config: ProjectConfig | None = None,
|
|
65
|
+
project_root: Path | None = None,
|
|
66
|
+
max_parallel: int = 4,
|
|
67
|
+
review_timeout: float = DEFAULT_REVIEW_TIMEOUT,
|
|
68
|
+
):
|
|
69
|
+
"""
|
|
70
|
+
Initialize batch review workflow.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
config: Optional project configuration
|
|
74
|
+
project_root: Optional project root directory
|
|
75
|
+
max_parallel: Maximum number of parallel reviews (default: 4)
|
|
76
|
+
review_timeout: Timeout in seconds for single service review (default: 300.0)
|
|
77
|
+
"""
|
|
78
|
+
self.config = config
|
|
79
|
+
self.project_root = project_root or Path.cwd()
|
|
80
|
+
self.max_parallel = max_parallel
|
|
81
|
+
self.review_timeout = review_timeout
|
|
82
|
+
|
|
83
|
+
async def review_services(
|
|
84
|
+
self,
|
|
85
|
+
services: list[Service],
|
|
86
|
+
parallel: bool = True,
|
|
87
|
+
include_scoring: bool = True,
|
|
88
|
+
include_llm_feedback: bool = True,
|
|
89
|
+
) -> BatchReviewResult:
|
|
90
|
+
"""
|
|
91
|
+
Review multiple services in parallel or sequentially.
|
|
92
|
+
|
|
93
|
+
Phase 4.2: Batch Review with Parallel Execution
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
services: List of Service objects to review
|
|
97
|
+
parallel: Whether to execute reviews in parallel (default: True)
|
|
98
|
+
include_scoring: Whether to include code quality scoring
|
|
99
|
+
include_llm_feedback: Whether to include LLM feedback
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
BatchReviewResult with aggregated results
|
|
103
|
+
"""
|
|
104
|
+
if not services:
|
|
105
|
+
return BatchReviewResult(
|
|
106
|
+
services_reviewed=0,
|
|
107
|
+
passed=0,
|
|
108
|
+
failed=0,
|
|
109
|
+
average_score=0.0,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
if parallel:
|
|
113
|
+
return await self._review_services_parallel(
|
|
114
|
+
services, include_scoring, include_llm_feedback
|
|
115
|
+
)
|
|
116
|
+
else:
|
|
117
|
+
return await self._review_services_sequential(
|
|
118
|
+
services, include_scoring, include_llm_feedback
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
async def _review_services_parallel(
|
|
122
|
+
self,
|
|
123
|
+
services: list[Service],
|
|
124
|
+
include_scoring: bool,
|
|
125
|
+
include_llm_feedback: bool,
|
|
126
|
+
) -> BatchReviewResult:
|
|
127
|
+
"""
|
|
128
|
+
Review services in parallel using asyncio.TaskGroup.
|
|
129
|
+
|
|
130
|
+
Phase 4.2: Parallel Execution with TaskGroup
|
|
131
|
+
"""
|
|
132
|
+
results: list[ServiceReviewResult] = []
|
|
133
|
+
errors: list[str] = []
|
|
134
|
+
|
|
135
|
+
# Use TaskGroup for structured concurrency (Python 3.11+)
|
|
136
|
+
if sys.version_info >= (3, 11):
|
|
137
|
+
tasks_map: dict[asyncio.Task[ServiceReviewResult], Service] = {}
|
|
138
|
+
try:
|
|
139
|
+
async with asyncio.TaskGroup() as tg:
|
|
140
|
+
# Create tasks for all services
|
|
141
|
+
for service in services:
|
|
142
|
+
task = tg.create_task(
|
|
143
|
+
self._review_single_service(
|
|
144
|
+
service, include_scoring, include_llm_feedback
|
|
145
|
+
)
|
|
146
|
+
)
|
|
147
|
+
tasks_map[task] = service
|
|
148
|
+
|
|
149
|
+
# All tasks completed successfully - collect results
|
|
150
|
+
for task, service in tasks_map.items():
|
|
151
|
+
result = await task
|
|
152
|
+
results.append(result)
|
|
153
|
+
|
|
154
|
+
except* Exception as eg: # ExceptionGroup (Python 3.11+)
|
|
155
|
+
# Handle exception group from TaskGroup
|
|
156
|
+
# TaskGroup automatically cancels all tasks if any task raises an exception
|
|
157
|
+
for task, service in tasks_map.items():
|
|
158
|
+
if task.done():
|
|
159
|
+
try:
|
|
160
|
+
result = await task
|
|
161
|
+
results.append(result)
|
|
162
|
+
except Exception as e:
|
|
163
|
+
logger.error(
|
|
164
|
+
f"Exception in completed task for service {service.name}: {e}",
|
|
165
|
+
exc_info=True,
|
|
166
|
+
)
|
|
167
|
+
errors.append(f"{service.name}: {str(e)}")
|
|
168
|
+
results.append(
|
|
169
|
+
ServiceReviewResult(
|
|
170
|
+
service_name=service.name,
|
|
171
|
+
service_path=str(service.path),
|
|
172
|
+
language=service.language.value,
|
|
173
|
+
passed=False,
|
|
174
|
+
overall_score=0.0,
|
|
175
|
+
error=str(e),
|
|
176
|
+
)
|
|
177
|
+
)
|
|
178
|
+
else:
|
|
179
|
+
# Task was cancelled by TaskGroup
|
|
180
|
+
errors.append(f"{service.name}: Task cancelled")
|
|
181
|
+
results.append(
|
|
182
|
+
ServiceReviewResult(
|
|
183
|
+
service_name=service.name,
|
|
184
|
+
service_path=str(service.path),
|
|
185
|
+
language=service.language.value,
|
|
186
|
+
passed=False,
|
|
187
|
+
overall_score=0.0,
|
|
188
|
+
error="Task cancelled due to another service's failure",
|
|
189
|
+
)
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
# Add exception group errors
|
|
193
|
+
for exc in eg.exceptions:
|
|
194
|
+
logger.error(f"TaskGroup exception: {exc}", exc_info=True)
|
|
195
|
+
errors.append(f"TaskGroup error: {str(exc)}")
|
|
196
|
+
else:
|
|
197
|
+
# Fallback for Python < 3.11: use asyncio.gather with semaphore
|
|
198
|
+
semaphore = asyncio.Semaphore(self.max_parallel)
|
|
199
|
+
|
|
200
|
+
async def review_with_semaphore(service: Service) -> ServiceReviewResult:
|
|
201
|
+
async with semaphore:
|
|
202
|
+
return await self._review_single_service(
|
|
203
|
+
service, include_scoring, include_llm_feedback
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
tasks = [review_with_semaphore(service) for service in services]
|
|
207
|
+
gathered_results = await asyncio.gather(*tasks, return_exceptions=True)
|
|
208
|
+
|
|
209
|
+
for i, result in enumerate(gathered_results):
|
|
210
|
+
if isinstance(result, Exception):
|
|
211
|
+
service = services[i]
|
|
212
|
+
logger.error(
|
|
213
|
+
f"Exception during review for service {service.name}: {result}",
|
|
214
|
+
exc_info=True,
|
|
215
|
+
)
|
|
216
|
+
errors.append(f"{service.name}: {str(result)}")
|
|
217
|
+
results.append(
|
|
218
|
+
ServiceReviewResult(
|
|
219
|
+
service_name=service.name,
|
|
220
|
+
service_path=str(service.path),
|
|
221
|
+
language=service.language.value,
|
|
222
|
+
passed=False,
|
|
223
|
+
overall_score=0.0,
|
|
224
|
+
error=str(result),
|
|
225
|
+
)
|
|
226
|
+
)
|
|
227
|
+
else:
|
|
228
|
+
results.append(result)
|
|
229
|
+
|
|
230
|
+
return self._aggregate_results(results, errors)
|
|
231
|
+
|
|
232
|
+
async def _review_services_sequential(
|
|
233
|
+
self,
|
|
234
|
+
services: list[Service],
|
|
235
|
+
include_scoring: bool,
|
|
236
|
+
include_llm_feedback: bool,
|
|
237
|
+
) -> BatchReviewResult:
|
|
238
|
+
"""Review services sequentially."""
|
|
239
|
+
results: list[ServiceReviewResult] = []
|
|
240
|
+
errors: list[str] = []
|
|
241
|
+
|
|
242
|
+
for service in services:
|
|
243
|
+
try:
|
|
244
|
+
result = await self._review_single_service(
|
|
245
|
+
service, include_scoring, include_llm_feedback
|
|
246
|
+
)
|
|
247
|
+
results.append(result)
|
|
248
|
+
except Exception as e:
|
|
249
|
+
errors.append(f"{service.name}: {str(e)}")
|
|
250
|
+
results.append(
|
|
251
|
+
ServiceReviewResult(
|
|
252
|
+
service_name=service.name,
|
|
253
|
+
service_path=str(service.path),
|
|
254
|
+
language=service.language.value,
|
|
255
|
+
passed=False,
|
|
256
|
+
overall_score=0.0,
|
|
257
|
+
error=str(e),
|
|
258
|
+
)
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
return self._aggregate_results(results, errors)
|
|
262
|
+
|
|
263
|
+
async def _review_single_service(
|
|
264
|
+
self,
|
|
265
|
+
service: Service,
|
|
266
|
+
include_scoring: bool,
|
|
267
|
+
include_llm_feedback: bool,
|
|
268
|
+
) -> ServiceReviewResult:
|
|
269
|
+
"""
|
|
270
|
+
Review a single service.
|
|
271
|
+
|
|
272
|
+
Args:
|
|
273
|
+
service: Service to review
|
|
274
|
+
include_scoring: Whether to include scoring
|
|
275
|
+
include_llm_feedback: Whether to include LLM feedback
|
|
276
|
+
|
|
277
|
+
Returns:
|
|
278
|
+
ServiceReviewResult
|
|
279
|
+
"""
|
|
280
|
+
# Find main files in service directory to review
|
|
281
|
+
service_path = service.path
|
|
282
|
+
main_files = self._find_main_files(service_path, service.language)
|
|
283
|
+
|
|
284
|
+
if not main_files:
|
|
285
|
+
# No files to review, return neutral result
|
|
286
|
+
return ServiceReviewResult(
|
|
287
|
+
service_name=service.name,
|
|
288
|
+
service_path=str(service_path),
|
|
289
|
+
language=service.language.value,
|
|
290
|
+
passed=True,
|
|
291
|
+
overall_score=5.0, # Neutral score
|
|
292
|
+
review_details={"message": "No code files found to review"},
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
# Initialize reviewer agent
|
|
296
|
+
reviewer = ReviewerAgent(config=self.config)
|
|
297
|
+
try:
|
|
298
|
+
# Review first/main file as representative
|
|
299
|
+
# TODO: Could review multiple files and aggregate
|
|
300
|
+
main_file = main_files[0]
|
|
301
|
+
|
|
302
|
+
# Add timeout to prevent hanging
|
|
303
|
+
try:
|
|
304
|
+
review_result = await asyncio.wait_for(
|
|
305
|
+
reviewer.review_file(
|
|
306
|
+
main_file,
|
|
307
|
+
include_scoring=include_scoring,
|
|
308
|
+
include_llm_feedback=include_llm_feedback,
|
|
309
|
+
),
|
|
310
|
+
timeout=self.review_timeout,
|
|
311
|
+
)
|
|
312
|
+
except asyncio.TimeoutError:
|
|
313
|
+
logger.error(
|
|
314
|
+
f"Review timeout ({self.review_timeout}s) exceeded for service {service.name}"
|
|
315
|
+
)
|
|
316
|
+
return ServiceReviewResult(
|
|
317
|
+
service_name=service.name,
|
|
318
|
+
service_path=str(service_path),
|
|
319
|
+
language=service.language.value,
|
|
320
|
+
passed=False,
|
|
321
|
+
overall_score=0.0,
|
|
322
|
+
error=f"Review timeout after {self.review_timeout} seconds",
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
# Extract scores
|
|
326
|
+
scores = review_result.get("scores", {})
|
|
327
|
+
overall_score = scores.get("overall_score", 0.0)
|
|
328
|
+
|
|
329
|
+
# Determine pass/fail (threshold: 70.0)
|
|
330
|
+
threshold = 70.0
|
|
331
|
+
if self.config and self.config.scoring:
|
|
332
|
+
threshold = self.config.scoring.quality_threshold
|
|
333
|
+
|
|
334
|
+
passed = overall_score >= threshold
|
|
335
|
+
|
|
336
|
+
return ServiceReviewResult(
|
|
337
|
+
service_name=service.name,
|
|
338
|
+
service_path=str(service_path),
|
|
339
|
+
language=service.language.value,
|
|
340
|
+
passed=passed,
|
|
341
|
+
overall_score=overall_score,
|
|
342
|
+
scores={
|
|
343
|
+
"complexity": scores.get("complexity_score", 0.0),
|
|
344
|
+
"security": scores.get("security_score", 0.0),
|
|
345
|
+
"maintainability": scores.get("maintainability_score", 0.0),
|
|
346
|
+
"test_coverage": scores.get("test_coverage_score", 0.0),
|
|
347
|
+
"performance": scores.get("performance_score", 0.0),
|
|
348
|
+
},
|
|
349
|
+
review_details=review_result,
|
|
350
|
+
)
|
|
351
|
+
except Exception as e:
|
|
352
|
+
logger.error(
|
|
353
|
+
f"Exception during review for service {service.name}: {e}",
|
|
354
|
+
exc_info=True,
|
|
355
|
+
)
|
|
356
|
+
return ServiceReviewResult(
|
|
357
|
+
service_name=service.name,
|
|
358
|
+
service_path=str(service_path),
|
|
359
|
+
language=service.language.value,
|
|
360
|
+
passed=False,
|
|
361
|
+
overall_score=0.0,
|
|
362
|
+
error=str(e),
|
|
363
|
+
)
|
|
364
|
+
finally:
|
|
365
|
+
await reviewer.close()
|
|
366
|
+
|
|
367
|
+
def _find_main_files(self, service_path: Path, language: Language) -> list[Path]:
|
|
368
|
+
"""
|
|
369
|
+
Find main code files to review in a service directory.
|
|
370
|
+
|
|
371
|
+
Args:
|
|
372
|
+
service_path: Path to service directory
|
|
373
|
+
language: Primary language of the service
|
|
374
|
+
|
|
375
|
+
Returns:
|
|
376
|
+
List of main file paths to review
|
|
377
|
+
"""
|
|
378
|
+
main_files = []
|
|
379
|
+
|
|
380
|
+
# Language-specific file patterns
|
|
381
|
+
if language == Language.PYTHON:
|
|
382
|
+
# Look for __init__.py, main.py, app.py, or service entry points
|
|
383
|
+
patterns = ["**/__init__.py", "**/main.py", "**/app.py", "**/*_service.py"]
|
|
384
|
+
for pattern in patterns:
|
|
385
|
+
main_files.extend(list(service_path.glob(pattern))[:5])
|
|
386
|
+
|
|
387
|
+
elif language in [Language.TYPESCRIPT, Language.JAVASCRIPT, Language.REACT]:
|
|
388
|
+
# Look for index.ts, index.tsx, main.ts, app.tsx
|
|
389
|
+
patterns = [
|
|
390
|
+
"**/index.ts",
|
|
391
|
+
"**/index.tsx",
|
|
392
|
+
"**/main.ts",
|
|
393
|
+
"**/app.tsx",
|
|
394
|
+
"**/App.tsx",
|
|
395
|
+
]
|
|
396
|
+
for pattern in patterns:
|
|
397
|
+
main_files.extend(list(service_path.glob(pattern))[:5])
|
|
398
|
+
|
|
399
|
+
# If no specific main files found, get first code file
|
|
400
|
+
if not main_files:
|
|
401
|
+
code_extensions = {
|
|
402
|
+
Language.PYTHON: ".py",
|
|
403
|
+
Language.TYPESCRIPT: ".ts",
|
|
404
|
+
Language.JAVASCRIPT: ".js",
|
|
405
|
+
Language.REACT: ".tsx",
|
|
406
|
+
}
|
|
407
|
+
ext = code_extensions.get(language, ".py")
|
|
408
|
+
main_files = list(service_path.glob(f"**/*{ext}"))[:1]
|
|
409
|
+
|
|
410
|
+
return main_files[:1] # Return first file for now
|
|
411
|
+
|
|
412
|
+
def _aggregate_results(
|
|
413
|
+
self, results: list[ServiceReviewResult], errors: list[str]
|
|
414
|
+
) -> BatchReviewResult:
|
|
415
|
+
"""
|
|
416
|
+
Aggregate individual service review results.
|
|
417
|
+
|
|
418
|
+
Args:
|
|
419
|
+
results: List of service review results
|
|
420
|
+
errors: List of error messages
|
|
421
|
+
|
|
422
|
+
Returns:
|
|
423
|
+
BatchReviewResult with aggregated statistics
|
|
424
|
+
"""
|
|
425
|
+
if not results:
|
|
426
|
+
return BatchReviewResult(
|
|
427
|
+
services_reviewed=0,
|
|
428
|
+
passed=0,
|
|
429
|
+
failed=0,
|
|
430
|
+
average_score=0.0,
|
|
431
|
+
errors=errors,
|
|
432
|
+
)
|
|
433
|
+
|
|
434
|
+
passed = sum(1 for r in results if r.passed)
|
|
435
|
+
failed = len(results) - passed
|
|
436
|
+
|
|
437
|
+
scores = [r.overall_score for r in results if r.overall_score > 0]
|
|
438
|
+
average_score = sum(scores) / len(scores) if scores else 0.0
|
|
439
|
+
|
|
440
|
+
return BatchReviewResult(
|
|
441
|
+
services_reviewed=len(results),
|
|
442
|
+
passed=passed,
|
|
443
|
+
failed=failed,
|
|
444
|
+
average_score=average_score,
|
|
445
|
+
results=results,
|
|
446
|
+
errors=errors,
|
|
447
|
+
)
|
|
448
|
+
|