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
attune/cache_stats.py
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
"""Cache Statistics and Performance Reporting
|
|
2
|
+
|
|
3
|
+
Provides comprehensive reporting on cache performance metrics and recommendations.
|
|
4
|
+
|
|
5
|
+
Copyright 2025 Smart AI Memory, LLC
|
|
6
|
+
Licensed under Fair Source 0.9
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
from attune.cache_monitor import CacheMonitor, CacheStats
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class CacheHealthScore:
|
|
17
|
+
"""Health assessment for a cache."""
|
|
18
|
+
|
|
19
|
+
cache_name: str
|
|
20
|
+
hit_rate: float
|
|
21
|
+
health: str # "excellent", "good", "fair", "poor"
|
|
22
|
+
confidence: str # "high", "medium", "low"
|
|
23
|
+
recommendation: str
|
|
24
|
+
reasons: list[str]
|
|
25
|
+
|
|
26
|
+
def to_dict(self) -> dict[str, Any]:
|
|
27
|
+
"""Convert to dictionary."""
|
|
28
|
+
return {
|
|
29
|
+
"cache_name": self.cache_name,
|
|
30
|
+
"hit_rate": round(self.hit_rate, 4),
|
|
31
|
+
"health": self.health,
|
|
32
|
+
"confidence": self.confidence,
|
|
33
|
+
"recommendation": self.recommendation,
|
|
34
|
+
"reasons": self.reasons,
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class CacheAnalyzer:
|
|
39
|
+
"""Analyzes cache performance and provides recommendations.
|
|
40
|
+
|
|
41
|
+
Evaluates cache effectiveness based on hit rates, request patterns,
|
|
42
|
+
and memory usage, then provides actionable recommendations.
|
|
43
|
+
|
|
44
|
+
Example:
|
|
45
|
+
>>> analyzer = CacheAnalyzer()
|
|
46
|
+
>>> health = analyzer.analyze_cache("ast_parse")
|
|
47
|
+
>>> print(f"Health: {health.health}")
|
|
48
|
+
>>> print(f"Recommendation: {health.recommendation}")
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
@staticmethod
|
|
52
|
+
def analyze_cache(cache_name: str) -> CacheHealthScore | None:
|
|
53
|
+
"""Analyze health of a specific cache.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
cache_name: Name of cache to analyze
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
CacheHealthScore with assessment and recommendations
|
|
60
|
+
"""
|
|
61
|
+
monitor = CacheMonitor.get_instance()
|
|
62
|
+
stats = monitor.get_stats(cache_name)
|
|
63
|
+
|
|
64
|
+
if not stats:
|
|
65
|
+
return None
|
|
66
|
+
|
|
67
|
+
return CacheAnalyzer._calculate_health(stats)
|
|
68
|
+
|
|
69
|
+
@staticmethod
|
|
70
|
+
def analyze_all() -> dict[str, CacheHealthScore]:
|
|
71
|
+
"""Analyze health of all caches.
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
Dictionary mapping cache names to CacheHealthScore
|
|
75
|
+
"""
|
|
76
|
+
monitor = CacheMonitor.get_instance()
|
|
77
|
+
all_stats = monitor.get_all_stats()
|
|
78
|
+
|
|
79
|
+
return {name: CacheAnalyzer._calculate_health(stats) for name, stats in all_stats.items()}
|
|
80
|
+
|
|
81
|
+
@staticmethod
|
|
82
|
+
def _calculate_health(stats: CacheStats) -> CacheHealthScore:
|
|
83
|
+
"""Calculate health score for cache statistics.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
stats: CacheStats to analyze
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
CacheHealthScore with health assessment
|
|
90
|
+
"""
|
|
91
|
+
hit_rate = stats.hit_rate
|
|
92
|
+
total_requests = stats.total_requests
|
|
93
|
+
utilization = stats.utilization
|
|
94
|
+
|
|
95
|
+
# Determine health based on hit rate and request count
|
|
96
|
+
if total_requests < 10:
|
|
97
|
+
# Low request count - low confidence
|
|
98
|
+
confidence = "low"
|
|
99
|
+
if hit_rate >= 0.8:
|
|
100
|
+
health = "excellent"
|
|
101
|
+
elif hit_rate >= 0.6:
|
|
102
|
+
health = "good"
|
|
103
|
+
else:
|
|
104
|
+
health = "fair"
|
|
105
|
+
elif total_requests < 100:
|
|
106
|
+
# Medium request count - medium confidence
|
|
107
|
+
confidence = "medium"
|
|
108
|
+
if hit_rate >= 0.7:
|
|
109
|
+
health = "excellent"
|
|
110
|
+
elif hit_rate >= 0.5:
|
|
111
|
+
health = "good"
|
|
112
|
+
elif hit_rate >= 0.3:
|
|
113
|
+
health = "fair"
|
|
114
|
+
else:
|
|
115
|
+
health = "poor"
|
|
116
|
+
else:
|
|
117
|
+
# High request count - high confidence
|
|
118
|
+
confidence = "high"
|
|
119
|
+
if hit_rate >= 0.6:
|
|
120
|
+
health = "excellent"
|
|
121
|
+
elif hit_rate >= 0.4:
|
|
122
|
+
health = "good"
|
|
123
|
+
elif hit_rate >= 0.2:
|
|
124
|
+
health = "fair"
|
|
125
|
+
else:
|
|
126
|
+
health = "poor"
|
|
127
|
+
|
|
128
|
+
# Generate reasons and recommendations
|
|
129
|
+
reasons = []
|
|
130
|
+
recommendation = ""
|
|
131
|
+
|
|
132
|
+
if hit_rate > 0.7:
|
|
133
|
+
reasons.append("Strong hit rate indicates good cache effectiveness")
|
|
134
|
+
if total_requests >= 100:
|
|
135
|
+
recommendation = (
|
|
136
|
+
"Cache is performing well. Consider monitoring for memory usage as it grows."
|
|
137
|
+
)
|
|
138
|
+
else:
|
|
139
|
+
recommendation = "Cache shows promise with limited data. Continue monitoring."
|
|
140
|
+
elif hit_rate > 0.5:
|
|
141
|
+
reasons.append("Moderate hit rate suggests cache is somewhat effective")
|
|
142
|
+
recommendation = "Monitor for patterns. May benefit from adjusted cache key strategy."
|
|
143
|
+
elif hit_rate > 0.2:
|
|
144
|
+
reasons.append("Low hit rate indicates cache may not be effective for this pattern")
|
|
145
|
+
recommendation = "Review cache invalidation strategy or consider disabling if overhead exceeds benefit."
|
|
146
|
+
else:
|
|
147
|
+
reasons.append("Very low hit rate suggests cache is ineffective")
|
|
148
|
+
recommendation = "Strongly consider disabling this cache or redesigning cache key."
|
|
149
|
+
|
|
150
|
+
if utilization > 0.9 and stats.max_size > 0:
|
|
151
|
+
reasons.append("Cache is nearly full - may be evicting useful entries")
|
|
152
|
+
recommendation = (
|
|
153
|
+
f"{recommendation} Consider increasing cache size to {int(stats.max_size * 1.5)}."
|
|
154
|
+
)
|
|
155
|
+
elif utilization < 0.1 and stats.max_size > 0 and total_requests > 50:
|
|
156
|
+
reasons.append("Cache is underutilized - may be oversized")
|
|
157
|
+
recommendation = f"{recommendation} Consider reducing cache size to {max(1, int(stats.max_size * 0.5))}."
|
|
158
|
+
|
|
159
|
+
if total_requests > 1000 and hit_rate < 0.3:
|
|
160
|
+
reasons.append("High request volume with low hit rate suggests cache thrashing")
|
|
161
|
+
recommendation = "Cache invalidation may be too aggressive. Review cache lifetime."
|
|
162
|
+
|
|
163
|
+
return CacheHealthScore(
|
|
164
|
+
cache_name=stats.name,
|
|
165
|
+
hit_rate=hit_rate,
|
|
166
|
+
health=health,
|
|
167
|
+
confidence=confidence,
|
|
168
|
+
recommendation=recommendation,
|
|
169
|
+
reasons=reasons,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
class CacheReporter:
|
|
174
|
+
"""Generates formatted cache performance reports.
|
|
175
|
+
|
|
176
|
+
Creates human-readable reports on cache metrics, health scores,
|
|
177
|
+
and recommendations for optimization.
|
|
178
|
+
|
|
179
|
+
Example:
|
|
180
|
+
>>> reporter = CacheReporter()
|
|
181
|
+
>>> print(reporter.generate_health_report())
|
|
182
|
+
"""
|
|
183
|
+
|
|
184
|
+
@staticmethod
|
|
185
|
+
def generate_health_report(verbose: bool = False) -> str:
|
|
186
|
+
"""Generate cache health report.
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
verbose: Include detailed metrics
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
Formatted health report
|
|
193
|
+
"""
|
|
194
|
+
analyzer = CacheAnalyzer()
|
|
195
|
+
health_scores = analyzer.analyze_all()
|
|
196
|
+
|
|
197
|
+
if not health_scores:
|
|
198
|
+
return "No caches registered for monitoring"
|
|
199
|
+
|
|
200
|
+
# Sort by health (excellent -> poor)
|
|
201
|
+
health_order = {"excellent": 0, "good": 1, "fair": 2, "poor": 3}
|
|
202
|
+
sorted_scores = sorted(
|
|
203
|
+
health_scores.values(),
|
|
204
|
+
key=lambda s: (health_order.get(s.health, 99), -s.hit_rate),
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
lines = ["=" * 80, "CACHE HEALTH REPORT", "=" * 80, ""]
|
|
208
|
+
|
|
209
|
+
for score in sorted_scores:
|
|
210
|
+
lines.append(f"Cache: {score.cache_name}")
|
|
211
|
+
lines.append("-" * 80)
|
|
212
|
+
lines.append(f" Health: {score.health.upper()}")
|
|
213
|
+
lines.append(f" Confidence: {score.confidence.upper()}")
|
|
214
|
+
lines.append(f" Hit Rate: {score.hit_rate:.1%}")
|
|
215
|
+
lines.append(f" Recommendation: {score.recommendation}")
|
|
216
|
+
|
|
217
|
+
if verbose:
|
|
218
|
+
for reason in score.reasons:
|
|
219
|
+
lines.append(f" - {reason}")
|
|
220
|
+
|
|
221
|
+
lines.append("")
|
|
222
|
+
|
|
223
|
+
# Summary
|
|
224
|
+
excellent = sum(1 for s in health_scores.values() if s.health == "excellent")
|
|
225
|
+
good = sum(1 for s in health_scores.values() if s.health == "good")
|
|
226
|
+
fair = sum(1 for s in health_scores.values() if s.health == "fair")
|
|
227
|
+
poor = sum(1 for s in health_scores.values() if s.health == "poor")
|
|
228
|
+
|
|
229
|
+
lines.append("=" * 80)
|
|
230
|
+
lines.append("SUMMARY")
|
|
231
|
+
lines.append("=" * 80)
|
|
232
|
+
lines.append(f" Total Caches: {len(health_scores)}")
|
|
233
|
+
lines.append(f" Excellent: {excellent}")
|
|
234
|
+
lines.append(f" Good: {good}")
|
|
235
|
+
lines.append(f" Fair: {fair}")
|
|
236
|
+
lines.append(f" Poor: {poor}")
|
|
237
|
+
lines.append("=" * 80)
|
|
238
|
+
|
|
239
|
+
return "\n".join(lines)
|
|
240
|
+
|
|
241
|
+
@staticmethod
|
|
242
|
+
def generate_optimization_report() -> str:
|
|
243
|
+
"""Generate cache optimization recommendations.
|
|
244
|
+
|
|
245
|
+
Returns:
|
|
246
|
+
Formatted optimization report
|
|
247
|
+
"""
|
|
248
|
+
monitor = CacheMonitor.get_instance()
|
|
249
|
+
analyzer = CacheAnalyzer()
|
|
250
|
+
|
|
251
|
+
lines = ["=" * 80, "CACHE OPTIMIZATION OPPORTUNITIES", "=" * 80, ""]
|
|
252
|
+
|
|
253
|
+
underperformers = monitor.get_underperformers(threshold=0.3)
|
|
254
|
+
if underperformers:
|
|
255
|
+
lines.append("LOW-PERFORMING CACHES (hit rate < 30%):")
|
|
256
|
+
lines.append("-" * 80)
|
|
257
|
+
for stats in underperformers:
|
|
258
|
+
health = analyzer.analyze_cache(stats.name)
|
|
259
|
+
if health:
|
|
260
|
+
lines.append(f" {stats.name}: {health.recommendation}")
|
|
261
|
+
lines.append("")
|
|
262
|
+
|
|
263
|
+
high_performers = monitor.get_high_performers(threshold=0.7)
|
|
264
|
+
if high_performers:
|
|
265
|
+
lines.append("HIGH-PERFORMING CACHES (hit rate > 70%):")
|
|
266
|
+
lines.append("-" * 80)
|
|
267
|
+
for stats in high_performers:
|
|
268
|
+
lines.append(f" {stats.name}: Performing well ({stats.hit_rate:.1%} hit rate)")
|
|
269
|
+
lines.append("")
|
|
270
|
+
|
|
271
|
+
lines.append("=" * 80)
|
|
272
|
+
|
|
273
|
+
return "\n".join(lines)
|
|
274
|
+
|
|
275
|
+
@staticmethod
|
|
276
|
+
def generate_full_report() -> str:
|
|
277
|
+
"""Generate comprehensive cache report.
|
|
278
|
+
|
|
279
|
+
Returns:
|
|
280
|
+
Formatted comprehensive report
|
|
281
|
+
"""
|
|
282
|
+
monitor = CacheMonitor.get_instance()
|
|
283
|
+
|
|
284
|
+
report_parts = [
|
|
285
|
+
"=" * 80,
|
|
286
|
+
"COMPREHENSIVE CACHE ANALYSIS REPORT",
|
|
287
|
+
"=" * 80,
|
|
288
|
+
"",
|
|
289
|
+
monitor.get_report(verbose=True),
|
|
290
|
+
"",
|
|
291
|
+
monitor.get_size_report(),
|
|
292
|
+
"",
|
|
293
|
+
CacheReporter.generate_health_report(verbose=True),
|
|
294
|
+
"",
|
|
295
|
+
CacheReporter.generate_optimization_report(),
|
|
296
|
+
]
|
|
297
|
+
|
|
298
|
+
return "\n".join(report_parts)
|
attune/cli/__init__.py
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"""Empathy Framework CLI - Refactored modular structure.
|
|
2
|
+
|
|
3
|
+
Entry point for the empathy command-line interface.
|
|
4
|
+
|
|
5
|
+
Copyright 2025 Smart-AI-Memory
|
|
6
|
+
Licensed under Fair Source License 0.9
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import argparse
|
|
10
|
+
import sys
|
|
11
|
+
|
|
12
|
+
from attune.discovery import show_tip_if_available
|
|
13
|
+
from attune.logging_config import get_logger
|
|
14
|
+
from attune.platform_utils import setup_asyncio_policy
|
|
15
|
+
|
|
16
|
+
logger = get_logger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def get_version() -> str:
|
|
20
|
+
"""Get package version.
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
Version string or "dev" if not installed
|
|
24
|
+
"""
|
|
25
|
+
try:
|
|
26
|
+
from importlib.metadata import version
|
|
27
|
+
|
|
28
|
+
return version("empathy-framework")
|
|
29
|
+
except Exception: # noqa: BLE001
|
|
30
|
+
return "dev"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def main() -> int:
|
|
34
|
+
"""Main CLI entry point.
|
|
35
|
+
|
|
36
|
+
This is the refactored CLI entry point that uses modular command
|
|
37
|
+
and parser organization instead of a monolithic 3,957-line file.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
Exit code (0 for success, non-zero for error)
|
|
41
|
+
"""
|
|
42
|
+
# Windows async compatibility
|
|
43
|
+
setup_asyncio_policy()
|
|
44
|
+
|
|
45
|
+
# Create main parser
|
|
46
|
+
parser = argparse.ArgumentParser(
|
|
47
|
+
prog="empathy", description="Empathy Framework - Context-aware development automation"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
# Add global flags
|
|
51
|
+
parser.add_argument("--version", action="version", version=f"empathy {get_version()}")
|
|
52
|
+
|
|
53
|
+
# Create subparsers
|
|
54
|
+
subparsers = parser.add_subparsers(
|
|
55
|
+
dest="command", title="commands", description="Available commands"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# Register all command parsers (modular!)
|
|
59
|
+
from .parsers import register_all_parsers
|
|
60
|
+
|
|
61
|
+
register_all_parsers(subparsers)
|
|
62
|
+
|
|
63
|
+
# TODO: Import and register remaining commands from cli.py
|
|
64
|
+
# This is a partial refactoring - additional commands still in cli.py
|
|
65
|
+
# For now, if command not found in new structure, fall back to old cli.py
|
|
66
|
+
#
|
|
67
|
+
# NOTE: Temporarily disabled to avoid conflicts with extracted commands.
|
|
68
|
+
# Commands that have been extracted:
|
|
69
|
+
# - help, tier, info, patterns, status (Phase 1)
|
|
70
|
+
# - workflow, inspect (run, inspect, export, import) (Phase 2)
|
|
71
|
+
# Once all commands are extracted, the old cli.py will be removed entirely.
|
|
72
|
+
#
|
|
73
|
+
# try:
|
|
74
|
+
# from attune import cli as old_cli
|
|
75
|
+
# _register_legacy_commands(subparsers, old_cli)
|
|
76
|
+
# except ImportError:
|
|
77
|
+
# pass # Old cli.py not available or already moved
|
|
78
|
+
|
|
79
|
+
# Parse arguments
|
|
80
|
+
args = parser.parse_args()
|
|
81
|
+
|
|
82
|
+
# Execute command
|
|
83
|
+
if hasattr(args, "func"):
|
|
84
|
+
try:
|
|
85
|
+
result = args.func(args)
|
|
86
|
+
|
|
87
|
+
# Show discovery tips (except for dashboard/run)
|
|
88
|
+
if args.command and args.command not in ("dashboard", "run"):
|
|
89
|
+
try:
|
|
90
|
+
show_tip_if_available(args.command)
|
|
91
|
+
except Exception: # noqa: BLE001
|
|
92
|
+
logger.debug("Discovery tip not available")
|
|
93
|
+
|
|
94
|
+
return result if result is not None else 0
|
|
95
|
+
|
|
96
|
+
except KeyboardInterrupt:
|
|
97
|
+
print("\n\n⚠️ Interrupted by user")
|
|
98
|
+
return 130
|
|
99
|
+
|
|
100
|
+
except Exception as e: # noqa: BLE001
|
|
101
|
+
logger.exception(f"Unexpected error in command {args.command}")
|
|
102
|
+
print(f"\n❌ Error: {e}")
|
|
103
|
+
return 1
|
|
104
|
+
|
|
105
|
+
# No command specified
|
|
106
|
+
parser.print_help()
|
|
107
|
+
return 0
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _register_legacy_commands(subparsers, old_cli):
|
|
111
|
+
"""Temporarily register commands not yet extracted from old cli.py.
|
|
112
|
+
|
|
113
|
+
This function provides backward compatibility during the refactoring process.
|
|
114
|
+
As commands are extracted into the new structure, they should be removed
|
|
115
|
+
from this registration.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
subparsers: ArgumentParser subparsers object
|
|
119
|
+
old_cli: Reference to old cli module
|
|
120
|
+
|
|
121
|
+
Note:
|
|
122
|
+
This is a TEMPORARY function that will be removed once all commands
|
|
123
|
+
are extracted from the monolithic cli.py file.
|
|
124
|
+
"""
|
|
125
|
+
# Import command functions that haven't been extracted yet
|
|
126
|
+
try:
|
|
127
|
+
# Patterns commands
|
|
128
|
+
from attune.cli import cmd_patterns_export, cmd_patterns_list, cmd_patterns_resolve
|
|
129
|
+
|
|
130
|
+
patterns_parser = subparsers.add_parser("patterns", help="Pattern management")
|
|
131
|
+
patterns_sub = patterns_parser.add_subparsers(dest="patterns_command")
|
|
132
|
+
|
|
133
|
+
p_list = patterns_sub.add_parser("list", help="List patterns")
|
|
134
|
+
p_list.set_defaults(func=cmd_patterns_list)
|
|
135
|
+
|
|
136
|
+
p_export = patterns_sub.add_parser("export", help="Export patterns")
|
|
137
|
+
p_export.add_argument("output", help="Output file")
|
|
138
|
+
p_export.set_defaults(func=cmd_patterns_export)
|
|
139
|
+
|
|
140
|
+
p_resolve = patterns_sub.add_parser("resolve", help="Resolve pattern")
|
|
141
|
+
p_resolve.add_argument("pattern_id", help="Pattern ID")
|
|
142
|
+
p_resolve.set_defaults(func=cmd_patterns_resolve)
|
|
143
|
+
except (ImportError, AttributeError):
|
|
144
|
+
pass # Commands not available
|
|
145
|
+
|
|
146
|
+
# Add other legacy commands as needed...
|
|
147
|
+
# This list will shrink as commands are extracted
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
# Preserve backward compatibility
|
|
151
|
+
if __name__ == "__main__":
|
|
152
|
+
sys.exit(main())
|
attune/cli/__main__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""CLI command implementations."""
|