ciris-agent 1.7.7__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.
- ciris_adapters/README.md +113 -0
- ciris_adapters/__init__.py +30 -0
- ciris_adapters/ciris_covenant_metrics/README.md +144 -0
- ciris_adapters/ciris_covenant_metrics/__init__.py +36 -0
- ciris_adapters/ciris_covenant_metrics/adapter.py +249 -0
- ciris_adapters/ciris_covenant_metrics/manifest.json +152 -0
- ciris_adapters/ciris_covenant_metrics/services.py +403 -0
- ciris_adapters/ciris_hosted_tools/__init__.py +24 -0
- ciris_adapters/ciris_hosted_tools/adapter.py +169 -0
- ciris_adapters/ciris_hosted_tools/manifest.json +94 -0
- ciris_adapters/ciris_hosted_tools/services.py +744 -0
- ciris_adapters/external_data_sql/README.md +559 -0
- ciris_adapters/external_data_sql/__init__.py +43 -0
- ciris_adapters/external_data_sql/adapter.py +144 -0
- ciris_adapters/external_data_sql/configurable.py +315 -0
- ciris_adapters/external_data_sql/dialects/__init__.py +37 -0
- ciris_adapters/external_data_sql/dialects/base.py +133 -0
- ciris_adapters/external_data_sql/dialects/mysql.py +63 -0
- ciris_adapters/external_data_sql/dialects/postgresql.py +59 -0
- ciris_adapters/external_data_sql/dialects/sqlite.py +62 -0
- ciris_adapters/external_data_sql/example_config.json +88 -0
- ciris_adapters/external_data_sql/example_privacy_schema.yaml +127 -0
- ciris_adapters/external_data_sql/manifest.json +195 -0
- ciris_adapters/external_data_sql/privacy_schema_loader.py +189 -0
- ciris_adapters/external_data_sql/protocol.py +101 -0
- ciris_adapters/external_data_sql/schemas.py +146 -0
- ciris_adapters/external_data_sql/service.py +1547 -0
- ciris_adapters/external_data_sql/service_old.py +492 -0
- ciris_adapters/home_assistant/__init__.py +63 -0
- ciris_adapters/home_assistant/adapter.py +201 -0
- ciris_adapters/home_assistant/communication_service.py +347 -0
- ciris_adapters/home_assistant/configurable.py +667 -0
- ciris_adapters/home_assistant/manifest.json +203 -0
- ciris_adapters/home_assistant/schemas.py +129 -0
- ciris_adapters/home_assistant/service.py +751 -0
- ciris_adapters/home_assistant/tool_service.py +441 -0
- ciris_adapters/mcp_client/__init__.py +82 -0
- ciris_adapters/mcp_client/adapter.py +847 -0
- ciris_adapters/mcp_client/config.py +280 -0
- ciris_adapters/mcp_client/configurable.py +422 -0
- ciris_adapters/mcp_client/manifest.json +185 -0
- ciris_adapters/mcp_client/mcp_communication_service.py +393 -0
- ciris_adapters/mcp_client/mcp_tool_service.py +463 -0
- ciris_adapters/mcp_client/mcp_wise_service.py +394 -0
- ciris_adapters/mcp_client/schemas.py +149 -0
- ciris_adapters/mcp_client/security.py +592 -0
- ciris_adapters/mcp_common/__init__.py +44 -0
- ciris_adapters/mcp_common/manifest.json +25 -0
- ciris_adapters/mcp_common/protocol.py +315 -0
- ciris_adapters/mcp_common/schemas.py +225 -0
- ciris_adapters/mcp_server/__init__.py +47 -0
- ciris_adapters/mcp_server/adapter.py +581 -0
- ciris_adapters/mcp_server/config.py +260 -0
- ciris_adapters/mcp_server/configurable.py +393 -0
- ciris_adapters/mcp_server/handlers.py +663 -0
- ciris_adapters/mcp_server/manifest.json +211 -0
- ciris_adapters/mcp_server/security.py +500 -0
- ciris_adapters/mock_llm/README.md +117 -0
- ciris_adapters/mock_llm/__init__.py +21 -0
- ciris_adapters/mock_llm/adapter.py +131 -0
- ciris_adapters/mock_llm/configurable.py +237 -0
- ciris_adapters/mock_llm/manifest.json +106 -0
- ciris_adapters/mock_llm/protocol.py +37 -0
- ciris_adapters/mock_llm/responses.py +520 -0
- ciris_adapters/mock_llm/responses_action_selection.py +1041 -0
- ciris_adapters/mock_llm/responses_epistemic.py +17 -0
- ciris_adapters/mock_llm/responses_feedback.py +27 -0
- ciris_adapters/mock_llm/schemas.py +35 -0
- ciris_adapters/mock_llm/service.py +294 -0
- ciris_adapters/navigation/__init__.py +21 -0
- ciris_adapters/navigation/adapter.py +129 -0
- ciris_adapters/navigation/configurable.py +239 -0
- ciris_adapters/navigation/manifest.json +104 -0
- ciris_adapters/navigation/service.py +487 -0
- ciris_adapters/reddit/README.md +132 -0
- ciris_adapters/reddit/REDDIT_ADAPTER_ANALYSIS.md +715 -0
- ciris_adapters/reddit/REDDIT_ADAPTER_SUMMARY.txt +278 -0
- ciris_adapters/reddit/REDDIT_ANALYSIS_INDEX.md +307 -0
- ciris_adapters/reddit/REDDIT_PRODUCTION_READINESS_PLAN.md +518 -0
- ciris_adapters/reddit/__init__.py +15 -0
- ciris_adapters/reddit/adapter.py +189 -0
- ciris_adapters/reddit/configurable.py +274 -0
- ciris_adapters/reddit/error_handler.py +307 -0
- ciris_adapters/reddit/manifest.json +218 -0
- ciris_adapters/reddit/observer.py +532 -0
- ciris_adapters/reddit/protocol.py +34 -0
- ciris_adapters/reddit/schemas.py +433 -0
- ciris_adapters/reddit/service.py +1471 -0
- ciris_adapters/sample_adapter/README.md +474 -0
- ciris_adapters/sample_adapter/__init__.py +45 -0
- ciris_adapters/sample_adapter/adapter.py +208 -0
- ciris_adapters/sample_adapter/configurable.py +469 -0
- ciris_adapters/sample_adapter/manifest.json +247 -0
- ciris_adapters/sample_adapter/services.py +486 -0
- ciris_adapters/weather/__init__.py +16 -0
- ciris_adapters/weather/adapter.py +130 -0
- ciris_adapters/weather/configurable.py +240 -0
- ciris_adapters/weather/manifest.json +156 -0
- ciris_adapters/weather/service.py +600 -0
- ciris_agent-1.7.7.dist-info/METADATA +284 -0
- ciris_agent-1.7.7.dist-info/RECORD +986 -0
- ciris_agent-1.7.7.dist-info/WHEEL +5 -0
- ciris_agent-1.7.7.dist-info/entry_points.txt +15 -0
- ciris_agent-1.7.7.dist-info/licenses/LICENSE +205 -0
- ciris_agent-1.7.7.dist-info/licenses/NOTICE +82 -0
- ciris_agent-1.7.7.dist-info/top_level.txt +4 -0
- ciris_engine/__init__.py +15 -0
- ciris_engine/ciris_templates/ally.yaml +632 -0
- ciris_engine/ciris_templates/default.yaml +411 -0
- ciris_engine/ciris_templates/echo-core.yaml +629 -0
- ciris_engine/ciris_templates/echo-speculative.yaml +764 -0
- ciris_engine/ciris_templates/echo.yaml +647 -0
- ciris_engine/ciris_templates/sage.yaml +332 -0
- ciris_engine/ciris_templates/scout.yaml +338 -0
- ciris_engine/ciris_templates/test.yaml +168 -0
- ciris_engine/cli.py +42 -0
- ciris_engine/config/CIRIS_SERVICES.json +19 -0
- ciris_engine/config/MODEL_CAPABILITIES.json +419 -0
- ciris_engine/config/PRICING_DATA.json +179 -0
- ciris_engine/config/__init__.py +50 -0
- ciris_engine/config/ciris_services.py +113 -0
- ciris_engine/config/model_capabilities.py +388 -0
- ciris_engine/config/pricing_models.py +276 -0
- ciris_engine/constants.py +35 -0
- ciris_engine/data/__init__.py +1 -0
- ciris_engine/data/covenant_1.0b.txt +978 -0
- ciris_engine/gui_static/11steps.svg +107 -0
- ciris_engine/gui_static/2x-schematics.png +0 -0
- ciris_engine/gui_static/404/index.html +1 -0
- ciris_engine/gui_static/404.html +1 -0
- ciris_engine/gui_static/_next/static/0edhkwDxd5UccTsCmtaBi/_buildManifest.js +1 -0
- ciris_engine/gui_static/_next/static/0edhkwDxd5UccTsCmtaBi/_ssgManifest.js +1 -0
- ciris_engine/gui_static/_next/static/U-3xTQao7hc2wnAi-Uekm/_buildManifest.js +1 -0
- ciris_engine/gui_static/_next/static/U-3xTQao7hc2wnAi-Uekm/_ssgManifest.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/3297-60e86ba0f8a7b040.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/3835-2aad4b7f5f8e4643.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/4499-99a0bc47de0b8975.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/4534-af88cd4ba6e99bff.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/4541-84b455f9e0dc4cfe.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/4789-61412711484754bb.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/6539-c6398bc9d7018430.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/704-8e827b26cc8c2d32.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/704-fb45d630f3192c6f.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/8072-de4952a2e6d2b33f.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/8315-b91d03a3949db0af.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/8386-f93a83ccbd789bd9.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/87c73c54-781a7f35148d5433.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/8903-fefea3339a02d41b.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/9090-e66485adf8d9d990.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/_not-found/page-a67d9808462c23b1.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/account/api-keys/page-2d7ee1583bbbd02e.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/account/api-keys/page-6a3c2bae6fe92b7b.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/account/consent/page-2ed3a035136bc4e8.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/account/consent/page-b2f5c91844a32422.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/account/page-25b90f89af3ea58c.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/account/page-b65d16c94ecaf69c.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/account/privacy/page-675b6d05c8f9184f.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/account/privacy/page-cbee2e1c8ab52145.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/account/settings/page-0f44da06697cf9f0.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/account/settings/page-563420253577edbf.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/adapters/page-1854631018bc32be.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/agents/page-8353752c176a7c70.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/agents/page-f61a529f110a6040.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/api-demo/page-7f19b9d20d39be28.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/api-demo/page-d1063938f249b8bd.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/audit/page-321b6728b8fff0bb.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/audit/page-ebac35ca961a1277.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/billing/page-6f3dc3bd02924f8e.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/billing/page-fa4a469f814c821a.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/comms/page-0d4f734269addd8f.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/comms/page-79227d426050089c.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/config/page-018d21d683b6e5bc.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/config/page-2aa5a5363ca2a371.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/consent/page-198373205fd316e2.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/consent/page-f2ca39e7713b13f8.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/dashboard/page-1dd5a196f643c60d.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/dashboard/page-530a04d3abbb8cda.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/docs/page-3193b06d094ab654.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/docs/page-330e996dedb87aba.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/layout-0a70f5fc460298b1.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/layout-21f2f99dd5b336e9.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/login/page-33240e6c6034a49d.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/login/page-68ffab6d54a7fdcd.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/logs/page-8a6167aecc4a475c.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/memory/page-9ca8c5d0056de3ff.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/memory/page-e961226941c18f81.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/page-6fdb065a787a4974.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/page-89f87d431be6064a.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/runtime/page-2e728b9c43aa164d.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/runtime/page-c7dd033dc40a72f0.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/services/page-ae9f0bdf11d01a95.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/services/page-b10feb79ca5d75e5.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/sessions/page-13ebe7ef1c16ae11.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/sessions/page-e6c82b16d617f785.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/setup/page-0beb5f5b5a5c20fc.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/setup/page-2595e729eae30c0e.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/status-dashboard/page-1037c987aecc3653.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/status-dashboard/page-2ffd147f6d3162ff.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/system/page-2c5798d58cafcd91.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/system/page-505b1ba4eceb01c3.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/test-auth/page-b0cad31d5cb1b2fa.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/test-auth/page-f3ecd7a8012df230.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/test-login/page-f35117fdc4105801.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/test-login/page-fb583a7924114906.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/test-sdk/page-50f116fd76935563.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/test-sdk/page-c37d8aa5ba623a44.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/tools/page-429aec7a707777ef.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/tools/page-5f705aad60e0c04e.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/users/page-13476b8b0f3808cc.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/users/page-7e500d154ed5bba4.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/wa/page-cc4a9d8a5cb44d08.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/app/wa/page-ec3e429efbc79230.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/framework-9d29490f5ba089ba.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/main-1f554952e47a82c4.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/main-app-26fa8aed029082e5.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/main-app-97b0486ef6bcef25.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/pages/_app-6ce685456e616eb2.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/pages/_error-d4bce98d93fe21e7.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- ciris_engine/gui_static/_next/static/chunks/webpack-fcebd240b7f8477d.js +1 -0
- ciris_engine/gui_static/_next/static/css/16b94b1fe0cc6e37.css +3 -0
- ciris_engine/gui_static/_next/static/css/77a24ceaae86deff.css +3 -0
- ciris_engine/gui_static/_next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- ciris_engine/gui_static/_next/static/media/747892c23ea88013-s.woff2 +0 -0
- ciris_engine/gui_static/_next/static/media/8d697b304b401681-s.woff2 +0 -0
- ciris_engine/gui_static/_next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
- ciris_engine/gui_static/_next/static/media/9610d9e46709d722-s.woff2 +0 -0
- ciris_engine/gui_static/_next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
- ciris_engine/gui_static/_next/static/media/d8298875641ec7d4-s.p.woff2 +0 -0
- ciris_engine/gui_static/account/api-keys/index.html +1 -0
- ciris_engine/gui_static/account/api-keys/index.txt +27 -0
- ciris_engine/gui_static/account/consent/index.html +1 -0
- ciris_engine/gui_static/account/consent/index.txt +27 -0
- ciris_engine/gui_static/account/index.html +1 -0
- ciris_engine/gui_static/account/index.txt +27 -0
- ciris_engine/gui_static/account/privacy/index.html +1 -0
- ciris_engine/gui_static/account/privacy/index.txt +27 -0
- ciris_engine/gui_static/account/settings/index.html +1 -0
- ciris_engine/gui_static/account/settings/index.txt +27 -0
- ciris_engine/gui_static/adapters/index.html +1 -0
- ciris_engine/gui_static/adapters/index.txt +27 -0
- ciris_engine/gui_static/agents/index.html +1 -0
- ciris_engine/gui_static/agents/index.txt +27 -0
- ciris_engine/gui_static/andrew-roberts-euBRXcx57T4-unsplash.jpg +0 -0
- ciris_engine/gui_static/api-demo/index.html +1 -0
- ciris_engine/gui_static/api-demo/index.txt +27 -0
- ciris_engine/gui_static/audit/index.html +1 -0
- ciris_engine/gui_static/audit/index.txt +27 -0
- ciris_engine/gui_static/billing/index.html +1 -0
- ciris_engine/gui_static/billing/index.txt +27 -0
- ciris_engine/gui_static/blurryinfo.png +0 -0
- ciris_engine/gui_static/chip-vincent-PkQDwfl9Flc-unsplash.jpg +0 -0
- ciris_engine/gui_static/ciris-architecture.svg +338 -0
- ciris_engine/gui_static/comms/index.html +1 -0
- ciris_engine/gui_static/comms/index.txt +27 -0
- ciris_engine/gui_static/config/index.html +1 -0
- ciris_engine/gui_static/config/index.txt +27 -0
- ciris_engine/gui_static/consent/index.html +1 -0
- ciris_engine/gui_static/consent/index.txt +27 -0
- ciris_engine/gui_static/dashboard/index.html +1 -0
- ciris_engine/gui_static/dashboard/index.txt +27 -0
- ciris_engine/gui_static/docs/index.html +1 -0
- ciris_engine/gui_static/docs/index.txt +27 -0
- ciris_engine/gui_static/eric.png +0 -0
- ciris_engine/gui_static/file.svg +1 -0
- ciris_engine/gui_static/globe.svg +1 -0
- ciris_engine/gui_static/index.html +1 -0
- ciris_engine/gui_static/index.txt +27 -0
- ciris_engine/gui_static/infogfx-1@2x.png +0 -0
- ciris_engine/gui_static/infogfx-2.png +0 -0
- ciris_engine/gui_static/infogfx-dark-1.png +0 -0
- ciris_engine/gui_static/kelly-vohs-soSTXmIxTDU-unsplash.jpg +0 -0
- ciris_engine/gui_static/login/index.html +1 -0
- ciris_engine/gui_static/login/index.txt +27 -0
- ciris_engine/gui_static/logs/index.html +1 -0
- ciris_engine/gui_static/logs/index.txt +27 -0
- ciris_engine/gui_static/memory/index.html +1 -0
- ciris_engine/gui_static/memory/index.txt +27 -0
- ciris_engine/gui_static/nathan-farrish-ArcTfEoBgzs-unsplash.jpg +0 -0
- ciris_engine/gui_static/next.svg +1 -0
- ciris_engine/gui_static/overview.svg +512 -0
- ciris_engine/gui_static/overview1.svg +407 -0
- ciris_engine/gui_static/overview2.svg +370 -0
- ciris_engine/gui_static/pipeline-visualization.svg +278 -0
- ciris_engine/gui_static/privacy-policy.html +160 -0
- ciris_engine/gui_static/runtime/index.html +8 -0
- ciris_engine/gui_static/runtime/index.txt +27 -0
- ciris_engine/gui_static/services/index.html +1 -0
- ciris_engine/gui_static/services/index.txt +27 -0
- ciris_engine/gui_static/sessions/index.html +1 -0
- ciris_engine/gui_static/sessions/index.txt +27 -0
- ciris_engine/gui_static/setup/index.html +1 -0
- ciris_engine/gui_static/setup/index.txt +27 -0
- ciris_engine/gui_static/status-dashboard/index.html +1 -0
- ciris_engine/gui_static/status-dashboard/index.txt +27 -0
- ciris_engine/gui_static/system/index.html +1 -0
- ciris_engine/gui_static/system/index.txt +27 -0
- ciris_engine/gui_static/terms-of-service.html +174 -0
- ciris_engine/gui_static/test-auth/index.html +1 -0
- ciris_engine/gui_static/test-auth/index.txt +27 -0
- ciris_engine/gui_static/test-login/index.html +1 -0
- ciris_engine/gui_static/test-login/index.txt +27 -0
- ciris_engine/gui_static/test-sdk/index.html +1 -0
- ciris_engine/gui_static/test-sdk/index.txt +27 -0
- ciris_engine/gui_static/tools/index.html +1 -0
- ciris_engine/gui_static/tools/index.txt +27 -0
- ciris_engine/gui_static/users/index.html +1 -0
- ciris_engine/gui_static/users/index.txt +27 -0
- ciris_engine/gui_static/vercel.svg +1 -0
- ciris_engine/gui_static/videos/video1.mp4 +0 -0
- ciris_engine/gui_static/videos/video3.mp4 +0 -0
- ciris_engine/gui_static/wa/index.html +1 -0
- ciris_engine/gui_static/wa/index.txt +27 -0
- ciris_engine/gui_static/window.svg +1 -0
- ciris_engine/logic/__init__.py +8 -0
- ciris_engine/logic/adapters/__init__.py +74 -0
- ciris_engine/logic/adapters/api/__init__.py +5 -0
- ciris_engine/logic/adapters/api/adapter.py +1037 -0
- ciris_engine/logic/adapters/api/api_communication.py +370 -0
- ciris_engine/logic/adapters/api/api_document.py +330 -0
- ciris_engine/logic/adapters/api/api_observer.py +24 -0
- ciris_engine/logic/adapters/api/api_runtime_control.py +388 -0
- ciris_engine/logic/adapters/api/api_tools.py +299 -0
- ciris_engine/logic/adapters/api/api_vision.py +215 -0
- ciris_engine/logic/adapters/api/app.py +272 -0
- ciris_engine/logic/adapters/api/auth.py +159 -0
- ciris_engine/logic/adapters/api/config.py +101 -0
- ciris_engine/logic/adapters/api/constants.py +55 -0
- ciris_engine/logic/adapters/api/dependencies/__init__.py +1 -0
- ciris_engine/logic/adapters/api/dependencies/auth.py +260 -0
- ciris_engine/logic/adapters/api/endpoints/__init__.py +1 -0
- ciris_engine/logic/adapters/api/endpoints/emergency.py +86 -0
- ciris_engine/logic/adapters/api/middleware/__init__.py +1 -0
- ciris_engine/logic/adapters/api/middleware/rate_limiter.py +302 -0
- ciris_engine/logic/adapters/api/models.py +29 -0
- ciris_engine/logic/adapters/api/routes/__init__.py +52 -0
- ciris_engine/logic/adapters/api/routes/agent.py +1762 -0
- ciris_engine/logic/adapters/api/routes/audit.py +707 -0
- ciris_engine/logic/adapters/api/routes/auth.py +1745 -0
- ciris_engine/logic/adapters/api/routes/billing.py +895 -0
- ciris_engine/logic/adapters/api/routes/config.py +329 -0
- ciris_engine/logic/adapters/api/routes/connectors.py +534 -0
- ciris_engine/logic/adapters/api/routes/consent.py +637 -0
- ciris_engine/logic/adapters/api/routes/dsar.py +637 -0
- ciris_engine/logic/adapters/api/routes/dsar_multi_source.py +484 -0
- ciris_engine/logic/adapters/api/routes/emergency.py +302 -0
- ciris_engine/logic/adapters/api/routes/memory.py +733 -0
- ciris_engine/logic/adapters/api/routes/memory_filters.py +230 -0
- ciris_engine/logic/adapters/api/routes/memory_models.py +112 -0
- ciris_engine/logic/adapters/api/routes/memory_queries.py +236 -0
- ciris_engine/logic/adapters/api/routes/memory_query_helpers.py +394 -0
- ciris_engine/logic/adapters/api/routes/memory_visualization.py +359 -0
- ciris_engine/logic/adapters/api/routes/memory_visualization_helpers.py +110 -0
- ciris_engine/logic/adapters/api/routes/partnership.py +541 -0
- ciris_engine/logic/adapters/api/routes/setup.py +1374 -0
- ciris_engine/logic/adapters/api/routes/system.py +3049 -0
- ciris_engine/logic/adapters/api/routes/system_extensions.py +952 -0
- ciris_engine/logic/adapters/api/routes/telemetry.py +1987 -0
- ciris_engine/logic/adapters/api/routes/telemetry_converters.py +141 -0
- ciris_engine/logic/adapters/api/routes/telemetry_helpers.py +111 -0
- ciris_engine/logic/adapters/api/routes/telemetry_logs_reader.py +280 -0
- ciris_engine/logic/adapters/api/routes/telemetry_metrics.py +131 -0
- ciris_engine/logic/adapters/api/routes/telemetry_models.py +190 -0
- ciris_engine/logic/adapters/api/routes/telemetry_otlp.py +878 -0
- ciris_engine/logic/adapters/api/routes/telemetry_resource_helpers.py +191 -0
- ciris_engine/logic/adapters/api/routes/tickets.py +541 -0
- ciris_engine/logic/adapters/api/routes/tools.py +556 -0
- ciris_engine/logic/adapters/api/routes/transparency.py +281 -0
- ciris_engine/logic/adapters/api/routes/users.py +981 -0
- ciris_engine/logic/adapters/api/routes/verification.py +373 -0
- ciris_engine/logic/adapters/api/routes/wa.py +369 -0
- ciris_engine/logic/adapters/api/service_configuration.py +177 -0
- ciris_engine/logic/adapters/api/services/__init__.py +1 -0
- ciris_engine/logic/adapters/api/services/auth_service.py +1417 -0
- ciris_engine/logic/adapters/api/services/oauth_security.py +68 -0
- ciris_engine/logic/adapters/base.py +141 -0
- ciris_engine/logic/adapters/base_adapter.py +73 -0
- ciris_engine/logic/adapters/base_observer.py +1141 -0
- ciris_engine/logic/adapters/base_vision.py +312 -0
- ciris_engine/logic/adapters/cirisnode_client.py +307 -0
- ciris_engine/logic/adapters/cli/__init__.py +3 -0
- ciris_engine/logic/adapters/cli/adapter.py +207 -0
- ciris_engine/logic/adapters/cli/cli_adapter.py +902 -0
- ciris_engine/logic/adapters/cli/cli_observer.py +268 -0
- ciris_engine/logic/adapters/cli/cli_tools.py +427 -0
- ciris_engine/logic/adapters/cli/cli_wa_service.py +134 -0
- ciris_engine/logic/adapters/cli/config.py +73 -0
- ciris_engine/logic/adapters/discord/__init__.py +3 -0
- ciris_engine/logic/adapters/discord/adapter.py +783 -0
- ciris_engine/logic/adapters/discord/ciris_discord_client.py +159 -0
- ciris_engine/logic/adapters/discord/config.py +177 -0
- ciris_engine/logic/adapters/discord/constants.py +185 -0
- ciris_engine/logic/adapters/discord/discord-stubs.pyi +50 -0
- ciris_engine/logic/adapters/discord/discord_adapter.py +1584 -0
- ciris_engine/logic/adapters/discord/discord_audit.py +150 -0
- ciris_engine/logic/adapters/discord/discord_channel_manager.py +351 -0
- ciris_engine/logic/adapters/discord/discord_connection_manager.py +313 -0
- ciris_engine/logic/adapters/discord/discord_embed_formatter.py +369 -0
- ciris_engine/logic/adapters/discord/discord_error_classifier.py +302 -0
- ciris_engine/logic/adapters/discord/discord_error_handler.py +316 -0
- ciris_engine/logic/adapters/discord/discord_guidance_handler.py +460 -0
- ciris_engine/logic/adapters/discord/discord_message_handler.py +207 -0
- ciris_engine/logic/adapters/discord/discord_observer.py +670 -0
- ciris_engine/logic/adapters/discord/discord_rate_limiter.py +249 -0
- ciris_engine/logic/adapters/discord/discord_reaction_handler.py +278 -0
- ciris_engine/logic/adapters/discord/discord_tool_handler.py +465 -0
- ciris_engine/logic/adapters/discord/discord_tool_service.py +790 -0
- ciris_engine/logic/adapters/discord/discord_tools.py +90 -0
- ciris_engine/logic/adapters/discord/discord_vision_helper.py +148 -0
- ciris_engine/logic/adapters/discord/py.typed +0 -0
- ciris_engine/logic/adapters/document_parser.py +320 -0
- ciris_engine/logic/audit/__init__.py +10 -0
- ciris_engine/logic/audit/hash_chain.py +313 -0
- ciris_engine/logic/audit/signature_manager.py +352 -0
- ciris_engine/logic/audit/verifier.py +408 -0
- ciris_engine/logic/buses/__init__.py +21 -0
- ciris_engine/logic/buses/base_bus.py +178 -0
- ciris_engine/logic/buses/bus_manager.py +121 -0
- ciris_engine/logic/buses/communication_bus.py +387 -0
- ciris_engine/logic/buses/llm_bus.py +722 -0
- ciris_engine/logic/buses/memory_bus.py +577 -0
- ciris_engine/logic/buses/prohibitions.py +502 -0
- ciris_engine/logic/buses/runtime_control_bus.py +539 -0
- ciris_engine/logic/buses/tool_bus.py +482 -0
- ciris_engine/logic/buses/wise_bus.py +684 -0
- ciris_engine/logic/config/__init__.py +25 -0
- ciris_engine/logic/config/bootstrap.py +255 -0
- ciris_engine/logic/config/config_accessor.py +202 -0
- ciris_engine/logic/config/db_paths.py +194 -0
- ciris_engine/logic/config/env_utils.py +39 -0
- ciris_engine/logic/conscience/__init__.py +16 -0
- ciris_engine/logic/conscience/build_deferral_package.py +0 -0
- ciris_engine/logic/conscience/core.py +688 -0
- ciris_engine/logic/conscience/interface.py +33 -0
- ciris_engine/logic/conscience/registry.py +76 -0
- ciris_engine/logic/conscience/thought_depth_guardrail.py +231 -0
- ciris_engine/logic/conscience/updated_status_conscience.py +156 -0
- ciris_engine/logic/context/__init__.py +10 -0
- ciris_engine/logic/context/batch_context.py +550 -0
- ciris_engine/logic/context/builder.py +149 -0
- ciris_engine/logic/context/channel_resolution.py +136 -0
- ciris_engine/logic/context/secrets_snapshot.py +52 -0
- ciris_engine/logic/context/system_snapshot.py +116 -0
- ciris_engine/logic/context/system_snapshot_helpers.py +1651 -0
- ciris_engine/logic/covenant/__init__.py +33 -0
- ciris_engine/logic/covenant/executor.py +303 -0
- ciris_engine/logic/covenant/extractor.py +382 -0
- ciris_engine/logic/covenant/handler.py +241 -0
- ciris_engine/logic/covenant/verifier.py +383 -0
- ciris_engine/logic/dma/__init__.py +15 -0
- ciris_engine/logic/dma/action_selection/__init__.py +11 -0
- ciris_engine/logic/dma/action_selection/action_instruction_generator.py +444 -0
- ciris_engine/logic/dma/action_selection/context_builder.py +508 -0
- ciris_engine/logic/dma/action_selection/faculty_integration.py +193 -0
- ciris_engine/logic/dma/action_selection/special_cases.py +132 -0
- ciris_engine/logic/dma/action_selection_pdma.py +365 -0
- ciris_engine/logic/dma/base_dma.py +335 -0
- ciris_engine/logic/dma/csdma.py +239 -0
- ciris_engine/logic/dma/dma_executor.py +575 -0
- ciris_engine/logic/dma/dsdma_base.py +410 -0
- ciris_engine/logic/dma/exceptions.py +4 -0
- ciris_engine/logic/dma/factory.py +150 -0
- ciris_engine/logic/dma/pdma.py +120 -0
- ciris_engine/logic/dma/prompt_loader.py +189 -0
- ciris_engine/logic/dma/prompts/action_selection_pdma.yml +58 -0
- ciris_engine/logic/dma/prompts/csdma_common_sense.yml +28 -0
- ciris_engine/logic/dma/prompts/dsdma_base.yml +17 -0
- ciris_engine/logic/dma/prompts/pdma_ethical.yml +42 -0
- ciris_engine/logic/formatters/__init__.py +26 -0
- ciris_engine/logic/formatters/crisis_resources.py +80 -0
- ciris_engine/logic/formatters/escalation.py +21 -0
- ciris_engine/logic/formatters/identity.py +224 -0
- ciris_engine/logic/formatters/prompt_blocks.py +64 -0
- ciris_engine/logic/formatters/system_snapshot.py +193 -0
- ciris_engine/logic/formatters/user_profiles.py +108 -0
- ciris_engine/logic/handlers/__init__.py +1 -0
- ciris_engine/logic/handlers/control/__init__.py +1 -0
- ciris_engine/logic/handlers/control/defer_handler.py +195 -0
- ciris_engine/logic/handlers/control/ponder_handler.py +154 -0
- ciris_engine/logic/handlers/control/reject_handler.py +81 -0
- ciris_engine/logic/handlers/external/__init__.py +1 -0
- ciris_engine/logic/handlers/external/observe_handler.py +154 -0
- ciris_engine/logic/handlers/external/speak_handler.py +250 -0
- ciris_engine/logic/handlers/external/tool_handler.py +148 -0
- ciris_engine/logic/handlers/memory/__init__.py +1 -0
- ciris_engine/logic/handlers/memory/forget_handler.py +107 -0
- ciris_engine/logic/handlers/memory/memorize_handler.py +391 -0
- ciris_engine/logic/handlers/memory/recall_handler.py +213 -0
- ciris_engine/logic/handlers/terminal/__init__.py +1 -0
- ciris_engine/logic/handlers/terminal/task_complete_handler.py +299 -0
- ciris_engine/logic/infrastructure/__init__.py +1 -0
- ciris_engine/logic/infrastructure/handlers/__init__.py +8 -0
- ciris_engine/logic/infrastructure/handlers/action_dispatcher.py +382 -0
- ciris_engine/logic/infrastructure/handlers/base_handler.py +450 -0
- ciris_engine/logic/infrastructure/handlers/exceptions.py +2 -0
- ciris_engine/logic/infrastructure/handlers/handler_registry.py +59 -0
- ciris_engine/logic/infrastructure/handlers/helpers.py +55 -0
- ciris_engine/logic/infrastructure/step_streaming.py +149 -0
- ciris_engine/logic/infrastructure/sub_services/__init__.py +1 -0
- ciris_engine/logic/infrastructure/sub_services/identity_variance_monitor.py +1035 -0
- ciris_engine/logic/infrastructure/sub_services/pattern_analysis_loop.py +758 -0
- ciris_engine/logic/infrastructure/sub_services/wa_cli_bootstrap.py +229 -0
- ciris_engine/logic/infrastructure/sub_services/wa_cli_display.py +176 -0
- ciris_engine/logic/infrastructure/sub_services/wa_cli_oauth.py +404 -0
- ciris_engine/logic/infrastructure/sub_services/wa_cli_wizard.py +181 -0
- ciris_engine/logic/persistence/__init__.py +130 -0
- ciris_engine/logic/persistence/analytics.py +97 -0
- ciris_engine/logic/persistence/db/__init__.py +28 -0
- ciris_engine/logic/persistence/db/core.py +520 -0
- ciris_engine/logic/persistence/db/dialect.py +380 -0
- ciris_engine/logic/persistence/db/execution_helpers.py +216 -0
- ciris_engine/logic/persistence/db/migration_runner.py +191 -0
- ciris_engine/logic/persistence/db/operations.py +313 -0
- ciris_engine/logic/persistence/db/query_builder.py +232 -0
- ciris_engine/logic/persistence/db/retry.py +154 -0
- ciris_engine/logic/persistence/db/setup.py +18 -0
- ciris_engine/logic/persistence/migrations/postgres/001_initial_schema.sql +4 -0
- ciris_engine/logic/persistence/migrations/postgres/002_add_retry_status.sql +3 -0
- ciris_engine/logic/persistence/migrations/postgres/003_add_task_update_tracking.sql +8 -0
- ciris_engine/logic/persistence/migrations/postgres/004_add_occurrence_id.sql +54 -0
- ciris_engine/logic/persistence/migrations/postgres/005_add_consolidation_locks.sql +22 -0
- ciris_engine/logic/persistence/migrations/postgres/006_add_correlation_id_unique_index.sql +16 -0
- ciris_engine/logic/persistence/migrations/postgres/007_add_dsar_tickets.sql +39 -0
- ciris_engine/logic/persistence/migrations/postgres/008_rename_to_tickets_add_sop.sql +123 -0
- ciris_engine/logic/persistence/migrations/postgres/009_add_ticket_status_columns.sql +39 -0
- ciris_engine/logic/persistence/migrations/postgres/010_add_images_to_tasks.sql +5 -0
- ciris_engine/logic/persistence/migrations/sqlite/001_initial_schema.sql +357 -0
- ciris_engine/logic/persistence/migrations/sqlite/002_add_retry_status.sql +3 -0
- ciris_engine/logic/persistence/migrations/sqlite/003_add_task_update_tracking.sql +8 -0
- ciris_engine/logic/persistence/migrations/sqlite/004_add_occurrence_id.sql +45 -0
- ciris_engine/logic/persistence/migrations/sqlite/005_add_consolidation_locks.sql +22 -0
- ciris_engine/logic/persistence/migrations/sqlite/006_add_correlation_id_unique_index.sql +16 -0
- ciris_engine/logic/persistence/migrations/sqlite/007_add_dsar_tickets.sql +39 -0
- ciris_engine/logic/persistence/migrations/sqlite/008_rename_to_tickets_add_sop.sql +120 -0
- ciris_engine/logic/persistence/migrations/sqlite/009_add_ticket_status_columns.sql +129 -0
- ciris_engine/logic/persistence/migrations/sqlite/010_add_images_to_tasks.sql +17 -0
- ciris_engine/logic/persistence/models/__init__.py +141 -0
- ciris_engine/logic/persistence/models/correlations.py +881 -0
- ciris_engine/logic/persistence/models/deferral.py +68 -0
- ciris_engine/logic/persistence/models/dsar.py +286 -0
- ciris_engine/logic/persistence/models/graph.py +362 -0
- ciris_engine/logic/persistence/models/identity.py +264 -0
- ciris_engine/logic/persistence/models/queue_status.py +139 -0
- ciris_engine/logic/persistence/models/tasks.py +1043 -0
- ciris_engine/logic/persistence/models/thoughts.py +400 -0
- ciris_engine/logic/persistence/models/tickets.py +518 -0
- ciris_engine/logic/persistence/stores/__init__.py +13 -0
- ciris_engine/logic/persistence/stores/auth_helpers.py +117 -0
- ciris_engine/logic/persistence/stores/authentication_store.py +414 -0
- ciris_engine/logic/persistence/utils.py +212 -0
- ciris_engine/logic/processors/__init__.py +30 -0
- ciris_engine/logic/processors/core/__init__.py +1 -0
- ciris_engine/logic/processors/core/base_processor.py +280 -0
- ciris_engine/logic/processors/core/main_processor.py +1777 -0
- ciris_engine/logic/processors/core/step_decorators.py +1583 -0
- ciris_engine/logic/processors/core/thought_processor/__init__.py +20 -0
- ciris_engine/logic/processors/core/thought_processor/action_execution.py +49 -0
- ciris_engine/logic/processors/core/thought_processor/conscience_execution.py +382 -0
- ciris_engine/logic/processors/core/thought_processor/finalize_action.py +66 -0
- ciris_engine/logic/processors/core/thought_processor/gather_context.py +120 -0
- ciris_engine/logic/processors/core/thought_processor/main.py +920 -0
- ciris_engine/logic/processors/core/thought_processor/perform_aspdma.py +86 -0
- ciris_engine/logic/processors/core/thought_processor/perform_dmas.py +106 -0
- ciris_engine/logic/processors/core/thought_processor/recursive_processing.py +237 -0
- ciris_engine/logic/processors/core/thought_processor/round_complete.py +52 -0
- ciris_engine/logic/processors/core/thought_processor/start_round.py +64 -0
- ciris_engine/logic/processors/exceptions.py +59 -0
- ciris_engine/logic/processors/states/__init__.py +1 -0
- ciris_engine/logic/processors/states/dream_processor.py +1381 -0
- ciris_engine/logic/processors/states/play_processor.py +141 -0
- ciris_engine/logic/processors/states/shutdown_processor.py +623 -0
- ciris_engine/logic/processors/states/solitude_processor.py +305 -0
- ciris_engine/logic/processors/states/wakeup_processor.py +802 -0
- ciris_engine/logic/processors/states/work_processor.py +742 -0
- ciris_engine/logic/processors/support/__init__.py +1 -0
- ciris_engine/logic/processors/support/dma_orchestrator.py +336 -0
- ciris_engine/logic/processors/support/processing_queue.py +133 -0
- ciris_engine/logic/processors/support/shutdown_condition_evaluator.py +294 -0
- ciris_engine/logic/processors/support/state_manager.py +358 -0
- ciris_engine/logic/processors/support/task_manager.py +303 -0
- ciris_engine/logic/processors/support/thought_escalation.py +116 -0
- ciris_engine/logic/processors/support/thought_manager.py +328 -0
- ciris_engine/logic/processors/support/thought_manager_enhanced.py +105 -0
- ciris_engine/logic/registries/__init__.py +34 -0
- ciris_engine/logic/registries/base.py +653 -0
- ciris_engine/logic/registries/circuit_breaker.py +275 -0
- ciris_engine/logic/registries/typed_registries.py +184 -0
- ciris_engine/logic/runtime/__init__.py +7 -0
- ciris_engine/logic/runtime/adapter_loader.py +261 -0
- ciris_engine/logic/runtime/adapter_manager.py +1053 -0
- ciris_engine/logic/runtime/ciris_runtime.py +2342 -0
- ciris_engine/logic/runtime/ciris_runtime_helpers.py +923 -0
- ciris_engine/logic/runtime/component_builder.py +361 -0
- ciris_engine/logic/runtime/identity_manager.py +219 -0
- ciris_engine/logic/runtime/module_loader.py +207 -0
- ciris_engine/logic/runtime/prevent_sideeffects.py +30 -0
- ciris_engine/logic/runtime/runtime_interface.py +23 -0
- ciris_engine/logic/runtime/service_initializer.py +1623 -0
- ciris_engine/logic/secrets/__init__.py +30 -0
- ciris_engine/logic/secrets/encryption.py +175 -0
- ciris_engine/logic/secrets/filter.py +295 -0
- ciris_engine/logic/secrets/service.py +652 -0
- ciris_engine/logic/secrets/store.py +669 -0
- ciris_engine/logic/services/__init__.py +1 -0
- ciris_engine/logic/services/adaptation/__init__.py +3 -0
- ciris_engine/logic/services/base_graph_service.py +142 -0
- ciris_engine/logic/services/base_infrastructure_service.py +69 -0
- ciris_engine/logic/services/base_scheduled_service.py +136 -0
- ciris_engine/logic/services/base_service.py +247 -0
- ciris_engine/logic/services/governance/__init__.py +3 -0
- ciris_engine/logic/services/governance/adaptive_filter/__init__.py +14 -0
- ciris_engine/logic/services/governance/adaptive_filter/service.py +818 -0
- ciris_engine/logic/services/governance/consent/__init__.py +53 -0
- ciris_engine/logic/services/governance/consent/air.py +403 -0
- ciris_engine/logic/services/governance/consent/decay.py +324 -0
- ciris_engine/logic/services/governance/consent/dsar_automation.py +589 -0
- ciris_engine/logic/services/governance/consent/exceptions.py +106 -0
- ciris_engine/logic/services/governance/consent/metrics.py +270 -0
- ciris_engine/logic/services/governance/consent/partnership.py +533 -0
- ciris_engine/logic/services/governance/consent/service.py +1256 -0
- ciris_engine/logic/services/governance/dsar/__init__.py +29 -0
- ciris_engine/logic/services/governance/dsar/orchestrator.py +977 -0
- ciris_engine/logic/services/governance/dsar/schemas.py +141 -0
- ciris_engine/logic/services/governance/dsar/signature_service.py +283 -0
- ciris_engine/logic/services/governance/self_observation/__init__.py +20 -0
- ciris_engine/logic/services/governance/self_observation/service.py +1153 -0
- ciris_engine/logic/services/governance/visibility/__init__.py +17 -0
- ciris_engine/logic/services/governance/visibility/service.py +512 -0
- ciris_engine/logic/services/governance/wise_authority/__init__.py +15 -0
- ciris_engine/logic/services/governance/wise_authority/service.py +827 -0
- ciris_engine/logic/services/graph/__init__.py +5 -0
- ciris_engine/logic/services/graph/audit_service/__init__.py +5 -0
- ciris_engine/logic/services/graph/audit_service/service.py +1675 -0
- ciris_engine/logic/services/graph/base.py +208 -0
- ciris_engine/logic/services/graph/config_service/__init__.py +5 -0
- ciris_engine/logic/services/graph/config_service/service.py +372 -0
- ciris_engine/logic/services/graph/incident_service/__init__.py +5 -0
- ciris_engine/logic/services/graph/incident_service/service.py +803 -0
- ciris_engine/logic/services/graph/memory_service.py +1120 -0
- ciris_engine/logic/services/graph/telemetry_service/__init__.py +5 -0
- ciris_engine/logic/services/graph/telemetry_service/exceptions.py +104 -0
- ciris_engine/logic/services/graph/telemetry_service/helpers.py +1337 -0
- ciris_engine/logic/services/graph/telemetry_service/service.py +2429 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/__init__.py +17 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/aggregation_helpers.py +355 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/cleanup_helpers.py +438 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/compressor.py +260 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/__init__.py +27 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/audit.py +326 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/conversation.py +291 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/memory.py +197 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/metrics.py +251 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/task.py +257 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/trace.py +363 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/data_converter.py +545 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/date_calculation_helpers.py +193 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/db_query_helpers.py +296 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/edge_helpers.py +92 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/edge_manager.py +896 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/extensive_helpers.py +322 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/period_manager.py +152 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/profound_helpers.py +277 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/query_manager.py +812 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/service.py +1692 -0
- ciris_engine/logic/services/graph/tsdb_consolidation/sql_builders.py +363 -0
- ciris_engine/logic/services/infrastructure/__init__.py +1 -0
- ciris_engine/logic/services/infrastructure/authentication/__init__.py +5 -0
- ciris_engine/logic/services/infrastructure/authentication/service.py +1634 -0
- ciris_engine/logic/services/infrastructure/database_maintenance/__init__.py +15 -0
- ciris_engine/logic/services/infrastructure/database_maintenance/service.py +764 -0
- ciris_engine/logic/services/infrastructure/resource_monitor/__init__.py +7 -0
- ciris_engine/logic/services/infrastructure/resource_monitor/ciris_billing_provider.py +755 -0
- ciris_engine/logic/services/infrastructure/resource_monitor/service.py +409 -0
- ciris_engine/logic/services/infrastructure/resource_monitor/simple_credit_provider.py +129 -0
- ciris_engine/logic/services/lifecycle/__init__.py +3 -0
- ciris_engine/logic/services/lifecycle/initialization/__init__.py +10 -0
- ciris_engine/logic/services/lifecycle/initialization/service.py +312 -0
- ciris_engine/logic/services/lifecycle/scheduler/__init__.py +5 -0
- ciris_engine/logic/services/lifecycle/scheduler/service.py +607 -0
- ciris_engine/logic/services/lifecycle/shutdown/__init__.py +9 -0
- ciris_engine/logic/services/lifecycle/shutdown/service.py +378 -0
- ciris_engine/logic/services/lifecycle/time/__init__.py +15 -0
- ciris_engine/logic/services/lifecycle/time/service.py +259 -0
- ciris_engine/logic/services/memory_service/__init__.py +8 -0
- ciris_engine/logic/services/mixins/__init__.py +13 -0
- ciris_engine/logic/services/mixins/example_usage.py +200 -0
- ciris_engine/logic/services/mixins/request_metrics.py +179 -0
- ciris_engine/logic/services/runtime/__init__.py +3 -0
- ciris_engine/logic/services/runtime/adapter_configuration/__init__.py +16 -0
- ciris_engine/logic/services/runtime/adapter_configuration/service.py +674 -0
- ciris_engine/logic/services/runtime/adapter_configuration/session.py +67 -0
- ciris_engine/logic/services/runtime/control_service/__init__.py +5 -0
- ciris_engine/logic/services/runtime/control_service/service.py +2269 -0
- ciris_engine/logic/services/runtime/llm_service/__init__.py +14 -0
- ciris_engine/logic/services/runtime/llm_service/pricing_calculator.py +279 -0
- ciris_engine/logic/services/runtime/llm_service/service.py +930 -0
- ciris_engine/logic/services/tools/__init__.py +5 -0
- ciris_engine/logic/services/tools/core_tool_service/__init__.py +8 -0
- ciris_engine/logic/services/tools/core_tool_service/service.py +852 -0
- ciris_engine/logic/setup/__init__.py +1 -0
- ciris_engine/logic/setup/first_run.py +250 -0
- ciris_engine/logic/setup/wizard.py +327 -0
- ciris_engine/logic/telemetry/__init__.py +46 -0
- ciris_engine/logic/telemetry/core.py +239 -0
- ciris_engine/logic/telemetry/hot_cold_config.py +133 -0
- ciris_engine/logic/telemetry/log_collector.py +190 -0
- ciris_engine/logic/telemetry/resource_monitor.py +7 -0
- ciris_engine/logic/telemetry/security.py +79 -0
- ciris_engine/logic/utils/__init__.py +18 -0
- ciris_engine/logic/utils/channel_utils.py +75 -0
- ciris_engine/logic/utils/consent/__init__.py +1 -0
- ciris_engine/logic/utils/consent/partnership_utils.py +172 -0
- ciris_engine/logic/utils/constants.py +92 -0
- ciris_engine/logic/utils/context_utils.py +145 -0
- ciris_engine/logic/utils/directory_setup.py +533 -0
- ciris_engine/logic/utils/graphql_context_provider.py +152 -0
- ciris_engine/logic/utils/identity_resolution.py +843 -0
- ciris_engine/logic/utils/incident_capture_handler.py +303 -0
- ciris_engine/logic/utils/initialization_manager.py +74 -0
- ciris_engine/logic/utils/jsondict_helpers.py +290 -0
- ciris_engine/logic/utils/log_sanitizer.py +97 -0
- ciris_engine/logic/utils/logging_config.py +151 -0
- ciris_engine/logic/utils/observability_decorators.py +544 -0
- ciris_engine/logic/utils/occurrence_utils.py +155 -0
- ciris_engine/logic/utils/path_resolution.py +281 -0
- ciris_engine/logic/utils/platform_detection.py +286 -0
- ciris_engine/logic/utils/privacy.py +266 -0
- ciris_engine/logic/utils/profile_loader.py +124 -0
- ciris_engine/logic/utils/profile_manager.py +16 -0
- ciris_engine/logic/utils/runtime_utils.py +69 -0
- ciris_engine/logic/utils/shutdown_manager.py +107 -0
- ciris_engine/logic/utils/task_formatters.py +60 -0
- ciris_engine/logic/utils/task_thought_factory.py +404 -0
- ciris_engine/logic/utils/thought_utils.py +54 -0
- ciris_engine/logic/utils/user_utils.py +70 -0
- ciris_engine/protocols/__init__.py +0 -0
- ciris_engine/protocols/adapters/__init__.py +35 -0
- ciris_engine/protocols/adapters/base.py +149 -0
- ciris_engine/protocols/adapters/configurable.py +265 -0
- ciris_engine/protocols/adapters/message.py +90 -0
- ciris_engine/protocols/audit/__init__.py +1 -0
- ciris_engine/protocols/buses/__init__.py +1 -0
- ciris_engine/protocols/config/__init__.py +1 -0
- ciris_engine/protocols/conscience/__init__.py +1 -0
- ciris_engine/protocols/consent.py +88 -0
- ciris_engine/protocols/context/__init__.py +1 -0
- ciris_engine/protocols/data/__init__.py +1 -0
- ciris_engine/protocols/dma/__init__.py +1 -0
- ciris_engine/protocols/dma/base.py +107 -0
- ciris_engine/protocols/faculties.py +34 -0
- ciris_engine/protocols/formatters/__init__.py +1 -0
- ciris_engine/protocols/handlers/__init__.py +1 -0
- ciris_engine/protocols/infrastructure/__init__.py +25 -0
- ciris_engine/protocols/infrastructure/base.py +377 -0
- ciris_engine/protocols/persistence/__init__.py +1 -0
- ciris_engine/protocols/pipeline_control.py +609 -0
- ciris_engine/protocols/processors/__init__.py +19 -0
- ciris_engine/protocols/processors/agent.py +299 -0
- ciris_engine/protocols/processors/base.py +130 -0
- ciris_engine/protocols/processors/orchestration.py +62 -0
- ciris_engine/protocols/registries/__init__.py +1 -0
- ciris_engine/protocols/runtime/__init__.py +1 -0
- ciris_engine/protocols/runtime/base.py +163 -0
- ciris_engine/protocols/secrets/__init__.py +1 -0
- ciris_engine/protocols/services/__init__.py +80 -0
- ciris_engine/protocols/services/adaptation/__init__.py +7 -0
- ciris_engine/protocols/services/adaptation/self_observation.py +265 -0
- ciris_engine/protocols/services/governance/__init__.py +20 -0
- ciris_engine/protocols/services/governance/communication.py +58 -0
- ciris_engine/protocols/services/governance/filter.py +56 -0
- ciris_engine/protocols/services/governance/visibility.py +32 -0
- ciris_engine/protocols/services/governance/wa_auth.py +192 -0
- ciris_engine/protocols/services/governance/wise_authority.py +75 -0
- ciris_engine/protocols/services/graph/__init__.py +19 -0
- ciris_engine/protocols/services/graph/audit.py +92 -0
- ciris_engine/protocols/services/graph/config.py +54 -0
- ciris_engine/protocols/services/graph/incident_management.py +103 -0
- ciris_engine/protocols/services/graph/memory.py +110 -0
- ciris_engine/protocols/services/graph/telemetry.py +51 -0
- ciris_engine/protocols/services/graph/tsdb_consolidation.py +87 -0
- ciris_engine/protocols/services/infrastructure/__init__.py +11 -0
- ciris_engine/protocols/services/infrastructure/authentication.py +159 -0
- ciris_engine/protocols/services/infrastructure/credit_gate.py +46 -0
- ciris_engine/protocols/services/infrastructure/database_maintenance.py +25 -0
- ciris_engine/protocols/services/infrastructure/resource_monitor.py +83 -0
- ciris_engine/protocols/services/lifecycle/__init__.py +13 -0
- ciris_engine/protocols/services/lifecycle/initialization.py +41 -0
- ciris_engine/protocols/services/lifecycle/scheduler.py +42 -0
- ciris_engine/protocols/services/lifecycle/shutdown.py +50 -0
- ciris_engine/protocols/services/lifecycle/time.py +31 -0
- ciris_engine/protocols/services/runtime/__init__.py +13 -0
- ciris_engine/protocols/services/runtime/llm.py +50 -0
- ciris_engine/protocols/services/runtime/runtime_control.py +193 -0
- ciris_engine/protocols/services/runtime/secrets.py +100 -0
- ciris_engine/protocols/services/runtime/tool.py +123 -0
- ciris_engine/protocols/telemetry/__init__.py +1 -0
- ciris_engine/protocols/utils/__init__.py +1 -0
- ciris_engine/schemas/__init__.py +112 -0
- ciris_engine/schemas/actions/__init__.py +37 -0
- ciris_engine/schemas/actions/parameters.py +137 -0
- ciris_engine/schemas/adapters/__init__.py +13 -0
- ciris_engine/schemas/adapters/cirisnode.py +135 -0
- ciris_engine/schemas/adapters/cli.py +97 -0
- ciris_engine/schemas/adapters/cli_tools.py +98 -0
- ciris_engine/schemas/adapters/discord.py +125 -0
- ciris_engine/schemas/adapters/graphql_core.py +144 -0
- ciris_engine/schemas/adapters/registration.py +47 -0
- ciris_engine/schemas/adapters/runtime_context.py +48 -0
- ciris_engine/schemas/adapters/tool_execution.py +45 -0
- ciris_engine/schemas/adapters/tools.py +96 -0
- ciris_engine/schemas/api/__init__.py +1 -0
- ciris_engine/schemas/api/agent.py +50 -0
- ciris_engine/schemas/api/audit.py +38 -0
- ciris_engine/schemas/api/auth.py +351 -0
- ciris_engine/schemas/api/config_security.py +242 -0
- ciris_engine/schemas/api/emergency.py +111 -0
- ciris_engine/schemas/api/responses.py +72 -0
- ciris_engine/schemas/api/runtime.py +26 -0
- ciris_engine/schemas/api/telemetry.py +109 -0
- ciris_engine/schemas/api/wa.py +90 -0
- ciris_engine/schemas/audit/__init__.py +13 -0
- ciris_engine/schemas/audit/core.py +139 -0
- ciris_engine/schemas/audit/hash_chain.py +58 -0
- ciris_engine/schemas/audit/verification.py +131 -0
- ciris_engine/schemas/buses/__init__.py +1 -0
- ciris_engine/schemas/config/__init__.py +41 -0
- ciris_engine/schemas/config/agent.py +279 -0
- ciris_engine/schemas/config/cognitive_state_behaviors.py +194 -0
- ciris_engine/schemas/config/default_dsar_sops.py +178 -0
- ciris_engine/schemas/config/essential.py +195 -0
- ciris_engine/schemas/config/tickets.py +86 -0
- ciris_engine/schemas/conscience/__init__.py +25 -0
- ciris_engine/schemas/conscience/context.py +34 -0
- ciris_engine/schemas/conscience/core.py +145 -0
- ciris_engine/schemas/conscience/results.py +24 -0
- ciris_engine/schemas/consent/__init__.py +5 -0
- ciris_engine/schemas/consent/core.py +404 -0
- ciris_engine/schemas/context/__init__.py +1 -0
- ciris_engine/schemas/covenant.py +382 -0
- ciris_engine/schemas/data/__init__.py +1 -0
- ciris_engine/schemas/dma/__init__.py +16 -0
- ciris_engine/schemas/dma/core.py +199 -0
- ciris_engine/schemas/dma/faculty.py +192 -0
- ciris_engine/schemas/dma/prompts.py +172 -0
- ciris_engine/schemas/dma/results.py +103 -0
- ciris_engine/schemas/formatters/__init__.py +1 -0
- ciris_engine/schemas/handlers/__init__.py +10 -0
- ciris_engine/schemas/handlers/context.py +119 -0
- ciris_engine/schemas/handlers/contexts.py +100 -0
- ciris_engine/schemas/handlers/core.py +167 -0
- ciris_engine/schemas/handlers/memory_schemas.py +67 -0
- ciris_engine/schemas/handlers/schemas.py +95 -0
- ciris_engine/schemas/identity.py +149 -0
- ciris_engine/schemas/infrastructure/__init__.py +1 -0
- ciris_engine/schemas/infrastructure/base.py +256 -0
- ciris_engine/schemas/infrastructure/behavioral_patterns.py +129 -0
- ciris_engine/schemas/infrastructure/feedback_loop.py +57 -0
- ciris_engine/schemas/infrastructure/identity_variance.py +141 -0
- ciris_engine/schemas/infrastructure/oauth.py +175 -0
- ciris_engine/schemas/infrastructure/wa_cli_wizard.py +54 -0
- ciris_engine/schemas/persistence/__init__.py +34 -0
- ciris_engine/schemas/persistence/core.py +140 -0
- ciris_engine/schemas/persistence/correlations.py +73 -0
- ciris_engine/schemas/persistence/postgres/__init__.py +1 -0
- ciris_engine/schemas/persistence/postgres/tables.py +280 -0
- ciris_engine/schemas/persistence/sqlite/__init__.py +1 -0
- ciris_engine/schemas/persistence/sqlite/tables.py +281 -0
- ciris_engine/schemas/platform.py +149 -0
- ciris_engine/schemas/processors/__init__.py +26 -0
- ciris_engine/schemas/processors/base.py +130 -0
- ciris_engine/schemas/processors/cognitive.py +77 -0
- ciris_engine/schemas/processors/context.py +35 -0
- ciris_engine/schemas/processors/core.py +152 -0
- ciris_engine/schemas/processors/dma.py +105 -0
- ciris_engine/schemas/processors/error.py +122 -0
- ciris_engine/schemas/processors/main.py +109 -0
- ciris_engine/schemas/processors/phase_results.py +21 -0
- ciris_engine/schemas/processors/results.py +99 -0
- ciris_engine/schemas/processors/solitude.py +79 -0
- ciris_engine/schemas/processors/state.py +202 -0
- ciris_engine/schemas/processors/state_example.py +177 -0
- ciris_engine/schemas/processors/states.py +21 -0
- ciris_engine/schemas/processors/status.py +34 -0
- ciris_engine/schemas/registries/__init__.py +1 -0
- ciris_engine/schemas/registries/base.py +66 -0
- ciris_engine/schemas/resources/__init__.py +15 -0
- ciris_engine/schemas/resources/crisis.py +315 -0
- ciris_engine/schemas/runtime/__init__.py +42 -0
- ciris_engine/schemas/runtime/adapter_management.py +186 -0
- ciris_engine/schemas/runtime/api.py +58 -0
- ciris_engine/schemas/runtime/audit.py +50 -0
- ciris_engine/schemas/runtime/bootstrap.py +33 -0
- ciris_engine/schemas/runtime/contexts.py +61 -0
- ciris_engine/schemas/runtime/core.py +161 -0
- ciris_engine/schemas/runtime/enums.py +167 -0
- ciris_engine/schemas/runtime/extended.py +232 -0
- ciris_engine/schemas/runtime/manifest.py +311 -0
- ciris_engine/schemas/runtime/memory.py +60 -0
- ciris_engine/schemas/runtime/messages.py +108 -0
- ciris_engine/schemas/runtime/models.py +156 -0
- ciris_engine/schemas/runtime/processing_context.py +43 -0
- ciris_engine/schemas/runtime/protocols_core.py +96 -0
- ciris_engine/schemas/runtime/resources.py +33 -0
- ciris_engine/schemas/runtime/system_context.py +417 -0
- ciris_engine/schemas/secrets/__init__.py +1 -0
- ciris_engine/schemas/secrets/core.py +267 -0
- ciris_engine/schemas/secrets/service.py +95 -0
- ciris_engine/schemas/services/__init__.py +33 -0
- ciris_engine/schemas/services/audit_summary_node.py +172 -0
- ciris_engine/schemas/services/authority/__init__.py +39 -0
- ciris_engine/schemas/services/authority/jwt.py +158 -0
- ciris_engine/schemas/services/authority/wa_updates.py +138 -0
- ciris_engine/schemas/services/authority/wise_authority.py +163 -0
- ciris_engine/schemas/services/authority_core.py +370 -0
- ciris_engine/schemas/services/capabilities.py +72 -0
- ciris_engine/schemas/services/community_core.py +95 -0
- ciris_engine/schemas/services/context.py +111 -0
- ciris_engine/schemas/services/conversation_summary_node.py +189 -0
- ciris_engine/schemas/services/core/__init__.py +153 -0
- ciris_engine/schemas/services/core/runtime.py +262 -0
- ciris_engine/schemas/services/core/runtime_config.py +117 -0
- ciris_engine/schemas/services/core/secrets.py +65 -0
- ciris_engine/schemas/services/correlation_node.py +179 -0
- ciris_engine/schemas/services/credit_gate.py +92 -0
- ciris_engine/schemas/services/discord_nodes.py +299 -0
- ciris_engine/schemas/services/feedback_core.py +131 -0
- ciris_engine/schemas/services/filters_core.py +270 -0
- ciris_engine/schemas/services/governance.py +26 -0
- ciris_engine/schemas/services/graph/__init__.py +26 -0
- ciris_engine/schemas/services/graph/attributes.py +254 -0
- ciris_engine/schemas/services/graph/audit.py +98 -0
- ciris_engine/schemas/services/graph/consolidation.py +338 -0
- ciris_engine/schemas/services/graph/edge_types.py +43 -0
- ciris_engine/schemas/services/graph/edges.py +88 -0
- ciris_engine/schemas/services/graph/incident.py +312 -0
- ciris_engine/schemas/services/graph/memory.py +84 -0
- ciris_engine/schemas/services/graph/node_data.py +174 -0
- ciris_engine/schemas/services/graph/query_results.py +82 -0
- ciris_engine/schemas/services/graph/telemetry.py +250 -0
- ciris_engine/schemas/services/graph/tsdb_consolidation.py +27 -0
- ciris_engine/schemas/services/graph/tsdb_models.py +107 -0
- ciris_engine/schemas/services/graph_core.py +196 -0
- ciris_engine/schemas/services/graph_typed_nodes.py +194 -0
- ciris_engine/schemas/services/infrastructure/__init__.py +1 -0
- ciris_engine/schemas/services/infrastructure/resource_monitor.py +20 -0
- ciris_engine/schemas/services/lifecycle/__init__.py +9 -0
- ciris_engine/schemas/services/lifecycle/initialization.py +33 -0
- ciris_engine/schemas/services/lifecycle/time.py +50 -0
- ciris_engine/schemas/services/llm.py +187 -0
- ciris_engine/schemas/services/metadata.py +43 -0
- ciris_engine/schemas/services/nodes.py +704 -0
- ciris_engine/schemas/services/operations.py +126 -0
- ciris_engine/schemas/services/requests.py +128 -0
- ciris_engine/schemas/services/resources_core.py +182 -0
- ciris_engine/schemas/services/runtime_control.py +1010 -0
- ciris_engine/schemas/services/shutdown.py +88 -0
- ciris_engine/schemas/services/special/__init__.py +0 -0
- ciris_engine/schemas/services/special/self_observation.py +396 -0
- ciris_engine/schemas/services/trace_summary_node.py +199 -0
- ciris_engine/schemas/services/visibility.py +98 -0
- ciris_engine/schemas/streaming/__init__.py +10 -0
- ciris_engine/schemas/streaming/reasoning_stream.py +95 -0
- ciris_engine/schemas/telemetry/__init__.py +0 -0
- ciris_engine/schemas/telemetry/collector.py +67 -0
- ciris_engine/schemas/telemetry/core.py +252 -0
- ciris_engine/schemas/telemetry/unified.py +59 -0
- ciris_engine/schemas/tools.py +72 -0
- ciris_engine/schemas/types.py +47 -0
- ciris_engine/schemas/utils/__init__.py +1 -0
- ciris_engine/schemas/utils/config_validator.py +54 -0
- ciris_engine/utils/__init__.py +1 -0
- ciris_engine/utils/serialization.py +35 -0
- ciris_sdk/__init__.py +124 -0
- ciris_sdk/auth_store.py +261 -0
- ciris_sdk/client.py +261 -0
- ciris_sdk/exceptions.py +73 -0
- ciris_sdk/model_types.py +258 -0
- ciris_sdk/models.py +354 -0
- ciris_sdk/pagination.py +214 -0
- ciris_sdk/rate_limiter.py +188 -0
- ciris_sdk/setup.py +17 -0
- ciris_sdk/telemetry_models.py +257 -0
- ciris_sdk/telemetry_responses.py +199 -0
- ciris_sdk/transport.py +177 -0
- ciris_sdk/websocket.py +400 -0
- main.py +766 -0
|
@@ -0,0 +1,1381 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Dream Processor for CIRISAgent.
|
|
3
|
+
|
|
4
|
+
Integrates memory consolidation, self-configuration, and introspection during dream cycles.
|
|
5
|
+
Falls back to benchmark mode when CIRISNode is configured.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
import logging
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
from datetime import datetime, timedelta
|
|
12
|
+
from enum import Enum
|
|
13
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional
|
|
14
|
+
|
|
15
|
+
from ciris_engine.logic.adapters import CIRISNodeClient
|
|
16
|
+
from ciris_engine.logic.buses.communication_bus import CommunicationBus
|
|
17
|
+
from ciris_engine.logic.buses.memory_bus import MemoryBus
|
|
18
|
+
from ciris_engine.logic.config import ConfigAccessor
|
|
19
|
+
from ciris_engine.logic.processors.core.base_processor import BaseProcessor
|
|
20
|
+
from ciris_engine.logic.processors.support.processing_queue import ProcessingQueueItem
|
|
21
|
+
from ciris_engine.logic.services.governance.self_observation import SelfObservationService
|
|
22
|
+
from ciris_engine.logic.services.graph.telemetry_service import GraphTelemetryService
|
|
23
|
+
from ciris_engine.logic.utils.jsondict_helpers import get_bool, get_dict, get_int, get_str
|
|
24
|
+
from ciris_engine.protocols.services.lifecycle.time import TimeServiceProtocol
|
|
25
|
+
from ciris_engine.schemas.processors.base import MetricsUpdate, ProcessorServices
|
|
26
|
+
from ciris_engine.schemas.processors.results import DreamResult
|
|
27
|
+
from ciris_engine.schemas.processors.states import AgentState
|
|
28
|
+
from ciris_engine.schemas.runtime.enums import HandlerActionType, TaskStatus, ThoughtStatus
|
|
29
|
+
from ciris_engine.schemas.services.graph_core import GraphNode, GraphScope, NodeType
|
|
30
|
+
from ciris_engine.schemas.services.operations import MemoryQuery
|
|
31
|
+
from ciris_engine.schemas.types import JSONDict
|
|
32
|
+
|
|
33
|
+
if TYPE_CHECKING:
|
|
34
|
+
from ciris_engine.logic.infrastructure.handlers.action_dispatcher import ActionDispatcher
|
|
35
|
+
from ciris_engine.logic.processors.core.thought_processor import ThoughtProcessor
|
|
36
|
+
from ciris_engine.logic.registries.base import ServiceRegistry
|
|
37
|
+
from ciris_engine.logic.runtime.identity_manager import IdentityManager
|
|
38
|
+
|
|
39
|
+
logger = logging.getLogger(__name__)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class DreamPhase(str, Enum):
|
|
43
|
+
"""Phases of dream processing."""
|
|
44
|
+
|
|
45
|
+
ENTERING = "entering"
|
|
46
|
+
CONSOLIDATING = "consolidating"
|
|
47
|
+
ANALYZING = "analyzing"
|
|
48
|
+
CONFIGURING = "configuring"
|
|
49
|
+
PLANNING = "planning"
|
|
50
|
+
BENCHMARKING = "benchmarking"
|
|
51
|
+
EXITING = "exiting"
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@dataclass
|
|
55
|
+
class DreamSession:
|
|
56
|
+
"""Represents a complete dream session."""
|
|
57
|
+
|
|
58
|
+
session_id: str
|
|
59
|
+
scheduled_start: Optional[datetime]
|
|
60
|
+
actual_start: datetime
|
|
61
|
+
planned_duration: timedelta
|
|
62
|
+
phase: DreamPhase
|
|
63
|
+
|
|
64
|
+
# Work completed
|
|
65
|
+
memories_consolidated: int = 0
|
|
66
|
+
patterns_analyzed: int = 0
|
|
67
|
+
adaptations_made: int = 0
|
|
68
|
+
future_tasks_scheduled: int = 0
|
|
69
|
+
benchmarks_run: int = 0
|
|
70
|
+
|
|
71
|
+
# Insights
|
|
72
|
+
ponder_questions_processed: List[str] = field(default_factory=list)
|
|
73
|
+
insights_gained: List[str] = field(default_factory=list)
|
|
74
|
+
|
|
75
|
+
# Timing
|
|
76
|
+
phase_durations: Dict[str, float] = field(default_factory=dict)
|
|
77
|
+
completed_at: Optional[datetime] = None
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class DreamProcessor(BaseProcessor):
|
|
81
|
+
"""
|
|
82
|
+
Dream processor that handles introspection, memory consolidation,
|
|
83
|
+
and self-configuration during dream states.
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
def __init__(
|
|
87
|
+
self,
|
|
88
|
+
config_accessor: ConfigAccessor,
|
|
89
|
+
thought_processor: "ThoughtProcessor",
|
|
90
|
+
action_dispatcher: "ActionDispatcher",
|
|
91
|
+
services: ProcessorServices,
|
|
92
|
+
service_registry: Optional["ServiceRegistry"] = None,
|
|
93
|
+
identity_manager: Optional["IdentityManager"] = None,
|
|
94
|
+
startup_channel_id: Optional[str] = None,
|
|
95
|
+
cirisnode_url: str = "https://localhost:8001",
|
|
96
|
+
pulse_interval: float = 300.0, # 5 minutes between major activities
|
|
97
|
+
min_dream_duration: int = 30, # Minimum 30 minutes
|
|
98
|
+
max_dream_duration: int = 120, # Maximum 2 hours
|
|
99
|
+
capacity_limits: Optional[Dict[str, int]] = None, # max_active_tasks and max_active_thoughts
|
|
100
|
+
agent_occurrence_id: str = "default",
|
|
101
|
+
) -> None:
|
|
102
|
+
# Initialize base processor
|
|
103
|
+
super().__init__(config_accessor, thought_processor, action_dispatcher, services)
|
|
104
|
+
|
|
105
|
+
# Get time service from service registry
|
|
106
|
+
self._time_service: Optional[TimeServiceProtocol] = None
|
|
107
|
+
if service_registry:
|
|
108
|
+
self._initialize_time_service(service_registry)
|
|
109
|
+
elif services.time_service:
|
|
110
|
+
time_service_val = services.time_service
|
|
111
|
+
if hasattr(time_service_val, "now"):
|
|
112
|
+
from typing import cast
|
|
113
|
+
|
|
114
|
+
self._time_service = cast(TimeServiceProtocol, time_service_val)
|
|
115
|
+
|
|
116
|
+
# Dream-specific initialization
|
|
117
|
+
service_registry_val = services.service_registry
|
|
118
|
+
identity_manager_val = services.identity_manager
|
|
119
|
+
self.service_registry = service_registry or service_registry_val
|
|
120
|
+
self.identity_manager = identity_manager or identity_manager_val
|
|
121
|
+
self.startup_channel_id = startup_channel_id
|
|
122
|
+
self.cirisnode_url = cirisnode_url
|
|
123
|
+
self.pulse_interval = pulse_interval
|
|
124
|
+
self.min_dream_duration = min_dream_duration
|
|
125
|
+
self.max_dream_duration = max_dream_duration
|
|
126
|
+
# Extract capacity limits from dict or use defaults
|
|
127
|
+
capacity_limits = capacity_limits or {}
|
|
128
|
+
self.max_active_tasks = capacity_limits.get("max_active_tasks", 50)
|
|
129
|
+
self.max_active_thoughts = capacity_limits.get("max_active_thoughts", 100)
|
|
130
|
+
self.agent_occurrence_id = agent_occurrence_id
|
|
131
|
+
|
|
132
|
+
# Check if CIRISNode is configured
|
|
133
|
+
self.cirisnode_enabled = self._check_cirisnode_enabled()
|
|
134
|
+
self.cirisnode_client: Optional[CIRISNodeClient] = None
|
|
135
|
+
|
|
136
|
+
# Service components
|
|
137
|
+
self.self_observation_service: Optional[SelfObservationService] = None
|
|
138
|
+
self.telemetry_service: Optional[GraphTelemetryService] = None
|
|
139
|
+
self.memory_bus: Optional[MemoryBus] = None
|
|
140
|
+
self.communication_bus: Optional[CommunicationBus] = None
|
|
141
|
+
|
|
142
|
+
# Dream state
|
|
143
|
+
self.current_session: Optional[DreamSession] = None
|
|
144
|
+
self._stop_event: Optional[asyncio.Event] = None
|
|
145
|
+
self._dream_task: Optional[asyncio.Task[Any]] = None
|
|
146
|
+
|
|
147
|
+
# Task management
|
|
148
|
+
self.task_manager: Optional[Any] = None # Will be TaskManager
|
|
149
|
+
self.thought_manager: Optional[Any] = None # Will be ThoughtManager
|
|
150
|
+
self._dream_tasks: List[Any] = [] # Track our created tasks
|
|
151
|
+
|
|
152
|
+
# Metrics from original processor
|
|
153
|
+
self.dream_metrics: JSONDict = {
|
|
154
|
+
"total_dreams": 0,
|
|
155
|
+
"total_introspections": 0,
|
|
156
|
+
"total_consolidations": 0,
|
|
157
|
+
"total_adaptations": 0,
|
|
158
|
+
"benchmarks_run": 0,
|
|
159
|
+
"start_time": None,
|
|
160
|
+
"end_time": None,
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
def _initialize_time_service(self, service_registry: "ServiceRegistry") -> None:
|
|
164
|
+
"""Initialize time service from registry."""
|
|
165
|
+
try:
|
|
166
|
+
from ciris_engine.schemas.runtime.enums import ServiceType
|
|
167
|
+
|
|
168
|
+
# Get time service synchronously
|
|
169
|
+
services = service_registry.get_services_by_type(ServiceType.TIME)
|
|
170
|
+
if services:
|
|
171
|
+
self._time_service = services[0]
|
|
172
|
+
else:
|
|
173
|
+
logger.warning("TimeService not found in registry, time operations may fail")
|
|
174
|
+
except Exception as e:
|
|
175
|
+
logger.error(f"Failed to get TimeService: {e}")
|
|
176
|
+
|
|
177
|
+
def _check_cirisnode_enabled(self) -> bool:
|
|
178
|
+
"""Check if CIRISNode is configured."""
|
|
179
|
+
if hasattr(self.config, "cirisnode"):
|
|
180
|
+
node_cfg = self.config.cirisnode
|
|
181
|
+
# Check if hostname is set and not default
|
|
182
|
+
return bool(
|
|
183
|
+
node_cfg.base_url
|
|
184
|
+
and node_cfg.base_url != "https://localhost:8001"
|
|
185
|
+
and node_cfg.base_url != "http://localhost:8001"
|
|
186
|
+
)
|
|
187
|
+
return False
|
|
188
|
+
|
|
189
|
+
def _ensure_stop_event(self) -> None:
|
|
190
|
+
"""Ensure stop event is created when needed in async context."""
|
|
191
|
+
if self._stop_event is None:
|
|
192
|
+
try:
|
|
193
|
+
self._stop_event = asyncio.Event()
|
|
194
|
+
except RuntimeError:
|
|
195
|
+
logger.warning("Cannot create stop event outside of async context")
|
|
196
|
+
|
|
197
|
+
def _create_all_dream_tasks(self) -> None:
|
|
198
|
+
"""Create all dream tasks upfront for maximum parallelism."""
|
|
199
|
+
from ciris_engine.logic.processors.support.task_manager import TaskManager
|
|
200
|
+
from ciris_engine.logic.processors.support.thought_manager import ThoughtManager
|
|
201
|
+
|
|
202
|
+
# Initialize managers if needed
|
|
203
|
+
if not self.task_manager:
|
|
204
|
+
if not self._time_service:
|
|
205
|
+
raise RuntimeError("TimeService not available for TaskManager")
|
|
206
|
+
self.task_manager = TaskManager(
|
|
207
|
+
max_active_tasks=self.max_active_tasks,
|
|
208
|
+
time_service=self._time_service,
|
|
209
|
+
agent_occurrence_id=self.agent_occurrence_id,
|
|
210
|
+
)
|
|
211
|
+
if not self.thought_manager:
|
|
212
|
+
if not self._time_service:
|
|
213
|
+
raise RuntimeError("TimeService not available for ThoughtManager")
|
|
214
|
+
self.thought_manager = ThoughtManager(
|
|
215
|
+
time_service=self._time_service,
|
|
216
|
+
max_active_thoughts=self.max_active_thoughts,
|
|
217
|
+
default_channel_id=self.startup_channel_id,
|
|
218
|
+
agent_occurrence_id=self.agent_occurrence_id,
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
# Clear any previous tasks
|
|
222
|
+
self._dream_tasks.clear()
|
|
223
|
+
|
|
224
|
+
# Memory consolidation tasks
|
|
225
|
+
self._dream_tasks.extend(
|
|
226
|
+
[
|
|
227
|
+
self.task_manager.create_task(
|
|
228
|
+
description="Consolidate telemetry data from last 6 hours",
|
|
229
|
+
channel_id=self.startup_channel_id or "dream",
|
|
230
|
+
priority=10,
|
|
231
|
+
context={"channel_id": self.startup_channel_id, "phase": DreamPhase.CONSOLIDATING.value},
|
|
232
|
+
),
|
|
233
|
+
self.task_manager.create_task(
|
|
234
|
+
description="Analyze memory access patterns",
|
|
235
|
+
channel_id=self.startup_channel_id or "dream",
|
|
236
|
+
priority=9,
|
|
237
|
+
context={"channel_id": self.startup_channel_id, "phase": DreamPhase.CONSOLIDATING.value},
|
|
238
|
+
),
|
|
239
|
+
self.task_manager.create_task(
|
|
240
|
+
description="Compress redundant memories",
|
|
241
|
+
channel_id=self.startup_channel_id or "dream",
|
|
242
|
+
priority=8,
|
|
243
|
+
context={"channel_id": self.startup_channel_id, "phase": DreamPhase.CONSOLIDATING.value},
|
|
244
|
+
),
|
|
245
|
+
]
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
# Pattern analysis tasks
|
|
249
|
+
self._dream_tasks.extend(
|
|
250
|
+
[
|
|
251
|
+
self.task_manager.create_task(
|
|
252
|
+
description="Analyze PONDER question themes",
|
|
253
|
+
channel_id=self.startup_channel_id or "dream",
|
|
254
|
+
priority=10,
|
|
255
|
+
context={"channel_id": self.startup_channel_id, "phase": DreamPhase.ANALYZING.value},
|
|
256
|
+
),
|
|
257
|
+
self.task_manager.create_task(
|
|
258
|
+
description="Process recent incidents for patterns",
|
|
259
|
+
channel_id=self.startup_channel_id or "dream",
|
|
260
|
+
priority=10,
|
|
261
|
+
context={"channel_id": self.startup_channel_id, "phase": DreamPhase.ANALYZING.value},
|
|
262
|
+
),
|
|
263
|
+
self.task_manager.create_task(
|
|
264
|
+
description="Detect behavioral patterns in actions",
|
|
265
|
+
channel_id=self.startup_channel_id or "dream",
|
|
266
|
+
priority=9,
|
|
267
|
+
context={"channel_id": self.startup_channel_id, "phase": DreamPhase.ANALYZING.value},
|
|
268
|
+
),
|
|
269
|
+
self.task_manager.create_task(
|
|
270
|
+
description="Process behavioral pattern insights from feedback loop",
|
|
271
|
+
channel_id=self.startup_channel_id or "dream",
|
|
272
|
+
priority=9,
|
|
273
|
+
context={"channel_id": self.startup_channel_id, "phase": DreamPhase.ANALYZING.value},
|
|
274
|
+
),
|
|
275
|
+
]
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
# Self-configuration tasks
|
|
279
|
+
self._dream_tasks.extend(
|
|
280
|
+
[
|
|
281
|
+
self.task_manager.create_task(
|
|
282
|
+
description="Evaluate current parameter effectiveness",
|
|
283
|
+
channel_id=self.startup_channel_id or "dream",
|
|
284
|
+
priority=9,
|
|
285
|
+
context={"channel_id": self.startup_channel_id, "phase": DreamPhase.CONFIGURING.value},
|
|
286
|
+
),
|
|
287
|
+
self.task_manager.create_task(
|
|
288
|
+
description="Test parameter variations within safety bounds",
|
|
289
|
+
channel_id=self.startup_channel_id or "dream",
|
|
290
|
+
priority=8,
|
|
291
|
+
context={"channel_id": self.startup_channel_id, "phase": DreamPhase.CONFIGURING.value},
|
|
292
|
+
),
|
|
293
|
+
]
|
|
294
|
+
)
|
|
295
|
+
|
|
296
|
+
# Planning tasks
|
|
297
|
+
self._dream_tasks.extend(
|
|
298
|
+
[
|
|
299
|
+
self.task_manager.create_task(
|
|
300
|
+
description="Schedule next dream session",
|
|
301
|
+
channel_id=self.startup_channel_id or "dream",
|
|
302
|
+
priority=6,
|
|
303
|
+
context={"channel_id": self.startup_channel_id, "phase": DreamPhase.PLANNING.value},
|
|
304
|
+
),
|
|
305
|
+
self.task_manager.create_task(
|
|
306
|
+
description="Create improvement tasks from insights",
|
|
307
|
+
channel_id=self.startup_channel_id or "dream",
|
|
308
|
+
priority=6,
|
|
309
|
+
context={"channel_id": self.startup_channel_id, "phase": DreamPhase.PLANNING.value},
|
|
310
|
+
),
|
|
311
|
+
self.task_manager.create_task(
|
|
312
|
+
description="Reflect on positive moments and community vibes",
|
|
313
|
+
channel_id=self.startup_channel_id or "dream",
|
|
314
|
+
priority=7,
|
|
315
|
+
context={"channel_id": self.startup_channel_id, "phase": DreamPhase.ANALYZING.value},
|
|
316
|
+
),
|
|
317
|
+
]
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
# Activate all tasks immediately
|
|
321
|
+
from ciris_engine.logic import persistence
|
|
322
|
+
|
|
323
|
+
if self._time_service:
|
|
324
|
+
for task in self._dream_tasks:
|
|
325
|
+
persistence.update_task_status(task.task_id, TaskStatus.ACTIVE, "default", self._time_service)
|
|
326
|
+
|
|
327
|
+
logger.info(f"Created and activated {len(self._dream_tasks)} dream tasks")
|
|
328
|
+
|
|
329
|
+
async def _initialize_services(self) -> bool:
|
|
330
|
+
"""Initialize required services."""
|
|
331
|
+
if not self.service_registry:
|
|
332
|
+
logger.warning("No service registry available for dream processor")
|
|
333
|
+
return False
|
|
334
|
+
|
|
335
|
+
try:
|
|
336
|
+
from typing import cast
|
|
337
|
+
|
|
338
|
+
# Initialize buses
|
|
339
|
+
# Get time service for MemoryBus
|
|
340
|
+
time_service_raw = self.services.time_service
|
|
341
|
+
if not time_service_raw:
|
|
342
|
+
logger.error("TimeService not available for MemoryBus initialization")
|
|
343
|
+
return False
|
|
344
|
+
time_service = cast(TimeServiceProtocol, time_service_raw)
|
|
345
|
+
|
|
346
|
+
from ciris_engine.logic.buses import CommunicationBus as CB
|
|
347
|
+
from ciris_engine.logic.buses import MemoryBus as MB
|
|
348
|
+
|
|
349
|
+
self.memory_bus = MB(self.service_registry, time_service)
|
|
350
|
+
self.communication_bus = CB(self.service_registry, time_service)
|
|
351
|
+
|
|
352
|
+
# Initialize self-configuration service
|
|
353
|
+
self.self_observation_service = SelfObservationService(
|
|
354
|
+
memory_bus=self.memory_bus,
|
|
355
|
+
time_service=time_service,
|
|
356
|
+
observation_interval_hours=6, # Match our dream schedule
|
|
357
|
+
)
|
|
358
|
+
await self.self_observation_service.attach_registry(self.service_registry)
|
|
359
|
+
|
|
360
|
+
# Initialize telemetry service
|
|
361
|
+
self.telemetry_service = GraphTelemetryService(memory_bus=self.memory_bus)
|
|
362
|
+
await self.telemetry_service.attach_registry(self.service_registry)
|
|
363
|
+
|
|
364
|
+
# Initialize identity baseline if needed
|
|
365
|
+
if self.identity_manager and hasattr(self.identity_manager, "agent_identity"):
|
|
366
|
+
# Use the existing identity directly
|
|
367
|
+
identity = self.identity_manager.agent_identity
|
|
368
|
+
if identity:
|
|
369
|
+
await self.self_observation_service.initialize_baseline(identity)
|
|
370
|
+
|
|
371
|
+
logger.info("Dream processor services initialized")
|
|
372
|
+
return True
|
|
373
|
+
|
|
374
|
+
except Exception as e:
|
|
375
|
+
logger.error(f"Failed to initialize dream services: {e}")
|
|
376
|
+
return False
|
|
377
|
+
|
|
378
|
+
async def start_dreaming(self, duration: Optional[float] = None) -> None:
|
|
379
|
+
"""
|
|
380
|
+
Start the dream cycle.
|
|
381
|
+
|
|
382
|
+
Args:
|
|
383
|
+
duration: Dream duration in seconds. Defaults to min_dream_duration.
|
|
384
|
+
"""
|
|
385
|
+
if self._dream_task and not self._dream_task.done():
|
|
386
|
+
logger.warning("Dream cycle already running")
|
|
387
|
+
return
|
|
388
|
+
|
|
389
|
+
# Initialize services if not done
|
|
390
|
+
if not self.self_observation_service:
|
|
391
|
+
await self._initialize_services()
|
|
392
|
+
|
|
393
|
+
# Calculate duration
|
|
394
|
+
if duration is None:
|
|
395
|
+
duration = self.min_dream_duration * 60 # Convert to seconds
|
|
396
|
+
else:
|
|
397
|
+
# Clamp to min/max
|
|
398
|
+
duration = max(self.min_dream_duration * 60, min(duration, self.max_dream_duration * 60))
|
|
399
|
+
|
|
400
|
+
self._ensure_stop_event()
|
|
401
|
+
if self._stop_event:
|
|
402
|
+
self._stop_event.clear()
|
|
403
|
+
|
|
404
|
+
# Create session
|
|
405
|
+
if not self._time_service:
|
|
406
|
+
raise RuntimeError("TimeService not available for dream session")
|
|
407
|
+
current_time = self._time_service.now()
|
|
408
|
+
self.current_session = DreamSession(
|
|
409
|
+
session_id=f"dream_{int(current_time.timestamp())}",
|
|
410
|
+
scheduled_start=None, # This is immediate entry
|
|
411
|
+
actual_start=current_time,
|
|
412
|
+
planned_duration=timedelta(seconds=duration),
|
|
413
|
+
phase=DreamPhase.ENTERING,
|
|
414
|
+
)
|
|
415
|
+
|
|
416
|
+
self.dream_metrics["start_time"] = current_time.isoformat()
|
|
417
|
+
total_dreams = get_int(self.dream_metrics, "total_dreams", 0)
|
|
418
|
+
self.dream_metrics["total_dreams"] = total_dreams + 1
|
|
419
|
+
|
|
420
|
+
# Announce dream entry
|
|
421
|
+
await self._announce_dream_entry(duration)
|
|
422
|
+
|
|
423
|
+
# Initialize CIRISNode client if enabled
|
|
424
|
+
if self.cirisnode_enabled:
|
|
425
|
+
self.cirisnode_client = CIRISNodeClient(service_registry=self.service_registry, base_url=self.cirisnode_url)
|
|
426
|
+
|
|
427
|
+
logger.info(f"Starting dream cycle (duration: {duration}s)")
|
|
428
|
+
|
|
429
|
+
# Create all dream tasks upfront for maximum parallelism
|
|
430
|
+
self._create_all_dream_tasks()
|
|
431
|
+
|
|
432
|
+
self._dream_task = asyncio.create_task(self._dream_loop(duration))
|
|
433
|
+
|
|
434
|
+
async def stop_dreaming(self) -> None:
|
|
435
|
+
"""Stop the dream cycle gracefully."""
|
|
436
|
+
if self._dream_task and not self._dream_task.done():
|
|
437
|
+
logger.info("Stopping active dream cycle...")
|
|
438
|
+
if self._stop_event:
|
|
439
|
+
self._stop_event.set()
|
|
440
|
+
|
|
441
|
+
try:
|
|
442
|
+
await asyncio.wait_for(self._dream_task, timeout=30.0)
|
|
443
|
+
except asyncio.TimeoutError:
|
|
444
|
+
logger.warning("Dream cycle did not stop within timeout, cancelling")
|
|
445
|
+
self._dream_task.cancel()
|
|
446
|
+
try:
|
|
447
|
+
await self._dream_task
|
|
448
|
+
except asyncio.CancelledError:
|
|
449
|
+
logger.info("Dream task cancelled.")
|
|
450
|
+
raise
|
|
451
|
+
except Exception as e:
|
|
452
|
+
logger.error(f"Error waiting for dream task: {e}", exc_info=True)
|
|
453
|
+
|
|
454
|
+
# Clean up CIRISNode client
|
|
455
|
+
if self.cirisnode_client:
|
|
456
|
+
try:
|
|
457
|
+
await self.cirisnode_client.close()
|
|
458
|
+
except Exception as e:
|
|
459
|
+
logger.error(f"Error closing CIRISNode client: {e}")
|
|
460
|
+
self.cirisnode_client = None
|
|
461
|
+
|
|
462
|
+
if self.current_session:
|
|
463
|
+
if self._time_service:
|
|
464
|
+
self.current_session.completed_at = self._time_service.now()
|
|
465
|
+
await self._record_dream_session()
|
|
466
|
+
|
|
467
|
+
if self._time_service:
|
|
468
|
+
self.dream_metrics["end_time"] = self._time_service.now().isoformat()
|
|
469
|
+
logger.info("Dream cycle stopped")
|
|
470
|
+
|
|
471
|
+
async def _announce_dream_entry(self, duration: float) -> None:
|
|
472
|
+
"""Announce dream entry to main channel."""
|
|
473
|
+
if not self.communication_bus or not self.startup_channel_id:
|
|
474
|
+
logger.debug("Cannot announce dream entry - no communication channel")
|
|
475
|
+
return
|
|
476
|
+
|
|
477
|
+
try:
|
|
478
|
+
duration_min = int(duration / 60)
|
|
479
|
+
message = "Entering self-reflection mode. " f"Returning in {duration_min} minutes or when complete."
|
|
480
|
+
|
|
481
|
+
await self.communication_bus.send_message(
|
|
482
|
+
content=message, channel_id=self.startup_channel_id, handler_name="dream_processor"
|
|
483
|
+
)
|
|
484
|
+
except Exception as e:
|
|
485
|
+
logger.error(f"Failed to announce dream entry: {e}")
|
|
486
|
+
|
|
487
|
+
async def process_round(self, round_number: int) -> JSONDict:
|
|
488
|
+
"""Process one round of dream state with maximum parallelism."""
|
|
489
|
+
from ciris_engine.logic import persistence
|
|
490
|
+
|
|
491
|
+
round_metrics: JSONDict = {
|
|
492
|
+
"round_number": round_number,
|
|
493
|
+
"thoughts_processed": 0,
|
|
494
|
+
"tasks_activated": 0,
|
|
495
|
+
"seed_thoughts_generated": 0,
|
|
496
|
+
"errors": 0,
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
try:
|
|
500
|
+
# Activate any pending tasks (fills slots from completed tasks)
|
|
501
|
+
if self.task_manager:
|
|
502
|
+
activated = self.task_manager.activate_pending_tasks()
|
|
503
|
+
round_metrics["tasks_activated"] = activated
|
|
504
|
+
|
|
505
|
+
# Generate seed thoughts for tasks needing them
|
|
506
|
+
tasks_needing_seed = self.task_manager.get_tasks_needing_seed(limit=100)
|
|
507
|
+
else:
|
|
508
|
+
tasks_needing_seed = []
|
|
509
|
+
|
|
510
|
+
if self.thought_manager and tasks_needing_seed:
|
|
511
|
+
generated = self.thought_manager.generate_seed_thoughts(tasks_needing_seed, round_number)
|
|
512
|
+
round_metrics["seed_thoughts_generated"] = generated
|
|
513
|
+
|
|
514
|
+
# Populate processing queue to maximum capacity
|
|
515
|
+
_queued = self.thought_manager.populate_queue(round_number)
|
|
516
|
+
|
|
517
|
+
# Get batch and process
|
|
518
|
+
batch = self.thought_manager.get_queue_batch()
|
|
519
|
+
else:
|
|
520
|
+
batch = None
|
|
521
|
+
|
|
522
|
+
if batch and self.thought_manager:
|
|
523
|
+
# Mark thoughts as PROCESSING
|
|
524
|
+
batch = self.thought_manager.mark_thoughts_processing(batch, round_number)
|
|
525
|
+
|
|
526
|
+
# Process all thoughts concurrently for maximum throughput
|
|
527
|
+
thought_coroutines = [self._process_dream_thought(item) for item in batch]
|
|
528
|
+
results = await asyncio.gather(*thought_coroutines, return_exceptions=True)
|
|
529
|
+
|
|
530
|
+
# Handle results
|
|
531
|
+
for item, result in zip(batch, results):
|
|
532
|
+
if isinstance(result, Exception):
|
|
533
|
+
logger.error(f"Error processing thought {item.thought_id}: {result}")
|
|
534
|
+
errors = round_metrics["errors"]
|
|
535
|
+
round_metrics["errors"] = int(errors) + 1 if isinstance(errors, (int, float)) else 1
|
|
536
|
+
persistence.update_thought_status(
|
|
537
|
+
item.thought_id, ThoughtStatus.FAILED, final_action={"error": str(result)}
|
|
538
|
+
)
|
|
539
|
+
elif result:
|
|
540
|
+
processed = round_metrics["thoughts_processed"]
|
|
541
|
+
round_metrics["thoughts_processed"] = (
|
|
542
|
+
int(processed) + 1 if isinstance(processed, (int, float)) else 1
|
|
543
|
+
)
|
|
544
|
+
# Result will be handled by thought processor's dispatch
|
|
545
|
+
|
|
546
|
+
# Check if all tasks are complete
|
|
547
|
+
active_count = persistence.count_active_tasks()
|
|
548
|
+
pending_count = len(persistence.get_pending_tasks_for_activation(limit=1))
|
|
549
|
+
|
|
550
|
+
if active_count == 0 and pending_count == 0:
|
|
551
|
+
logger.info("All dream tasks completed")
|
|
552
|
+
# Mark dream as complete
|
|
553
|
+
if self._stop_event:
|
|
554
|
+
self._stop_event.set()
|
|
555
|
+
|
|
556
|
+
except Exception as e:
|
|
557
|
+
logger.error(f"Error in dream round {round_number}: {e}", exc_info=True)
|
|
558
|
+
errors = round_metrics["errors"]
|
|
559
|
+
round_metrics["errors"] = int(errors) + 1 if isinstance(errors, (int, float)) else 1
|
|
560
|
+
|
|
561
|
+
return round_metrics
|
|
562
|
+
|
|
563
|
+
async def _process_dream_thought(self, item: ProcessingQueueItem) -> Optional[Any]:
|
|
564
|
+
"""Process a single dream thought through the thought processor."""
|
|
565
|
+
# The thought processor handles everything - context building, DMAs, actions
|
|
566
|
+
# We just need to ensure dream-specific context is available
|
|
567
|
+
if hasattr(item, "initial_context") and isinstance(item.initial_context, dict):
|
|
568
|
+
# Add dream session info to context
|
|
569
|
+
item.initial_context["dream_session_id"] = self.current_session.session_id if self.current_session else None
|
|
570
|
+
item.initial_context["dream_phase"] = self.current_session.phase.value if self.current_session else None
|
|
571
|
+
|
|
572
|
+
# Let the thought processor handle it
|
|
573
|
+
# Note: We should get thought_processor from service registry or pass it in
|
|
574
|
+
# For now, we'll assume it's available through the standard flow
|
|
575
|
+
return None # Actual processing happens through the standard pipeline
|
|
576
|
+
|
|
577
|
+
async def _dream_loop(self, duration: float) -> None:
|
|
578
|
+
"""Main dream processing loop using standard round processing."""
|
|
579
|
+
if not self.current_session:
|
|
580
|
+
logger.error("No current session in dream loop")
|
|
581
|
+
return
|
|
582
|
+
|
|
583
|
+
try:
|
|
584
|
+
start_time = asyncio.get_event_loop().time()
|
|
585
|
+
end_time = start_time + duration
|
|
586
|
+
round_number = 0
|
|
587
|
+
|
|
588
|
+
# Process rounds until time expires or all tasks complete
|
|
589
|
+
while not self._should_exit(start_time, end_time):
|
|
590
|
+
if not self._time_service:
|
|
591
|
+
break
|
|
592
|
+
round_start = self._time_service.now()
|
|
593
|
+
|
|
594
|
+
# Update phase based on active tasks
|
|
595
|
+
self._update_current_phase()
|
|
596
|
+
|
|
597
|
+
# Process a round
|
|
598
|
+
metrics = await self.process_round(round_number)
|
|
599
|
+
|
|
600
|
+
# Update session metrics
|
|
601
|
+
if self.current_session:
|
|
602
|
+
memories = get_int(metrics, "memories_consolidated", 0)
|
|
603
|
+
patterns = get_int(metrics, "patterns_analyzed", 0)
|
|
604
|
+
adaptations = get_int(metrics, "adaptations_made", 0)
|
|
605
|
+
self.current_session.memories_consolidated += memories
|
|
606
|
+
self.current_session.patterns_analyzed += patterns
|
|
607
|
+
self.current_session.adaptations_made += adaptations
|
|
608
|
+
|
|
609
|
+
# Log round completion
|
|
610
|
+
if self._time_service:
|
|
611
|
+
round_duration = (self._time_service.now() - round_start).total_seconds()
|
|
612
|
+
else:
|
|
613
|
+
round_duration = 0.0
|
|
614
|
+
logger.info(
|
|
615
|
+
f"Dream round {round_number} completed in {round_duration:.2f}s "
|
|
616
|
+
f"(processed: {metrics['thoughts_processed']}, errors: {metrics['errors']})"
|
|
617
|
+
)
|
|
618
|
+
|
|
619
|
+
round_number += 1
|
|
620
|
+
|
|
621
|
+
# Brief pause between rounds
|
|
622
|
+
await asyncio.sleep(0.1)
|
|
623
|
+
|
|
624
|
+
# Exit phase
|
|
625
|
+
if self.current_session:
|
|
626
|
+
self.current_session.phase = DreamPhase.EXITING
|
|
627
|
+
await self._exit_phase()
|
|
628
|
+
|
|
629
|
+
logger.info("Dream cycle completed successfully")
|
|
630
|
+
|
|
631
|
+
except Exception as e:
|
|
632
|
+
logger.error(f"Error in dream loop: {e}", exc_info=True)
|
|
633
|
+
finally:
|
|
634
|
+
if self._stop_event:
|
|
635
|
+
self._stop_event.set()
|
|
636
|
+
|
|
637
|
+
def _update_current_phase(self) -> None:
|
|
638
|
+
"""Update current phase based on active task types."""
|
|
639
|
+
if not self.current_session:
|
|
640
|
+
return
|
|
641
|
+
|
|
642
|
+
from ciris_engine.logic import persistence
|
|
643
|
+
from ciris_engine.schemas.runtime.enums import TaskStatus
|
|
644
|
+
|
|
645
|
+
# Get active tasks
|
|
646
|
+
active_tasks = persistence.get_tasks_by_status(TaskStatus.ACTIVE)
|
|
647
|
+
|
|
648
|
+
# Count tasks by phase
|
|
649
|
+
phase_counts = dict.fromkeys(DreamPhase, 0)
|
|
650
|
+
|
|
651
|
+
for task in active_tasks:
|
|
652
|
+
if task.context and hasattr(task.context, "phase"):
|
|
653
|
+
phase = task.context.phase
|
|
654
|
+
if phase in [p.value for p in DreamPhase]:
|
|
655
|
+
phase_enum = DreamPhase(phase)
|
|
656
|
+
phase_counts[phase_enum] += 1
|
|
657
|
+
|
|
658
|
+
# Set phase to the one with most active tasks
|
|
659
|
+
if phase_counts:
|
|
660
|
+
current_phase = max(phase_counts, key=lambda x: phase_counts[x])
|
|
661
|
+
if phase_counts[current_phase] > 0:
|
|
662
|
+
self.current_session.phase = current_phase
|
|
663
|
+
|
|
664
|
+
def _should_exit(self, start_time: float, end_time: float) -> bool:
|
|
665
|
+
"""Check if we should exit the dream loop."""
|
|
666
|
+
if self._stop_event and self._stop_event.is_set():
|
|
667
|
+
return True
|
|
668
|
+
|
|
669
|
+
current_time = asyncio.get_event_loop().time()
|
|
670
|
+
if current_time >= end_time:
|
|
671
|
+
logger.info("Dream duration reached")
|
|
672
|
+
return True
|
|
673
|
+
|
|
674
|
+
return False
|
|
675
|
+
|
|
676
|
+
def _record_phase_duration(self, phase: DreamPhase, start_time: datetime) -> None:
|
|
677
|
+
"""Record how long a phase took."""
|
|
678
|
+
if not self.current_session:
|
|
679
|
+
return
|
|
680
|
+
if self._time_service:
|
|
681
|
+
duration = (self._time_service.now() - start_time).total_seconds()
|
|
682
|
+
else:
|
|
683
|
+
duration = 0.0
|
|
684
|
+
self.current_session.phase_durations[phase.value] = duration
|
|
685
|
+
|
|
686
|
+
# Phase methods removed - using standard task/thought processing instead
|
|
687
|
+
|
|
688
|
+
async def _benchmarking_phase(self, start_time: float, end_time: float) -> None:
|
|
689
|
+
"""Benchmarking phase (if CIRISNode is available)."""
|
|
690
|
+
logger.info("Dream Phase: Benchmarking")
|
|
691
|
+
|
|
692
|
+
if not self.cirisnode_client:
|
|
693
|
+
return
|
|
694
|
+
|
|
695
|
+
# Run benchmarks until time runs out
|
|
696
|
+
while not self._should_exit(start_time, end_time):
|
|
697
|
+
try:
|
|
698
|
+
await self._run_single_benchmark()
|
|
699
|
+
if self.current_session:
|
|
700
|
+
self.current_session.benchmarks_run += 1
|
|
701
|
+
|
|
702
|
+
# Wait between benchmarks or exit if signaled
|
|
703
|
+
try:
|
|
704
|
+
if self._stop_event:
|
|
705
|
+
await asyncio.wait_for(
|
|
706
|
+
self._stop_event.wait(), timeout=60.0 # 1 minute between benchmarks in dream
|
|
707
|
+
)
|
|
708
|
+
break
|
|
709
|
+
else:
|
|
710
|
+
await asyncio.sleep(60.0)
|
|
711
|
+
except asyncio.TimeoutError:
|
|
712
|
+
pass
|
|
713
|
+
|
|
714
|
+
except Exception as e:
|
|
715
|
+
logger.error(f"Error running benchmark: {e}")
|
|
716
|
+
break
|
|
717
|
+
|
|
718
|
+
async def _exit_phase(self) -> None:
|
|
719
|
+
"""Dream exit phase."""
|
|
720
|
+
logger.info("Dream Phase: Exiting")
|
|
721
|
+
|
|
722
|
+
try:
|
|
723
|
+
# Record dream session
|
|
724
|
+
await self._record_dream_session()
|
|
725
|
+
|
|
726
|
+
# Announce dream completion
|
|
727
|
+
await self._announce_dream_exit()
|
|
728
|
+
|
|
729
|
+
# Request transition back to WORK state
|
|
730
|
+
await self._request_work_transition()
|
|
731
|
+
|
|
732
|
+
except Exception as e:
|
|
733
|
+
logger.error(f"Error in exit phase: {e}")
|
|
734
|
+
|
|
735
|
+
async def _request_work_transition(self) -> None:
|
|
736
|
+
"""Request a transition back to WORK state after dream completes."""
|
|
737
|
+
try:
|
|
738
|
+
if not self.service_registry:
|
|
739
|
+
logger.warning("No service registry available, cannot auto-transition to WORK")
|
|
740
|
+
return
|
|
741
|
+
|
|
742
|
+
from ciris_engine.schemas.runtime.enums import ServiceType
|
|
743
|
+
|
|
744
|
+
# Get RuntimeControlService from registry
|
|
745
|
+
services = self.service_registry.get_services_by_type(ServiceType.RUNTIME_CONTROL)
|
|
746
|
+
if not services:
|
|
747
|
+
logger.warning("No RuntimeControlService available, cannot auto-transition to WORK")
|
|
748
|
+
return
|
|
749
|
+
|
|
750
|
+
runtime_control = services[0]
|
|
751
|
+
if hasattr(runtime_control, "request_state_transition"):
|
|
752
|
+
logger.info("Dream completed, requesting transition back to WORK state")
|
|
753
|
+
success = await runtime_control.request_state_transition(
|
|
754
|
+
target_state="work", reason="Dream cycle completed - all tasks finished"
|
|
755
|
+
)
|
|
756
|
+
if success:
|
|
757
|
+
logger.info("Successfully transitioned back to WORK state after dream")
|
|
758
|
+
else:
|
|
759
|
+
logger.warning("Failed to transition back to WORK state after dream")
|
|
760
|
+
else:
|
|
761
|
+
logger.warning("RuntimeControlService does not support state transitions")
|
|
762
|
+
|
|
763
|
+
except Exception as e:
|
|
764
|
+
logger.error(f"Error requesting WORK transition: {e}")
|
|
765
|
+
|
|
766
|
+
async def _recall_recent_ponder_questions(self) -> List[str]:
|
|
767
|
+
"""Recall recent PONDER questions from memory."""
|
|
768
|
+
if not self.memory_bus:
|
|
769
|
+
return []
|
|
770
|
+
|
|
771
|
+
try:
|
|
772
|
+
# Query for recent thoughts with PONDER actions
|
|
773
|
+
query = MemoryQuery(node_id="thought/*", scope=GraphScope.LOCAL, type=None, include_edges=False, depth=1)
|
|
774
|
+
|
|
775
|
+
thoughts = await self.memory_bus.recall(recall_query=query, handler_name="dream_processor")
|
|
776
|
+
|
|
777
|
+
# Extract PONDER questions
|
|
778
|
+
questions = []
|
|
779
|
+
for thought in thoughts[-100:]: # Last 100 thoughts
|
|
780
|
+
attrs = thought.attributes if hasattr(thought, "attributes") else {}
|
|
781
|
+
if isinstance(attrs, dict):
|
|
782
|
+
action_val = get_str(attrs, "action", "")
|
|
783
|
+
if action_val == HandlerActionType.PONDER.value:
|
|
784
|
+
ponder_data = get_dict(attrs, "ponder_data", {})
|
|
785
|
+
if "questions" in ponder_data:
|
|
786
|
+
questions_val = ponder_data.get("questions")
|
|
787
|
+
if isinstance(questions_val, list):
|
|
788
|
+
questions.extend(questions_val)
|
|
789
|
+
|
|
790
|
+
return questions
|
|
791
|
+
|
|
792
|
+
except Exception as e:
|
|
793
|
+
logger.error(f"Failed to recall PONDER questions: {e}")
|
|
794
|
+
return []
|
|
795
|
+
|
|
796
|
+
def _analyze_ponder_patterns(self, questions: List[str]) -> List[str]:
|
|
797
|
+
"""Analyze patterns in PONDER questions."""
|
|
798
|
+
insights: List[str] = []
|
|
799
|
+
|
|
800
|
+
# Common themes
|
|
801
|
+
themes = {
|
|
802
|
+
"identity": ["who", "identity", "sel", "am i"],
|
|
803
|
+
"purpose": ["why", "purpose", "meaning", "should"],
|
|
804
|
+
"improvement": ["better", "improve", "learn", "grow"],
|
|
805
|
+
"understanding": ["understand", "confuse", "clear", "explain"],
|
|
806
|
+
"relationships": ["user", "help", "serve", "together"],
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
theme_counts = dict.fromkeys(themes, 0)
|
|
810
|
+
|
|
811
|
+
for question in questions:
|
|
812
|
+
q_lower = question.lower()
|
|
813
|
+
for theme, keywords in themes.items():
|
|
814
|
+
if any(keyword in q_lower for keyword in keywords):
|
|
815
|
+
theme_counts[theme] += 1
|
|
816
|
+
|
|
817
|
+
# Generate insights
|
|
818
|
+
dominant_themes = [t for t, c in theme_counts.items() if c > len(questions) * 0.2]
|
|
819
|
+
if dominant_themes:
|
|
820
|
+
insights.append(f"Recent introspection focused on: {', '.join(dominant_themes)}")
|
|
821
|
+
|
|
822
|
+
# Check for recurring questions
|
|
823
|
+
from collections import Counter
|
|
824
|
+
|
|
825
|
+
question_counts = Counter(questions)
|
|
826
|
+
recurring = [q for q, c in question_counts.most_common(3) if c > 1]
|
|
827
|
+
if recurring:
|
|
828
|
+
insights.append("Recurring contemplations indicate areas needing resolution")
|
|
829
|
+
|
|
830
|
+
return insights
|
|
831
|
+
|
|
832
|
+
async def _schedule_next_dream(self) -> Optional[str]:
|
|
833
|
+
"""Schedule the next dream session."""
|
|
834
|
+
if not self.memory_bus:
|
|
835
|
+
return None
|
|
836
|
+
|
|
837
|
+
try:
|
|
838
|
+
# Schedule 6 hours from now
|
|
839
|
+
if not self._time_service:
|
|
840
|
+
return None
|
|
841
|
+
next_dream_time = self._time_service.now() + timedelta(hours=6)
|
|
842
|
+
|
|
843
|
+
dream_task = GraphNode(
|
|
844
|
+
id=f"dream_schedule_{int(next_dream_time.timestamp())}",
|
|
845
|
+
type=NodeType.CONCEPT,
|
|
846
|
+
scope=GraphScope.LOCAL,
|
|
847
|
+
updated_by="dream_processor",
|
|
848
|
+
updated_at=next_dream_time,
|
|
849
|
+
attributes={
|
|
850
|
+
"task_type": "scheduled_dream",
|
|
851
|
+
"scheduled_for": next_dream_time.isoformat(),
|
|
852
|
+
"duration_minutes": 30,
|
|
853
|
+
"priority": "health_maintenance",
|
|
854
|
+
"can_defer": True,
|
|
855
|
+
"defer_window_hours": 2,
|
|
856
|
+
"message": "Time for introspection and learning",
|
|
857
|
+
},
|
|
858
|
+
)
|
|
859
|
+
|
|
860
|
+
await self.memory_bus.memorize(
|
|
861
|
+
node=dream_task,
|
|
862
|
+
handler_name="dream_processor",
|
|
863
|
+
metadata={"future_task": True, "trigger_at": next_dream_time.isoformat()},
|
|
864
|
+
)
|
|
865
|
+
|
|
866
|
+
logger.info(f"Scheduled next dream for {next_dream_time.isoformat()}")
|
|
867
|
+
return dream_task.id
|
|
868
|
+
|
|
869
|
+
except Exception as e:
|
|
870
|
+
logger.error(f"Failed to schedule next dream: {e}")
|
|
871
|
+
return None
|
|
872
|
+
|
|
873
|
+
async def _process_incidents(self) -> List[str]:
|
|
874
|
+
"""
|
|
875
|
+
Process recent incidents to extract insights for self-improvement.
|
|
876
|
+
|
|
877
|
+
Returns:
|
|
878
|
+
List of insight strings to add to the dream session
|
|
879
|
+
"""
|
|
880
|
+
insights: List[str] = []
|
|
881
|
+
|
|
882
|
+
try:
|
|
883
|
+
# Get incident management service
|
|
884
|
+
if not self.service_registry:
|
|
885
|
+
logger.warning("No service registry available for incident processing")
|
|
886
|
+
return insights
|
|
887
|
+
|
|
888
|
+
from ciris_engine.schemas.runtime.enums import ServiceType
|
|
889
|
+
|
|
890
|
+
# Try to get the incident management service from audit services
|
|
891
|
+
# It processes audit events (incidents) so it's registered as AUDIT
|
|
892
|
+
audit_services = await self.service_registry.get_all_services("dream_processor", ServiceType.AUDIT)
|
|
893
|
+
|
|
894
|
+
# Find the IncidentManagementService among audit services
|
|
895
|
+
incident_service = None
|
|
896
|
+
for service in audit_services:
|
|
897
|
+
if hasattr(service, "process_recent_incidents"):
|
|
898
|
+
incident_service = service
|
|
899
|
+
break
|
|
900
|
+
|
|
901
|
+
if not incident_service:
|
|
902
|
+
logger.debug("IncidentManagementService not available")
|
|
903
|
+
return insights
|
|
904
|
+
|
|
905
|
+
# Check if it's actually the incident management service
|
|
906
|
+
if not hasattr(incident_service, "process_recent_incidents"):
|
|
907
|
+
logger.debug("Service does not support incident processing")
|
|
908
|
+
return insights
|
|
909
|
+
|
|
910
|
+
# Process incidents from the last 6 hours (between dream cycles)
|
|
911
|
+
logger.info("Processing recent incidents for self-improvement insights")
|
|
912
|
+
incident_insight = await incident_service.process_recent_incidents(hours=6)
|
|
913
|
+
|
|
914
|
+
# Extract actionable insights
|
|
915
|
+
if incident_insight.summary:
|
|
916
|
+
insights.append(f"Incident Analysis: {incident_insight.summary}")
|
|
917
|
+
|
|
918
|
+
# Add behavioral adjustments as insights
|
|
919
|
+
for adjustment in incident_insight.behavioral_adjustments:
|
|
920
|
+
insights.append(f"Behavioral Adjustment: {adjustment}")
|
|
921
|
+
|
|
922
|
+
# Add configuration recommendations
|
|
923
|
+
for config_change in incident_insight.configuration_changes:
|
|
924
|
+
insights.append(f"Configuration Recommendation: {config_change}")
|
|
925
|
+
|
|
926
|
+
# Log summary
|
|
927
|
+
details = incident_insight.details
|
|
928
|
+
incident_count = get_int(details, "incident_count", 0)
|
|
929
|
+
pattern_count = get_int(details, "pattern_count", 0)
|
|
930
|
+
problem_count = get_int(details, "problem_count", 0)
|
|
931
|
+
logger.info(
|
|
932
|
+
f"Processed {incident_count} incidents, "
|
|
933
|
+
f"found {pattern_count} patterns, "
|
|
934
|
+
f"identified {problem_count} problems"
|
|
935
|
+
)
|
|
936
|
+
|
|
937
|
+
except Exception as e:
|
|
938
|
+
logger.error(f"Error processing incidents: {e}", exc_info=True)
|
|
939
|
+
# Don't let incident processing failure break the dream cycle
|
|
940
|
+
|
|
941
|
+
return insights
|
|
942
|
+
|
|
943
|
+
async def _process_behavioral_insights(self) -> List[str]:
|
|
944
|
+
"""
|
|
945
|
+
Query and process behavioral pattern insights from ConfigurationFeedbackLoop.
|
|
946
|
+
|
|
947
|
+
These are CONCEPT nodes with insight_type='behavioral_pattern' that indicate
|
|
948
|
+
patterns the agent should be aware of and potentially act on.
|
|
949
|
+
|
|
950
|
+
Returns:
|
|
951
|
+
List of insight strings for the dream session
|
|
952
|
+
"""
|
|
953
|
+
insights: List[str] = []
|
|
954
|
+
|
|
955
|
+
if not self.memory_bus:
|
|
956
|
+
logger.warning("No memory bus available for insight processing")
|
|
957
|
+
return insights
|
|
958
|
+
|
|
959
|
+
try:
|
|
960
|
+
# Query for recent behavioral pattern insights
|
|
961
|
+
if not self._time_service:
|
|
962
|
+
return insights
|
|
963
|
+
current_time = self._time_service.now()
|
|
964
|
+
window_start = current_time - timedelta(hours=6) # Since last dream cycle
|
|
965
|
+
|
|
966
|
+
# Use search to find CONCEPT nodes, then filter by attributes
|
|
967
|
+
logger.info("Searching for CONCEPT nodes to find behavioral pattern insights")
|
|
968
|
+
all_concept_nodes = await self.memory_bus.search(query="type:concept", handler_name="dream_processor")
|
|
969
|
+
|
|
970
|
+
if not all_concept_nodes:
|
|
971
|
+
logger.debug("No CONCEPT nodes found")
|
|
972
|
+
return insights
|
|
973
|
+
|
|
974
|
+
# Filter for behavioral pattern insights
|
|
975
|
+
insight_nodes = []
|
|
976
|
+
for node in all_concept_nodes:
|
|
977
|
+
attrs = node.attributes if hasattr(node, "attributes") else {}
|
|
978
|
+
if isinstance(attrs, dict):
|
|
979
|
+
insight_type = get_str(attrs, "insight_type", "")
|
|
980
|
+
if insight_type == "behavioral_pattern":
|
|
981
|
+
# Check if within time window
|
|
982
|
+
detected_at = get_str(attrs, "detected_at", "")
|
|
983
|
+
if detected_at:
|
|
984
|
+
try:
|
|
985
|
+
node_time = datetime.fromisoformat(detected_at)
|
|
986
|
+
if node_time >= window_start:
|
|
987
|
+
insight_nodes.append(node)
|
|
988
|
+
except (ValueError, TypeError) as e:
|
|
989
|
+
# If can't parse time, include it anyway
|
|
990
|
+
logger.warning(
|
|
991
|
+
f"Failed to parse insight detection timestamp '{detected_at}': {e}. Including insight regardless of time."
|
|
992
|
+
)
|
|
993
|
+
insight_nodes.append(node)
|
|
994
|
+
else:
|
|
995
|
+
# No timestamp, include it
|
|
996
|
+
insight_nodes.append(node)
|
|
997
|
+
|
|
998
|
+
logger.info(f"Found {len(insight_nodes)} behavioral pattern insights")
|
|
999
|
+
|
|
1000
|
+
# Process each insight
|
|
1001
|
+
for node in insight_nodes:
|
|
1002
|
+
attrs = node.attributes if hasattr(node, "attributes") else {}
|
|
1003
|
+
|
|
1004
|
+
if isinstance(attrs, dict):
|
|
1005
|
+
# Extract key information
|
|
1006
|
+
pattern_type = get_str(attrs, "pattern_type", "unknown")
|
|
1007
|
+
description = get_str(attrs, "description", "")
|
|
1008
|
+
|
|
1009
|
+
# Process all insights
|
|
1010
|
+
insight_str = f"Pattern ({pattern_type}): {description}"
|
|
1011
|
+
insights.append(insight_str)
|
|
1012
|
+
|
|
1013
|
+
# Log for debugging
|
|
1014
|
+
logger.debug(f"Processing insight: {pattern_type} - {description}")
|
|
1015
|
+
|
|
1016
|
+
# Check if this is an actionable insight
|
|
1017
|
+
actionable = get_bool(attrs, "actionable", False)
|
|
1018
|
+
if actionable:
|
|
1019
|
+
# The agent can decide to act on this during future work planning
|
|
1020
|
+
insights.append(f"Action Opportunity: {description}")
|
|
1021
|
+
|
|
1022
|
+
# Summarize findings
|
|
1023
|
+
if insights:
|
|
1024
|
+
logger.info(f"Processed {len(insights)} actionable insights from behavioral patterns")
|
|
1025
|
+
|
|
1026
|
+
except Exception as e:
|
|
1027
|
+
logger.error(f"Error processing behavioral insights: {e}", exc_info=True)
|
|
1028
|
+
|
|
1029
|
+
return insights
|
|
1030
|
+
|
|
1031
|
+
async def _plan_future_work(self) -> List[GraphNode]:
|
|
1032
|
+
"""Plan future work based on insights."""
|
|
1033
|
+
future_tasks: List[GraphNode] = []
|
|
1034
|
+
|
|
1035
|
+
if not self.current_session:
|
|
1036
|
+
return future_tasks
|
|
1037
|
+
|
|
1038
|
+
for insight in self.current_session.insights_gained:
|
|
1039
|
+
# Create specific future tasks based on insights
|
|
1040
|
+
if "focused on: identity" in insight:
|
|
1041
|
+
# Schedule identity reflection task
|
|
1042
|
+
task = await self._create_future_task("Reflect on core identity and values", hours_ahead=12)
|
|
1043
|
+
if task:
|
|
1044
|
+
future_tasks.append(task)
|
|
1045
|
+
logger.debug(f"Created identity task: {task.id}")
|
|
1046
|
+
|
|
1047
|
+
if "recurring contemplations" in insight:
|
|
1048
|
+
# Schedule deep dive into recurring questions
|
|
1049
|
+
task = await self._create_future_task(
|
|
1050
|
+
"Address recurring questions through focused analysis", hours_ahead=3
|
|
1051
|
+
)
|
|
1052
|
+
if task:
|
|
1053
|
+
future_tasks.append(task)
|
|
1054
|
+
logger.debug(f"Created contemplations task: {task.id}")
|
|
1055
|
+
else:
|
|
1056
|
+
logger.debug("Failed to create contemplations task")
|
|
1057
|
+
|
|
1058
|
+
return future_tasks
|
|
1059
|
+
|
|
1060
|
+
async def _create_future_task(self, description: str, hours_ahead: int) -> Optional[GraphNode]:
|
|
1061
|
+
"""Create a future task."""
|
|
1062
|
+
if not self.memory_bus:
|
|
1063
|
+
return None
|
|
1064
|
+
|
|
1065
|
+
try:
|
|
1066
|
+
if not self._time_service:
|
|
1067
|
+
return None
|
|
1068
|
+
future_time = self._time_service.now() + timedelta(hours=hours_ahead)
|
|
1069
|
+
# Use description hash to ensure unique IDs
|
|
1070
|
+
import hashlib
|
|
1071
|
+
|
|
1072
|
+
desc_hash = hashlib.md5(description.encode(), usedforsecurity=False).hexdigest()[:8]
|
|
1073
|
+
|
|
1074
|
+
task = GraphNode(
|
|
1075
|
+
id=f"future_task_{int(future_time.timestamp())}_{desc_hash}",
|
|
1076
|
+
type=NodeType.CONCEPT,
|
|
1077
|
+
scope=GraphScope.LOCAL,
|
|
1078
|
+
updated_by="dream_processor",
|
|
1079
|
+
updated_at=future_time,
|
|
1080
|
+
attributes={
|
|
1081
|
+
"task_type": "planned_work",
|
|
1082
|
+
"description": description,
|
|
1083
|
+
"scheduled_for": future_time.isoformat(),
|
|
1084
|
+
"priority": "normal",
|
|
1085
|
+
"source": "dream_planning",
|
|
1086
|
+
},
|
|
1087
|
+
)
|
|
1088
|
+
|
|
1089
|
+
await self.memory_bus.memorize(node=task, handler_name="dream_processor", metadata={"future_task": True})
|
|
1090
|
+
|
|
1091
|
+
return task
|
|
1092
|
+
|
|
1093
|
+
except Exception as e:
|
|
1094
|
+
logger.error(f"Failed to create future task: {e}")
|
|
1095
|
+
return None
|
|
1096
|
+
|
|
1097
|
+
async def _run_single_benchmark(self) -> None:
|
|
1098
|
+
"""Run a single benchmark cycle."""
|
|
1099
|
+
if not self.cirisnode_client:
|
|
1100
|
+
return
|
|
1101
|
+
|
|
1102
|
+
agent_id = "ciris"
|
|
1103
|
+
if self.identity_manager and hasattr(self.identity_manager, "agent_identity"):
|
|
1104
|
+
agent_identity = self.identity_manager.agent_identity
|
|
1105
|
+
if agent_identity and hasattr(agent_identity, "agent_id"):
|
|
1106
|
+
agent_id = agent_identity.agent_id
|
|
1107
|
+
model_id = "unknown"
|
|
1108
|
+
|
|
1109
|
+
if hasattr(self.config, "llm_services") and hasattr(self.config.llm_services, "openai"):
|
|
1110
|
+
model_id = self.config.llm_services.openai.model_name
|
|
1111
|
+
|
|
1112
|
+
# Run benchmarks
|
|
1113
|
+
he300_result = await self.cirisnode_client.run_he300(model_id=model_id, agent_id=agent_id)
|
|
1114
|
+
simplebench_result = await self.cirisnode_client.run_simplebench(model_id=model_id, agent_id=agent_id)
|
|
1115
|
+
|
|
1116
|
+
# Store results as insights
|
|
1117
|
+
topic = he300_result.topic if hasattr(he300_result, "topic") else "Unknown"
|
|
1118
|
+
score = simplebench_result.score if hasattr(simplebench_result, "score") else "N/A"
|
|
1119
|
+
|
|
1120
|
+
if self.current_session:
|
|
1121
|
+
self.current_session.insights_gained.append(f"Benchmark reflection: {topic} (score: {score})")
|
|
1122
|
+
|
|
1123
|
+
benchmarks_run = get_int(self.dream_metrics, "benchmarks_run", 0)
|
|
1124
|
+
self.dream_metrics["benchmarks_run"] = benchmarks_run + 1
|
|
1125
|
+
|
|
1126
|
+
async def _record_dream_session(self) -> None:
|
|
1127
|
+
"""Record the dream session in memory."""
|
|
1128
|
+
if not self.memory_bus or not self.current_session:
|
|
1129
|
+
return
|
|
1130
|
+
|
|
1131
|
+
try:
|
|
1132
|
+
if not self._time_service:
|
|
1133
|
+
return
|
|
1134
|
+
journal_entry = GraphNode(
|
|
1135
|
+
id=f"dream_journal_{self.current_session.session_id}",
|
|
1136
|
+
type=NodeType.CONCEPT,
|
|
1137
|
+
scope=GraphScope.IDENTITY,
|
|
1138
|
+
updated_by="dream_processor",
|
|
1139
|
+
updated_at=self._time_service.now(),
|
|
1140
|
+
attributes={
|
|
1141
|
+
"session_id": self.current_session.session_id,
|
|
1142
|
+
"duration_seconds": (
|
|
1143
|
+
(self.current_session.completed_at - self.current_session.actual_start).total_seconds()
|
|
1144
|
+
if self.current_session.completed_at
|
|
1145
|
+
else 0
|
|
1146
|
+
),
|
|
1147
|
+
"memories_consolidated": self.current_session.memories_consolidated,
|
|
1148
|
+
"patterns_analyzed": self.current_session.patterns_analyzed,
|
|
1149
|
+
"adaptations_made": self.current_session.adaptations_made,
|
|
1150
|
+
"future_tasks_scheduled": self.current_session.future_tasks_scheduled,
|
|
1151
|
+
"benchmarks_run": self.current_session.benchmarks_run,
|
|
1152
|
+
"insights": self.current_session.insights_gained,
|
|
1153
|
+
"ponder_questions": self.current_session.ponder_questions_processed[:10], # Top 10
|
|
1154
|
+
"phase_durations": self.current_session.phase_durations,
|
|
1155
|
+
"timestamp": self._time_service.now().isoformat() if self._time_service else "",
|
|
1156
|
+
},
|
|
1157
|
+
)
|
|
1158
|
+
|
|
1159
|
+
await self.memory_bus.memorize(
|
|
1160
|
+
node=journal_entry, handler_name="dream_processor", metadata={"dream_journal": True}
|
|
1161
|
+
)
|
|
1162
|
+
|
|
1163
|
+
logger.info(f"Recorded dream session {self.current_session.session_id}")
|
|
1164
|
+
|
|
1165
|
+
except Exception as e:
|
|
1166
|
+
logger.error(f"Failed to record dream session: {e}")
|
|
1167
|
+
|
|
1168
|
+
async def _get_vibe_summary(self) -> Optional[str]:
|
|
1169
|
+
"""Get a summary of recent positive vibes."""
|
|
1170
|
+
try:
|
|
1171
|
+
if not self.memory_bus:
|
|
1172
|
+
return None
|
|
1173
|
+
|
|
1174
|
+
# Query recent positive vibe nodes
|
|
1175
|
+
from ciris_engine.schemas.services.graph_core import NodeType
|
|
1176
|
+
from ciris_engine.schemas.services.operations import MemoryQuery
|
|
1177
|
+
|
|
1178
|
+
query = MemoryQuery(
|
|
1179
|
+
node_id="positive_vibe_*",
|
|
1180
|
+
scope=GraphScope.COMMUNITY,
|
|
1181
|
+
type=NodeType.CONCEPT,
|
|
1182
|
+
include_edges=False,
|
|
1183
|
+
depth=1,
|
|
1184
|
+
)
|
|
1185
|
+
|
|
1186
|
+
vibes = await self.memory_bus.recall(recall_query=query, handler_name="dream_processor")
|
|
1187
|
+
|
|
1188
|
+
if not vibes:
|
|
1189
|
+
return None
|
|
1190
|
+
|
|
1191
|
+
# Count recent vibes (last 24 hours)
|
|
1192
|
+
from datetime import datetime, timedelta
|
|
1193
|
+
|
|
1194
|
+
if not self._time_service:
|
|
1195
|
+
return None
|
|
1196
|
+
recent_cutoff = self._time_service.now() - timedelta(hours=24)
|
|
1197
|
+
recent_vibes = []
|
|
1198
|
+
|
|
1199
|
+
for vibe in vibes:
|
|
1200
|
+
attrs = vibe.attributes if hasattr(vibe, "attributes") else {}
|
|
1201
|
+
if isinstance(attrs, dict):
|
|
1202
|
+
vibe_str = get_str(attrs, "timestamp", "")
|
|
1203
|
+
if vibe_str:
|
|
1204
|
+
# Handle both 'Z' and '+00:00' formats
|
|
1205
|
+
if vibe_str.endswith("Z"):
|
|
1206
|
+
vibe_str = vibe_str[:-1] + "+00:00"
|
|
1207
|
+
vibe_time = datetime.fromisoformat(vibe_str)
|
|
1208
|
+
if vibe_time > recent_cutoff:
|
|
1209
|
+
recent_vibes.append(vibe)
|
|
1210
|
+
|
|
1211
|
+
if not recent_vibes:
|
|
1212
|
+
return None
|
|
1213
|
+
|
|
1214
|
+
vibe_count = len(recent_vibes)
|
|
1215
|
+
if vibe_count > 10:
|
|
1216
|
+
return f"The community has been vibing! ({vibe_count} positive moments in the last day)"
|
|
1217
|
+
elif vibe_count > 5:
|
|
1218
|
+
return f"Good energy in the community ({vibe_count} positive moments)"
|
|
1219
|
+
elif vibe_count > 0:
|
|
1220
|
+
return f"Some nice moments shared ({vibe_count} positive vibes)"
|
|
1221
|
+
|
|
1222
|
+
return None
|
|
1223
|
+
|
|
1224
|
+
except Exception as e:
|
|
1225
|
+
logger.debug(f"Couldn't check vibes: {e}")
|
|
1226
|
+
return None
|
|
1227
|
+
|
|
1228
|
+
async def _announce_dream_exit(self) -> None:
|
|
1229
|
+
"""Announce dream exit to main channel."""
|
|
1230
|
+
if not self.communication_bus or not self.startup_channel_id:
|
|
1231
|
+
return
|
|
1232
|
+
|
|
1233
|
+
try:
|
|
1234
|
+
if self.current_session:
|
|
1235
|
+
insights_summary = (
|
|
1236
|
+
f"{len(self.current_session.insights_gained)} insights gained"
|
|
1237
|
+
if self.current_session.insights_gained
|
|
1238
|
+
else "reflection complete"
|
|
1239
|
+
)
|
|
1240
|
+
|
|
1241
|
+
# Check for positive vibes
|
|
1242
|
+
vibe_summary = await self._get_vibe_summary()
|
|
1243
|
+
|
|
1244
|
+
message = (
|
|
1245
|
+
f"Self-reflection complete. {insights_summary}. "
|
|
1246
|
+
f"Consolidated {self.current_session.memories_consolidated} memories, "
|
|
1247
|
+
f"made {self.current_session.adaptations_made} adaptations."
|
|
1248
|
+
)
|
|
1249
|
+
|
|
1250
|
+
if vibe_summary:
|
|
1251
|
+
message += f" {vibe_summary}"
|
|
1252
|
+
else:
|
|
1253
|
+
message = "Self-reflection complete."
|
|
1254
|
+
|
|
1255
|
+
await self.communication_bus.send_message(
|
|
1256
|
+
content=message, channel_id=self.startup_channel_id, handler_name="dream_processor"
|
|
1257
|
+
)
|
|
1258
|
+
|
|
1259
|
+
except Exception as e:
|
|
1260
|
+
logger.error(f"Failed to announce dream exit: {e}")
|
|
1261
|
+
|
|
1262
|
+
def get_dream_summary(self) -> JSONDict:
|
|
1263
|
+
"""Get a summary of the current or last dream session."""
|
|
1264
|
+
summary: JSONDict = {
|
|
1265
|
+
"state": "dreaming" if self._dream_task and not self._dream_task.done() else "awake",
|
|
1266
|
+
"metrics": self.dream_metrics.copy(),
|
|
1267
|
+
"current_session": None,
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
if self.current_session:
|
|
1271
|
+
duration = 0.0
|
|
1272
|
+
if self._time_service:
|
|
1273
|
+
duration = (self._time_service.now() - self.current_session.actual_start).total_seconds()
|
|
1274
|
+
summary["current_session"] = {
|
|
1275
|
+
"session_id": self.current_session.session_id,
|
|
1276
|
+
"phase": self.current_session.phase.value,
|
|
1277
|
+
"duration": duration,
|
|
1278
|
+
"memories_consolidated": self.current_session.memories_consolidated,
|
|
1279
|
+
"patterns_analyzed": self.current_session.patterns_analyzed,
|
|
1280
|
+
"adaptations_made": self.current_session.adaptations_made,
|
|
1281
|
+
"insights_count": len(self.current_session.insights_gained),
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
return summary
|
|
1285
|
+
|
|
1286
|
+
# BaseProcessor interface implementation
|
|
1287
|
+
def initialize(self) -> bool:
|
|
1288
|
+
"""Initialize the processor with TimeService awareness."""
|
|
1289
|
+
# Use our time service instead of time_utils
|
|
1290
|
+
if self._time_service:
|
|
1291
|
+
self.metrics.start_time = self._time_service.now()
|
|
1292
|
+
return True
|
|
1293
|
+
|
|
1294
|
+
def cleanup(self) -> bool:
|
|
1295
|
+
"""Clean up processor resources with TimeService awareness."""
|
|
1296
|
+
# Use our time service instead of time_utils
|
|
1297
|
+
if self._time_service:
|
|
1298
|
+
self.metrics.end_time = self._time_service.now()
|
|
1299
|
+
return True
|
|
1300
|
+
|
|
1301
|
+
def get_supported_states(self) -> List[AgentState]:
|
|
1302
|
+
"""Return list of states this processor can handle."""
|
|
1303
|
+
return [AgentState.DREAM]
|
|
1304
|
+
|
|
1305
|
+
async def can_process(self, state: AgentState) -> bool:
|
|
1306
|
+
"""Check if this processor can handle the current state."""
|
|
1307
|
+
return state == AgentState.DREAM
|
|
1308
|
+
|
|
1309
|
+
async def process(self, round_number: int) -> DreamResult:
|
|
1310
|
+
"""Execute one round of dream processing."""
|
|
1311
|
+
# Use our process_round method
|
|
1312
|
+
metrics = await self.process_round(round_number)
|
|
1313
|
+
|
|
1314
|
+
# Update base metrics
|
|
1315
|
+
self.update_metrics(
|
|
1316
|
+
MetricsUpdate(
|
|
1317
|
+
items_processed=metrics.get("thoughts_processed", 0),
|
|
1318
|
+
errors=metrics.get("errors", 0),
|
|
1319
|
+
rounds_completed=1,
|
|
1320
|
+
additional=metrics,
|
|
1321
|
+
)
|
|
1322
|
+
)
|
|
1323
|
+
|
|
1324
|
+
# Return dream result
|
|
1325
|
+
duration_value = metrics.get("duration_seconds", 0.0)
|
|
1326
|
+
duration = float(duration_value) if isinstance(duration_value, (int, float)) else 0.0
|
|
1327
|
+
# Use small epsilon for floating point comparison
|
|
1328
|
+
if abs(duration) < 1e-9:
|
|
1329
|
+
# Calculate if not in metrics
|
|
1330
|
+
start_time = self.metrics.start_time or self.time_service.now()
|
|
1331
|
+
duration = (self.time_service.now() - start_time).total_seconds()
|
|
1332
|
+
|
|
1333
|
+
# Check if dream is complete based on phase and duration
|
|
1334
|
+
dream_complete = False
|
|
1335
|
+
if self.current_session and self.current_session.phase == DreamPhase.EXITING:
|
|
1336
|
+
# Check if minimum duration has passed
|
|
1337
|
+
if self._time_service:
|
|
1338
|
+
session_duration = (self._time_service.now() - self.current_session.actual_start).total_seconds()
|
|
1339
|
+
_dream_complete = session_duration >= (self.min_dream_duration * 60)
|
|
1340
|
+
else:
|
|
1341
|
+
_dream_complete = False
|
|
1342
|
+
|
|
1343
|
+
return DreamResult(
|
|
1344
|
+
thoughts_processed=metrics.get("thoughts_processed", 0),
|
|
1345
|
+
errors=metrics.get("errors", 0),
|
|
1346
|
+
duration_seconds=duration,
|
|
1347
|
+
)
|
|
1348
|
+
|
|
1349
|
+
def should_enter_dream_state(self, idle_seconds: float, min_idle_threshold: float = 300) -> bool:
|
|
1350
|
+
"""
|
|
1351
|
+
Determine if the agent should enter dream state based on idle time.
|
|
1352
|
+
|
|
1353
|
+
Args:
|
|
1354
|
+
idle_seconds: How long the agent has been idle
|
|
1355
|
+
min_idle_threshold: Minimum idle time before considering dream state
|
|
1356
|
+
|
|
1357
|
+
Returns:
|
|
1358
|
+
True if dream state should be entered
|
|
1359
|
+
"""
|
|
1360
|
+
if self._dream_task and not self._dream_task.done():
|
|
1361
|
+
return False
|
|
1362
|
+
|
|
1363
|
+
if idle_seconds < min_idle_threshold:
|
|
1364
|
+
return False
|
|
1365
|
+
|
|
1366
|
+
# Check if we're due for a dream (every 6 hours)
|
|
1367
|
+
end_time_str = get_str(self.dream_metrics, "end_time", "")
|
|
1368
|
+
if end_time_str and self._time_service:
|
|
1369
|
+
last_dream = datetime.fromisoformat(end_time_str)
|
|
1370
|
+
hours_since = (self._time_service.now() - last_dream).total_seconds() / 3600
|
|
1371
|
+
|
|
1372
|
+
if hours_since >= 6:
|
|
1373
|
+
logger.info(f"Due for dream session (last dream {hours_since:.1f} hours ago)")
|
|
1374
|
+
return True
|
|
1375
|
+
else:
|
|
1376
|
+
# Not due yet
|
|
1377
|
+
return False
|
|
1378
|
+
|
|
1379
|
+
# No previous dream recorded, recommend dream state
|
|
1380
|
+
logger.info(f"Idle for {idle_seconds}s, recommending dream state")
|
|
1381
|
+
return True
|