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,803 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Incident Management Service - ITIL-aligned incident processing for self-improvement.
|
|
3
|
+
|
|
4
|
+
This service processes incidents captured from logs, detects patterns, identifies problems,
|
|
5
|
+
and generates insights for agent self-improvement. It's integrated with the dream cycle
|
|
6
|
+
for continuous learning from operational issues.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import logging
|
|
10
|
+
from collections import defaultdict
|
|
11
|
+
from datetime import datetime, timedelta
|
|
12
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional
|
|
13
|
+
|
|
14
|
+
import aiofiles
|
|
15
|
+
|
|
16
|
+
from ciris_engine.logic.services.base_graph_service import BaseGraphService
|
|
17
|
+
from ciris_engine.schemas.runtime.enums import ServiceType
|
|
18
|
+
from ciris_engine.schemas.services.core import ServiceCapabilities, ServiceStatus
|
|
19
|
+
from ciris_engine.schemas.services.graph.incident import (
|
|
20
|
+
IncidentInsightNode,
|
|
21
|
+
IncidentNode,
|
|
22
|
+
IncidentSeverity,
|
|
23
|
+
IncidentStatus,
|
|
24
|
+
ProblemNode,
|
|
25
|
+
)
|
|
26
|
+
from ciris_engine.schemas.services.graph_core import GraphScope, NodeType
|
|
27
|
+
from ciris_engine.schemas.services.operations import MemoryOpStatus
|
|
28
|
+
|
|
29
|
+
if TYPE_CHECKING:
|
|
30
|
+
from ciris_engine.logic.buses import MemoryBus
|
|
31
|
+
from ciris_engine.protocols.services.lifecycle.time import TimeServiceProtocol
|
|
32
|
+
|
|
33
|
+
logger = logging.getLogger(__name__)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class IncidentManagementService(BaseGraphService):
|
|
37
|
+
"""
|
|
38
|
+
Manages incidents, problems, and insights for agent self-improvement.
|
|
39
|
+
|
|
40
|
+
This service:
|
|
41
|
+
1. Processes incidents captured from WARNING/ERROR logs
|
|
42
|
+
2. Detects patterns and recurring issues
|
|
43
|
+
3. Identifies root causes (problems)
|
|
44
|
+
4. Generates actionable insights for self-improvement
|
|
45
|
+
5. Tracks effectiveness of applied changes
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
def __init__(
|
|
49
|
+
self, memory_bus: Optional["MemoryBus"] = None, time_service: Optional["TimeServiceProtocol"] = None
|
|
50
|
+
) -> None:
|
|
51
|
+
super().__init__(memory_bus=memory_bus, time_service=time_service)
|
|
52
|
+
self.service_name = "IncidentManagementService"
|
|
53
|
+
self._started = False
|
|
54
|
+
self._start_time: Optional[datetime] = None
|
|
55
|
+
self._metrics_tracking: Dict[str, float] = {
|
|
56
|
+
"created": 0.0,
|
|
57
|
+
"resolved": 0.0,
|
|
58
|
+
"active": 0.0,
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
def _get_time_service(self) -> "TimeServiceProtocol":
|
|
62
|
+
"""Get time service for consistent timestamps."""
|
|
63
|
+
|
|
64
|
+
if self._time_service is None:
|
|
65
|
+
raise RuntimeError("Time service not initialized")
|
|
66
|
+
return self._time_service
|
|
67
|
+
|
|
68
|
+
async def process_recent_incidents(self, hours: int = 24) -> IncidentInsightNode:
|
|
69
|
+
"""
|
|
70
|
+
Process recent incidents to identify patterns and generate insights.
|
|
71
|
+
This is called during the dream cycle for self-improvement.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
hours: How many hours of incidents to analyze
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
IncidentInsightNode with analysis results and recommendations
|
|
78
|
+
"""
|
|
79
|
+
try:
|
|
80
|
+
# Get time service
|
|
81
|
+
time_service = self._get_time_service()
|
|
82
|
+
if not time_service:
|
|
83
|
+
raise RuntimeError("CRITICAL: TimeService not available")
|
|
84
|
+
|
|
85
|
+
# Query recent incidents
|
|
86
|
+
current_time = time_service.now()
|
|
87
|
+
cutoff_time = current_time - timedelta(hours=hours)
|
|
88
|
+
|
|
89
|
+
incidents = await self._get_recent_incidents(cutoff_time)
|
|
90
|
+
|
|
91
|
+
if not incidents:
|
|
92
|
+
logger.info("No incidents found in the last %d hours", hours)
|
|
93
|
+
return self._create_no_incidents_insight(current_time)
|
|
94
|
+
|
|
95
|
+
# Analyze incidents
|
|
96
|
+
patterns = self._detect_patterns(incidents)
|
|
97
|
+
problems = await self._identify_problems(patterns)
|
|
98
|
+
recommendations = self._generate_recommendations(patterns, problems)
|
|
99
|
+
|
|
100
|
+
# Create insight node
|
|
101
|
+
insight = IncidentInsightNode(
|
|
102
|
+
id=f"incident_insight_{current_time.strftime('%Y%m%d_%H%M%S')}",
|
|
103
|
+
type=NodeType.CONCEPT,
|
|
104
|
+
scope=GraphScope.LOCAL,
|
|
105
|
+
attributes={}, # Required for TypedGraphNode
|
|
106
|
+
insight_type="PERIODIC_ANALYSIS",
|
|
107
|
+
summary=self._summarize_analysis(len(incidents), len(patterns), len(problems)),
|
|
108
|
+
details={
|
|
109
|
+
"incident_count": len(incidents),
|
|
110
|
+
"pattern_count": len(patterns),
|
|
111
|
+
"problem_count": len(problems),
|
|
112
|
+
"severity_breakdown": self._get_severity_breakdown(incidents),
|
|
113
|
+
"component_breakdown": self._get_component_breakdown(incidents),
|
|
114
|
+
"time_distribution": self._get_time_distribution(incidents),
|
|
115
|
+
},
|
|
116
|
+
behavioral_adjustments=recommendations.get("behavioral", []),
|
|
117
|
+
configuration_changes=recommendations.get("configuration", []),
|
|
118
|
+
source_incidents=[i.id for i in incidents],
|
|
119
|
+
source_problems=[p.id for p in problems],
|
|
120
|
+
analysis_timestamp=current_time,
|
|
121
|
+
updated_by="IncidentManagementService",
|
|
122
|
+
updated_at=current_time,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
# Store insight in graph
|
|
126
|
+
if self._memory_bus:
|
|
127
|
+
result = await self._memory_bus.memorize(node=insight.to_graph_node(), handler_name=self.service_name)
|
|
128
|
+
|
|
129
|
+
if result.status != MemoryOpStatus.OK:
|
|
130
|
+
logger.error("Failed to store incident insight: %s", result.error)
|
|
131
|
+
else:
|
|
132
|
+
logger.warning("Memory bus not available, cannot store incident insight")
|
|
133
|
+
|
|
134
|
+
# Mark analyzed incidents
|
|
135
|
+
await self._mark_incidents_analyzed(incidents)
|
|
136
|
+
|
|
137
|
+
return insight
|
|
138
|
+
|
|
139
|
+
except Exception as e:
|
|
140
|
+
logger.error("Failed to process incidents: %s", e, exc_info=True)
|
|
141
|
+
raise
|
|
142
|
+
|
|
143
|
+
async def _get_recent_incidents(self, cutoff_time: datetime) -> List[IncidentNode]:
|
|
144
|
+
"""Get recent incidents from memory service."""
|
|
145
|
+
if not self._memory_bus:
|
|
146
|
+
logger.error("Memory bus not available")
|
|
147
|
+
return []
|
|
148
|
+
|
|
149
|
+
try:
|
|
150
|
+
# First try to get from memory service (for tests)
|
|
151
|
+
memory_services = (
|
|
152
|
+
self._memory_bus.service_registry.get_services_by_type("memory")
|
|
153
|
+
if hasattr(self._memory_bus, "service_registry")
|
|
154
|
+
else []
|
|
155
|
+
)
|
|
156
|
+
memory_service = memory_services[0] if memory_services else None
|
|
157
|
+
|
|
158
|
+
if memory_service and hasattr(memory_service, "search"):
|
|
159
|
+
# Use the mocked search method in tests
|
|
160
|
+
nodes = await memory_service.search(NodeType.AUDIT_ENTRY, cutoff_time)
|
|
161
|
+
incidents = []
|
|
162
|
+
for node in nodes:
|
|
163
|
+
try:
|
|
164
|
+
incident = IncidentNode.from_graph_node(node)
|
|
165
|
+
incidents.append(incident)
|
|
166
|
+
except Exception as e:
|
|
167
|
+
logger.warning(f"Failed to parse incident node: {e}")
|
|
168
|
+
continue
|
|
169
|
+
return incidents
|
|
170
|
+
|
|
171
|
+
# Otherwise query memory bus normally
|
|
172
|
+
from ciris_engine.schemas.services.graph.memory import MemorySearchFilter
|
|
173
|
+
|
|
174
|
+
# Create search filter for audit entries created after cutoff time
|
|
175
|
+
search_filter = MemorySearchFilter(
|
|
176
|
+
node_type=NodeType.AUDIT_ENTRY.value, created_after=cutoff_time, limit=1000
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
# Use search method to find audit entries
|
|
180
|
+
nodes = await self._memory_bus.search(
|
|
181
|
+
query="", # Empty query to get all matching nodes
|
|
182
|
+
filters=search_filter,
|
|
183
|
+
handler_name="incident_service",
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
# Convert GraphNodes to IncidentNodes
|
|
187
|
+
incidents = []
|
|
188
|
+
for node in nodes:
|
|
189
|
+
try:
|
|
190
|
+
incident = IncidentNode.from_graph_node(node)
|
|
191
|
+
incidents.append(incident)
|
|
192
|
+
except Exception as e:
|
|
193
|
+
logger.warning(f"Failed to parse incident node: {e}")
|
|
194
|
+
continue
|
|
195
|
+
|
|
196
|
+
return incidents
|
|
197
|
+
|
|
198
|
+
except Exception as e:
|
|
199
|
+
logger.warning(f"Failed to get incidents from memory service: {e}")
|
|
200
|
+
|
|
201
|
+
# Fallback to reading from file if memory service fails
|
|
202
|
+
from pathlib import Path
|
|
203
|
+
|
|
204
|
+
log_dir = Path("/app/logs")
|
|
205
|
+
incidents_file = log_dir / "incidents_latest.log"
|
|
206
|
+
|
|
207
|
+
if not incidents_file.exists():
|
|
208
|
+
logger.warning("No incidents log file found")
|
|
209
|
+
return []
|
|
210
|
+
|
|
211
|
+
incidents = []
|
|
212
|
+
try:
|
|
213
|
+
# Parse the incidents log file
|
|
214
|
+
async with aiofiles.open(incidents_file, "r") as f:
|
|
215
|
+
async for line in f:
|
|
216
|
+
line = line.strip()
|
|
217
|
+
if not line or line.startswith("==="):
|
|
218
|
+
continue
|
|
219
|
+
|
|
220
|
+
# Parse log line: "2025-07-09 15:24:43.200 - WARNING - component - file.py:line - message"
|
|
221
|
+
parts = line.split(" - ", 4)
|
|
222
|
+
if len(parts) >= 5:
|
|
223
|
+
timestamp_str = parts[0]
|
|
224
|
+
level = parts[1].strip()
|
|
225
|
+
component = parts[2].strip()
|
|
226
|
+
location = parts[3].strip()
|
|
227
|
+
message = parts[4].strip()
|
|
228
|
+
|
|
229
|
+
# Parse timestamp
|
|
230
|
+
from datetime import datetime
|
|
231
|
+
|
|
232
|
+
timestamp = datetime.strptime(timestamp_str, "%Y-%m-%d %H:%M:%S.%f")
|
|
233
|
+
|
|
234
|
+
# Skip if before cutoff
|
|
235
|
+
if timestamp.replace(tzinfo=cutoff_time.tzinfo) < cutoff_time:
|
|
236
|
+
continue
|
|
237
|
+
|
|
238
|
+
# Create incident node
|
|
239
|
+
incident = IncidentNode(
|
|
240
|
+
id=f"incident_{timestamp.strftime('%Y%m%d_%H%M%S')}_{hash(message) % 10000}",
|
|
241
|
+
type=NodeType.AUDIT_ENTRY,
|
|
242
|
+
scope=GraphScope.LOCAL,
|
|
243
|
+
attributes={},
|
|
244
|
+
incident_type=level,
|
|
245
|
+
severity=IncidentSeverity.HIGH if level == "ERROR" else IncidentSeverity.MEDIUM,
|
|
246
|
+
status=IncidentStatus.OPEN,
|
|
247
|
+
description=message,
|
|
248
|
+
source_component=component,
|
|
249
|
+
detected_at=timestamp,
|
|
250
|
+
filename=location, # Use location as filename
|
|
251
|
+
line_number=0, # Line number not available from log parsing
|
|
252
|
+
impact="TBD",
|
|
253
|
+
urgency="MEDIUM",
|
|
254
|
+
updated_by="incident_service",
|
|
255
|
+
updated_at=timestamp,
|
|
256
|
+
)
|
|
257
|
+
# Track incident creation
|
|
258
|
+
self._increment_metric("created")
|
|
259
|
+
incidents.append(incident)
|
|
260
|
+
|
|
261
|
+
except Exception as e:
|
|
262
|
+
logger.error(f"Failed to parse incidents log: {e}")
|
|
263
|
+
|
|
264
|
+
logger.info(f"Found {len(incidents)} incidents since {cutoff_time}")
|
|
265
|
+
return incidents
|
|
266
|
+
|
|
267
|
+
def _detect_patterns(self, incidents: List[IncidentNode]) -> Dict[str, List[IncidentNode]]:
|
|
268
|
+
"""Detect patterns in incidents."""
|
|
269
|
+
patterns = defaultdict(list)
|
|
270
|
+
|
|
271
|
+
# Group by error message similarity
|
|
272
|
+
error_groups = self._group_by_similarity(incidents)
|
|
273
|
+
for group_key, group_incidents in error_groups.items():
|
|
274
|
+
if len(group_incidents) >= 3: # At least 3 occurrences
|
|
275
|
+
patterns[f"recurring_error_{group_key}"] = group_incidents
|
|
276
|
+
|
|
277
|
+
# Group by component
|
|
278
|
+
component_groups = defaultdict(list)
|
|
279
|
+
for incident in incidents:
|
|
280
|
+
if hasattr(incident, "source_component") and incident.source_component:
|
|
281
|
+
component_groups[incident.source_component].append(incident)
|
|
282
|
+
else:
|
|
283
|
+
component_groups["unknown"].append(incident)
|
|
284
|
+
|
|
285
|
+
for component, comp_incidents in component_groups.items():
|
|
286
|
+
if len(comp_incidents) >= 5: # Component with many incidents
|
|
287
|
+
patterns[f"component_issues_{component}"] = comp_incidents
|
|
288
|
+
|
|
289
|
+
# Detect time-based clusters (error spikes)
|
|
290
|
+
time_clusters = self._detect_time_clusters(incidents)
|
|
291
|
+
for idx, cluster in enumerate(time_clusters):
|
|
292
|
+
if len(cluster) >= 5: # At least 5 incidents in cluster
|
|
293
|
+
patterns[f"error_spike_{idx}"] = cluster
|
|
294
|
+
|
|
295
|
+
return dict(patterns)
|
|
296
|
+
|
|
297
|
+
async def _identify_problems(self, patterns: Dict[str, List[IncidentNode]]) -> List[ProblemNode]:
|
|
298
|
+
"""Identify root cause problems from patterns."""
|
|
299
|
+
problems: List[ProblemNode] = []
|
|
300
|
+
|
|
301
|
+
# Get current time for timestamps
|
|
302
|
+
if not self._time_service:
|
|
303
|
+
raise RuntimeError("CRITICAL: TimeService not available for incident problem identification")
|
|
304
|
+
current_time = self._time_service.now()
|
|
305
|
+
|
|
306
|
+
for pattern_key, pattern_incidents in patterns.items():
|
|
307
|
+
# Skip if too few incidents
|
|
308
|
+
if len(pattern_incidents) < 3:
|
|
309
|
+
continue
|
|
310
|
+
|
|
311
|
+
# Analyze root causes
|
|
312
|
+
root_causes = self._analyze_root_causes(pattern_incidents)
|
|
313
|
+
|
|
314
|
+
# Create problem node
|
|
315
|
+
problem = ProblemNode(
|
|
316
|
+
id=f"problem_{pattern_key}_{len(problems)}",
|
|
317
|
+
type=NodeType.CONCEPT,
|
|
318
|
+
scope=GraphScope.IDENTITY,
|
|
319
|
+
attributes={}, # Required for TypedGraphNode
|
|
320
|
+
problem_statement=self._create_problem_statement(pattern_key, pattern_incidents),
|
|
321
|
+
affected_incidents=[i.id for i in pattern_incidents],
|
|
322
|
+
status="UNDER_INVESTIGATION",
|
|
323
|
+
potential_root_causes=root_causes,
|
|
324
|
+
recommended_actions=self._suggest_fixes(pattern_key, root_causes),
|
|
325
|
+
incident_count=len(pattern_incidents),
|
|
326
|
+
first_occurrence=min(i.detected_at for i in pattern_incidents),
|
|
327
|
+
last_occurrence=max(i.detected_at for i in pattern_incidents),
|
|
328
|
+
updated_by="IncidentManagementService",
|
|
329
|
+
updated_at=current_time,
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
# Store problem in graph
|
|
333
|
+
if self._memory_bus:
|
|
334
|
+
result = await self._memory_bus.memorize(node=problem.to_graph_node(), handler_name=self.service_name)
|
|
335
|
+
|
|
336
|
+
if result.status == MemoryOpStatus.OK:
|
|
337
|
+
problems.append(problem)
|
|
338
|
+
|
|
339
|
+
# Link incidents to problem
|
|
340
|
+
for incident in pattern_incidents:
|
|
341
|
+
incident.problem_id = problem.id
|
|
342
|
+
incident.status = IncidentStatus.RECURRING
|
|
343
|
+
await self._update_incident(incident)
|
|
344
|
+
else:
|
|
345
|
+
logger.warning("Memory bus not available, cannot store problem node")
|
|
346
|
+
problems.append(problem) # Still add to problems list for return value
|
|
347
|
+
|
|
348
|
+
return problems
|
|
349
|
+
|
|
350
|
+
def _generate_recommendations(
|
|
351
|
+
self, patterns: Dict[str, List[IncidentNode]], problems: List[ProblemNode]
|
|
352
|
+
) -> Dict[str, List[str]]:
|
|
353
|
+
"""Generate actionable recommendations."""
|
|
354
|
+
recommendations: Dict[str, List[str]] = {"behavioral": [], "configuration": []}
|
|
355
|
+
|
|
356
|
+
# Analyze patterns for recommendations
|
|
357
|
+
for pattern_key, incidents in patterns.items():
|
|
358
|
+
if "timeout" in pattern_key.lower():
|
|
359
|
+
recommendations["configuration"].append("Consider increasing timeout values for affected operations")
|
|
360
|
+
recommendations["behavioral"].append(
|
|
361
|
+
"Add retry logic with exponential backoff for timeout-prone operations"
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
elif "memory" in pattern_key.lower():
|
|
365
|
+
recommendations["configuration"].append("Increase memory limits or implement memory usage monitoring")
|
|
366
|
+
recommendations["behavioral"].append("Implement periodic memory cleanup in long-running operations")
|
|
367
|
+
|
|
368
|
+
elif "component_issues" in pattern_key:
|
|
369
|
+
component = pattern_key.split("_")[-1]
|
|
370
|
+
recommendations["behavioral"].append(f"Add additional error handling and logging to {component}")
|
|
371
|
+
recommendations["configuration"].append(f"Consider circuit breaker pattern for {component}")
|
|
372
|
+
|
|
373
|
+
# Analyze problems for deeper recommendations
|
|
374
|
+
for problem in problems:
|
|
375
|
+
if "configuration" in " ".join(problem.potential_root_causes).lower():
|
|
376
|
+
recommendations["configuration"].append("Review and validate all configuration settings")
|
|
377
|
+
|
|
378
|
+
if "resource" in " ".join(problem.potential_root_causes).lower():
|
|
379
|
+
recommendations["behavioral"].append("Implement resource usage monitoring and alerts")
|
|
380
|
+
|
|
381
|
+
# De-duplicate recommendations
|
|
382
|
+
recommendations["behavioral"] = list(set(recommendations["behavioral"]))
|
|
383
|
+
recommendations["configuration"] = list(set(recommendations["configuration"]))
|
|
384
|
+
|
|
385
|
+
return recommendations
|
|
386
|
+
|
|
387
|
+
# Helper methods
|
|
388
|
+
|
|
389
|
+
def _group_by_similarity(self, incidents: List[IncidentNode]) -> Dict[str, List[IncidentNode]]:
|
|
390
|
+
"""Group incidents by error message similarity."""
|
|
391
|
+
groups = defaultdict(list)
|
|
392
|
+
|
|
393
|
+
for incident in incidents:
|
|
394
|
+
# Simple grouping by first few words of description
|
|
395
|
+
key = "_".join(incident.description.split()[:3]).lower()
|
|
396
|
+
groups[key].append(incident)
|
|
397
|
+
|
|
398
|
+
return dict(groups)
|
|
399
|
+
|
|
400
|
+
def _detect_time_clusters(self, incidents: List[IncidentNode]) -> List[List[IncidentNode]]:
|
|
401
|
+
"""Detect time-based clusters of incidents."""
|
|
402
|
+
# Sort by time
|
|
403
|
+
sorted_incidents = sorted(incidents, key=lambda i: i.detected_at)
|
|
404
|
+
|
|
405
|
+
clusters: List[List[IncidentNode]] = []
|
|
406
|
+
current_cluster: List[IncidentNode] = []
|
|
407
|
+
cluster_threshold = timedelta(minutes=5) # Incidents within 5 minutes
|
|
408
|
+
|
|
409
|
+
for incident in sorted_incidents:
|
|
410
|
+
if not current_cluster:
|
|
411
|
+
current_cluster.append(incident)
|
|
412
|
+
else:
|
|
413
|
+
time_diff = incident.detected_at - current_cluster[-1].detected_at
|
|
414
|
+
if time_diff <= cluster_threshold:
|
|
415
|
+
current_cluster.append(incident)
|
|
416
|
+
else:
|
|
417
|
+
if len(current_cluster) >= 3:
|
|
418
|
+
clusters.append(current_cluster)
|
|
419
|
+
current_cluster = [incident]
|
|
420
|
+
|
|
421
|
+
if len(current_cluster) >= 3:
|
|
422
|
+
clusters.append(current_cluster)
|
|
423
|
+
|
|
424
|
+
return clusters
|
|
425
|
+
|
|
426
|
+
def _analyze_root_causes(self, incidents: List[IncidentNode]) -> List[str]:
|
|
427
|
+
"""Analyze potential root causes."""
|
|
428
|
+
root_causes: List[str] = []
|
|
429
|
+
|
|
430
|
+
# Check for common patterns
|
|
431
|
+
descriptions = [i.description.lower() for i in incidents]
|
|
432
|
+
|
|
433
|
+
if any("timeout" in d for d in descriptions):
|
|
434
|
+
root_causes.append("Timeout configuration may be too aggressive")
|
|
435
|
+
|
|
436
|
+
if any("connection" in d for d in descriptions):
|
|
437
|
+
root_causes.append("Network connectivity or service availability issues")
|
|
438
|
+
|
|
439
|
+
if any("memory" in d or "resource" in d for d in descriptions):
|
|
440
|
+
root_causes.append("Resource constraints or memory leaks")
|
|
441
|
+
|
|
442
|
+
if any("permission" in d or "auth" in d for d in descriptions):
|
|
443
|
+
root_causes.append("Authentication or authorization configuration issues")
|
|
444
|
+
|
|
445
|
+
# Check for specific components
|
|
446
|
+
components = set(i.source_component for i in incidents)
|
|
447
|
+
if len(components) == 1:
|
|
448
|
+
root_causes.append(f"Issue isolated to {list(components)[0]} component")
|
|
449
|
+
|
|
450
|
+
return root_causes
|
|
451
|
+
|
|
452
|
+
def _create_problem_statement(self, pattern_key: str, incidents: List[IncidentNode]) -> str:
|
|
453
|
+
"""Create a human-readable problem statement."""
|
|
454
|
+
if "recurring_error" in pattern_key:
|
|
455
|
+
return f"Recurring error: {incidents[0].description} (occurred {len(incidents)} times)"
|
|
456
|
+
elif "component_issues" in pattern_key:
|
|
457
|
+
component = pattern_key.split("_")[-1]
|
|
458
|
+
return f"Multiple issues in {component} component ({len(incidents)} incidents)"
|
|
459
|
+
elif "error_spike" in pattern_key:
|
|
460
|
+
return f"Error spike detected with {len(incidents)} incidents in short time period"
|
|
461
|
+
else:
|
|
462
|
+
return f"Pattern detected: {pattern_key} affecting {len(incidents)} incidents"
|
|
463
|
+
|
|
464
|
+
def _suggest_fixes(self, pattern_key: str, root_causes: List[str]) -> List[str]:
|
|
465
|
+
"""Suggest specific fixes for the problem."""
|
|
466
|
+
fixes = []
|
|
467
|
+
|
|
468
|
+
# Pattern-based fixes
|
|
469
|
+
if "timeout" in pattern_key.lower():
|
|
470
|
+
fixes.append("Increase timeout values in configuration")
|
|
471
|
+
fixes.append("Implement retry logic with exponential backof")
|
|
472
|
+
|
|
473
|
+
# Root cause based fixes
|
|
474
|
+
for cause in root_causes:
|
|
475
|
+
if "memory" in cause.lower():
|
|
476
|
+
fixes.append("Implement memory profiling to identify leaks")
|
|
477
|
+
fixes.append("Add memory usage limits and monitoring")
|
|
478
|
+
elif "network" in cause.lower():
|
|
479
|
+
fixes.append("Add connection pooling and retry logic")
|
|
480
|
+
fixes.append("Implement circuit breaker for external services")
|
|
481
|
+
|
|
482
|
+
return fixes
|
|
483
|
+
|
|
484
|
+
def _summarize_analysis(self, incident_count: int, pattern_count: int, problem_count: int) -> str:
|
|
485
|
+
"""Create a summary of the analysis."""
|
|
486
|
+
if incident_count == 0:
|
|
487
|
+
return "No incidents detected in the analysis period"
|
|
488
|
+
elif problem_count == 0:
|
|
489
|
+
return f"Analyzed {incident_count} incidents, no recurring problems identified"
|
|
490
|
+
else:
|
|
491
|
+
return (
|
|
492
|
+
f"Analyzed {incident_count} incidents, found {pattern_count} patterns "
|
|
493
|
+
f"and identified {problem_count} problems requiring attention"
|
|
494
|
+
)
|
|
495
|
+
|
|
496
|
+
def _get_severity_breakdown(self, incidents: List[IncidentNode]) -> Dict[str, int]:
|
|
497
|
+
"""Get breakdown by severity."""
|
|
498
|
+
breakdown: defaultdict[str, int] = defaultdict(int)
|
|
499
|
+
for incident in incidents:
|
|
500
|
+
breakdown[incident.severity.value] += 1
|
|
501
|
+
return dict(breakdown)
|
|
502
|
+
|
|
503
|
+
def _get_component_breakdown(self, incidents: List[IncidentNode]) -> Dict[str, int]:
|
|
504
|
+
"""Get breakdown by component."""
|
|
505
|
+
breakdown: defaultdict[str, int] = defaultdict(int)
|
|
506
|
+
for incident in incidents:
|
|
507
|
+
breakdown[incident.source_component] += 1
|
|
508
|
+
return dict(breakdown)
|
|
509
|
+
|
|
510
|
+
def _get_time_distribution(self, incidents: List[IncidentNode]) -> Dict[str, int]:
|
|
511
|
+
"""Get distribution over time (hourly buckets)."""
|
|
512
|
+
distribution: defaultdict[str, int] = defaultdict(int)
|
|
513
|
+
for incident in incidents:
|
|
514
|
+
hour_key = incident.detected_at.strftime("%Y-%m-%d %H:00")
|
|
515
|
+
distribution[hour_key] += 1
|
|
516
|
+
return dict(distribution)
|
|
517
|
+
|
|
518
|
+
def _create_no_incidents_insight(self, current_time: datetime) -> IncidentInsightNode:
|
|
519
|
+
"""Create insight when no incidents found."""
|
|
520
|
+
return IncidentInsightNode(
|
|
521
|
+
id=f"incident_insight_{current_time.strftime('%Y%m%d_%H%M%S')}",
|
|
522
|
+
type=NodeType.CONCEPT,
|
|
523
|
+
scope=GraphScope.LOCAL,
|
|
524
|
+
attributes={}, # Required for TypedGraphNode
|
|
525
|
+
insight_type="NO_INCIDENTS",
|
|
526
|
+
summary="No incidents detected - system operating normally",
|
|
527
|
+
details={"incident_count": 0, "pattern_count": 0, "problem_count": 0},
|
|
528
|
+
behavioral_adjustments=[],
|
|
529
|
+
configuration_changes=[],
|
|
530
|
+
source_incidents=[],
|
|
531
|
+
source_problems=[],
|
|
532
|
+
analysis_timestamp=current_time,
|
|
533
|
+
updated_by="IncidentManagementService",
|
|
534
|
+
updated_at=current_time,
|
|
535
|
+
)
|
|
536
|
+
|
|
537
|
+
async def get_incident_count(self, hours: int = 1) -> int:
|
|
538
|
+
"""Get count of incidents in the specified time window.
|
|
539
|
+
|
|
540
|
+
Args:
|
|
541
|
+
hours: Number of hours to look back
|
|
542
|
+
|
|
543
|
+
Returns:
|
|
544
|
+
Count of incidents
|
|
545
|
+
"""
|
|
546
|
+
try:
|
|
547
|
+
time_service = self._get_time_service()
|
|
548
|
+
current_time = time_service.now()
|
|
549
|
+
cutoff_time = current_time - timedelta(hours=hours)
|
|
550
|
+
incidents = await self._get_recent_incidents(cutoff_time)
|
|
551
|
+
return len(incidents)
|
|
552
|
+
except Exception as e:
|
|
553
|
+
logger.warning(f"Failed to get incident count: {e}")
|
|
554
|
+
return 0
|
|
555
|
+
|
|
556
|
+
async def query_incidents(
|
|
557
|
+
self,
|
|
558
|
+
start_time: Optional[datetime] = None,
|
|
559
|
+
end_time: Optional[datetime] = None,
|
|
560
|
+
severity: Optional[str] = None,
|
|
561
|
+
status: Optional[str] = None,
|
|
562
|
+
) -> List[IncidentNode]:
|
|
563
|
+
"""Query incidents with optional filtering.
|
|
564
|
+
|
|
565
|
+
Args:
|
|
566
|
+
start_time: Filter incidents after this time
|
|
567
|
+
end_time: Filter incidents before this time
|
|
568
|
+
severity: Filter by severity (CRITICAL, HIGH, MEDIUM, LOW)
|
|
569
|
+
status: Filter by status (OPEN, INVESTIGATING, RESOLVED, CLOSED, RECURRING)
|
|
570
|
+
|
|
571
|
+
Returns:
|
|
572
|
+
List of matching IncidentNode objects
|
|
573
|
+
"""
|
|
574
|
+
try:
|
|
575
|
+
time_service = self._get_time_service()
|
|
576
|
+
|
|
577
|
+
# Use start_time or default to 24 hours ago
|
|
578
|
+
if not start_time:
|
|
579
|
+
start_time = time_service.now() - timedelta(hours=24)
|
|
580
|
+
|
|
581
|
+
# Get all incidents since start_time
|
|
582
|
+
incidents = await self._get_recent_incidents(start_time)
|
|
583
|
+
|
|
584
|
+
# Apply filters
|
|
585
|
+
filtered_incidents = []
|
|
586
|
+
for incident in incidents:
|
|
587
|
+
# Filter by end_time
|
|
588
|
+
if end_time and incident.detected_at > end_time:
|
|
589
|
+
continue
|
|
590
|
+
|
|
591
|
+
# Filter by severity (case-insensitive)
|
|
592
|
+
if severity and incident.severity.value.upper() != severity.upper():
|
|
593
|
+
continue
|
|
594
|
+
|
|
595
|
+
# Filter by status (case-insensitive)
|
|
596
|
+
if status and incident.status.value.upper() != status.upper():
|
|
597
|
+
continue
|
|
598
|
+
|
|
599
|
+
filtered_incidents.append(incident)
|
|
600
|
+
|
|
601
|
+
return filtered_incidents
|
|
602
|
+
|
|
603
|
+
except Exception as e:
|
|
604
|
+
logger.warning(f"Failed to query incidents: {e}")
|
|
605
|
+
return []
|
|
606
|
+
|
|
607
|
+
async def get_insights(
|
|
608
|
+
self,
|
|
609
|
+
start_time: Optional[datetime] = None,
|
|
610
|
+
end_time: Optional[datetime] = None,
|
|
611
|
+
limit: int = 10,
|
|
612
|
+
) -> List[IncidentInsightNode]:
|
|
613
|
+
"""Get incident insights with optional filtering.
|
|
614
|
+
|
|
615
|
+
Args:
|
|
616
|
+
start_time: Filter insights after this time
|
|
617
|
+
end_time: Filter insights before this time
|
|
618
|
+
limit: Maximum number of insights to return
|
|
619
|
+
|
|
620
|
+
Returns:
|
|
621
|
+
List of IncidentInsightNode objects
|
|
622
|
+
"""
|
|
623
|
+
if not self._memory_bus:
|
|
624
|
+
logger.warning("Memory bus not available")
|
|
625
|
+
return []
|
|
626
|
+
|
|
627
|
+
try:
|
|
628
|
+
from ciris_engine.schemas.services.graph.memory import MemorySearchFilter
|
|
629
|
+
|
|
630
|
+
time_service = self._get_time_service()
|
|
631
|
+
|
|
632
|
+
# Use start_time or default to 7 days ago (insights are less frequent)
|
|
633
|
+
if not start_time:
|
|
634
|
+
start_time = time_service.now() - timedelta(days=7)
|
|
635
|
+
|
|
636
|
+
# Create search filter for insight nodes
|
|
637
|
+
search_filter = MemorySearchFilter(
|
|
638
|
+
node_type=NodeType.CONCEPT.value,
|
|
639
|
+
created_after=start_time,
|
|
640
|
+
limit=limit * 2, # Get extra for filtering
|
|
641
|
+
)
|
|
642
|
+
|
|
643
|
+
# Query for concept nodes (insights are stored as concepts)
|
|
644
|
+
nodes = await self._memory_bus.search(
|
|
645
|
+
query="incident insight",
|
|
646
|
+
filters=search_filter,
|
|
647
|
+
handler_name="incident_service",
|
|
648
|
+
)
|
|
649
|
+
|
|
650
|
+
# Convert to IncidentInsightNode and filter
|
|
651
|
+
insights = []
|
|
652
|
+
for node in nodes:
|
|
653
|
+
try:
|
|
654
|
+
# Check if this is actually an insight node
|
|
655
|
+
attrs = node.attributes if isinstance(node.attributes, dict) else node.attributes.model_dump()
|
|
656
|
+
if "insight_type" not in attrs:
|
|
657
|
+
continue
|
|
658
|
+
|
|
659
|
+
insight = IncidentInsightNode.from_graph_node(node)
|
|
660
|
+
|
|
661
|
+
# Filter by end_time
|
|
662
|
+
if end_time and insight.analysis_timestamp > end_time:
|
|
663
|
+
continue
|
|
664
|
+
|
|
665
|
+
insights.append(insight)
|
|
666
|
+
|
|
667
|
+
# Stop if we've reached the limit
|
|
668
|
+
if len(insights) >= limit:
|
|
669
|
+
break
|
|
670
|
+
|
|
671
|
+
except Exception as e:
|
|
672
|
+
logger.warning(f"Failed to parse insight node: {e}")
|
|
673
|
+
continue
|
|
674
|
+
|
|
675
|
+
return insights
|
|
676
|
+
|
|
677
|
+
except Exception as e:
|
|
678
|
+
logger.warning(f"Failed to get insights: {e}")
|
|
679
|
+
return []
|
|
680
|
+
|
|
681
|
+
async def _mark_incidents_analyzed(self, incidents: List[IncidentNode]) -> None:
|
|
682
|
+
"""Mark incidents as analyzed."""
|
|
683
|
+
for incident in incidents:
|
|
684
|
+
incident.status = IncidentStatus.INVESTIGATING
|
|
685
|
+
await self._update_incident(incident)
|
|
686
|
+
# Track incident resolution when analyzed
|
|
687
|
+
if incident.status == IncidentStatus.INVESTIGATING:
|
|
688
|
+
self._increment_metric("resolved")
|
|
689
|
+
|
|
690
|
+
async def _update_incident(self, incident: IncidentNode) -> None:
|
|
691
|
+
"""Update an incident in the graph."""
|
|
692
|
+
if self._memory_bus:
|
|
693
|
+
result = await self._memory_bus.memorize(node=incident.to_graph_node(), handler_name=self.service_name)
|
|
694
|
+
|
|
695
|
+
if result.status != MemoryOpStatus.OK:
|
|
696
|
+
logger.error("Failed to update incident %s: %s", incident.id, result.error)
|
|
697
|
+
else:
|
|
698
|
+
logger.warning("Memory bus not available, cannot update incident %s", incident.id)
|
|
699
|
+
|
|
700
|
+
# Service protocol methods
|
|
701
|
+
|
|
702
|
+
def get_node_type(self) -> str:
|
|
703
|
+
"""Get the type of nodes this service manages."""
|
|
704
|
+
return "INCIDENT"
|
|
705
|
+
|
|
706
|
+
def _get_actions(self) -> List[str]:
|
|
707
|
+
"""Get list of actions this service can handle."""
|
|
708
|
+
# Graph services typically don't handle actions through buses
|
|
709
|
+
return []
|
|
710
|
+
|
|
711
|
+
# start() and stop() removed - use inherited methods from BaseGraphService/BaseService
|
|
712
|
+
|
|
713
|
+
def get_capabilities(self) -> ServiceCapabilities:
|
|
714
|
+
"""Get service capabilities."""
|
|
715
|
+
return ServiceCapabilities(
|
|
716
|
+
service_name="IncidentManagementService",
|
|
717
|
+
actions=["process_recent_incidents", "detect_patterns", "identify_problems", "generate_insights"],
|
|
718
|
+
version="1.0.0",
|
|
719
|
+
dependencies=["MemoryService", "TimeService"],
|
|
720
|
+
metadata=None,
|
|
721
|
+
)
|
|
722
|
+
|
|
723
|
+
def get_status(self) -> ServiceStatus:
|
|
724
|
+
"""Get service status."""
|
|
725
|
+
current_time = self._time_service.now() if self._time_service else datetime.now()
|
|
726
|
+
uptime_seconds = (current_time - self._start_time).total_seconds() if self._start_time else 0.0
|
|
727
|
+
|
|
728
|
+
return ServiceStatus(
|
|
729
|
+
service_name="IncidentManagementService",
|
|
730
|
+
service_type="graph_service",
|
|
731
|
+
is_healthy=self._started and self._memory_bus is not None,
|
|
732
|
+
uptime_seconds=uptime_seconds,
|
|
733
|
+
metrics={"service_available": bool(self._memory_bus)},
|
|
734
|
+
last_error=None,
|
|
735
|
+
last_health_check=current_time,
|
|
736
|
+
)
|
|
737
|
+
|
|
738
|
+
async def is_healthy(self) -> bool:
|
|
739
|
+
"""Check if service is healthy."""
|
|
740
|
+
return self._started and self._memory_bus is not None
|
|
741
|
+
|
|
742
|
+
def get_service_type(self) -> ServiceType:
|
|
743
|
+
"""Get the service type."""
|
|
744
|
+
return ServiceType.AUDIT
|
|
745
|
+
|
|
746
|
+
async def get_metrics(self) -> Dict[str, float]:
|
|
747
|
+
"""Get incident management service metrics - v1.4.3 set."""
|
|
748
|
+
# Initialize tracking if not present
|
|
749
|
+
if not hasattr(self, "_metrics_tracking"):
|
|
750
|
+
self._metrics_tracking = {
|
|
751
|
+
"created": 0.0,
|
|
752
|
+
"resolved": 0.0,
|
|
753
|
+
"active": 0.0,
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
# Calculate uptime
|
|
757
|
+
uptime_seconds = 0.0
|
|
758
|
+
if self._start_time:
|
|
759
|
+
current_time = self._time_service.now() if self._time_service else datetime.now()
|
|
760
|
+
uptime_seconds = (current_time - self._start_time).total_seconds()
|
|
761
|
+
|
|
762
|
+
# Get active incident count safely
|
|
763
|
+
active_count = 0.0
|
|
764
|
+
try:
|
|
765
|
+
# Get recent unresolved incidents as active count
|
|
766
|
+
incidents_24h = await self.get_incident_count(hours=24)
|
|
767
|
+
# For simplicity, treat last 24h incidents as active if not resolved
|
|
768
|
+
active_count = float(incidents_24h) - self._track_metric("resolved", 0.0)
|
|
769
|
+
if active_count < 0:
|
|
770
|
+
active_count = 0.0
|
|
771
|
+
except Exception as e:
|
|
772
|
+
logger.warning(f"Failed to get active incident count: {e}")
|
|
773
|
+
active_count = 0.0
|
|
774
|
+
|
|
775
|
+
# Return exactly the 4 required v1.4.3 metrics
|
|
776
|
+
return {
|
|
777
|
+
"incidents_created": self._track_metric("created", 0),
|
|
778
|
+
"incidents_resolved": self._track_metric("resolved", 0),
|
|
779
|
+
"incidents_active": float(active_count),
|
|
780
|
+
"incident_uptime_seconds": uptime_seconds,
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
def _track_metric(self, metric_name: str, default: float = 0.0) -> float:
|
|
784
|
+
"""Track a metric with real values from service state."""
|
|
785
|
+
if not hasattr(self, "_metrics_tracking"):
|
|
786
|
+
self._metrics_tracking = {
|
|
787
|
+
"created": 0.0,
|
|
788
|
+
"resolved": 0.0,
|
|
789
|
+
"active": 0.0,
|
|
790
|
+
}
|
|
791
|
+
return float(self._metrics_tracking.get(metric_name, default))
|
|
792
|
+
|
|
793
|
+
def _increment_metric(self, metric_name: str, amount: float = 1.0) -> None:
|
|
794
|
+
"""Increment a tracked metric."""
|
|
795
|
+
if not hasattr(self, "_metrics_tracking"):
|
|
796
|
+
self._metrics_tracking = {
|
|
797
|
+
"created": 0.0,
|
|
798
|
+
"resolved": 0.0,
|
|
799
|
+
"active": 0.0,
|
|
800
|
+
}
|
|
801
|
+
self._metrics_tracking[metric_name] = self._metrics_tracking.get(metric_name, 0.0) + amount
|
|
802
|
+
|
|
803
|
+
# get_telemetry() removed - use get_metrics() from BaseService instead
|