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,522 +1,522 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Orchestrator Agent - Coordinates workflows and makes gate decisions.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from pathlib import Path
|
|
6
|
-
from typing import Any
|
|
7
|
-
|
|
8
|
-
from tapps_agents.core.agent_base import BaseAgent
|
|
9
|
-
from tapps_agents.workflow import Workflow, WorkflowExecutor, WorkflowParser
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class OrchestratorAgent(BaseAgent):
|
|
13
|
-
"""
|
|
14
|
-
Orchestrator Agent - Coordinates YAML-defined workflows and makes gate decisions.
|
|
15
|
-
|
|
16
|
-
⚠️ CRITICAL ACCURACY REQUIREMENT:
|
|
17
|
-
- NEVER make up, invent, or fabricate information - Only report verified facts
|
|
18
|
-
- ALWAYS verify claims by checking actual results, not just test pass/fail
|
|
19
|
-
- Verify API calls succeed - inspect response data, status codes, error messages
|
|
20
|
-
- Distinguish between code paths executing and actual functionality working
|
|
21
|
-
- Admit uncertainty explicitly when you cannot verify
|
|
22
|
-
|
|
23
|
-
Responsibilities:
|
|
24
|
-
- Load and execute workflows
|
|
25
|
-
- Make gate decisions based on scoring/conditions
|
|
26
|
-
- Route to Greenfield/Brownfield workflows
|
|
27
|
-
- Track workflow state
|
|
28
|
-
- Coordinate agent execution
|
|
29
|
-
"""
|
|
30
|
-
|
|
31
|
-
def __init__(self, config: Any | None = None):
|
|
32
|
-
super().__init__(
|
|
33
|
-
agent_id="orchestrator", agent_name="Orchestrator", config=config
|
|
34
|
-
)
|
|
35
|
-
self.workflow_executor: WorkflowExecutor | None = None
|
|
36
|
-
self.current_workflow: Workflow | None = None
|
|
37
|
-
|
|
38
|
-
async def activate(self, project_root: Path | None = None, offline_mode: bool = False):
|
|
39
|
-
"""Activate the orchestrator agent."""
|
|
40
|
-
await super().activate(project_root, offline_mode=offline_mode)
|
|
41
|
-
|
|
42
|
-
# Initialize workflow executor
|
|
43
|
-
if project_root:
|
|
44
|
-
self.workflow_executor = WorkflowExecutor(project_root=project_root)
|
|
45
|
-
else:
|
|
46
|
-
self.workflow_executor = WorkflowExecutor()
|
|
47
|
-
|
|
48
|
-
async def run(self, command: str, **kwargs: Any) -> dict[str, Any]:
|
|
49
|
-
"""
|
|
50
|
-
Execute orchestrator commands.
|
|
51
|
-
|
|
52
|
-
Commands:
|
|
53
|
-
- *workflow-list: List available workflows
|
|
54
|
-
- *workflow-start {id}: Start a workflow
|
|
55
|
-
- *workflow {file_path}: Execute a workflow from a YAML file path
|
|
56
|
-
- *workflow-status: Show current workflow status
|
|
57
|
-
- *workflow-next: Show next step
|
|
58
|
-
- *workflow-skip {step}: Skip an optional step
|
|
59
|
-
- *workflow-resume: Resume interrupted workflow
|
|
60
|
-
- *gate {condition}: Make a gate decision
|
|
61
|
-
"""
|
|
62
|
-
if command == "*workflow-list":
|
|
63
|
-
return await self._list_workflows()
|
|
64
|
-
elif command == "*workflow-start":
|
|
65
|
-
workflow_id = kwargs.get("workflow_id")
|
|
66
|
-
if not workflow_id:
|
|
67
|
-
return {"error": "workflow_id required"}
|
|
68
|
-
return await self._start_workflow(workflow_id)
|
|
69
|
-
elif command == "*workflow":
|
|
70
|
-
workflow_file = kwargs.get("workflow_file")
|
|
71
|
-
if not workflow_file:
|
|
72
|
-
return {"error": "workflow_file required"}
|
|
73
|
-
return await self._execute_workflow_from_file(workflow_file)
|
|
74
|
-
elif command == "*workflow-status":
|
|
75
|
-
return await self._get_workflow_status()
|
|
76
|
-
elif command == "*workflow-next":
|
|
77
|
-
return await self._get_next_step()
|
|
78
|
-
elif command == "*workflow-skip":
|
|
79
|
-
step_id = kwargs.get("step_id")
|
|
80
|
-
if not step_id:
|
|
81
|
-
return {"error": "step_id required"}
|
|
82
|
-
return await self._skip_step(step_id)
|
|
83
|
-
elif command == "*workflow-resume":
|
|
84
|
-
return await self._resume_workflow()
|
|
85
|
-
elif command == "*gate":
|
|
86
|
-
condition = kwargs.get("condition")
|
|
87
|
-
scoring_data = kwargs.get("scoring_data", {})
|
|
88
|
-
return await self._make_gate_decision(condition, scoring_data)
|
|
89
|
-
elif command == "*help":
|
|
90
|
-
return self._help()
|
|
91
|
-
elif command == "*validate-workflow-artifacts":
|
|
92
|
-
requirements = kwargs.get("requirements", None)
|
|
93
|
-
stories = kwargs.get("stories", None)
|
|
94
|
-
architecture = kwargs.get("architecture", None)
|
|
95
|
-
api_design = kwargs.get("api_design", None)
|
|
96
|
-
implementation_files = kwargs.get("implementation_files", None)
|
|
97
|
-
|
|
98
|
-
# Load from files if paths provided
|
|
99
|
-
if isinstance(requirements, str):
|
|
100
|
-
req_path = Path(requirements)
|
|
101
|
-
if req_path.exists():
|
|
102
|
-
import json
|
|
103
|
-
requirements = json.loads(req_path.read_text(encoding="utf-8"))
|
|
104
|
-
else:
|
|
105
|
-
return {"error": f"Requirements file not found: {requirements}"}
|
|
106
|
-
|
|
107
|
-
if isinstance(stories, str):
|
|
108
|
-
story_path = Path(stories)
|
|
109
|
-
if story_path.exists():
|
|
110
|
-
import json
|
|
111
|
-
stories = json.loads(story_path.read_text(encoding="utf-8"))
|
|
112
|
-
else:
|
|
113
|
-
return {"error": f"Stories file not found: {stories}"}
|
|
114
|
-
|
|
115
|
-
if isinstance(architecture, str):
|
|
116
|
-
arch_path = Path(architecture)
|
|
117
|
-
if arch_path.exists():
|
|
118
|
-
import json
|
|
119
|
-
architecture = json.loads(arch_path.read_text(encoding="utf-8"))
|
|
120
|
-
else:
|
|
121
|
-
return {"error": f"Architecture file not found: {architecture}"}
|
|
122
|
-
|
|
123
|
-
if isinstance(api_design, str):
|
|
124
|
-
api_path = Path(api_design)
|
|
125
|
-
if api_path.exists():
|
|
126
|
-
import json
|
|
127
|
-
api_design = json.loads(api_path.read_text(encoding="utf-8"))
|
|
128
|
-
else:
|
|
129
|
-
return {"error": f"API design file not found: {api_design}"}
|
|
130
|
-
|
|
131
|
-
return await self._validate_workflow_artifacts(
|
|
132
|
-
requirements, stories, architecture, api_design, implementation_files
|
|
133
|
-
)
|
|
134
|
-
else:
|
|
135
|
-
return {"error": f"Unknown command: {command}"}
|
|
136
|
-
|
|
137
|
-
async def _validate_workflow_artifacts(
|
|
138
|
-
self,
|
|
139
|
-
requirements: dict[str, Any] | None = None,
|
|
140
|
-
stories: list[dict[str, Any]] | None = None,
|
|
141
|
-
architecture: dict[str, Any] | None = None,
|
|
142
|
-
api_design: dict[str, Any] | None = None,
|
|
143
|
-
implementation_files: list[str] | None = None,
|
|
144
|
-
) -> dict[str, Any]:
|
|
145
|
-
"""Validate consistency across workflow artifacts."""
|
|
146
|
-
from ...core.workflow_validator import WorkflowValidator
|
|
147
|
-
|
|
148
|
-
validator = WorkflowValidator()
|
|
149
|
-
result = validator.validate_workflow_artifacts(
|
|
150
|
-
requirements=requirements,
|
|
151
|
-
stories=stories,
|
|
152
|
-
architecture=architecture,
|
|
153
|
-
api_design=api_design,
|
|
154
|
-
implementation_files=implementation_files,
|
|
155
|
-
)
|
|
156
|
-
|
|
157
|
-
return {
|
|
158
|
-
"success": True,
|
|
159
|
-
"is_consistent": result.is_consistent,
|
|
160
|
-
"consistency_score": result.consistency_score,
|
|
161
|
-
"issues": [
|
|
162
|
-
{
|
|
163
|
-
"artifact_type": issue.artifact_type,
|
|
164
|
-
"artifact_id": issue.artifact_id,
|
|
165
|
-
"issue_type": issue.issue_type,
|
|
166
|
-
"description": issue.description,
|
|
167
|
-
"severity": issue.severity,
|
|
168
|
-
"related_artifacts": issue.related_artifacts,
|
|
169
|
-
}
|
|
170
|
-
for issue in result.issues
|
|
171
|
-
],
|
|
172
|
-
"gaps": result.gaps,
|
|
173
|
-
"recommendations": result.recommendations,
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
def _find_all_workflow_files(self, workflows_dir: Path) -> list[Path]:
|
|
177
|
-
"""
|
|
178
|
-
Find all workflow YAML files recursively in the workflows directory.
|
|
179
|
-
|
|
180
|
-
Args:
|
|
181
|
-
workflows_dir: Path to the workflows directory
|
|
182
|
-
|
|
183
|
-
Returns:
|
|
184
|
-
List of Path objects for all workflow files found
|
|
185
|
-
"""
|
|
186
|
-
if not workflows_dir.exists():
|
|
187
|
-
return []
|
|
188
|
-
|
|
189
|
-
# Recursively search for .yaml and .yml files
|
|
190
|
-
workflow_files = list(workflows_dir.rglob("*.yaml")) + list(
|
|
191
|
-
workflows_dir.rglob("*.yml")
|
|
192
|
-
)
|
|
193
|
-
|
|
194
|
-
return workflow_files
|
|
195
|
-
|
|
196
|
-
async def _list_workflows(self) -> dict[str, Any]:
|
|
197
|
-
"""List available workflows."""
|
|
198
|
-
workflows_dir = Path("workflows")
|
|
199
|
-
if not workflows_dir.exists():
|
|
200
|
-
return {"workflows": [], "message": "No workflows directory found"}
|
|
201
|
-
|
|
202
|
-
workflow_files = self._find_all_workflow_files(workflows_dir)
|
|
203
|
-
|
|
204
|
-
workflows = []
|
|
205
|
-
for workflow_file in workflow_files:
|
|
206
|
-
try:
|
|
207
|
-
workflow = WorkflowParser.parse_file(workflow_file)
|
|
208
|
-
workflows.append(
|
|
209
|
-
{
|
|
210
|
-
"id": workflow.id,
|
|
211
|
-
"name": workflow.name,
|
|
212
|
-
"description": workflow.description,
|
|
213
|
-
"version": workflow.version,
|
|
214
|
-
"type": workflow.type.value,
|
|
215
|
-
"file": str(workflow_file),
|
|
216
|
-
}
|
|
217
|
-
)
|
|
218
|
-
except Exception as e:
|
|
219
|
-
workflows.append(
|
|
220
|
-
{
|
|
221
|
-
"id": workflow_file.stem,
|
|
222
|
-
"name": workflow_file.name,
|
|
223
|
-
"error": str(e),
|
|
224
|
-
}
|
|
225
|
-
)
|
|
226
|
-
|
|
227
|
-
return {"workflows": workflows}
|
|
228
|
-
|
|
229
|
-
def _find_workflow_by_id(self, workflows_dir: Path, workflow_id: str) -> Path | None:
|
|
230
|
-
"""
|
|
231
|
-
Find a workflow file by ID, searching recursively in subdirectories.
|
|
232
|
-
|
|
233
|
-
Args:
|
|
234
|
-
workflows_dir: Path to the workflows directory
|
|
235
|
-
workflow_id: The workflow ID to search for
|
|
236
|
-
|
|
237
|
-
Returns:
|
|
238
|
-
Path to the workflow file, or None if not found
|
|
239
|
-
"""
|
|
240
|
-
if not workflows_dir.exists():
|
|
241
|
-
return None
|
|
242
|
-
|
|
243
|
-
# Search recursively for files matching the workflow ID
|
|
244
|
-
for ext in [".yaml", ".yml"]:
|
|
245
|
-
candidates = list(workflows_dir.rglob(f"{workflow_id}{ext}"))
|
|
246
|
-
if candidates:
|
|
247
|
-
# If multiple found, prefer exact match in root, otherwise return first
|
|
248
|
-
root_candidate = workflows_dir / f"{workflow_id}{ext}"
|
|
249
|
-
if root_candidate in candidates:
|
|
250
|
-
return root_candidate
|
|
251
|
-
return candidates[0]
|
|
252
|
-
|
|
253
|
-
return None
|
|
254
|
-
|
|
255
|
-
async def _execute_workflow_from_file(self, workflow_file_path: str) -> dict[str, Any]:
|
|
256
|
-
"""Execute a workflow from a file path."""
|
|
257
|
-
if not self.workflow_executor:
|
|
258
|
-
return {"error": "Workflow executor not initialized"}
|
|
259
|
-
|
|
260
|
-
# Validate input
|
|
261
|
-
if not workflow_file_path or not isinstance(workflow_file_path, str):
|
|
262
|
-
return {"error": "workflow_file_path must be a non-empty string"}
|
|
263
|
-
|
|
264
|
-
# Resolve file path (supports both relative and absolute paths)
|
|
265
|
-
workflow_path = Path(workflow_file_path)
|
|
266
|
-
if not workflow_path.is_absolute():
|
|
267
|
-
# Relative path - resolve from project root (set during activate)
|
|
268
|
-
# BaseAgent stores project_root as _project_root
|
|
269
|
-
base_path = getattr(self, "_project_root", None) or Path.cwd()
|
|
270
|
-
workflow_path = (base_path / workflow_path).resolve()
|
|
271
|
-
else:
|
|
272
|
-
workflow_path = workflow_path.resolve()
|
|
273
|
-
|
|
274
|
-
if not workflow_path.exists():
|
|
275
|
-
return {"error": f"Workflow file not found: {workflow_file_path} (resolved to: {workflow_path})"}
|
|
276
|
-
|
|
277
|
-
if not workflow_path.is_file():
|
|
278
|
-
return {"error": f"Path is not a file: {workflow_file_path} (resolved to: {workflow_path})"}
|
|
279
|
-
|
|
280
|
-
try:
|
|
281
|
-
# Load and start workflow
|
|
282
|
-
workflow = self.workflow_executor.load_workflow(workflow_path)
|
|
283
|
-
self.current_workflow = workflow
|
|
284
|
-
state = self.workflow_executor.start()
|
|
285
|
-
|
|
286
|
-
return {
|
|
287
|
-
"success": True,
|
|
288
|
-
"workflow_id": workflow.id,
|
|
289
|
-
"workflow_name": workflow.name,
|
|
290
|
-
"workflow_file": str(workflow_path),
|
|
291
|
-
"status": state.status,
|
|
292
|
-
"current_step": state.current_step,
|
|
293
|
-
"message": f"Workflow '{workflow.name}' started from {workflow_file_path}",
|
|
294
|
-
}
|
|
295
|
-
except Exception as e:
|
|
296
|
-
return {"error": f"Failed to execute workflow from file: {str(e)}"}
|
|
297
|
-
|
|
298
|
-
async def _start_workflow(self, workflow_id: str) -> dict[str, Any]:
|
|
299
|
-
"""Start a workflow."""
|
|
300
|
-
if not self.workflow_executor:
|
|
301
|
-
return {"error": "Workflow executor not initialized"}
|
|
302
|
-
|
|
303
|
-
# Find workflow file recursively
|
|
304
|
-
workflows_dir = Path("workflows")
|
|
305
|
-
workflow_file = self._find_workflow_by_id(workflows_dir, workflow_id)
|
|
306
|
-
|
|
307
|
-
if not workflow_file:
|
|
308
|
-
return {"error": f"Workflow '{workflow_id}' not found"}
|
|
309
|
-
|
|
310
|
-
try:
|
|
311
|
-
# Load and start workflow
|
|
312
|
-
workflow = self.workflow_executor.load_workflow(workflow_file)
|
|
313
|
-
self.current_workflow = workflow
|
|
314
|
-
state = self.workflow_executor.start()
|
|
315
|
-
|
|
316
|
-
return {
|
|
317
|
-
"success": True,
|
|
318
|
-
"workflow_id": workflow.id,
|
|
319
|
-
"workflow_name": workflow.name,
|
|
320
|
-
"status": state.status,
|
|
321
|
-
"current_step": state.current_step,
|
|
322
|
-
"message": f"Workflow '{workflow.name}' started",
|
|
323
|
-
}
|
|
324
|
-
except Exception as e:
|
|
325
|
-
return {"error": f"Failed to start workflow: {str(e)}"}
|
|
326
|
-
|
|
327
|
-
async def _get_workflow_status(self) -> dict[str, Any]:
|
|
328
|
-
"""Get current workflow status."""
|
|
329
|
-
if not self.workflow_executor:
|
|
330
|
-
return {"error": "No workflow active"}
|
|
331
|
-
|
|
332
|
-
status = self.workflow_executor.get_status()
|
|
333
|
-
return status
|
|
334
|
-
|
|
335
|
-
async def _get_next_step(self) -> dict[str, Any]:
|
|
336
|
-
"""Get next workflow step."""
|
|
337
|
-
if not self.workflow_executor:
|
|
338
|
-
return {"error": "No workflow active"}
|
|
339
|
-
|
|
340
|
-
next_step = self.workflow_executor.get_next_step()
|
|
341
|
-
if not next_step:
|
|
342
|
-
return {"message": "No next step (workflow may be complete)"}
|
|
343
|
-
|
|
344
|
-
return {
|
|
345
|
-
"next_step": {
|
|
346
|
-
"id": next_step.id,
|
|
347
|
-
"agent": next_step.agent,
|
|
348
|
-
"action": next_step.action,
|
|
349
|
-
"context_tier": next_step.context_tier,
|
|
350
|
-
"requires": next_step.requires,
|
|
351
|
-
"creates": next_step.creates,
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
async def _skip_step(self, step_id: str) -> dict[str, Any]:
|
|
356
|
-
"""Skip an optional step."""
|
|
357
|
-
if not self.workflow_executor:
|
|
358
|
-
return {"error": "No workflow active"}
|
|
359
|
-
|
|
360
|
-
try:
|
|
361
|
-
self.workflow_executor.skip_step(step_id)
|
|
362
|
-
return {
|
|
363
|
-
"success": True,
|
|
364
|
-
"message": f"Step '{step_id}' skipped",
|
|
365
|
-
"current_step": (
|
|
366
|
-
self.workflow_executor.state.current_step
|
|
367
|
-
if self.workflow_executor.state
|
|
368
|
-
else None
|
|
369
|
-
),
|
|
370
|
-
}
|
|
371
|
-
except Exception as e:
|
|
372
|
-
return {"error": f"Failed to skip step: {str(e)}"}
|
|
373
|
-
|
|
374
|
-
async def _resume_workflow(self) -> dict[str, Any]:
|
|
375
|
-
"""Resume an interrupted workflow."""
|
|
376
|
-
if not self.workflow_executor:
|
|
377
|
-
return {"error": "Workflow executor not initialized"}
|
|
378
|
-
|
|
379
|
-
try:
|
|
380
|
-
state = self.workflow_executor.load_last_state()
|
|
381
|
-
self.current_workflow = self.workflow_executor.workflow
|
|
382
|
-
|
|
383
|
-
return {
|
|
384
|
-
"success": True,
|
|
385
|
-
"workflow_id": state.workflow_id,
|
|
386
|
-
"status": state.status,
|
|
387
|
-
"current_step": state.current_step,
|
|
388
|
-
"completed_steps": state.completed_steps,
|
|
389
|
-
"skipped_steps": state.skipped_steps,
|
|
390
|
-
"artifacts": {
|
|
391
|
-
k: {"path": v.path, "status": v.status}
|
|
392
|
-
for k, v in (state.artifacts or {}).items()
|
|
393
|
-
},
|
|
394
|
-
"message": "Workflow resumed from persisted state",
|
|
395
|
-
}
|
|
396
|
-
except FileNotFoundError as e:
|
|
397
|
-
return {"error": str(e)}
|
|
398
|
-
except Exception as e:
|
|
399
|
-
return {"error": f"Failed to resume workflow: {str(e)}"}
|
|
400
|
-
|
|
401
|
-
async def _make_gate_decision(
|
|
402
|
-
self, condition: str | None, scoring_data: dict[str, Any]
|
|
403
|
-
) -> dict[str, Any]:
|
|
404
|
-
"""
|
|
405
|
-
Make a gate decision based on condition and scoring data.
|
|
406
|
-
|
|
407
|
-
Args:
|
|
408
|
-
condition: Gate condition string (e.g., "scoring.passed == true")
|
|
409
|
-
scoring_data: Scoring results from reviewer agent
|
|
410
|
-
|
|
411
|
-
Returns:
|
|
412
|
-
Gate decision with pass/fail status
|
|
413
|
-
"""
|
|
414
|
-
if not condition:
|
|
415
|
-
# Default gate: check if scoring passed
|
|
416
|
-
passed = scoring_data.get("passed", False)
|
|
417
|
-
overall_score = scoring_data.get("overall_score", 0)
|
|
418
|
-
|
|
419
|
-
return {
|
|
420
|
-
"passed": passed,
|
|
421
|
-
"overall_score": overall_score,
|
|
422
|
-
"message": "Gate passed" if passed else "Gate failed",
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
# Evaluate condition (simplified - in production, use a proper expression evaluator)
|
|
426
|
-
try:
|
|
427
|
-
# Simple condition evaluation
|
|
428
|
-
if "scoring.passed" in condition:
|
|
429
|
-
passed = scoring_data.get("passed", False)
|
|
430
|
-
if "==" in condition and "true" in condition:
|
|
431
|
-
gate_passed = passed
|
|
432
|
-
elif "==" in condition and "false" in condition:
|
|
433
|
-
gate_passed = not passed
|
|
434
|
-
else:
|
|
435
|
-
gate_passed = passed
|
|
436
|
-
|
|
437
|
-
return {
|
|
438
|
-
"passed": gate_passed,
|
|
439
|
-
"condition": condition,
|
|
440
|
-
"scoring": scoring_data,
|
|
441
|
-
"message": "Gate passed" if gate_passed else "Gate failed",
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
# Check score thresholds
|
|
445
|
-
if "overall_score" in condition or "overall_min" in condition:
|
|
446
|
-
overall_score = scoring_data.get("overall_score", 0)
|
|
447
|
-
# Extract threshold from condition (simplified)
|
|
448
|
-
threshold = 70 # Default
|
|
449
|
-
if ">=" in condition:
|
|
450
|
-
try:
|
|
451
|
-
threshold = int(condition.split(">=")[1].strip().split()[0])
|
|
452
|
-
except (ValueError, IndexError):
|
|
453
|
-
pass
|
|
454
|
-
|
|
455
|
-
gate_passed = overall_score >= threshold
|
|
456
|
-
return {
|
|
457
|
-
"passed": gate_passed,
|
|
458
|
-
"overall_score": overall_score,
|
|
459
|
-
"threshold": threshold,
|
|
460
|
-
"message": f"Gate {'passed' if gate_passed else 'failed'}: {overall_score} >= {threshold}",
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
return {
|
|
464
|
-
"passed": False,
|
|
465
|
-
"error": f"Unsupported condition: {condition}",
|
|
466
|
-
"message": "Gate evaluation failed",
|
|
467
|
-
}
|
|
468
|
-
except Exception as e:
|
|
469
|
-
return {
|
|
470
|
-
"passed": False,
|
|
471
|
-
"error": str(e),
|
|
472
|
-
"message": "Gate evaluation error",
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
def _help(self) -> dict[str, Any]:
|
|
476
|
-
"""
|
|
477
|
-
Return help information for Orchestrator Agent.
|
|
478
|
-
|
|
479
|
-
Returns standardized help format with commands and description.
|
|
480
|
-
|
|
481
|
-
Returns:
|
|
482
|
-
dict: Help information with standardized format:
|
|
483
|
-
- type (str): Always "help"
|
|
484
|
-
- content (str): Formatted help text containing:
|
|
485
|
-
- Available commands with descriptions
|
|
486
|
-
- Agent description
|
|
487
|
-
|
|
488
|
-
Note:
|
|
489
|
-
This method is synchronous as it performs no I/O operations.
|
|
490
|
-
Called via agent.run("help") which handles async context.
|
|
491
|
-
Standardized to match format used by other agents.
|
|
492
|
-
"""
|
|
493
|
-
commands_dict = {
|
|
494
|
-
"*workflow-list": "List available workflows",
|
|
495
|
-
"*workflow-start {workflow_id}": "Start a workflow by ID",
|
|
496
|
-
"*workflow {workflow_file}": "Execute a workflow from a YAML file path",
|
|
497
|
-
"*workflow-status": "Show current workflow status",
|
|
498
|
-
"*workflow-next": "Show next step in workflow",
|
|
499
|
-
"*workflow-skip {step_id}": "Skip an optional step",
|
|
500
|
-
"*workflow-resume": "Resume interrupted workflow",
|
|
501
|
-
"*gate {condition}": "Make a gate decision based on condition and scoring",
|
|
502
|
-
"*help": "Show this help message",
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
# Format as markdown for consistency with other agents
|
|
506
|
-
command_lines = [
|
|
507
|
-
f"- **{cmd}**: {desc}"
|
|
508
|
-
for cmd, desc in commands_dict.items()
|
|
509
|
-
]
|
|
510
|
-
|
|
511
|
-
content = f"""# {self.agent_name} - Help
|
|
512
|
-
|
|
513
|
-
## Available Commands
|
|
514
|
-
|
|
515
|
-
{chr(10).join(command_lines)}
|
|
516
|
-
|
|
517
|
-
## Description
|
|
518
|
-
|
|
519
|
-
Orchestrator Agent coordinates workflows and makes gate decisions.
|
|
520
|
-
"""
|
|
521
|
-
|
|
522
|
-
return {"type": "help", "content": content}
|
|
1
|
+
"""
|
|
2
|
+
Orchestrator Agent - Coordinates workflows and makes gate decisions.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from tapps_agents.core.agent_base import BaseAgent
|
|
9
|
+
from tapps_agents.workflow import Workflow, WorkflowExecutor, WorkflowParser
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class OrchestratorAgent(BaseAgent):
|
|
13
|
+
"""
|
|
14
|
+
Orchestrator Agent - Coordinates YAML-defined workflows and makes gate decisions.
|
|
15
|
+
|
|
16
|
+
⚠️ CRITICAL ACCURACY REQUIREMENT:
|
|
17
|
+
- NEVER make up, invent, or fabricate information - Only report verified facts
|
|
18
|
+
- ALWAYS verify claims by checking actual results, not just test pass/fail
|
|
19
|
+
- Verify API calls succeed - inspect response data, status codes, error messages
|
|
20
|
+
- Distinguish between code paths executing and actual functionality working
|
|
21
|
+
- Admit uncertainty explicitly when you cannot verify
|
|
22
|
+
|
|
23
|
+
Responsibilities:
|
|
24
|
+
- Load and execute workflows
|
|
25
|
+
- Make gate decisions based on scoring/conditions
|
|
26
|
+
- Route to Greenfield/Brownfield workflows
|
|
27
|
+
- Track workflow state
|
|
28
|
+
- Coordinate agent execution
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self, config: Any | None = None):
|
|
32
|
+
super().__init__(
|
|
33
|
+
agent_id="orchestrator", agent_name="Orchestrator", config=config
|
|
34
|
+
)
|
|
35
|
+
self.workflow_executor: WorkflowExecutor | None = None
|
|
36
|
+
self.current_workflow: Workflow | None = None
|
|
37
|
+
|
|
38
|
+
async def activate(self, project_root: Path | None = None, offline_mode: bool = False):
|
|
39
|
+
"""Activate the orchestrator agent."""
|
|
40
|
+
await super().activate(project_root, offline_mode=offline_mode)
|
|
41
|
+
|
|
42
|
+
# Initialize workflow executor
|
|
43
|
+
if project_root:
|
|
44
|
+
self.workflow_executor = WorkflowExecutor(project_root=project_root)
|
|
45
|
+
else:
|
|
46
|
+
self.workflow_executor = WorkflowExecutor()
|
|
47
|
+
|
|
48
|
+
async def run(self, command: str, **kwargs: Any) -> dict[str, Any]:
|
|
49
|
+
"""
|
|
50
|
+
Execute orchestrator commands.
|
|
51
|
+
|
|
52
|
+
Commands:
|
|
53
|
+
- *workflow-list: List available workflows
|
|
54
|
+
- *workflow-start {id}: Start a workflow
|
|
55
|
+
- *workflow {file_path}: Execute a workflow from a YAML file path
|
|
56
|
+
- *workflow-status: Show current workflow status
|
|
57
|
+
- *workflow-next: Show next step
|
|
58
|
+
- *workflow-skip {step}: Skip an optional step
|
|
59
|
+
- *workflow-resume: Resume interrupted workflow
|
|
60
|
+
- *gate {condition}: Make a gate decision
|
|
61
|
+
"""
|
|
62
|
+
if command == "*workflow-list":
|
|
63
|
+
return await self._list_workflows()
|
|
64
|
+
elif command == "*workflow-start":
|
|
65
|
+
workflow_id = kwargs.get("workflow_id")
|
|
66
|
+
if not workflow_id:
|
|
67
|
+
return {"error": "workflow_id required"}
|
|
68
|
+
return await self._start_workflow(workflow_id)
|
|
69
|
+
elif command == "*workflow":
|
|
70
|
+
workflow_file = kwargs.get("workflow_file")
|
|
71
|
+
if not workflow_file:
|
|
72
|
+
return {"error": "workflow_file required"}
|
|
73
|
+
return await self._execute_workflow_from_file(workflow_file)
|
|
74
|
+
elif command == "*workflow-status":
|
|
75
|
+
return await self._get_workflow_status()
|
|
76
|
+
elif command == "*workflow-next":
|
|
77
|
+
return await self._get_next_step()
|
|
78
|
+
elif command == "*workflow-skip":
|
|
79
|
+
step_id = kwargs.get("step_id")
|
|
80
|
+
if not step_id:
|
|
81
|
+
return {"error": "step_id required"}
|
|
82
|
+
return await self._skip_step(step_id)
|
|
83
|
+
elif command == "*workflow-resume":
|
|
84
|
+
return await self._resume_workflow()
|
|
85
|
+
elif command == "*gate":
|
|
86
|
+
condition = kwargs.get("condition")
|
|
87
|
+
scoring_data = kwargs.get("scoring_data", {})
|
|
88
|
+
return await self._make_gate_decision(condition, scoring_data)
|
|
89
|
+
elif command == "*help":
|
|
90
|
+
return self._help()
|
|
91
|
+
elif command == "*validate-workflow-artifacts":
|
|
92
|
+
requirements = kwargs.get("requirements", None)
|
|
93
|
+
stories = kwargs.get("stories", None)
|
|
94
|
+
architecture = kwargs.get("architecture", None)
|
|
95
|
+
api_design = kwargs.get("api_design", None)
|
|
96
|
+
implementation_files = kwargs.get("implementation_files", None)
|
|
97
|
+
|
|
98
|
+
# Load from files if paths provided
|
|
99
|
+
if isinstance(requirements, str):
|
|
100
|
+
req_path = Path(requirements)
|
|
101
|
+
if req_path.exists():
|
|
102
|
+
import json
|
|
103
|
+
requirements = json.loads(req_path.read_text(encoding="utf-8"))
|
|
104
|
+
else:
|
|
105
|
+
return {"error": f"Requirements file not found: {requirements}"}
|
|
106
|
+
|
|
107
|
+
if isinstance(stories, str):
|
|
108
|
+
story_path = Path(stories)
|
|
109
|
+
if story_path.exists():
|
|
110
|
+
import json
|
|
111
|
+
stories = json.loads(story_path.read_text(encoding="utf-8"))
|
|
112
|
+
else:
|
|
113
|
+
return {"error": f"Stories file not found: {stories}"}
|
|
114
|
+
|
|
115
|
+
if isinstance(architecture, str):
|
|
116
|
+
arch_path = Path(architecture)
|
|
117
|
+
if arch_path.exists():
|
|
118
|
+
import json
|
|
119
|
+
architecture = json.loads(arch_path.read_text(encoding="utf-8"))
|
|
120
|
+
else:
|
|
121
|
+
return {"error": f"Architecture file not found: {architecture}"}
|
|
122
|
+
|
|
123
|
+
if isinstance(api_design, str):
|
|
124
|
+
api_path = Path(api_design)
|
|
125
|
+
if api_path.exists():
|
|
126
|
+
import json
|
|
127
|
+
api_design = json.loads(api_path.read_text(encoding="utf-8"))
|
|
128
|
+
else:
|
|
129
|
+
return {"error": f"API design file not found: {api_design}"}
|
|
130
|
+
|
|
131
|
+
return await self._validate_workflow_artifacts(
|
|
132
|
+
requirements, stories, architecture, api_design, implementation_files
|
|
133
|
+
)
|
|
134
|
+
else:
|
|
135
|
+
return {"error": f"Unknown command: {command}"}
|
|
136
|
+
|
|
137
|
+
async def _validate_workflow_artifacts(
|
|
138
|
+
self,
|
|
139
|
+
requirements: dict[str, Any] | None = None,
|
|
140
|
+
stories: list[dict[str, Any]] | None = None,
|
|
141
|
+
architecture: dict[str, Any] | None = None,
|
|
142
|
+
api_design: dict[str, Any] | None = None,
|
|
143
|
+
implementation_files: list[str] | None = None,
|
|
144
|
+
) -> dict[str, Any]:
|
|
145
|
+
"""Validate consistency across workflow artifacts."""
|
|
146
|
+
from ...core.workflow_validator import WorkflowValidator
|
|
147
|
+
|
|
148
|
+
validator = WorkflowValidator()
|
|
149
|
+
result = validator.validate_workflow_artifacts(
|
|
150
|
+
requirements=requirements,
|
|
151
|
+
stories=stories,
|
|
152
|
+
architecture=architecture,
|
|
153
|
+
api_design=api_design,
|
|
154
|
+
implementation_files=implementation_files,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
"success": True,
|
|
159
|
+
"is_consistent": result.is_consistent,
|
|
160
|
+
"consistency_score": result.consistency_score,
|
|
161
|
+
"issues": [
|
|
162
|
+
{
|
|
163
|
+
"artifact_type": issue.artifact_type,
|
|
164
|
+
"artifact_id": issue.artifact_id,
|
|
165
|
+
"issue_type": issue.issue_type,
|
|
166
|
+
"description": issue.description,
|
|
167
|
+
"severity": issue.severity,
|
|
168
|
+
"related_artifacts": issue.related_artifacts,
|
|
169
|
+
}
|
|
170
|
+
for issue in result.issues
|
|
171
|
+
],
|
|
172
|
+
"gaps": result.gaps,
|
|
173
|
+
"recommendations": result.recommendations,
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
def _find_all_workflow_files(self, workflows_dir: Path) -> list[Path]:
|
|
177
|
+
"""
|
|
178
|
+
Find all workflow YAML files recursively in the workflows directory.
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
workflows_dir: Path to the workflows directory
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
List of Path objects for all workflow files found
|
|
185
|
+
"""
|
|
186
|
+
if not workflows_dir.exists():
|
|
187
|
+
return []
|
|
188
|
+
|
|
189
|
+
# Recursively search for .yaml and .yml files
|
|
190
|
+
workflow_files = list(workflows_dir.rglob("*.yaml")) + list(
|
|
191
|
+
workflows_dir.rglob("*.yml")
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
return workflow_files
|
|
195
|
+
|
|
196
|
+
async def _list_workflows(self) -> dict[str, Any]:
|
|
197
|
+
"""List available workflows."""
|
|
198
|
+
workflows_dir = Path("workflows")
|
|
199
|
+
if not workflows_dir.exists():
|
|
200
|
+
return {"workflows": [], "message": "No workflows directory found"}
|
|
201
|
+
|
|
202
|
+
workflow_files = self._find_all_workflow_files(workflows_dir)
|
|
203
|
+
|
|
204
|
+
workflows = []
|
|
205
|
+
for workflow_file in workflow_files:
|
|
206
|
+
try:
|
|
207
|
+
workflow = WorkflowParser.parse_file(workflow_file)
|
|
208
|
+
workflows.append(
|
|
209
|
+
{
|
|
210
|
+
"id": workflow.id,
|
|
211
|
+
"name": workflow.name,
|
|
212
|
+
"description": workflow.description,
|
|
213
|
+
"version": workflow.version,
|
|
214
|
+
"type": workflow.type.value,
|
|
215
|
+
"file": str(workflow_file),
|
|
216
|
+
}
|
|
217
|
+
)
|
|
218
|
+
except Exception as e:
|
|
219
|
+
workflows.append(
|
|
220
|
+
{
|
|
221
|
+
"id": workflow_file.stem,
|
|
222
|
+
"name": workflow_file.name,
|
|
223
|
+
"error": str(e),
|
|
224
|
+
}
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
return {"workflows": workflows}
|
|
228
|
+
|
|
229
|
+
def _find_workflow_by_id(self, workflows_dir: Path, workflow_id: str) -> Path | None:
|
|
230
|
+
"""
|
|
231
|
+
Find a workflow file by ID, searching recursively in subdirectories.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
workflows_dir: Path to the workflows directory
|
|
235
|
+
workflow_id: The workflow ID to search for
|
|
236
|
+
|
|
237
|
+
Returns:
|
|
238
|
+
Path to the workflow file, or None if not found
|
|
239
|
+
"""
|
|
240
|
+
if not workflows_dir.exists():
|
|
241
|
+
return None
|
|
242
|
+
|
|
243
|
+
# Search recursively for files matching the workflow ID
|
|
244
|
+
for ext in [".yaml", ".yml"]:
|
|
245
|
+
candidates = list(workflows_dir.rglob(f"{workflow_id}{ext}"))
|
|
246
|
+
if candidates:
|
|
247
|
+
# If multiple found, prefer exact match in root, otherwise return first
|
|
248
|
+
root_candidate = workflows_dir / f"{workflow_id}{ext}"
|
|
249
|
+
if root_candidate in candidates:
|
|
250
|
+
return root_candidate
|
|
251
|
+
return candidates[0]
|
|
252
|
+
|
|
253
|
+
return None
|
|
254
|
+
|
|
255
|
+
async def _execute_workflow_from_file(self, workflow_file_path: str) -> dict[str, Any]:
|
|
256
|
+
"""Execute a workflow from a file path."""
|
|
257
|
+
if not self.workflow_executor:
|
|
258
|
+
return {"error": "Workflow executor not initialized"}
|
|
259
|
+
|
|
260
|
+
# Validate input
|
|
261
|
+
if not workflow_file_path or not isinstance(workflow_file_path, str):
|
|
262
|
+
return {"error": "workflow_file_path must be a non-empty string"}
|
|
263
|
+
|
|
264
|
+
# Resolve file path (supports both relative and absolute paths)
|
|
265
|
+
workflow_path = Path(workflow_file_path)
|
|
266
|
+
if not workflow_path.is_absolute():
|
|
267
|
+
# Relative path - resolve from project root (set during activate)
|
|
268
|
+
# BaseAgent stores project_root as _project_root
|
|
269
|
+
base_path = getattr(self, "_project_root", None) or Path.cwd()
|
|
270
|
+
workflow_path = (base_path / workflow_path).resolve()
|
|
271
|
+
else:
|
|
272
|
+
workflow_path = workflow_path.resolve()
|
|
273
|
+
|
|
274
|
+
if not workflow_path.exists():
|
|
275
|
+
return {"error": f"Workflow file not found: {workflow_file_path} (resolved to: {workflow_path})"}
|
|
276
|
+
|
|
277
|
+
if not workflow_path.is_file():
|
|
278
|
+
return {"error": f"Path is not a file: {workflow_file_path} (resolved to: {workflow_path})"}
|
|
279
|
+
|
|
280
|
+
try:
|
|
281
|
+
# Load and start workflow
|
|
282
|
+
workflow = self.workflow_executor.load_workflow(workflow_path)
|
|
283
|
+
self.current_workflow = workflow
|
|
284
|
+
state = self.workflow_executor.start()
|
|
285
|
+
|
|
286
|
+
return {
|
|
287
|
+
"success": True,
|
|
288
|
+
"workflow_id": workflow.id,
|
|
289
|
+
"workflow_name": workflow.name,
|
|
290
|
+
"workflow_file": str(workflow_path),
|
|
291
|
+
"status": state.status,
|
|
292
|
+
"current_step": state.current_step,
|
|
293
|
+
"message": f"Workflow '{workflow.name}' started from {workflow_file_path}",
|
|
294
|
+
}
|
|
295
|
+
except Exception as e:
|
|
296
|
+
return {"error": f"Failed to execute workflow from file: {str(e)}"}
|
|
297
|
+
|
|
298
|
+
async def _start_workflow(self, workflow_id: str) -> dict[str, Any]:
|
|
299
|
+
"""Start a workflow."""
|
|
300
|
+
if not self.workflow_executor:
|
|
301
|
+
return {"error": "Workflow executor not initialized"}
|
|
302
|
+
|
|
303
|
+
# Find workflow file recursively
|
|
304
|
+
workflows_dir = Path("workflows")
|
|
305
|
+
workflow_file = self._find_workflow_by_id(workflows_dir, workflow_id)
|
|
306
|
+
|
|
307
|
+
if not workflow_file:
|
|
308
|
+
return {"error": f"Workflow '{workflow_id}' not found"}
|
|
309
|
+
|
|
310
|
+
try:
|
|
311
|
+
# Load and start workflow
|
|
312
|
+
workflow = self.workflow_executor.load_workflow(workflow_file)
|
|
313
|
+
self.current_workflow = workflow
|
|
314
|
+
state = self.workflow_executor.start()
|
|
315
|
+
|
|
316
|
+
return {
|
|
317
|
+
"success": True,
|
|
318
|
+
"workflow_id": workflow.id,
|
|
319
|
+
"workflow_name": workflow.name,
|
|
320
|
+
"status": state.status,
|
|
321
|
+
"current_step": state.current_step,
|
|
322
|
+
"message": f"Workflow '{workflow.name}' started",
|
|
323
|
+
}
|
|
324
|
+
except Exception as e:
|
|
325
|
+
return {"error": f"Failed to start workflow: {str(e)}"}
|
|
326
|
+
|
|
327
|
+
async def _get_workflow_status(self) -> dict[str, Any]:
|
|
328
|
+
"""Get current workflow status."""
|
|
329
|
+
if not self.workflow_executor:
|
|
330
|
+
return {"error": "No workflow active"}
|
|
331
|
+
|
|
332
|
+
status = self.workflow_executor.get_status()
|
|
333
|
+
return status
|
|
334
|
+
|
|
335
|
+
async def _get_next_step(self) -> dict[str, Any]:
|
|
336
|
+
"""Get next workflow step."""
|
|
337
|
+
if not self.workflow_executor:
|
|
338
|
+
return {"error": "No workflow active"}
|
|
339
|
+
|
|
340
|
+
next_step = self.workflow_executor.get_next_step()
|
|
341
|
+
if not next_step:
|
|
342
|
+
return {"message": "No next step (workflow may be complete)"}
|
|
343
|
+
|
|
344
|
+
return {
|
|
345
|
+
"next_step": {
|
|
346
|
+
"id": next_step.id,
|
|
347
|
+
"agent": next_step.agent,
|
|
348
|
+
"action": next_step.action,
|
|
349
|
+
"context_tier": next_step.context_tier,
|
|
350
|
+
"requires": next_step.requires,
|
|
351
|
+
"creates": next_step.creates,
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
async def _skip_step(self, step_id: str) -> dict[str, Any]:
|
|
356
|
+
"""Skip an optional step."""
|
|
357
|
+
if not self.workflow_executor:
|
|
358
|
+
return {"error": "No workflow active"}
|
|
359
|
+
|
|
360
|
+
try:
|
|
361
|
+
self.workflow_executor.skip_step(step_id)
|
|
362
|
+
return {
|
|
363
|
+
"success": True,
|
|
364
|
+
"message": f"Step '{step_id}' skipped",
|
|
365
|
+
"current_step": (
|
|
366
|
+
self.workflow_executor.state.current_step
|
|
367
|
+
if self.workflow_executor.state
|
|
368
|
+
else None
|
|
369
|
+
),
|
|
370
|
+
}
|
|
371
|
+
except Exception as e:
|
|
372
|
+
return {"error": f"Failed to skip step: {str(e)}"}
|
|
373
|
+
|
|
374
|
+
async def _resume_workflow(self) -> dict[str, Any]:
|
|
375
|
+
"""Resume an interrupted workflow."""
|
|
376
|
+
if not self.workflow_executor:
|
|
377
|
+
return {"error": "Workflow executor not initialized"}
|
|
378
|
+
|
|
379
|
+
try:
|
|
380
|
+
state = self.workflow_executor.load_last_state()
|
|
381
|
+
self.current_workflow = self.workflow_executor.workflow
|
|
382
|
+
|
|
383
|
+
return {
|
|
384
|
+
"success": True,
|
|
385
|
+
"workflow_id": state.workflow_id,
|
|
386
|
+
"status": state.status,
|
|
387
|
+
"current_step": state.current_step,
|
|
388
|
+
"completed_steps": state.completed_steps,
|
|
389
|
+
"skipped_steps": state.skipped_steps,
|
|
390
|
+
"artifacts": {
|
|
391
|
+
k: {"path": v.path, "status": v.status}
|
|
392
|
+
for k, v in (state.artifacts or {}).items()
|
|
393
|
+
},
|
|
394
|
+
"message": "Workflow resumed from persisted state",
|
|
395
|
+
}
|
|
396
|
+
except FileNotFoundError as e:
|
|
397
|
+
return {"error": str(e)}
|
|
398
|
+
except Exception as e:
|
|
399
|
+
return {"error": f"Failed to resume workflow: {str(e)}"}
|
|
400
|
+
|
|
401
|
+
async def _make_gate_decision(
|
|
402
|
+
self, condition: str | None, scoring_data: dict[str, Any]
|
|
403
|
+
) -> dict[str, Any]:
|
|
404
|
+
"""
|
|
405
|
+
Make a gate decision based on condition and scoring data.
|
|
406
|
+
|
|
407
|
+
Args:
|
|
408
|
+
condition: Gate condition string (e.g., "scoring.passed == true")
|
|
409
|
+
scoring_data: Scoring results from reviewer agent
|
|
410
|
+
|
|
411
|
+
Returns:
|
|
412
|
+
Gate decision with pass/fail status
|
|
413
|
+
"""
|
|
414
|
+
if not condition:
|
|
415
|
+
# Default gate: check if scoring passed
|
|
416
|
+
passed = scoring_data.get("passed", False)
|
|
417
|
+
overall_score = scoring_data.get("overall_score", 0)
|
|
418
|
+
|
|
419
|
+
return {
|
|
420
|
+
"passed": passed,
|
|
421
|
+
"overall_score": overall_score,
|
|
422
|
+
"message": "Gate passed" if passed else "Gate failed",
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
# Evaluate condition (simplified - in production, use a proper expression evaluator)
|
|
426
|
+
try:
|
|
427
|
+
# Simple condition evaluation
|
|
428
|
+
if "scoring.passed" in condition:
|
|
429
|
+
passed = scoring_data.get("passed", False)
|
|
430
|
+
if "==" in condition and "true" in condition:
|
|
431
|
+
gate_passed = passed
|
|
432
|
+
elif "==" in condition and "false" in condition:
|
|
433
|
+
gate_passed = not passed
|
|
434
|
+
else:
|
|
435
|
+
gate_passed = passed
|
|
436
|
+
|
|
437
|
+
return {
|
|
438
|
+
"passed": gate_passed,
|
|
439
|
+
"condition": condition,
|
|
440
|
+
"scoring": scoring_data,
|
|
441
|
+
"message": "Gate passed" if gate_passed else "Gate failed",
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
# Check score thresholds
|
|
445
|
+
if "overall_score" in condition or "overall_min" in condition:
|
|
446
|
+
overall_score = scoring_data.get("overall_score", 0)
|
|
447
|
+
# Extract threshold from condition (simplified)
|
|
448
|
+
threshold = 70 # Default
|
|
449
|
+
if ">=" in condition:
|
|
450
|
+
try:
|
|
451
|
+
threshold = int(condition.split(">=")[1].strip().split()[0])
|
|
452
|
+
except (ValueError, IndexError):
|
|
453
|
+
pass
|
|
454
|
+
|
|
455
|
+
gate_passed = overall_score >= threshold
|
|
456
|
+
return {
|
|
457
|
+
"passed": gate_passed,
|
|
458
|
+
"overall_score": overall_score,
|
|
459
|
+
"threshold": threshold,
|
|
460
|
+
"message": f"Gate {'passed' if gate_passed else 'failed'}: {overall_score} >= {threshold}",
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
return {
|
|
464
|
+
"passed": False,
|
|
465
|
+
"error": f"Unsupported condition: {condition}",
|
|
466
|
+
"message": "Gate evaluation failed",
|
|
467
|
+
}
|
|
468
|
+
except Exception as e:
|
|
469
|
+
return {
|
|
470
|
+
"passed": False,
|
|
471
|
+
"error": str(e),
|
|
472
|
+
"message": "Gate evaluation error",
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
def _help(self) -> dict[str, Any]:
|
|
476
|
+
"""
|
|
477
|
+
Return help information for Orchestrator Agent.
|
|
478
|
+
|
|
479
|
+
Returns standardized help format with commands and description.
|
|
480
|
+
|
|
481
|
+
Returns:
|
|
482
|
+
dict: Help information with standardized format:
|
|
483
|
+
- type (str): Always "help"
|
|
484
|
+
- content (str): Formatted help text containing:
|
|
485
|
+
- Available commands with descriptions
|
|
486
|
+
- Agent description
|
|
487
|
+
|
|
488
|
+
Note:
|
|
489
|
+
This method is synchronous as it performs no I/O operations.
|
|
490
|
+
Called via agent.run("help") which handles async context.
|
|
491
|
+
Standardized to match format used by other agents.
|
|
492
|
+
"""
|
|
493
|
+
commands_dict = {
|
|
494
|
+
"*workflow-list": "List available workflows",
|
|
495
|
+
"*workflow-start {workflow_id}": "Start a workflow by ID",
|
|
496
|
+
"*workflow {workflow_file}": "Execute a workflow from a YAML file path",
|
|
497
|
+
"*workflow-status": "Show current workflow status",
|
|
498
|
+
"*workflow-next": "Show next step in workflow",
|
|
499
|
+
"*workflow-skip {step_id}": "Skip an optional step",
|
|
500
|
+
"*workflow-resume": "Resume interrupted workflow",
|
|
501
|
+
"*gate {condition}": "Make a gate decision based on condition and scoring",
|
|
502
|
+
"*help": "Show this help message",
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
# Format as markdown for consistency with other agents
|
|
506
|
+
command_lines = [
|
|
507
|
+
f"- **{cmd}**: {desc}"
|
|
508
|
+
for cmd, desc in commands_dict.items()
|
|
509
|
+
]
|
|
510
|
+
|
|
511
|
+
content = f"""# {self.agent_name} - Help
|
|
512
|
+
|
|
513
|
+
## Available Commands
|
|
514
|
+
|
|
515
|
+
{chr(10).join(command_lines)}
|
|
516
|
+
|
|
517
|
+
## Description
|
|
518
|
+
|
|
519
|
+
Orchestrator Agent coordinates workflows and makes gate decisions.
|
|
520
|
+
"""
|
|
521
|
+
|
|
522
|
+
return {"type": "help", "content": content}
|