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,465 +1,465 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Expert Engine Runtime Component
|
|
3
|
-
|
|
4
|
-
Orchestrates expert consultation and knowledge retrieval automatically.
|
|
5
|
-
Provides intelligent routing, knowledge need detection, and metrics collection.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from __future__ import annotations
|
|
9
|
-
|
|
10
|
-
from dataclasses import dataclass, field
|
|
11
|
-
from datetime import datetime
|
|
12
|
-
from pathlib import Path
|
|
13
|
-
from typing import Any
|
|
14
|
-
|
|
15
|
-
from ..core.project_profile import ProjectProfile
|
|
16
|
-
from ..core.unified_cache import CacheType, UnifiedCache
|
|
17
|
-
from .expert_registry import ConsultationResult, ExpertRegistry
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
@dataclass
|
|
21
|
-
class KnowledgeNeed:
|
|
22
|
-
"""Represents a detected knowledge need."""
|
|
23
|
-
|
|
24
|
-
domain: str
|
|
25
|
-
query: str
|
|
26
|
-
context: dict[str, Any] = field(default_factory=dict)
|
|
27
|
-
priority: str = "normal" # low, normal, high, critical
|
|
28
|
-
detected_at: datetime = field(default_factory=datetime.now)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
@dataclass
|
|
32
|
-
class ExpertRoutingPlan:
|
|
33
|
-
"""Plan for which experts to consult for a given knowledge need."""
|
|
34
|
-
|
|
35
|
-
knowledge_need: KnowledgeNeed
|
|
36
|
-
expert_ids: list[str]
|
|
37
|
-
domains: list[str]
|
|
38
|
-
priority_order: list[str] = field(default_factory=list)
|
|
39
|
-
reasoning: str = ""
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
@dataclass
|
|
43
|
-
class KnowledgeRetrievalPlan:
|
|
44
|
-
"""Plan for knowledge retrieval from different sources."""
|
|
45
|
-
|
|
46
|
-
knowledge_need: KnowledgeNeed
|
|
47
|
-
context7_sources: list[dict[str, str]] = field(default_factory=list) # [{library, topic}]
|
|
48
|
-
local_kb_sources: list[str] = field(default_factory=list) # [domain paths]
|
|
49
|
-
retrieval_strategy: str = "hybrid" # context7_only, local_only, hybrid
|
|
50
|
-
reasoning: str = ""
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
@dataclass
|
|
54
|
-
class KnowledgeWriteRequest:
|
|
55
|
-
"""Request to write knowledge to the KB."""
|
|
56
|
-
|
|
57
|
-
domain: str
|
|
58
|
-
content: str
|
|
59
|
-
metadata: dict[str, Any] = field(default_factory=dict)
|
|
60
|
-
source: str = "" # Where this knowledge came from
|
|
61
|
-
validated: bool = False
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
@dataclass
|
|
65
|
-
class ExpertEngineMetrics:
|
|
66
|
-
"""Metrics collected by the Expert Engine."""
|
|
67
|
-
|
|
68
|
-
cache_hit_rate: float = 0.0
|
|
69
|
-
context7_hit_rate: float = 0.0
|
|
70
|
-
local_kb_hit_rate: float = 0.0
|
|
71
|
-
retrieval_quality_scores: list[float] = field(default_factory=list)
|
|
72
|
-
confidence_trends: list[float] = field(default_factory=list)
|
|
73
|
-
knowledge_needs_detected: int = 0
|
|
74
|
-
expert_consultations: int = 0
|
|
75
|
-
knowledge_writes: int = 0
|
|
76
|
-
last_updated: datetime = field(default_factory=datetime.now)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
class ExpertEngine:
|
|
80
|
-
"""
|
|
81
|
-
Expert Engine runtime component that orchestrates expert consultation and knowledge retrieval.
|
|
82
|
-
|
|
83
|
-
Provides:
|
|
84
|
-
- Automatic knowledge need detection
|
|
85
|
-
- Expert routing plan generation
|
|
86
|
-
- Knowledge retrieval plan generation
|
|
87
|
-
- Controlled knowledge writes
|
|
88
|
-
- Metrics collection
|
|
89
|
-
"""
|
|
90
|
-
|
|
91
|
-
def __init__(
|
|
92
|
-
self,
|
|
93
|
-
expert_registry: ExpertRegistry,
|
|
94
|
-
unified_cache: UnifiedCache | None = None,
|
|
95
|
-
project_root: Path | None = None,
|
|
96
|
-
enable_metrics: bool = True,
|
|
97
|
-
):
|
|
98
|
-
"""
|
|
99
|
-
Initialize Expert Engine.
|
|
100
|
-
|
|
101
|
-
Args:
|
|
102
|
-
expert_registry: Expert registry for consultation
|
|
103
|
-
unified_cache: Unified cache for knowledge retrieval (optional)
|
|
104
|
-
project_root: Project root directory (optional)
|
|
105
|
-
enable_metrics: Whether to collect metrics (default: True)
|
|
106
|
-
"""
|
|
107
|
-
self.expert_registry = expert_registry
|
|
108
|
-
self.unified_cache = unified_cache
|
|
109
|
-
self.project_root = project_root or Path.cwd()
|
|
110
|
-
self.enable_metrics = enable_metrics
|
|
111
|
-
|
|
112
|
-
# Metrics tracking
|
|
113
|
-
self.metrics = ExpertEngineMetrics()
|
|
114
|
-
self._cache_hits = 0
|
|
115
|
-
self._cache_misses = 0
|
|
116
|
-
self._context7_hits = 0
|
|
117
|
-
self._context7_misses = 0
|
|
118
|
-
self._local_kb_hits = 0
|
|
119
|
-
self._local_kb_misses = 0
|
|
120
|
-
|
|
121
|
-
def detect_knowledge_need(
|
|
122
|
-
self,
|
|
123
|
-
query: str | None = None,
|
|
124
|
-
domain: str | None = None,
|
|
125
|
-
context: dict[str, Any] | None = None,
|
|
126
|
-
step_context: dict[str, Any] | None = None,
|
|
127
|
-
) -> KnowledgeNeed | None:
|
|
128
|
-
"""
|
|
129
|
-
Detect knowledge need from context.
|
|
130
|
-
|
|
131
|
-
Args:
|
|
132
|
-
query: Optional explicit query
|
|
133
|
-
domain: Optional domain hint
|
|
134
|
-
context: Optional context dictionary
|
|
135
|
-
step_context: Optional workflow step context
|
|
136
|
-
|
|
137
|
-
Returns:
|
|
138
|
-
KnowledgeNeed if detected, None otherwise
|
|
139
|
-
"""
|
|
140
|
-
if not query and not step_context:
|
|
141
|
-
return None
|
|
142
|
-
|
|
143
|
-
# Extract query from step context if not provided
|
|
144
|
-
if not query and step_context:
|
|
145
|
-
agent = step_context.get("agent", "")
|
|
146
|
-
action = step_context.get("action", "")
|
|
147
|
-
notes = step_context.get("notes", "")
|
|
148
|
-
metadata = step_context.get("metadata", {})
|
|
149
|
-
|
|
150
|
-
query_parts = []
|
|
151
|
-
if agent:
|
|
152
|
-
query_parts.append(f"Agent: {agent}")
|
|
153
|
-
if action:
|
|
154
|
-
query_parts.append(f"Action: {action}")
|
|
155
|
-
if notes:
|
|
156
|
-
query_parts.append(f"Context: {notes}")
|
|
157
|
-
if metadata:
|
|
158
|
-
context_info = metadata.get("context") or metadata.get("description")
|
|
159
|
-
if context_info:
|
|
160
|
-
query_parts.append(f"Additional context: {context_info}")
|
|
161
|
-
|
|
162
|
-
query = " | ".join(query_parts) if query_parts else None
|
|
163
|
-
|
|
164
|
-
if not query:
|
|
165
|
-
return None
|
|
166
|
-
|
|
167
|
-
# Infer domain from context if not provided
|
|
168
|
-
if not domain:
|
|
169
|
-
if step_context:
|
|
170
|
-
# Try to infer from expert IDs in step
|
|
171
|
-
expert_ids = step_context.get("consults", [])
|
|
172
|
-
if expert_ids:
|
|
173
|
-
first_expert = expert_ids[0]
|
|
174
|
-
if first_expert.startswith("expert-"):
|
|
175
|
-
domain = first_expert.replace("expert-", "")
|
|
176
|
-
else:
|
|
177
|
-
domain = first_expert.split("-")[-1] if "-" in first_expert else "general"
|
|
178
|
-
else:
|
|
179
|
-
# Infer from agent/action
|
|
180
|
-
agent = step_context.get("agent", "")
|
|
181
|
-
if agent:
|
|
182
|
-
domain = agent.replace("agent-", "") if agent.startswith("agent-") else agent
|
|
183
|
-
else:
|
|
184
|
-
domain = "general"
|
|
185
|
-
else:
|
|
186
|
-
domain = "general"
|
|
187
|
-
|
|
188
|
-
# Determine priority
|
|
189
|
-
priority = "normal"
|
|
190
|
-
if context:
|
|
191
|
-
if context.get("critical") or context.get("urgent"):
|
|
192
|
-
priority = "critical"
|
|
193
|
-
elif context.get("high_priority"):
|
|
194
|
-
priority = "high"
|
|
195
|
-
elif context.get("low_priority"):
|
|
196
|
-
priority = "low"
|
|
197
|
-
|
|
198
|
-
knowledge_need = KnowledgeNeed(
|
|
199
|
-
domain=domain,
|
|
200
|
-
query=query,
|
|
201
|
-
context=context or {},
|
|
202
|
-
priority=priority,
|
|
203
|
-
)
|
|
204
|
-
|
|
205
|
-
if self.enable_metrics:
|
|
206
|
-
self.metrics.knowledge_needs_detected += 1
|
|
207
|
-
|
|
208
|
-
return knowledge_need
|
|
209
|
-
|
|
210
|
-
def generate_routing_plan(
|
|
211
|
-
self, knowledge_need: KnowledgeNeed, available_experts: list[str] | None = None
|
|
212
|
-
) -> ExpertRoutingPlan:
|
|
213
|
-
"""
|
|
214
|
-
Generate expert routing plan for a knowledge need.
|
|
215
|
-
|
|
216
|
-
Args:
|
|
217
|
-
knowledge_need: The detected knowledge need
|
|
218
|
-
available_experts: Optional list of available expert IDs (if None, uses registry)
|
|
219
|
-
|
|
220
|
-
Returns:
|
|
221
|
-
ExpertRoutingPlan with expert IDs and domains to consult
|
|
222
|
-
"""
|
|
223
|
-
# Get available experts from registry if not provided
|
|
224
|
-
if available_experts is None:
|
|
225
|
-
available_experts = list(self.expert_registry.experts.keys())
|
|
226
|
-
|
|
227
|
-
# Determine which experts to consult based on domain
|
|
228
|
-
expert_ids = []
|
|
229
|
-
domains = [knowledge_need.domain]
|
|
230
|
-
|
|
231
|
-
# Check if domain-specific experts exist
|
|
232
|
-
domain_expert_id = f"expert-{knowledge_need.domain}"
|
|
233
|
-
if domain_expert_id in available_experts:
|
|
234
|
-
expert_ids.append(domain_expert_id)
|
|
235
|
-
|
|
236
|
-
# Check for related domains/experts
|
|
237
|
-
# For now, use the primary domain expert
|
|
238
|
-
# Future: could use domain config to find related domains
|
|
239
|
-
|
|
240
|
-
# If no domain-specific expert, use general expert
|
|
241
|
-
if not expert_ids:
|
|
242
|
-
general_expert_id = "expert-general"
|
|
243
|
-
if general_expert_id in available_experts:
|
|
244
|
-
expert_ids.append(general_expert_id)
|
|
245
|
-
elif available_experts:
|
|
246
|
-
# Use first available expert as fallback
|
|
247
|
-
expert_ids.append(available_experts[0])
|
|
248
|
-
|
|
249
|
-
# Priority order: domain-specific first, then general
|
|
250
|
-
priority_order = expert_ids.copy()
|
|
251
|
-
|
|
252
|
-
reasoning = f"Routing to {len(expert_ids)} expert(s) for domain '{knowledge_need.domain}'"
|
|
253
|
-
|
|
254
|
-
return ExpertRoutingPlan(
|
|
255
|
-
knowledge_need=knowledge_need,
|
|
256
|
-
expert_ids=expert_ids,
|
|
257
|
-
domains=domains,
|
|
258
|
-
priority_order=priority_order,
|
|
259
|
-
reasoning=reasoning,
|
|
260
|
-
)
|
|
261
|
-
|
|
262
|
-
def generate_retrieval_plan(
|
|
263
|
-
self,
|
|
264
|
-
knowledge_need: KnowledgeNeed,
|
|
265
|
-
project_profile: ProjectProfile | None = None,
|
|
266
|
-
) -> KnowledgeRetrievalPlan:
|
|
267
|
-
"""
|
|
268
|
-
Generate knowledge retrieval plan.
|
|
269
|
-
|
|
270
|
-
Args:
|
|
271
|
-
knowledge_need: The detected knowledge need
|
|
272
|
-
project_profile: Optional project profile for context
|
|
273
|
-
|
|
274
|
-
Returns:
|
|
275
|
-
KnowledgeRetrievalPlan with sources to retrieve from
|
|
276
|
-
"""
|
|
277
|
-
context7_sources = []
|
|
278
|
-
local_kb_sources = []
|
|
279
|
-
retrieval_strategy = "hybrid"
|
|
280
|
-
|
|
281
|
-
# For now, use hybrid strategy
|
|
282
|
-
# Future: could analyze query to determine if Context7 or local KB is more appropriate
|
|
283
|
-
|
|
284
|
-
# Check if query mentions specific libraries (Context7 candidates)
|
|
285
|
-
query_lower = knowledge_need.query.lower()
|
|
286
|
-
# Simple heuristic: if query mentions common library patterns, consider Context7
|
|
287
|
-
library_keywords = ["library", "framework", "package", "dependency", "api"]
|
|
288
|
-
if any(keyword in query_lower for keyword in library_keywords):
|
|
289
|
-
# Would need library detection from project profile or query analysis
|
|
290
|
-
# For now, leave empty - will be populated by domain detector (Story 28.2)
|
|
291
|
-
pass
|
|
292
|
-
|
|
293
|
-
# Local KB sources: use domain
|
|
294
|
-
if knowledge_need.domain:
|
|
295
|
-
local_kb_sources.append(knowledge_need.domain)
|
|
296
|
-
|
|
297
|
-
reasoning = f"Hybrid retrieval: Context7 for library docs, local KB for domain '{knowledge_need.domain}'"
|
|
298
|
-
|
|
299
|
-
return KnowledgeRetrievalPlan(
|
|
300
|
-
knowledge_need=knowledge_need,
|
|
301
|
-
context7_sources=context7_sources,
|
|
302
|
-
local_kb_sources=local_kb_sources,
|
|
303
|
-
retrieval_strategy=retrieval_strategy,
|
|
304
|
-
reasoning=reasoning,
|
|
305
|
-
)
|
|
306
|
-
|
|
307
|
-
async def consult_with_plan(
|
|
308
|
-
self, routing_plan: ExpertRoutingPlan
|
|
309
|
-
) -> ConsultationResult:
|
|
310
|
-
"""
|
|
311
|
-
Consult experts using a routing plan.
|
|
312
|
-
|
|
313
|
-
Args:
|
|
314
|
-
routing_plan: The expert routing plan
|
|
315
|
-
|
|
316
|
-
Returns:
|
|
317
|
-
ConsultationResult from expert registry
|
|
318
|
-
"""
|
|
319
|
-
knowledge_need = routing_plan.knowledge_need
|
|
320
|
-
|
|
321
|
-
# Consult experts via registry
|
|
322
|
-
consultation_result = await self.expert_registry.consult(
|
|
323
|
-
query=knowledge_need.query,
|
|
324
|
-
domain=knowledge_need.domain,
|
|
325
|
-
include_all=True,
|
|
326
|
-
)
|
|
327
|
-
|
|
328
|
-
if self.enable_metrics:
|
|
329
|
-
self.metrics.expert_consultations += 1
|
|
330
|
-
self.metrics.confidence_trends.append(consultation_result.confidence)
|
|
331
|
-
|
|
332
|
-
return consultation_result
|
|
333
|
-
|
|
334
|
-
async def retrieve_knowledge(
|
|
335
|
-
self, retrieval_plan: KnowledgeRetrievalPlan
|
|
336
|
-
) -> dict[str, Any]:
|
|
337
|
-
"""
|
|
338
|
-
Retrieve knowledge according to retrieval plan.
|
|
339
|
-
|
|
340
|
-
Args:
|
|
341
|
-
retrieval_plan: The knowledge retrieval plan
|
|
342
|
-
|
|
343
|
-
Returns:
|
|
344
|
-
Dictionary with retrieved knowledge from various sources
|
|
345
|
-
"""
|
|
346
|
-
if not self.unified_cache:
|
|
347
|
-
return {"error": "Unified cache not available"}
|
|
348
|
-
|
|
349
|
-
knowledge_need = retrieval_plan.knowledge_need
|
|
350
|
-
results = {
|
|
351
|
-
"context7": {},
|
|
352
|
-
"local_kb": {},
|
|
353
|
-
"cache_hits": 0,
|
|
354
|
-
"cache_misses": 0,
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
# Retrieve from Context7 KB cache
|
|
358
|
-
for source in retrieval_plan.context7_sources:
|
|
359
|
-
library = source.get("library", "")
|
|
360
|
-
topic = source.get("topic", "")
|
|
361
|
-
if library and topic:
|
|
362
|
-
cached = self.unified_cache.get(
|
|
363
|
-
CacheType.CONTEXT7_KB,
|
|
364
|
-
key=f"{library}/{topic}",
|
|
365
|
-
library=library,
|
|
366
|
-
topic=topic,
|
|
367
|
-
)
|
|
368
|
-
if cached:
|
|
369
|
-
results["context7"][f"{library}/{topic}"] = cached.content
|
|
370
|
-
self._context7_hits += 1
|
|
371
|
-
results["cache_hits"] += 1
|
|
372
|
-
else:
|
|
373
|
-
self._context7_misses += 1
|
|
374
|
-
results["cache_misses"] += 1
|
|
375
|
-
|
|
376
|
-
# Retrieve from local KB (RAG)
|
|
377
|
-
for domain in retrieval_plan.local_kb_sources:
|
|
378
|
-
if domain:
|
|
379
|
-
cached = self.unified_cache.get(
|
|
380
|
-
CacheType.RAG_KNOWLEDGE,
|
|
381
|
-
key=domain,
|
|
382
|
-
domain=domain,
|
|
383
|
-
query=knowledge_need.query,
|
|
384
|
-
)
|
|
385
|
-
if cached:
|
|
386
|
-
results["local_kb"][domain] = cached.content
|
|
387
|
-
self._local_kb_hits += 1
|
|
388
|
-
results["cache_hits"] += 1
|
|
389
|
-
else:
|
|
390
|
-
self._local_kb_misses += 1
|
|
391
|
-
results["cache_misses"] += 1
|
|
392
|
-
|
|
393
|
-
# Update metrics
|
|
394
|
-
if self.enable_metrics:
|
|
395
|
-
total_requests = results["cache_hits"] + results["cache_misses"]
|
|
396
|
-
if total_requests > 0:
|
|
397
|
-
self._cache_hits += results["cache_hits"]
|
|
398
|
-
self._cache_misses += results["cache_misses"]
|
|
399
|
-
self._update_cache_metrics()
|
|
400
|
-
|
|
401
|
-
return results
|
|
402
|
-
|
|
403
|
-
def write_knowledge(
|
|
404
|
-
self, write_request: KnowledgeWriteRequest, validate: bool = True
|
|
405
|
-
) -> dict[str, Any]:
|
|
406
|
-
"""
|
|
407
|
-
Write knowledge to the KB (controlled write).
|
|
408
|
-
|
|
409
|
-
Args:
|
|
410
|
-
write_request: The knowledge write request
|
|
411
|
-
validate: Whether to validate before writing (default: True)
|
|
412
|
-
|
|
413
|
-
Returns:
|
|
414
|
-
Dictionary with write result
|
|
415
|
-
"""
|
|
416
|
-
if validate and not write_request.validated:
|
|
417
|
-
# Basic validation: check for secrets/PII (will be enhanced in Story 28.5)
|
|
418
|
-
content_lower = write_request.content.lower()
|
|
419
|
-
secret_indicators = ["password", "secret", "api_key", "token", "credential"]
|
|
420
|
-
if any(indicator in content_lower for indicator in secret_indicators):
|
|
421
|
-
return {
|
|
422
|
-
"success": False,
|
|
423
|
-
"error": "Potential secret detected in content. Validation failed.",
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
# For now, return success but don't actually write
|
|
427
|
-
# Actual write implementation will be in Story 28.4 (Knowledge Ingestion Pipeline)
|
|
428
|
-
# This is a controlled interface that will be used by the ingestion pipeline
|
|
429
|
-
|
|
430
|
-
if self.enable_metrics:
|
|
431
|
-
self.metrics.knowledge_writes += 1
|
|
432
|
-
|
|
433
|
-
return {
|
|
434
|
-
"success": True,
|
|
435
|
-
"domain": write_request.domain,
|
|
436
|
-
"validated": write_request.validated,
|
|
437
|
-
"note": "Write interface ready - actual write will be implemented in Story 28.4",
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
def get_metrics(self) -> ExpertEngineMetrics:
|
|
441
|
-
"""
|
|
442
|
-
Get current metrics.
|
|
443
|
-
|
|
444
|
-
Returns:
|
|
445
|
-
ExpertEngineMetrics with current statistics
|
|
446
|
-
"""
|
|
447
|
-
if self.enable_metrics:
|
|
448
|
-
self._update_cache_metrics()
|
|
449
|
-
self.metrics.last_updated = datetime.now()
|
|
450
|
-
return self.metrics
|
|
451
|
-
|
|
452
|
-
def _update_cache_metrics(self):
|
|
453
|
-
"""Update cache hit rate metrics."""
|
|
454
|
-
total_cache_requests = self._cache_hits + self._cache_misses
|
|
455
|
-
if total_cache_requests > 0:
|
|
456
|
-
self.metrics.cache_hit_rate = self._cache_hits / total_cache_requests
|
|
457
|
-
|
|
458
|
-
total_context7_requests = self._context7_hits + self._context7_misses
|
|
459
|
-
if total_context7_requests > 0:
|
|
460
|
-
self.metrics.context7_hit_rate = self._context7_hits / total_context7_requests
|
|
461
|
-
|
|
462
|
-
total_local_kb_requests = self._local_kb_hits + self._local_kb_misses
|
|
463
|
-
if total_local_kb_requests > 0:
|
|
464
|
-
self.metrics.local_kb_hit_rate = self._local_kb_hits / total_local_kb_requests
|
|
465
|
-
|
|
1
|
+
"""
|
|
2
|
+
Expert Engine Runtime Component
|
|
3
|
+
|
|
4
|
+
Orchestrates expert consultation and knowledge retrieval automatically.
|
|
5
|
+
Provides intelligent routing, knowledge need detection, and metrics collection.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
from datetime import datetime
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
from ..core.project_profile import ProjectProfile
|
|
16
|
+
from ..core.unified_cache import CacheType, UnifiedCache
|
|
17
|
+
from .expert_registry import ConsultationResult, ExpertRegistry
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class KnowledgeNeed:
|
|
22
|
+
"""Represents a detected knowledge need."""
|
|
23
|
+
|
|
24
|
+
domain: str
|
|
25
|
+
query: str
|
|
26
|
+
context: dict[str, Any] = field(default_factory=dict)
|
|
27
|
+
priority: str = "normal" # low, normal, high, critical
|
|
28
|
+
detected_at: datetime = field(default_factory=datetime.now)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass
|
|
32
|
+
class ExpertRoutingPlan:
|
|
33
|
+
"""Plan for which experts to consult for a given knowledge need."""
|
|
34
|
+
|
|
35
|
+
knowledge_need: KnowledgeNeed
|
|
36
|
+
expert_ids: list[str]
|
|
37
|
+
domains: list[str]
|
|
38
|
+
priority_order: list[str] = field(default_factory=list)
|
|
39
|
+
reasoning: str = ""
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass
|
|
43
|
+
class KnowledgeRetrievalPlan:
|
|
44
|
+
"""Plan for knowledge retrieval from different sources."""
|
|
45
|
+
|
|
46
|
+
knowledge_need: KnowledgeNeed
|
|
47
|
+
context7_sources: list[dict[str, str]] = field(default_factory=list) # [{library, topic}]
|
|
48
|
+
local_kb_sources: list[str] = field(default_factory=list) # [domain paths]
|
|
49
|
+
retrieval_strategy: str = "hybrid" # context7_only, local_only, hybrid
|
|
50
|
+
reasoning: str = ""
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@dataclass
|
|
54
|
+
class KnowledgeWriteRequest:
|
|
55
|
+
"""Request to write knowledge to the KB."""
|
|
56
|
+
|
|
57
|
+
domain: str
|
|
58
|
+
content: str
|
|
59
|
+
metadata: dict[str, Any] = field(default_factory=dict)
|
|
60
|
+
source: str = "" # Where this knowledge came from
|
|
61
|
+
validated: bool = False
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@dataclass
|
|
65
|
+
class ExpertEngineMetrics:
|
|
66
|
+
"""Metrics collected by the Expert Engine."""
|
|
67
|
+
|
|
68
|
+
cache_hit_rate: float = 0.0
|
|
69
|
+
context7_hit_rate: float = 0.0
|
|
70
|
+
local_kb_hit_rate: float = 0.0
|
|
71
|
+
retrieval_quality_scores: list[float] = field(default_factory=list)
|
|
72
|
+
confidence_trends: list[float] = field(default_factory=list)
|
|
73
|
+
knowledge_needs_detected: int = 0
|
|
74
|
+
expert_consultations: int = 0
|
|
75
|
+
knowledge_writes: int = 0
|
|
76
|
+
last_updated: datetime = field(default_factory=datetime.now)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class ExpertEngine:
|
|
80
|
+
"""
|
|
81
|
+
Expert Engine runtime component that orchestrates expert consultation and knowledge retrieval.
|
|
82
|
+
|
|
83
|
+
Provides:
|
|
84
|
+
- Automatic knowledge need detection
|
|
85
|
+
- Expert routing plan generation
|
|
86
|
+
- Knowledge retrieval plan generation
|
|
87
|
+
- Controlled knowledge writes
|
|
88
|
+
- Metrics collection
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
def __init__(
|
|
92
|
+
self,
|
|
93
|
+
expert_registry: ExpertRegistry,
|
|
94
|
+
unified_cache: UnifiedCache | None = None,
|
|
95
|
+
project_root: Path | None = None,
|
|
96
|
+
enable_metrics: bool = True,
|
|
97
|
+
):
|
|
98
|
+
"""
|
|
99
|
+
Initialize Expert Engine.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
expert_registry: Expert registry for consultation
|
|
103
|
+
unified_cache: Unified cache for knowledge retrieval (optional)
|
|
104
|
+
project_root: Project root directory (optional)
|
|
105
|
+
enable_metrics: Whether to collect metrics (default: True)
|
|
106
|
+
"""
|
|
107
|
+
self.expert_registry = expert_registry
|
|
108
|
+
self.unified_cache = unified_cache
|
|
109
|
+
self.project_root = project_root or Path.cwd()
|
|
110
|
+
self.enable_metrics = enable_metrics
|
|
111
|
+
|
|
112
|
+
# Metrics tracking
|
|
113
|
+
self.metrics = ExpertEngineMetrics()
|
|
114
|
+
self._cache_hits = 0
|
|
115
|
+
self._cache_misses = 0
|
|
116
|
+
self._context7_hits = 0
|
|
117
|
+
self._context7_misses = 0
|
|
118
|
+
self._local_kb_hits = 0
|
|
119
|
+
self._local_kb_misses = 0
|
|
120
|
+
|
|
121
|
+
def detect_knowledge_need(
|
|
122
|
+
self,
|
|
123
|
+
query: str | None = None,
|
|
124
|
+
domain: str | None = None,
|
|
125
|
+
context: dict[str, Any] | None = None,
|
|
126
|
+
step_context: dict[str, Any] | None = None,
|
|
127
|
+
) -> KnowledgeNeed | None:
|
|
128
|
+
"""
|
|
129
|
+
Detect knowledge need from context.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
query: Optional explicit query
|
|
133
|
+
domain: Optional domain hint
|
|
134
|
+
context: Optional context dictionary
|
|
135
|
+
step_context: Optional workflow step context
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
KnowledgeNeed if detected, None otherwise
|
|
139
|
+
"""
|
|
140
|
+
if not query and not step_context:
|
|
141
|
+
return None
|
|
142
|
+
|
|
143
|
+
# Extract query from step context if not provided
|
|
144
|
+
if not query and step_context:
|
|
145
|
+
agent = step_context.get("agent", "")
|
|
146
|
+
action = step_context.get("action", "")
|
|
147
|
+
notes = step_context.get("notes", "")
|
|
148
|
+
metadata = step_context.get("metadata", {})
|
|
149
|
+
|
|
150
|
+
query_parts = []
|
|
151
|
+
if agent:
|
|
152
|
+
query_parts.append(f"Agent: {agent}")
|
|
153
|
+
if action:
|
|
154
|
+
query_parts.append(f"Action: {action}")
|
|
155
|
+
if notes:
|
|
156
|
+
query_parts.append(f"Context: {notes}")
|
|
157
|
+
if metadata:
|
|
158
|
+
context_info = metadata.get("context") or metadata.get("description")
|
|
159
|
+
if context_info:
|
|
160
|
+
query_parts.append(f"Additional context: {context_info}")
|
|
161
|
+
|
|
162
|
+
query = " | ".join(query_parts) if query_parts else None
|
|
163
|
+
|
|
164
|
+
if not query:
|
|
165
|
+
return None
|
|
166
|
+
|
|
167
|
+
# Infer domain from context if not provided
|
|
168
|
+
if not domain:
|
|
169
|
+
if step_context:
|
|
170
|
+
# Try to infer from expert IDs in step
|
|
171
|
+
expert_ids = step_context.get("consults", [])
|
|
172
|
+
if expert_ids:
|
|
173
|
+
first_expert = expert_ids[0]
|
|
174
|
+
if first_expert.startswith("expert-"):
|
|
175
|
+
domain = first_expert.replace("expert-", "")
|
|
176
|
+
else:
|
|
177
|
+
domain = first_expert.split("-")[-1] if "-" in first_expert else "general"
|
|
178
|
+
else:
|
|
179
|
+
# Infer from agent/action
|
|
180
|
+
agent = step_context.get("agent", "")
|
|
181
|
+
if agent:
|
|
182
|
+
domain = agent.replace("agent-", "") if agent.startswith("agent-") else agent
|
|
183
|
+
else:
|
|
184
|
+
domain = "general"
|
|
185
|
+
else:
|
|
186
|
+
domain = "general"
|
|
187
|
+
|
|
188
|
+
# Determine priority
|
|
189
|
+
priority = "normal"
|
|
190
|
+
if context:
|
|
191
|
+
if context.get("critical") or context.get("urgent"):
|
|
192
|
+
priority = "critical"
|
|
193
|
+
elif context.get("high_priority"):
|
|
194
|
+
priority = "high"
|
|
195
|
+
elif context.get("low_priority"):
|
|
196
|
+
priority = "low"
|
|
197
|
+
|
|
198
|
+
knowledge_need = KnowledgeNeed(
|
|
199
|
+
domain=domain,
|
|
200
|
+
query=query,
|
|
201
|
+
context=context or {},
|
|
202
|
+
priority=priority,
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
if self.enable_metrics:
|
|
206
|
+
self.metrics.knowledge_needs_detected += 1
|
|
207
|
+
|
|
208
|
+
return knowledge_need
|
|
209
|
+
|
|
210
|
+
def generate_routing_plan(
|
|
211
|
+
self, knowledge_need: KnowledgeNeed, available_experts: list[str] | None = None
|
|
212
|
+
) -> ExpertRoutingPlan:
|
|
213
|
+
"""
|
|
214
|
+
Generate expert routing plan for a knowledge need.
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
knowledge_need: The detected knowledge need
|
|
218
|
+
available_experts: Optional list of available expert IDs (if None, uses registry)
|
|
219
|
+
|
|
220
|
+
Returns:
|
|
221
|
+
ExpertRoutingPlan with expert IDs and domains to consult
|
|
222
|
+
"""
|
|
223
|
+
# Get available experts from registry if not provided
|
|
224
|
+
if available_experts is None:
|
|
225
|
+
available_experts = list(self.expert_registry.experts.keys())
|
|
226
|
+
|
|
227
|
+
# Determine which experts to consult based on domain
|
|
228
|
+
expert_ids = []
|
|
229
|
+
domains = [knowledge_need.domain]
|
|
230
|
+
|
|
231
|
+
# Check if domain-specific experts exist
|
|
232
|
+
domain_expert_id = f"expert-{knowledge_need.domain}"
|
|
233
|
+
if domain_expert_id in available_experts:
|
|
234
|
+
expert_ids.append(domain_expert_id)
|
|
235
|
+
|
|
236
|
+
# Check for related domains/experts
|
|
237
|
+
# For now, use the primary domain expert
|
|
238
|
+
# Future: could use domain config to find related domains
|
|
239
|
+
|
|
240
|
+
# If no domain-specific expert, use general expert
|
|
241
|
+
if not expert_ids:
|
|
242
|
+
general_expert_id = "expert-general"
|
|
243
|
+
if general_expert_id in available_experts:
|
|
244
|
+
expert_ids.append(general_expert_id)
|
|
245
|
+
elif available_experts:
|
|
246
|
+
# Use first available expert as fallback
|
|
247
|
+
expert_ids.append(available_experts[0])
|
|
248
|
+
|
|
249
|
+
# Priority order: domain-specific first, then general
|
|
250
|
+
priority_order = expert_ids.copy()
|
|
251
|
+
|
|
252
|
+
reasoning = f"Routing to {len(expert_ids)} expert(s) for domain '{knowledge_need.domain}'"
|
|
253
|
+
|
|
254
|
+
return ExpertRoutingPlan(
|
|
255
|
+
knowledge_need=knowledge_need,
|
|
256
|
+
expert_ids=expert_ids,
|
|
257
|
+
domains=domains,
|
|
258
|
+
priority_order=priority_order,
|
|
259
|
+
reasoning=reasoning,
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
def generate_retrieval_plan(
|
|
263
|
+
self,
|
|
264
|
+
knowledge_need: KnowledgeNeed,
|
|
265
|
+
project_profile: ProjectProfile | None = None,
|
|
266
|
+
) -> KnowledgeRetrievalPlan:
|
|
267
|
+
"""
|
|
268
|
+
Generate knowledge retrieval plan.
|
|
269
|
+
|
|
270
|
+
Args:
|
|
271
|
+
knowledge_need: The detected knowledge need
|
|
272
|
+
project_profile: Optional project profile for context
|
|
273
|
+
|
|
274
|
+
Returns:
|
|
275
|
+
KnowledgeRetrievalPlan with sources to retrieve from
|
|
276
|
+
"""
|
|
277
|
+
context7_sources = []
|
|
278
|
+
local_kb_sources = []
|
|
279
|
+
retrieval_strategy = "hybrid"
|
|
280
|
+
|
|
281
|
+
# For now, use hybrid strategy
|
|
282
|
+
# Future: could analyze query to determine if Context7 or local KB is more appropriate
|
|
283
|
+
|
|
284
|
+
# Check if query mentions specific libraries (Context7 candidates)
|
|
285
|
+
query_lower = knowledge_need.query.lower()
|
|
286
|
+
# Simple heuristic: if query mentions common library patterns, consider Context7
|
|
287
|
+
library_keywords = ["library", "framework", "package", "dependency", "api"]
|
|
288
|
+
if any(keyword in query_lower for keyword in library_keywords):
|
|
289
|
+
# Would need library detection from project profile or query analysis
|
|
290
|
+
# For now, leave empty - will be populated by domain detector (Story 28.2)
|
|
291
|
+
pass
|
|
292
|
+
|
|
293
|
+
# Local KB sources: use domain
|
|
294
|
+
if knowledge_need.domain:
|
|
295
|
+
local_kb_sources.append(knowledge_need.domain)
|
|
296
|
+
|
|
297
|
+
reasoning = f"Hybrid retrieval: Context7 for library docs, local KB for domain '{knowledge_need.domain}'"
|
|
298
|
+
|
|
299
|
+
return KnowledgeRetrievalPlan(
|
|
300
|
+
knowledge_need=knowledge_need,
|
|
301
|
+
context7_sources=context7_sources,
|
|
302
|
+
local_kb_sources=local_kb_sources,
|
|
303
|
+
retrieval_strategy=retrieval_strategy,
|
|
304
|
+
reasoning=reasoning,
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
async def consult_with_plan(
|
|
308
|
+
self, routing_plan: ExpertRoutingPlan
|
|
309
|
+
) -> ConsultationResult:
|
|
310
|
+
"""
|
|
311
|
+
Consult experts using a routing plan.
|
|
312
|
+
|
|
313
|
+
Args:
|
|
314
|
+
routing_plan: The expert routing plan
|
|
315
|
+
|
|
316
|
+
Returns:
|
|
317
|
+
ConsultationResult from expert registry
|
|
318
|
+
"""
|
|
319
|
+
knowledge_need = routing_plan.knowledge_need
|
|
320
|
+
|
|
321
|
+
# Consult experts via registry
|
|
322
|
+
consultation_result = await self.expert_registry.consult(
|
|
323
|
+
query=knowledge_need.query,
|
|
324
|
+
domain=knowledge_need.domain,
|
|
325
|
+
include_all=True,
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
if self.enable_metrics:
|
|
329
|
+
self.metrics.expert_consultations += 1
|
|
330
|
+
self.metrics.confidence_trends.append(consultation_result.confidence)
|
|
331
|
+
|
|
332
|
+
return consultation_result
|
|
333
|
+
|
|
334
|
+
async def retrieve_knowledge(
|
|
335
|
+
self, retrieval_plan: KnowledgeRetrievalPlan
|
|
336
|
+
) -> dict[str, Any]:
|
|
337
|
+
"""
|
|
338
|
+
Retrieve knowledge according to retrieval plan.
|
|
339
|
+
|
|
340
|
+
Args:
|
|
341
|
+
retrieval_plan: The knowledge retrieval plan
|
|
342
|
+
|
|
343
|
+
Returns:
|
|
344
|
+
Dictionary with retrieved knowledge from various sources
|
|
345
|
+
"""
|
|
346
|
+
if not self.unified_cache:
|
|
347
|
+
return {"error": "Unified cache not available"}
|
|
348
|
+
|
|
349
|
+
knowledge_need = retrieval_plan.knowledge_need
|
|
350
|
+
results = {
|
|
351
|
+
"context7": {},
|
|
352
|
+
"local_kb": {},
|
|
353
|
+
"cache_hits": 0,
|
|
354
|
+
"cache_misses": 0,
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
# Retrieve from Context7 KB cache
|
|
358
|
+
for source in retrieval_plan.context7_sources:
|
|
359
|
+
library = source.get("library", "")
|
|
360
|
+
topic = source.get("topic", "")
|
|
361
|
+
if library and topic:
|
|
362
|
+
cached = self.unified_cache.get(
|
|
363
|
+
CacheType.CONTEXT7_KB,
|
|
364
|
+
key=f"{library}/{topic}",
|
|
365
|
+
library=library,
|
|
366
|
+
topic=topic,
|
|
367
|
+
)
|
|
368
|
+
if cached:
|
|
369
|
+
results["context7"][f"{library}/{topic}"] = cached.content
|
|
370
|
+
self._context7_hits += 1
|
|
371
|
+
results["cache_hits"] += 1
|
|
372
|
+
else:
|
|
373
|
+
self._context7_misses += 1
|
|
374
|
+
results["cache_misses"] += 1
|
|
375
|
+
|
|
376
|
+
# Retrieve from local KB (RAG)
|
|
377
|
+
for domain in retrieval_plan.local_kb_sources:
|
|
378
|
+
if domain:
|
|
379
|
+
cached = self.unified_cache.get(
|
|
380
|
+
CacheType.RAG_KNOWLEDGE,
|
|
381
|
+
key=domain,
|
|
382
|
+
domain=domain,
|
|
383
|
+
query=knowledge_need.query,
|
|
384
|
+
)
|
|
385
|
+
if cached:
|
|
386
|
+
results["local_kb"][domain] = cached.content
|
|
387
|
+
self._local_kb_hits += 1
|
|
388
|
+
results["cache_hits"] += 1
|
|
389
|
+
else:
|
|
390
|
+
self._local_kb_misses += 1
|
|
391
|
+
results["cache_misses"] += 1
|
|
392
|
+
|
|
393
|
+
# Update metrics
|
|
394
|
+
if self.enable_metrics:
|
|
395
|
+
total_requests = results["cache_hits"] + results["cache_misses"]
|
|
396
|
+
if total_requests > 0:
|
|
397
|
+
self._cache_hits += results["cache_hits"]
|
|
398
|
+
self._cache_misses += results["cache_misses"]
|
|
399
|
+
self._update_cache_metrics()
|
|
400
|
+
|
|
401
|
+
return results
|
|
402
|
+
|
|
403
|
+
def write_knowledge(
|
|
404
|
+
self, write_request: KnowledgeWriteRequest, validate: bool = True
|
|
405
|
+
) -> dict[str, Any]:
|
|
406
|
+
"""
|
|
407
|
+
Write knowledge to the KB (controlled write).
|
|
408
|
+
|
|
409
|
+
Args:
|
|
410
|
+
write_request: The knowledge write request
|
|
411
|
+
validate: Whether to validate before writing (default: True)
|
|
412
|
+
|
|
413
|
+
Returns:
|
|
414
|
+
Dictionary with write result
|
|
415
|
+
"""
|
|
416
|
+
if validate and not write_request.validated:
|
|
417
|
+
# Basic validation: check for secrets/PII (will be enhanced in Story 28.5)
|
|
418
|
+
content_lower = write_request.content.lower()
|
|
419
|
+
secret_indicators = ["password", "secret", "api_key", "token", "credential"]
|
|
420
|
+
if any(indicator in content_lower for indicator in secret_indicators):
|
|
421
|
+
return {
|
|
422
|
+
"success": False,
|
|
423
|
+
"error": "Potential secret detected in content. Validation failed.",
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
# For now, return success but don't actually write
|
|
427
|
+
# Actual write implementation will be in Story 28.4 (Knowledge Ingestion Pipeline)
|
|
428
|
+
# This is a controlled interface that will be used by the ingestion pipeline
|
|
429
|
+
|
|
430
|
+
if self.enable_metrics:
|
|
431
|
+
self.metrics.knowledge_writes += 1
|
|
432
|
+
|
|
433
|
+
return {
|
|
434
|
+
"success": True,
|
|
435
|
+
"domain": write_request.domain,
|
|
436
|
+
"validated": write_request.validated,
|
|
437
|
+
"note": "Write interface ready - actual write will be implemented in Story 28.4",
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
def get_metrics(self) -> ExpertEngineMetrics:
|
|
441
|
+
"""
|
|
442
|
+
Get current metrics.
|
|
443
|
+
|
|
444
|
+
Returns:
|
|
445
|
+
ExpertEngineMetrics with current statistics
|
|
446
|
+
"""
|
|
447
|
+
if self.enable_metrics:
|
|
448
|
+
self._update_cache_metrics()
|
|
449
|
+
self.metrics.last_updated = datetime.now()
|
|
450
|
+
return self.metrics
|
|
451
|
+
|
|
452
|
+
def _update_cache_metrics(self):
|
|
453
|
+
"""Update cache hit rate metrics."""
|
|
454
|
+
total_cache_requests = self._cache_hits + self._cache_misses
|
|
455
|
+
if total_cache_requests > 0:
|
|
456
|
+
self.metrics.cache_hit_rate = self._cache_hits / total_cache_requests
|
|
457
|
+
|
|
458
|
+
total_context7_requests = self._context7_hits + self._context7_misses
|
|
459
|
+
if total_context7_requests > 0:
|
|
460
|
+
self.metrics.context7_hit_rate = self._context7_hits / total_context7_requests
|
|
461
|
+
|
|
462
|
+
total_local_kb_requests = self._local_kb_hits + self._local_kb_misses
|
|
463
|
+
if total_local_kb_requests > 0:
|
|
464
|
+
self.metrics.local_kb_hit_rate = self._local_kb_hits / total_local_kb_requests
|
|
465
|
+
|