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,240 @@
|
|
|
1
|
+
"""CLI for workflow scaffolding.
|
|
2
|
+
|
|
3
|
+
Usage:
|
|
4
|
+
python -m scaffolding create my_workflow --domain healthcare
|
|
5
|
+
python -m scaffolding create my_workflow --methodology tdd --domain finance
|
|
6
|
+
python -m scaffolding create my_workflow --interactive
|
|
7
|
+
|
|
8
|
+
Copyright 2025 Smart AI Memory, LLC
|
|
9
|
+
Licensed under Fair Source 0.9
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import argparse
|
|
13
|
+
import logging
|
|
14
|
+
import sys
|
|
15
|
+
|
|
16
|
+
from patterns import get_pattern_registry
|
|
17
|
+
|
|
18
|
+
from .methodologies.pattern_compose import PatternCompose
|
|
19
|
+
from .methodologies.tdd_first import TDDFirst
|
|
20
|
+
|
|
21
|
+
logging.basicConfig(
|
|
22
|
+
level=logging.INFO,
|
|
23
|
+
format="%(levelname)s: %(message)s",
|
|
24
|
+
)
|
|
25
|
+
logger = logging.getLogger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def cmd_create(args):
|
|
29
|
+
"""Create a new workflow using specified methodology.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
args: Command line arguments
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
workflow_name = args.name
|
|
36
|
+
domain = args.domain or "general"
|
|
37
|
+
workflow_type = args.type or "domain"
|
|
38
|
+
methodology = args.methodology or "pattern"
|
|
39
|
+
|
|
40
|
+
print(f"\n{'=' * 60}")
|
|
41
|
+
print(f"Creating Workflow: {workflow_name}")
|
|
42
|
+
print(f"{'=' * 60}\n")
|
|
43
|
+
print(f"Domain: {domain}")
|
|
44
|
+
print(f"Type: {workflow_type}")
|
|
45
|
+
print(f"Methodology: {methodology}")
|
|
46
|
+
print()
|
|
47
|
+
|
|
48
|
+
# Get pattern recommendations
|
|
49
|
+
registry = get_pattern_registry()
|
|
50
|
+
recommended = registry.recommend_for_workflow(
|
|
51
|
+
workflow_type=workflow_type,
|
|
52
|
+
domain=domain,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
print(f"Recommended Patterns ({len(recommended)}):")
|
|
56
|
+
for i, pattern in enumerate(recommended, 1):
|
|
57
|
+
print(f" {i}. {pattern.name} - {pattern.description[:60]}...")
|
|
58
|
+
|
|
59
|
+
# Pattern selection
|
|
60
|
+
if args.patterns:
|
|
61
|
+
# User provided patterns
|
|
62
|
+
selected_patterns = args.patterns.split(",")
|
|
63
|
+
elif args.interactive:
|
|
64
|
+
# Interactive selection
|
|
65
|
+
print("\nSelect patterns (comma-separated numbers, or 'all' for all):")
|
|
66
|
+
selection = input("> ").strip()
|
|
67
|
+
|
|
68
|
+
if selection.lower() == "all":
|
|
69
|
+
selected_patterns = [p.id for p in recommended]
|
|
70
|
+
else:
|
|
71
|
+
try:
|
|
72
|
+
indices = [int(i.strip()) - 1 for i in selection.split(",")]
|
|
73
|
+
selected_patterns = [recommended[i].id for i in indices]
|
|
74
|
+
except (ValueError, IndexError):
|
|
75
|
+
print("Invalid selection. Using all patterns.")
|
|
76
|
+
selected_patterns = [p.id for p in recommended]
|
|
77
|
+
else:
|
|
78
|
+
# Use all recommended
|
|
79
|
+
selected_patterns = [p.id for p in recommended]
|
|
80
|
+
|
|
81
|
+
print(f"\nUsing {len(selected_patterns)} patterns:")
|
|
82
|
+
for pid in selected_patterns:
|
|
83
|
+
print(f" - {pid}")
|
|
84
|
+
|
|
85
|
+
# Create workflow using selected methodology
|
|
86
|
+
print(f"\nCreating workflow with {methodology} methodology...")
|
|
87
|
+
|
|
88
|
+
if methodology == "pattern":
|
|
89
|
+
method = PatternCompose()
|
|
90
|
+
result = method.create_workflow(
|
|
91
|
+
name=workflow_name,
|
|
92
|
+
domain=domain,
|
|
93
|
+
workflow_type=workflow_type,
|
|
94
|
+
selected_patterns=selected_patterns,
|
|
95
|
+
)
|
|
96
|
+
elif methodology == "tdd":
|
|
97
|
+
method = TDDFirst()
|
|
98
|
+
result = method.create_workflow(
|
|
99
|
+
name=workflow_name,
|
|
100
|
+
domain=domain,
|
|
101
|
+
workflow_type=workflow_type,
|
|
102
|
+
pattern_ids=selected_patterns,
|
|
103
|
+
)
|
|
104
|
+
else:
|
|
105
|
+
print(f"Unknown methodology: {methodology}")
|
|
106
|
+
sys.exit(1)
|
|
107
|
+
|
|
108
|
+
# Display results
|
|
109
|
+
print(f"\n{'=' * 60}")
|
|
110
|
+
print("✅ Workflow Created Successfully!")
|
|
111
|
+
print(f"{'=' * 60}\n")
|
|
112
|
+
|
|
113
|
+
print("Generated Files:")
|
|
114
|
+
for file_path in result["files"]:
|
|
115
|
+
print(f" - {file_path}")
|
|
116
|
+
|
|
117
|
+
print("\nPatterns Used:")
|
|
118
|
+
for pattern_name in result.get("patterns", selected_patterns):
|
|
119
|
+
print(f" - {pattern_name}")
|
|
120
|
+
|
|
121
|
+
print("\nNext Steps:")
|
|
122
|
+
for step in result["next_steps"]:
|
|
123
|
+
print(f" {step}")
|
|
124
|
+
|
|
125
|
+
print()
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def cmd_list_patterns(args):
|
|
129
|
+
"""List available patterns.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
args: Command line arguments
|
|
133
|
+
|
|
134
|
+
"""
|
|
135
|
+
registry = get_pattern_registry()
|
|
136
|
+
|
|
137
|
+
print(f"\n{'=' * 60}")
|
|
138
|
+
print("Available Patterns")
|
|
139
|
+
print(f"{'=' * 60}\n")
|
|
140
|
+
|
|
141
|
+
# Group by category
|
|
142
|
+
from patterns.core import PatternCategory
|
|
143
|
+
|
|
144
|
+
for category in PatternCategory:
|
|
145
|
+
patterns = registry.list_by_category(category)
|
|
146
|
+
if not patterns:
|
|
147
|
+
continue
|
|
148
|
+
|
|
149
|
+
print(f"{category.value.upper()} ({len(patterns)} patterns):")
|
|
150
|
+
for pattern in patterns:
|
|
151
|
+
print(
|
|
152
|
+
f" - {pattern.id:25} | {pattern.name:20} | Reusability: {pattern.reusability_score:.2f}"
|
|
153
|
+
)
|
|
154
|
+
print()
|
|
155
|
+
|
|
156
|
+
stats = registry.get_statistics()
|
|
157
|
+
print(f"Total: {stats['total_patterns']} patterns")
|
|
158
|
+
print(f"Average Reusability: {stats['average_reusability']:.2f}")
|
|
159
|
+
print()
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def main():
|
|
163
|
+
"""Main CLI entry point."""
|
|
164
|
+
parser = argparse.ArgumentParser(
|
|
165
|
+
description="Workflow Scaffolding for Empathy Framework",
|
|
166
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
167
|
+
epilog="""
|
|
168
|
+
Examples:
|
|
169
|
+
# Create healthcare workflow (recommended approach)
|
|
170
|
+
%(prog)s create patient_intake --domain healthcare
|
|
171
|
+
|
|
172
|
+
# Create with TDD methodology
|
|
173
|
+
%(prog)s create my_workflow --methodology tdd --domain finance
|
|
174
|
+
|
|
175
|
+
# Interactive pattern selection
|
|
176
|
+
%(prog)s create my_workflow --interactive --domain legal
|
|
177
|
+
|
|
178
|
+
# Specify patterns manually
|
|
179
|
+
%(prog)s create my_workflow --patterns linear_flow,approval,structured_fields
|
|
180
|
+
|
|
181
|
+
# List available patterns
|
|
182
|
+
%(prog)s list-patterns
|
|
183
|
+
""",
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
subparsers = parser.add_subparsers(dest="command", help="Command to run")
|
|
187
|
+
|
|
188
|
+
# Create command
|
|
189
|
+
create_parser = subparsers.add_parser("create", help="Create a new workflow")
|
|
190
|
+
create_parser.add_argument("name", help="Workflow name (e.g., patient_intake)")
|
|
191
|
+
create_parser.add_argument(
|
|
192
|
+
"--domain",
|
|
193
|
+
"-d",
|
|
194
|
+
help="Domain (e.g., healthcare, finance, legal)",
|
|
195
|
+
)
|
|
196
|
+
create_parser.add_argument(
|
|
197
|
+
"--type",
|
|
198
|
+
"-t",
|
|
199
|
+
choices=["domain", "coach", "ai"],
|
|
200
|
+
help="Workflow type (default: domain)",
|
|
201
|
+
)
|
|
202
|
+
create_parser.add_argument(
|
|
203
|
+
"--methodology",
|
|
204
|
+
"-m",
|
|
205
|
+
choices=["pattern", "tdd"],
|
|
206
|
+
help="Methodology (default: pattern)",
|
|
207
|
+
)
|
|
208
|
+
create_parser.add_argument(
|
|
209
|
+
"--patterns",
|
|
210
|
+
"-p",
|
|
211
|
+
help="Comma-separated pattern IDs",
|
|
212
|
+
)
|
|
213
|
+
create_parser.add_argument(
|
|
214
|
+
"--interactive",
|
|
215
|
+
"-i",
|
|
216
|
+
action="store_true",
|
|
217
|
+
help="Interactive pattern selection",
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
# List patterns command
|
|
221
|
+
subparsers.add_parser("list-patterns", help="List available patterns")
|
|
222
|
+
|
|
223
|
+
args = parser.parse_args()
|
|
224
|
+
|
|
225
|
+
if not args.command:
|
|
226
|
+
parser.print_help()
|
|
227
|
+
sys.exit(1)
|
|
228
|
+
|
|
229
|
+
# Execute command
|
|
230
|
+
if args.command == "create":
|
|
231
|
+
cmd_create(args)
|
|
232
|
+
elif args.command == "list-patterns":
|
|
233
|
+
cmd_list_patterns(args)
|
|
234
|
+
else:
|
|
235
|
+
parser.print_help()
|
|
236
|
+
sys.exit(1)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
if __name__ == "__main__":
|
|
240
|
+
main()
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""{{ wizard_name | title | replace('_', ' ') }} Wizard.
|
|
2
|
+
|
|
3
|
+
Auto-generated by Empathy Framework Scaffolding
|
|
4
|
+
Methodology: {{ methodology }}
|
|
5
|
+
Domain: {{ domain }}
|
|
6
|
+
Type: {{ wizard_type }}
|
|
7
|
+
Patterns: {{ pattern_ids | join(', ') }}
|
|
8
|
+
Generated: {{ timestamp }}
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import logging
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
from fastapi import APIRouter, HTTPException
|
|
15
|
+
from pydantic import BaseModel, Field
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
router = APIRouter(prefix="/{{ wizard_name }}", tags=["{{ wizard_name }}"])
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# Request/Response Models
|
|
23
|
+
class ProcessRequest(BaseModel):
|
|
24
|
+
"""Request to process wizard input."""
|
|
25
|
+
data: dict[str, Any] = Field(..., description="Input data to process")
|
|
26
|
+
context: dict[str, Any] = Field(default_factory=dict, description="Additional context")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ProcessResult(BaseModel):
|
|
30
|
+
"""Wizard processing result."""
|
|
31
|
+
wizard_id: str
|
|
32
|
+
result: dict[str, Any]
|
|
33
|
+
status: str = "success"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# In-memory session storage (replace with Redis in production)
|
|
37
|
+
sessions: dict[str, dict[str, Any]] = {}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@router.post("/process", response_model=ProcessResult)
|
|
41
|
+
async def process(request: ProcessRequest) -> ProcessResult:
|
|
42
|
+
"""Process wizard input.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
request: Processing request with input data
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
Processing result
|
|
49
|
+
|
|
50
|
+
Raises:
|
|
51
|
+
HTTPException: If processing fails
|
|
52
|
+
"""
|
|
53
|
+
try:
|
|
54
|
+
# Create session
|
|
55
|
+
wizard_id = f"{{ wizard_name }}_{len(sessions) + 1}"
|
|
56
|
+
|
|
57
|
+
# Process data
|
|
58
|
+
result = await _process_data(request.data, request.context)
|
|
59
|
+
|
|
60
|
+
# Store session
|
|
61
|
+
sessions[wizard_id] = {
|
|
62
|
+
"wizard_id": wizard_id,
|
|
63
|
+
"input_data": request.data,
|
|
64
|
+
"context": request.context,
|
|
65
|
+
"result": result,
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
logger.info(f"Processing complete for {wizard_id}")
|
|
69
|
+
|
|
70
|
+
return ProcessResult(
|
|
71
|
+
wizard_id=wizard_id,
|
|
72
|
+
result=result,
|
|
73
|
+
status="success",
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
except Exception as e:
|
|
77
|
+
logger.exception(f"Processing failed: {e}")
|
|
78
|
+
raise HTTPException(status_code=500, detail=f"Processing failed: {str(e)}")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@router.get("/{wizard_id}/result", response_model=dict[str, Any])
|
|
82
|
+
async def get_result(wizard_id: str) -> dict[str, Any]:
|
|
83
|
+
"""Get wizard result.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
wizard_id: Wizard session ID
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
Complete wizard result
|
|
90
|
+
|
|
91
|
+
Raises:
|
|
92
|
+
HTTPException: If session not found
|
|
93
|
+
"""
|
|
94
|
+
if wizard_id not in sessions:
|
|
95
|
+
raise HTTPException(status_code=404, detail="Session not found")
|
|
96
|
+
|
|
97
|
+
session = sessions[wizard_id]
|
|
98
|
+
return {
|
|
99
|
+
"wizard_id": wizard_id,
|
|
100
|
+
"input_data": session["input_data"],
|
|
101
|
+
"result": session["result"],
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# Helper functions
|
|
106
|
+
async def _process_data(data: dict[str, Any], context: dict[str, Any]) -> dict[str, Any]:
|
|
107
|
+
"""Process wizard data.
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
data: Input data to process
|
|
111
|
+
context: Additional context
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
Processing result
|
|
115
|
+
"""
|
|
116
|
+
# TODO: Implement actual processing logic
|
|
117
|
+
return {
|
|
118
|
+
"processed": True,
|
|
119
|
+
"data": data,
|
|
120
|
+
"context": context,
|
|
121
|
+
}
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
"""{{ wizard_name | title | replace('_', ' ') }} Coach Wizard.
|
|
2
|
+
|
|
3
|
+
Auto-generated by Empathy Framework Scaffolding
|
|
4
|
+
Methodology: {{ methodology }}
|
|
5
|
+
Domain: {{ domain }}
|
|
6
|
+
Patterns: {{ pattern_ids | join(', ') }}
|
|
7
|
+
Generated: {{ timestamp }}
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import logging
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
from fastapi import APIRouter, HTTPException
|
|
14
|
+
from pydantic import BaseModel, Field
|
|
15
|
+
|
|
16
|
+
from empathy_llm_toolkit.memory_manager import MemoryManager
|
|
17
|
+
from patterns import get_pattern_registry
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
router = APIRouter(prefix="/{{ wizard_name }}", tags=["{{ wizard_name }}"])
|
|
22
|
+
|
|
23
|
+
# Pattern registry for recommendations
|
|
24
|
+
registry = get_pattern_registry()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# Request/Response Models
|
|
28
|
+
class AnalysisRequest(BaseModel):
|
|
29
|
+
"""Request to analyze code."""
|
|
30
|
+
code: str = Field(..., description="Code to analyze")
|
|
31
|
+
context: dict[str, Any] = Field(default_factory=dict, description="Additional context")
|
|
32
|
+
{% if 'risk_assessment' in pattern_ids %}
|
|
33
|
+
include_risk_assessment: bool = Field(default=True, description="Include risk analysis")
|
|
34
|
+
{% endif %}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class AnalysisResult(BaseModel):
|
|
38
|
+
"""Analysis result."""
|
|
39
|
+
wizard_id: str
|
|
40
|
+
analysis: dict[str, Any]
|
|
41
|
+
{% if 'risk_assessment' in pattern_ids %}
|
|
42
|
+
risk_assessment: dict[str, Any] | None = None
|
|
43
|
+
{% endif %}
|
|
44
|
+
{% if 'prediction' in pattern_ids %}
|
|
45
|
+
predictions: list[dict[str, Any]] = Field(default_factory=list)
|
|
46
|
+
{% endif %}
|
|
47
|
+
{% if 'fix_application' in pattern_ids %}
|
|
48
|
+
suggested_fixes: list[dict[str, Any]] = Field(default_factory=list)
|
|
49
|
+
{% endif %}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
{% if 'fix_application' in pattern_ids %}
|
|
53
|
+
class FixRequest(BaseModel):
|
|
54
|
+
"""Request to apply a fix."""
|
|
55
|
+
wizard_id: str
|
|
56
|
+
fix_id: str
|
|
57
|
+
approval: dict[str, Any] = Field(..., description="User approval data")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class FixResult(BaseModel):
|
|
61
|
+
"""Fix application result."""
|
|
62
|
+
wizard_id: str
|
|
63
|
+
fix_id: str
|
|
64
|
+
applied: bool
|
|
65
|
+
modified_code: str | None = None
|
|
66
|
+
error: str | None = None
|
|
67
|
+
{% endif %}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# In-memory session storage (replace with Redis in production)
|
|
71
|
+
sessions: dict[str, dict[str, Any]] = {}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@router.post("/analyze", response_model=AnalysisResult)
|
|
75
|
+
async def analyze_code(request: AnalysisRequest) -> AnalysisResult:
|
|
76
|
+
"""Analyze code and provide recommendations.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
request: Analysis request with code and context
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
Analysis results with recommendations
|
|
83
|
+
|
|
84
|
+
Raises:
|
|
85
|
+
HTTPException: If analysis fails
|
|
86
|
+
"""
|
|
87
|
+
try:
|
|
88
|
+
# Create session
|
|
89
|
+
wizard_id = f"{{ wizard_name }}_{len(sessions) + 1}"
|
|
90
|
+
|
|
91
|
+
# Perform code analysis
|
|
92
|
+
analysis = await _analyze_code(request.code, request.context)
|
|
93
|
+
|
|
94
|
+
result = AnalysisResult(
|
|
95
|
+
wizard_id=wizard_id,
|
|
96
|
+
analysis=analysis,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
{% if 'risk_assessment' in pattern_ids %}
|
|
100
|
+
# Perform risk assessment
|
|
101
|
+
if request.include_risk_assessment:
|
|
102
|
+
risk_assessment = await _assess_risk(analysis)
|
|
103
|
+
result.risk_assessment = risk_assessment
|
|
104
|
+
{% endif %}
|
|
105
|
+
|
|
106
|
+
{% if 'prediction' in pattern_ids %}
|
|
107
|
+
# Generate predictions
|
|
108
|
+
predictions = await _generate_predictions(analysis)
|
|
109
|
+
result.predictions = predictions
|
|
110
|
+
{% endif %}
|
|
111
|
+
|
|
112
|
+
{% if 'fix_application' in pattern_ids %}
|
|
113
|
+
# Suggest fixes
|
|
114
|
+
fixes = await _suggest_fixes(analysis)
|
|
115
|
+
result.suggested_fixes = fixes
|
|
116
|
+
{% endif %}
|
|
117
|
+
|
|
118
|
+
# Store session
|
|
119
|
+
sessions[wizard_id] = {
|
|
120
|
+
"wizard_id": wizard_id,
|
|
121
|
+
"code": request.code,
|
|
122
|
+
"analysis": analysis,
|
|
123
|
+
"result": result.model_dump(),
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
logger.info(f"Analysis complete for {wizard_id}")
|
|
127
|
+
return result
|
|
128
|
+
|
|
129
|
+
except Exception as e:
|
|
130
|
+
logger.exception(f"Analysis failed: {e}")
|
|
131
|
+
raise HTTPException(status_code=500, detail=f"Analysis failed: {str(e)}")
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
{% if 'fix_application' in pattern_ids %}
|
|
135
|
+
@router.post("/fix/apply", response_model=FixResult)
|
|
136
|
+
async def apply_fix(request: FixRequest) -> FixResult:
|
|
137
|
+
"""Apply a suggested fix to code.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
request: Fix application request
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
Fix application result
|
|
144
|
+
|
|
145
|
+
Raises:
|
|
146
|
+
HTTPException: If session not found or fix fails
|
|
147
|
+
"""
|
|
148
|
+
# Validate session
|
|
149
|
+
if request.wizard_id not in sessions:
|
|
150
|
+
raise HTTPException(status_code=404, detail="Session not found")
|
|
151
|
+
|
|
152
|
+
session = sessions[request.wizard_id]
|
|
153
|
+
|
|
154
|
+
try:
|
|
155
|
+
# Validate approval
|
|
156
|
+
if not request.approval.get("user_approved"):
|
|
157
|
+
raise HTTPException(status_code=400, detail="User approval required")
|
|
158
|
+
|
|
159
|
+
# Find fix
|
|
160
|
+
suggested_fixes = session["result"].get("suggested_fixes", [])
|
|
161
|
+
fix = next((f for f in suggested_fixes if f["id"] == request.fix_id), None)
|
|
162
|
+
|
|
163
|
+
if not fix:
|
|
164
|
+
raise HTTPException(status_code=404, detail="Fix not found")
|
|
165
|
+
|
|
166
|
+
# Apply fix (placeholder - implement actual fix application)
|
|
167
|
+
modified_code = await _apply_fix(session["code"], fix)
|
|
168
|
+
|
|
169
|
+
# Update session
|
|
170
|
+
session["modified_code"] = modified_code
|
|
171
|
+
session["applied_fixes"] = session.get("applied_fixes", []) + [request.fix_id]
|
|
172
|
+
|
|
173
|
+
logger.info(f"Fix {request.fix_id} applied for {request.wizard_id}")
|
|
174
|
+
|
|
175
|
+
return FixResult(
|
|
176
|
+
wizard_id=request.wizard_id,
|
|
177
|
+
fix_id=request.fix_id,
|
|
178
|
+
applied=True,
|
|
179
|
+
modified_code=modified_code,
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
except HTTPException:
|
|
183
|
+
raise
|
|
184
|
+
except Exception as e:
|
|
185
|
+
logger.exception(f"Fix application failed: {e}")
|
|
186
|
+
return FixResult(
|
|
187
|
+
wizard_id=request.wizard_id,
|
|
188
|
+
fix_id=request.fix_id,
|
|
189
|
+
applied=False,
|
|
190
|
+
error=str(e),
|
|
191
|
+
)
|
|
192
|
+
{% endif %}
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
@router.get("/{wizard_id}/report", response_model=dict[str, Any])
|
|
196
|
+
async def get_report(wizard_id: str) -> dict[str, Any]:
|
|
197
|
+
"""Get analysis report.
|
|
198
|
+
|
|
199
|
+
Args:
|
|
200
|
+
wizard_id: Wizard session ID
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
Complete analysis report
|
|
204
|
+
|
|
205
|
+
Raises:
|
|
206
|
+
HTTPException: If session not found
|
|
207
|
+
"""
|
|
208
|
+
if wizard_id not in sessions:
|
|
209
|
+
raise HTTPException(status_code=404, detail="Session not found")
|
|
210
|
+
|
|
211
|
+
session = sessions[wizard_id]
|
|
212
|
+
return {
|
|
213
|
+
"wizard_id": wizard_id,
|
|
214
|
+
"analysis": session["analysis"],
|
|
215
|
+
"result": session["result"],
|
|
216
|
+
{% if 'fix_application' in pattern_ids %}
|
|
217
|
+
"applied_fixes": session.get("applied_fixes", []),
|
|
218
|
+
"modified_code": session.get("modified_code"),
|
|
219
|
+
{% endif %}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
# Helper functions
|
|
224
|
+
async def _analyze_code(code: str, context: dict[str, Any]) -> dict[str, Any]:
|
|
225
|
+
"""Analyze code (placeholder - implement actual analysis).
|
|
226
|
+
|
|
227
|
+
Args:
|
|
228
|
+
code: Code to analyze
|
|
229
|
+
context: Additional context
|
|
230
|
+
|
|
231
|
+
Returns:
|
|
232
|
+
Analysis results
|
|
233
|
+
"""
|
|
234
|
+
# TODO: Implement actual code analysis
|
|
235
|
+
return {
|
|
236
|
+
"lines_of_code": len(code.split("\n")),
|
|
237
|
+
"complexity": "medium",
|
|
238
|
+
"issues_found": 0,
|
|
239
|
+
"context": context,
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
{% if 'risk_assessment' in pattern_ids %}
|
|
244
|
+
async def _assess_risk(analysis: dict[str, Any]) -> dict[str, Any]:
|
|
245
|
+
"""Assess risk based on analysis.
|
|
246
|
+
|
|
247
|
+
Args:
|
|
248
|
+
analysis: Code analysis results
|
|
249
|
+
|
|
250
|
+
Returns:
|
|
251
|
+
Risk assessment
|
|
252
|
+
"""
|
|
253
|
+
# TODO: Implement actual risk assessment
|
|
254
|
+
return {
|
|
255
|
+
"alert_level": "LOW",
|
|
256
|
+
"risk_score": 0.2,
|
|
257
|
+
"by_risk_level": {
|
|
258
|
+
"critical": 0,
|
|
259
|
+
"high": 0,
|
|
260
|
+
"medium": 0,
|
|
261
|
+
"low": 0,
|
|
262
|
+
},
|
|
263
|
+
}
|
|
264
|
+
{% endif %}
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
{% if 'prediction' in pattern_ids %}
|
|
268
|
+
async def _generate_predictions(analysis: dict[str, Any]) -> list[dict[str, Any]]:
|
|
269
|
+
"""Generate predictions about future issues.
|
|
270
|
+
|
|
271
|
+
Args:
|
|
272
|
+
analysis: Code analysis results
|
|
273
|
+
|
|
274
|
+
Returns:
|
|
275
|
+
List of predictions
|
|
276
|
+
"""
|
|
277
|
+
# TODO: Implement actual predictions
|
|
278
|
+
return [
|
|
279
|
+
{
|
|
280
|
+
"type": "performance",
|
|
281
|
+
"confidence": 0.8,
|
|
282
|
+
"description": "May experience performance issues with large datasets",
|
|
283
|
+
}
|
|
284
|
+
]
|
|
285
|
+
{% endif %}
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
{% if 'fix_application' in pattern_ids %}
|
|
289
|
+
async def _suggest_fixes(analysis: dict[str, Any]) -> list[dict[str, Any]]:
|
|
290
|
+
"""Suggest fixes for identified issues.
|
|
291
|
+
|
|
292
|
+
Args:
|
|
293
|
+
analysis: Code analysis results
|
|
294
|
+
|
|
295
|
+
Returns:
|
|
296
|
+
List of suggested fixes
|
|
297
|
+
"""
|
|
298
|
+
# TODO: Implement actual fix suggestions
|
|
299
|
+
return [
|
|
300
|
+
{
|
|
301
|
+
"id": "fix_1",
|
|
302
|
+
"type": "optimization",
|
|
303
|
+
"description": "Add caching to improve performance",
|
|
304
|
+
"confidence": 0.9,
|
|
305
|
+
}
|
|
306
|
+
]
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
async def _apply_fix(code: str, fix: dict[str, Any]) -> str:
|
|
310
|
+
"""Apply a fix to code.
|
|
311
|
+
|
|
312
|
+
Args:
|
|
313
|
+
code: Original code
|
|
314
|
+
fix: Fix to apply
|
|
315
|
+
|
|
316
|
+
Returns:
|
|
317
|
+
Modified code
|
|
318
|
+
"""
|
|
319
|
+
# TODO: Implement actual fix application
|
|
320
|
+
return code + f"\n# Applied fix: {fix['id']}\n"
|
|
321
|
+
{% endif %}
|