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,552 +1,552 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Context-Aware Suggestion Engine
|
|
3
|
-
|
|
4
|
-
Epic 13: Context-Aware Suggestions
|
|
5
|
-
Provides intelligent suggestions for workflows, agents, and actions based on project context.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from __future__ import annotations
|
|
9
|
-
|
|
10
|
-
import json
|
|
11
|
-
import logging
|
|
12
|
-
from dataclasses import dataclass, field
|
|
13
|
-
from datetime import datetime
|
|
14
|
-
from enum import Enum
|
|
15
|
-
from pathlib import Path
|
|
16
|
-
from typing import Any
|
|
17
|
-
|
|
18
|
-
from ..core.project_profile import ProjectProfile, ProjectProfileDetector
|
|
19
|
-
from .context_analyzer import ContextAnalyzer, ProjectContext
|
|
20
|
-
from .recommender import WorkflowRecommendation, WorkflowRecommender
|
|
21
|
-
|
|
22
|
-
logger = logging.getLogger(__name__)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
# Backward compatibility: Legacy SuggestionEngine for nlp_executor
|
|
26
|
-
class SuggestionEngine:
|
|
27
|
-
"""
|
|
28
|
-
Legacy suggestion engine wrapper for backward compatibility.
|
|
29
|
-
|
|
30
|
-
This class provides a simple interface for NLP executor.
|
|
31
|
-
For new code, use ContextAwareSuggestionEngine instead.
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
def __init__(self, preset_loader):
|
|
35
|
-
"""Initialize legacy suggestion engine."""
|
|
36
|
-
self.preset_loader = preset_loader
|
|
37
|
-
self.engine = ContextAwareSuggestionEngine()
|
|
38
|
-
|
|
39
|
-
def suggest_workflows(self, context):
|
|
40
|
-
"""Suggest workflows based on context (legacy interface)."""
|
|
41
|
-
suggestions = self.engine.get_suggestions(include_agents=False, include_actions=False)
|
|
42
|
-
return suggestions.workflows
|
|
43
|
-
|
|
44
|
-
def format_suggestions(self, suggestions):
|
|
45
|
-
"""Format suggestions for display (legacy interface)."""
|
|
46
|
-
if not suggestions:
|
|
47
|
-
return "No workflow suggestions available."
|
|
48
|
-
|
|
49
|
-
lines = ["## Workflow Suggestions\n"]
|
|
50
|
-
for i, suggestion in enumerate(suggestions[:5], 1): # Top 5
|
|
51
|
-
lines.append(f"{i}. **{suggestion.value}** ({suggestion.confidence:.0%} confidence)")
|
|
52
|
-
lines.append(f" {suggestion.explanation}\n")
|
|
53
|
-
|
|
54
|
-
return "\n".join(lines)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
class SuggestionType(Enum):
|
|
58
|
-
"""Type of suggestion."""
|
|
59
|
-
|
|
60
|
-
WORKFLOW = "workflow"
|
|
61
|
-
AGENT = "agent"
|
|
62
|
-
ACTION = "action"
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
@dataclass
|
|
66
|
-
class Suggestion:
|
|
67
|
-
"""A single suggestion with ranking and explanation."""
|
|
68
|
-
|
|
69
|
-
type: SuggestionType
|
|
70
|
-
value: str # Workflow name, agent name, or action description
|
|
71
|
-
confidence: float # 0.0 to 1.0
|
|
72
|
-
explanation: str # Why this suggestion
|
|
73
|
-
context_matches: list[str] = field(default_factory=list) # What context matched
|
|
74
|
-
metadata: dict[str, Any] = field(default_factory=dict)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
@dataclass
|
|
78
|
-
class SuggestionSet:
|
|
79
|
-
"""A set of suggestions for a context."""
|
|
80
|
-
|
|
81
|
-
workflows: list[Suggestion] = field(default_factory=list)
|
|
82
|
-
agents: list[Suggestion] = field(default_factory=list)
|
|
83
|
-
actions: list[Suggestion] = field(default_factory=list)
|
|
84
|
-
context: ProjectContext | None = None
|
|
85
|
-
project_profile: ProjectProfile | None = None
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
class ContextAwareSuggestionEngine:
|
|
89
|
-
"""
|
|
90
|
-
Context-aware suggestion engine.
|
|
91
|
-
|
|
92
|
-
Analyzes project context and provides intelligent suggestions for:
|
|
93
|
-
- Workflows to use
|
|
94
|
-
- Agents to employ
|
|
95
|
-
- Actions to take
|
|
96
|
-
"""
|
|
97
|
-
|
|
98
|
-
# Agent mapping based on task context
|
|
99
|
-
AGENT_MAPPING = {
|
|
100
|
-
"requirements": ["analyst", "po"],
|
|
101
|
-
"design": ["architect", "ux-expert"],
|
|
102
|
-
"implementation": ["dev"],
|
|
103
|
-
"testing": ["qa"],
|
|
104
|
-
"review": ["reviewer"],
|
|
105
|
-
"documentation": ["documenter"],
|
|
106
|
-
"planning": ["pm", "po"],
|
|
107
|
-
"security": ["security"],
|
|
108
|
-
"deployment": ["ops"],
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
# Action suggestions based on context
|
|
112
|
-
ACTION_PATTERNS = {
|
|
113
|
-
"new_feature": [
|
|
114
|
-
"Run requirements analysis workflow",
|
|
115
|
-
"Create feature branch",
|
|
116
|
-
"Set up testing framework",
|
|
117
|
-
],
|
|
118
|
-
"bug_fix": [
|
|
119
|
-
"Run fix workflow",
|
|
120
|
-
"Create test case for bug",
|
|
121
|
-
"Review related code",
|
|
122
|
-
],
|
|
123
|
-
"refactoring": [
|
|
124
|
-
"Run full SDLC workflow",
|
|
125
|
-
"Update documentation",
|
|
126
|
-
"Run comprehensive tests",
|
|
127
|
-
],
|
|
128
|
-
"documentation": [
|
|
129
|
-
"Run documentation workflow",
|
|
130
|
-
"Review existing docs",
|
|
131
|
-
"Update API documentation",
|
|
132
|
-
],
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
def __init__(self, project_root: Path | None = None):
|
|
136
|
-
"""
|
|
137
|
-
Initialize suggestion engine.
|
|
138
|
-
|
|
139
|
-
Args:
|
|
140
|
-
project_root: Project root directory
|
|
141
|
-
"""
|
|
142
|
-
self.project_root = Path(project_root) if project_root else Path.cwd()
|
|
143
|
-
self.context_analyzer = ContextAnalyzer(project_root)
|
|
144
|
-
self.workflow_recommender = WorkflowRecommender(project_root)
|
|
145
|
-
self.profile_detector = ProjectProfileDetector(project_root)
|
|
146
|
-
self.learning_data_path = self.project_root / ".tapps-agents" / "suggestion_learning.json"
|
|
147
|
-
self.learning_data: dict[str, Any] = self._load_learning_data()
|
|
148
|
-
|
|
149
|
-
def get_suggestions(
|
|
150
|
-
self,
|
|
151
|
-
user_query: str | None = None,
|
|
152
|
-
include_workflows: bool = True,
|
|
153
|
-
include_agents: bool = True,
|
|
154
|
-
include_actions: bool = True,
|
|
155
|
-
) -> SuggestionSet:
|
|
156
|
-
"""
|
|
157
|
-
Get context-aware suggestions.
|
|
158
|
-
|
|
159
|
-
Args:
|
|
160
|
-
user_query: Optional user query for context
|
|
161
|
-
include_workflows: Whether to include workflow suggestions
|
|
162
|
-
include_agents: Whether to include agent suggestions
|
|
163
|
-
include_actions: Whether to include action suggestions
|
|
164
|
-
|
|
165
|
-
Returns:
|
|
166
|
-
SuggestionSet with all suggestions
|
|
167
|
-
"""
|
|
168
|
-
# Analyze context
|
|
169
|
-
context = self.context_analyzer.analyze()
|
|
170
|
-
|
|
171
|
-
# Get project profile
|
|
172
|
-
try:
|
|
173
|
-
project_profile = self.profile_detector.detect()
|
|
174
|
-
except Exception as e:
|
|
175
|
-
logger.warning(f"Failed to detect project profile: {e}")
|
|
176
|
-
project_profile = None
|
|
177
|
-
|
|
178
|
-
suggestions = SuggestionSet(context=context, project_profile=project_profile)
|
|
179
|
-
|
|
180
|
-
# Get workflow suggestions
|
|
181
|
-
if include_workflows:
|
|
182
|
-
suggestions.workflows = self._suggest_workflows(context, user_query)
|
|
183
|
-
|
|
184
|
-
# Get agent suggestions
|
|
185
|
-
if include_agents:
|
|
186
|
-
suggestions.agents = self._suggest_agents(context, user_query)
|
|
187
|
-
|
|
188
|
-
# Get action suggestions
|
|
189
|
-
if include_actions:
|
|
190
|
-
suggestions.actions = self._suggest_actions(context, user_query)
|
|
191
|
-
|
|
192
|
-
return suggestions
|
|
193
|
-
|
|
194
|
-
def _suggest_workflows(
|
|
195
|
-
self, context: ProjectContext, user_query: str | None = None
|
|
196
|
-
) -> list[Suggestion]:
|
|
197
|
-
"""Suggest workflows based on context."""
|
|
198
|
-
suggestions = []
|
|
199
|
-
|
|
200
|
-
try:
|
|
201
|
-
# Use workflow recommender
|
|
202
|
-
recommendation = self.workflow_recommender.recommend(user_query=user_query)
|
|
203
|
-
|
|
204
|
-
if recommendation.workflow_file:
|
|
205
|
-
suggestions.append(
|
|
206
|
-
Suggestion(
|
|
207
|
-
type=SuggestionType.WORKFLOW,
|
|
208
|
-
value=recommendation.workflow_file,
|
|
209
|
-
confidence=recommendation.confidence,
|
|
210
|
-
explanation=recommendation.message,
|
|
211
|
-
context_matches=self._extract_context_matches(context, recommendation),
|
|
212
|
-
metadata={
|
|
213
|
-
"track": recommendation.track.value,
|
|
214
|
-
"characteristics": recommendation.characteristics.__dict__ if hasattr(recommendation.characteristics, '__dict__') else {},
|
|
215
|
-
},
|
|
216
|
-
)
|
|
217
|
-
)
|
|
218
|
-
|
|
219
|
-
# Add alternative workflows
|
|
220
|
-
for alt_workflow in recommendation.alternative_workflows[:3]: # Top 3 alternatives
|
|
221
|
-
suggestions.append(
|
|
222
|
-
Suggestion(
|
|
223
|
-
type=SuggestionType.WORKFLOW,
|
|
224
|
-
value=alt_workflow,
|
|
225
|
-
confidence=recommendation.confidence * 0.7, # Lower confidence for alternatives
|
|
226
|
-
explanation=f"Alternative workflow: {alt_workflow}",
|
|
227
|
-
context_matches=[],
|
|
228
|
-
)
|
|
229
|
-
)
|
|
230
|
-
|
|
231
|
-
except Exception as e:
|
|
232
|
-
logger.warning(f"Failed to suggest workflows: {e}")
|
|
233
|
-
|
|
234
|
-
# Apply learning-based ranking
|
|
235
|
-
suggestions = self._apply_learning_ranking(suggestions, "workflow")
|
|
236
|
-
|
|
237
|
-
return sorted(suggestions, key=lambda s: s.confidence, reverse=True)
|
|
238
|
-
|
|
239
|
-
def _suggest_agents(
|
|
240
|
-
self, context: ProjectContext, user_query: str | None = None
|
|
241
|
-
) -> list[Suggestion]:
|
|
242
|
-
"""Suggest agents based on context."""
|
|
243
|
-
suggestions = []
|
|
244
|
-
|
|
245
|
-
# Analyze context to determine task type
|
|
246
|
-
task_type = self._infer_task_type(context, user_query)
|
|
247
|
-
|
|
248
|
-
# Get agents for task type
|
|
249
|
-
agent_names = self.AGENT_MAPPING.get(task_type, ["dev"])
|
|
250
|
-
|
|
251
|
-
for agent_name in agent_names:
|
|
252
|
-
confidence = self._calculate_agent_confidence(agent_name, context, task_type)
|
|
253
|
-
explanation = self._generate_agent_explanation(agent_name, task_type, context)
|
|
254
|
-
|
|
255
|
-
suggestions.append(
|
|
256
|
-
Suggestion(
|
|
257
|
-
type=SuggestionType.AGENT,
|
|
258
|
-
value=agent_name,
|
|
259
|
-
confidence=confidence,
|
|
260
|
-
explanation=explanation,
|
|
261
|
-
context_matches=[task_type] if task_type else [],
|
|
262
|
-
metadata={"task_type": task_type},
|
|
263
|
-
)
|
|
264
|
-
)
|
|
265
|
-
|
|
266
|
-
# Apply learning-based ranking
|
|
267
|
-
suggestions = self._apply_learning_ranking(suggestions, "agent")
|
|
268
|
-
|
|
269
|
-
return sorted(suggestions, key=lambda s: s.confidence, reverse=True)
|
|
270
|
-
|
|
271
|
-
def _suggest_actions(
|
|
272
|
-
self, context: ProjectContext, user_query: str | None = None
|
|
273
|
-
) -> list[Suggestion]:
|
|
274
|
-
"""Suggest actions based on context."""
|
|
275
|
-
suggestions = []
|
|
276
|
-
|
|
277
|
-
# Infer action context
|
|
278
|
-
action_context = self._infer_action_context(context, user_query)
|
|
279
|
-
|
|
280
|
-
# Get action patterns for context
|
|
281
|
-
action_patterns = self.ACTION_PATTERNS.get(action_context, [])
|
|
282
|
-
|
|
283
|
-
for action in action_patterns:
|
|
284
|
-
confidence = self._calculate_action_confidence(action, context, action_context)
|
|
285
|
-
explanation = self._generate_action_explanation(action, action_context, context)
|
|
286
|
-
|
|
287
|
-
suggestions.append(
|
|
288
|
-
Suggestion(
|
|
289
|
-
type=SuggestionType.ACTION,
|
|
290
|
-
value=action,
|
|
291
|
-
confidence=confidence,
|
|
292
|
-
explanation=explanation,
|
|
293
|
-
context_matches=[action_context] if action_context else [],
|
|
294
|
-
metadata={"action_context": action_context},
|
|
295
|
-
)
|
|
296
|
-
)
|
|
297
|
-
|
|
298
|
-
# Apply learning-based ranking
|
|
299
|
-
suggestions = self._apply_learning_ranking(suggestions, "action")
|
|
300
|
-
|
|
301
|
-
return sorted(suggestions, key=lambda s: s.confidence, reverse=True)
|
|
302
|
-
|
|
303
|
-
def _infer_task_type(self, context: ProjectContext, user_query: str | None = None) -> str:
|
|
304
|
-
"""Infer task type from context."""
|
|
305
|
-
if user_query:
|
|
306
|
-
query_lower = user_query.lower()
|
|
307
|
-
if any(word in query_lower for word in ["requirement", "analyze", "spec"]):
|
|
308
|
-
return "requirements"
|
|
309
|
-
if any(word in query_lower for word in ["design", "architecture", "structure"]):
|
|
310
|
-
return "design"
|
|
311
|
-
if any(word in query_lower for word in ["test", "testing", "qa"]):
|
|
312
|
-
return "testing"
|
|
313
|
-
if any(word in query_lower for word in ["review", "code review"]):
|
|
314
|
-
return "review"
|
|
315
|
-
if any(word in query_lower for word in ["document", "docs", "readme"]):
|
|
316
|
-
return "documentation"
|
|
317
|
-
if any(word in query_lower for word in ["plan", "planning", "roadmap"]):
|
|
318
|
-
return "planning"
|
|
319
|
-
if any(word in query_lower for word in ["security", "secure", "vulnerability"]):
|
|
320
|
-
return "security"
|
|
321
|
-
if any(word in query_lower for word in ["deploy", "deployment", "ops"]):
|
|
322
|
-
return "deployment"
|
|
323
|
-
|
|
324
|
-
# Infer from branch name
|
|
325
|
-
if context.branch_name:
|
|
326
|
-
branch_lower = context.branch_name.lower()
|
|
327
|
-
if "feature" in branch_lower or "feat" in branch_lower:
|
|
328
|
-
return "implementation"
|
|
329
|
-
if "fix" in branch_lower or "bug" in branch_lower:
|
|
330
|
-
return "testing"
|
|
331
|
-
if "doc" in branch_lower:
|
|
332
|
-
return "documentation"
|
|
333
|
-
if "refactor" in branch_lower:
|
|
334
|
-
return "implementation"
|
|
335
|
-
|
|
336
|
-
# Infer from file changes
|
|
337
|
-
if context.recent_changes:
|
|
338
|
-
file_types = self._analyze_file_types(context.recent_changes)
|
|
339
|
-
if file_types.get("test", 0) > 0:
|
|
340
|
-
return "testing"
|
|
341
|
-
if file_types.get("doc", 0) > 0:
|
|
342
|
-
return "documentation"
|
|
343
|
-
|
|
344
|
-
return "implementation" # Default
|
|
345
|
-
|
|
346
|
-
def _infer_action_context(self, context: ProjectContext, user_query: str | None = None) -> str:
|
|
347
|
-
"""Infer action context from project state."""
|
|
348
|
-
if user_query:
|
|
349
|
-
query_lower = user_query.lower()
|
|
350
|
-
if any(word in query_lower for word in ["new", "feature", "add"]):
|
|
351
|
-
return "new_feature"
|
|
352
|
-
if any(word in query_lower for word in ["fix", "bug", "error"]):
|
|
353
|
-
return "bug_fix"
|
|
354
|
-
if any(word in query_lower for word in ["refactor", "restructure"]):
|
|
355
|
-
return "refactoring"
|
|
356
|
-
if any(word in query_lower for word in ["document", "docs"]):
|
|
357
|
-
return "documentation"
|
|
358
|
-
|
|
359
|
-
# Infer from branch name
|
|
360
|
-
if context.branch_name:
|
|
361
|
-
branch_lower = context.branch_name.lower()
|
|
362
|
-
if "feature" in branch_lower:
|
|
363
|
-
return "new_feature"
|
|
364
|
-
if "fix" in branch_lower or "bug" in branch_lower:
|
|
365
|
-
return "bug_fix"
|
|
366
|
-
if "refactor" in branch_lower:
|
|
367
|
-
return "refactoring"
|
|
368
|
-
|
|
369
|
-
# Infer from file changes
|
|
370
|
-
if context.modified_files_count > 20:
|
|
371
|
-
return "refactoring"
|
|
372
|
-
elif context.modified_files_count > 5:
|
|
373
|
-
return "new_feature"
|
|
374
|
-
else:
|
|
375
|
-
return "bug_fix"
|
|
376
|
-
|
|
377
|
-
def _analyze_file_types(self, files: list[str]) -> dict[str, int]:
|
|
378
|
-
"""Analyze file types in changed files."""
|
|
379
|
-
types = {"test": 0, "doc": 0, "code": 0}
|
|
380
|
-
for file in files:
|
|
381
|
-
file_lower = file.lower()
|
|
382
|
-
if "test" in file_lower or "spec" in file_lower:
|
|
383
|
-
types["test"] += 1
|
|
384
|
-
elif any(ext in file_lower for ext in [".md", ".txt", ".rst"]):
|
|
385
|
-
types["doc"] += 1
|
|
386
|
-
else:
|
|
387
|
-
types["code"] += 1
|
|
388
|
-
return types
|
|
389
|
-
|
|
390
|
-
def _calculate_agent_confidence(
|
|
391
|
-
self, agent_name: str, context: ProjectContext, task_type: str
|
|
392
|
-
) -> float:
|
|
393
|
-
"""Calculate confidence for agent suggestion."""
|
|
394
|
-
base_confidence = 0.7
|
|
395
|
-
|
|
396
|
-
# Boost confidence if agent matches task type
|
|
397
|
-
if task_type in self.AGENT_MAPPING and agent_name in self.AGENT_MAPPING[task_type]:
|
|
398
|
-
base_confidence += 0.2
|
|
399
|
-
|
|
400
|
-
# Apply learning-based adjustments
|
|
401
|
-
learning_boost = self._get_learning_boost(agent_name, "agent")
|
|
402
|
-
base_confidence += learning_boost
|
|
403
|
-
|
|
404
|
-
return min(1.0, max(0.0, base_confidence))
|
|
405
|
-
|
|
406
|
-
def _calculate_action_confidence(
|
|
407
|
-
self, action: str, context: ProjectContext, action_context: str
|
|
408
|
-
) -> float:
|
|
409
|
-
"""Calculate confidence for action suggestion."""
|
|
410
|
-
base_confidence = 0.6
|
|
411
|
-
|
|
412
|
-
# Boost confidence if action matches context
|
|
413
|
-
if action_context in self.ACTION_PATTERNS and action in self.ACTION_PATTERNS[action_context]:
|
|
414
|
-
base_confidence += 0.2
|
|
415
|
-
|
|
416
|
-
# Apply learning-based adjustments
|
|
417
|
-
learning_boost = self._get_learning_boost(action, "action")
|
|
418
|
-
base_confidence += learning_boost
|
|
419
|
-
|
|
420
|
-
return min(1.0, max(0.0, base_confidence))
|
|
421
|
-
|
|
422
|
-
def _generate_agent_explanation(
|
|
423
|
-
self, agent_name: str, task_type: str, context: ProjectContext
|
|
424
|
-
) -> str:
|
|
425
|
-
"""Generate explanation for agent suggestion."""
|
|
426
|
-
explanations = {
|
|
427
|
-
"analyst": "Best for requirements analysis and gathering",
|
|
428
|
-
"architect": "Best for system design and architecture",
|
|
429
|
-
"dev": "Best for implementation and coding tasks",
|
|
430
|
-
"qa": "Best for testing and quality assurance",
|
|
431
|
-
"reviewer": "Best for code review and quality gates",
|
|
432
|
-
"documenter": "Best for documentation tasks",
|
|
433
|
-
"pm": "Best for project planning and management",
|
|
434
|
-
"po": "Best for product ownership and requirements",
|
|
435
|
-
}
|
|
436
|
-
base_explanation = explanations.get(agent_name, f"Recommended for {task_type} tasks")
|
|
437
|
-
|
|
438
|
-
if context.branch_name:
|
|
439
|
-
base_explanation += f" (current branch: {context.branch_name})"
|
|
440
|
-
|
|
441
|
-
return base_explanation
|
|
442
|
-
|
|
443
|
-
def _generate_action_explanation(
|
|
444
|
-
self, action: str, action_context: str, context: ProjectContext
|
|
445
|
-
) -> str:
|
|
446
|
-
"""Generate explanation for action suggestion."""
|
|
447
|
-
explanations = {
|
|
448
|
-
"new_feature": "Starting a new feature - recommended workflow",
|
|
449
|
-
"bug_fix": "Fixing a bug - quick workflow recommended",
|
|
450
|
-
"refactoring": "Refactoring code - comprehensive workflow recommended",
|
|
451
|
-
"documentation": "Documentation work - documentation workflow recommended",
|
|
452
|
-
}
|
|
453
|
-
base_explanation = explanations.get(action_context, "Recommended based on project context")
|
|
454
|
-
|
|
455
|
-
if context.modified_files_count > 0:
|
|
456
|
-
base_explanation += f" ({context.modified_files_count} files modified)"
|
|
457
|
-
|
|
458
|
-
return base_explanation
|
|
459
|
-
|
|
460
|
-
def _extract_context_matches(
|
|
461
|
-
self, context: ProjectContext, recommendation: WorkflowRecommendation
|
|
462
|
-
) -> list[str]:
|
|
463
|
-
"""Extract context matches for explanation."""
|
|
464
|
-
matches = []
|
|
465
|
-
|
|
466
|
-
if context.branch_name:
|
|
467
|
-
matches.append(f"Branch: {context.branch_name}")
|
|
468
|
-
|
|
469
|
-
if context.project_type:
|
|
470
|
-
matches.append(f"Project type: {context.project_type}")
|
|
471
|
-
|
|
472
|
-
if context.modified_files_count > 0:
|
|
473
|
-
matches.append(f"{context.modified_files_count} files modified")
|
|
474
|
-
|
|
475
|
-
return matches
|
|
476
|
-
|
|
477
|
-
def _apply_learning_ranking(
|
|
478
|
-
self, suggestions: list[Suggestion], suggestion_type: str
|
|
479
|
-
) -> list[Suggestion]:
|
|
480
|
-
"""Apply learning-based ranking adjustments."""
|
|
481
|
-
for suggestion in suggestions:
|
|
482
|
-
learning_boost = self._get_learning_boost(suggestion.value, suggestion_type)
|
|
483
|
-
suggestion.confidence = min(1.0, suggestion.confidence + learning_boost)
|
|
484
|
-
|
|
485
|
-
return suggestions
|
|
486
|
-
|
|
487
|
-
def _get_learning_boost(self, value: str, suggestion_type: str) -> float:
|
|
488
|
-
"""Get learning-based confidence boost."""
|
|
489
|
-
if not self.learning_data:
|
|
490
|
-
return 0.0
|
|
491
|
-
|
|
492
|
-
key = f"{suggestion_type}:{value}"
|
|
493
|
-
stats = self.learning_data.get(key, {})
|
|
494
|
-
|
|
495
|
-
accepted = stats.get("accepted", 0)
|
|
496
|
-
rejected = stats.get("rejected", 0)
|
|
497
|
-
total = accepted + rejected
|
|
498
|
-
|
|
499
|
-
if total == 0:
|
|
500
|
-
return 0.0
|
|
501
|
-
|
|
502
|
-
# Calculate acceptance rate boost (max 0.1 boost)
|
|
503
|
-
acceptance_rate = accepted / total
|
|
504
|
-
boost = (acceptance_rate - 0.5) * 0.2 # -0.1 to +0.1
|
|
505
|
-
|
|
506
|
-
return boost
|
|
507
|
-
|
|
508
|
-
def record_feedback(
|
|
509
|
-
self, suggestion_type: SuggestionType, value: str, accepted: bool
|
|
510
|
-
) -> None:
|
|
511
|
-
"""
|
|
512
|
-
Record user feedback on a suggestion.
|
|
513
|
-
|
|
514
|
-
Args:
|
|
515
|
-
suggestion_type: Type of suggestion
|
|
516
|
-
value: Suggestion value
|
|
517
|
-
accepted: Whether suggestion was accepted
|
|
518
|
-
"""
|
|
519
|
-
key = f"{suggestion_type.value}:{value}"
|
|
520
|
-
|
|
521
|
-
if key not in self.learning_data:
|
|
522
|
-
self.learning_data[key] = {"accepted": 0, "rejected": 0, "last_updated": None}
|
|
523
|
-
|
|
524
|
-
if accepted:
|
|
525
|
-
self.learning_data[key]["accepted"] += 1
|
|
526
|
-
else:
|
|
527
|
-
self.learning_data[key]["rejected"] += 1
|
|
528
|
-
|
|
529
|
-
self.learning_data[key]["last_updated"] = datetime.now().isoformat()
|
|
530
|
-
|
|
531
|
-
self._save_learning_data()
|
|
532
|
-
|
|
533
|
-
def _load_learning_data(self) -> dict[str, Any]:
|
|
534
|
-
"""Load learning data from disk."""
|
|
535
|
-
if not self.learning_data_path.exists():
|
|
536
|
-
return {}
|
|
537
|
-
|
|
538
|
-
try:
|
|
539
|
-
with open(self.learning_data_path) as f:
|
|
540
|
-
return json.load(f)
|
|
541
|
-
except Exception as e:
|
|
542
|
-
logger.warning(f"Failed to load learning data: {e}")
|
|
543
|
-
return {}
|
|
544
|
-
|
|
545
|
-
def _save_learning_data(self) -> None:
|
|
546
|
-
"""Save learning data to disk."""
|
|
547
|
-
try:
|
|
548
|
-
self.learning_data_path.parent.mkdir(parents=True, exist_ok=True)
|
|
549
|
-
with open(self.learning_data_path, "w") as f:
|
|
550
|
-
json.dump(self.learning_data, f, indent=2)
|
|
551
|
-
except Exception as e:
|
|
552
|
-
logger.warning(f"Failed to save learning data: {e}")
|
|
1
|
+
"""
|
|
2
|
+
Context-Aware Suggestion Engine
|
|
3
|
+
|
|
4
|
+
Epic 13: Context-Aware Suggestions
|
|
5
|
+
Provides intelligent suggestions for workflows, agents, and actions based on project context.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
import logging
|
|
12
|
+
from dataclasses import dataclass, field
|
|
13
|
+
from datetime import datetime
|
|
14
|
+
from enum import Enum
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from typing import Any
|
|
17
|
+
|
|
18
|
+
from ..core.project_profile import ProjectProfile, ProjectProfileDetector
|
|
19
|
+
from .context_analyzer import ContextAnalyzer, ProjectContext
|
|
20
|
+
from .recommender import WorkflowRecommendation, WorkflowRecommender
|
|
21
|
+
|
|
22
|
+
logger = logging.getLogger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# Backward compatibility: Legacy SuggestionEngine for nlp_executor
|
|
26
|
+
class SuggestionEngine:
|
|
27
|
+
"""
|
|
28
|
+
Legacy suggestion engine wrapper for backward compatibility.
|
|
29
|
+
|
|
30
|
+
This class provides a simple interface for NLP executor.
|
|
31
|
+
For new code, use ContextAwareSuggestionEngine instead.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
def __init__(self, preset_loader):
|
|
35
|
+
"""Initialize legacy suggestion engine."""
|
|
36
|
+
self.preset_loader = preset_loader
|
|
37
|
+
self.engine = ContextAwareSuggestionEngine()
|
|
38
|
+
|
|
39
|
+
def suggest_workflows(self, context):
|
|
40
|
+
"""Suggest workflows based on context (legacy interface)."""
|
|
41
|
+
suggestions = self.engine.get_suggestions(include_agents=False, include_actions=False)
|
|
42
|
+
return suggestions.workflows
|
|
43
|
+
|
|
44
|
+
def format_suggestions(self, suggestions):
|
|
45
|
+
"""Format suggestions for display (legacy interface)."""
|
|
46
|
+
if not suggestions:
|
|
47
|
+
return "No workflow suggestions available."
|
|
48
|
+
|
|
49
|
+
lines = ["## Workflow Suggestions\n"]
|
|
50
|
+
for i, suggestion in enumerate(suggestions[:5], 1): # Top 5
|
|
51
|
+
lines.append(f"{i}. **{suggestion.value}** ({suggestion.confidence:.0%} confidence)")
|
|
52
|
+
lines.append(f" {suggestion.explanation}\n")
|
|
53
|
+
|
|
54
|
+
return "\n".join(lines)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class SuggestionType(Enum):
|
|
58
|
+
"""Type of suggestion."""
|
|
59
|
+
|
|
60
|
+
WORKFLOW = "workflow"
|
|
61
|
+
AGENT = "agent"
|
|
62
|
+
ACTION = "action"
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@dataclass
|
|
66
|
+
class Suggestion:
|
|
67
|
+
"""A single suggestion with ranking and explanation."""
|
|
68
|
+
|
|
69
|
+
type: SuggestionType
|
|
70
|
+
value: str # Workflow name, agent name, or action description
|
|
71
|
+
confidence: float # 0.0 to 1.0
|
|
72
|
+
explanation: str # Why this suggestion
|
|
73
|
+
context_matches: list[str] = field(default_factory=list) # What context matched
|
|
74
|
+
metadata: dict[str, Any] = field(default_factory=dict)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@dataclass
|
|
78
|
+
class SuggestionSet:
|
|
79
|
+
"""A set of suggestions for a context."""
|
|
80
|
+
|
|
81
|
+
workflows: list[Suggestion] = field(default_factory=list)
|
|
82
|
+
agents: list[Suggestion] = field(default_factory=list)
|
|
83
|
+
actions: list[Suggestion] = field(default_factory=list)
|
|
84
|
+
context: ProjectContext | None = None
|
|
85
|
+
project_profile: ProjectProfile | None = None
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class ContextAwareSuggestionEngine:
|
|
89
|
+
"""
|
|
90
|
+
Context-aware suggestion engine.
|
|
91
|
+
|
|
92
|
+
Analyzes project context and provides intelligent suggestions for:
|
|
93
|
+
- Workflows to use
|
|
94
|
+
- Agents to employ
|
|
95
|
+
- Actions to take
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
# Agent mapping based on task context
|
|
99
|
+
AGENT_MAPPING = {
|
|
100
|
+
"requirements": ["analyst", "po"],
|
|
101
|
+
"design": ["architect", "ux-expert"],
|
|
102
|
+
"implementation": ["dev"],
|
|
103
|
+
"testing": ["qa"],
|
|
104
|
+
"review": ["reviewer"],
|
|
105
|
+
"documentation": ["documenter"],
|
|
106
|
+
"planning": ["pm", "po"],
|
|
107
|
+
"security": ["security"],
|
|
108
|
+
"deployment": ["ops"],
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
# Action suggestions based on context
|
|
112
|
+
ACTION_PATTERNS = {
|
|
113
|
+
"new_feature": [
|
|
114
|
+
"Run requirements analysis workflow",
|
|
115
|
+
"Create feature branch",
|
|
116
|
+
"Set up testing framework",
|
|
117
|
+
],
|
|
118
|
+
"bug_fix": [
|
|
119
|
+
"Run fix workflow",
|
|
120
|
+
"Create test case for bug",
|
|
121
|
+
"Review related code",
|
|
122
|
+
],
|
|
123
|
+
"refactoring": [
|
|
124
|
+
"Run full SDLC workflow",
|
|
125
|
+
"Update documentation",
|
|
126
|
+
"Run comprehensive tests",
|
|
127
|
+
],
|
|
128
|
+
"documentation": [
|
|
129
|
+
"Run documentation workflow",
|
|
130
|
+
"Review existing docs",
|
|
131
|
+
"Update API documentation",
|
|
132
|
+
],
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
def __init__(self, project_root: Path | None = None):
|
|
136
|
+
"""
|
|
137
|
+
Initialize suggestion engine.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
project_root: Project root directory
|
|
141
|
+
"""
|
|
142
|
+
self.project_root = Path(project_root) if project_root else Path.cwd()
|
|
143
|
+
self.context_analyzer = ContextAnalyzer(project_root)
|
|
144
|
+
self.workflow_recommender = WorkflowRecommender(project_root)
|
|
145
|
+
self.profile_detector = ProjectProfileDetector(project_root)
|
|
146
|
+
self.learning_data_path = self.project_root / ".tapps-agents" / "suggestion_learning.json"
|
|
147
|
+
self.learning_data: dict[str, Any] = self._load_learning_data()
|
|
148
|
+
|
|
149
|
+
def get_suggestions(
|
|
150
|
+
self,
|
|
151
|
+
user_query: str | None = None,
|
|
152
|
+
include_workflows: bool = True,
|
|
153
|
+
include_agents: bool = True,
|
|
154
|
+
include_actions: bool = True,
|
|
155
|
+
) -> SuggestionSet:
|
|
156
|
+
"""
|
|
157
|
+
Get context-aware suggestions.
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
user_query: Optional user query for context
|
|
161
|
+
include_workflows: Whether to include workflow suggestions
|
|
162
|
+
include_agents: Whether to include agent suggestions
|
|
163
|
+
include_actions: Whether to include action suggestions
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
SuggestionSet with all suggestions
|
|
167
|
+
"""
|
|
168
|
+
# Analyze context
|
|
169
|
+
context = self.context_analyzer.analyze()
|
|
170
|
+
|
|
171
|
+
# Get project profile
|
|
172
|
+
try:
|
|
173
|
+
project_profile = self.profile_detector.detect()
|
|
174
|
+
except Exception as e:
|
|
175
|
+
logger.warning(f"Failed to detect project profile: {e}")
|
|
176
|
+
project_profile = None
|
|
177
|
+
|
|
178
|
+
suggestions = SuggestionSet(context=context, project_profile=project_profile)
|
|
179
|
+
|
|
180
|
+
# Get workflow suggestions
|
|
181
|
+
if include_workflows:
|
|
182
|
+
suggestions.workflows = self._suggest_workflows(context, user_query)
|
|
183
|
+
|
|
184
|
+
# Get agent suggestions
|
|
185
|
+
if include_agents:
|
|
186
|
+
suggestions.agents = self._suggest_agents(context, user_query)
|
|
187
|
+
|
|
188
|
+
# Get action suggestions
|
|
189
|
+
if include_actions:
|
|
190
|
+
suggestions.actions = self._suggest_actions(context, user_query)
|
|
191
|
+
|
|
192
|
+
return suggestions
|
|
193
|
+
|
|
194
|
+
def _suggest_workflows(
|
|
195
|
+
self, context: ProjectContext, user_query: str | None = None
|
|
196
|
+
) -> list[Suggestion]:
|
|
197
|
+
"""Suggest workflows based on context."""
|
|
198
|
+
suggestions = []
|
|
199
|
+
|
|
200
|
+
try:
|
|
201
|
+
# Use workflow recommender
|
|
202
|
+
recommendation = self.workflow_recommender.recommend(user_query=user_query)
|
|
203
|
+
|
|
204
|
+
if recommendation.workflow_file:
|
|
205
|
+
suggestions.append(
|
|
206
|
+
Suggestion(
|
|
207
|
+
type=SuggestionType.WORKFLOW,
|
|
208
|
+
value=recommendation.workflow_file,
|
|
209
|
+
confidence=recommendation.confidence,
|
|
210
|
+
explanation=recommendation.message,
|
|
211
|
+
context_matches=self._extract_context_matches(context, recommendation),
|
|
212
|
+
metadata={
|
|
213
|
+
"track": recommendation.track.value,
|
|
214
|
+
"characteristics": recommendation.characteristics.__dict__ if hasattr(recommendation.characteristics, '__dict__') else {},
|
|
215
|
+
},
|
|
216
|
+
)
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
# Add alternative workflows
|
|
220
|
+
for alt_workflow in recommendation.alternative_workflows[:3]: # Top 3 alternatives
|
|
221
|
+
suggestions.append(
|
|
222
|
+
Suggestion(
|
|
223
|
+
type=SuggestionType.WORKFLOW,
|
|
224
|
+
value=alt_workflow,
|
|
225
|
+
confidence=recommendation.confidence * 0.7, # Lower confidence for alternatives
|
|
226
|
+
explanation=f"Alternative workflow: {alt_workflow}",
|
|
227
|
+
context_matches=[],
|
|
228
|
+
)
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
except Exception as e:
|
|
232
|
+
logger.warning(f"Failed to suggest workflows: {e}")
|
|
233
|
+
|
|
234
|
+
# Apply learning-based ranking
|
|
235
|
+
suggestions = self._apply_learning_ranking(suggestions, "workflow")
|
|
236
|
+
|
|
237
|
+
return sorted(suggestions, key=lambda s: s.confidence, reverse=True)
|
|
238
|
+
|
|
239
|
+
def _suggest_agents(
|
|
240
|
+
self, context: ProjectContext, user_query: str | None = None
|
|
241
|
+
) -> list[Suggestion]:
|
|
242
|
+
"""Suggest agents based on context."""
|
|
243
|
+
suggestions = []
|
|
244
|
+
|
|
245
|
+
# Analyze context to determine task type
|
|
246
|
+
task_type = self._infer_task_type(context, user_query)
|
|
247
|
+
|
|
248
|
+
# Get agents for task type
|
|
249
|
+
agent_names = self.AGENT_MAPPING.get(task_type, ["dev"])
|
|
250
|
+
|
|
251
|
+
for agent_name in agent_names:
|
|
252
|
+
confidence = self._calculate_agent_confidence(agent_name, context, task_type)
|
|
253
|
+
explanation = self._generate_agent_explanation(agent_name, task_type, context)
|
|
254
|
+
|
|
255
|
+
suggestions.append(
|
|
256
|
+
Suggestion(
|
|
257
|
+
type=SuggestionType.AGENT,
|
|
258
|
+
value=agent_name,
|
|
259
|
+
confidence=confidence,
|
|
260
|
+
explanation=explanation,
|
|
261
|
+
context_matches=[task_type] if task_type else [],
|
|
262
|
+
metadata={"task_type": task_type},
|
|
263
|
+
)
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
# Apply learning-based ranking
|
|
267
|
+
suggestions = self._apply_learning_ranking(suggestions, "agent")
|
|
268
|
+
|
|
269
|
+
return sorted(suggestions, key=lambda s: s.confidence, reverse=True)
|
|
270
|
+
|
|
271
|
+
def _suggest_actions(
|
|
272
|
+
self, context: ProjectContext, user_query: str | None = None
|
|
273
|
+
) -> list[Suggestion]:
|
|
274
|
+
"""Suggest actions based on context."""
|
|
275
|
+
suggestions = []
|
|
276
|
+
|
|
277
|
+
# Infer action context
|
|
278
|
+
action_context = self._infer_action_context(context, user_query)
|
|
279
|
+
|
|
280
|
+
# Get action patterns for context
|
|
281
|
+
action_patterns = self.ACTION_PATTERNS.get(action_context, [])
|
|
282
|
+
|
|
283
|
+
for action in action_patterns:
|
|
284
|
+
confidence = self._calculate_action_confidence(action, context, action_context)
|
|
285
|
+
explanation = self._generate_action_explanation(action, action_context, context)
|
|
286
|
+
|
|
287
|
+
suggestions.append(
|
|
288
|
+
Suggestion(
|
|
289
|
+
type=SuggestionType.ACTION,
|
|
290
|
+
value=action,
|
|
291
|
+
confidence=confidence,
|
|
292
|
+
explanation=explanation,
|
|
293
|
+
context_matches=[action_context] if action_context else [],
|
|
294
|
+
metadata={"action_context": action_context},
|
|
295
|
+
)
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
# Apply learning-based ranking
|
|
299
|
+
suggestions = self._apply_learning_ranking(suggestions, "action")
|
|
300
|
+
|
|
301
|
+
return sorted(suggestions, key=lambda s: s.confidence, reverse=True)
|
|
302
|
+
|
|
303
|
+
def _infer_task_type(self, context: ProjectContext, user_query: str | None = None) -> str:
|
|
304
|
+
"""Infer task type from context."""
|
|
305
|
+
if user_query:
|
|
306
|
+
query_lower = user_query.lower()
|
|
307
|
+
if any(word in query_lower for word in ["requirement", "analyze", "spec"]):
|
|
308
|
+
return "requirements"
|
|
309
|
+
if any(word in query_lower for word in ["design", "architecture", "structure"]):
|
|
310
|
+
return "design"
|
|
311
|
+
if any(word in query_lower for word in ["test", "testing", "qa"]):
|
|
312
|
+
return "testing"
|
|
313
|
+
if any(word in query_lower for word in ["review", "code review"]):
|
|
314
|
+
return "review"
|
|
315
|
+
if any(word in query_lower for word in ["document", "docs", "readme"]):
|
|
316
|
+
return "documentation"
|
|
317
|
+
if any(word in query_lower for word in ["plan", "planning", "roadmap"]):
|
|
318
|
+
return "planning"
|
|
319
|
+
if any(word in query_lower for word in ["security", "secure", "vulnerability"]):
|
|
320
|
+
return "security"
|
|
321
|
+
if any(word in query_lower for word in ["deploy", "deployment", "ops"]):
|
|
322
|
+
return "deployment"
|
|
323
|
+
|
|
324
|
+
# Infer from branch name
|
|
325
|
+
if context.branch_name:
|
|
326
|
+
branch_lower = context.branch_name.lower()
|
|
327
|
+
if "feature" in branch_lower or "feat" in branch_lower:
|
|
328
|
+
return "implementation"
|
|
329
|
+
if "fix" in branch_lower or "bug" in branch_lower:
|
|
330
|
+
return "testing"
|
|
331
|
+
if "doc" in branch_lower:
|
|
332
|
+
return "documentation"
|
|
333
|
+
if "refactor" in branch_lower:
|
|
334
|
+
return "implementation"
|
|
335
|
+
|
|
336
|
+
# Infer from file changes
|
|
337
|
+
if context.recent_changes:
|
|
338
|
+
file_types = self._analyze_file_types(context.recent_changes)
|
|
339
|
+
if file_types.get("test", 0) > 0:
|
|
340
|
+
return "testing"
|
|
341
|
+
if file_types.get("doc", 0) > 0:
|
|
342
|
+
return "documentation"
|
|
343
|
+
|
|
344
|
+
return "implementation" # Default
|
|
345
|
+
|
|
346
|
+
def _infer_action_context(self, context: ProjectContext, user_query: str | None = None) -> str:
|
|
347
|
+
"""Infer action context from project state."""
|
|
348
|
+
if user_query:
|
|
349
|
+
query_lower = user_query.lower()
|
|
350
|
+
if any(word in query_lower for word in ["new", "feature", "add"]):
|
|
351
|
+
return "new_feature"
|
|
352
|
+
if any(word in query_lower for word in ["fix", "bug", "error"]):
|
|
353
|
+
return "bug_fix"
|
|
354
|
+
if any(word in query_lower for word in ["refactor", "restructure"]):
|
|
355
|
+
return "refactoring"
|
|
356
|
+
if any(word in query_lower for word in ["document", "docs"]):
|
|
357
|
+
return "documentation"
|
|
358
|
+
|
|
359
|
+
# Infer from branch name
|
|
360
|
+
if context.branch_name:
|
|
361
|
+
branch_lower = context.branch_name.lower()
|
|
362
|
+
if "feature" in branch_lower:
|
|
363
|
+
return "new_feature"
|
|
364
|
+
if "fix" in branch_lower or "bug" in branch_lower:
|
|
365
|
+
return "bug_fix"
|
|
366
|
+
if "refactor" in branch_lower:
|
|
367
|
+
return "refactoring"
|
|
368
|
+
|
|
369
|
+
# Infer from file changes
|
|
370
|
+
if context.modified_files_count > 20:
|
|
371
|
+
return "refactoring"
|
|
372
|
+
elif context.modified_files_count > 5:
|
|
373
|
+
return "new_feature"
|
|
374
|
+
else:
|
|
375
|
+
return "bug_fix"
|
|
376
|
+
|
|
377
|
+
def _analyze_file_types(self, files: list[str]) -> dict[str, int]:
|
|
378
|
+
"""Analyze file types in changed files."""
|
|
379
|
+
types = {"test": 0, "doc": 0, "code": 0}
|
|
380
|
+
for file in files:
|
|
381
|
+
file_lower = file.lower()
|
|
382
|
+
if "test" in file_lower or "spec" in file_lower:
|
|
383
|
+
types["test"] += 1
|
|
384
|
+
elif any(ext in file_lower for ext in [".md", ".txt", ".rst"]):
|
|
385
|
+
types["doc"] += 1
|
|
386
|
+
else:
|
|
387
|
+
types["code"] += 1
|
|
388
|
+
return types
|
|
389
|
+
|
|
390
|
+
def _calculate_agent_confidence(
|
|
391
|
+
self, agent_name: str, context: ProjectContext, task_type: str
|
|
392
|
+
) -> float:
|
|
393
|
+
"""Calculate confidence for agent suggestion."""
|
|
394
|
+
base_confidence = 0.7
|
|
395
|
+
|
|
396
|
+
# Boost confidence if agent matches task type
|
|
397
|
+
if task_type in self.AGENT_MAPPING and agent_name in self.AGENT_MAPPING[task_type]:
|
|
398
|
+
base_confidence += 0.2
|
|
399
|
+
|
|
400
|
+
# Apply learning-based adjustments
|
|
401
|
+
learning_boost = self._get_learning_boost(agent_name, "agent")
|
|
402
|
+
base_confidence += learning_boost
|
|
403
|
+
|
|
404
|
+
return min(1.0, max(0.0, base_confidence))
|
|
405
|
+
|
|
406
|
+
def _calculate_action_confidence(
|
|
407
|
+
self, action: str, context: ProjectContext, action_context: str
|
|
408
|
+
) -> float:
|
|
409
|
+
"""Calculate confidence for action suggestion."""
|
|
410
|
+
base_confidence = 0.6
|
|
411
|
+
|
|
412
|
+
# Boost confidence if action matches context
|
|
413
|
+
if action_context in self.ACTION_PATTERNS and action in self.ACTION_PATTERNS[action_context]:
|
|
414
|
+
base_confidence += 0.2
|
|
415
|
+
|
|
416
|
+
# Apply learning-based adjustments
|
|
417
|
+
learning_boost = self._get_learning_boost(action, "action")
|
|
418
|
+
base_confidence += learning_boost
|
|
419
|
+
|
|
420
|
+
return min(1.0, max(0.0, base_confidence))
|
|
421
|
+
|
|
422
|
+
def _generate_agent_explanation(
|
|
423
|
+
self, agent_name: str, task_type: str, context: ProjectContext
|
|
424
|
+
) -> str:
|
|
425
|
+
"""Generate explanation for agent suggestion."""
|
|
426
|
+
explanations = {
|
|
427
|
+
"analyst": "Best for requirements analysis and gathering",
|
|
428
|
+
"architect": "Best for system design and architecture",
|
|
429
|
+
"dev": "Best for implementation and coding tasks",
|
|
430
|
+
"qa": "Best for testing and quality assurance",
|
|
431
|
+
"reviewer": "Best for code review and quality gates",
|
|
432
|
+
"documenter": "Best for documentation tasks",
|
|
433
|
+
"pm": "Best for project planning and management",
|
|
434
|
+
"po": "Best for product ownership and requirements",
|
|
435
|
+
}
|
|
436
|
+
base_explanation = explanations.get(agent_name, f"Recommended for {task_type} tasks")
|
|
437
|
+
|
|
438
|
+
if context.branch_name:
|
|
439
|
+
base_explanation += f" (current branch: {context.branch_name})"
|
|
440
|
+
|
|
441
|
+
return base_explanation
|
|
442
|
+
|
|
443
|
+
def _generate_action_explanation(
|
|
444
|
+
self, action: str, action_context: str, context: ProjectContext
|
|
445
|
+
) -> str:
|
|
446
|
+
"""Generate explanation for action suggestion."""
|
|
447
|
+
explanations = {
|
|
448
|
+
"new_feature": "Starting a new feature - recommended workflow",
|
|
449
|
+
"bug_fix": "Fixing a bug - quick workflow recommended",
|
|
450
|
+
"refactoring": "Refactoring code - comprehensive workflow recommended",
|
|
451
|
+
"documentation": "Documentation work - documentation workflow recommended",
|
|
452
|
+
}
|
|
453
|
+
base_explanation = explanations.get(action_context, "Recommended based on project context")
|
|
454
|
+
|
|
455
|
+
if context.modified_files_count > 0:
|
|
456
|
+
base_explanation += f" ({context.modified_files_count} files modified)"
|
|
457
|
+
|
|
458
|
+
return base_explanation
|
|
459
|
+
|
|
460
|
+
def _extract_context_matches(
|
|
461
|
+
self, context: ProjectContext, recommendation: WorkflowRecommendation
|
|
462
|
+
) -> list[str]:
|
|
463
|
+
"""Extract context matches for explanation."""
|
|
464
|
+
matches = []
|
|
465
|
+
|
|
466
|
+
if context.branch_name:
|
|
467
|
+
matches.append(f"Branch: {context.branch_name}")
|
|
468
|
+
|
|
469
|
+
if context.project_type:
|
|
470
|
+
matches.append(f"Project type: {context.project_type}")
|
|
471
|
+
|
|
472
|
+
if context.modified_files_count > 0:
|
|
473
|
+
matches.append(f"{context.modified_files_count} files modified")
|
|
474
|
+
|
|
475
|
+
return matches
|
|
476
|
+
|
|
477
|
+
def _apply_learning_ranking(
|
|
478
|
+
self, suggestions: list[Suggestion], suggestion_type: str
|
|
479
|
+
) -> list[Suggestion]:
|
|
480
|
+
"""Apply learning-based ranking adjustments."""
|
|
481
|
+
for suggestion in suggestions:
|
|
482
|
+
learning_boost = self._get_learning_boost(suggestion.value, suggestion_type)
|
|
483
|
+
suggestion.confidence = min(1.0, suggestion.confidence + learning_boost)
|
|
484
|
+
|
|
485
|
+
return suggestions
|
|
486
|
+
|
|
487
|
+
def _get_learning_boost(self, value: str, suggestion_type: str) -> float:
|
|
488
|
+
"""Get learning-based confidence boost."""
|
|
489
|
+
if not self.learning_data:
|
|
490
|
+
return 0.0
|
|
491
|
+
|
|
492
|
+
key = f"{suggestion_type}:{value}"
|
|
493
|
+
stats = self.learning_data.get(key, {})
|
|
494
|
+
|
|
495
|
+
accepted = stats.get("accepted", 0)
|
|
496
|
+
rejected = stats.get("rejected", 0)
|
|
497
|
+
total = accepted + rejected
|
|
498
|
+
|
|
499
|
+
if total == 0:
|
|
500
|
+
return 0.0
|
|
501
|
+
|
|
502
|
+
# Calculate acceptance rate boost (max 0.1 boost)
|
|
503
|
+
acceptance_rate = accepted / total
|
|
504
|
+
boost = (acceptance_rate - 0.5) * 0.2 # -0.1 to +0.1
|
|
505
|
+
|
|
506
|
+
return boost
|
|
507
|
+
|
|
508
|
+
def record_feedback(
|
|
509
|
+
self, suggestion_type: SuggestionType, value: str, accepted: bool
|
|
510
|
+
) -> None:
|
|
511
|
+
"""
|
|
512
|
+
Record user feedback on a suggestion.
|
|
513
|
+
|
|
514
|
+
Args:
|
|
515
|
+
suggestion_type: Type of suggestion
|
|
516
|
+
value: Suggestion value
|
|
517
|
+
accepted: Whether suggestion was accepted
|
|
518
|
+
"""
|
|
519
|
+
key = f"{suggestion_type.value}:{value}"
|
|
520
|
+
|
|
521
|
+
if key not in self.learning_data:
|
|
522
|
+
self.learning_data[key] = {"accepted": 0, "rejected": 0, "last_updated": None}
|
|
523
|
+
|
|
524
|
+
if accepted:
|
|
525
|
+
self.learning_data[key]["accepted"] += 1
|
|
526
|
+
else:
|
|
527
|
+
self.learning_data[key]["rejected"] += 1
|
|
528
|
+
|
|
529
|
+
self.learning_data[key]["last_updated"] = datetime.now().isoformat()
|
|
530
|
+
|
|
531
|
+
self._save_learning_data()
|
|
532
|
+
|
|
533
|
+
def _load_learning_data(self) -> dict[str, Any]:
|
|
534
|
+
"""Load learning data from disk."""
|
|
535
|
+
if not self.learning_data_path.exists():
|
|
536
|
+
return {}
|
|
537
|
+
|
|
538
|
+
try:
|
|
539
|
+
with open(self.learning_data_path) as f:
|
|
540
|
+
return json.load(f)
|
|
541
|
+
except Exception as e:
|
|
542
|
+
logger.warning(f"Failed to load learning data: {e}")
|
|
543
|
+
return {}
|
|
544
|
+
|
|
545
|
+
def _save_learning_data(self) -> None:
|
|
546
|
+
"""Save learning data to disk."""
|
|
547
|
+
try:
|
|
548
|
+
self.learning_data_path.parent.mkdir(parents=True, exist_ok=True)
|
|
549
|
+
with open(self.learning_data_path, "w") as f:
|
|
550
|
+
json.dump(self.learning_data, f, indent=2)
|
|
551
|
+
except Exception as e:
|
|
552
|
+
logger.warning(f"Failed to save learning data: {e}")
|