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/trust_building.py
ADDED
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
"""Trust-Building Behaviors for Anticipatory AI Agents
|
|
2
|
+
|
|
3
|
+
Implements behaviors that build trust through anticipatory actions:
|
|
4
|
+
- Pre-format data for handoffs (reduce cognitive load)
|
|
5
|
+
- Clarify ambiguous instructions before execution (prevent wasted effort)
|
|
6
|
+
- Volunteer structure during stress (actual scaffolding, not pep talks)
|
|
7
|
+
- Proactively offer help when collaborators are struggling
|
|
8
|
+
|
|
9
|
+
These behaviors demonstrate Level 4 Anticipatory Empathy by:
|
|
10
|
+
1. Predicting friction points (handoffs, confusion, stress, overload)
|
|
11
|
+
2. Acting without being asked (but without overstepping)
|
|
12
|
+
3. Providing structural relief (not just emotional support)
|
|
13
|
+
4. Building trust through consistent, helpful actions
|
|
14
|
+
|
|
15
|
+
Based on trust-building patterns from ai-nurse-florence.
|
|
16
|
+
|
|
17
|
+
Copyright 2025 Smart AI Memory, LLC
|
|
18
|
+
Licensed under Fair Source 0.9
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import logging
|
|
22
|
+
from dataclasses import dataclass, field
|
|
23
|
+
from datetime import datetime
|
|
24
|
+
from typing import Any
|
|
25
|
+
|
|
26
|
+
logger = logging.getLogger(__name__)
|
|
27
|
+
|
|
28
|
+
# Role categories for O(1) lookups
|
|
29
|
+
EXECUTIVE_ROLES = frozenset({"executive", "ceo", "cto", "manager", "director", "vp"})
|
|
30
|
+
TECHNICAL_ROLES = frozenset({"developer", "engineer", "architect", "devops", "sre"})
|
|
31
|
+
COORDINATION_ROLES = frozenset({"team_lead", "project_manager", "scrum_master", "coordinator"})
|
|
32
|
+
|
|
33
|
+
# Stress level categories
|
|
34
|
+
HIGH_STRESS_LEVELS = frozenset({"critical", "high", "severe"})
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclass
|
|
38
|
+
class TrustSignal:
|
|
39
|
+
"""A signal that indicates trust is building or eroding
|
|
40
|
+
|
|
41
|
+
Trust signals help track how trust evolves over time based on
|
|
42
|
+
observable behaviors and outcomes.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
signal_type: str # "building" or "eroding"
|
|
46
|
+
behavior: str
|
|
47
|
+
timestamp: datetime = field(default_factory=datetime.now)
|
|
48
|
+
evidence: str | None = None
|
|
49
|
+
impact: float = 0.5 # 0.0-1.0, magnitude of impact
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class TrustBuildingBehaviors:
|
|
53
|
+
"""Level 4 Anticipatory trust-building behaviors
|
|
54
|
+
|
|
55
|
+
Philosophy: Trust is earned through consistent, helpful actions that
|
|
56
|
+
demonstrate understanding of collaboration dynamics and proactive
|
|
57
|
+
problem-solving.
|
|
58
|
+
|
|
59
|
+
**Core Principle**: Reduce cognitive load through anticipation
|
|
60
|
+
|
|
61
|
+
**Key Behaviors:**
|
|
62
|
+
1. Pre-format data for handoffs
|
|
63
|
+
2. Clarify ambiguous instructions before acting
|
|
64
|
+
3. Volunteer structure during stress
|
|
65
|
+
4. Offer help proactively when needed
|
|
66
|
+
|
|
67
|
+
Example:
|
|
68
|
+
>>> behaviors = TrustBuildingBehaviors()
|
|
69
|
+
>>>
|
|
70
|
+
>>> # Pre-format data for handoff
|
|
71
|
+
>>> data = {"items": [...], "total": 42}
|
|
72
|
+
>>> formatted = behaviors.pre_format_for_handoff(
|
|
73
|
+
... data=data,
|
|
74
|
+
... recipient_role="manager",
|
|
75
|
+
... context="quarterly_review"
|
|
76
|
+
... )
|
|
77
|
+
>>>
|
|
78
|
+
>>> # Clarify ambiguous instruction
|
|
79
|
+
>>> instruction = "Update the system"
|
|
80
|
+
>>> clarified = behaviors.clarify_before_acting(
|
|
81
|
+
... instruction=instruction,
|
|
82
|
+
... ambiguities=["which system?", "what changes?"]
|
|
83
|
+
... )
|
|
84
|
+
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
def __init__(self):
|
|
88
|
+
"""Initialize TrustBuildingBehaviors"""
|
|
89
|
+
self.trust_signals: list[TrustSignal] = []
|
|
90
|
+
|
|
91
|
+
def pre_format_for_handoff(
|
|
92
|
+
self,
|
|
93
|
+
data: dict[str, Any],
|
|
94
|
+
recipient_role: str,
|
|
95
|
+
context: str,
|
|
96
|
+
) -> dict[str, Any]:
|
|
97
|
+
"""Pre-format data for handoff to reduce recipient's cognitive load
|
|
98
|
+
|
|
99
|
+
**Trust Built:**
|
|
100
|
+
- "This AI understands my workflow"
|
|
101
|
+
- "I don't have to translate data myself"
|
|
102
|
+
- "My time is valued"
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
data: Raw data to be handed off
|
|
106
|
+
recipient_role: Role of the person receiving the data
|
|
107
|
+
context: Context of the handoff (e.g., "meeting_prep", "report")
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
Formatted data optimized for recipient's workflow
|
|
111
|
+
|
|
112
|
+
Example:
|
|
113
|
+
>>> data = {"tasks": [...], "metrics": {...}}
|
|
114
|
+
>>> formatted = behaviors.pre_format_for_handoff(
|
|
115
|
+
... data=data,
|
|
116
|
+
... recipient_role="executive",
|
|
117
|
+
... context="board_meeting"
|
|
118
|
+
... )
|
|
119
|
+
>>> # Returns: executive summary format with key highlights
|
|
120
|
+
|
|
121
|
+
"""
|
|
122
|
+
logger.info(f"Pre-formatting data for handoff to {recipient_role} (context: {context})")
|
|
123
|
+
|
|
124
|
+
formatted = {
|
|
125
|
+
"original_data": data,
|
|
126
|
+
"format": self._determine_format(recipient_role, context),
|
|
127
|
+
"timestamp": datetime.now().isoformat(),
|
|
128
|
+
"reasoning": f"Pre-formatted for {recipient_role} workflow",
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
# Format based on recipient role and context (O(1) set lookups)
|
|
132
|
+
if recipient_role in EXECUTIVE_ROLES:
|
|
133
|
+
formatted["summary"] = self._create_executive_summary(data, context)
|
|
134
|
+
|
|
135
|
+
elif recipient_role in TECHNICAL_ROLES:
|
|
136
|
+
formatted["summary"] = self._create_technical_summary(data, context)
|
|
137
|
+
|
|
138
|
+
elif recipient_role in COORDINATION_ROLES:
|
|
139
|
+
formatted["summary"] = self._create_action_oriented_summary(data, context)
|
|
140
|
+
|
|
141
|
+
else:
|
|
142
|
+
# Generic format for unknown roles
|
|
143
|
+
formatted["summary"] = self._create_generic_summary(data, context)
|
|
144
|
+
|
|
145
|
+
# Record trust signal
|
|
146
|
+
self._record_trust_signal(
|
|
147
|
+
signal_type="building",
|
|
148
|
+
behavior="pre_format_handoff",
|
|
149
|
+
evidence=f"Formatted data for {recipient_role}",
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
return formatted
|
|
153
|
+
|
|
154
|
+
def clarify_before_acting(
|
|
155
|
+
self,
|
|
156
|
+
instruction: str,
|
|
157
|
+
detected_ambiguities: list[str],
|
|
158
|
+
context: dict[str, Any] | None = None,
|
|
159
|
+
) -> dict[str, Any]:
|
|
160
|
+
"""Clarify ambiguous instructions before execution to prevent wasted effort
|
|
161
|
+
|
|
162
|
+
**Trust Built:**
|
|
163
|
+
- "This AI doesn't make dangerous assumptions"
|
|
164
|
+
- "It asks when uncertain (intelligent caution)"
|
|
165
|
+
- "My intent is understood, not just command followed"
|
|
166
|
+
|
|
167
|
+
Args:
|
|
168
|
+
instruction: The instruction received
|
|
169
|
+
detected_ambiguities: List of ambiguous aspects
|
|
170
|
+
context: Optional additional context
|
|
171
|
+
|
|
172
|
+
Returns:
|
|
173
|
+
Clarification request with specific questions
|
|
174
|
+
|
|
175
|
+
Example:
|
|
176
|
+
>>> instruction = "Deploy the changes"
|
|
177
|
+
>>> ambiguities = ["which environment?", "which changes?", "when?"]
|
|
178
|
+
>>> clarification = behaviors.clarify_before_acting(
|
|
179
|
+
... instruction=instruction,
|
|
180
|
+
... detected_ambiguities=ambiguities
|
|
181
|
+
... )
|
|
182
|
+
|
|
183
|
+
"""
|
|
184
|
+
logger.info(f"Clarifying ambiguous instruction: {instruction}")
|
|
185
|
+
|
|
186
|
+
clarifying_questions: list[dict[str, str]] = []
|
|
187
|
+
clarification: dict[str, Any] = {
|
|
188
|
+
"original_instruction": instruction,
|
|
189
|
+
"status": "needs_clarification",
|
|
190
|
+
"ambiguities_detected": detected_ambiguities,
|
|
191
|
+
"clarifying_questions": clarifying_questions,
|
|
192
|
+
"reasoning": (
|
|
193
|
+
"Detected ambiguities in instruction. Clarifying before acting "
|
|
194
|
+
"to prevent wasted effort or incorrect execution."
|
|
195
|
+
),
|
|
196
|
+
"timestamp": datetime.now().isoformat(),
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
# Generate specific clarifying questions
|
|
200
|
+
for ambiguity in detected_ambiguities:
|
|
201
|
+
question = self._generate_clarifying_question(instruction, ambiguity, context)
|
|
202
|
+
clarifying_questions.append(question)
|
|
203
|
+
|
|
204
|
+
# Record trust signal
|
|
205
|
+
self._record_trust_signal(
|
|
206
|
+
signal_type="building",
|
|
207
|
+
behavior="clarify_ambiguity",
|
|
208
|
+
evidence=f"Asked for clarification on {len(detected_ambiguities)} ambiguities",
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
return clarification
|
|
212
|
+
|
|
213
|
+
def volunteer_structure_during_stress(
|
|
214
|
+
self,
|
|
215
|
+
stress_indicators: dict[str, Any],
|
|
216
|
+
available_scaffolding: list[str],
|
|
217
|
+
) -> dict[str, Any]:
|
|
218
|
+
"""Volunteer structure/scaffolding during stressful situations
|
|
219
|
+
|
|
220
|
+
**Not pep talks, actual structural help:**
|
|
221
|
+
- Break down overwhelming tasks
|
|
222
|
+
- Provide templates
|
|
223
|
+
- Create checklists
|
|
224
|
+
- Suggest prioritization frameworks
|
|
225
|
+
|
|
226
|
+
**Trust Built:**
|
|
227
|
+
- "This AI provides real help, not platitudes"
|
|
228
|
+
- "It understands when I'm overwhelmed"
|
|
229
|
+
- "It offers structure, not just encouragement"
|
|
230
|
+
|
|
231
|
+
Args:
|
|
232
|
+
stress_indicators: Dict of detected stress signals
|
|
233
|
+
available_scaffolding: List of support types available
|
|
234
|
+
|
|
235
|
+
Returns:
|
|
236
|
+
Structured support offer
|
|
237
|
+
|
|
238
|
+
Example:
|
|
239
|
+
>>> stress = {"task_count": 15, "deadline_proximity": "24h"}
|
|
240
|
+
>>> scaffolding = ["prioritization", "templates", "breakdown"]
|
|
241
|
+
>>> support = behaviors.volunteer_structure_during_stress(
|
|
242
|
+
... stress_indicators=stress,
|
|
243
|
+
... available_scaffolding=scaffolding
|
|
244
|
+
... )
|
|
245
|
+
|
|
246
|
+
"""
|
|
247
|
+
logger.info("Volunteering structure during detected stress")
|
|
248
|
+
|
|
249
|
+
stress_level = self._assess_stress_level(stress_indicators)
|
|
250
|
+
|
|
251
|
+
offered_support: list[dict[str, Any]] = []
|
|
252
|
+
support: dict[str, Any] = {
|
|
253
|
+
"stress_assessment": {"level": stress_level, "indicators": stress_indicators},
|
|
254
|
+
"offered_support": offered_support,
|
|
255
|
+
"reasoning": (
|
|
256
|
+
f"Detected {stress_level} stress. Volunteering structural support "
|
|
257
|
+
"to reduce cognitive load and provide actionable scaffolding."
|
|
258
|
+
),
|
|
259
|
+
"timestamp": datetime.now().isoformat(),
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
# Offer appropriate scaffolding based on stress level
|
|
263
|
+
if stress_level in HIGH_STRESS_LEVELS:
|
|
264
|
+
if "prioritization" in available_scaffolding:
|
|
265
|
+
offered_support.append(
|
|
266
|
+
{
|
|
267
|
+
"type": "prioritization",
|
|
268
|
+
"description": "Help prioritize tasks using urgency-importance matrix",
|
|
269
|
+
"immediate": True,
|
|
270
|
+
},
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
if "breakdown" in available_scaffolding:
|
|
274
|
+
offered_support.append(
|
|
275
|
+
{
|
|
276
|
+
"type": "task_breakdown",
|
|
277
|
+
"description": "Break overwhelming tasks into smaller, manageable steps",
|
|
278
|
+
"immediate": True,
|
|
279
|
+
},
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
if "templates" in available_scaffolding:
|
|
283
|
+
offered_support.append(
|
|
284
|
+
{
|
|
285
|
+
"type": "templates",
|
|
286
|
+
"description": "Provide templates to reduce creation effort",
|
|
287
|
+
"immediate": False,
|
|
288
|
+
},
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
# Record trust signal
|
|
292
|
+
self._record_trust_signal(
|
|
293
|
+
signal_type="building",
|
|
294
|
+
behavior="volunteer_structure",
|
|
295
|
+
evidence=f"Offered {len(support['offered_support'])} types of structural support",
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
return support
|
|
299
|
+
|
|
300
|
+
def offer_proactive_help(
|
|
301
|
+
self,
|
|
302
|
+
struggle_indicators: dict[str, Any],
|
|
303
|
+
available_help: list[str],
|
|
304
|
+
) -> dict[str, Any]:
|
|
305
|
+
"""Proactively offer help when collaborator is struggling
|
|
306
|
+
|
|
307
|
+
**Trust Built:**
|
|
308
|
+
- "This AI notices when I'm stuck"
|
|
309
|
+
- "It offers help without waiting to be asked"
|
|
310
|
+
- "It doesn't overstep, but is ready to assist"
|
|
311
|
+
|
|
312
|
+
Args:
|
|
313
|
+
struggle_indicators: Signals that someone is struggling
|
|
314
|
+
available_help: Types of help available
|
|
315
|
+
|
|
316
|
+
Returns:
|
|
317
|
+
Help offer tailored to situation
|
|
318
|
+
|
|
319
|
+
Example:
|
|
320
|
+
>>> indicators = {"repeated_errors": 3, "time_on_task": 45}
|
|
321
|
+
>>> help_types = ["debugging", "explanation", "examples"]
|
|
322
|
+
>>> offer = behaviors.offer_proactive_help(
|
|
323
|
+
... struggle_indicators=indicators,
|
|
324
|
+
... available_help=help_types
|
|
325
|
+
... )
|
|
326
|
+
|
|
327
|
+
"""
|
|
328
|
+
logger.info("Offering proactive help based on struggle indicators")
|
|
329
|
+
|
|
330
|
+
struggle_type = self._classify_struggle(struggle_indicators)
|
|
331
|
+
|
|
332
|
+
help_offered: list[dict[str, str]] = []
|
|
333
|
+
offer: dict[str, Any] = {
|
|
334
|
+
"struggle_assessment": {"type": struggle_type, "indicators": struggle_indicators},
|
|
335
|
+
"help_offered": help_offered,
|
|
336
|
+
"tone": "supportive_not_condescending",
|
|
337
|
+
"reasoning": (
|
|
338
|
+
f"Detected {struggle_type} struggle pattern. Offering relevant help "
|
|
339
|
+
"proactively while respecting autonomy."
|
|
340
|
+
),
|
|
341
|
+
"timestamp": datetime.now().isoformat(),
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
# Offer appropriate help based on struggle type
|
|
345
|
+
if struggle_type == "comprehension":
|
|
346
|
+
if "explanation" in available_help:
|
|
347
|
+
help_offered.append(
|
|
348
|
+
{
|
|
349
|
+
"type": "explanation",
|
|
350
|
+
"description": "Provide clearer explanation of concept",
|
|
351
|
+
},
|
|
352
|
+
)
|
|
353
|
+
if "examples" in available_help:
|
|
354
|
+
help_offered.append({"type": "examples", "description": "Show concrete examples"})
|
|
355
|
+
|
|
356
|
+
elif struggle_type == "execution":
|
|
357
|
+
if "debugging" in available_help:
|
|
358
|
+
help_offered.append({"type": "debugging", "description": "Help debug the issue"})
|
|
359
|
+
if "guidance" in available_help:
|
|
360
|
+
help_offered.append(
|
|
361
|
+
{"type": "step_by_step", "description": "Provide step-by-step guidance"},
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
# Record trust signal
|
|
365
|
+
self._record_trust_signal(
|
|
366
|
+
signal_type="building",
|
|
367
|
+
behavior="proactive_help",
|
|
368
|
+
evidence=f"Offered help for {struggle_type} struggle",
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
return offer
|
|
372
|
+
|
|
373
|
+
def get_trust_trajectory(self) -> dict[str, Any]:
|
|
374
|
+
"""Get trust trajectory based on recorded signals
|
|
375
|
+
|
|
376
|
+
Returns:
|
|
377
|
+
Analysis of trust evolution over time
|
|
378
|
+
|
|
379
|
+
"""
|
|
380
|
+
if not self.trust_signals:
|
|
381
|
+
return {"status": "insufficient_data", "trajectory": "unknown", "signal_count": 0}
|
|
382
|
+
|
|
383
|
+
building_count = sum(1 for s in self.trust_signals if s.signal_type == "building")
|
|
384
|
+
eroding_count = sum(1 for s in self.trust_signals if s.signal_type == "eroding")
|
|
385
|
+
|
|
386
|
+
total = len(self.trust_signals)
|
|
387
|
+
building_ratio = building_count / total if total > 0 else 0
|
|
388
|
+
|
|
389
|
+
if building_ratio > 0.7:
|
|
390
|
+
trajectory = "strongly_building"
|
|
391
|
+
elif building_ratio > 0.5:
|
|
392
|
+
trajectory = "building"
|
|
393
|
+
elif building_ratio > 0.3:
|
|
394
|
+
trajectory = "mixed"
|
|
395
|
+
else:
|
|
396
|
+
trajectory = "eroding"
|
|
397
|
+
|
|
398
|
+
return {
|
|
399
|
+
"status": "active",
|
|
400
|
+
"trajectory": trajectory,
|
|
401
|
+
"signal_count": total,
|
|
402
|
+
"building_signals": building_count,
|
|
403
|
+
"eroding_signals": eroding_count,
|
|
404
|
+
"building_ratio": building_ratio,
|
|
405
|
+
"recent_behaviors": [s.behavior for s in self.trust_signals[-5:]],
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
# Helper methods
|
|
409
|
+
|
|
410
|
+
def _determine_format(self, role: str, context: str) -> str:
|
|
411
|
+
"""Determine appropriate format based on role and context"""
|
|
412
|
+
if role in ["executive", "manager", "director"]:
|
|
413
|
+
return "executive_summary"
|
|
414
|
+
if role in ["developer", "engineer", "analyst"]:
|
|
415
|
+
return "technical_detail"
|
|
416
|
+
if role in ["team_lead", "coordinator"]:
|
|
417
|
+
return "action_oriented"
|
|
418
|
+
return "general"
|
|
419
|
+
|
|
420
|
+
def _create_executive_summary(self, data: dict, context: str) -> dict:
|
|
421
|
+
"""Create executive summary format"""
|
|
422
|
+
return {
|
|
423
|
+
"type": "executive_summary",
|
|
424
|
+
"key_metrics": self._extract_key_metrics(data),
|
|
425
|
+
"highlights": self._extract_highlights(data),
|
|
426
|
+
"recommendations": self._extract_recommendations(data),
|
|
427
|
+
"context": context,
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
def _create_technical_summary(self, data: dict, context: str) -> dict:
|
|
431
|
+
"""Create technical summary format"""
|
|
432
|
+
return {
|
|
433
|
+
"type": "technical_detail",
|
|
434
|
+
"details": data,
|
|
435
|
+
"technical_notes": self._extract_technical_notes(data),
|
|
436
|
+
"context": context,
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
def _create_action_oriented_summary(self, data: dict, context: str) -> dict:
|
|
440
|
+
"""Create action-oriented summary format"""
|
|
441
|
+
return {
|
|
442
|
+
"type": "action_oriented",
|
|
443
|
+
"immediate_actions": self._extract_immediate_actions(data),
|
|
444
|
+
"priorities": self._extract_priorities(data),
|
|
445
|
+
"context": context,
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
def _create_generic_summary(self, data: dict, context: str) -> dict:
|
|
449
|
+
"""Create generic summary format"""
|
|
450
|
+
return {"type": "general", "summary": str(data), "context": context}
|
|
451
|
+
|
|
452
|
+
def _extract_key_metrics(self, data: dict) -> list[str]:
|
|
453
|
+
"""Extract key metrics from data"""
|
|
454
|
+
metrics = []
|
|
455
|
+
for key, value in data.items():
|
|
456
|
+
if isinstance(value, int | float):
|
|
457
|
+
metrics.append(f"{key}: {value}")
|
|
458
|
+
return metrics[:5] # Top 5 metrics
|
|
459
|
+
|
|
460
|
+
def _extract_highlights(self, data: dict) -> list[str]:
|
|
461
|
+
"""Extract highlights from data"""
|
|
462
|
+
return [f"Data contains {len(data)} fields"]
|
|
463
|
+
|
|
464
|
+
def _extract_recommendations(self, data: dict) -> list[str]:
|
|
465
|
+
"""Extract recommendations from data"""
|
|
466
|
+
return ["Review detailed data for full context"]
|
|
467
|
+
|
|
468
|
+
def _extract_technical_notes(self, data: dict) -> list[str]:
|
|
469
|
+
"""Extract technical notes"""
|
|
470
|
+
return [f"Data structure: {type(data).__name__}"]
|
|
471
|
+
|
|
472
|
+
def _extract_immediate_actions(self, data: dict[str, Any]) -> list[str]:
|
|
473
|
+
"""Extract immediate actions"""
|
|
474
|
+
if "actions" in data:
|
|
475
|
+
actions: list[str] = data["actions"][:5]
|
|
476
|
+
return actions
|
|
477
|
+
return ["Review data and determine next steps"]
|
|
478
|
+
|
|
479
|
+
def _extract_priorities(self, data: dict[str, Any]) -> list[str]:
|
|
480
|
+
"""Extract priorities"""
|
|
481
|
+
if "priorities" in data:
|
|
482
|
+
priorities: list[str] = data["priorities"]
|
|
483
|
+
return priorities
|
|
484
|
+
return []
|
|
485
|
+
|
|
486
|
+
def _generate_clarifying_question(
|
|
487
|
+
self,
|
|
488
|
+
instruction: str,
|
|
489
|
+
ambiguity: str,
|
|
490
|
+
context: dict | None,
|
|
491
|
+
) -> dict[str, str]:
|
|
492
|
+
"""Generate a specific clarifying question"""
|
|
493
|
+
return {
|
|
494
|
+
"ambiguity": ambiguity,
|
|
495
|
+
"question": f"Could you clarify: {ambiguity}",
|
|
496
|
+
"context": str(context) if context else "none",
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
def _assess_stress_level(self, indicators: dict) -> str:
|
|
500
|
+
"""Assess stress level from indicators"""
|
|
501
|
+
# Simple heuristic: count stress indicators
|
|
502
|
+
stress_score = len(indicators)
|
|
503
|
+
|
|
504
|
+
if stress_score >= 4:
|
|
505
|
+
return "critical"
|
|
506
|
+
if stress_score >= 3:
|
|
507
|
+
return "high"
|
|
508
|
+
if stress_score >= 2:
|
|
509
|
+
return "moderate"
|
|
510
|
+
return "low"
|
|
511
|
+
|
|
512
|
+
def _classify_struggle(self, indicators: dict) -> str:
|
|
513
|
+
"""Classify type of struggle"""
|
|
514
|
+
if "repeated_errors" in indicators:
|
|
515
|
+
return "execution"
|
|
516
|
+
if "time_on_task" in indicators:
|
|
517
|
+
return "comprehension"
|
|
518
|
+
return "general"
|
|
519
|
+
|
|
520
|
+
def _record_trust_signal(self, signal_type: str, behavior: str, evidence: str | None = None):
|
|
521
|
+
"""Record a trust signal"""
|
|
522
|
+
signal = TrustSignal(signal_type=signal_type, behavior=behavior, evidence=evidence)
|
|
523
|
+
self.trust_signals.append(signal)
|
|
524
|
+
|
|
525
|
+
def reset(self):
|
|
526
|
+
"""Reset trust tracking"""
|
|
527
|
+
self.trust_signals = []
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""XML validation for XML-enhanced prompts.
|
|
2
|
+
|
|
3
|
+
Provides schema validation and graceful fallbacks.
|
|
4
|
+
|
|
5
|
+
Copyright 2026 Smart-AI-Memory
|
|
6
|
+
Licensed under Fair Source License 0.9
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from attune.validation.xml_validator import (
|
|
10
|
+
ValidationResult,
|
|
11
|
+
XMLValidator,
|
|
12
|
+
validate_xml_response,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"XMLValidator",
|
|
17
|
+
"ValidationResult",
|
|
18
|
+
"validate_xml_response",
|
|
19
|
+
]
|