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,99 @@
|
|
|
1
|
+
"""Type definitions for long-term memory system
|
|
2
|
+
|
|
3
|
+
This module contains data classes, enums, and exceptions used by the long-term
|
|
4
|
+
memory system. Extracted from long_term.py for better modularity and testability.
|
|
5
|
+
|
|
6
|
+
Key Types:
|
|
7
|
+
- Classification: Three-tier security classification system
|
|
8
|
+
- ClassificationRules: Security rules per classification level
|
|
9
|
+
- PatternMetadata: Metadata for stored patterns
|
|
10
|
+
- SecurePattern: Pattern with content and metadata
|
|
11
|
+
- SecurityError, PermissionError: Exception types
|
|
12
|
+
|
|
13
|
+
Copyright 2025 Smart AI Memory, LLC
|
|
14
|
+
Licensed under Fair Source 0.9
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from dataclasses import dataclass, field
|
|
18
|
+
from enum import Enum
|
|
19
|
+
from typing import Any
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Classification(Enum):
|
|
23
|
+
"""Three-tier classification system for MemDocs patterns"""
|
|
24
|
+
|
|
25
|
+
PUBLIC = "PUBLIC" # Shareable across organization, anonymized
|
|
26
|
+
INTERNAL = "INTERNAL" # Team/project only, no PII or secrets
|
|
27
|
+
SENSITIVE = "SENSITIVE" # Encrypted at rest, access-controlled (HIPAA, finance)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass
|
|
31
|
+
class ClassificationRules:
|
|
32
|
+
"""Security rules for each classification level"""
|
|
33
|
+
|
|
34
|
+
classification: Classification
|
|
35
|
+
encryption_required: bool
|
|
36
|
+
retention_days: int
|
|
37
|
+
access_level: str # "all_users", "project_team", "explicit_permission"
|
|
38
|
+
audit_all_access: bool = False
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# Default classification rules based on enterprise security policy
|
|
42
|
+
DEFAULT_CLASSIFICATION_RULES: dict[Classification, ClassificationRules] = {
|
|
43
|
+
Classification.PUBLIC: ClassificationRules(
|
|
44
|
+
classification=Classification.PUBLIC,
|
|
45
|
+
encryption_required=False,
|
|
46
|
+
retention_days=365,
|
|
47
|
+
access_level="all_users",
|
|
48
|
+
audit_all_access=False,
|
|
49
|
+
),
|
|
50
|
+
Classification.INTERNAL: ClassificationRules(
|
|
51
|
+
classification=Classification.INTERNAL,
|
|
52
|
+
encryption_required=False,
|
|
53
|
+
retention_days=180,
|
|
54
|
+
access_level="project_team",
|
|
55
|
+
audit_all_access=False,
|
|
56
|
+
),
|
|
57
|
+
Classification.SENSITIVE: ClassificationRules(
|
|
58
|
+
classification=Classification.SENSITIVE,
|
|
59
|
+
encryption_required=True,
|
|
60
|
+
retention_days=90,
|
|
61
|
+
access_level="explicit_permission",
|
|
62
|
+
audit_all_access=True,
|
|
63
|
+
),
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@dataclass
|
|
68
|
+
class PatternMetadata:
|
|
69
|
+
"""Metadata for stored MemDocs patterns"""
|
|
70
|
+
|
|
71
|
+
pattern_id: str
|
|
72
|
+
created_by: str
|
|
73
|
+
created_at: str
|
|
74
|
+
classification: str
|
|
75
|
+
retention_days: int
|
|
76
|
+
encrypted: bool
|
|
77
|
+
pattern_type: str
|
|
78
|
+
sanitization_applied: bool
|
|
79
|
+
pii_removed: int
|
|
80
|
+
secrets_detected: int
|
|
81
|
+
access_control: dict[str, Any] = field(default_factory=dict)
|
|
82
|
+
custom_metadata: dict[str, Any] = field(default_factory=dict)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@dataclass
|
|
86
|
+
class SecurePattern:
|
|
87
|
+
"""Represents a securely stored pattern"""
|
|
88
|
+
|
|
89
|
+
pattern_id: str
|
|
90
|
+
content: str
|
|
91
|
+
metadata: PatternMetadata
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class SecurityError(Exception):
|
|
95
|
+
"""Raised when security policy is violated"""
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class PermissionError(Exception):
|
|
99
|
+
"""Raised when access is denied"""
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Memory mixins for UnifiedMemory composition.
|
|
2
|
+
|
|
3
|
+
Provides modular capabilities through mixin composition pattern.
|
|
4
|
+
|
|
5
|
+
Copyright 2025 Smart AI Memory, LLC
|
|
6
|
+
Licensed under Fair Source 0.9
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from .backend_init_mixin import BackendInitMixin
|
|
10
|
+
from .capabilities_mixin import CapabilitiesMixin
|
|
11
|
+
from .handoff_mixin import HandoffAndExportMixin
|
|
12
|
+
from .lifecycle_mixin import LifecycleMixin
|
|
13
|
+
from .long_term_mixin import LongTermOperationsMixin
|
|
14
|
+
from .promotion_mixin import PatternPromotionMixin
|
|
15
|
+
from .short_term_mixin import ShortTermOperationsMixin
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"BackendInitMixin",
|
|
19
|
+
"CapabilitiesMixin",
|
|
20
|
+
"HandoffAndExportMixin",
|
|
21
|
+
"LifecycleMixin",
|
|
22
|
+
"LongTermOperationsMixin",
|
|
23
|
+
"PatternPromotionMixin",
|
|
24
|
+
"ShortTermOperationsMixin",
|
|
25
|
+
]
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"""Backend initialization mixin for UnifiedMemory.
|
|
2
|
+
|
|
3
|
+
Handles initialization of file session, Redis, and long-term memory backends.
|
|
4
|
+
|
|
5
|
+
Copyright 2025 Smart AI Memory, LLC
|
|
6
|
+
Licensed under Fair Source 0.9
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import TYPE_CHECKING, Any
|
|
10
|
+
|
|
11
|
+
import structlog
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from ..file_session import FileSessionMemory
|
|
15
|
+
from ..long_term import LongTermMemory, SecureMemDocsIntegration
|
|
16
|
+
from ..redis_bootstrap import RedisStatus
|
|
17
|
+
from ..short_term import RedisShortTermMemory
|
|
18
|
+
|
|
19
|
+
logger = structlog.get_logger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class BackendInitMixin:
|
|
23
|
+
"""Mixin providing backend initialization for UnifiedMemory."""
|
|
24
|
+
|
|
25
|
+
# Type hints for attributes that will be provided by UnifiedMemory
|
|
26
|
+
user_id: str
|
|
27
|
+
config: Any # MemoryConfig
|
|
28
|
+
_file_session: "FileSessionMemory | None"
|
|
29
|
+
_short_term: "RedisShortTermMemory | None"
|
|
30
|
+
_long_term: "SecureMemDocsIntegration | None"
|
|
31
|
+
_simple_long_term: "LongTermMemory | None"
|
|
32
|
+
_redis_status: "RedisStatus | None"
|
|
33
|
+
_initialized: bool
|
|
34
|
+
|
|
35
|
+
# =========================================================================
|
|
36
|
+
# BACKEND INITIALIZATION
|
|
37
|
+
# =========================================================================
|
|
38
|
+
|
|
39
|
+
def _initialize_backends(self):
|
|
40
|
+
"""Initialize short-term and long-term memory backends.
|
|
41
|
+
|
|
42
|
+
File-First Architecture:
|
|
43
|
+
1. FileSessionMemory is always initialized (primary storage)
|
|
44
|
+
2. Redis is optional (for real-time features like pub/sub)
|
|
45
|
+
3. Falls back gracefully when Redis is unavailable
|
|
46
|
+
"""
|
|
47
|
+
from ..claude_memory import ClaudeMemoryConfig
|
|
48
|
+
from ..config import get_redis_memory
|
|
49
|
+
from ..file_session import FileSessionConfig, FileSessionMemory
|
|
50
|
+
from ..long_term import LongTermMemory, SecureMemDocsIntegration
|
|
51
|
+
from ..redis_bootstrap import RedisStartMethod, RedisStatus, ensure_redis
|
|
52
|
+
from ..short_term import RedisShortTermMemory
|
|
53
|
+
|
|
54
|
+
if self._initialized:
|
|
55
|
+
return
|
|
56
|
+
|
|
57
|
+
# Initialize file-based session memory (PRIMARY - always available)
|
|
58
|
+
if self.config.file_session_enabled:
|
|
59
|
+
try:
|
|
60
|
+
file_config = FileSessionConfig(base_dir=self.config.file_session_dir)
|
|
61
|
+
self._file_session = FileSessionMemory(
|
|
62
|
+
user_id=self.user_id,
|
|
63
|
+
config=file_config,
|
|
64
|
+
)
|
|
65
|
+
logger.info(
|
|
66
|
+
"file_session_memory_initialized",
|
|
67
|
+
base_dir=self.config.file_session_dir,
|
|
68
|
+
session_id=self._file_session._state.session_id,
|
|
69
|
+
)
|
|
70
|
+
except Exception as e:
|
|
71
|
+
logger.error("file_session_memory_failed", error=str(e))
|
|
72
|
+
self._file_session = None
|
|
73
|
+
|
|
74
|
+
# Initialize Redis short-term memory (OPTIONAL - for real-time features)
|
|
75
|
+
try:
|
|
76
|
+
if self.config.redis_mock:
|
|
77
|
+
self._short_term = RedisShortTermMemory(use_mock=True)
|
|
78
|
+
self._redis_status = RedisStatus(
|
|
79
|
+
available=False,
|
|
80
|
+
method=RedisStartMethod.MOCK,
|
|
81
|
+
message="Mock mode explicitly enabled",
|
|
82
|
+
)
|
|
83
|
+
elif self.config.redis_url:
|
|
84
|
+
self._short_term = get_redis_memory(url=self.config.redis_url)
|
|
85
|
+
self._redis_status = RedisStatus(
|
|
86
|
+
available=True,
|
|
87
|
+
method=RedisStartMethod.ALREADY_RUNNING,
|
|
88
|
+
message="Connected via REDIS_URL",
|
|
89
|
+
)
|
|
90
|
+
# Use auto-start if enabled
|
|
91
|
+
elif self.config.redis_auto_start:
|
|
92
|
+
self._redis_status = ensure_redis(
|
|
93
|
+
host=self.config.redis_host,
|
|
94
|
+
port=self.config.redis_port,
|
|
95
|
+
auto_start=True,
|
|
96
|
+
verbose=True,
|
|
97
|
+
)
|
|
98
|
+
if self._redis_status.available:
|
|
99
|
+
self._short_term = RedisShortTermMemory(
|
|
100
|
+
host=self.config.redis_host,
|
|
101
|
+
port=self.config.redis_port,
|
|
102
|
+
use_mock=False,
|
|
103
|
+
)
|
|
104
|
+
else:
|
|
105
|
+
# File session is primary, so Redis mock is not needed
|
|
106
|
+
self._short_term = None
|
|
107
|
+
self._redis_status = RedisStatus(
|
|
108
|
+
available=False,
|
|
109
|
+
method=RedisStartMethod.MOCK,
|
|
110
|
+
message="Redis unavailable, using file-based storage",
|
|
111
|
+
)
|
|
112
|
+
else:
|
|
113
|
+
# Try to connect to existing Redis
|
|
114
|
+
try:
|
|
115
|
+
self._short_term = get_redis_memory()
|
|
116
|
+
if self._short_term.is_connected():
|
|
117
|
+
self._redis_status = RedisStatus(
|
|
118
|
+
available=True,
|
|
119
|
+
method=RedisStartMethod.ALREADY_RUNNING,
|
|
120
|
+
message="Connected to existing Redis",
|
|
121
|
+
)
|
|
122
|
+
else:
|
|
123
|
+
self._short_term = None
|
|
124
|
+
self._redis_status = RedisStatus(
|
|
125
|
+
available=False,
|
|
126
|
+
method=RedisStartMethod.MOCK,
|
|
127
|
+
message="Redis not available, using file-based storage",
|
|
128
|
+
)
|
|
129
|
+
except Exception:
|
|
130
|
+
self._short_term = None
|
|
131
|
+
self._redis_status = RedisStatus(
|
|
132
|
+
available=False,
|
|
133
|
+
method=RedisStartMethod.MOCK,
|
|
134
|
+
message="Redis not available, using file-based storage",
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
logger.info(
|
|
138
|
+
"short_term_memory_initialized",
|
|
139
|
+
redis_available=self._redis_status.available if self._redis_status else False,
|
|
140
|
+
file_session_available=self._file_session is not None,
|
|
141
|
+
redis_method=self._redis_status.method.value if self._redis_status else "none",
|
|
142
|
+
environment=self.config.environment.value,
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
# Fail if Redis is required but not available
|
|
146
|
+
if self.config.redis_required and not (
|
|
147
|
+
self._redis_status and self._redis_status.available
|
|
148
|
+
):
|
|
149
|
+
raise RuntimeError(
|
|
150
|
+
"Redis is required but not available. "
|
|
151
|
+
f"Config requires Redis (redis_required=True, environment={self.config.environment.value}). "
|
|
152
|
+
"Either: (1) Start Redis server, (2) Set REDIS_URL environment variable, "
|
|
153
|
+
"or (3) Set redis_required=False in MemoryConfig."
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
except RuntimeError:
|
|
157
|
+
raise # Re-raise required Redis error
|
|
158
|
+
except Exception as e:
|
|
159
|
+
logger.warning("redis_initialization_failed", error=str(e))
|
|
160
|
+
self._short_term = None
|
|
161
|
+
self._redis_status = RedisStatus(
|
|
162
|
+
available=False,
|
|
163
|
+
method=RedisStartMethod.MOCK,
|
|
164
|
+
message=f"Failed to initialize: {e}",
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
# Initialize long-term memory (SecureMemDocs)
|
|
168
|
+
try:
|
|
169
|
+
claude_config = ClaudeMemoryConfig(
|
|
170
|
+
enabled=self.config.claude_memory_enabled,
|
|
171
|
+
load_enterprise=self.config.load_enterprise_memory,
|
|
172
|
+
load_project=self.config.load_project_memory,
|
|
173
|
+
load_user=self.config.load_user_memory,
|
|
174
|
+
)
|
|
175
|
+
self._long_term = SecureMemDocsIntegration(
|
|
176
|
+
claude_memory_config=claude_config,
|
|
177
|
+
storage_dir=self.config.storage_dir,
|
|
178
|
+
enable_encryption=self.config.encryption_enabled,
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
logger.info(
|
|
182
|
+
"long_term_memory_initialized",
|
|
183
|
+
storage_dir=self.config.storage_dir,
|
|
184
|
+
encryption=self.config.encryption_enabled,
|
|
185
|
+
)
|
|
186
|
+
except Exception as e:
|
|
187
|
+
logger.error("long_term_memory_failed", error=str(e))
|
|
188
|
+
self._long_term = None
|
|
189
|
+
|
|
190
|
+
# Initialize simple long-term memory (for testing and simple use cases)
|
|
191
|
+
try:
|
|
192
|
+
self._simple_long_term = LongTermMemory(storage_path=self.config.storage_dir)
|
|
193
|
+
logger.debug("simple_long_term_memory_initialized")
|
|
194
|
+
except Exception as e:
|
|
195
|
+
logger.error("simple_long_term_memory_failed", error=str(e))
|
|
196
|
+
self._simple_long_term = None
|
|
197
|
+
|
|
198
|
+
self._initialized = True
|
|
199
|
+
|
|
200
|
+
def get_backend_status(self) -> dict[str, Any]:
|
|
201
|
+
"""Get the current status of all memory backends.
|
|
202
|
+
|
|
203
|
+
Returns a structured dict suitable for health checks, debugging,
|
|
204
|
+
and dashboard display. Can be serialized to JSON.
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
dict with keys:
|
|
208
|
+
- environment: Current environment (development/staging/production)
|
|
209
|
+
- short_term: Status of Redis-based short-term memory
|
|
210
|
+
- long_term: Status of persistent long-term memory
|
|
211
|
+
- initialized: Whether backends have been initialized
|
|
212
|
+
|
|
213
|
+
Example:
|
|
214
|
+
>>> memory = UnifiedMemory(user_id="agent")
|
|
215
|
+
>>> status = memory.get_backend_status()
|
|
216
|
+
>>> print(status["short_term"]["available"])
|
|
217
|
+
True
|
|
218
|
+
|
|
219
|
+
"""
|
|
220
|
+
from ..redis_bootstrap import RedisStartMethod
|
|
221
|
+
|
|
222
|
+
short_term_status: dict[str, Any] = {
|
|
223
|
+
"available": False,
|
|
224
|
+
"mock": True,
|
|
225
|
+
"method": "unknown",
|
|
226
|
+
"message": "Not initialized",
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if self._redis_status:
|
|
230
|
+
short_term_status = {
|
|
231
|
+
"available": self._redis_status.available,
|
|
232
|
+
"mock": not self._redis_status.available
|
|
233
|
+
or self._redis_status.method == RedisStartMethod.MOCK,
|
|
234
|
+
"method": self._redis_status.method.value,
|
|
235
|
+
"message": self._redis_status.message,
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
long_term_status: dict[str, Any] = {
|
|
239
|
+
"available": self._long_term is not None,
|
|
240
|
+
"storage_dir": self.config.storage_dir,
|
|
241
|
+
"encryption_enabled": self.config.encryption_enabled,
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return {
|
|
245
|
+
"environment": self.config.environment.value,
|
|
246
|
+
"initialized": self._initialized,
|
|
247
|
+
"short_term": short_term_status,
|
|
248
|
+
"long_term": long_term_status,
|
|
249
|
+
}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"""Capabilities and health check mixin for UnifiedMemory.
|
|
2
|
+
|
|
3
|
+
Provides backend availability checks, health monitoring, and feature detection.
|
|
4
|
+
|
|
5
|
+
Copyright 2025 Smart AI Memory, LLC
|
|
6
|
+
Licensed under Fair Source 0.9
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import TYPE_CHECKING, Any
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from ..file_session import FileSessionMemory
|
|
13
|
+
from ..long_term import LongTermMemory
|
|
14
|
+
from ..redis_bootstrap import RedisStatus
|
|
15
|
+
from ..short_term import RedisShortTermMemory
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class CapabilitiesMixin:
|
|
19
|
+
"""Mixin providing capability detection and health checks for UnifiedMemory."""
|
|
20
|
+
|
|
21
|
+
# Type hints for attributes that will be provided by UnifiedMemory
|
|
22
|
+
_file_session: "FileSessionMemory | None"
|
|
23
|
+
_short_term: "RedisShortTermMemory | None"
|
|
24
|
+
_long_term: Any # SecureMemDocsIntegration
|
|
25
|
+
_simple_long_term: "LongTermMemory | None"
|
|
26
|
+
_redis_status: "RedisStatus | None"
|
|
27
|
+
config: Any # MemoryConfig
|
|
28
|
+
|
|
29
|
+
# =========================================================================
|
|
30
|
+
# BACKEND AVAILABILITY CHECKS
|
|
31
|
+
# =========================================================================
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def has_short_term(self) -> bool:
|
|
35
|
+
"""Check if short-term memory is available."""
|
|
36
|
+
return self._short_term is not None
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def has_long_term(self) -> bool:
|
|
40
|
+
"""Check if long-term memory is available."""
|
|
41
|
+
return self._long_term is not None
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def redis_status(self) -> "RedisStatus | None":
|
|
45
|
+
"""Get Redis connection status."""
|
|
46
|
+
return self._redis_status
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def using_real_redis(self) -> bool:
|
|
50
|
+
"""Check if using real Redis (not mock)."""
|
|
51
|
+
from ..redis_bootstrap import RedisStartMethod
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
self._redis_status is not None
|
|
55
|
+
and self._redis_status.available
|
|
56
|
+
and self._redis_status.method != RedisStartMethod.MOCK
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def short_term(self) -> "RedisShortTermMemory":
|
|
61
|
+
"""Get short-term memory backend for direct access (testing).
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
RedisShortTermMemory instance
|
|
65
|
+
|
|
66
|
+
Raises:
|
|
67
|
+
RuntimeError: If short-term memory is not initialized
|
|
68
|
+
|
|
69
|
+
"""
|
|
70
|
+
if self._short_term is None:
|
|
71
|
+
raise RuntimeError(
|
|
72
|
+
"Short-term memory not initialized. "
|
|
73
|
+
"Ensure Redis is running and UnifiedMemory was initialized with Redis enabled."
|
|
74
|
+
)
|
|
75
|
+
return self._short_term
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def long_term(self) -> "LongTermMemory":
|
|
79
|
+
"""Get simple long-term memory backend for direct access (testing).
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
LongTermMemory instance
|
|
83
|
+
|
|
84
|
+
Raises:
|
|
85
|
+
RuntimeError: If long-term memory is not initialized
|
|
86
|
+
|
|
87
|
+
Note:
|
|
88
|
+
For production use with security features (PII scrubbing, encryption),
|
|
89
|
+
use persist_pattern() and recall_pattern() methods instead.
|
|
90
|
+
|
|
91
|
+
"""
|
|
92
|
+
if self._simple_long_term is None:
|
|
93
|
+
raise RuntimeError(
|
|
94
|
+
"Long-term memory not initialized. "
|
|
95
|
+
"Ensure UnifiedMemory was initialized with long_term_enabled=True."
|
|
96
|
+
)
|
|
97
|
+
return self._simple_long_term
|
|
98
|
+
|
|
99
|
+
# =========================================================================
|
|
100
|
+
# HEALTH CHECKS
|
|
101
|
+
# =========================================================================
|
|
102
|
+
|
|
103
|
+
def health_check(self) -> dict[str, Any]:
|
|
104
|
+
"""Check health of memory backends.
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
Status of each memory backend
|
|
108
|
+
|
|
109
|
+
"""
|
|
110
|
+
redis_info: dict[str, Any] = {
|
|
111
|
+
"available": self.has_short_term,
|
|
112
|
+
"mock_mode": not self.using_real_redis,
|
|
113
|
+
}
|
|
114
|
+
if self._redis_status:
|
|
115
|
+
redis_info["method"] = self._redis_status.method.value
|
|
116
|
+
redis_info["host"] = self._redis_status.host
|
|
117
|
+
redis_info["port"] = self._redis_status.port
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
"file_session": {
|
|
121
|
+
"available": self._file_session is not None,
|
|
122
|
+
"session_id": self._file_session._state.session_id if self._file_session else None,
|
|
123
|
+
"base_dir": self.config.file_session_dir,
|
|
124
|
+
},
|
|
125
|
+
"short_term": redis_info,
|
|
126
|
+
"long_term": {
|
|
127
|
+
"available": self.has_long_term,
|
|
128
|
+
"storage_dir": self.config.storage_dir,
|
|
129
|
+
"encryption": self.config.encryption_enabled,
|
|
130
|
+
},
|
|
131
|
+
"environment": self.config.environment.value,
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
# =========================================================================
|
|
135
|
+
# CAPABILITY DETECTION (File-First Architecture)
|
|
136
|
+
# =========================================================================
|
|
137
|
+
|
|
138
|
+
@property
|
|
139
|
+
def has_file_session(self) -> bool:
|
|
140
|
+
"""Check if file-based session memory is available (always True if enabled)."""
|
|
141
|
+
return self._file_session is not None
|
|
142
|
+
|
|
143
|
+
@property
|
|
144
|
+
def file_session(self) -> "FileSessionMemory":
|
|
145
|
+
"""Get file session memory backend for direct access.
|
|
146
|
+
|
|
147
|
+
Returns:
|
|
148
|
+
FileSessionMemory instance
|
|
149
|
+
|
|
150
|
+
Raises:
|
|
151
|
+
RuntimeError: If file session memory is not initialized
|
|
152
|
+
"""
|
|
153
|
+
if self._file_session is None:
|
|
154
|
+
raise RuntimeError(
|
|
155
|
+
"File session memory not initialized. "
|
|
156
|
+
"File session tracking is automatically enabled when UnifiedMemory is initialized."
|
|
157
|
+
)
|
|
158
|
+
return self._file_session
|
|
159
|
+
|
|
160
|
+
def supports_realtime(self) -> bool:
|
|
161
|
+
"""Check if real-time features are available (requires Redis).
|
|
162
|
+
|
|
163
|
+
Real-time features include:
|
|
164
|
+
- Pub/Sub messaging between agents
|
|
165
|
+
- Cross-session coordination
|
|
166
|
+
- Distributed task queues
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
True if Redis is available and connected
|
|
170
|
+
"""
|
|
171
|
+
return self.using_real_redis
|
|
172
|
+
|
|
173
|
+
def supports_distributed(self) -> bool:
|
|
174
|
+
"""Check if distributed features are available (requires Redis).
|
|
175
|
+
|
|
176
|
+
Distributed features include:
|
|
177
|
+
- Multi-process coordination
|
|
178
|
+
- Cross-session state sharing
|
|
179
|
+
- Agent discovery
|
|
180
|
+
|
|
181
|
+
Returns:
|
|
182
|
+
True if Redis is available and connected
|
|
183
|
+
"""
|
|
184
|
+
return self.using_real_redis
|
|
185
|
+
|
|
186
|
+
def supports_persistence(self) -> bool:
|
|
187
|
+
"""Check if persistence is available (always True with file-first).
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
True if file session or long-term memory is available
|
|
191
|
+
"""
|
|
192
|
+
return self._file_session is not None or self._long_term is not None
|
|
193
|
+
|
|
194
|
+
def get_capabilities(self) -> dict[str, bool]:
|
|
195
|
+
"""Get a summary of available memory capabilities.
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
Dictionary mapping capability names to availability
|
|
199
|
+
"""
|
|
200
|
+
return {
|
|
201
|
+
"file_session": self.has_file_session,
|
|
202
|
+
"redis": self.using_real_redis,
|
|
203
|
+
"long_term": self.has_long_term,
|
|
204
|
+
"persistence": self.supports_persistence(),
|
|
205
|
+
"realtime": self.supports_realtime(),
|
|
206
|
+
"distributed": self.supports_distributed(),
|
|
207
|
+
"encryption": self.config.encryption_enabled and self.has_long_term,
|
|
208
|
+
}
|