attune-ai 2.0.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.
- attune/__init__.py +358 -0
- attune/adaptive/__init__.py +13 -0
- attune/adaptive/task_complexity.py +127 -0
- attune/agent_monitoring.py +414 -0
- attune/cache/__init__.py +117 -0
- attune/cache/base.py +166 -0
- attune/cache/dependency_manager.py +256 -0
- attune/cache/hash_only.py +251 -0
- attune/cache/hybrid.py +457 -0
- attune/cache/storage.py +285 -0
- attune/cache_monitor.py +356 -0
- attune/cache_stats.py +298 -0
- attune/cli/__init__.py +152 -0
- attune/cli/__main__.py +12 -0
- attune/cli/commands/__init__.py +1 -0
- attune/cli/commands/batch.py +264 -0
- attune/cli/commands/cache.py +248 -0
- attune/cli/commands/help.py +331 -0
- attune/cli/commands/info.py +140 -0
- attune/cli/commands/inspect.py +436 -0
- attune/cli/commands/inspection.py +57 -0
- attune/cli/commands/memory.py +48 -0
- attune/cli/commands/metrics.py +92 -0
- attune/cli/commands/orchestrate.py +184 -0
- attune/cli/commands/patterns.py +207 -0
- attune/cli/commands/profiling.py +202 -0
- attune/cli/commands/provider.py +98 -0
- attune/cli/commands/routing.py +285 -0
- attune/cli/commands/setup.py +96 -0
- attune/cli/commands/status.py +235 -0
- attune/cli/commands/sync.py +166 -0
- attune/cli/commands/tier.py +121 -0
- attune/cli/commands/utilities.py +114 -0
- attune/cli/commands/workflow.py +579 -0
- attune/cli/core.py +32 -0
- attune/cli/parsers/__init__.py +68 -0
- attune/cli/parsers/batch.py +118 -0
- attune/cli/parsers/cache.py +65 -0
- attune/cli/parsers/help.py +41 -0
- attune/cli/parsers/info.py +26 -0
- attune/cli/parsers/inspect.py +66 -0
- attune/cli/parsers/metrics.py +42 -0
- attune/cli/parsers/orchestrate.py +61 -0
- attune/cli/parsers/patterns.py +54 -0
- attune/cli/parsers/provider.py +40 -0
- attune/cli/parsers/routing.py +110 -0
- attune/cli/parsers/setup.py +42 -0
- attune/cli/parsers/status.py +47 -0
- attune/cli/parsers/sync.py +31 -0
- attune/cli/parsers/tier.py +33 -0
- attune/cli/parsers/workflow.py +77 -0
- attune/cli/utils/__init__.py +1 -0
- attune/cli/utils/data.py +242 -0
- attune/cli/utils/helpers.py +68 -0
- attune/cli_legacy.py +3957 -0
- attune/cli_minimal.py +1159 -0
- attune/cli_router.py +437 -0
- attune/cli_unified.py +814 -0
- attune/config/__init__.py +66 -0
- attune/config/xml_config.py +286 -0
- attune/config.py +545 -0
- attune/coordination.py +870 -0
- attune/core.py +1511 -0
- attune/core_modules/__init__.py +15 -0
- attune/cost_tracker.py +626 -0
- attune/dashboard/__init__.py +41 -0
- attune/dashboard/app.py +512 -0
- attune/dashboard/simple_server.py +435 -0
- attune/dashboard/standalone_server.py +547 -0
- attune/discovery.py +306 -0
- attune/emergence.py +306 -0
- attune/exceptions.py +123 -0
- attune/feedback_loops.py +373 -0
- attune/hot_reload/README.md +473 -0
- attune/hot_reload/__init__.py +62 -0
- attune/hot_reload/config.py +83 -0
- attune/hot_reload/integration.py +229 -0
- attune/hot_reload/reloader.py +298 -0
- attune/hot_reload/watcher.py +183 -0
- attune/hot_reload/websocket.py +177 -0
- attune/levels.py +577 -0
- attune/leverage_points.py +441 -0
- attune/logging_config.py +261 -0
- attune/mcp/__init__.py +10 -0
- attune/mcp/server.py +506 -0
- attune/memory/__init__.py +237 -0
- attune/memory/claude_memory.py +469 -0
- attune/memory/config.py +224 -0
- attune/memory/control_panel.py +1290 -0
- attune/memory/control_panel_support.py +145 -0
- attune/memory/cross_session.py +845 -0
- attune/memory/edges.py +179 -0
- attune/memory/encryption.py +159 -0
- attune/memory/file_session.py +770 -0
- attune/memory/graph.py +570 -0
- attune/memory/long_term.py +913 -0
- attune/memory/long_term_types.py +99 -0
- attune/memory/mixins/__init__.py +25 -0
- attune/memory/mixins/backend_init_mixin.py +249 -0
- attune/memory/mixins/capabilities_mixin.py +208 -0
- attune/memory/mixins/handoff_mixin.py +208 -0
- attune/memory/mixins/lifecycle_mixin.py +49 -0
- attune/memory/mixins/long_term_mixin.py +352 -0
- attune/memory/mixins/promotion_mixin.py +109 -0
- attune/memory/mixins/short_term_mixin.py +182 -0
- attune/memory/nodes.py +179 -0
- attune/memory/redis_bootstrap.py +540 -0
- attune/memory/security/__init__.py +31 -0
- attune/memory/security/audit_logger.py +932 -0
- attune/memory/security/pii_scrubber.py +640 -0
- attune/memory/security/secrets_detector.py +678 -0
- attune/memory/short_term.py +2192 -0
- attune/memory/simple_storage.py +302 -0
- attune/memory/storage/__init__.py +15 -0
- attune/memory/storage_backend.py +167 -0
- attune/memory/summary_index.py +583 -0
- attune/memory/types.py +446 -0
- attune/memory/unified.py +182 -0
- attune/meta_workflows/__init__.py +74 -0
- attune/meta_workflows/agent_creator.py +248 -0
- attune/meta_workflows/builtin_templates.py +567 -0
- attune/meta_workflows/cli_commands/__init__.py +56 -0
- attune/meta_workflows/cli_commands/agent_commands.py +321 -0
- attune/meta_workflows/cli_commands/analytics_commands.py +442 -0
- attune/meta_workflows/cli_commands/config_commands.py +232 -0
- attune/meta_workflows/cli_commands/memory_commands.py +182 -0
- attune/meta_workflows/cli_commands/template_commands.py +354 -0
- attune/meta_workflows/cli_commands/workflow_commands.py +382 -0
- attune/meta_workflows/cli_meta_workflows.py +59 -0
- attune/meta_workflows/form_engine.py +292 -0
- attune/meta_workflows/intent_detector.py +409 -0
- attune/meta_workflows/models.py +569 -0
- attune/meta_workflows/pattern_learner.py +738 -0
- attune/meta_workflows/plan_generator.py +384 -0
- attune/meta_workflows/session_context.py +397 -0
- attune/meta_workflows/template_registry.py +229 -0
- attune/meta_workflows/workflow.py +984 -0
- attune/metrics/__init__.py +12 -0
- attune/metrics/collector.py +31 -0
- attune/metrics/prompt_metrics.py +194 -0
- attune/models/__init__.py +172 -0
- attune/models/__main__.py +13 -0
- attune/models/adaptive_routing.py +437 -0
- attune/models/auth_cli.py +444 -0
- attune/models/auth_strategy.py +450 -0
- attune/models/cli.py +655 -0
- attune/models/empathy_executor.py +354 -0
- attune/models/executor.py +257 -0
- attune/models/fallback.py +762 -0
- attune/models/provider_config.py +282 -0
- attune/models/registry.py +472 -0
- attune/models/tasks.py +359 -0
- attune/models/telemetry/__init__.py +71 -0
- attune/models/telemetry/analytics.py +594 -0
- attune/models/telemetry/backend.py +196 -0
- attune/models/telemetry/data_models.py +431 -0
- attune/models/telemetry/storage.py +489 -0
- attune/models/token_estimator.py +420 -0
- attune/models/validation.py +280 -0
- attune/monitoring/__init__.py +52 -0
- attune/monitoring/alerts.py +946 -0
- attune/monitoring/alerts_cli.py +448 -0
- attune/monitoring/multi_backend.py +271 -0
- attune/monitoring/otel_backend.py +362 -0
- attune/optimization/__init__.py +19 -0
- attune/optimization/context_optimizer.py +272 -0
- attune/orchestration/__init__.py +67 -0
- attune/orchestration/agent_templates.py +707 -0
- attune/orchestration/config_store.py +499 -0
- attune/orchestration/execution_strategies.py +2111 -0
- attune/orchestration/meta_orchestrator.py +1168 -0
- attune/orchestration/pattern_learner.py +696 -0
- attune/orchestration/real_tools.py +931 -0
- attune/pattern_cache.py +187 -0
- attune/pattern_library.py +542 -0
- attune/patterns/debugging/all_patterns.json +81 -0
- attune/patterns/debugging/workflow_20260107_1770825e.json +77 -0
- attune/patterns/refactoring_memory.json +89 -0
- attune/persistence.py +564 -0
- attune/platform_utils.py +265 -0
- attune/plugins/__init__.py +28 -0
- attune/plugins/base.py +361 -0
- attune/plugins/registry.py +268 -0
- attune/project_index/__init__.py +32 -0
- attune/project_index/cli.py +335 -0
- attune/project_index/index.py +667 -0
- attune/project_index/models.py +504 -0
- attune/project_index/reports.py +474 -0
- attune/project_index/scanner.py +777 -0
- attune/project_index/scanner_parallel.py +291 -0
- attune/prompts/__init__.py +61 -0
- attune/prompts/config.py +77 -0
- attune/prompts/context.py +177 -0
- attune/prompts/parser.py +285 -0
- attune/prompts/registry.py +313 -0
- attune/prompts/templates.py +208 -0
- attune/redis_config.py +302 -0
- attune/redis_memory.py +799 -0
- attune/resilience/__init__.py +56 -0
- attune/resilience/circuit_breaker.py +256 -0
- attune/resilience/fallback.py +179 -0
- attune/resilience/health.py +300 -0
- attune/resilience/retry.py +209 -0
- attune/resilience/timeout.py +135 -0
- attune/routing/__init__.py +43 -0
- attune/routing/chain_executor.py +433 -0
- attune/routing/classifier.py +217 -0
- attune/routing/smart_router.py +234 -0
- attune/routing/workflow_registry.py +343 -0
- attune/scaffolding/README.md +589 -0
- attune/scaffolding/__init__.py +35 -0
- attune/scaffolding/__main__.py +14 -0
- attune/scaffolding/cli.py +240 -0
- attune/scaffolding/templates/base_wizard.py.jinja2 +121 -0
- attune/scaffolding/templates/coach_wizard.py.jinja2 +321 -0
- attune/scaffolding/templates/domain_wizard.py.jinja2 +408 -0
- attune/scaffolding/templates/linear_flow_wizard.py.jinja2 +203 -0
- attune/socratic/__init__.py +256 -0
- attune/socratic/ab_testing.py +958 -0
- attune/socratic/blueprint.py +533 -0
- attune/socratic/cli.py +703 -0
- attune/socratic/collaboration.py +1114 -0
- attune/socratic/domain_templates.py +924 -0
- attune/socratic/embeddings.py +738 -0
- attune/socratic/engine.py +794 -0
- attune/socratic/explainer.py +682 -0
- attune/socratic/feedback.py +772 -0
- attune/socratic/forms.py +629 -0
- attune/socratic/generator.py +732 -0
- attune/socratic/llm_analyzer.py +637 -0
- attune/socratic/mcp_server.py +702 -0
- attune/socratic/session.py +312 -0
- attune/socratic/storage.py +667 -0
- attune/socratic/success.py +730 -0
- attune/socratic/visual_editor.py +860 -0
- attune/socratic/web_ui.py +958 -0
- attune/telemetry/__init__.py +39 -0
- attune/telemetry/agent_coordination.py +475 -0
- attune/telemetry/agent_tracking.py +367 -0
- attune/telemetry/approval_gates.py +545 -0
- attune/telemetry/cli.py +1231 -0
- attune/telemetry/commands/__init__.py +14 -0
- attune/telemetry/commands/dashboard_commands.py +696 -0
- attune/telemetry/event_streaming.py +409 -0
- attune/telemetry/feedback_loop.py +567 -0
- attune/telemetry/usage_tracker.py +591 -0
- attune/templates.py +754 -0
- attune/test_generator/__init__.py +38 -0
- attune/test_generator/__main__.py +14 -0
- attune/test_generator/cli.py +234 -0
- attune/test_generator/generator.py +355 -0
- attune/test_generator/risk_analyzer.py +216 -0
- attune/test_generator/templates/unit_test.py.jinja2 +272 -0
- attune/tier_recommender.py +384 -0
- attune/tools.py +183 -0
- attune/trust/__init__.py +28 -0
- attune/trust/circuit_breaker.py +579 -0
- attune/trust_building.py +527 -0
- attune/validation/__init__.py +19 -0
- attune/validation/xml_validator.py +281 -0
- attune/vscode_bridge.py +173 -0
- attune/workflow_commands.py +780 -0
- attune/workflow_patterns/__init__.py +33 -0
- attune/workflow_patterns/behavior.py +249 -0
- attune/workflow_patterns/core.py +76 -0
- attune/workflow_patterns/output.py +99 -0
- attune/workflow_patterns/registry.py +255 -0
- attune/workflow_patterns/structural.py +288 -0
- attune/workflows/__init__.py +539 -0
- attune/workflows/autonomous_test_gen.py +1268 -0
- attune/workflows/base.py +2667 -0
- attune/workflows/batch_processing.py +342 -0
- attune/workflows/bug_predict.py +1084 -0
- attune/workflows/builder.py +273 -0
- attune/workflows/caching.py +253 -0
- attune/workflows/code_review.py +1048 -0
- attune/workflows/code_review_adapters.py +312 -0
- attune/workflows/code_review_pipeline.py +722 -0
- attune/workflows/config.py +645 -0
- attune/workflows/dependency_check.py +644 -0
- attune/workflows/document_gen/__init__.py +25 -0
- attune/workflows/document_gen/config.py +30 -0
- attune/workflows/document_gen/report_formatter.py +162 -0
- attune/workflows/document_gen/workflow.py +1426 -0
- attune/workflows/document_manager.py +216 -0
- attune/workflows/document_manager_README.md +134 -0
- attune/workflows/documentation_orchestrator.py +1205 -0
- attune/workflows/history.py +510 -0
- attune/workflows/keyboard_shortcuts/__init__.py +39 -0
- attune/workflows/keyboard_shortcuts/generators.py +391 -0
- attune/workflows/keyboard_shortcuts/parsers.py +416 -0
- attune/workflows/keyboard_shortcuts/prompts.py +295 -0
- attune/workflows/keyboard_shortcuts/schema.py +193 -0
- attune/workflows/keyboard_shortcuts/workflow.py +509 -0
- attune/workflows/llm_base.py +363 -0
- attune/workflows/manage_docs.py +87 -0
- attune/workflows/manage_docs_README.md +134 -0
- attune/workflows/manage_documentation.py +821 -0
- attune/workflows/new_sample_workflow1.py +149 -0
- attune/workflows/new_sample_workflow1_README.md +150 -0
- attune/workflows/orchestrated_health_check.py +849 -0
- attune/workflows/orchestrated_release_prep.py +600 -0
- attune/workflows/output.py +413 -0
- attune/workflows/perf_audit.py +863 -0
- attune/workflows/pr_review.py +762 -0
- attune/workflows/progress.py +785 -0
- attune/workflows/progress_server.py +322 -0
- attune/workflows/progressive/README 2.md +454 -0
- attune/workflows/progressive/README.md +454 -0
- attune/workflows/progressive/__init__.py +82 -0
- attune/workflows/progressive/cli.py +219 -0
- attune/workflows/progressive/core.py +488 -0
- attune/workflows/progressive/orchestrator.py +723 -0
- attune/workflows/progressive/reports.py +520 -0
- attune/workflows/progressive/telemetry.py +274 -0
- attune/workflows/progressive/test_gen.py +495 -0
- attune/workflows/progressive/workflow.py +589 -0
- attune/workflows/refactor_plan.py +694 -0
- attune/workflows/release_prep.py +895 -0
- attune/workflows/release_prep_crew.py +969 -0
- attune/workflows/research_synthesis.py +404 -0
- attune/workflows/routing.py +168 -0
- attune/workflows/secure_release.py +593 -0
- attune/workflows/security_adapters.py +297 -0
- attune/workflows/security_audit.py +1329 -0
- attune/workflows/security_audit_phase3.py +355 -0
- attune/workflows/seo_optimization.py +633 -0
- attune/workflows/step_config.py +234 -0
- attune/workflows/telemetry_mixin.py +269 -0
- attune/workflows/test5.py +125 -0
- attune/workflows/test5_README.md +158 -0
- attune/workflows/test_coverage_boost_crew.py +849 -0
- attune/workflows/test_gen/__init__.py +52 -0
- attune/workflows/test_gen/ast_analyzer.py +249 -0
- attune/workflows/test_gen/config.py +88 -0
- attune/workflows/test_gen/data_models.py +38 -0
- attune/workflows/test_gen/report_formatter.py +289 -0
- attune/workflows/test_gen/test_templates.py +381 -0
- attune/workflows/test_gen/workflow.py +655 -0
- attune/workflows/test_gen.py +54 -0
- attune/workflows/test_gen_behavioral.py +477 -0
- attune/workflows/test_gen_parallel.py +341 -0
- attune/workflows/test_lifecycle.py +526 -0
- attune/workflows/test_maintenance.py +627 -0
- attune/workflows/test_maintenance_cli.py +590 -0
- attune/workflows/test_maintenance_crew.py +840 -0
- attune/workflows/test_runner.py +622 -0
- attune/workflows/tier_tracking.py +531 -0
- attune/workflows/xml_enhanced_crew.py +285 -0
- attune_ai-2.0.0.dist-info/METADATA +1026 -0
- attune_ai-2.0.0.dist-info/RECORD +457 -0
- attune_ai-2.0.0.dist-info/WHEEL +5 -0
- attune_ai-2.0.0.dist-info/entry_points.txt +26 -0
- attune_ai-2.0.0.dist-info/licenses/LICENSE +201 -0
- attune_ai-2.0.0.dist-info/licenses/LICENSE_CHANGE_ANNOUNCEMENT.md +101 -0
- attune_ai-2.0.0.dist-info/top_level.txt +5 -0
- attune_healthcare/__init__.py +13 -0
- attune_healthcare/monitors/__init__.py +9 -0
- attune_healthcare/monitors/clinical_protocol_monitor.py +315 -0
- attune_healthcare/monitors/monitoring/__init__.py +44 -0
- attune_healthcare/monitors/monitoring/protocol_checker.py +300 -0
- attune_healthcare/monitors/monitoring/protocol_loader.py +214 -0
- attune_healthcare/monitors/monitoring/sensor_parsers.py +306 -0
- attune_healthcare/monitors/monitoring/trajectory_analyzer.py +389 -0
- attune_llm/README.md +553 -0
- attune_llm/__init__.py +28 -0
- attune_llm/agent_factory/__init__.py +53 -0
- attune_llm/agent_factory/adapters/__init__.py +85 -0
- attune_llm/agent_factory/adapters/autogen_adapter.py +312 -0
- attune_llm/agent_factory/adapters/crewai_adapter.py +483 -0
- attune_llm/agent_factory/adapters/haystack_adapter.py +298 -0
- attune_llm/agent_factory/adapters/langchain_adapter.py +362 -0
- attune_llm/agent_factory/adapters/langgraph_adapter.py +333 -0
- attune_llm/agent_factory/adapters/native.py +228 -0
- attune_llm/agent_factory/adapters/wizard_adapter.py +423 -0
- attune_llm/agent_factory/base.py +305 -0
- attune_llm/agent_factory/crews/__init__.py +67 -0
- attune_llm/agent_factory/crews/code_review.py +1113 -0
- attune_llm/agent_factory/crews/health_check.py +1262 -0
- attune_llm/agent_factory/crews/refactoring.py +1128 -0
- attune_llm/agent_factory/crews/security_audit.py +1018 -0
- attune_llm/agent_factory/decorators.py +287 -0
- attune_llm/agent_factory/factory.py +558 -0
- attune_llm/agent_factory/framework.py +193 -0
- attune_llm/agent_factory/memory_integration.py +328 -0
- attune_llm/agent_factory/resilient.py +320 -0
- attune_llm/agents_md/__init__.py +22 -0
- attune_llm/agents_md/loader.py +218 -0
- attune_llm/agents_md/parser.py +271 -0
- attune_llm/agents_md/registry.py +307 -0
- attune_llm/claude_memory.py +466 -0
- attune_llm/cli/__init__.py +8 -0
- attune_llm/cli/sync_claude.py +487 -0
- attune_llm/code_health.py +1313 -0
- attune_llm/commands/__init__.py +51 -0
- attune_llm/commands/context.py +375 -0
- attune_llm/commands/loader.py +301 -0
- attune_llm/commands/models.py +231 -0
- attune_llm/commands/parser.py +371 -0
- attune_llm/commands/registry.py +429 -0
- attune_llm/config/__init__.py +29 -0
- attune_llm/config/unified.py +291 -0
- attune_llm/context/__init__.py +22 -0
- attune_llm/context/compaction.py +455 -0
- attune_llm/context/manager.py +434 -0
- attune_llm/contextual_patterns.py +361 -0
- attune_llm/core.py +907 -0
- attune_llm/git_pattern_extractor.py +435 -0
- attune_llm/hooks/__init__.py +24 -0
- attune_llm/hooks/config.py +306 -0
- attune_llm/hooks/executor.py +289 -0
- attune_llm/hooks/registry.py +302 -0
- attune_llm/hooks/scripts/__init__.py +39 -0
- attune_llm/hooks/scripts/evaluate_session.py +201 -0
- attune_llm/hooks/scripts/first_time_init.py +285 -0
- attune_llm/hooks/scripts/pre_compact.py +207 -0
- attune_llm/hooks/scripts/session_end.py +183 -0
- attune_llm/hooks/scripts/session_start.py +163 -0
- attune_llm/hooks/scripts/suggest_compact.py +225 -0
- attune_llm/learning/__init__.py +30 -0
- attune_llm/learning/evaluator.py +438 -0
- attune_llm/learning/extractor.py +514 -0
- attune_llm/learning/storage.py +560 -0
- attune_llm/levels.py +227 -0
- attune_llm/pattern_confidence.py +414 -0
- attune_llm/pattern_resolver.py +272 -0
- attune_llm/pattern_summary.py +350 -0
- attune_llm/providers.py +967 -0
- attune_llm/routing/__init__.py +32 -0
- attune_llm/routing/model_router.py +362 -0
- attune_llm/security/IMPLEMENTATION_SUMMARY.md +413 -0
- attune_llm/security/PHASE2_COMPLETE.md +384 -0
- attune_llm/security/PHASE2_SECRETS_DETECTOR_COMPLETE.md +271 -0
- attune_llm/security/QUICK_REFERENCE.md +316 -0
- attune_llm/security/README.md +262 -0
- attune_llm/security/__init__.py +62 -0
- attune_llm/security/audit_logger.py +929 -0
- attune_llm/security/audit_logger_example.py +152 -0
- attune_llm/security/pii_scrubber.py +640 -0
- attune_llm/security/secrets_detector.py +678 -0
- attune_llm/security/secrets_detector_example.py +304 -0
- attune_llm/security/secure_memdocs.py +1192 -0
- attune_llm/security/secure_memdocs_example.py +278 -0
- attune_llm/session_status.py +745 -0
- attune_llm/state.py +246 -0
- attune_llm/utils/__init__.py +5 -0
- attune_llm/utils/tokens.py +349 -0
- attune_software/SOFTWARE_PLUGIN_README.md +57 -0
- attune_software/__init__.py +13 -0
- attune_software/cli/__init__.py +120 -0
- attune_software/cli/inspect.py +362 -0
- attune_software/cli.py +574 -0
- attune_software/plugin.py +188 -0
- workflow_scaffolding/__init__.py +11 -0
- workflow_scaffolding/__main__.py +12 -0
- workflow_scaffolding/cli.py +206 -0
- workflow_scaffolding/generator.py +265 -0
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
"""Agent and Workflow Blueprints
|
|
2
|
+
|
|
3
|
+
Intermediate representation for generating agents and workflows.
|
|
4
|
+
|
|
5
|
+
Blueprints capture the design decisions made through Socratic questioning
|
|
6
|
+
before actual agent generation. This allows for:
|
|
7
|
+
- Review before generation
|
|
8
|
+
- Modification of the design
|
|
9
|
+
- Serialization/persistence
|
|
10
|
+
- Template reuse
|
|
11
|
+
|
|
12
|
+
Copyright 2026 Smart-AI-Memory
|
|
13
|
+
Licensed under Fair Source License 0.9
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import uuid
|
|
19
|
+
from dataclasses import dataclass, field
|
|
20
|
+
from enum import Enum
|
|
21
|
+
from typing import Any
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class AgentRole(Enum):
|
|
25
|
+
"""Standard agent roles for team composition."""
|
|
26
|
+
|
|
27
|
+
# Analysis agents
|
|
28
|
+
ANALYZER = "analyzer" # Examines input, identifies patterns
|
|
29
|
+
REVIEWER = "reviewer" # Evaluates quality, finds issues
|
|
30
|
+
AUDITOR = "auditor" # Deep-dive security/compliance checks
|
|
31
|
+
RESEARCHER = "researcher" # Gathers information and context
|
|
32
|
+
|
|
33
|
+
# Action agents
|
|
34
|
+
GENERATOR = "generator" # Creates new content/code
|
|
35
|
+
FIXER = "fixer" # Applies corrections and improvements
|
|
36
|
+
REFACTORER = "refactorer" # Restructures without changing behavior
|
|
37
|
+
|
|
38
|
+
# Coordination agents
|
|
39
|
+
ORCHESTRATOR = "orchestrator" # Coordinates other agents
|
|
40
|
+
VALIDATOR = "validator" # Verifies outputs and quality
|
|
41
|
+
REPORTER = "reporter" # Synthesizes and presents results
|
|
42
|
+
|
|
43
|
+
# Specialized agents
|
|
44
|
+
SPECIALIST = "specialist" # Domain-specific expertise
|
|
45
|
+
ASSISTANT = "assistant" # General-purpose helper
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class ToolCategory(Enum):
|
|
49
|
+
"""Categories of tools agents can use."""
|
|
50
|
+
|
|
51
|
+
# Code intelligence
|
|
52
|
+
CODE_ANALYSIS = "code_analysis" # AST parsing, complexity metrics
|
|
53
|
+
CODE_SEARCH = "code_search" # Grep, file search
|
|
54
|
+
CODE_MODIFICATION = "code_modification" # Edit, write, refactor
|
|
55
|
+
|
|
56
|
+
# Quality tools
|
|
57
|
+
TESTING = "testing" # Run tests, coverage
|
|
58
|
+
LINTING = "linting" # Static analysis
|
|
59
|
+
SECURITY = "security" # Security scanners
|
|
60
|
+
|
|
61
|
+
# Documentation
|
|
62
|
+
DOCUMENTATION = "documentation" # Doc generation, README
|
|
63
|
+
KNOWLEDGE = "knowledge" # Pattern library, memory
|
|
64
|
+
|
|
65
|
+
# External
|
|
66
|
+
API = "api" # External API calls
|
|
67
|
+
DATABASE = "database" # Data storage/retrieval
|
|
68
|
+
FILESYSTEM = "filesystem" # File operations
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@dataclass
|
|
72
|
+
class ToolSpec:
|
|
73
|
+
"""Specification for a tool an agent can use.
|
|
74
|
+
|
|
75
|
+
Example:
|
|
76
|
+
>>> tool = ToolSpec(
|
|
77
|
+
... id="grep_codebase",
|
|
78
|
+
... name="Code Search",
|
|
79
|
+
... category=ToolCategory.CODE_SEARCH,
|
|
80
|
+
... description="Search codebase for patterns",
|
|
81
|
+
... parameters={
|
|
82
|
+
... "pattern": {"type": "string", "required": True},
|
|
83
|
+
... "file_type": {"type": "string", "required": False}
|
|
84
|
+
... }
|
|
85
|
+
... )
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
# Unique tool identifier
|
|
89
|
+
id: str
|
|
90
|
+
|
|
91
|
+
# Display name
|
|
92
|
+
name: str
|
|
93
|
+
|
|
94
|
+
# Tool category
|
|
95
|
+
category: ToolCategory
|
|
96
|
+
|
|
97
|
+
# Description of what the tool does
|
|
98
|
+
description: str
|
|
99
|
+
|
|
100
|
+
# Parameter schema
|
|
101
|
+
parameters: dict[str, dict[str, Any]] = field(default_factory=dict)
|
|
102
|
+
|
|
103
|
+
# Whether tool requires confirmation before use
|
|
104
|
+
requires_confirmation: bool = False
|
|
105
|
+
|
|
106
|
+
# Whether tool can modify state
|
|
107
|
+
is_mutating: bool = False
|
|
108
|
+
|
|
109
|
+
# Cost tier (for expensive operations)
|
|
110
|
+
cost_tier: str = "cheap" # cheap, moderate, expensive
|
|
111
|
+
|
|
112
|
+
def to_dict(self) -> dict[str, Any]:
|
|
113
|
+
"""Serialize to dictionary."""
|
|
114
|
+
return {
|
|
115
|
+
"id": self.id,
|
|
116
|
+
"name": self.name,
|
|
117
|
+
"category": self.category.value,
|
|
118
|
+
"description": self.description,
|
|
119
|
+
"parameters": self.parameters,
|
|
120
|
+
"requires_confirmation": self.requires_confirmation,
|
|
121
|
+
"is_mutating": self.is_mutating,
|
|
122
|
+
"cost_tier": self.cost_tier,
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@dataclass
|
|
127
|
+
class AgentSpec:
|
|
128
|
+
"""Specification for a single agent.
|
|
129
|
+
|
|
130
|
+
Example:
|
|
131
|
+
>>> agent = AgentSpec(
|
|
132
|
+
... id="security_reviewer",
|
|
133
|
+
... name="Security Reviewer",
|
|
134
|
+
... role=AgentRole.REVIEWER,
|
|
135
|
+
... goal="Identify security vulnerabilities in code",
|
|
136
|
+
... backstory="Expert in OWASP Top 10 and secure coding",
|
|
137
|
+
... tools=[security_scan_tool, grep_tool],
|
|
138
|
+
... quality_focus=["security"],
|
|
139
|
+
... model_tier="capable"
|
|
140
|
+
... )
|
|
141
|
+
"""
|
|
142
|
+
|
|
143
|
+
# Unique agent identifier
|
|
144
|
+
id: str
|
|
145
|
+
|
|
146
|
+
# Display name
|
|
147
|
+
name: str
|
|
148
|
+
|
|
149
|
+
# Agent's role in the team
|
|
150
|
+
role: AgentRole
|
|
151
|
+
|
|
152
|
+
# What this agent aims to achieve
|
|
153
|
+
goal: str
|
|
154
|
+
|
|
155
|
+
# Agent's expertise and personality
|
|
156
|
+
backstory: str
|
|
157
|
+
|
|
158
|
+
# Tools this agent can use
|
|
159
|
+
tools: list[ToolSpec] = field(default_factory=list)
|
|
160
|
+
|
|
161
|
+
# Quality attributes this agent focuses on
|
|
162
|
+
quality_focus: list[str] = field(default_factory=list)
|
|
163
|
+
|
|
164
|
+
# Model tier for this agent (cheap, capable, premium)
|
|
165
|
+
model_tier: str = "capable"
|
|
166
|
+
|
|
167
|
+
# Custom instructions for this agent
|
|
168
|
+
custom_instructions: list[str] = field(default_factory=list)
|
|
169
|
+
|
|
170
|
+
# Languages this agent specializes in
|
|
171
|
+
languages: list[str] = field(default_factory=list)
|
|
172
|
+
|
|
173
|
+
# Whether this agent is optional in the workflow
|
|
174
|
+
is_optional: bool = False
|
|
175
|
+
|
|
176
|
+
# Conditions for including this agent
|
|
177
|
+
include_when: dict[str, Any] | None = None
|
|
178
|
+
|
|
179
|
+
# Priority (higher = runs earlier in parallel execution)
|
|
180
|
+
priority: int = 5
|
|
181
|
+
|
|
182
|
+
# Maximum retries on failure
|
|
183
|
+
max_retries: int = 2
|
|
184
|
+
|
|
185
|
+
def to_dict(self) -> dict[str, Any]:
|
|
186
|
+
"""Serialize to dictionary."""
|
|
187
|
+
return {
|
|
188
|
+
"id": self.id,
|
|
189
|
+
"name": self.name,
|
|
190
|
+
"role": self.role.value,
|
|
191
|
+
"goal": self.goal,
|
|
192
|
+
"backstory": self.backstory,
|
|
193
|
+
"tools": [t.to_dict() for t in self.tools],
|
|
194
|
+
"quality_focus": self.quality_focus,
|
|
195
|
+
"model_tier": self.model_tier,
|
|
196
|
+
"custom_instructions": self.custom_instructions,
|
|
197
|
+
"languages": self.languages,
|
|
198
|
+
"is_optional": self.is_optional,
|
|
199
|
+
"include_when": self.include_when,
|
|
200
|
+
"priority": self.priority,
|
|
201
|
+
"max_retries": self.max_retries,
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
@dataclass
|
|
206
|
+
class StageSpec:
|
|
207
|
+
"""Specification for a workflow stage.
|
|
208
|
+
|
|
209
|
+
Stages define when and how agents execute in the workflow.
|
|
210
|
+
"""
|
|
211
|
+
|
|
212
|
+
# Stage identifier
|
|
213
|
+
id: str
|
|
214
|
+
|
|
215
|
+
# Display name
|
|
216
|
+
name: str
|
|
217
|
+
|
|
218
|
+
# Description of what happens in this stage
|
|
219
|
+
description: str
|
|
220
|
+
|
|
221
|
+
# Agents that execute in this stage (can be parallel)
|
|
222
|
+
agent_ids: list[str]
|
|
223
|
+
|
|
224
|
+
# Whether agents in this stage run in parallel
|
|
225
|
+
parallel: bool = False
|
|
226
|
+
|
|
227
|
+
# Conditions for running this stage
|
|
228
|
+
run_when: dict[str, Any] | None = None
|
|
229
|
+
|
|
230
|
+
# Stage this must complete before
|
|
231
|
+
depends_on: list[str] = field(default_factory=list)
|
|
232
|
+
|
|
233
|
+
# Data passed to agents in this stage
|
|
234
|
+
input_mapping: dict[str, str] = field(default_factory=dict)
|
|
235
|
+
|
|
236
|
+
# How to combine outputs from parallel agents
|
|
237
|
+
output_aggregation: str = "merge" # merge, first, vote, custom
|
|
238
|
+
|
|
239
|
+
# Timeout for this stage (seconds)
|
|
240
|
+
timeout: int = 300
|
|
241
|
+
|
|
242
|
+
def to_dict(self) -> dict[str, Any]:
|
|
243
|
+
"""Serialize to dictionary."""
|
|
244
|
+
return {
|
|
245
|
+
"id": self.id,
|
|
246
|
+
"name": self.name,
|
|
247
|
+
"description": self.description,
|
|
248
|
+
"agent_ids": self.agent_ids,
|
|
249
|
+
"parallel": self.parallel,
|
|
250
|
+
"run_when": self.run_when,
|
|
251
|
+
"depends_on": self.depends_on,
|
|
252
|
+
"input_mapping": self.input_mapping,
|
|
253
|
+
"output_aggregation": self.output_aggregation,
|
|
254
|
+
"timeout": self.timeout,
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
@dataclass
|
|
259
|
+
class AgentBlueprint:
|
|
260
|
+
"""Blueprint for generating an agent.
|
|
261
|
+
|
|
262
|
+
Contains all information needed to instantiate an agent.
|
|
263
|
+
"""
|
|
264
|
+
|
|
265
|
+
# The agent specification
|
|
266
|
+
spec: AgentSpec
|
|
267
|
+
|
|
268
|
+
# Generation metadata
|
|
269
|
+
generated_from: str = "socratic" # socratic, template, manual
|
|
270
|
+
|
|
271
|
+
# Template ID if based on a template
|
|
272
|
+
template_id: str | None = None
|
|
273
|
+
|
|
274
|
+
# Customizations applied
|
|
275
|
+
customizations: dict[str, Any] = field(default_factory=dict)
|
|
276
|
+
|
|
277
|
+
# Validation status
|
|
278
|
+
validated: bool = False
|
|
279
|
+
|
|
280
|
+
# Validation errors if any
|
|
281
|
+
validation_errors: list[str] = field(default_factory=list)
|
|
282
|
+
|
|
283
|
+
def validate(self) -> bool:
|
|
284
|
+
"""Validate the blueprint.
|
|
285
|
+
|
|
286
|
+
Returns:
|
|
287
|
+
True if valid, False otherwise
|
|
288
|
+
"""
|
|
289
|
+
self.validation_errors = []
|
|
290
|
+
|
|
291
|
+
if not self.spec.id:
|
|
292
|
+
self.validation_errors.append("Agent must have an ID")
|
|
293
|
+
|
|
294
|
+
if not self.spec.name:
|
|
295
|
+
self.validation_errors.append("Agent must have a name")
|
|
296
|
+
|
|
297
|
+
if not self.spec.goal:
|
|
298
|
+
self.validation_errors.append("Agent must have a goal")
|
|
299
|
+
|
|
300
|
+
if not self.spec.backstory:
|
|
301
|
+
self.validation_errors.append("Agent must have a backstory")
|
|
302
|
+
|
|
303
|
+
self.validated = len(self.validation_errors) == 0
|
|
304
|
+
return self.validated
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
@dataclass
|
|
308
|
+
class WorkflowBlueprint:
|
|
309
|
+
"""Blueprint for a complete workflow with agents.
|
|
310
|
+
|
|
311
|
+
Example:
|
|
312
|
+
>>> blueprint = WorkflowBlueprint(
|
|
313
|
+
... id="code_review_workflow",
|
|
314
|
+
... name="Automated Code Review",
|
|
315
|
+
... description="Multi-agent code review pipeline",
|
|
316
|
+
... agents=[security_agent, style_agent, complexity_agent],
|
|
317
|
+
... stages=[analysis_stage, synthesis_stage],
|
|
318
|
+
... success_criteria=success_spec
|
|
319
|
+
... )
|
|
320
|
+
"""
|
|
321
|
+
|
|
322
|
+
# Unique workflow identifier
|
|
323
|
+
id: str = field(default_factory=lambda: str(uuid.uuid4()))
|
|
324
|
+
|
|
325
|
+
# Workflow name
|
|
326
|
+
name: str = ""
|
|
327
|
+
|
|
328
|
+
# Description of what this workflow does
|
|
329
|
+
description: str = ""
|
|
330
|
+
|
|
331
|
+
# Agent blueprints in this workflow
|
|
332
|
+
agents: list[AgentBlueprint] = field(default_factory=list)
|
|
333
|
+
|
|
334
|
+
# Stage definitions
|
|
335
|
+
stages: list[StageSpec] = field(default_factory=list)
|
|
336
|
+
|
|
337
|
+
# Success criteria specification
|
|
338
|
+
success_criteria: Any = None # SuccessCriteria, imported lazily
|
|
339
|
+
|
|
340
|
+
# Input schema (what the workflow accepts)
|
|
341
|
+
input_schema: dict[str, Any] = field(default_factory=dict)
|
|
342
|
+
|
|
343
|
+
# Output schema (what the workflow produces)
|
|
344
|
+
output_schema: dict[str, Any] = field(default_factory=dict)
|
|
345
|
+
|
|
346
|
+
# Domain this workflow is for
|
|
347
|
+
domain: str = "general"
|
|
348
|
+
|
|
349
|
+
# Languages this workflow supports
|
|
350
|
+
supported_languages: list[str] = field(default_factory=list)
|
|
351
|
+
|
|
352
|
+
# Quality attributes this workflow optimizes for
|
|
353
|
+
quality_focus: list[str] = field(default_factory=list)
|
|
354
|
+
|
|
355
|
+
# Automation level
|
|
356
|
+
automation_level: str = "semi_auto"
|
|
357
|
+
|
|
358
|
+
# Estimated cost tier
|
|
359
|
+
cost_tier: str = "moderate"
|
|
360
|
+
|
|
361
|
+
# Version for tracking changes
|
|
362
|
+
version: str = "1.0.0"
|
|
363
|
+
|
|
364
|
+
# Generation timestamp
|
|
365
|
+
generated_at: str = ""
|
|
366
|
+
|
|
367
|
+
# Source session ID
|
|
368
|
+
source_session_id: str | None = None
|
|
369
|
+
|
|
370
|
+
# Additional metadata
|
|
371
|
+
metadata: dict[str, Any] = field(default_factory=dict)
|
|
372
|
+
|
|
373
|
+
def get_agent_by_id(self, agent_id: str) -> AgentBlueprint | None:
|
|
374
|
+
"""Get an agent blueprint by ID."""
|
|
375
|
+
for agent in self.agents:
|
|
376
|
+
if agent.spec.id == agent_id:
|
|
377
|
+
return agent
|
|
378
|
+
return None
|
|
379
|
+
|
|
380
|
+
def get_stage_by_id(self, stage_id: str) -> StageSpec | None:
|
|
381
|
+
"""Get a stage specification by ID."""
|
|
382
|
+
for stage in self.stages:
|
|
383
|
+
if stage.id == stage_id:
|
|
384
|
+
return stage
|
|
385
|
+
return None
|
|
386
|
+
|
|
387
|
+
def validate(self) -> tuple[bool, list[str]]:
|
|
388
|
+
"""Validate the entire blueprint.
|
|
389
|
+
|
|
390
|
+
Returns:
|
|
391
|
+
Tuple of (is_valid, list of error messages)
|
|
392
|
+
"""
|
|
393
|
+
errors = []
|
|
394
|
+
|
|
395
|
+
if not self.name:
|
|
396
|
+
errors.append("Workflow must have a name")
|
|
397
|
+
|
|
398
|
+
if not self.agents:
|
|
399
|
+
errors.append("Workflow must have at least one agent")
|
|
400
|
+
|
|
401
|
+
if not self.stages:
|
|
402
|
+
errors.append("Workflow must have at least one stage")
|
|
403
|
+
|
|
404
|
+
# Validate all agents
|
|
405
|
+
for agent in self.agents:
|
|
406
|
+
if not agent.validate():
|
|
407
|
+
errors.extend(f"Agent '{agent.spec.id}': {e}" for e in agent.validation_errors)
|
|
408
|
+
|
|
409
|
+
# Validate stages reference valid agents
|
|
410
|
+
agent_ids = {a.spec.id for a in self.agents}
|
|
411
|
+
for stage in self.stages:
|
|
412
|
+
for agent_id in stage.agent_ids:
|
|
413
|
+
if agent_id not in agent_ids:
|
|
414
|
+
errors.append(f"Stage '{stage.id}' references unknown agent '{agent_id}'")
|
|
415
|
+
|
|
416
|
+
# Validate stage dependencies
|
|
417
|
+
stage_ids = {s.id for s in self.stages}
|
|
418
|
+
for stage in self.stages:
|
|
419
|
+
for dep in stage.depends_on:
|
|
420
|
+
if dep not in stage_ids:
|
|
421
|
+
errors.append(f"Stage '{stage.id}' depends on unknown stage '{dep}'")
|
|
422
|
+
|
|
423
|
+
return len(errors) == 0, errors
|
|
424
|
+
|
|
425
|
+
def to_dict(self) -> dict[str, Any]:
|
|
426
|
+
"""Serialize to dictionary."""
|
|
427
|
+
return {
|
|
428
|
+
"id": self.id,
|
|
429
|
+
"name": self.name,
|
|
430
|
+
"description": self.description,
|
|
431
|
+
"agents": [
|
|
432
|
+
{
|
|
433
|
+
"spec": a.spec.to_dict(),
|
|
434
|
+
"generated_from": a.generated_from,
|
|
435
|
+
"template_id": a.template_id,
|
|
436
|
+
"customizations": a.customizations,
|
|
437
|
+
}
|
|
438
|
+
for a in self.agents
|
|
439
|
+
],
|
|
440
|
+
"stages": [s.to_dict() for s in self.stages],
|
|
441
|
+
"input_schema": self.input_schema,
|
|
442
|
+
"output_schema": self.output_schema,
|
|
443
|
+
"domain": self.domain,
|
|
444
|
+
"supported_languages": self.supported_languages,
|
|
445
|
+
"quality_focus": self.quality_focus,
|
|
446
|
+
"automation_level": self.automation_level,
|
|
447
|
+
"cost_tier": self.cost_tier,
|
|
448
|
+
"version": self.version,
|
|
449
|
+
"generated_at": self.generated_at,
|
|
450
|
+
"source_session_id": self.source_session_id,
|
|
451
|
+
"metadata": self.metadata,
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
@classmethod
|
|
455
|
+
def from_dict(cls, data: dict[str, Any]) -> WorkflowBlueprint:
|
|
456
|
+
"""Deserialize from dictionary."""
|
|
457
|
+
blueprint = cls(
|
|
458
|
+
id=data.get("id", str(uuid.uuid4())),
|
|
459
|
+
name=data.get("name", ""),
|
|
460
|
+
description=data.get("description", ""),
|
|
461
|
+
domain=data.get("domain", "general"),
|
|
462
|
+
supported_languages=data.get("supported_languages", []),
|
|
463
|
+
quality_focus=data.get("quality_focus", []),
|
|
464
|
+
automation_level=data.get("automation_level", "semi_auto"),
|
|
465
|
+
cost_tier=data.get("cost_tier", "moderate"),
|
|
466
|
+
version=data.get("version", "1.0.0"),
|
|
467
|
+
generated_at=data.get("generated_at", ""),
|
|
468
|
+
source_session_id=data.get("source_session_id"),
|
|
469
|
+
metadata=data.get("metadata", {}),
|
|
470
|
+
input_schema=data.get("input_schema", {}),
|
|
471
|
+
output_schema=data.get("output_schema", {}),
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
# Parse agents
|
|
475
|
+
for agent_data in data.get("agents", []):
|
|
476
|
+
spec_data = agent_data.get("spec", {})
|
|
477
|
+
spec = AgentSpec(
|
|
478
|
+
id=spec_data.get("id", ""),
|
|
479
|
+
name=spec_data.get("name", ""),
|
|
480
|
+
role=AgentRole(spec_data.get("role", "specialist")),
|
|
481
|
+
goal=spec_data.get("goal", ""),
|
|
482
|
+
backstory=spec_data.get("backstory", ""),
|
|
483
|
+
quality_focus=spec_data.get("quality_focus", []),
|
|
484
|
+
model_tier=spec_data.get("model_tier", "capable"),
|
|
485
|
+
custom_instructions=spec_data.get("custom_instructions", []),
|
|
486
|
+
languages=spec_data.get("languages", []),
|
|
487
|
+
is_optional=spec_data.get("is_optional", False),
|
|
488
|
+
priority=spec_data.get("priority", 5),
|
|
489
|
+
max_retries=spec_data.get("max_retries", 2),
|
|
490
|
+
)
|
|
491
|
+
|
|
492
|
+
# Parse tools
|
|
493
|
+
for tool_data in spec_data.get("tools", []):
|
|
494
|
+
spec.tools.append(
|
|
495
|
+
ToolSpec(
|
|
496
|
+
id=tool_data.get("id", ""),
|
|
497
|
+
name=tool_data.get("name", ""),
|
|
498
|
+
category=ToolCategory(tool_data.get("category", "code_analysis")),
|
|
499
|
+
description=tool_data.get("description", ""),
|
|
500
|
+
parameters=tool_data.get("parameters", {}),
|
|
501
|
+
requires_confirmation=tool_data.get("requires_confirmation", False),
|
|
502
|
+
is_mutating=tool_data.get("is_mutating", False),
|
|
503
|
+
cost_tier=tool_data.get("cost_tier", "cheap"),
|
|
504
|
+
)
|
|
505
|
+
)
|
|
506
|
+
|
|
507
|
+
blueprint.agents.append(
|
|
508
|
+
AgentBlueprint(
|
|
509
|
+
spec=spec,
|
|
510
|
+
generated_from=agent_data.get("generated_from", "socratic"),
|
|
511
|
+
template_id=agent_data.get("template_id"),
|
|
512
|
+
customizations=agent_data.get("customizations", {}),
|
|
513
|
+
)
|
|
514
|
+
)
|
|
515
|
+
|
|
516
|
+
# Parse stages
|
|
517
|
+
for stage_data in data.get("stages", []):
|
|
518
|
+
blueprint.stages.append(
|
|
519
|
+
StageSpec(
|
|
520
|
+
id=stage_data.get("id", ""),
|
|
521
|
+
name=stage_data.get("name", ""),
|
|
522
|
+
description=stage_data.get("description", ""),
|
|
523
|
+
agent_ids=stage_data.get("agent_ids", []),
|
|
524
|
+
parallel=stage_data.get("parallel", False),
|
|
525
|
+
run_when=stage_data.get("run_when"),
|
|
526
|
+
depends_on=stage_data.get("depends_on", []),
|
|
527
|
+
input_mapping=stage_data.get("input_mapping", {}),
|
|
528
|
+
output_aggregation=stage_data.get("output_aggregation", "merge"),
|
|
529
|
+
timeout=stage_data.get("timeout", 300),
|
|
530
|
+
)
|
|
531
|
+
)
|
|
532
|
+
|
|
533
|
+
return blueprint
|