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,438 @@
|
|
|
1
|
+
"""Session Evaluator for Continuous Learning
|
|
2
|
+
|
|
3
|
+
Evaluates sessions to determine if they contain learnable patterns.
|
|
4
|
+
Identifies high-value sessions worth analyzing for pattern extraction.
|
|
5
|
+
|
|
6
|
+
Architectural patterns inspired by everything-claude-code by Affaan Mustafa.
|
|
7
|
+
See: https://github.com/affaan-m/everything-claude-code (MIT License)
|
|
8
|
+
See: ACKNOWLEDGMENTS.md for full attribution.
|
|
9
|
+
|
|
10
|
+
Copyright 2025 Smart AI Memory, LLC
|
|
11
|
+
Licensed under Fair Source 0.9
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import logging
|
|
17
|
+
import re
|
|
18
|
+
from dataclasses import dataclass, field
|
|
19
|
+
from enum import Enum
|
|
20
|
+
from typing import TYPE_CHECKING, Any
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from attune_llm.state import CollaborationState
|
|
24
|
+
|
|
25
|
+
logger = logging.getLogger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class SessionQuality(Enum):
|
|
29
|
+
"""Quality rating for a session."""
|
|
30
|
+
|
|
31
|
+
EXCELLENT = "excellent" # High learning value
|
|
32
|
+
GOOD = "good" # Worth extracting patterns
|
|
33
|
+
AVERAGE = "average" # Some value
|
|
34
|
+
POOR = "poor" # Limited learning value
|
|
35
|
+
SKIP = "skip" # Don't process
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass
|
|
39
|
+
class SessionMetrics:
|
|
40
|
+
"""Metrics computed for a session."""
|
|
41
|
+
|
|
42
|
+
interaction_count: int = 0
|
|
43
|
+
user_corrections: int = 0
|
|
44
|
+
successful_resolutions: int = 0
|
|
45
|
+
trust_delta: float = 0.0
|
|
46
|
+
empathy_level_avg: float = 0.0
|
|
47
|
+
error_mentions: int = 0
|
|
48
|
+
workaround_mentions: int = 0
|
|
49
|
+
preference_signals: int = 0
|
|
50
|
+
session_duration_minutes: float = 0.0
|
|
51
|
+
|
|
52
|
+
def to_dict(self) -> dict[str, Any]:
|
|
53
|
+
"""Convert to dictionary."""
|
|
54
|
+
return {
|
|
55
|
+
"interaction_count": self.interaction_count,
|
|
56
|
+
"user_corrections": self.user_corrections,
|
|
57
|
+
"successful_resolutions": self.successful_resolutions,
|
|
58
|
+
"trust_delta": self.trust_delta,
|
|
59
|
+
"empathy_level_avg": self.empathy_level_avg,
|
|
60
|
+
"error_mentions": self.error_mentions,
|
|
61
|
+
"workaround_mentions": self.workaround_mentions,
|
|
62
|
+
"preference_signals": self.preference_signals,
|
|
63
|
+
"session_duration_minutes": self.session_duration_minutes,
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@dataclass
|
|
68
|
+
class EvaluationResult:
|
|
69
|
+
"""Result of session evaluation."""
|
|
70
|
+
|
|
71
|
+
quality: SessionQuality
|
|
72
|
+
score: float # 0.0 to 1.0
|
|
73
|
+
metrics: SessionMetrics
|
|
74
|
+
learnable_topics: list[str] = field(default_factory=list)
|
|
75
|
+
recommended_extraction: bool = False
|
|
76
|
+
reasoning: str = ""
|
|
77
|
+
|
|
78
|
+
def to_dict(self) -> dict[str, Any]:
|
|
79
|
+
"""Convert to dictionary."""
|
|
80
|
+
return {
|
|
81
|
+
"quality": self.quality.value,
|
|
82
|
+
"score": self.score,
|
|
83
|
+
"metrics": self.metrics.to_dict(),
|
|
84
|
+
"learnable_topics": self.learnable_topics,
|
|
85
|
+
"recommended_extraction": self.recommended_extraction,
|
|
86
|
+
"reasoning": self.reasoning,
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class SessionEvaluator:
|
|
91
|
+
"""Evaluates sessions for learning potential.
|
|
92
|
+
|
|
93
|
+
Analyzes collaboration sessions to determine if they contain
|
|
94
|
+
patterns worth extracting for continuous learning.
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
# Patterns indicating user corrections
|
|
98
|
+
CORRECTION_PATTERNS = [
|
|
99
|
+
r"actually[,\s]",
|
|
100
|
+
r"i meant",
|
|
101
|
+
r"no[,\s]+i",
|
|
102
|
+
r"that's not what i",
|
|
103
|
+
r"let me clarify",
|
|
104
|
+
r"to be clear",
|
|
105
|
+
r"what i really",
|
|
106
|
+
r"i should have said",
|
|
107
|
+
r"correction:",
|
|
108
|
+
]
|
|
109
|
+
|
|
110
|
+
# Patterns indicating errors/debugging
|
|
111
|
+
ERROR_PATTERNS = [
|
|
112
|
+
r"error",
|
|
113
|
+
r"exception",
|
|
114
|
+
r"failed",
|
|
115
|
+
r"doesn't work",
|
|
116
|
+
r"not working",
|
|
117
|
+
r"broken",
|
|
118
|
+
r"bug",
|
|
119
|
+
r"issue",
|
|
120
|
+
r"problem",
|
|
121
|
+
r"crash",
|
|
122
|
+
]
|
|
123
|
+
|
|
124
|
+
# Patterns indicating workarounds
|
|
125
|
+
WORKAROUND_PATTERNS = [
|
|
126
|
+
r"workaround",
|
|
127
|
+
r"instead[,\s]",
|
|
128
|
+
r"alternative",
|
|
129
|
+
r"hack",
|
|
130
|
+
r"trick",
|
|
131
|
+
r"bypass",
|
|
132
|
+
r"work around",
|
|
133
|
+
r"quick fix",
|
|
134
|
+
]
|
|
135
|
+
|
|
136
|
+
# Patterns indicating preferences
|
|
137
|
+
PREFERENCE_PATTERNS = [
|
|
138
|
+
r"i prefer",
|
|
139
|
+
r"i like",
|
|
140
|
+
r"i don't like",
|
|
141
|
+
r"i always",
|
|
142
|
+
r"i never",
|
|
143
|
+
r"my style",
|
|
144
|
+
r"usually i",
|
|
145
|
+
r"please always",
|
|
146
|
+
r"please don't",
|
|
147
|
+
]
|
|
148
|
+
|
|
149
|
+
# Patterns indicating successful resolution
|
|
150
|
+
SUCCESS_PATTERNS = [
|
|
151
|
+
r"that works",
|
|
152
|
+
r"perfect",
|
|
153
|
+
r"thanks",
|
|
154
|
+
r"great",
|
|
155
|
+
r"solved",
|
|
156
|
+
r"fixed",
|
|
157
|
+
r"working now",
|
|
158
|
+
r"exactly what i",
|
|
159
|
+
]
|
|
160
|
+
|
|
161
|
+
def __init__(
|
|
162
|
+
self,
|
|
163
|
+
min_interactions: int = 3,
|
|
164
|
+
min_score_for_extraction: float = 0.4,
|
|
165
|
+
):
|
|
166
|
+
"""Initialize the evaluator.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
min_interactions: Minimum interactions for evaluation
|
|
170
|
+
min_score_for_extraction: Minimum score to recommend extraction
|
|
171
|
+
"""
|
|
172
|
+
self._min_interactions = min_interactions
|
|
173
|
+
self._min_score_for_extraction = min_score_for_extraction
|
|
174
|
+
|
|
175
|
+
# Compile patterns
|
|
176
|
+
self._correction_re = self._compile_patterns(self.CORRECTION_PATTERNS)
|
|
177
|
+
self._error_re = self._compile_patterns(self.ERROR_PATTERNS)
|
|
178
|
+
self._workaround_re = self._compile_patterns(self.WORKAROUND_PATTERNS)
|
|
179
|
+
self._preference_re = self._compile_patterns(self.PREFERENCE_PATTERNS)
|
|
180
|
+
self._success_re = self._compile_patterns(self.SUCCESS_PATTERNS)
|
|
181
|
+
|
|
182
|
+
def _compile_patterns(self, patterns: list[str]) -> re.Pattern:
|
|
183
|
+
"""Compile patterns into a single regex."""
|
|
184
|
+
combined = "|".join(f"({p})" for p in patterns)
|
|
185
|
+
return re.compile(combined, re.IGNORECASE)
|
|
186
|
+
|
|
187
|
+
def evaluate(
|
|
188
|
+
self,
|
|
189
|
+
state: CollaborationState,
|
|
190
|
+
) -> EvaluationResult:
|
|
191
|
+
"""Evaluate a collaboration session.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
state: The collaboration state to evaluate
|
|
195
|
+
|
|
196
|
+
Returns:
|
|
197
|
+
EvaluationResult with quality rating and metrics
|
|
198
|
+
"""
|
|
199
|
+
# Compute metrics
|
|
200
|
+
metrics = self._compute_metrics(state)
|
|
201
|
+
|
|
202
|
+
# Determine learnable topics
|
|
203
|
+
topics = self._identify_topics(state, metrics)
|
|
204
|
+
|
|
205
|
+
# Calculate score
|
|
206
|
+
score = self._calculate_score(metrics, len(topics))
|
|
207
|
+
|
|
208
|
+
# Determine quality
|
|
209
|
+
quality = self._score_to_quality(score)
|
|
210
|
+
|
|
211
|
+
# Build reasoning
|
|
212
|
+
reasoning = self._build_reasoning(metrics, topics, score)
|
|
213
|
+
|
|
214
|
+
return EvaluationResult(
|
|
215
|
+
quality=quality,
|
|
216
|
+
score=score,
|
|
217
|
+
metrics=metrics,
|
|
218
|
+
learnable_topics=topics,
|
|
219
|
+
recommended_extraction=score >= self._min_score_for_extraction,
|
|
220
|
+
reasoning=reasoning,
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
def _compute_metrics(self, state: CollaborationState) -> SessionMetrics:
|
|
224
|
+
"""Compute session metrics."""
|
|
225
|
+
metrics = SessionMetrics()
|
|
226
|
+
|
|
227
|
+
metrics.interaction_count = len(state.interactions)
|
|
228
|
+
|
|
229
|
+
if metrics.interaction_count == 0:
|
|
230
|
+
return metrics
|
|
231
|
+
|
|
232
|
+
# Calculate duration
|
|
233
|
+
if state.interactions:
|
|
234
|
+
first = state.interactions[0].timestamp
|
|
235
|
+
last = state.interactions[-1].timestamp
|
|
236
|
+
duration = (last - first).total_seconds() / 60.0
|
|
237
|
+
metrics.session_duration_minutes = duration
|
|
238
|
+
|
|
239
|
+
# Calculate trust delta
|
|
240
|
+
if state.trust_trajectory:
|
|
241
|
+
initial = state.trust_trajectory[0] if state.trust_trajectory else 0.5
|
|
242
|
+
final = state.trust_level
|
|
243
|
+
metrics.trust_delta = final - initial
|
|
244
|
+
|
|
245
|
+
# Calculate average empathy level
|
|
246
|
+
if state.level_history:
|
|
247
|
+
metrics.empathy_level_avg = sum(state.level_history) / len(state.level_history)
|
|
248
|
+
else:
|
|
249
|
+
metrics.empathy_level_avg = state.current_level
|
|
250
|
+
|
|
251
|
+
# Analyze user messages
|
|
252
|
+
for interaction in state.interactions:
|
|
253
|
+
if interaction.role != "user":
|
|
254
|
+
continue
|
|
255
|
+
|
|
256
|
+
content_lower = interaction.content.lower()
|
|
257
|
+
|
|
258
|
+
# Count corrections
|
|
259
|
+
if self._correction_re.search(content_lower):
|
|
260
|
+
metrics.user_corrections += 1
|
|
261
|
+
|
|
262
|
+
# Count error mentions
|
|
263
|
+
if self._error_re.search(content_lower):
|
|
264
|
+
metrics.error_mentions += 1
|
|
265
|
+
|
|
266
|
+
# Count workaround mentions
|
|
267
|
+
if self._workaround_re.search(content_lower):
|
|
268
|
+
metrics.workaround_mentions += 1
|
|
269
|
+
|
|
270
|
+
# Count preference signals
|
|
271
|
+
if self._preference_re.search(content_lower):
|
|
272
|
+
metrics.preference_signals += 1
|
|
273
|
+
|
|
274
|
+
# Count successful resolutions
|
|
275
|
+
if self._success_re.search(content_lower):
|
|
276
|
+
metrics.successful_resolutions += 1
|
|
277
|
+
|
|
278
|
+
return metrics
|
|
279
|
+
|
|
280
|
+
def _identify_topics(
|
|
281
|
+
self,
|
|
282
|
+
state: CollaborationState,
|
|
283
|
+
metrics: SessionMetrics,
|
|
284
|
+
) -> list[str]:
|
|
285
|
+
"""Identify learnable topics from the session."""
|
|
286
|
+
topics = []
|
|
287
|
+
|
|
288
|
+
if metrics.user_corrections > 0:
|
|
289
|
+
topics.append("user_corrections")
|
|
290
|
+
|
|
291
|
+
if metrics.error_mentions > 0 and metrics.successful_resolutions > 0:
|
|
292
|
+
topics.append("error_resolution")
|
|
293
|
+
|
|
294
|
+
if metrics.workaround_mentions > 0:
|
|
295
|
+
topics.append("workarounds")
|
|
296
|
+
|
|
297
|
+
if metrics.preference_signals > 0:
|
|
298
|
+
topics.append("preferences")
|
|
299
|
+
|
|
300
|
+
# Check for project-specific patterns
|
|
301
|
+
if self._has_project_specific_content(state):
|
|
302
|
+
topics.append("project_specific")
|
|
303
|
+
|
|
304
|
+
return topics
|
|
305
|
+
|
|
306
|
+
def _has_project_specific_content(self, state: CollaborationState) -> bool:
|
|
307
|
+
"""Check if session contains project-specific content."""
|
|
308
|
+
# Look for file paths, function names, etc.
|
|
309
|
+
project_indicators = [
|
|
310
|
+
r"\.(py|js|ts|tsx|jsx|go|rs|java|cpp|c|h)\b", # File extensions
|
|
311
|
+
r"def\s+\w+", # Python functions
|
|
312
|
+
r"function\s+\w+", # JS functions
|
|
313
|
+
r"class\s+\w+", # Class definitions
|
|
314
|
+
r"import\s+", # Imports
|
|
315
|
+
r"from\s+\w+\s+import", # Python imports
|
|
316
|
+
]
|
|
317
|
+
|
|
318
|
+
project_re = re.compile("|".join(project_indicators), re.IGNORECASE)
|
|
319
|
+
|
|
320
|
+
for interaction in state.interactions:
|
|
321
|
+
if project_re.search(interaction.content):
|
|
322
|
+
return True
|
|
323
|
+
|
|
324
|
+
return False
|
|
325
|
+
|
|
326
|
+
def _calculate_score(
|
|
327
|
+
self,
|
|
328
|
+
metrics: SessionMetrics,
|
|
329
|
+
topic_count: int,
|
|
330
|
+
) -> float:
|
|
331
|
+
"""Calculate overall learning score."""
|
|
332
|
+
score = 0.0
|
|
333
|
+
|
|
334
|
+
# Base score from interaction count
|
|
335
|
+
if metrics.interaction_count >= self._min_interactions:
|
|
336
|
+
score += 0.1
|
|
337
|
+
|
|
338
|
+
# Corrections are highly valuable
|
|
339
|
+
if metrics.user_corrections > 0:
|
|
340
|
+
score += min(metrics.user_corrections * 0.15, 0.3)
|
|
341
|
+
|
|
342
|
+
# Error resolutions are valuable
|
|
343
|
+
if metrics.error_mentions > 0 and metrics.successful_resolutions > 0:
|
|
344
|
+
resolution_rate = metrics.successful_resolutions / max(metrics.error_mentions, 1)
|
|
345
|
+
score += resolution_rate * 0.2
|
|
346
|
+
|
|
347
|
+
# Workarounds are valuable
|
|
348
|
+
if metrics.workaround_mentions > 0:
|
|
349
|
+
score += min(metrics.workaround_mentions * 0.1, 0.2)
|
|
350
|
+
|
|
351
|
+
# Preferences help personalization
|
|
352
|
+
if metrics.preference_signals > 0:
|
|
353
|
+
score += min(metrics.preference_signals * 0.05, 0.1)
|
|
354
|
+
|
|
355
|
+
# Topic diversity bonus
|
|
356
|
+
score += topic_count * 0.05
|
|
357
|
+
|
|
358
|
+
# Trust increase indicates good interactions
|
|
359
|
+
if metrics.trust_delta > 0:
|
|
360
|
+
score += min(metrics.trust_delta * 0.2, 0.1)
|
|
361
|
+
|
|
362
|
+
# Penalize very short sessions
|
|
363
|
+
if metrics.interaction_count < self._min_interactions:
|
|
364
|
+
score *= 0.5
|
|
365
|
+
|
|
366
|
+
return min(score, 1.0)
|
|
367
|
+
|
|
368
|
+
def _score_to_quality(self, score: float) -> SessionQuality:
|
|
369
|
+
"""Convert score to quality rating."""
|
|
370
|
+
if score >= 0.7:
|
|
371
|
+
return SessionQuality.EXCELLENT
|
|
372
|
+
elif score >= 0.5:
|
|
373
|
+
return SessionQuality.GOOD
|
|
374
|
+
elif score >= 0.3:
|
|
375
|
+
return SessionQuality.AVERAGE
|
|
376
|
+
elif score >= 0.1:
|
|
377
|
+
return SessionQuality.POOR
|
|
378
|
+
else:
|
|
379
|
+
return SessionQuality.SKIP
|
|
380
|
+
|
|
381
|
+
def _build_reasoning(
|
|
382
|
+
self,
|
|
383
|
+
metrics: SessionMetrics,
|
|
384
|
+
topics: list[str],
|
|
385
|
+
score: float,
|
|
386
|
+
) -> str:
|
|
387
|
+
"""Build human-readable reasoning."""
|
|
388
|
+
parts = []
|
|
389
|
+
|
|
390
|
+
if metrics.user_corrections > 0:
|
|
391
|
+
parts.append(f"{metrics.user_corrections} user correction(s) found")
|
|
392
|
+
|
|
393
|
+
if metrics.successful_resolutions > 0:
|
|
394
|
+
parts.append(f"{metrics.successful_resolutions} successful resolution(s)")
|
|
395
|
+
|
|
396
|
+
if metrics.workaround_mentions > 0:
|
|
397
|
+
parts.append(f"{metrics.workaround_mentions} workaround(s) discussed")
|
|
398
|
+
|
|
399
|
+
if metrics.preference_signals > 0:
|
|
400
|
+
parts.append(f"{metrics.preference_signals} preference signal(s)")
|
|
401
|
+
|
|
402
|
+
if topics:
|
|
403
|
+
parts.append(f"Learnable topics: {', '.join(topics)}")
|
|
404
|
+
|
|
405
|
+
if not parts:
|
|
406
|
+
parts.append("Limited learning signals detected")
|
|
407
|
+
|
|
408
|
+
return "; ".join(parts) + f". Score: {score:.2f}"
|
|
409
|
+
|
|
410
|
+
def should_extract_patterns(
|
|
411
|
+
self,
|
|
412
|
+
state: CollaborationState,
|
|
413
|
+
) -> bool:
|
|
414
|
+
"""Quick check if patterns should be extracted.
|
|
415
|
+
|
|
416
|
+
Args:
|
|
417
|
+
state: Collaboration state to check
|
|
418
|
+
|
|
419
|
+
Returns:
|
|
420
|
+
True if extraction is recommended
|
|
421
|
+
"""
|
|
422
|
+
result = self.evaluate(state)
|
|
423
|
+
return result.recommended_extraction
|
|
424
|
+
|
|
425
|
+
def get_extraction_priority(
|
|
426
|
+
self,
|
|
427
|
+
state: CollaborationState,
|
|
428
|
+
) -> int:
|
|
429
|
+
"""Get extraction priority (higher = more important).
|
|
430
|
+
|
|
431
|
+
Args:
|
|
432
|
+
state: Collaboration state to evaluate
|
|
433
|
+
|
|
434
|
+
Returns:
|
|
435
|
+
Priority from 0-100
|
|
436
|
+
"""
|
|
437
|
+
result = self.evaluate(state)
|
|
438
|
+
return int(result.score * 100)
|