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,1153 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Self-Observation Service
|
|
3
|
+
|
|
4
|
+
Enables the agent to observe its own behavior patterns and generate insights
|
|
5
|
+
for continuous learning. This service coordinates:
|
|
6
|
+
- IdentityVarianceMonitor (tracks drift from baseline identity)
|
|
7
|
+
- PatternAnalysisLoop (detects patterns and stores insights)
|
|
8
|
+
- Configurable pattern detection algorithms (via graph config)
|
|
9
|
+
|
|
10
|
+
The agent can modify its own observation algorithms through graph configuration,
|
|
11
|
+
enabling meta-learning and self-directed analytical evolution.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import logging
|
|
15
|
+
from collections import defaultdict
|
|
16
|
+
from typing import TYPE_CHECKING, Dict, List, Optional
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from ciris_engine.logic.registries.base import ServiceRegistry
|
|
20
|
+
from ciris_engine.schemas.runtime.enums import ServiceType
|
|
21
|
+
|
|
22
|
+
from dataclasses import dataclass
|
|
23
|
+
from datetime import datetime, timedelta, timezone
|
|
24
|
+
from enum import Enum
|
|
25
|
+
|
|
26
|
+
from ciris_engine.logic.buses.memory_bus import MemoryBus
|
|
27
|
+
from ciris_engine.logic.infrastructure.sub_services.identity_variance_monitor import IdentityVarianceMonitor
|
|
28
|
+
from ciris_engine.logic.infrastructure.sub_services.pattern_analysis_loop import PatternAnalysisLoop
|
|
29
|
+
from ciris_engine.logic.services.base_scheduled_service import BaseScheduledService
|
|
30
|
+
from ciris_engine.logic.services.graph.telemetry_service import GraphTelemetryService
|
|
31
|
+
from ciris_engine.logic.utils.jsondict_helpers import get_float, get_int, get_str
|
|
32
|
+
from ciris_engine.protocols.infrastructure.base import RegistryAwareServiceProtocol, ServiceRegistryProtocol
|
|
33
|
+
from ciris_engine.protocols.runtime.base import ServiceProtocol
|
|
34
|
+
from ciris_engine.protocols.services import SelfObservationServiceProtocol
|
|
35
|
+
from ciris_engine.protocols.services.lifecycle.time import TimeServiceProtocol
|
|
36
|
+
from ciris_engine.schemas.infrastructure.behavioral_patterns import ActionFrequency, TemporalPattern
|
|
37
|
+
from ciris_engine.schemas.infrastructure.feedback_loop import AnalysisResult, DetectedPattern, PatternType
|
|
38
|
+
from ciris_engine.schemas.runtime.core import AgentIdentityRoot
|
|
39
|
+
from ciris_engine.schemas.services.core import ServiceCapabilities, ServiceStatus
|
|
40
|
+
from ciris_engine.schemas.services.graph_core import GraphNode, GraphScope, NodeType
|
|
41
|
+
from ciris_engine.schemas.services.special.self_observation import (
|
|
42
|
+
AnalysisStatus,
|
|
43
|
+
CycleEventData,
|
|
44
|
+
LearningSummary,
|
|
45
|
+
ObservabilityAnalysis,
|
|
46
|
+
ObservationCycleResult,
|
|
47
|
+
ObservationEffectiveness,
|
|
48
|
+
ObservationOpportunity,
|
|
49
|
+
ObservationStatus,
|
|
50
|
+
PatternEffectiveness,
|
|
51
|
+
PatternInsight,
|
|
52
|
+
PatternLibrarySummary,
|
|
53
|
+
ReviewOutcome,
|
|
54
|
+
ServiceImprovementReport,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
logger = logging.getLogger(__name__)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class ObservationState(str, Enum):
|
|
61
|
+
"""Current state of the self-observation system."""
|
|
62
|
+
|
|
63
|
+
LEARNING = "learning" # Gathering data, no changes yet
|
|
64
|
+
PROPOSING = "proposing" # Actively proposing adaptations
|
|
65
|
+
ADAPTING = "adapting" # Applying approved changes
|
|
66
|
+
STABILIZING = "stabilizing" # Waiting for changes to settle
|
|
67
|
+
REVIEWING = "reviewing" # Under WA review for variance
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@dataclass
|
|
71
|
+
class ObservationCycle:
|
|
72
|
+
"""Represents one complete observation and analysis cycle."""
|
|
73
|
+
|
|
74
|
+
cycle_id: str
|
|
75
|
+
started_at: datetime
|
|
76
|
+
state: ObservationState
|
|
77
|
+
patterns_detected: int
|
|
78
|
+
proposals_generated: int
|
|
79
|
+
changes_applied: int
|
|
80
|
+
variance_before: float
|
|
81
|
+
variance_after: Optional[float]
|
|
82
|
+
completed_at: Optional[datetime]
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class SelfObservationService(BaseScheduledService, SelfObservationServiceProtocol, RegistryAwareServiceProtocol):
|
|
86
|
+
"""
|
|
87
|
+
Service that enables self-observation, pattern detection, and insight generation.
|
|
88
|
+
|
|
89
|
+
This service:
|
|
90
|
+
1. Coordinates between variance monitoring, pattern detection, and telemetry
|
|
91
|
+
2. Manages the adaptation lifecycle with safety checks
|
|
92
|
+
3. Ensures changes stay within the 20% identity variance threshold
|
|
93
|
+
4. Provides a unified interface for self-configuration
|
|
94
|
+
|
|
95
|
+
The flow:
|
|
96
|
+
Experience → Telemetry → Patterns → Insights → Agent Decisions → Config Changes
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
def __init__(
|
|
100
|
+
self,
|
|
101
|
+
time_service: TimeServiceProtocol,
|
|
102
|
+
memory_bus: Optional[MemoryBus] = None,
|
|
103
|
+
variance_threshold: float = 0.20,
|
|
104
|
+
observation_interval_hours: int = 6,
|
|
105
|
+
stabilization_period_hours: int = 24,
|
|
106
|
+
) -> None:
|
|
107
|
+
# Convert observation interval to seconds for BaseScheduledService
|
|
108
|
+
super().__init__(time_service=time_service, run_interval_seconds=observation_interval_hours * 3600)
|
|
109
|
+
self._time_service: Optional[TimeServiceProtocol] = time_service
|
|
110
|
+
self._memory_bus = memory_bus
|
|
111
|
+
self._variance_threshold = variance_threshold
|
|
112
|
+
self._observation_interval = timedelta(hours=observation_interval_hours)
|
|
113
|
+
self._stabilization_period = timedelta(hours=stabilization_period_hours)
|
|
114
|
+
|
|
115
|
+
# Component services
|
|
116
|
+
self._variance_monitor: Optional[IdentityVarianceMonitor] = None
|
|
117
|
+
self._pattern_loop: Optional[PatternAnalysisLoop] = None
|
|
118
|
+
self._telemetry_service: Optional[GraphTelemetryService] = None
|
|
119
|
+
|
|
120
|
+
# State tracking
|
|
121
|
+
self._current_state = ObservationState.LEARNING
|
|
122
|
+
self._current_cycle: Optional[ObservationCycle] = None
|
|
123
|
+
self._adaptation_history: List[ObservationCycle] = []
|
|
124
|
+
self._last_adaptation = self._time_service.now() if self._time_service else datetime.now()
|
|
125
|
+
# No more pending proposals - agent decides through thoughts
|
|
126
|
+
|
|
127
|
+
# Safety mechanisms
|
|
128
|
+
self._emergency_stop = False
|
|
129
|
+
self._consecutive_failures = 0
|
|
130
|
+
self._max_failures = 3
|
|
131
|
+
self._pattern_history: List[DetectedPattern] = [] # Add missing attribute for tracking pattern history
|
|
132
|
+
self._last_variance_report = 0.0 # Store last variance for status reporting
|
|
133
|
+
self._start_time = (
|
|
134
|
+
self._time_service.now() if self._time_service else datetime.now(timezone.utc)
|
|
135
|
+
) # Track when service started
|
|
136
|
+
self._adaptation_errors = 0 # Track adaptation errors
|
|
137
|
+
self._last_error: Optional[str] = None # Store last error message
|
|
138
|
+
|
|
139
|
+
# Tracking variables for custom metrics
|
|
140
|
+
self._observations_made = 0
|
|
141
|
+
self._patterns_detected = 0
|
|
142
|
+
self._adaptations_triggered = 0
|
|
143
|
+
self._performance_checks = 0
|
|
144
|
+
self._anomalies_detected = 0
|
|
145
|
+
self._self_corrections = 0
|
|
146
|
+
self._learning_cycles = 0
|
|
147
|
+
self._model_updates = 0
|
|
148
|
+
|
|
149
|
+
async def attach_registry(self, registry: "ServiceRegistryProtocol") -> None:
|
|
150
|
+
"""
|
|
151
|
+
Attach service registry for bus and service discovery.
|
|
152
|
+
|
|
153
|
+
Implements RegistryAwareServiceProtocol to enable proper initialization
|
|
154
|
+
of memory bus and component services.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
registry: Service registry providing access to buses and services
|
|
158
|
+
"""
|
|
159
|
+
self._service_registry = registry
|
|
160
|
+
|
|
161
|
+
# Initialize memory bus
|
|
162
|
+
if not self._memory_bus and registry:
|
|
163
|
+
try:
|
|
164
|
+
from ciris_engine.logic.buses import MemoryBus
|
|
165
|
+
|
|
166
|
+
time_service = self._time_service
|
|
167
|
+
if time_service is not None:
|
|
168
|
+
self._memory_bus = MemoryBus(registry, time_service)
|
|
169
|
+
except Exception as e:
|
|
170
|
+
logger.error(f"Failed to initialize memory bus: {e}")
|
|
171
|
+
|
|
172
|
+
# Initialize component services
|
|
173
|
+
await self._initialize_components()
|
|
174
|
+
|
|
175
|
+
async def _initialize_components(self) -> None:
|
|
176
|
+
"""Initialize the component services."""
|
|
177
|
+
try:
|
|
178
|
+
# Create variance monitor
|
|
179
|
+
time_service = self._time_service
|
|
180
|
+
if time_service is not None:
|
|
181
|
+
self._variance_monitor = IdentityVarianceMonitor(
|
|
182
|
+
time_service=time_service, memory_bus=self._memory_bus, variance_threshold=self._variance_threshold
|
|
183
|
+
)
|
|
184
|
+
if self._service_registry and self._variance_monitor:
|
|
185
|
+
self._variance_monitor.set_service_registry(self._service_registry)
|
|
186
|
+
|
|
187
|
+
# Create feedback loop
|
|
188
|
+
if time_service is not None:
|
|
189
|
+
self._pattern_loop = PatternAnalysisLoop(
|
|
190
|
+
time_service=time_service,
|
|
191
|
+
memory_bus=self._memory_bus,
|
|
192
|
+
analysis_interval_hours=int(self._observation_interval.total_seconds() / 3600),
|
|
193
|
+
)
|
|
194
|
+
if self._service_registry and self._pattern_loop:
|
|
195
|
+
self._pattern_loop.set_service_registry(self._service_registry)
|
|
196
|
+
|
|
197
|
+
# Create telemetry service
|
|
198
|
+
self._telemetry_service = GraphTelemetryService(memory_bus=self._memory_bus)
|
|
199
|
+
if self._service_registry:
|
|
200
|
+
await self._telemetry_service.attach_registry(self._service_registry)
|
|
201
|
+
|
|
202
|
+
logger.info("Self-configuration components initialized")
|
|
203
|
+
|
|
204
|
+
except Exception as e:
|
|
205
|
+
logger.error(f"Failed to initialize components: {e}")
|
|
206
|
+
|
|
207
|
+
async def _initialize_identity_baseline(self, identity: AgentIdentityRoot) -> str:
|
|
208
|
+
"""
|
|
209
|
+
Initialize the identity baseline for variance monitoring.
|
|
210
|
+
|
|
211
|
+
This should be called once during agent initialization.
|
|
212
|
+
"""
|
|
213
|
+
if not self._variance_monitor:
|
|
214
|
+
raise RuntimeError("Variance monitor not initialized")
|
|
215
|
+
|
|
216
|
+
baseline_id = await self._variance_monitor.initialize_baseline(identity)
|
|
217
|
+
logger.info(f"Identity baseline established: {baseline_id}")
|
|
218
|
+
|
|
219
|
+
# Store initialization event
|
|
220
|
+
init_node = GraphNode(
|
|
221
|
+
id=f"self_observation_init_{int(self._time_service.now().timestamp() if self._time_service else datetime.now().timestamp())}",
|
|
222
|
+
type=NodeType.CONCEPT,
|
|
223
|
+
scope=GraphScope.IDENTITY,
|
|
224
|
+
attributes={
|
|
225
|
+
"event_type": "self_observation_initialized",
|
|
226
|
+
"baseline_id": baseline_id,
|
|
227
|
+
"variance_threshold": self._variance_threshold,
|
|
228
|
+
"timestamp": self._time_service.now().isoformat() if self._time_service else datetime.now().isoformat(),
|
|
229
|
+
},
|
|
230
|
+
updated_by="self_observation",
|
|
231
|
+
updated_at=self._time_service.now() if self._time_service else datetime.now(),
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
if self._memory_bus:
|
|
235
|
+
await self._memory_bus.memorize(init_node, handler_name="self_observation")
|
|
236
|
+
|
|
237
|
+
return baseline_id
|
|
238
|
+
|
|
239
|
+
async def _run_scheduled_task(self) -> None:
|
|
240
|
+
"""
|
|
241
|
+
Execute the scheduled observation cycle.
|
|
242
|
+
|
|
243
|
+
This is called periodically by BaseScheduledService.
|
|
244
|
+
"""
|
|
245
|
+
# Check if we should actually run
|
|
246
|
+
if not await self._should_run_observation_cycle():
|
|
247
|
+
return
|
|
248
|
+
|
|
249
|
+
# Run the observation cycle
|
|
250
|
+
await self._run_observation_cycle()
|
|
251
|
+
|
|
252
|
+
async def _should_run_observation_cycle(self) -> bool:
|
|
253
|
+
"""Check if it's time to run an adaptation cycle."""
|
|
254
|
+
# Don't run if in emergency stop
|
|
255
|
+
if self._emergency_stop:
|
|
256
|
+
return False
|
|
257
|
+
|
|
258
|
+
# Don't run if currently in a cycle
|
|
259
|
+
if self._current_cycle and not self._current_cycle.completed_at:
|
|
260
|
+
return False
|
|
261
|
+
|
|
262
|
+
# Check state-based conditions
|
|
263
|
+
if self._current_state == ObservationState.REVIEWING:
|
|
264
|
+
# Wait for WA review to complete
|
|
265
|
+
return False
|
|
266
|
+
|
|
267
|
+
if self._current_state == ObservationState.STABILIZING:
|
|
268
|
+
# Check if stabilization period has passed
|
|
269
|
+
if not self._time_service:
|
|
270
|
+
return False
|
|
271
|
+
time_since_last = self._time_service.now() - self._last_adaptation
|
|
272
|
+
if time_since_last < self._stabilization_period:
|
|
273
|
+
return False
|
|
274
|
+
|
|
275
|
+
# We're already scheduled by BaseScheduledService, so just check state
|
|
276
|
+
return True
|
|
277
|
+
|
|
278
|
+
async def _run_observation_cycle(self) -> ObservationCycleResult:
|
|
279
|
+
"""
|
|
280
|
+
Run a variance check cycle.
|
|
281
|
+
|
|
282
|
+
This method now only checks variance and triggers WA review if needed.
|
|
283
|
+
Actual configuration changes happen through agent decisions.
|
|
284
|
+
"""
|
|
285
|
+
try:
|
|
286
|
+
# Check current variance
|
|
287
|
+
if self._variance_monitor:
|
|
288
|
+
variance_report = await self._variance_monitor.check_variance()
|
|
289
|
+
# Store variance for status reporting
|
|
290
|
+
self._last_variance_report = variance_report.total_variance
|
|
291
|
+
else:
|
|
292
|
+
return ObservationCycleResult(
|
|
293
|
+
cycle_id="no_monitor",
|
|
294
|
+
state=ObservationState(self._current_state.value),
|
|
295
|
+
started_at=self._time_service.now() if self._time_service else datetime.now(),
|
|
296
|
+
completed_at=self._time_service.now() if self._time_service else datetime.now(),
|
|
297
|
+
patterns_detected=0,
|
|
298
|
+
proposals_generated=0,
|
|
299
|
+
proposals_approved=0,
|
|
300
|
+
proposals_rejected=0,
|
|
301
|
+
changes_applied=0,
|
|
302
|
+
rollbacks_performed=0,
|
|
303
|
+
variance_before=0.0,
|
|
304
|
+
variance_after=0.0,
|
|
305
|
+
success=False,
|
|
306
|
+
requires_review=False,
|
|
307
|
+
error="Variance monitor not initialized",
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
cycle_id = f"variance_check_{int(self._time_service.now().timestamp() if self._time_service else datetime.now().timestamp())}"
|
|
311
|
+
|
|
312
|
+
if variance_report.requires_wa_review:
|
|
313
|
+
# Variance too high - enter review state
|
|
314
|
+
self._current_state = ObservationState.REVIEWING
|
|
315
|
+
await self._store_cycle_event(
|
|
316
|
+
"variance_exceeded",
|
|
317
|
+
CycleEventData(
|
|
318
|
+
event_type="variance_exceeded",
|
|
319
|
+
cycle_id=cycle_id,
|
|
320
|
+
variance=variance_report.total_variance,
|
|
321
|
+
metadata={"threshold": self._variance_threshold},
|
|
322
|
+
),
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
return ObservationCycleResult(
|
|
326
|
+
cycle_id=cycle_id,
|
|
327
|
+
state=ObservationState(self._current_state.value),
|
|
328
|
+
started_at=self._time_service.now() if self._time_service else datetime.now(),
|
|
329
|
+
completed_at=self._time_service.now() if self._time_service else datetime.now(),
|
|
330
|
+
patterns_detected=0, # Patterns detected by feedback loop
|
|
331
|
+
proposals_generated=0, # No proposals - agent decides
|
|
332
|
+
proposals_approved=0,
|
|
333
|
+
proposals_rejected=0,
|
|
334
|
+
changes_applied=0, # Changes via MEMORIZE
|
|
335
|
+
rollbacks_performed=0,
|
|
336
|
+
variance_before=variance_report.total_variance,
|
|
337
|
+
variance_after=variance_report.total_variance,
|
|
338
|
+
success=True,
|
|
339
|
+
requires_review=variance_report.requires_wa_review,
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
except Exception as e:
|
|
343
|
+
logger.error(f"Variance check failed: {e}")
|
|
344
|
+
self._consecutive_failures += 1
|
|
345
|
+
|
|
346
|
+
if self._consecutive_failures >= self._max_failures:
|
|
347
|
+
self._emergency_stop = True
|
|
348
|
+
logger.error("Emergency stop activated after repeated failures")
|
|
349
|
+
|
|
350
|
+
return ObservationCycleResult(
|
|
351
|
+
cycle_id="error",
|
|
352
|
+
state=ObservationState(self._current_state.value),
|
|
353
|
+
started_at=self._time_service.now() if self._time_service else datetime.now(),
|
|
354
|
+
completed_at=self._time_service.now() if self._time_service else datetime.now(),
|
|
355
|
+
patterns_detected=0,
|
|
356
|
+
proposals_generated=0,
|
|
357
|
+
proposals_approved=0,
|
|
358
|
+
proposals_rejected=0,
|
|
359
|
+
changes_applied=0,
|
|
360
|
+
rollbacks_performed=0,
|
|
361
|
+
variance_before=0.0,
|
|
362
|
+
variance_after=0.0,
|
|
363
|
+
success=False,
|
|
364
|
+
requires_review=False,
|
|
365
|
+
error=str(e),
|
|
366
|
+
)
|
|
367
|
+
|
|
368
|
+
async def _store_cycle_event(self, event_type: str, data: CycleEventData) -> None:
|
|
369
|
+
"""Store an event during the adaptation cycle."""
|
|
370
|
+
cycle_id = self._current_cycle.cycle_id if self._current_cycle else "unknown"
|
|
371
|
+
event_node = GraphNode(
|
|
372
|
+
id=f"cycle_event_{cycle_id}_{event_type}_{int(self._time_service.now().timestamp() if self._time_service else datetime.now().timestamp())}",
|
|
373
|
+
type=NodeType.CONCEPT,
|
|
374
|
+
scope=GraphScope.LOCAL,
|
|
375
|
+
attributes={
|
|
376
|
+
"cycle_id": cycle_id,
|
|
377
|
+
"event_type": event_type,
|
|
378
|
+
"data": data.model_dump(),
|
|
379
|
+
"timestamp": self._time_service.now().isoformat() if self._time_service else datetime.now().isoformat(),
|
|
380
|
+
},
|
|
381
|
+
updated_by="self_observation",
|
|
382
|
+
updated_at=self._time_service.now() if self._time_service else datetime.now(),
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
if self._memory_bus:
|
|
386
|
+
await self._memory_bus.memorize(event_node, handler_name="self_observation")
|
|
387
|
+
|
|
388
|
+
async def _store_cycle_summary(self, cycle: ObservationCycle) -> None:
|
|
389
|
+
"""Store a summary of the completed adaptation cycle."""
|
|
390
|
+
summary_node = GraphNode(
|
|
391
|
+
id=f"cycle_summary_{cycle.cycle_id}",
|
|
392
|
+
type=NodeType.CONCEPT,
|
|
393
|
+
scope=GraphScope.IDENTITY,
|
|
394
|
+
attributes={
|
|
395
|
+
"cycle_id": cycle.cycle_id,
|
|
396
|
+
"duration_seconds": (
|
|
397
|
+
(cycle.completed_at - cycle.started_at).total_seconds() if cycle.completed_at else 0
|
|
398
|
+
),
|
|
399
|
+
"patterns_detected": cycle.patterns_detected,
|
|
400
|
+
"proposals_generated": cycle.proposals_generated,
|
|
401
|
+
"changes_applied": cycle.changes_applied,
|
|
402
|
+
"variance_before": cycle.variance_before,
|
|
403
|
+
"variance_after": cycle.variance_after,
|
|
404
|
+
"final_state": cycle.state.value,
|
|
405
|
+
"success": cycle.changes_applied > 0 or cycle.patterns_detected > 0,
|
|
406
|
+
"timestamp": (
|
|
407
|
+
cycle.completed_at.isoformat()
|
|
408
|
+
if cycle.completed_at
|
|
409
|
+
else (self._time_service.now().isoformat() if self._time_service else datetime.now().isoformat())
|
|
410
|
+
),
|
|
411
|
+
},
|
|
412
|
+
updated_by="self_observation",
|
|
413
|
+
updated_at=self._time_service.now() if self._time_service else datetime.now(),
|
|
414
|
+
)
|
|
415
|
+
|
|
416
|
+
if self._memory_bus:
|
|
417
|
+
await self._memory_bus.memorize(
|
|
418
|
+
node=summary_node, handler_name="self_observation", metadata={"cycle_summary": True}
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
async def get_adaptation_status(self) -> ObservationStatus:
|
|
422
|
+
"""Get current status of the self-observation system."""
|
|
423
|
+
# Get current variance from last check or default to 0
|
|
424
|
+
current_variance = 0.0
|
|
425
|
+
if self._variance_monitor and hasattr(self, "_last_variance_report"):
|
|
426
|
+
current_variance = getattr(self, "_last_variance_report", 0.0)
|
|
427
|
+
|
|
428
|
+
status = ObservationStatus(
|
|
429
|
+
is_active=not self._emergency_stop,
|
|
430
|
+
current_state=ObservationState(self._current_state.value),
|
|
431
|
+
cycles_completed=len(self._adaptation_history),
|
|
432
|
+
last_cycle_at=self._last_adaptation,
|
|
433
|
+
current_variance=current_variance,
|
|
434
|
+
patterns_in_buffer=0, # No more proposal buffer
|
|
435
|
+
pending_proposals=0, # No more proposals
|
|
436
|
+
average_cycle_duration_seconds=self._calculate_average_cycle_duration(),
|
|
437
|
+
total_changes_applied=sum(c.changes_applied for c in self._adaptation_history),
|
|
438
|
+
rollback_rate=self._calculate_rollback_rate(),
|
|
439
|
+
identity_stable=self._consecutive_failures < 3,
|
|
440
|
+
time_since_last_change=(
|
|
441
|
+
(self._time_service.now() - self._last_adaptation).total_seconds()
|
|
442
|
+
if self._time_service and self._last_adaptation
|
|
443
|
+
else None
|
|
444
|
+
),
|
|
445
|
+
under_review=self._current_state == ObservationState.REVIEWING,
|
|
446
|
+
review_reason="Variance exceeded threshold" if self._current_state == ObservationState.REVIEWING else None,
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
return status
|
|
450
|
+
|
|
451
|
+
async def resume_after_review(self, review_outcome: ReviewOutcome) -> None:
|
|
452
|
+
"""Resume self-configuration after WA review."""
|
|
453
|
+
if self._current_state != ObservationState.REVIEWING:
|
|
454
|
+
logger.warning("Resume called but not in REVIEWING state")
|
|
455
|
+
return
|
|
456
|
+
|
|
457
|
+
# Process review outcome
|
|
458
|
+
if review_outcome.decision == "approve":
|
|
459
|
+
self._current_state = ObservationState.STABILIZING
|
|
460
|
+
logger.info("WA review approved - entering stabilization")
|
|
461
|
+
else:
|
|
462
|
+
self._current_state = ObservationState.LEARNING
|
|
463
|
+
logger.info("WA review rejected - returning to learning")
|
|
464
|
+
|
|
465
|
+
# Reset failure counter on successful review
|
|
466
|
+
self._consecutive_failures = 0
|
|
467
|
+
|
|
468
|
+
# Store review outcome
|
|
469
|
+
review_node = GraphNode(
|
|
470
|
+
id=f"wa_review_outcome_{int(self._time_service.now().timestamp() if self._time_service else datetime.now().timestamp())}",
|
|
471
|
+
type=NodeType.CONCEPT,
|
|
472
|
+
scope=GraphScope.IDENTITY,
|
|
473
|
+
attributes={
|
|
474
|
+
"review_type": "identity_variance",
|
|
475
|
+
"outcome": review_outcome.model_dump(),
|
|
476
|
+
"new_state": self._current_state.value,
|
|
477
|
+
"timestamp": self._time_service.now().isoformat() if self._time_service else datetime.now().isoformat(),
|
|
478
|
+
},
|
|
479
|
+
updated_by="self_observation",
|
|
480
|
+
updated_at=self._time_service.now() if self._time_service else datetime.now(),
|
|
481
|
+
)
|
|
482
|
+
|
|
483
|
+
if self._memory_bus:
|
|
484
|
+
await self._memory_bus.memorize(review_node, handler_name="self_observation")
|
|
485
|
+
|
|
486
|
+
async def emergency_stop(self, reason: str) -> None:
|
|
487
|
+
"""Activate emergency stop for self-configuration."""
|
|
488
|
+
self._emergency_stop = True
|
|
489
|
+
logger.error(f"Emergency stop activated: {reason}")
|
|
490
|
+
|
|
491
|
+
# Store emergency stop event
|
|
492
|
+
stop_node = GraphNode(
|
|
493
|
+
id=f"emergency_stop_{int(self._time_service.now().timestamp() if self._time_service else datetime.now().timestamp())}",
|
|
494
|
+
type=NodeType.CONCEPT,
|
|
495
|
+
scope=GraphScope.IDENTITY,
|
|
496
|
+
attributes={
|
|
497
|
+
"event_type": "emergency_stop",
|
|
498
|
+
"reason": reason,
|
|
499
|
+
"previous_state": self._current_state.value,
|
|
500
|
+
"timestamp": self._time_service.now().isoformat() if self._time_service else datetime.now().isoformat(),
|
|
501
|
+
},
|
|
502
|
+
updated_by="self_observation",
|
|
503
|
+
updated_at=self._time_service.now() if self._time_service else datetime.now(),
|
|
504
|
+
)
|
|
505
|
+
|
|
506
|
+
if self._memory_bus:
|
|
507
|
+
await self._memory_bus.memorize(stop_node, handler_name="self_observation")
|
|
508
|
+
|
|
509
|
+
def _calculate_average_cycle_duration(self) -> float:
|
|
510
|
+
"""Calculate average duration of completed observation cycles."""
|
|
511
|
+
if not self._adaptation_history:
|
|
512
|
+
return 0.0
|
|
513
|
+
|
|
514
|
+
completed_cycles = [cycle for cycle in self._adaptation_history if cycle.completed_at is not None]
|
|
515
|
+
|
|
516
|
+
if not completed_cycles:
|
|
517
|
+
return 0.0
|
|
518
|
+
|
|
519
|
+
total_duration = 0.0
|
|
520
|
+
for cycle in completed_cycles:
|
|
521
|
+
if cycle.completed_at and cycle.started_at:
|
|
522
|
+
duration = (cycle.completed_at - cycle.started_at).total_seconds()
|
|
523
|
+
total_duration += duration
|
|
524
|
+
|
|
525
|
+
return total_duration / len(completed_cycles)
|
|
526
|
+
|
|
527
|
+
def _calculate_rollback_rate(self) -> float:
|
|
528
|
+
"""Calculate rollback rate from adaptation history."""
|
|
529
|
+
if not self._adaptation_history:
|
|
530
|
+
return 0.0
|
|
531
|
+
|
|
532
|
+
total_changes = sum(cycle.changes_applied for cycle in self._adaptation_history)
|
|
533
|
+
total_rollbacks = sum(getattr(cycle, "rollbacks_performed", 0) for cycle in self._adaptation_history)
|
|
534
|
+
|
|
535
|
+
if total_changes == 0:
|
|
536
|
+
return 0.0
|
|
537
|
+
|
|
538
|
+
return total_rollbacks / total_changes
|
|
539
|
+
|
|
540
|
+
async def _on_start(self) -> None:
|
|
541
|
+
"""Start the self-configuration service."""
|
|
542
|
+
# Start component services
|
|
543
|
+
if self._variance_monitor:
|
|
544
|
+
await self._variance_monitor.start()
|
|
545
|
+
if self._pattern_loop:
|
|
546
|
+
await self._pattern_loop.start()
|
|
547
|
+
if self._telemetry_service:
|
|
548
|
+
await self._telemetry_service.start()
|
|
549
|
+
|
|
550
|
+
logger.info("SelfObservationService started - enabling autonomous observation and learning")
|
|
551
|
+
|
|
552
|
+
async def _on_stop(self) -> None:
|
|
553
|
+
"""Stop the service."""
|
|
554
|
+
# Complete current cycle if any
|
|
555
|
+
if self._current_cycle and not self._current_cycle.completed_at:
|
|
556
|
+
self._current_cycle.completed_at = self._time_service.now() if self._time_service else datetime.now()
|
|
557
|
+
await self._store_cycle_summary(self._current_cycle)
|
|
558
|
+
|
|
559
|
+
# Stop component services
|
|
560
|
+
if self._variance_monitor:
|
|
561
|
+
await self._variance_monitor.stop()
|
|
562
|
+
if self._pattern_loop:
|
|
563
|
+
await self._pattern_loop.stop()
|
|
564
|
+
if self._telemetry_service:
|
|
565
|
+
await self._telemetry_service.stop()
|
|
566
|
+
|
|
567
|
+
logger.info("SelfObservationService stopped")
|
|
568
|
+
|
|
569
|
+
async def is_healthy(self) -> bool:
|
|
570
|
+
"""Check if the service is healthy."""
|
|
571
|
+
if self._emergency_stop:
|
|
572
|
+
return False
|
|
573
|
+
|
|
574
|
+
# Check component health
|
|
575
|
+
components_healthy = all(
|
|
576
|
+
[
|
|
577
|
+
await self._variance_monitor.is_healthy() if self._variance_monitor else False,
|
|
578
|
+
await self._pattern_loop.is_healthy() if self._pattern_loop else False,
|
|
579
|
+
await self._telemetry_service.is_healthy() if self._telemetry_service else False,
|
|
580
|
+
]
|
|
581
|
+
)
|
|
582
|
+
|
|
583
|
+
return components_healthy and self._consecutive_failures < self._max_failures
|
|
584
|
+
|
|
585
|
+
def get_capabilities(self) -> ServiceCapabilities:
|
|
586
|
+
"""Get service capabilities."""
|
|
587
|
+
return ServiceCapabilities(
|
|
588
|
+
service_name="SelfObservationService",
|
|
589
|
+
actions=["adapt_configuration", "monitor_identity", "process_feedback", "emergency_stop"],
|
|
590
|
+
version="1.0.0",
|
|
591
|
+
dependencies=["variance_monitor", "feedback_loop", "telemetry_service"],
|
|
592
|
+
metadata=None,
|
|
593
|
+
)
|
|
594
|
+
|
|
595
|
+
def get_status(self) -> ServiceStatus:
|
|
596
|
+
"""Get current service status."""
|
|
597
|
+
# Let BaseScheduledService handle the status
|
|
598
|
+
status = super().get_status()
|
|
599
|
+
|
|
600
|
+
# Add our custom metrics
|
|
601
|
+
if status.custom_metrics is not None:
|
|
602
|
+
status.custom_metrics.update(
|
|
603
|
+
{
|
|
604
|
+
"adaptation_count": float(len(self._adaptation_history)),
|
|
605
|
+
"consecutive_failures": float(self._consecutive_failures),
|
|
606
|
+
"emergency_stop": float(self._emergency_stop),
|
|
607
|
+
"changes_since_last_adaptation": float(
|
|
608
|
+
sum(c.changes_applied for c in self._adaptation_history[-1:]) if self._adaptation_history else 0
|
|
609
|
+
),
|
|
610
|
+
"current_variance": self._last_variance_report,
|
|
611
|
+
}
|
|
612
|
+
)
|
|
613
|
+
|
|
614
|
+
return status
|
|
615
|
+
|
|
616
|
+
# ========== New Protocol Methods for 1000-Year Operation ==========
|
|
617
|
+
|
|
618
|
+
async def initialize_baseline(self, identity: AgentIdentityRoot) -> str:
|
|
619
|
+
"""
|
|
620
|
+
Establish identity baseline for variance monitoring.
|
|
621
|
+
This is an alias for _initialize_identity_baseline to match the protocol.
|
|
622
|
+
"""
|
|
623
|
+
return await self._initialize_identity_baseline(identity)
|
|
624
|
+
|
|
625
|
+
async def analyze_observability_window(self, window: timedelta = timedelta(hours=6)) -> ObservabilityAnalysis:
|
|
626
|
+
"""
|
|
627
|
+
Analyze all observability signals for adaptation opportunities.
|
|
628
|
+
|
|
629
|
+
This method looks at insights stored by the feedback loop.
|
|
630
|
+
"""
|
|
631
|
+
current_time = self._time_service.now() if self._time_service else datetime.now()
|
|
632
|
+
window_start = current_time - window
|
|
633
|
+
|
|
634
|
+
analysis = ObservabilityAnalysis(
|
|
635
|
+
window_start=window_start,
|
|
636
|
+
window_end=current_time,
|
|
637
|
+
total_signals=0,
|
|
638
|
+
signals_by_type={},
|
|
639
|
+
observation_opportunities=[],
|
|
640
|
+
)
|
|
641
|
+
|
|
642
|
+
if not self._memory_bus:
|
|
643
|
+
return analysis
|
|
644
|
+
|
|
645
|
+
# Query for insights in the window
|
|
646
|
+
from ciris_engine.schemas.services.operations import MemoryQuery
|
|
647
|
+
|
|
648
|
+
query = MemoryQuery(
|
|
649
|
+
node_id="behavioral_patterns", # MemoryQuery requires node_id
|
|
650
|
+
scope=GraphScope.LOCAL,
|
|
651
|
+
type=NodeType.CONCEPT,
|
|
652
|
+
include_edges=False,
|
|
653
|
+
depth=1,
|
|
654
|
+
)
|
|
655
|
+
|
|
656
|
+
insights = await self._memory_bus.recall(query, handler_name="self_observation")
|
|
657
|
+
|
|
658
|
+
# Process insights into opportunities
|
|
659
|
+
for insight in insights:
|
|
660
|
+
if isinstance(insight.attributes, dict) and insight.attributes.get("actionable", False):
|
|
661
|
+
opportunity = ObservationOpportunity(
|
|
662
|
+
opportunity_id=f"opp_{insight.id}",
|
|
663
|
+
trigger_signals=[], # No specific signals, derived from patterns
|
|
664
|
+
proposed_changes=[], # Agent decides on changes
|
|
665
|
+
expected_improvement={"general": 0.1}, # Conservative estimate
|
|
666
|
+
risk_assessment="low", # All insights are pre-filtered as safe
|
|
667
|
+
priority=1,
|
|
668
|
+
)
|
|
669
|
+
analysis.observation_opportunities.append(opportunity)
|
|
670
|
+
|
|
671
|
+
analysis.total_signals = len(insights)
|
|
672
|
+
|
|
673
|
+
return analysis
|
|
674
|
+
|
|
675
|
+
async def trigger_adaptation_cycle(self) -> ObservationCycleResult:
|
|
676
|
+
"""
|
|
677
|
+
Manually trigger an adaptation assessment cycle.
|
|
678
|
+
|
|
679
|
+
This now just runs a variance check.
|
|
680
|
+
"""
|
|
681
|
+
if self._emergency_stop:
|
|
682
|
+
return ObservationCycleResult(
|
|
683
|
+
cycle_id="manual_trigger_blocked",
|
|
684
|
+
state=ObservationState(self._current_state.value),
|
|
685
|
+
started_at=self._time_service.now() if self._time_service else datetime.now(),
|
|
686
|
+
completed_at=self._time_service.now() if self._time_service else datetime.now(),
|
|
687
|
+
patterns_detected=0,
|
|
688
|
+
proposals_generated=0,
|
|
689
|
+
proposals_approved=0,
|
|
690
|
+
proposals_rejected=0,
|
|
691
|
+
changes_applied=0,
|
|
692
|
+
rollbacks_performed=0,
|
|
693
|
+
variance_before=0.0,
|
|
694
|
+
variance_after=0.0,
|
|
695
|
+
success=False,
|
|
696
|
+
requires_review=False,
|
|
697
|
+
error="Emergency stop active",
|
|
698
|
+
)
|
|
699
|
+
|
|
700
|
+
# Run variance check
|
|
701
|
+
return await self._run_observation_cycle()
|
|
702
|
+
|
|
703
|
+
async def get_pattern_library(self) -> PatternLibrarySummary:
|
|
704
|
+
"""
|
|
705
|
+
Get summary of learned adaptation patterns.
|
|
706
|
+
|
|
707
|
+
Patterns are now insights stored by the feedback loop.
|
|
708
|
+
"""
|
|
709
|
+
summary = PatternLibrarySummary(
|
|
710
|
+
total_patterns=0,
|
|
711
|
+
high_reliability_patterns=0,
|
|
712
|
+
recently_used_patterns=0,
|
|
713
|
+
most_effective_patterns=[],
|
|
714
|
+
pattern_categories={},
|
|
715
|
+
)
|
|
716
|
+
|
|
717
|
+
if not self._memory_bus:
|
|
718
|
+
return summary
|
|
719
|
+
|
|
720
|
+
# Query for pattern nodes
|
|
721
|
+
from ciris_engine.schemas.services.operations import MemoryQuery
|
|
722
|
+
|
|
723
|
+
query = MemoryQuery(
|
|
724
|
+
node_id="pattern_library", # MemoryQuery requires node_id
|
|
725
|
+
scope=GraphScope.LOCAL,
|
|
726
|
+
type=NodeType.CONCEPT,
|
|
727
|
+
include_edges=False,
|
|
728
|
+
depth=1,
|
|
729
|
+
)
|
|
730
|
+
|
|
731
|
+
patterns = await self._memory_bus.recall(query, handler_name="self_observation")
|
|
732
|
+
|
|
733
|
+
summary.total_patterns = len(patterns)
|
|
734
|
+
|
|
735
|
+
# Group by type
|
|
736
|
+
for pattern in patterns:
|
|
737
|
+
if isinstance(pattern.attributes, dict):
|
|
738
|
+
pattern_type = get_str(pattern.attributes, "pattern_type", "unknown")
|
|
739
|
+
if pattern_type not in summary.pattern_categories:
|
|
740
|
+
summary.pattern_categories[pattern_type] = 0
|
|
741
|
+
summary.pattern_categories[pattern_type] += 1
|
|
742
|
+
|
|
743
|
+
return summary
|
|
744
|
+
|
|
745
|
+
async def measure_adaptation_effectiveness(self, adaptation_id: str) -> ObservationEffectiveness:
|
|
746
|
+
"""
|
|
747
|
+
Measure if an adaptation actually improved the system.
|
|
748
|
+
|
|
749
|
+
Since adaptations are now agent-driven, effectiveness
|
|
750
|
+
is measured by variance stability.
|
|
751
|
+
"""
|
|
752
|
+
effectiveness = ObservationEffectiveness(
|
|
753
|
+
observation_id=adaptation_id,
|
|
754
|
+
measurement_period_hours=24,
|
|
755
|
+
overall_effectiveness=0.0,
|
|
756
|
+
recommendation="keep", # Default recommendation
|
|
757
|
+
)
|
|
758
|
+
|
|
759
|
+
# Check if variance is stable
|
|
760
|
+
if self._variance_monitor and hasattr(self, "_last_variance_report"):
|
|
761
|
+
current_variance = self._last_variance_report
|
|
762
|
+
if current_variance < self._variance_threshold:
|
|
763
|
+
effectiveness.recommendation = "keep"
|
|
764
|
+
effectiveness.overall_effectiveness = 1.0 - (current_variance / self._variance_threshold)
|
|
765
|
+
else:
|
|
766
|
+
effectiveness.recommendation = "review"
|
|
767
|
+
|
|
768
|
+
return effectiveness
|
|
769
|
+
|
|
770
|
+
async def get_improvement_report(self, period: timedelta = timedelta(days=30)) -> ServiceImprovementReport:
|
|
771
|
+
"""
|
|
772
|
+
Generate service improvement report for period.
|
|
773
|
+
"""
|
|
774
|
+
current_time = self._time_service.now() if self._time_service else datetime.now()
|
|
775
|
+
period_start = current_time - period
|
|
776
|
+
|
|
777
|
+
report = ServiceImprovementReport(
|
|
778
|
+
report_period_start=period_start,
|
|
779
|
+
report_period_end=current_time,
|
|
780
|
+
total_observations=0,
|
|
781
|
+
successful_observations=0,
|
|
782
|
+
rolled_back_observations=0,
|
|
783
|
+
average_performance_improvement=0.0,
|
|
784
|
+
error_rate_reduction=0.0,
|
|
785
|
+
resource_efficiency_gain=0.0,
|
|
786
|
+
starting_variance=0.0,
|
|
787
|
+
ending_variance=self._last_variance_report if hasattr(self, "_last_variance_report") else 0.0,
|
|
788
|
+
peak_variance=0.0,
|
|
789
|
+
top_improvements=[],
|
|
790
|
+
recommendations=[],
|
|
791
|
+
)
|
|
792
|
+
|
|
793
|
+
# Count variance checks in period
|
|
794
|
+
for cycle in self._adaptation_history:
|
|
795
|
+
if hasattr(cycle, "started_at") and cycle.started_at >= period_start:
|
|
796
|
+
report.total_observations += 1
|
|
797
|
+
if hasattr(cycle, "success") and cycle.success:
|
|
798
|
+
report.successful_observations += 1
|
|
799
|
+
|
|
800
|
+
# Add recommendations based on current state
|
|
801
|
+
if self._emergency_stop:
|
|
802
|
+
report.recommendations.append("Clear emergency stop and investigate cause")
|
|
803
|
+
if self._consecutive_failures > 0:
|
|
804
|
+
report.recommendations.append("Investigate variance check failures")
|
|
805
|
+
|
|
806
|
+
return report
|
|
807
|
+
|
|
808
|
+
# ========== Pattern Detection Protocol Methods ==========
|
|
809
|
+
|
|
810
|
+
async def analyze_patterns(self, force: bool = False) -> AnalysisResult:
|
|
811
|
+
"""
|
|
812
|
+
Analyze recent system behavior and detect patterns.
|
|
813
|
+
|
|
814
|
+
Delegates to the PatternAnalysisLoop component.
|
|
815
|
+
"""
|
|
816
|
+
if self._pattern_loop:
|
|
817
|
+
return await self._pattern_loop.analyze_and_adapt(force=force)
|
|
818
|
+
|
|
819
|
+
# Return empty result if no pattern loop
|
|
820
|
+
return AnalysisResult(
|
|
821
|
+
status="no_pattern_loop",
|
|
822
|
+
patterns_detected=0,
|
|
823
|
+
insights_stored=0,
|
|
824
|
+
timestamp=self._time_service.now() if self._time_service else datetime.now(),
|
|
825
|
+
next_analysis_in=None,
|
|
826
|
+
error="Pattern analysis loop not initialized",
|
|
827
|
+
)
|
|
828
|
+
|
|
829
|
+
async def get_detected_patterns(
|
|
830
|
+
self, pattern_type: Optional[PatternType] = None, hours: int = 24
|
|
831
|
+
) -> List[DetectedPattern]:
|
|
832
|
+
"""
|
|
833
|
+
Get recently detected patterns.
|
|
834
|
+
|
|
835
|
+
Queries the pattern loop for detected patterns.
|
|
836
|
+
"""
|
|
837
|
+
if not self._pattern_loop:
|
|
838
|
+
return []
|
|
839
|
+
|
|
840
|
+
# Get patterns from the pattern loop
|
|
841
|
+
all_patterns = list(self._pattern_loop._detected_patterns.values())
|
|
842
|
+
|
|
843
|
+
# Filter by time window
|
|
844
|
+
cutoff_time = (self._time_service.now() if self._time_service else datetime.now()) - timedelta(hours=hours)
|
|
845
|
+
recent_patterns = [p for p in all_patterns if p.detected_at >= cutoff_time]
|
|
846
|
+
|
|
847
|
+
# Filter by type if specified
|
|
848
|
+
if pattern_type:
|
|
849
|
+
recent_patterns = [p for p in recent_patterns if p.pattern_type == pattern_type]
|
|
850
|
+
|
|
851
|
+
return recent_patterns
|
|
852
|
+
|
|
853
|
+
async def get_action_frequency(self, hours: int = 24) -> Dict[str, ActionFrequency]:
|
|
854
|
+
"""
|
|
855
|
+
Get frequency analysis of agent actions.
|
|
856
|
+
|
|
857
|
+
Analyzes telemetry data to compute action frequencies.
|
|
858
|
+
"""
|
|
859
|
+
action_frequencies: Dict[str, ActionFrequency] = {}
|
|
860
|
+
|
|
861
|
+
if not self._memory_bus:
|
|
862
|
+
return action_frequencies
|
|
863
|
+
|
|
864
|
+
# Query telemetry nodes from memory
|
|
865
|
+
from ciris_engine.schemas.services.operations import MemoryQuery
|
|
866
|
+
|
|
867
|
+
query = MemoryQuery(
|
|
868
|
+
node_id="telemetry_metrics", scope=GraphScope.LOCAL, type=NodeType.TSDB_DATA, include_edges=False, depth=1
|
|
869
|
+
)
|
|
870
|
+
|
|
871
|
+
try:
|
|
872
|
+
telemetry_nodes = await self._memory_bus.recall(query, handler_name="self_observation")
|
|
873
|
+
|
|
874
|
+
# Count actions in the time window
|
|
875
|
+
cutoff_time = (self._time_service.now() if self._time_service else datetime.now()) - timedelta(hours=hours)
|
|
876
|
+
action_counts: Dict[str, List[datetime]] = defaultdict(list)
|
|
877
|
+
|
|
878
|
+
for node in telemetry_nodes:
|
|
879
|
+
if isinstance(node.attributes, dict) and node.attributes.get("action"):
|
|
880
|
+
action_name = get_str(node.attributes, "action", "")
|
|
881
|
+
timestamp_str = get_str(node.attributes, "timestamp", "")
|
|
882
|
+
if timestamp_str:
|
|
883
|
+
timestamp = datetime.fromisoformat(timestamp_str)
|
|
884
|
+
if timestamp >= cutoff_time:
|
|
885
|
+
action_counts[action_name].append(timestamp)
|
|
886
|
+
|
|
887
|
+
# Build frequency objects
|
|
888
|
+
for action, timestamps in action_counts.items():
|
|
889
|
+
timestamps_sorted = sorted(timestamps)
|
|
890
|
+
daily_average = len(timestamps) / (hours / 24.0) if hours > 0 else 0.0
|
|
891
|
+
|
|
892
|
+
action_frequencies[action] = ActionFrequency(
|
|
893
|
+
action=action,
|
|
894
|
+
count=len(timestamps),
|
|
895
|
+
evidence=[ts.isoformat() for ts in timestamps_sorted[-3:]], # Last 3 examples
|
|
896
|
+
last_seen=(
|
|
897
|
+
timestamps_sorted[-1]
|
|
898
|
+
if timestamps_sorted
|
|
899
|
+
else (self._time_service.now() if self._time_service else datetime.now())
|
|
900
|
+
),
|
|
901
|
+
daily_average=daily_average,
|
|
902
|
+
)
|
|
903
|
+
|
|
904
|
+
except Exception as e:
|
|
905
|
+
logger.error(f"Failed to get action frequency: {e}")
|
|
906
|
+
|
|
907
|
+
return action_frequencies
|
|
908
|
+
|
|
909
|
+
async def get_pattern_insights(self, limit: int = 50) -> List[PatternInsight]:
|
|
910
|
+
"""
|
|
911
|
+
Get stored pattern insights from graph memory.
|
|
912
|
+
"""
|
|
913
|
+
insights: List[PatternInsight] = []
|
|
914
|
+
|
|
915
|
+
if not self._memory_bus:
|
|
916
|
+
return insights
|
|
917
|
+
|
|
918
|
+
# Query insight nodes
|
|
919
|
+
from ciris_engine.schemas.services.operations import MemoryQuery
|
|
920
|
+
|
|
921
|
+
query = MemoryQuery(
|
|
922
|
+
node_id="pattern_insights", scope=GraphScope.LOCAL, type=NodeType.CONCEPT, include_edges=False, depth=1
|
|
923
|
+
)
|
|
924
|
+
|
|
925
|
+
try:
|
|
926
|
+
insight_nodes = await self._memory_bus.recall(query, handler_name="self_observation")
|
|
927
|
+
|
|
928
|
+
# Convert to PatternInsight objects
|
|
929
|
+
for node in insight_nodes[:limit]:
|
|
930
|
+
if isinstance(node.attributes, dict):
|
|
931
|
+
# Map detected_at to last_seen for schema compatibility
|
|
932
|
+
last_seen_str = get_str(node.attributes, "detected_at", "")
|
|
933
|
+
if last_seen_str:
|
|
934
|
+
try:
|
|
935
|
+
last_seen_dt = datetime.fromisoformat(last_seen_str.replace("Z", "+00:00"))
|
|
936
|
+
except (ValueError, TypeError):
|
|
937
|
+
last_seen_dt = datetime.now()
|
|
938
|
+
else:
|
|
939
|
+
last_seen_dt = datetime.now()
|
|
940
|
+
|
|
941
|
+
insights.append(
|
|
942
|
+
PatternInsight(
|
|
943
|
+
pattern_id=node.id,
|
|
944
|
+
pattern_type=get_str(node.attributes, "pattern_type", "unknown"),
|
|
945
|
+
description=get_str(node.attributes, "description", ""),
|
|
946
|
+
confidence=get_float(node.attributes, "confidence", 0.0),
|
|
947
|
+
occurrences=get_int(node.attributes, "occurrences", 1),
|
|
948
|
+
last_seen=last_seen_dt,
|
|
949
|
+
metadata=(
|
|
950
|
+
node.attributes.get("metadata", {})
|
|
951
|
+
if isinstance(node.attributes.get("metadata"), dict)
|
|
952
|
+
else {}
|
|
953
|
+
),
|
|
954
|
+
)
|
|
955
|
+
)
|
|
956
|
+
|
|
957
|
+
except Exception as e:
|
|
958
|
+
logger.error(f"Failed to get pattern insights: {e}")
|
|
959
|
+
|
|
960
|
+
return insights
|
|
961
|
+
|
|
962
|
+
async def get_learning_summary(self) -> LearningSummary:
|
|
963
|
+
"""
|
|
964
|
+
Get summary of what the system has learned.
|
|
965
|
+
"""
|
|
966
|
+
patterns = await self.get_detected_patterns(hours=168) # 1 week
|
|
967
|
+
action_freq = await self.get_action_frequency(hours=168)
|
|
968
|
+
insights = await self.get_pattern_insights(limit=10)
|
|
969
|
+
|
|
970
|
+
# Group patterns by type
|
|
971
|
+
patterns_by_type: Dict[str, int] = defaultdict(int)
|
|
972
|
+
for pattern in patterns:
|
|
973
|
+
patterns_by_type[pattern.pattern_type.value] += 1
|
|
974
|
+
|
|
975
|
+
# Find most/least used actions
|
|
976
|
+
sorted_actions = sorted(action_freq.items(), key=lambda x: x[1].count, reverse=True)
|
|
977
|
+
most_used = [name for name, _ in sorted_actions[:5]]
|
|
978
|
+
least_used = [name for name, _ in sorted_actions[-5:] if _.count > 0]
|
|
979
|
+
|
|
980
|
+
action_frequencies = {name: freq.count for name, freq in action_freq.items()}
|
|
981
|
+
|
|
982
|
+
recent_insight_descriptions = [insight.description for insight in insights[:5]]
|
|
983
|
+
|
|
984
|
+
current_time = self._time_service.now() if self._time_service else datetime.now(timezone.utc)
|
|
985
|
+
# Ensure both datetimes are timezone-aware for subtraction
|
|
986
|
+
if hasattr(self, "_start_time") and self._start_time is not None:
|
|
987
|
+
if self._start_time.tzinfo is None:
|
|
988
|
+
self._start_time = self._start_time.replace(tzinfo=timezone.utc)
|
|
989
|
+
if current_time.tzinfo is None:
|
|
990
|
+
current_time = current_time.replace(tzinfo=timezone.utc)
|
|
991
|
+
days_running = max(1, (current_time - self._start_time).days)
|
|
992
|
+
else:
|
|
993
|
+
# Fallback if _start_time is not set
|
|
994
|
+
days_running = 1
|
|
995
|
+
learning_rate = len(patterns) / days_running
|
|
996
|
+
|
|
997
|
+
return LearningSummary(
|
|
998
|
+
total_patterns=len(patterns),
|
|
999
|
+
patterns_by_type=dict(patterns_by_type),
|
|
1000
|
+
action_frequencies=action_frequencies,
|
|
1001
|
+
most_used_actions=most_used,
|
|
1002
|
+
least_used_actions=least_used,
|
|
1003
|
+
insights_count=len(insights),
|
|
1004
|
+
recent_insights=recent_insight_descriptions,
|
|
1005
|
+
learning_rate=learning_rate,
|
|
1006
|
+
recommendation="continue" if len(patterns) > 10 else "gather more data",
|
|
1007
|
+
)
|
|
1008
|
+
|
|
1009
|
+
async def get_temporal_patterns(self, hours: int = 168) -> List[TemporalPattern]:
|
|
1010
|
+
"""
|
|
1011
|
+
Get temporal patterns (daily, weekly cycles).
|
|
1012
|
+
"""
|
|
1013
|
+
temporal_patterns = []
|
|
1014
|
+
|
|
1015
|
+
# Get patterns of temporal type
|
|
1016
|
+
patterns = await self.get_detected_patterns(pattern_type=PatternType.TEMPORAL, hours=hours)
|
|
1017
|
+
|
|
1018
|
+
# Convert to TemporalPattern objects
|
|
1019
|
+
for pattern in patterns:
|
|
1020
|
+
temporal_patterns.append(
|
|
1021
|
+
TemporalPattern(
|
|
1022
|
+
pattern_id=pattern.pattern_id,
|
|
1023
|
+
pattern_type=pattern.metrics.metadata.get("temporal_type", "unknown"),
|
|
1024
|
+
time_window=pattern.metrics.metadata.get("time_window", ""),
|
|
1025
|
+
activity_description=pattern.description,
|
|
1026
|
+
occurrence_count=pattern.metrics.occurrence_count,
|
|
1027
|
+
first_detected=pattern.detected_at,
|
|
1028
|
+
last_observed=pattern.detected_at, # Would need to track this separately
|
|
1029
|
+
metrics={
|
|
1030
|
+
"average_value": pattern.metrics.average_value,
|
|
1031
|
+
"peak_value": pattern.metrics.peak_value,
|
|
1032
|
+
"data_points": float(pattern.metrics.data_points),
|
|
1033
|
+
},
|
|
1034
|
+
)
|
|
1035
|
+
)
|
|
1036
|
+
|
|
1037
|
+
return temporal_patterns
|
|
1038
|
+
|
|
1039
|
+
async def get_pattern_effectiveness(self, pattern_id: str) -> Optional[PatternEffectiveness]:
|
|
1040
|
+
"""
|
|
1041
|
+
Get effectiveness metrics for a specific pattern.
|
|
1042
|
+
"""
|
|
1043
|
+
|
|
1044
|
+
# This would need to track whether acting on patterns improved outcomes
|
|
1045
|
+
# For now, return a simple structure
|
|
1046
|
+
|
|
1047
|
+
# Check if pattern exists
|
|
1048
|
+
if self._pattern_loop and pattern_id in self._pattern_loop._detected_patterns:
|
|
1049
|
+
pattern = self._pattern_loop._detected_patterns[pattern_id]
|
|
1050
|
+
|
|
1051
|
+
return PatternEffectiveness(
|
|
1052
|
+
pattern_id=pattern_id,
|
|
1053
|
+
pattern_type=pattern.pattern_type.value,
|
|
1054
|
+
times_applied=0, # Would need to track this
|
|
1055
|
+
success_rate=0.0, # Would need to track outcomes
|
|
1056
|
+
average_improvement=0.0, # Would need metrics
|
|
1057
|
+
last_applied=None,
|
|
1058
|
+
recommendation="monitor", # or "apply", "ignore"
|
|
1059
|
+
)
|
|
1060
|
+
|
|
1061
|
+
return None
|
|
1062
|
+
|
|
1063
|
+
async def get_analysis_status(self) -> AnalysisStatus:
|
|
1064
|
+
"""
|
|
1065
|
+
Get current analysis status.
|
|
1066
|
+
"""
|
|
1067
|
+
time_since_last = (self._time_service.now() if self._time_service else datetime.now()) - self._last_adaptation
|
|
1068
|
+
next_analysis_in = max(0, self._observation_interval.total_seconds() - time_since_last.total_seconds())
|
|
1069
|
+
|
|
1070
|
+
# Get total patterns and insights
|
|
1071
|
+
patterns_detected = len(self._pattern_history)
|
|
1072
|
+
insights = await self.get_pattern_insights()
|
|
1073
|
+
|
|
1074
|
+
return AnalysisStatus(
|
|
1075
|
+
is_running=not self._emergency_stop,
|
|
1076
|
+
last_analysis=self._last_adaptation,
|
|
1077
|
+
next_analysis_in_seconds=next_analysis_in,
|
|
1078
|
+
patterns_detected=patterns_detected,
|
|
1079
|
+
insights_generated=len(insights),
|
|
1080
|
+
analysis_interval_seconds=self._observation_interval.total_seconds(),
|
|
1081
|
+
error_count=self._adaptation_errors,
|
|
1082
|
+
last_error=self._last_error,
|
|
1083
|
+
)
|
|
1084
|
+
|
|
1085
|
+
def get_service_type(self) -> "ServiceType":
|
|
1086
|
+
"""Get the service type enum value."""
|
|
1087
|
+
from ciris_engine.schemas.runtime.enums import ServiceType
|
|
1088
|
+
|
|
1089
|
+
# Self-observation is closest to visibility in available ServiceType options
|
|
1090
|
+
return ServiceType.VISIBILITY
|
|
1091
|
+
|
|
1092
|
+
def _get_actions(self) -> List[str]:
|
|
1093
|
+
"""Get list of actions this service provides."""
|
|
1094
|
+
return [
|
|
1095
|
+
"observe",
|
|
1096
|
+
"analyze_patterns",
|
|
1097
|
+
"get_insights",
|
|
1098
|
+
"get_variance",
|
|
1099
|
+
"pause_adaptation",
|
|
1100
|
+
"resume_adaptation",
|
|
1101
|
+
"emergency_stop",
|
|
1102
|
+
]
|
|
1103
|
+
|
|
1104
|
+
def _check_dependencies(self) -> bool:
|
|
1105
|
+
"""Check if all required dependencies are available."""
|
|
1106
|
+
return self._time_service is not None
|
|
1107
|
+
|
|
1108
|
+
async def get_metrics(self) -> Dict[str, float]:
|
|
1109
|
+
"""Get all self-observation metrics including base, custom, and v1.4.3 specific."""
|
|
1110
|
+
# Get all base + custom metrics
|
|
1111
|
+
metrics = self._collect_metrics()
|
|
1112
|
+
|
|
1113
|
+
# Add v1.4.3 specific metrics
|
|
1114
|
+
metrics.update(
|
|
1115
|
+
{
|
|
1116
|
+
"self_observation_observations": float(self._observations_made),
|
|
1117
|
+
"self_observation_patterns_detected": float(self._patterns_detected),
|
|
1118
|
+
"self_observation_identity_variance": float(self._last_variance_report),
|
|
1119
|
+
"self_observation_uptime_seconds": self._calculate_uptime(),
|
|
1120
|
+
}
|
|
1121
|
+
)
|
|
1122
|
+
|
|
1123
|
+
return metrics
|
|
1124
|
+
|
|
1125
|
+
def _collect_custom_metrics(self) -> Dict[str, float]:
|
|
1126
|
+
"""Collect self-observation metrics."""
|
|
1127
|
+
metrics = super()._collect_custom_metrics()
|
|
1128
|
+
|
|
1129
|
+
# Calculate observation rate
|
|
1130
|
+
obs_rate = 0.0
|
|
1131
|
+
if hasattr(self, "_start_time") and self._start_time:
|
|
1132
|
+
uptime = (datetime.now(timezone.utc) - self._start_time).total_seconds()
|
|
1133
|
+
if uptime > 0:
|
|
1134
|
+
obs_rate = self._observations_made / uptime
|
|
1135
|
+
|
|
1136
|
+
metrics.update(
|
|
1137
|
+
{
|
|
1138
|
+
"observations_made": float(self._observations_made),
|
|
1139
|
+
"patterns_detected": float(self._patterns_detected),
|
|
1140
|
+
"adaptations_triggered": float(self._adaptations_triggered),
|
|
1141
|
+
"performance_checks": float(self._performance_checks),
|
|
1142
|
+
"anomalies_detected": float(self._anomalies_detected),
|
|
1143
|
+
"self_corrections": float(self._self_corrections),
|
|
1144
|
+
"learning_cycles": float(self._learning_cycles),
|
|
1145
|
+
"model_updates": float(self._model_updates),
|
|
1146
|
+
"observation_rate_per_hour": obs_rate * 3600,
|
|
1147
|
+
"pattern_variance_monitor_active": 1.0, # Sub-service
|
|
1148
|
+
"identity_variance_monitor_active": 1.0, # Sub-service
|
|
1149
|
+
"analysis_loop_active": 1.0, # Pattern analysis loop
|
|
1150
|
+
}
|
|
1151
|
+
)
|
|
1152
|
+
|
|
1153
|
+
return metrics
|