tapps-agents 3.6.0__py3-none-any.whl → 3.6.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/service_discovery.py +534 -534
- 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/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 -227
- tapps_agents/cli/commands/tester.py +191 -191
- 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/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/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.backup_20260204_064058.py +324 -0
- tapps_agents/health/checks/outcomes.backup_20260204_064256.py +324 -0
- tapps_agents/health/checks/outcomes.backup_20260204_064600.py +324 -0
- 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/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/resources/__init__.py +5 -0
- tapps_agents/resources/claude/__init__.py +1 -0
- tapps_agents/resources/claude/commands/README.md +156 -0
- tapps_agents/resources/claude/commands/__init__.py +1 -0
- tapps_agents/resources/claude/commands/build-fix.md +22 -0
- tapps_agents/resources/claude/commands/build.md +77 -0
- tapps_agents/resources/claude/commands/debug.md +53 -0
- tapps_agents/resources/claude/commands/design.md +68 -0
- tapps_agents/resources/claude/commands/docs.md +53 -0
- tapps_agents/resources/claude/commands/e2e.md +22 -0
- tapps_agents/resources/claude/commands/fix.md +54 -0
- tapps_agents/resources/claude/commands/implement.md +53 -0
- tapps_agents/resources/claude/commands/improve.md +53 -0
- tapps_agents/resources/claude/commands/library-docs.md +64 -0
- tapps_agents/resources/claude/commands/lint.md +52 -0
- tapps_agents/resources/claude/commands/plan.md +65 -0
- tapps_agents/resources/claude/commands/refactor-clean.md +21 -0
- tapps_agents/resources/claude/commands/refactor.md +55 -0
- tapps_agents/resources/claude/commands/review.md +67 -0
- tapps_agents/resources/claude/commands/score.md +60 -0
- tapps_agents/resources/claude/commands/security-review.md +22 -0
- tapps_agents/resources/claude/commands/security-scan.md +54 -0
- tapps_agents/resources/claude/commands/tdd.md +24 -0
- tapps_agents/resources/claude/commands/test-coverage.md +21 -0
- tapps_agents/resources/claude/commands/test.md +54 -0
- tapps_agents/resources/claude/commands/update-codemaps.md +20 -0
- tapps_agents/resources/claude/commands/update-docs.md +21 -0
- tapps_agents/resources/claude/skills/__init__.py +1 -0
- tapps_agents/resources/claude/skills/analyst/SKILL.md +272 -0
- tapps_agents/resources/claude/skills/analyst/__init__.py +1 -0
- tapps_agents/resources/claude/skills/architect/SKILL.md +282 -0
- tapps_agents/resources/claude/skills/architect/__init__.py +1 -0
- tapps_agents/resources/claude/skills/backend-patterns/SKILL.md +30 -0
- tapps_agents/resources/claude/skills/backend-patterns/__init__.py +1 -0
- tapps_agents/resources/claude/skills/coding-standards/SKILL.md +29 -0
- tapps_agents/resources/claude/skills/coding-standards/__init__.py +1 -0
- tapps_agents/resources/claude/skills/debugger/SKILL.md +203 -0
- tapps_agents/resources/claude/skills/debugger/__init__.py +1 -0
- tapps_agents/resources/claude/skills/designer/SKILL.md +243 -0
- tapps_agents/resources/claude/skills/designer/__init__.py +1 -0
- tapps_agents/resources/claude/skills/documenter/SKILL.md +252 -0
- tapps_agents/resources/claude/skills/documenter/__init__.py +1 -0
- tapps_agents/resources/claude/skills/enhancer/SKILL.md +307 -0
- tapps_agents/resources/claude/skills/enhancer/__init__.py +1 -0
- tapps_agents/resources/claude/skills/evaluator/SKILL.md +204 -0
- tapps_agents/resources/claude/skills/evaluator/__init__.py +1 -0
- tapps_agents/resources/claude/skills/frontend-patterns/SKILL.md +29 -0
- tapps_agents/resources/claude/skills/frontend-patterns/__init__.py +1 -0
- tapps_agents/resources/claude/skills/implementer/SKILL.md +188 -0
- tapps_agents/resources/claude/skills/implementer/__init__.py +1 -0
- tapps_agents/resources/claude/skills/improver/SKILL.md +218 -0
- tapps_agents/resources/claude/skills/improver/__init__.py +1 -0
- tapps_agents/resources/claude/skills/ops/SKILL.md +281 -0
- tapps_agents/resources/claude/skills/ops/__init__.py +1 -0
- tapps_agents/resources/claude/skills/orchestrator/SKILL.md +390 -0
- tapps_agents/resources/claude/skills/orchestrator/__init__.py +1 -0
- tapps_agents/resources/claude/skills/planner/SKILL.md +254 -0
- tapps_agents/resources/claude/skills/planner/__init__.py +1 -0
- tapps_agents/resources/claude/skills/reviewer/SKILL.md +434 -0
- tapps_agents/resources/claude/skills/reviewer/__init__.py +1 -0
- tapps_agents/resources/claude/skills/security-review/SKILL.md +31 -0
- tapps_agents/resources/claude/skills/security-review/__init__.py +1 -0
- tapps_agents/resources/claude/skills/simple-mode/SKILL.md +695 -0
- tapps_agents/resources/claude/skills/simple-mode/__init__.py +1 -0
- tapps_agents/resources/claude/skills/tester/SKILL.md +219 -0
- tapps_agents/resources/claude/skills/tester/__init__.py +1 -0
- tapps_agents/resources/cursor/.cursorignore +35 -0
- tapps_agents/resources/cursor/__init__.py +1 -0
- tapps_agents/resources/cursor/commands/__init__.py +1 -0
- tapps_agents/resources/cursor/commands/build-fix.md +11 -0
- tapps_agents/resources/cursor/commands/build.md +11 -0
- tapps_agents/resources/cursor/commands/e2e.md +11 -0
- tapps_agents/resources/cursor/commands/fix.md +11 -0
- tapps_agents/resources/cursor/commands/refactor-clean.md +11 -0
- tapps_agents/resources/cursor/commands/review.md +11 -0
- tapps_agents/resources/cursor/commands/security-review.md +11 -0
- tapps_agents/resources/cursor/commands/tdd.md +11 -0
- tapps_agents/resources/cursor/commands/test-coverage.md +11 -0
- tapps_agents/resources/cursor/commands/test.md +11 -0
- tapps_agents/resources/cursor/commands/update-codemaps.md +10 -0
- tapps_agents/resources/cursor/commands/update-docs.md +11 -0
- tapps_agents/resources/cursor/rules/__init__.py +1 -0
- tapps_agents/resources/cursor/rules/agent-capabilities.mdc +687 -0
- tapps_agents/resources/cursor/rules/coding-style.mdc +31 -0
- tapps_agents/resources/cursor/rules/command-reference.mdc +2081 -0
- tapps_agents/resources/cursor/rules/cursor-mode-usage.mdc +125 -0
- tapps_agents/resources/cursor/rules/git-workflow.mdc +29 -0
- tapps_agents/resources/cursor/rules/performance.mdc +29 -0
- tapps_agents/resources/cursor/rules/project-context.mdc +163 -0
- tapps_agents/resources/cursor/rules/project-profiling.mdc +197 -0
- tapps_agents/resources/cursor/rules/quick-reference.mdc +630 -0
- tapps_agents/resources/cursor/rules/security.mdc +32 -0
- tapps_agents/resources/cursor/rules/simple-mode.mdc +500 -0
- tapps_agents/resources/cursor/rules/testing.mdc +31 -0
- tapps_agents/resources/cursor/rules/when-to-use.mdc +156 -0
- tapps_agents/resources/cursor/rules/workflow-presets.mdc +179 -0
- tapps_agents/resources/customizations/__init__.py +1 -0
- tapps_agents/resources/customizations/example-custom.yaml +83 -0
- tapps_agents/resources/hooks/__init__.py +1 -0
- tapps_agents/resources/hooks/templates/README.md +5 -0
- tapps_agents/resources/hooks/templates/__init__.py +1 -0
- tapps_agents/resources/hooks/templates/add-project-context.yaml +8 -0
- tapps_agents/resources/hooks/templates/auto-format-js.yaml +10 -0
- tapps_agents/resources/hooks/templates/auto-format-python.yaml +10 -0
- tapps_agents/resources/hooks/templates/git-commit-check.yaml +7 -0
- tapps_agents/resources/hooks/templates/notify-on-complete.yaml +8 -0
- tapps_agents/resources/hooks/templates/quality-gate.yaml +8 -0
- tapps_agents/resources/hooks/templates/security-scan-on-edit.yaml +10 -0
- tapps_agents/resources/hooks/templates/session-end-log.yaml +7 -0
- tapps_agents/resources/hooks/templates/show-beads-ready.yaml +8 -0
- tapps_agents/resources/hooks/templates/test-on-edit.yaml +10 -0
- tapps_agents/resources/hooks/templates/update-docs-on-complete.yaml +8 -0
- tapps_agents/resources/hooks/templates/user-prompt-log.yaml +7 -0
- tapps_agents/resources/scripts/__init__.py +1 -0
- tapps_agents/resources/scripts/set_bd_path.ps1 +51 -0
- tapps_agents/resources/workflows/__init__.py +1 -0
- tapps_agents/resources/workflows/presets/__init__.py +1 -0
- tapps_agents/resources/workflows/presets/brownfield-analysis.yaml +235 -0
- tapps_agents/resources/workflows/presets/fix.yaml +78 -0
- tapps_agents/resources/workflows/presets/full-sdlc.yaml +122 -0
- tapps_agents/resources/workflows/presets/quality.yaml +82 -0
- tapps_agents/resources/workflows/presets/rapid-dev.yaml +84 -0
- 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/breakdown_orchestrator.py +49 -49
- tapps_agents/simple_mode/orchestrators/brownfield_orchestrator.py +135 -135
- 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/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_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/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 -148
- 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.6.0.dist-info → tapps_agents-3.6.1.dist-info}/METADATA +672 -672
- tapps_agents-3.6.1.dist-info/RECORD +883 -0
- {tapps_agents-3.6.0.dist-info → tapps_agents-3.6.1.dist-info}/licenses/LICENSE +22 -22
- tapps_agents-3.6.0.dist-info/RECORD +0 -758
- {tapps_agents-3.6.0.dist-info → tapps_agents-3.6.1.dist-info}/WHEEL +0 -0
- {tapps_agents-3.6.0.dist-info → tapps_agents-3.6.1.dist-info}/entry_points.txt +0 -0
- {tapps_agents-3.6.0.dist-info → tapps_agents-3.6.1.dist-info}/top_level.txt +0 -0
|
@@ -1,528 +1,528 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Natural Language Parser for Workflow Triggers
|
|
3
|
-
|
|
4
|
-
Parses natural language input to extract workflow intent and match workflows.
|
|
5
|
-
Epic 9 / Story 9.1: Natural Language Parser Foundation
|
|
6
|
-
Epic 9 / Story 9.2: Workflow Intent Detection
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
import difflib
|
|
10
|
-
import re
|
|
11
|
-
from dataclasses import dataclass, field
|
|
12
|
-
from typing import Any
|
|
13
|
-
|
|
14
|
-
from .preset_loader import PRESET_ALIASES, PresetLoader
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@dataclass
|
|
18
|
-
class WorkflowIntent:
|
|
19
|
-
"""Parsed workflow intent result."""
|
|
20
|
-
|
|
21
|
-
intent_type: str # "workflow_trigger", "workflow_query", "unknown"
|
|
22
|
-
workflow_name: str | None # Matched workflow name (canonical)
|
|
23
|
-
confidence: float # 0.0 to 1.0
|
|
24
|
-
aliases_matched: list[str] # Aliases that matched
|
|
25
|
-
raw_input: str # Original input
|
|
26
|
-
match_type: str | None = None # "exact", "partial", "fuzzy", "alias", "synonym"
|
|
27
|
-
alternative_matches: list[tuple[str, float]] | None = None # (workflow_name, confidence)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
@dataclass
|
|
31
|
-
class WorkflowIntentResult:
|
|
32
|
-
"""Complete intent detection result with action verb and parameters."""
|
|
33
|
-
|
|
34
|
-
action_verb: str | None # "run", "execute", "start", "trigger", etc.
|
|
35
|
-
workflow_type: str | None # Detected workflow type/category
|
|
36
|
-
workflow_name: str | None # Matched workflow name
|
|
37
|
-
parameters: dict[str, Any] = field(default_factory=dict) # Extracted parameters
|
|
38
|
-
ambiguity_flag: bool = False # True if multiple workflows match
|
|
39
|
-
suggestions: list[str] = field(default_factory=list) # Alternative workflows
|
|
40
|
-
confidence: float = 0.0 # Overall confidence score
|
|
41
|
-
intent_confidence: float = 0.0 # Confidence in intent detection
|
|
42
|
-
workflow_confidence: float = 0.0 # Confidence in workflow matching
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
# Workflow synonyms for natural language matching
|
|
46
|
-
WORKFLOW_SYNONYMS: dict[str, list[str]] = {
|
|
47
|
-
"full-sdlc": [
|
|
48
|
-
"full sdlc",
|
|
49
|
-
"full software development lifecycle",
|
|
50
|
-
"complete sdlc",
|
|
51
|
-
"enterprise workflow",
|
|
52
|
-
"full pipeline",
|
|
53
|
-
"complete workflow",
|
|
54
|
-
],
|
|
55
|
-
"rapid-dev": [
|
|
56
|
-
"rapid development",
|
|
57
|
-
"rapid dev",
|
|
58
|
-
"quick development",
|
|
59
|
-
"fast development",
|
|
60
|
-
"feature development",
|
|
61
|
-
"sprint workflow",
|
|
62
|
-
],
|
|
63
|
-
"fix": [
|
|
64
|
-
"fix workflow",
|
|
65
|
-
"maintenance workflow",
|
|
66
|
-
"bug fix",
|
|
67
|
-
"bug fixing",
|
|
68
|
-
"refactoring",
|
|
69
|
-
"technical debt",
|
|
70
|
-
"code improvement",
|
|
71
|
-
"quick fix",
|
|
72
|
-
"hotfix",
|
|
73
|
-
"urgent fix",
|
|
74
|
-
"emergency fix",
|
|
75
|
-
"critical fix",
|
|
76
|
-
"patch",
|
|
77
|
-
],
|
|
78
|
-
"quality": [
|
|
79
|
-
"quality improvement",
|
|
80
|
-
"code quality",
|
|
81
|
-
"quality workflow",
|
|
82
|
-
"code review",
|
|
83
|
-
"quality check",
|
|
84
|
-
],
|
|
85
|
-
"brownfield-analysis": [
|
|
86
|
-
"brownfield",
|
|
87
|
-
"brownfield analysis",
|
|
88
|
-
"existing codebase",
|
|
89
|
-
"legacy analysis",
|
|
90
|
-
],
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
class NaturalLanguageParser:
|
|
95
|
-
"""Parses natural language input to extract workflow intent."""
|
|
96
|
-
|
|
97
|
-
def __init__(self, preset_loader: PresetLoader | None = None):
|
|
98
|
-
"""
|
|
99
|
-
Initialize natural language parser.
|
|
100
|
-
|
|
101
|
-
Args:
|
|
102
|
-
preset_loader: PresetLoader instance (creates new one if None)
|
|
103
|
-
"""
|
|
104
|
-
self.preset_loader = preset_loader or PresetLoader()
|
|
105
|
-
self._workflow_names_cache: list[str] | None = None
|
|
106
|
-
|
|
107
|
-
def _get_workflow_names(self) -> list[str]:
|
|
108
|
-
"""Get list of available workflow names (cached)."""
|
|
109
|
-
if self._workflow_names_cache is None:
|
|
110
|
-
presets = self.preset_loader.list_presets()
|
|
111
|
-
self._workflow_names_cache = list(presets.keys())
|
|
112
|
-
return self._workflow_names_cache
|
|
113
|
-
|
|
114
|
-
def parse(self, input_text: str) -> WorkflowIntent:
|
|
115
|
-
"""
|
|
116
|
-
Parse natural language input to extract workflow intent.
|
|
117
|
-
|
|
118
|
-
Args:
|
|
119
|
-
input_text: Natural language input from user
|
|
120
|
-
|
|
121
|
-
Returns:
|
|
122
|
-
WorkflowIntent with parsed results
|
|
123
|
-
"""
|
|
124
|
-
if not input_text or not input_text.strip():
|
|
125
|
-
return WorkflowIntent(
|
|
126
|
-
intent_type="unknown",
|
|
127
|
-
workflow_name=None,
|
|
128
|
-
confidence=0.0,
|
|
129
|
-
aliases_matched=[],
|
|
130
|
-
raw_input=input_text,
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
normalized = input_text.lower().strip()
|
|
134
|
-
|
|
135
|
-
# Try exact match first
|
|
136
|
-
result = self._try_exact_match(normalized)
|
|
137
|
-
if result and result.confidence >= 0.9:
|
|
138
|
-
return result
|
|
139
|
-
|
|
140
|
-
# Try alias match
|
|
141
|
-
result = self._try_alias_match(normalized)
|
|
142
|
-
if result and result.confidence >= 0.8:
|
|
143
|
-
return result
|
|
144
|
-
|
|
145
|
-
# Try synonym match
|
|
146
|
-
result = self._try_synonym_match(normalized)
|
|
147
|
-
if result and result.confidence >= 0.7:
|
|
148
|
-
return result
|
|
149
|
-
|
|
150
|
-
# Try partial match
|
|
151
|
-
result = self._try_partial_match(normalized)
|
|
152
|
-
if result and result.confidence >= 0.6:
|
|
153
|
-
return result
|
|
154
|
-
|
|
155
|
-
# Try fuzzy match
|
|
156
|
-
result = self._try_fuzzy_match(normalized)
|
|
157
|
-
if result:
|
|
158
|
-
return result
|
|
159
|
-
|
|
160
|
-
# No match found
|
|
161
|
-
return WorkflowIntent(
|
|
162
|
-
intent_type="unknown",
|
|
163
|
-
workflow_name=None,
|
|
164
|
-
confidence=0.0,
|
|
165
|
-
aliases_matched=[],
|
|
166
|
-
raw_input=input_text,
|
|
167
|
-
)
|
|
168
|
-
|
|
169
|
-
def _try_exact_match(self, normalized: str) -> WorkflowIntent | None:
|
|
170
|
-
"""Try exact match against workflow names and aliases."""
|
|
171
|
-
workflow_names = self._get_workflow_names()
|
|
172
|
-
|
|
173
|
-
# Check exact match against workflow names
|
|
174
|
-
for workflow_name in workflow_names:
|
|
175
|
-
if normalized == workflow_name.lower():
|
|
176
|
-
return WorkflowIntent(
|
|
177
|
-
intent_type="workflow_trigger",
|
|
178
|
-
workflow_name=workflow_name,
|
|
179
|
-
confidence=1.0,
|
|
180
|
-
aliases_matched=[workflow_name],
|
|
181
|
-
raw_input=normalized,
|
|
182
|
-
match_type="exact",
|
|
183
|
-
)
|
|
184
|
-
|
|
185
|
-
# Check exact match against aliases
|
|
186
|
-
for alias, workflow_name in PRESET_ALIASES.items():
|
|
187
|
-
if normalized == alias.lower():
|
|
188
|
-
return WorkflowIntent(
|
|
189
|
-
intent_type="workflow_trigger",
|
|
190
|
-
workflow_name=workflow_name,
|
|
191
|
-
confidence=0.95,
|
|
192
|
-
aliases_matched=[alias],
|
|
193
|
-
raw_input=normalized,
|
|
194
|
-
match_type="exact",
|
|
195
|
-
)
|
|
196
|
-
|
|
197
|
-
return None
|
|
198
|
-
|
|
199
|
-
def _try_alias_match(self, normalized: str) -> WorkflowIntent | None:
|
|
200
|
-
"""Try matching against aliases (substring)."""
|
|
201
|
-
best_match: tuple[str, str, float] | None = None
|
|
202
|
-
|
|
203
|
-
for alias, workflow_name in PRESET_ALIASES.items():
|
|
204
|
-
alias_lower = alias.lower()
|
|
205
|
-
if alias_lower in normalized or normalized in alias_lower:
|
|
206
|
-
# Calculate confidence based on match quality
|
|
207
|
-
if normalized == alias_lower:
|
|
208
|
-
confidence = 0.95
|
|
209
|
-
elif normalized.startswith(alias_lower) or alias_lower.startswith(normalized):
|
|
210
|
-
confidence = 0.85
|
|
211
|
-
else:
|
|
212
|
-
confidence = 0.75
|
|
213
|
-
|
|
214
|
-
if best_match is None or confidence > best_match[2]:
|
|
215
|
-
best_match = (alias, workflow_name, confidence)
|
|
216
|
-
|
|
217
|
-
if best_match:
|
|
218
|
-
alias, workflow_name, confidence = best_match
|
|
219
|
-
return WorkflowIntent(
|
|
220
|
-
intent_type="workflow_trigger",
|
|
221
|
-
workflow_name=workflow_name,
|
|
222
|
-
confidence=confidence,
|
|
223
|
-
aliases_matched=[alias],
|
|
224
|
-
raw_input=normalized,
|
|
225
|
-
match_type="alias",
|
|
226
|
-
)
|
|
227
|
-
|
|
228
|
-
return None
|
|
229
|
-
|
|
230
|
-
def _try_synonym_match(self, normalized: str) -> WorkflowIntent | None:
|
|
231
|
-
"""Try matching against synonyms."""
|
|
232
|
-
best_match: tuple[str, float] | None = None
|
|
233
|
-
|
|
234
|
-
for workflow_name, synonyms in WORKFLOW_SYNONYMS.items():
|
|
235
|
-
for synonym in synonyms:
|
|
236
|
-
synonym_lower = synonym.lower()
|
|
237
|
-
if synonym_lower in normalized or normalized in synonym_lower:
|
|
238
|
-
# Calculate confidence based on match quality
|
|
239
|
-
if normalized == synonym_lower:
|
|
240
|
-
confidence = 0.9
|
|
241
|
-
elif normalized.startswith(synonym_lower) or synonym_lower.startswith(normalized):
|
|
242
|
-
confidence = 0.8
|
|
243
|
-
else:
|
|
244
|
-
confidence = 0.7
|
|
245
|
-
|
|
246
|
-
if best_match is None or confidence > best_match[1]:
|
|
247
|
-
best_match = (workflow_name, confidence)
|
|
248
|
-
|
|
249
|
-
if best_match:
|
|
250
|
-
workflow_name, confidence = best_match
|
|
251
|
-
return WorkflowIntent(
|
|
252
|
-
intent_type="workflow_trigger",
|
|
253
|
-
workflow_name=workflow_name,
|
|
254
|
-
confidence=confidence,
|
|
255
|
-
aliases_matched=[],
|
|
256
|
-
raw_input=normalized,
|
|
257
|
-
match_type="synonym",
|
|
258
|
-
)
|
|
259
|
-
|
|
260
|
-
return None
|
|
261
|
-
|
|
262
|
-
def _try_partial_match(self, normalized: str) -> WorkflowIntent | None:
|
|
263
|
-
"""Try partial/substring matching."""
|
|
264
|
-
workflow_names = self._get_workflow_names()
|
|
265
|
-
best_match: tuple[str, float] | None = None
|
|
266
|
-
|
|
267
|
-
for workflow_name in workflow_names:
|
|
268
|
-
workflow_lower = workflow_name.lower()
|
|
269
|
-
# Check if normalized contains workflow name or vice versa
|
|
270
|
-
if workflow_lower in normalized:
|
|
271
|
-
# Calculate confidence based on how much of the workflow name matches
|
|
272
|
-
match_ratio = len(workflow_lower) / len(normalized) if normalized else 0
|
|
273
|
-
confidence = min(0.8, 0.5 + match_ratio * 0.3)
|
|
274
|
-
|
|
275
|
-
if best_match is None or confidence > best_match[1]:
|
|
276
|
-
best_match = (workflow_name, confidence)
|
|
277
|
-
elif normalized in workflow_lower:
|
|
278
|
-
# Normalized is substring of workflow name
|
|
279
|
-
match_ratio = len(normalized) / len(workflow_lower) if workflow_lower else 0
|
|
280
|
-
confidence = min(0.75, 0.4 + match_ratio * 0.35)
|
|
281
|
-
|
|
282
|
-
if best_match is None or confidence > best_match[1]:
|
|
283
|
-
best_match = (workflow_name, confidence)
|
|
284
|
-
|
|
285
|
-
if best_match:
|
|
286
|
-
workflow_name, confidence = best_match
|
|
287
|
-
return WorkflowIntent(
|
|
288
|
-
intent_type="workflow_trigger",
|
|
289
|
-
workflow_name=workflow_name,
|
|
290
|
-
confidence=confidence,
|
|
291
|
-
aliases_matched=[],
|
|
292
|
-
raw_input=normalized,
|
|
293
|
-
match_type="partial",
|
|
294
|
-
)
|
|
295
|
-
|
|
296
|
-
return None
|
|
297
|
-
|
|
298
|
-
def _try_fuzzy_match(self, normalized: str) -> WorkflowIntent | None:
|
|
299
|
-
"""Try fuzzy matching using string similarity."""
|
|
300
|
-
workflow_names = self._get_workflow_names()
|
|
301
|
-
best_matches: list[tuple[str, float]] = []
|
|
302
|
-
|
|
303
|
-
for workflow_name in workflow_names:
|
|
304
|
-
# Calculate similarity using SequenceMatcher
|
|
305
|
-
similarity = difflib.SequenceMatcher(None, normalized, workflow_name.lower()).ratio()
|
|
306
|
-
|
|
307
|
-
if similarity >= 0.5: # Minimum threshold for fuzzy match
|
|
308
|
-
best_matches.append((workflow_name, similarity))
|
|
309
|
-
|
|
310
|
-
# Also check aliases
|
|
311
|
-
for alias, workflow_name in PRESET_ALIASES.items():
|
|
312
|
-
similarity = difflib.SequenceMatcher(None, normalized, alias.lower()).ratio()
|
|
313
|
-
|
|
314
|
-
if similarity >= 0.5:
|
|
315
|
-
best_matches.append((workflow_name, similarity))
|
|
316
|
-
|
|
317
|
-
if not best_matches:
|
|
318
|
-
return None
|
|
319
|
-
|
|
320
|
-
# Sort by similarity (descending)
|
|
321
|
-
best_matches.sort(key=lambda x: x[1], reverse=True)
|
|
322
|
-
|
|
323
|
-
# Get best match
|
|
324
|
-
best_workflow, best_confidence = best_matches[0]
|
|
325
|
-
|
|
326
|
-
# Get alternative matches (top 3)
|
|
327
|
-
alternatives = best_matches[1:4] if len(best_matches) > 1 else None
|
|
328
|
-
|
|
329
|
-
return WorkflowIntent(
|
|
330
|
-
intent_type="workflow_trigger",
|
|
331
|
-
workflow_name=best_workflow,
|
|
332
|
-
confidence=min(0.7, best_confidence * 0.9), # Cap fuzzy match confidence
|
|
333
|
-
aliases_matched=[],
|
|
334
|
-
raw_input=normalized,
|
|
335
|
-
match_type="fuzzy",
|
|
336
|
-
alternative_matches=alternatives,
|
|
337
|
-
)
|
|
338
|
-
|
|
339
|
-
# Story 9.2: Intent Detection Methods
|
|
340
|
-
|
|
341
|
-
# Action verbs that indicate workflow execution intent
|
|
342
|
-
ACTION_VERBS = [
|
|
343
|
-
"run",
|
|
344
|
-
"execute",
|
|
345
|
-
"start",
|
|
346
|
-
"trigger",
|
|
347
|
-
"launch",
|
|
348
|
-
"begin",
|
|
349
|
-
"perform",
|
|
350
|
-
"do",
|
|
351
|
-
"create",
|
|
352
|
-
"build",
|
|
353
|
-
]
|
|
354
|
-
|
|
355
|
-
# Action verb variations and phrases
|
|
356
|
-
ACTION_PHRASES = [
|
|
357
|
-
r"i want to (\w+)",
|
|
358
|
-
r"please (\w+)",
|
|
359
|
-
r"can you (\w+)",
|
|
360
|
-
r"could you (\w+)",
|
|
361
|
-
r"let's (\w+)",
|
|
362
|
-
r"let me (\w+)",
|
|
363
|
-
]
|
|
364
|
-
|
|
365
|
-
# Workflow type keywords
|
|
366
|
-
WORKFLOW_TYPE_KEYWORDS = {
|
|
367
|
-
"rapid": ["rapid", "quick", "fast", "feature", "sprint", "dev"],
|
|
368
|
-
"full": ["full", "enterprise", "complete", "sdlc", "lifecycle", "all"],
|
|
369
|
-
"fix": ["fix", "maintenance", "bug", "repair", "patch"],
|
|
370
|
-
"quality": ["quality", "improve", "review", "refactor", "clean"],
|
|
371
|
-
"hotfix": ["hotfix", "urgent", "emergency", "critical", "patch"],
|
|
372
|
-
"enterprise": ["enterprise", "full", "complete", "sdlc"],
|
|
373
|
-
"feature": ["feature", "rapid", "quick", "new"],
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
def detect_intent(self, input_text: str) -> WorkflowIntentResult:
|
|
377
|
-
"""
|
|
378
|
-
Detect complete workflow intent including action verb and parameters.
|
|
379
|
-
|
|
380
|
-
Args:
|
|
381
|
-
input_text: Natural language input from user
|
|
382
|
-
|
|
383
|
-
Returns:
|
|
384
|
-
WorkflowIntentResult with complete intent information
|
|
385
|
-
"""
|
|
386
|
-
if not input_text or not input_text.strip():
|
|
387
|
-
return WorkflowIntentResult(
|
|
388
|
-
action_verb=None,
|
|
389
|
-
workflow_type=None,
|
|
390
|
-
workflow_name=None,
|
|
391
|
-
confidence=0.0,
|
|
392
|
-
)
|
|
393
|
-
|
|
394
|
-
normalized = input_text.lower().strip()
|
|
395
|
-
|
|
396
|
-
# Detect action verb
|
|
397
|
-
action_verb = self._detect_action_verb(normalized)
|
|
398
|
-
intent_confidence = 0.9 if action_verb else 0.5
|
|
399
|
-
|
|
400
|
-
# Detect workflow type
|
|
401
|
-
workflow_type = self._detect_workflow_type(normalized)
|
|
402
|
-
|
|
403
|
-
# Parse workflow name using base parser
|
|
404
|
-
workflow_intent = self.parse(input_text)
|
|
405
|
-
workflow_confidence = workflow_intent.confidence
|
|
406
|
-
|
|
407
|
-
# Extract parameters
|
|
408
|
-
parameters = self._extract_parameters(normalized, input_text)
|
|
409
|
-
|
|
410
|
-
# Detect ambiguity
|
|
411
|
-
ambiguity_flag = self._detect_ambiguity(workflow_intent)
|
|
412
|
-
|
|
413
|
-
# Generate suggestions
|
|
414
|
-
suggestions = self._generate_suggestions(workflow_intent)
|
|
415
|
-
|
|
416
|
-
# Calculate overall confidence
|
|
417
|
-
overall_confidence = (intent_confidence * 0.3 + workflow_confidence * 0.7) if workflow_intent.workflow_name else intent_confidence * 0.5
|
|
418
|
-
|
|
419
|
-
return WorkflowIntentResult(
|
|
420
|
-
action_verb=action_verb,
|
|
421
|
-
workflow_type=workflow_type,
|
|
422
|
-
workflow_name=workflow_intent.workflow_name,
|
|
423
|
-
parameters=parameters,
|
|
424
|
-
ambiguity_flag=ambiguity_flag,
|
|
425
|
-
suggestions=suggestions,
|
|
426
|
-
confidence=overall_confidence,
|
|
427
|
-
intent_confidence=intent_confidence,
|
|
428
|
-
workflow_confidence=workflow_confidence,
|
|
429
|
-
)
|
|
430
|
-
|
|
431
|
-
def _detect_action_verb(self, normalized: str) -> str | None:
|
|
432
|
-
"""Detect action verb in input."""
|
|
433
|
-
# Check for direct verb matches
|
|
434
|
-
for verb in self.ACTION_VERBS:
|
|
435
|
-
# Match verb as whole word
|
|
436
|
-
pattern = r"\b" + re.escape(verb) + r"\b"
|
|
437
|
-
if re.search(pattern, normalized):
|
|
438
|
-
return verb
|
|
439
|
-
|
|
440
|
-
# Check for action phrases
|
|
441
|
-
for phrase_pattern in self.ACTION_PHRASES:
|
|
442
|
-
match = re.search(phrase_pattern, normalized)
|
|
443
|
-
if match:
|
|
444
|
-
verb = match.group(1)
|
|
445
|
-
if verb in self.ACTION_VERBS:
|
|
446
|
-
return verb
|
|
447
|
-
|
|
448
|
-
return None
|
|
449
|
-
|
|
450
|
-
def _detect_workflow_type(self, normalized: str) -> str | None:
|
|
451
|
-
"""Detect workflow type from keywords."""
|
|
452
|
-
best_match: tuple[str, int] | None = None
|
|
453
|
-
|
|
454
|
-
for workflow_type, keywords in self.WORKFLOW_TYPE_KEYWORDS.items():
|
|
455
|
-
score = sum(1 for keyword in keywords if keyword in normalized)
|
|
456
|
-
if score > 0:
|
|
457
|
-
if best_match is None or score > best_match[1]:
|
|
458
|
-
best_match = (workflow_type, score)
|
|
459
|
-
|
|
460
|
-
return best_match[0] if best_match else None
|
|
461
|
-
|
|
462
|
-
def _extract_parameters(self, normalized: str, original: str) -> dict[str, Any]:
|
|
463
|
-
"""Extract parameters from input (target file, options)."""
|
|
464
|
-
parameters: dict[str, Any] = {}
|
|
465
|
-
|
|
466
|
-
# Extract target file
|
|
467
|
-
# Patterns: "on file.py", "for example.py", "targeting bug.py", "file: example.py"
|
|
468
|
-
file_patterns = [
|
|
469
|
-
r"(?:on|for|targeting|file:?)\s+([^\s]+\.(?:py|js|ts|java|go|rs|cpp|c|h|md|yaml|yml|json|txt))",
|
|
470
|
-
r"([^\s]+\.(?:py|js|ts|java|go|rs|cpp|c|h|md|yaml|yml|json|txt))",
|
|
471
|
-
]
|
|
472
|
-
|
|
473
|
-
for pattern in file_patterns:
|
|
474
|
-
match = re.search(pattern, normalized, re.IGNORECASE)
|
|
475
|
-
if match:
|
|
476
|
-
file_path = match.group(1)
|
|
477
|
-
parameters["target_file"] = file_path
|
|
478
|
-
break
|
|
479
|
-
|
|
480
|
-
# Extract options/flags
|
|
481
|
-
if "auto" in normalized or "automatic" in normalized:
|
|
482
|
-
parameters["auto"] = True
|
|
483
|
-
|
|
484
|
-
if "skip" in normalized and "test" in normalized:
|
|
485
|
-
parameters["skip_tests"] = True
|
|
486
|
-
|
|
487
|
-
if "prompt" in normalized:
|
|
488
|
-
# Try to extract prompt text
|
|
489
|
-
prompt_match = re.search(r'prompt[:\s]+["\']?([^"\']+)["\']?', normalized)
|
|
490
|
-
if prompt_match:
|
|
491
|
-
parameters["prompt"] = prompt_match.group(1)
|
|
492
|
-
|
|
493
|
-
return parameters
|
|
494
|
-
|
|
495
|
-
def _detect_ambiguity(self, workflow_intent: WorkflowIntent) -> bool:
|
|
496
|
-
"""Detect if request is ambiguous (multiple matches with similar confidence)."""
|
|
497
|
-
if not workflow_intent.workflow_name:
|
|
498
|
-
return False
|
|
499
|
-
|
|
500
|
-
# Check if there are alternative matches with similar confidence
|
|
501
|
-
if workflow_intent.alternative_matches:
|
|
502
|
-
best_confidence = workflow_intent.confidence
|
|
503
|
-
for _, alt_confidence in workflow_intent.alternative_matches:
|
|
504
|
-
# If alternative is within 20% of best match, consider ambiguous
|
|
505
|
-
if abs(best_confidence - alt_confidence) < 0.2:
|
|
506
|
-
return True
|
|
507
|
-
|
|
508
|
-
# Low confidence itself indicates potential ambiguity
|
|
509
|
-
if workflow_intent.confidence < 0.7:
|
|
510
|
-
return True
|
|
511
|
-
|
|
512
|
-
return False
|
|
513
|
-
|
|
514
|
-
def _generate_suggestions(self, workflow_intent: WorkflowIntent) -> list[str]:
|
|
515
|
-
"""Generate workflow suggestions based on intent."""
|
|
516
|
-
suggestions: list[str] = []
|
|
517
|
-
|
|
518
|
-
if workflow_intent.alternative_matches:
|
|
519
|
-
for workflow_name, _ in workflow_intent.alternative_matches[:3]:
|
|
520
|
-
suggestions.append(workflow_name)
|
|
521
|
-
|
|
522
|
-
# If no match, suggest all available workflows
|
|
523
|
-
if not workflow_intent.workflow_name:
|
|
524
|
-
workflow_names = self._get_workflow_names()
|
|
525
|
-
suggestions.extend(workflow_names[:5])
|
|
526
|
-
|
|
527
|
-
return suggestions
|
|
528
|
-
|
|
1
|
+
"""
|
|
2
|
+
Natural Language Parser for Workflow Triggers
|
|
3
|
+
|
|
4
|
+
Parses natural language input to extract workflow intent and match workflows.
|
|
5
|
+
Epic 9 / Story 9.1: Natural Language Parser Foundation
|
|
6
|
+
Epic 9 / Story 9.2: Workflow Intent Detection
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import difflib
|
|
10
|
+
import re
|
|
11
|
+
from dataclasses import dataclass, field
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
from .preset_loader import PRESET_ALIASES, PresetLoader
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class WorkflowIntent:
|
|
19
|
+
"""Parsed workflow intent result."""
|
|
20
|
+
|
|
21
|
+
intent_type: str # "workflow_trigger", "workflow_query", "unknown"
|
|
22
|
+
workflow_name: str | None # Matched workflow name (canonical)
|
|
23
|
+
confidence: float # 0.0 to 1.0
|
|
24
|
+
aliases_matched: list[str] # Aliases that matched
|
|
25
|
+
raw_input: str # Original input
|
|
26
|
+
match_type: str | None = None # "exact", "partial", "fuzzy", "alias", "synonym"
|
|
27
|
+
alternative_matches: list[tuple[str, float]] | None = None # (workflow_name, confidence)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass
|
|
31
|
+
class WorkflowIntentResult:
|
|
32
|
+
"""Complete intent detection result with action verb and parameters."""
|
|
33
|
+
|
|
34
|
+
action_verb: str | None # "run", "execute", "start", "trigger", etc.
|
|
35
|
+
workflow_type: str | None # Detected workflow type/category
|
|
36
|
+
workflow_name: str | None # Matched workflow name
|
|
37
|
+
parameters: dict[str, Any] = field(default_factory=dict) # Extracted parameters
|
|
38
|
+
ambiguity_flag: bool = False # True if multiple workflows match
|
|
39
|
+
suggestions: list[str] = field(default_factory=list) # Alternative workflows
|
|
40
|
+
confidence: float = 0.0 # Overall confidence score
|
|
41
|
+
intent_confidence: float = 0.0 # Confidence in intent detection
|
|
42
|
+
workflow_confidence: float = 0.0 # Confidence in workflow matching
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# Workflow synonyms for natural language matching
|
|
46
|
+
WORKFLOW_SYNONYMS: dict[str, list[str]] = {
|
|
47
|
+
"full-sdlc": [
|
|
48
|
+
"full sdlc",
|
|
49
|
+
"full software development lifecycle",
|
|
50
|
+
"complete sdlc",
|
|
51
|
+
"enterprise workflow",
|
|
52
|
+
"full pipeline",
|
|
53
|
+
"complete workflow",
|
|
54
|
+
],
|
|
55
|
+
"rapid-dev": [
|
|
56
|
+
"rapid development",
|
|
57
|
+
"rapid dev",
|
|
58
|
+
"quick development",
|
|
59
|
+
"fast development",
|
|
60
|
+
"feature development",
|
|
61
|
+
"sprint workflow",
|
|
62
|
+
],
|
|
63
|
+
"fix": [
|
|
64
|
+
"fix workflow",
|
|
65
|
+
"maintenance workflow",
|
|
66
|
+
"bug fix",
|
|
67
|
+
"bug fixing",
|
|
68
|
+
"refactoring",
|
|
69
|
+
"technical debt",
|
|
70
|
+
"code improvement",
|
|
71
|
+
"quick fix",
|
|
72
|
+
"hotfix",
|
|
73
|
+
"urgent fix",
|
|
74
|
+
"emergency fix",
|
|
75
|
+
"critical fix",
|
|
76
|
+
"patch",
|
|
77
|
+
],
|
|
78
|
+
"quality": [
|
|
79
|
+
"quality improvement",
|
|
80
|
+
"code quality",
|
|
81
|
+
"quality workflow",
|
|
82
|
+
"code review",
|
|
83
|
+
"quality check",
|
|
84
|
+
],
|
|
85
|
+
"brownfield-analysis": [
|
|
86
|
+
"brownfield",
|
|
87
|
+
"brownfield analysis",
|
|
88
|
+
"existing codebase",
|
|
89
|
+
"legacy analysis",
|
|
90
|
+
],
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class NaturalLanguageParser:
|
|
95
|
+
"""Parses natural language input to extract workflow intent."""
|
|
96
|
+
|
|
97
|
+
def __init__(self, preset_loader: PresetLoader | None = None):
|
|
98
|
+
"""
|
|
99
|
+
Initialize natural language parser.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
preset_loader: PresetLoader instance (creates new one if None)
|
|
103
|
+
"""
|
|
104
|
+
self.preset_loader = preset_loader or PresetLoader()
|
|
105
|
+
self._workflow_names_cache: list[str] | None = None
|
|
106
|
+
|
|
107
|
+
def _get_workflow_names(self) -> list[str]:
|
|
108
|
+
"""Get list of available workflow names (cached)."""
|
|
109
|
+
if self._workflow_names_cache is None:
|
|
110
|
+
presets = self.preset_loader.list_presets()
|
|
111
|
+
self._workflow_names_cache = list(presets.keys())
|
|
112
|
+
return self._workflow_names_cache
|
|
113
|
+
|
|
114
|
+
def parse(self, input_text: str) -> WorkflowIntent:
|
|
115
|
+
"""
|
|
116
|
+
Parse natural language input to extract workflow intent.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
input_text: Natural language input from user
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
WorkflowIntent with parsed results
|
|
123
|
+
"""
|
|
124
|
+
if not input_text or not input_text.strip():
|
|
125
|
+
return WorkflowIntent(
|
|
126
|
+
intent_type="unknown",
|
|
127
|
+
workflow_name=None,
|
|
128
|
+
confidence=0.0,
|
|
129
|
+
aliases_matched=[],
|
|
130
|
+
raw_input=input_text,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
normalized = input_text.lower().strip()
|
|
134
|
+
|
|
135
|
+
# Try exact match first
|
|
136
|
+
result = self._try_exact_match(normalized)
|
|
137
|
+
if result and result.confidence >= 0.9:
|
|
138
|
+
return result
|
|
139
|
+
|
|
140
|
+
# Try alias match
|
|
141
|
+
result = self._try_alias_match(normalized)
|
|
142
|
+
if result and result.confidence >= 0.8:
|
|
143
|
+
return result
|
|
144
|
+
|
|
145
|
+
# Try synonym match
|
|
146
|
+
result = self._try_synonym_match(normalized)
|
|
147
|
+
if result and result.confidence >= 0.7:
|
|
148
|
+
return result
|
|
149
|
+
|
|
150
|
+
# Try partial match
|
|
151
|
+
result = self._try_partial_match(normalized)
|
|
152
|
+
if result and result.confidence >= 0.6:
|
|
153
|
+
return result
|
|
154
|
+
|
|
155
|
+
# Try fuzzy match
|
|
156
|
+
result = self._try_fuzzy_match(normalized)
|
|
157
|
+
if result:
|
|
158
|
+
return result
|
|
159
|
+
|
|
160
|
+
# No match found
|
|
161
|
+
return WorkflowIntent(
|
|
162
|
+
intent_type="unknown",
|
|
163
|
+
workflow_name=None,
|
|
164
|
+
confidence=0.0,
|
|
165
|
+
aliases_matched=[],
|
|
166
|
+
raw_input=input_text,
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
def _try_exact_match(self, normalized: str) -> WorkflowIntent | None:
|
|
170
|
+
"""Try exact match against workflow names and aliases."""
|
|
171
|
+
workflow_names = self._get_workflow_names()
|
|
172
|
+
|
|
173
|
+
# Check exact match against workflow names
|
|
174
|
+
for workflow_name in workflow_names:
|
|
175
|
+
if normalized == workflow_name.lower():
|
|
176
|
+
return WorkflowIntent(
|
|
177
|
+
intent_type="workflow_trigger",
|
|
178
|
+
workflow_name=workflow_name,
|
|
179
|
+
confidence=1.0,
|
|
180
|
+
aliases_matched=[workflow_name],
|
|
181
|
+
raw_input=normalized,
|
|
182
|
+
match_type="exact",
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
# Check exact match against aliases
|
|
186
|
+
for alias, workflow_name in PRESET_ALIASES.items():
|
|
187
|
+
if normalized == alias.lower():
|
|
188
|
+
return WorkflowIntent(
|
|
189
|
+
intent_type="workflow_trigger",
|
|
190
|
+
workflow_name=workflow_name,
|
|
191
|
+
confidence=0.95,
|
|
192
|
+
aliases_matched=[alias],
|
|
193
|
+
raw_input=normalized,
|
|
194
|
+
match_type="exact",
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
return None
|
|
198
|
+
|
|
199
|
+
def _try_alias_match(self, normalized: str) -> WorkflowIntent | None:
|
|
200
|
+
"""Try matching against aliases (substring)."""
|
|
201
|
+
best_match: tuple[str, str, float] | None = None
|
|
202
|
+
|
|
203
|
+
for alias, workflow_name in PRESET_ALIASES.items():
|
|
204
|
+
alias_lower = alias.lower()
|
|
205
|
+
if alias_lower in normalized or normalized in alias_lower:
|
|
206
|
+
# Calculate confidence based on match quality
|
|
207
|
+
if normalized == alias_lower:
|
|
208
|
+
confidence = 0.95
|
|
209
|
+
elif normalized.startswith(alias_lower) or alias_lower.startswith(normalized):
|
|
210
|
+
confidence = 0.85
|
|
211
|
+
else:
|
|
212
|
+
confidence = 0.75
|
|
213
|
+
|
|
214
|
+
if best_match is None or confidence > best_match[2]:
|
|
215
|
+
best_match = (alias, workflow_name, confidence)
|
|
216
|
+
|
|
217
|
+
if best_match:
|
|
218
|
+
alias, workflow_name, confidence = best_match
|
|
219
|
+
return WorkflowIntent(
|
|
220
|
+
intent_type="workflow_trigger",
|
|
221
|
+
workflow_name=workflow_name,
|
|
222
|
+
confidence=confidence,
|
|
223
|
+
aliases_matched=[alias],
|
|
224
|
+
raw_input=normalized,
|
|
225
|
+
match_type="alias",
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
return None
|
|
229
|
+
|
|
230
|
+
def _try_synonym_match(self, normalized: str) -> WorkflowIntent | None:
|
|
231
|
+
"""Try matching against synonyms."""
|
|
232
|
+
best_match: tuple[str, float] | None = None
|
|
233
|
+
|
|
234
|
+
for workflow_name, synonyms in WORKFLOW_SYNONYMS.items():
|
|
235
|
+
for synonym in synonyms:
|
|
236
|
+
synonym_lower = synonym.lower()
|
|
237
|
+
if synonym_lower in normalized or normalized in synonym_lower:
|
|
238
|
+
# Calculate confidence based on match quality
|
|
239
|
+
if normalized == synonym_lower:
|
|
240
|
+
confidence = 0.9
|
|
241
|
+
elif normalized.startswith(synonym_lower) or synonym_lower.startswith(normalized):
|
|
242
|
+
confidence = 0.8
|
|
243
|
+
else:
|
|
244
|
+
confidence = 0.7
|
|
245
|
+
|
|
246
|
+
if best_match is None or confidence > best_match[1]:
|
|
247
|
+
best_match = (workflow_name, confidence)
|
|
248
|
+
|
|
249
|
+
if best_match:
|
|
250
|
+
workflow_name, confidence = best_match
|
|
251
|
+
return WorkflowIntent(
|
|
252
|
+
intent_type="workflow_trigger",
|
|
253
|
+
workflow_name=workflow_name,
|
|
254
|
+
confidence=confidence,
|
|
255
|
+
aliases_matched=[],
|
|
256
|
+
raw_input=normalized,
|
|
257
|
+
match_type="synonym",
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
return None
|
|
261
|
+
|
|
262
|
+
def _try_partial_match(self, normalized: str) -> WorkflowIntent | None:
|
|
263
|
+
"""Try partial/substring matching."""
|
|
264
|
+
workflow_names = self._get_workflow_names()
|
|
265
|
+
best_match: tuple[str, float] | None = None
|
|
266
|
+
|
|
267
|
+
for workflow_name in workflow_names:
|
|
268
|
+
workflow_lower = workflow_name.lower()
|
|
269
|
+
# Check if normalized contains workflow name or vice versa
|
|
270
|
+
if workflow_lower in normalized:
|
|
271
|
+
# Calculate confidence based on how much of the workflow name matches
|
|
272
|
+
match_ratio = len(workflow_lower) / len(normalized) if normalized else 0
|
|
273
|
+
confidence = min(0.8, 0.5 + match_ratio * 0.3)
|
|
274
|
+
|
|
275
|
+
if best_match is None or confidence > best_match[1]:
|
|
276
|
+
best_match = (workflow_name, confidence)
|
|
277
|
+
elif normalized in workflow_lower:
|
|
278
|
+
# Normalized is substring of workflow name
|
|
279
|
+
match_ratio = len(normalized) / len(workflow_lower) if workflow_lower else 0
|
|
280
|
+
confidence = min(0.75, 0.4 + match_ratio * 0.35)
|
|
281
|
+
|
|
282
|
+
if best_match is None or confidence > best_match[1]:
|
|
283
|
+
best_match = (workflow_name, confidence)
|
|
284
|
+
|
|
285
|
+
if best_match:
|
|
286
|
+
workflow_name, confidence = best_match
|
|
287
|
+
return WorkflowIntent(
|
|
288
|
+
intent_type="workflow_trigger",
|
|
289
|
+
workflow_name=workflow_name,
|
|
290
|
+
confidence=confidence,
|
|
291
|
+
aliases_matched=[],
|
|
292
|
+
raw_input=normalized,
|
|
293
|
+
match_type="partial",
|
|
294
|
+
)
|
|
295
|
+
|
|
296
|
+
return None
|
|
297
|
+
|
|
298
|
+
def _try_fuzzy_match(self, normalized: str) -> WorkflowIntent | None:
|
|
299
|
+
"""Try fuzzy matching using string similarity."""
|
|
300
|
+
workflow_names = self._get_workflow_names()
|
|
301
|
+
best_matches: list[tuple[str, float]] = []
|
|
302
|
+
|
|
303
|
+
for workflow_name in workflow_names:
|
|
304
|
+
# Calculate similarity using SequenceMatcher
|
|
305
|
+
similarity = difflib.SequenceMatcher(None, normalized, workflow_name.lower()).ratio()
|
|
306
|
+
|
|
307
|
+
if similarity >= 0.5: # Minimum threshold for fuzzy match
|
|
308
|
+
best_matches.append((workflow_name, similarity))
|
|
309
|
+
|
|
310
|
+
# Also check aliases
|
|
311
|
+
for alias, workflow_name in PRESET_ALIASES.items():
|
|
312
|
+
similarity = difflib.SequenceMatcher(None, normalized, alias.lower()).ratio()
|
|
313
|
+
|
|
314
|
+
if similarity >= 0.5:
|
|
315
|
+
best_matches.append((workflow_name, similarity))
|
|
316
|
+
|
|
317
|
+
if not best_matches:
|
|
318
|
+
return None
|
|
319
|
+
|
|
320
|
+
# Sort by similarity (descending)
|
|
321
|
+
best_matches.sort(key=lambda x: x[1], reverse=True)
|
|
322
|
+
|
|
323
|
+
# Get best match
|
|
324
|
+
best_workflow, best_confidence = best_matches[0]
|
|
325
|
+
|
|
326
|
+
# Get alternative matches (top 3)
|
|
327
|
+
alternatives = best_matches[1:4] if len(best_matches) > 1 else None
|
|
328
|
+
|
|
329
|
+
return WorkflowIntent(
|
|
330
|
+
intent_type="workflow_trigger",
|
|
331
|
+
workflow_name=best_workflow,
|
|
332
|
+
confidence=min(0.7, best_confidence * 0.9), # Cap fuzzy match confidence
|
|
333
|
+
aliases_matched=[],
|
|
334
|
+
raw_input=normalized,
|
|
335
|
+
match_type="fuzzy",
|
|
336
|
+
alternative_matches=alternatives,
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
# Story 9.2: Intent Detection Methods
|
|
340
|
+
|
|
341
|
+
# Action verbs that indicate workflow execution intent
|
|
342
|
+
ACTION_VERBS = [
|
|
343
|
+
"run",
|
|
344
|
+
"execute",
|
|
345
|
+
"start",
|
|
346
|
+
"trigger",
|
|
347
|
+
"launch",
|
|
348
|
+
"begin",
|
|
349
|
+
"perform",
|
|
350
|
+
"do",
|
|
351
|
+
"create",
|
|
352
|
+
"build",
|
|
353
|
+
]
|
|
354
|
+
|
|
355
|
+
# Action verb variations and phrases
|
|
356
|
+
ACTION_PHRASES = [
|
|
357
|
+
r"i want to (\w+)",
|
|
358
|
+
r"please (\w+)",
|
|
359
|
+
r"can you (\w+)",
|
|
360
|
+
r"could you (\w+)",
|
|
361
|
+
r"let's (\w+)",
|
|
362
|
+
r"let me (\w+)",
|
|
363
|
+
]
|
|
364
|
+
|
|
365
|
+
# Workflow type keywords
|
|
366
|
+
WORKFLOW_TYPE_KEYWORDS = {
|
|
367
|
+
"rapid": ["rapid", "quick", "fast", "feature", "sprint", "dev"],
|
|
368
|
+
"full": ["full", "enterprise", "complete", "sdlc", "lifecycle", "all"],
|
|
369
|
+
"fix": ["fix", "maintenance", "bug", "repair", "patch"],
|
|
370
|
+
"quality": ["quality", "improve", "review", "refactor", "clean"],
|
|
371
|
+
"hotfix": ["hotfix", "urgent", "emergency", "critical", "patch"],
|
|
372
|
+
"enterprise": ["enterprise", "full", "complete", "sdlc"],
|
|
373
|
+
"feature": ["feature", "rapid", "quick", "new"],
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
def detect_intent(self, input_text: str) -> WorkflowIntentResult:
|
|
377
|
+
"""
|
|
378
|
+
Detect complete workflow intent including action verb and parameters.
|
|
379
|
+
|
|
380
|
+
Args:
|
|
381
|
+
input_text: Natural language input from user
|
|
382
|
+
|
|
383
|
+
Returns:
|
|
384
|
+
WorkflowIntentResult with complete intent information
|
|
385
|
+
"""
|
|
386
|
+
if not input_text or not input_text.strip():
|
|
387
|
+
return WorkflowIntentResult(
|
|
388
|
+
action_verb=None,
|
|
389
|
+
workflow_type=None,
|
|
390
|
+
workflow_name=None,
|
|
391
|
+
confidence=0.0,
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
normalized = input_text.lower().strip()
|
|
395
|
+
|
|
396
|
+
# Detect action verb
|
|
397
|
+
action_verb = self._detect_action_verb(normalized)
|
|
398
|
+
intent_confidence = 0.9 if action_verb else 0.5
|
|
399
|
+
|
|
400
|
+
# Detect workflow type
|
|
401
|
+
workflow_type = self._detect_workflow_type(normalized)
|
|
402
|
+
|
|
403
|
+
# Parse workflow name using base parser
|
|
404
|
+
workflow_intent = self.parse(input_text)
|
|
405
|
+
workflow_confidence = workflow_intent.confidence
|
|
406
|
+
|
|
407
|
+
# Extract parameters
|
|
408
|
+
parameters = self._extract_parameters(normalized, input_text)
|
|
409
|
+
|
|
410
|
+
# Detect ambiguity
|
|
411
|
+
ambiguity_flag = self._detect_ambiguity(workflow_intent)
|
|
412
|
+
|
|
413
|
+
# Generate suggestions
|
|
414
|
+
suggestions = self._generate_suggestions(workflow_intent)
|
|
415
|
+
|
|
416
|
+
# Calculate overall confidence
|
|
417
|
+
overall_confidence = (intent_confidence * 0.3 + workflow_confidence * 0.7) if workflow_intent.workflow_name else intent_confidence * 0.5
|
|
418
|
+
|
|
419
|
+
return WorkflowIntentResult(
|
|
420
|
+
action_verb=action_verb,
|
|
421
|
+
workflow_type=workflow_type,
|
|
422
|
+
workflow_name=workflow_intent.workflow_name,
|
|
423
|
+
parameters=parameters,
|
|
424
|
+
ambiguity_flag=ambiguity_flag,
|
|
425
|
+
suggestions=suggestions,
|
|
426
|
+
confidence=overall_confidence,
|
|
427
|
+
intent_confidence=intent_confidence,
|
|
428
|
+
workflow_confidence=workflow_confidence,
|
|
429
|
+
)
|
|
430
|
+
|
|
431
|
+
def _detect_action_verb(self, normalized: str) -> str | None:
|
|
432
|
+
"""Detect action verb in input."""
|
|
433
|
+
# Check for direct verb matches
|
|
434
|
+
for verb in self.ACTION_VERBS:
|
|
435
|
+
# Match verb as whole word
|
|
436
|
+
pattern = r"\b" + re.escape(verb) + r"\b"
|
|
437
|
+
if re.search(pattern, normalized):
|
|
438
|
+
return verb
|
|
439
|
+
|
|
440
|
+
# Check for action phrases
|
|
441
|
+
for phrase_pattern in self.ACTION_PHRASES:
|
|
442
|
+
match = re.search(phrase_pattern, normalized)
|
|
443
|
+
if match:
|
|
444
|
+
verb = match.group(1)
|
|
445
|
+
if verb in self.ACTION_VERBS:
|
|
446
|
+
return verb
|
|
447
|
+
|
|
448
|
+
return None
|
|
449
|
+
|
|
450
|
+
def _detect_workflow_type(self, normalized: str) -> str | None:
|
|
451
|
+
"""Detect workflow type from keywords."""
|
|
452
|
+
best_match: tuple[str, int] | None = None
|
|
453
|
+
|
|
454
|
+
for workflow_type, keywords in self.WORKFLOW_TYPE_KEYWORDS.items():
|
|
455
|
+
score = sum(1 for keyword in keywords if keyword in normalized)
|
|
456
|
+
if score > 0:
|
|
457
|
+
if best_match is None or score > best_match[1]:
|
|
458
|
+
best_match = (workflow_type, score)
|
|
459
|
+
|
|
460
|
+
return best_match[0] if best_match else None
|
|
461
|
+
|
|
462
|
+
def _extract_parameters(self, normalized: str, original: str) -> dict[str, Any]:
|
|
463
|
+
"""Extract parameters from input (target file, options)."""
|
|
464
|
+
parameters: dict[str, Any] = {}
|
|
465
|
+
|
|
466
|
+
# Extract target file
|
|
467
|
+
# Patterns: "on file.py", "for example.py", "targeting bug.py", "file: example.py"
|
|
468
|
+
file_patterns = [
|
|
469
|
+
r"(?:on|for|targeting|file:?)\s+([^\s]+\.(?:py|js|ts|java|go|rs|cpp|c|h|md|yaml|yml|json|txt))",
|
|
470
|
+
r"([^\s]+\.(?:py|js|ts|java|go|rs|cpp|c|h|md|yaml|yml|json|txt))",
|
|
471
|
+
]
|
|
472
|
+
|
|
473
|
+
for pattern in file_patterns:
|
|
474
|
+
match = re.search(pattern, normalized, re.IGNORECASE)
|
|
475
|
+
if match:
|
|
476
|
+
file_path = match.group(1)
|
|
477
|
+
parameters["target_file"] = file_path
|
|
478
|
+
break
|
|
479
|
+
|
|
480
|
+
# Extract options/flags
|
|
481
|
+
if "auto" in normalized or "automatic" in normalized:
|
|
482
|
+
parameters["auto"] = True
|
|
483
|
+
|
|
484
|
+
if "skip" in normalized and "test" in normalized:
|
|
485
|
+
parameters["skip_tests"] = True
|
|
486
|
+
|
|
487
|
+
if "prompt" in normalized:
|
|
488
|
+
# Try to extract prompt text
|
|
489
|
+
prompt_match = re.search(r'prompt[:\s]+["\']?([^"\']+)["\']?', normalized)
|
|
490
|
+
if prompt_match:
|
|
491
|
+
parameters["prompt"] = prompt_match.group(1)
|
|
492
|
+
|
|
493
|
+
return parameters
|
|
494
|
+
|
|
495
|
+
def _detect_ambiguity(self, workflow_intent: WorkflowIntent) -> bool:
|
|
496
|
+
"""Detect if request is ambiguous (multiple matches with similar confidence)."""
|
|
497
|
+
if not workflow_intent.workflow_name:
|
|
498
|
+
return False
|
|
499
|
+
|
|
500
|
+
# Check if there are alternative matches with similar confidence
|
|
501
|
+
if workflow_intent.alternative_matches:
|
|
502
|
+
best_confidence = workflow_intent.confidence
|
|
503
|
+
for _, alt_confidence in workflow_intent.alternative_matches:
|
|
504
|
+
# If alternative is within 20% of best match, consider ambiguous
|
|
505
|
+
if abs(best_confidence - alt_confidence) < 0.2:
|
|
506
|
+
return True
|
|
507
|
+
|
|
508
|
+
# Low confidence itself indicates potential ambiguity
|
|
509
|
+
if workflow_intent.confidence < 0.7:
|
|
510
|
+
return True
|
|
511
|
+
|
|
512
|
+
return False
|
|
513
|
+
|
|
514
|
+
def _generate_suggestions(self, workflow_intent: WorkflowIntent) -> list[str]:
|
|
515
|
+
"""Generate workflow suggestions based on intent."""
|
|
516
|
+
suggestions: list[str] = []
|
|
517
|
+
|
|
518
|
+
if workflow_intent.alternative_matches:
|
|
519
|
+
for workflow_name, _ in workflow_intent.alternative_matches[:3]:
|
|
520
|
+
suggestions.append(workflow_name)
|
|
521
|
+
|
|
522
|
+
# If no match, suggest all available workflows
|
|
523
|
+
if not workflow_intent.workflow_name:
|
|
524
|
+
workflow_names = self._get_workflow_names()
|
|
525
|
+
suggestions.extend(workflow_names[:5])
|
|
526
|
+
|
|
527
|
+
return suggestions
|
|
528
|
+
|