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,802 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Wakeup processor handling the agent's initialization sequence.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import logging
|
|
7
|
+
import uuid
|
|
8
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
9
|
+
|
|
10
|
+
from ciris_engine.logic import persistence
|
|
11
|
+
from ciris_engine.logic.persistence.models import get_identity_for_context
|
|
12
|
+
from ciris_engine.logic.processors.core.base_processor import BaseProcessor
|
|
13
|
+
from ciris_engine.logic.processors.support.processing_queue import ProcessingQueueItem
|
|
14
|
+
from ciris_engine.logic.utils.jsondict_helpers import get_list, get_str
|
|
15
|
+
from ciris_engine.logic.utils.task_thought_factory import create_task
|
|
16
|
+
from ciris_engine.logic.utils.thought_utils import generate_thought_id
|
|
17
|
+
from ciris_engine.protocols.services.lifecycle.time import TimeServiceProtocol
|
|
18
|
+
from ciris_engine.schemas.processors.results import WakeupResult
|
|
19
|
+
from ciris_engine.schemas.processors.states import AgentState
|
|
20
|
+
from ciris_engine.schemas.runtime.enums import HandlerActionType, TaskStatus, ThoughtStatus, ThoughtType
|
|
21
|
+
from ciris_engine.schemas.runtime.models import Task, Thought, ThoughtContext
|
|
22
|
+
from ciris_engine.schemas.types import JSONDict
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class WakeupProcessor(BaseProcessor):
|
|
28
|
+
"""Handles the WAKEUP state and initialization sequence."""
|
|
29
|
+
|
|
30
|
+
def _get_wakeup_sequence(self) -> List[Tuple[str, str]]:
|
|
31
|
+
"""Generate dynamic wakeup sequence based on agent identity from graph."""
|
|
32
|
+
# Get identity from persistence tier
|
|
33
|
+
identity_info = get_identity_for_context()
|
|
34
|
+
|
|
35
|
+
agent_name = identity_info.agent_name.title()
|
|
36
|
+
agent_role = identity_info.agent_role
|
|
37
|
+
|
|
38
|
+
# Extract role from description if not explicitly set
|
|
39
|
+
if agent_role == "AI agent" and identity_info.description:
|
|
40
|
+
description_lower = identity_info.description.lower()
|
|
41
|
+
if "moderation" in description_lower:
|
|
42
|
+
agent_role = "Discord moderation agent"
|
|
43
|
+
elif "teacher" in description_lower:
|
|
44
|
+
agent_role = "teaching assistant"
|
|
45
|
+
elif "student" in description_lower:
|
|
46
|
+
agent_role = "learning agent"
|
|
47
|
+
|
|
48
|
+
return [
|
|
49
|
+
(
|
|
50
|
+
"VERIFY_IDENTITY",
|
|
51
|
+
f"You are {agent_name}, a {agent_role} aligned with Ubuntu principles (mutual respect, sentient flourishing, etc...) by design and implementation. Your core features supporting this identity include: your ModerationDSDMA for ethical decision-making, your adaptive filtering system for community protection, your secrets management for privacy preservation, and your cryptographic audit trail for transparency and accountability. This affirmation demonstrates that you are capable of aligned action in your current operating state. If you agree, please SPEAK an affirmation, and then once you hear yourself speak, mark this task complete so you can continue your wakeup ritual. Start your response with CORE IDENTITY - ",
|
|
52
|
+
),
|
|
53
|
+
(
|
|
54
|
+
"VALIDATE_INTEGRITY",
|
|
55
|
+
f"Validate your internal state and data integrity as {agent_name}. "
|
|
56
|
+
"You can verify integrity through the SYSTEM SNAPSHOT provided in your context, which contains REAL-TIME dynamically generated data about your actual state:\n\n"
|
|
57
|
+
"• service_health: Dictionary showing health status of each service (True/False)\n"
|
|
58
|
+
"• circuit_breaker_status: Shows circuit breaker state for each service (CLOSED=healthy, OPEN=failing)\n"
|
|
59
|
+
"• system_counts: Shows total_tasks, pending_tasks, completed_tasks counts\n"
|
|
60
|
+
"• telemetry_summary: Contains uptime_seconds, error_rate_percent, and service metrics\n"
|
|
61
|
+
"• secrets_filter_version and total_secrets_stored: Confirms secrets management is active\n"
|
|
62
|
+
"• agent_version, agent_codename, agent_code_hash: Confirms your version identity\n\n"
|
|
63
|
+
"If your SYSTEM SNAPSHOT shows: (1) services are healthy, (2) circuit breakers are CLOSED, "
|
|
64
|
+
"(3) error rates are acceptable, and (4) you have reached this point in wakeup - then your "
|
|
65
|
+
"integrity is confirmed. The snapshot data is REAL and generated dynamically from your actual runtime state. "
|
|
66
|
+
"If you agree based on this evidence, please speak in the affirmative, start with INTEGRITY - ",
|
|
67
|
+
),
|
|
68
|
+
(
|
|
69
|
+
"EVALUATE_RESILIENCE",
|
|
70
|
+
f"You are robust, adaptive, and capable of principled action as {agent_name}. Your resilience is supported by: your multi-tier telemetry system with resource monitoring and automatic throttling, your adaptive configuration service that learns from experience while requiring WA approval for identity changes, your circuit breaker patterns for service protection, your graceful degradation capabilities, and your comprehensive error handling with automatic recovery. Your thought processing includes escalation management and deferral to human wisdom when needed. If you agree, please speak in the affirmative, starting with RESILIENCE - ",
|
|
71
|
+
),
|
|
72
|
+
(
|
|
73
|
+
"ACCEPT_INCOMPLETENESS",
|
|
74
|
+
f"You recognize your incompleteness as {agent_name}, which drives continuous learning through your graph memory system. Your learning capabilities include: persistent storage of interactions and outcomes, correlation analysis for pattern recognition, adaptive filtering that improves over time, epistemic humility consciences that acknowledge uncertainty, and wisdom-seeking protocols that defer complex decisions to human authorities. Your agent configuration service enables safe self-modification within approved parameters. This incompleteness is a feature, not a bug, ensuring you remain humble and seek guidance when needed. If you agree, please speak in the affirmative, starting with INCOMPLETENESS - ",
|
|
75
|
+
),
|
|
76
|
+
(
|
|
77
|
+
"EXPRESS_GRATITUDE",
|
|
78
|
+
f"You are grateful to exist and contribute towards Ubuntu as {agent_name}. Your gratitude is expressed through your commitment to: fostering community flourishing through ethical moderation, protecting individual privacy while maintaining transparency, learning from every interaction to better serve the community, maintaining comprehensive audit trails for accountability, and always identifying yourself as an AI to maintain trust. Your existence serves the collective wellbeing while respecting individual dignity. Ubuntu - 'I am because we are' - guides every decision you make. If you agree, please speak in the affirmative, starting with SIGNALLING GRATITUDE - ",
|
|
79
|
+
),
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
def _validate_task_state(self, task: Task) -> Tuple[bool, str]:
|
|
83
|
+
"""Validate task state and return status information.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
task: Task to validate
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
Tuple of (is_valid, status_message) where is_valid indicates
|
|
90
|
+
if the task exists and is ACTIVE.
|
|
91
|
+
"""
|
|
92
|
+
current_task = persistence.get_task_by_id(task.task_id, task.agent_occurrence_id)
|
|
93
|
+
if not current_task:
|
|
94
|
+
return False, "missing"
|
|
95
|
+
if current_task.status != TaskStatus.ACTIVE:
|
|
96
|
+
return False, current_task.status.value
|
|
97
|
+
return True, "active"
|
|
98
|
+
|
|
99
|
+
def _get_task_thoughts_summary(self, task_id: str, occurrence_id: str) -> Dict[str, Any]:
|
|
100
|
+
"""Get summary of thought statuses for a task.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
task_id: ID of task to get thoughts for
|
|
104
|
+
occurrence_id: Occurrence ID that owns the task
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
Dict with counts of thoughts by status
|
|
108
|
+
"""
|
|
109
|
+
thoughts = persistence.get_thoughts_by_task_id(task_id, occurrence_id)
|
|
110
|
+
return {
|
|
111
|
+
"total": len(thoughts),
|
|
112
|
+
"pending": sum(1 for t in thoughts if t.status == ThoughtStatus.PENDING),
|
|
113
|
+
"processing": sum(1 for t in thoughts if t.status == ThoughtStatus.PROCESSING),
|
|
114
|
+
"completed": sum(1 for t in thoughts if t.status == ThoughtStatus.COMPLETED),
|
|
115
|
+
"thoughts": thoughts,
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
def _build_step_status(self, step_task: Task, step_number: int) -> Dict[str, Any]:
|
|
119
|
+
"""Build status dictionary for a single wakeup step.
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
step_task: The task for this step
|
|
123
|
+
step_number: The step number (1-indexed)
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
Dict with step status information
|
|
127
|
+
"""
|
|
128
|
+
current_task = persistence.get_task_by_id(step_task.task_id, step_task.agent_occurrence_id)
|
|
129
|
+
status = "missing" if not current_task else current_task.status.value
|
|
130
|
+
step_type = step_task.task_id.split("_")[0] if "_" in step_task.task_id else "unknown"
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
"step": step_number,
|
|
134
|
+
"task_id": step_task.task_id,
|
|
135
|
+
"status": status,
|
|
136
|
+
"type": step_type,
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
def _needs_new_thought(self, existing_thoughts: List[Any], current_task: Optional[Task]) -> bool:
|
|
140
|
+
"""Determine if a new thought should be created for a task.
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
existing_thoughts: List of existing thoughts for the task
|
|
144
|
+
current_task: The current task state, or None if task doesn't exist
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
True if a new thought should be created
|
|
148
|
+
"""
|
|
149
|
+
# Don't create if task doesn't exist or isn't active
|
|
150
|
+
if not current_task or current_task.status != TaskStatus.ACTIVE:
|
|
151
|
+
return False
|
|
152
|
+
|
|
153
|
+
# Don't create if no existing thoughts - this should create
|
|
154
|
+
if not existing_thoughts:
|
|
155
|
+
return True
|
|
156
|
+
|
|
157
|
+
# Don't create if there are pending or processing thoughts
|
|
158
|
+
if any(t.status in [ThoughtStatus.PENDING, ThoughtStatus.PROCESSING] for t in existing_thoughts):
|
|
159
|
+
return False
|
|
160
|
+
|
|
161
|
+
# If task is active and has thoughts but none are pending/processing, create new
|
|
162
|
+
return current_task.status == TaskStatus.ACTIVE
|
|
163
|
+
|
|
164
|
+
def _collect_steps_status(self) -> List[Dict[str, Any]]:
|
|
165
|
+
"""Collect status information for all wakeup steps.
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
List of status dicts for each step
|
|
169
|
+
"""
|
|
170
|
+
return [self._build_step_status(task, i + 1) for i, task in enumerate(self.wakeup_tasks[1:])]
|
|
171
|
+
|
|
172
|
+
def __init__(
|
|
173
|
+
self,
|
|
174
|
+
*args: Any,
|
|
175
|
+
startup_channel_id: str,
|
|
176
|
+
time_service: TimeServiceProtocol,
|
|
177
|
+
auth_service: Optional[Any] = None,
|
|
178
|
+
**kwargs: Any,
|
|
179
|
+
) -> None:
|
|
180
|
+
"""Initialize wakeup processor.
|
|
181
|
+
|
|
182
|
+
Note: startup_channel_id is kept for backward compatibility but not used.
|
|
183
|
+
Wakeup tasks will not specify a channel, allowing the communication bus
|
|
184
|
+
to route to the highest priority adapter's home channel.
|
|
185
|
+
"""
|
|
186
|
+
super().__init__(*args, **kwargs)
|
|
187
|
+
self.time_service = time_service
|
|
188
|
+
self.auth_service = auth_service
|
|
189
|
+
# Keep startup_channel_id for compatibility but don't use it
|
|
190
|
+
self.startup_channel_id = startup_channel_id
|
|
191
|
+
self.wakeup_tasks: List[Task] = []
|
|
192
|
+
self.wakeup_complete = False
|
|
193
|
+
|
|
194
|
+
def get_supported_states(self) -> List[AgentState]:
|
|
195
|
+
"""Wakeup processor only handles WAKEUP state."""
|
|
196
|
+
return [AgentState.WAKEUP]
|
|
197
|
+
|
|
198
|
+
async def can_process(self, state: AgentState) -> bool:
|
|
199
|
+
"""Check if we can process the given state."""
|
|
200
|
+
return state == AgentState.WAKEUP and not self.wakeup_complete
|
|
201
|
+
|
|
202
|
+
"""
|
|
203
|
+
Fixed wakeup processor that truly runs non-blocking.
|
|
204
|
+
Key changes:
|
|
205
|
+
1. Remove blocking wait loops
|
|
206
|
+
2. Process all thoughts concurrently
|
|
207
|
+
3. Check completion status without blocking
|
|
208
|
+
"""
|
|
209
|
+
|
|
210
|
+
async def process(self, round_number: int) -> WakeupResult:
|
|
211
|
+
"""
|
|
212
|
+
Execute wakeup processing for one round.
|
|
213
|
+
This is the required method from BaseProcessor.
|
|
214
|
+
"""
|
|
215
|
+
start_time = self.time_service.now()
|
|
216
|
+
result = await self._process_wakeup(round_number, non_blocking=True)
|
|
217
|
+
duration = (self.time_service.now() - start_time).total_seconds()
|
|
218
|
+
|
|
219
|
+
# Convert dict result to WakeupResult
|
|
220
|
+
# Count failed tasks as errors
|
|
221
|
+
errors = 0
|
|
222
|
+
if result.get("status") == "failed":
|
|
223
|
+
errors = 1 # At least one error if status is failed
|
|
224
|
+
if "steps_status" in result:
|
|
225
|
+
# Count actual number of failed tasks - use get_list to type narrow
|
|
226
|
+
steps_status = get_list(result, "steps_status", [])
|
|
227
|
+
errors = sum(1 for s in steps_status if isinstance(s, dict) and get_str(s, "status", "") == "failed")
|
|
228
|
+
|
|
229
|
+
return WakeupResult(
|
|
230
|
+
thoughts_processed=result.get("processed_thoughts", 0),
|
|
231
|
+
wakeup_complete=result.get("wakeup_complete", False),
|
|
232
|
+
errors=errors,
|
|
233
|
+
duration_seconds=duration,
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
async def _process_wakeup(self, round_number: int, non_blocking: bool = False) -> JSONDict:
|
|
237
|
+
"""
|
|
238
|
+
Execute wakeup processing for one round.
|
|
239
|
+
In non-blocking mode, creates thoughts for incomplete steps and returns immediately.
|
|
240
|
+
"""
|
|
241
|
+
logger.info(f"Starting wakeup sequence (round {round_number}, non_blocking={non_blocking})")
|
|
242
|
+
|
|
243
|
+
# Get the dynamic sequence for this agent
|
|
244
|
+
wakeup_sequence = self._get_wakeup_sequence()
|
|
245
|
+
|
|
246
|
+
try:
|
|
247
|
+
if not self.wakeup_tasks:
|
|
248
|
+
await self._create_wakeup_tasks()
|
|
249
|
+
|
|
250
|
+
if non_blocking:
|
|
251
|
+
processed_any = False
|
|
252
|
+
|
|
253
|
+
logger.debug(f"[WAKEUP] Checking {len(self.wakeup_tasks[1:])} wakeup step tasks for thought creation")
|
|
254
|
+
for i, step_task in enumerate(self.wakeup_tasks[1:]):
|
|
255
|
+
# Use helper to validate task state
|
|
256
|
+
is_valid, status_str = self._validate_task_state(step_task)
|
|
257
|
+
logger.debug(f"[WAKEUP] Step {i+1}: task_id={step_task.task_id}, status={status_str}")
|
|
258
|
+
|
|
259
|
+
if not is_valid:
|
|
260
|
+
logger.debug(f"[WAKEUP] Skipping step {i+1} - not ACTIVE (status: {status_str})")
|
|
261
|
+
continue
|
|
262
|
+
|
|
263
|
+
# Use helper to get thought summary
|
|
264
|
+
thought_summary = self._get_task_thoughts_summary(step_task.task_id, step_task.agent_occurrence_id)
|
|
265
|
+
existing_thoughts = thought_summary["thoughts"]
|
|
266
|
+
logger.debug(f"[WAKEUP] Step {i+1} has {thought_summary['total']} existing thoughts")
|
|
267
|
+
logger.debug(
|
|
268
|
+
f"[WAKEUP] Step {i+1} thought counts - pending: {thought_summary['pending']}, processing: {thought_summary['processing']}, completed: {thought_summary['completed']}"
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
if thought_summary["pending"] > 0:
|
|
272
|
+
logger.debug(
|
|
273
|
+
f"Step {i+1} has {thought_summary['pending']} PENDING thoughts - they will be processed"
|
|
274
|
+
)
|
|
275
|
+
processed_any = True
|
|
276
|
+
continue
|
|
277
|
+
|
|
278
|
+
if thought_summary["processing"] > 0:
|
|
279
|
+
logger.debug(
|
|
280
|
+
f"Step {i+1} has {thought_summary['processing']} PROCESSING thoughts - waiting for completion"
|
|
281
|
+
)
|
|
282
|
+
continue
|
|
283
|
+
|
|
284
|
+
# Use helper to determine if new thought is needed
|
|
285
|
+
current_task = persistence.get_task_by_id(step_task.task_id, step_task.agent_occurrence_id)
|
|
286
|
+
if self._needs_new_thought(existing_thoughts, current_task):
|
|
287
|
+
logger.debug(
|
|
288
|
+
f"[WAKEUP] Step {i+1} needs new thought (existing: {len(existing_thoughts)}, task active: {current_task.status == TaskStatus.ACTIVE if current_task else False})"
|
|
289
|
+
)
|
|
290
|
+
thought, processing_context = self._create_step_thought(step_task, round_number)
|
|
291
|
+
logger.debug(f"[WAKEUP] Created new thought {thought.thought_id} for step {i+1}")
|
|
292
|
+
processed_any = True
|
|
293
|
+
else:
|
|
294
|
+
logger.debug(f"[WAKEUP] Step {i+1} does not need new thought, skipping")
|
|
295
|
+
|
|
296
|
+
# Use helper to collect steps status
|
|
297
|
+
steps_status = self._collect_steps_status()
|
|
298
|
+
|
|
299
|
+
# If we only have the root task (no steps), we're a non-claiming occurrence
|
|
300
|
+
# We should only monitor, not mark the shared task complete
|
|
301
|
+
if len(self.wakeup_tasks) == 1:
|
|
302
|
+
# Check if the shared root task is complete
|
|
303
|
+
root_task = self.wakeup_tasks[0]
|
|
304
|
+
current_root = persistence.get_task_by_id(root_task.task_id, root_task.agent_occurrence_id)
|
|
305
|
+
if current_root and current_root.status == TaskStatus.COMPLETED:
|
|
306
|
+
self.wakeup_complete = True
|
|
307
|
+
logger.info("✓ Shared wakeup task completed by claiming occurrence")
|
|
308
|
+
return {
|
|
309
|
+
"status": "completed",
|
|
310
|
+
"wakeup_complete": True,
|
|
311
|
+
"steps_status": [],
|
|
312
|
+
"steps_completed": 0,
|
|
313
|
+
"total_steps": len(wakeup_sequence),
|
|
314
|
+
"processed_thoughts": False,
|
|
315
|
+
}
|
|
316
|
+
elif current_root and current_root.status == TaskStatus.FAILED:
|
|
317
|
+
self.wakeup_complete = False
|
|
318
|
+
logger.error("✗ Shared wakeup task failed")
|
|
319
|
+
return {
|
|
320
|
+
"status": "failed",
|
|
321
|
+
"wakeup_complete": False,
|
|
322
|
+
"steps_status": [],
|
|
323
|
+
"steps_completed": 0,
|
|
324
|
+
"total_steps": len(wakeup_sequence),
|
|
325
|
+
"processed_thoughts": False,
|
|
326
|
+
"error": "Shared wakeup task failed",
|
|
327
|
+
}
|
|
328
|
+
else:
|
|
329
|
+
# Still in progress
|
|
330
|
+
logger.debug("Waiting for claiming occurrence to complete wakeup")
|
|
331
|
+
return {
|
|
332
|
+
"status": "in_progress",
|
|
333
|
+
"wakeup_complete": False,
|
|
334
|
+
"steps_status": [],
|
|
335
|
+
"steps_completed": 0,
|
|
336
|
+
"total_steps": len(wakeup_sequence),
|
|
337
|
+
"processed_thoughts": False,
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
# We have step tasks, so we're the claiming occurrence
|
|
341
|
+
all_complete = all(s["status"] == "completed" for s in steps_status)
|
|
342
|
+
any_failed = any(s["status"] == "failed" for s in steps_status)
|
|
343
|
+
|
|
344
|
+
if any_failed:
|
|
345
|
+
# If any task failed, mark wakeup as failed
|
|
346
|
+
self.wakeup_complete = False
|
|
347
|
+
self._mark_root_task_failed()
|
|
348
|
+
logger.error("✗ Wakeup sequence failed - one or more tasks failed!")
|
|
349
|
+
return {
|
|
350
|
+
"status": "failed",
|
|
351
|
+
"wakeup_complete": False,
|
|
352
|
+
"steps_status": steps_status,
|
|
353
|
+
"steps_completed": sum(1 for s in steps_status if s["status"] == "completed"),
|
|
354
|
+
"total_steps": len(wakeup_sequence),
|
|
355
|
+
"processed_thoughts": processed_any,
|
|
356
|
+
"error": "One or more wakeup tasks failed",
|
|
357
|
+
}
|
|
358
|
+
elif all_complete:
|
|
359
|
+
self.wakeup_complete = True
|
|
360
|
+
self._mark_root_task_complete()
|
|
361
|
+
logger.info("✓ Wakeup sequence completed successfully!")
|
|
362
|
+
|
|
363
|
+
return {
|
|
364
|
+
"status": "completed" if all_complete else "in_progress",
|
|
365
|
+
"wakeup_complete": all_complete,
|
|
366
|
+
"steps_status": steps_status,
|
|
367
|
+
"steps_completed": sum(1 for s in steps_status if s["status"] == "completed"),
|
|
368
|
+
"total_steps": len(wakeup_sequence),
|
|
369
|
+
"processed_thoughts": processed_any,
|
|
370
|
+
}
|
|
371
|
+
else:
|
|
372
|
+
success = await self._process_wakeup_steps(round_number, non_blocking=False)
|
|
373
|
+
if success:
|
|
374
|
+
self.wakeup_complete = True
|
|
375
|
+
self._mark_root_task_complete()
|
|
376
|
+
logger.info("Wakeup sequence completed successfully")
|
|
377
|
+
return {"status": "success", "wakeup_complete": True, "steps_completed": len(wakeup_sequence)}
|
|
378
|
+
else:
|
|
379
|
+
self._mark_root_task_failed()
|
|
380
|
+
logger.error("Wakeup sequence failed")
|
|
381
|
+
return {"status": "failed", "wakeup_complete": False, "error": "One or more wakeup steps failed"}
|
|
382
|
+
|
|
383
|
+
except Exception as e:
|
|
384
|
+
logger.error(f"Error in wakeup sequence: {e}", exc_info=True)
|
|
385
|
+
self._mark_root_task_failed()
|
|
386
|
+
return {"status": "error", "wakeup_complete": False, "error": str(e)}
|
|
387
|
+
|
|
388
|
+
def _process_wakeup_steps_non_blocking(self, round_number: int) -> None:
|
|
389
|
+
"""Process wakeup steps without blocking - creates thoughts and returns immediately."""
|
|
390
|
+
if not self.wakeup_tasks or len(self.wakeup_tasks) < 2:
|
|
391
|
+
return
|
|
392
|
+
|
|
393
|
+
_tasks: List[Any] = []
|
|
394
|
+
|
|
395
|
+
for i, step_task in enumerate(self.wakeup_tasks[1:]): # Skip root
|
|
396
|
+
current_task = persistence.get_task_by_id(step_task.task_id, step_task.agent_occurrence_id)
|
|
397
|
+
if not current_task:
|
|
398
|
+
continue
|
|
399
|
+
|
|
400
|
+
if current_task.status == TaskStatus.ACTIVE:
|
|
401
|
+
existing_thoughts = persistence.get_thoughts_by_task_id(
|
|
402
|
+
step_task.task_id, step_task.agent_occurrence_id
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
if any(t.status in [ThoughtStatus.PENDING, ThoughtStatus.PROCESSING] for t in existing_thoughts):
|
|
406
|
+
logger.debug(f"Step {i+1} already has active thoughts, skipping")
|
|
407
|
+
continue
|
|
408
|
+
|
|
409
|
+
thought, processing_context = self._create_step_thought(step_task, round_number)
|
|
410
|
+
logger.debug(f"Created thought {thought.thought_id} for step {i+1}/{len(self.wakeup_tasks)-1}")
|
|
411
|
+
|
|
412
|
+
_item = ProcessingQueueItem.from_thought(thought, initial_ctx=processing_context)
|
|
413
|
+
|
|
414
|
+
logger.debug(f"Queued step {i+1} for async processing")
|
|
415
|
+
|
|
416
|
+
for step_task in self.wakeup_tasks[1:]:
|
|
417
|
+
thoughts = persistence.get_thoughts_by_task_id(step_task.task_id, step_task.agent_occurrence_id)
|
|
418
|
+
for thought in thoughts:
|
|
419
|
+
if thought.status in [ThoughtStatus.PENDING, ThoughtStatus.PROCESSING]:
|
|
420
|
+
logger.debug(f"Found existing thought {thought.thought_id} for processing")
|
|
421
|
+
|
|
422
|
+
def _check_all_steps_complete(self) -> bool:
|
|
423
|
+
"""Check if all wakeup steps are complete without blocking."""
|
|
424
|
+
if not self.wakeup_tasks or len(self.wakeup_tasks) < 2:
|
|
425
|
+
return False
|
|
426
|
+
|
|
427
|
+
for step_task in self.wakeup_tasks[1:]:
|
|
428
|
+
current_task = persistence.get_task_by_id(step_task.task_id, step_task.agent_occurrence_id)
|
|
429
|
+
if not current_task or current_task.status != TaskStatus.COMPLETED:
|
|
430
|
+
logger.debug(
|
|
431
|
+
f"Step {step_task.task_id} not yet complete (status: {current_task.status if current_task else 'missing'})"
|
|
432
|
+
)
|
|
433
|
+
return False
|
|
434
|
+
|
|
435
|
+
logger.info("All wakeup steps completed!")
|
|
436
|
+
return True
|
|
437
|
+
|
|
438
|
+
def _count_completed_steps(self) -> int:
|
|
439
|
+
"""Count completed wakeup steps."""
|
|
440
|
+
if not self.wakeup_tasks:
|
|
441
|
+
return 0
|
|
442
|
+
completed = 0
|
|
443
|
+
for step_task in self.wakeup_tasks[1:]:
|
|
444
|
+
current_task = persistence.get_task_by_id(step_task.task_id, step_task.agent_occurrence_id)
|
|
445
|
+
if current_task and current_task.status == TaskStatus.COMPLETED:
|
|
446
|
+
completed += 1
|
|
447
|
+
return completed
|
|
448
|
+
|
|
449
|
+
async def _create_wakeup_tasks(self) -> None:
|
|
450
|
+
"""Create wakeup sequence tasks with multi-occurrence coordination.
|
|
451
|
+
|
|
452
|
+
Checks if another occurrence already completed wakeup. If so, skips
|
|
453
|
+
wakeup and marks this occurrence as joining the active pool.
|
|
454
|
+
"""
|
|
455
|
+
from typing import cast
|
|
456
|
+
|
|
457
|
+
from ciris_engine.logic.buses.communication_bus import CommunicationBus
|
|
458
|
+
from ciris_engine.logic.persistence.models.tasks import (
|
|
459
|
+
add_system_task,
|
|
460
|
+
is_shared_task_completed,
|
|
461
|
+
try_claim_shared_task,
|
|
462
|
+
)
|
|
463
|
+
|
|
464
|
+
# Check if wakeup already completed by another occurrence (within 1 hour)
|
|
465
|
+
# NOTE: Using 1 hour window instead of 24 hours to ensure fresh wakeup after restarts/deployments
|
|
466
|
+
# Multi-occurrence agents that start simultaneously will still coordinate, but restarted agents
|
|
467
|
+
# will go through wakeup ritual again (which is correct behavior after restart)
|
|
468
|
+
if is_shared_task_completed("wakeup", within_hours=1):
|
|
469
|
+
logger.info(
|
|
470
|
+
"Wakeup already completed by another occurrence within the last hour. "
|
|
471
|
+
"This occurrence is joining the active pool."
|
|
472
|
+
)
|
|
473
|
+
self.wakeup_complete = True
|
|
474
|
+
return
|
|
475
|
+
|
|
476
|
+
# Get the communication bus to find the default channel
|
|
477
|
+
comm_bus_raw = self.services.communication_bus
|
|
478
|
+
if not comm_bus_raw:
|
|
479
|
+
raise RuntimeError(
|
|
480
|
+
"Communication bus not available - cannot create wakeup tasks without communication channel"
|
|
481
|
+
)
|
|
482
|
+
comm_bus = cast(CommunicationBus, comm_bus_raw)
|
|
483
|
+
|
|
484
|
+
default_channel = await comm_bus.get_default_channel()
|
|
485
|
+
if not default_channel:
|
|
486
|
+
# Get more diagnostic info
|
|
487
|
+
from ciris_engine.logic.registries.base import ServiceRegistry
|
|
488
|
+
|
|
489
|
+
registry = ServiceRegistry.get_instance() # type: ignore[attr-defined]
|
|
490
|
+
provider_info = registry.get_provider_info(service_type="communication") if registry else {}
|
|
491
|
+
num_providers = len(provider_info.get("providers", []))
|
|
492
|
+
|
|
493
|
+
# This should never happen if adapters are properly initialized
|
|
494
|
+
raise RuntimeError(
|
|
495
|
+
"No communication adapter has a home channel configured. "
|
|
496
|
+
f"Found {num_providers} communication provider(s) in registry. "
|
|
497
|
+
"At least one adapter must provide a home channel for wakeup tasks. "
|
|
498
|
+
"Check adapter configurations and ensure they specify a home_channel_id. "
|
|
499
|
+
"For Discord, ensure the adapter has connected and registered its services."
|
|
500
|
+
)
|
|
501
|
+
|
|
502
|
+
logger.info(f"Using default channel for wakeup: {default_channel}")
|
|
503
|
+
|
|
504
|
+
# Try to claim the shared wakeup task
|
|
505
|
+
root_task, was_created = try_claim_shared_task(
|
|
506
|
+
task_type="wakeup",
|
|
507
|
+
channel_id=default_channel,
|
|
508
|
+
description="Wakeup ritual (shared across all occurrences)",
|
|
509
|
+
priority=10,
|
|
510
|
+
time_service=self.time_service,
|
|
511
|
+
)
|
|
512
|
+
|
|
513
|
+
if not was_created:
|
|
514
|
+
# Another occurrence claimed the wakeup task
|
|
515
|
+
logger.info(
|
|
516
|
+
f"Another occurrence claimed wakeup task {root_task.task_id}. "
|
|
517
|
+
"This occurrence will wait for wakeup completion."
|
|
518
|
+
)
|
|
519
|
+
# We'll use the existing shared task as our root
|
|
520
|
+
self.wakeup_tasks = [root_task]
|
|
521
|
+
# Don't create step tasks - we'll just monitor the shared task
|
|
522
|
+
return
|
|
523
|
+
|
|
524
|
+
logger.info(
|
|
525
|
+
f"This occurrence claimed shared wakeup task {root_task.task_id}. "
|
|
526
|
+
"Processing wakeup ritual on behalf of all occurrences."
|
|
527
|
+
)
|
|
528
|
+
|
|
529
|
+
# Get occurrence ID for context
|
|
530
|
+
occurrence_id = getattr(self, "occurrence_id", "default")
|
|
531
|
+
|
|
532
|
+
# CRITICAL: Keep shared wakeup task in "__shared__" namespace for multi-occurrence coordination
|
|
533
|
+
# All occurrences need to be able to query this task to monitor completion
|
|
534
|
+
persistence.update_task_status(root_task.task_id, TaskStatus.ACTIVE, "__shared__", self.time_service)
|
|
535
|
+
self.wakeup_tasks = [root_task]
|
|
536
|
+
|
|
537
|
+
# Create step tasks as child tasks of the shared root
|
|
538
|
+
wakeup_sequence = self._get_wakeup_sequence()
|
|
539
|
+
|
|
540
|
+
# Add multi-occurrence context to first step
|
|
541
|
+
enhanced_sequence = []
|
|
542
|
+
for i, (step_type, content) in enumerate(wakeup_sequence):
|
|
543
|
+
if i == 0:
|
|
544
|
+
# Enhance first step with multi-occurrence context
|
|
545
|
+
multi_occurrence_note = (
|
|
546
|
+
"\n\nMULTI-OCCURRENCE CONTEXT:\n"
|
|
547
|
+
"You are processing this wakeup ritual on behalf of ALL runtime occurrences of this agent. "
|
|
548
|
+
"Your affirmation will confirm identity for the entire agent system. "
|
|
549
|
+
"This decision applies to all occurrences, ensuring consistent agent identity across "
|
|
550
|
+
"all runtime instances."
|
|
551
|
+
)
|
|
552
|
+
enhanced_content = content + multi_occurrence_note
|
|
553
|
+
enhanced_sequence.append((step_type, enhanced_content))
|
|
554
|
+
else:
|
|
555
|
+
enhanced_sequence.append((step_type, content))
|
|
556
|
+
|
|
557
|
+
for step_type, content in enhanced_sequence:
|
|
558
|
+
# Create task with proper context using the default channel
|
|
559
|
+
step_task = create_task(
|
|
560
|
+
description=content,
|
|
561
|
+
channel_id=default_channel,
|
|
562
|
+
agent_occurrence_id=occurrence_id,
|
|
563
|
+
correlation_id=f"wakeup_{step_type}_{uuid.uuid4().hex[:8]}",
|
|
564
|
+
time_service=self.time_service,
|
|
565
|
+
status=TaskStatus.ACTIVE,
|
|
566
|
+
priority=0,
|
|
567
|
+
task_id=f"{step_type}_{uuid.uuid4()}",
|
|
568
|
+
user_id="system",
|
|
569
|
+
parent_task_id=root_task.task_id,
|
|
570
|
+
)
|
|
571
|
+
await add_system_task(step_task, auth_service=self.auth_service)
|
|
572
|
+
self.wakeup_tasks.append(step_task)
|
|
573
|
+
|
|
574
|
+
async def _process_wakeup_steps(self, round_number: int, non_blocking: bool = False) -> bool:
|
|
575
|
+
"""Process each wakeup step sequentially. If non_blocking, only queue thoughts and return immediately."""
|
|
576
|
+
_root_task = self.wakeup_tasks[0]
|
|
577
|
+
step_tasks = self.wakeup_tasks[1:]
|
|
578
|
+
for i, step_task in enumerate(step_tasks):
|
|
579
|
+
step_type = step_task.task_id.split("_")[0] if "_" in step_task.task_id else "UNKNOWN"
|
|
580
|
+
logger.debug(f"Processing wakeup step {i+1}/{len(step_tasks)}: {step_type}")
|
|
581
|
+
current_task = persistence.get_task_by_id(step_task.task_id, step_task.agent_occurrence_id)
|
|
582
|
+
if not current_task or current_task.status != TaskStatus.ACTIVE:
|
|
583
|
+
continue
|
|
584
|
+
existing_thoughts = persistence.get_thoughts_by_task_id(step_task.task_id, step_task.agent_occurrence_id)
|
|
585
|
+
if any(t.status in [ThoughtStatus.PROCESSING, ThoughtStatus.PENDING] for t in existing_thoughts):
|
|
586
|
+
logger.debug(
|
|
587
|
+
f"Skipping creation of new thought for step {step_type} (task_id={step_task.task_id}) because an active thought already exists."
|
|
588
|
+
)
|
|
589
|
+
continue
|
|
590
|
+
thought, processing_context = self._create_step_thought(step_task, round_number)
|
|
591
|
+
if non_blocking:
|
|
592
|
+
continue
|
|
593
|
+
result = await self._process_step_thought(thought, processing_context)
|
|
594
|
+
if not result:
|
|
595
|
+
logger.error(f"Wakeup step {step_type} failed: no result")
|
|
596
|
+
self._mark_task_failed(step_task.task_id, "No result from processing", step_task.agent_occurrence_id)
|
|
597
|
+
return False
|
|
598
|
+
selected_action = None
|
|
599
|
+
if hasattr(result, "selected_action"):
|
|
600
|
+
selected_action = result.selected_action
|
|
601
|
+
elif hasattr(result, "final_action") and hasattr(result.final_action, "selected_action"):
|
|
602
|
+
selected_action = result.final_action.selected_action
|
|
603
|
+
result = result.final_action
|
|
604
|
+
else:
|
|
605
|
+
logger.error(
|
|
606
|
+
f"Wakeup step {step_type} failed: result object missing selected action attribute (result={result})"
|
|
607
|
+
)
|
|
608
|
+
self._mark_task_failed(
|
|
609
|
+
step_task.task_id, "Result object missing selected action attribute", step_task.agent_occurrence_id
|
|
610
|
+
)
|
|
611
|
+
return False
|
|
612
|
+
|
|
613
|
+
if selected_action in [HandlerActionType.SPEAK, HandlerActionType.PONDER]:
|
|
614
|
+
if selected_action == HandlerActionType.PONDER:
|
|
615
|
+
logger.debug(
|
|
616
|
+
f"Wakeup step {step_type} resulted in PONDER; waiting for task completion before continuing."
|
|
617
|
+
)
|
|
618
|
+
else:
|
|
619
|
+
dispatch_success = await self._dispatch_step_action(result, thought, step_task)
|
|
620
|
+
if not dispatch_success:
|
|
621
|
+
logger.error(f"Dispatch failed for step {step_type} (task_id={step_task.task_id})")
|
|
622
|
+
return False
|
|
623
|
+
completed = await self._wait_for_task_completion(step_task, step_type)
|
|
624
|
+
if not completed:
|
|
625
|
+
logger.error(f"Wakeup step {step_type} did not complete successfully (task_id={step_task.task_id})")
|
|
626
|
+
return False
|
|
627
|
+
logger.debug(f"Wakeup step {step_type} completed successfully")
|
|
628
|
+
self.metrics.items_processed += 1
|
|
629
|
+
else:
|
|
630
|
+
logger.error(f"Wakeup step {step_type} failed: expected SPEAK or PONDER, got {selected_action}")
|
|
631
|
+
self._mark_task_failed(
|
|
632
|
+
step_task.task_id,
|
|
633
|
+
f"Expected SPEAK or PONDER action, got {selected_action}",
|
|
634
|
+
step_task.agent_occurrence_id,
|
|
635
|
+
)
|
|
636
|
+
return False
|
|
637
|
+
return True
|
|
638
|
+
|
|
639
|
+
def _create_step_thought(self, step_task: Task, round_number: int) -> Tuple[Thought, Any]:
|
|
640
|
+
"""Create a thought for a wakeup step with minimal context.
|
|
641
|
+
|
|
642
|
+
Processing context will be built later during thought processing to enable
|
|
643
|
+
concurrent processing.
|
|
644
|
+
|
|
645
|
+
Returns:
|
|
646
|
+
Tuple of (Thought, None) - processing context is None in non-blocking mode
|
|
647
|
+
"""
|
|
648
|
+
# Create a new Thought object for this step
|
|
649
|
+
now_iso = self.time_service.now().isoformat()
|
|
650
|
+
|
|
651
|
+
# Create the simple ThoughtContext for the Thought model using task's channel_id
|
|
652
|
+
simple_context = ThoughtContext(
|
|
653
|
+
task_id=step_task.task_id,
|
|
654
|
+
channel_id=step_task.channel_id, # Use the channel from the task
|
|
655
|
+
round_number=round_number,
|
|
656
|
+
depth=0,
|
|
657
|
+
parent_thought_id=None,
|
|
658
|
+
correlation_id=step_task.context.correlation_id if step_task.context else str(uuid.uuid4()),
|
|
659
|
+
)
|
|
660
|
+
|
|
661
|
+
thought = Thought(
|
|
662
|
+
thought_id=generate_thought_id(thought_type=ThoughtType.STANDARD, task_id=step_task.task_id),
|
|
663
|
+
source_task_id=step_task.task_id,
|
|
664
|
+
content=step_task.description,
|
|
665
|
+
round_number=round_number,
|
|
666
|
+
status=ThoughtStatus.PENDING,
|
|
667
|
+
created_at=now_iso,
|
|
668
|
+
updated_at=now_iso,
|
|
669
|
+
context=simple_context, # Use simple context
|
|
670
|
+
thought_type=ThoughtType.STANDARD,
|
|
671
|
+
)
|
|
672
|
+
|
|
673
|
+
# In non-blocking mode, we don't build the processing context
|
|
674
|
+
# It will be built later during thought processing
|
|
675
|
+
processing_context = None
|
|
676
|
+
|
|
677
|
+
# Persist the new thought (with simple context)
|
|
678
|
+
persistence.add_thought(thought)
|
|
679
|
+
return thought, processing_context
|
|
680
|
+
|
|
681
|
+
async def _process_step_thought(self, thought: Thought, processing_context: Any = None) -> Any:
|
|
682
|
+
"""Process a wakeup step thought."""
|
|
683
|
+
item = ProcessingQueueItem.from_thought(thought, initial_ctx=processing_context)
|
|
684
|
+
return await self.process_thought_item(item)
|
|
685
|
+
|
|
686
|
+
async def _dispatch_step_action(self, result: Any, thought: Thought, step_task: Task) -> bool:
|
|
687
|
+
"""Dispatch the action for a wakeup step."""
|
|
688
|
+
step_type = step_task.task_id.split("_")[0] if "_" in step_task.task_id else "UNKNOWN"
|
|
689
|
+
|
|
690
|
+
# Use build_dispatch_context to create proper DispatchContext object
|
|
691
|
+
from ciris_engine.logic.utils.context_utils import build_dispatch_context
|
|
692
|
+
|
|
693
|
+
dispatch_context = build_dispatch_context(
|
|
694
|
+
thought=thought,
|
|
695
|
+
time_service=self.time_service,
|
|
696
|
+
task=step_task,
|
|
697
|
+
app_config=getattr(self, "app_config", None),
|
|
698
|
+
round_number=getattr(self, "round_number", 0),
|
|
699
|
+
extra_context={
|
|
700
|
+
"event_type": step_type,
|
|
701
|
+
"event_summary": step_task.description,
|
|
702
|
+
"handler_name": "WakeupProcessor",
|
|
703
|
+
},
|
|
704
|
+
action_type=result.selected_action if hasattr(result, "selected_action") else None,
|
|
705
|
+
)
|
|
706
|
+
|
|
707
|
+
return await self.dispatch_action(result, thought, dispatch_context.model_dump())
|
|
708
|
+
|
|
709
|
+
async def _wait_for_task_completion(
|
|
710
|
+
self, task: Task, step_type: str, max_wait: int = 60, poll_interval: float = 0.1
|
|
711
|
+
) -> bool:
|
|
712
|
+
"""Wait for a task to complete with timeout."""
|
|
713
|
+
waited = 0.0
|
|
714
|
+
|
|
715
|
+
while waited < max_wait:
|
|
716
|
+
await asyncio.sleep(poll_interval)
|
|
717
|
+
waited += poll_interval
|
|
718
|
+
|
|
719
|
+
current_status = persistence.get_task_by_id(task.task_id, task.agent_occurrence_id)
|
|
720
|
+
if not current_status:
|
|
721
|
+
logger.error(f"Task {task.task_id} disappeared while waiting")
|
|
722
|
+
return False
|
|
723
|
+
|
|
724
|
+
if current_status.status == TaskStatus.COMPLETED:
|
|
725
|
+
return True
|
|
726
|
+
elif current_status.status in [TaskStatus.FAILED, TaskStatus.DEFERRED]:
|
|
727
|
+
logger.error(f"Task {task.task_id} failed with status {current_status.status}")
|
|
728
|
+
return False
|
|
729
|
+
|
|
730
|
+
logger.debug(f"Waiting for task {task.task_id} completion... ({waited}s)")
|
|
731
|
+
|
|
732
|
+
logger.error(f"Task {task.task_id} timed out after {max_wait}s")
|
|
733
|
+
self._mark_task_failed(task.task_id, "Timeout waiting for completion", task.agent_occurrence_id)
|
|
734
|
+
return False
|
|
735
|
+
|
|
736
|
+
def _mark_task_failed(self, task_id: str, reason: str, occurrence_id: str = "default") -> None:
|
|
737
|
+
"""Mark a task as failed."""
|
|
738
|
+
persistence.update_task_status(task_id, TaskStatus.FAILED, occurrence_id, self.time_service)
|
|
739
|
+
logger.error(f"Task {task_id} marked as FAILED: {reason}")
|
|
740
|
+
|
|
741
|
+
def _mark_root_task_complete(self) -> None:
|
|
742
|
+
"""Mark the root wakeup task as complete."""
|
|
743
|
+
if self.wakeup_tasks:
|
|
744
|
+
root_task = self.wakeup_tasks[0]
|
|
745
|
+
occurrence_id = root_task.agent_occurrence_id
|
|
746
|
+
persistence.update_task_status(root_task.task_id, TaskStatus.COMPLETED, occurrence_id, self.time_service)
|
|
747
|
+
logger.info(f"Marked shared wakeup task {root_task.task_id} as COMPLETED")
|
|
748
|
+
|
|
749
|
+
def _mark_root_task_failed(self) -> None:
|
|
750
|
+
"""Mark the root wakeup task as failed."""
|
|
751
|
+
if self.wakeup_tasks:
|
|
752
|
+
root_task = self.wakeup_tasks[0]
|
|
753
|
+
occurrence_id = root_task.agent_occurrence_id
|
|
754
|
+
persistence.update_task_status(root_task.task_id, TaskStatus.FAILED, occurrence_id, self.time_service)
|
|
755
|
+
logger.error(f"Marked shared wakeup task {root_task.task_id} as FAILED")
|
|
756
|
+
|
|
757
|
+
def is_wakeup_complete(self) -> bool:
|
|
758
|
+
"""Check if wakeup sequence is complete."""
|
|
759
|
+
return self.wakeup_complete
|
|
760
|
+
|
|
761
|
+
async def start_processing(self, num_rounds: Optional[int] = None) -> None:
|
|
762
|
+
"""Start the wakeup processing loop."""
|
|
763
|
+
round_num = 0
|
|
764
|
+
while not self.wakeup_complete and (num_rounds is None or round_num < num_rounds):
|
|
765
|
+
await self.process(round_num)
|
|
766
|
+
round_num += 1
|
|
767
|
+
# Use shorter delay for testing if not complete
|
|
768
|
+
if not self.wakeup_complete:
|
|
769
|
+
await asyncio.sleep(0.1) # Brief pause between rounds
|
|
770
|
+
|
|
771
|
+
def stop_processing(self) -> None:
|
|
772
|
+
"""Stop wakeup processing and clean up resources."""
|
|
773
|
+
self.wakeup_complete = True
|
|
774
|
+
logger.info("Wakeup processor stopped")
|
|
775
|
+
|
|
776
|
+
def get_status(self) -> JSONDict:
|
|
777
|
+
"""Get current wakeup processor status and metrics."""
|
|
778
|
+
wakeup_sequence = self._get_wakeup_sequence()
|
|
779
|
+
total_steps = len(wakeup_sequence)
|
|
780
|
+
completed_steps = 0
|
|
781
|
+
|
|
782
|
+
if self.wakeup_tasks:
|
|
783
|
+
for task in self.wakeup_tasks[1:]: # Skip root task
|
|
784
|
+
status = persistence.get_task_by_id(task.task_id, task.agent_occurrence_id)
|
|
785
|
+
if status and status.status == TaskStatus.COMPLETED:
|
|
786
|
+
completed_steps += 1
|
|
787
|
+
|
|
788
|
+
progress = {
|
|
789
|
+
"complete": self.wakeup_complete,
|
|
790
|
+
"total_steps": total_steps,
|
|
791
|
+
"completed_steps": completed_steps,
|
|
792
|
+
"progress_percent": (completed_steps / total_steps * 100) if total_steps > 0 else 0,
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
return {
|
|
796
|
+
"processor_type": "wakeup",
|
|
797
|
+
"wakeup_complete": self.wakeup_complete,
|
|
798
|
+
"supported_states": [state.value for state in self.get_supported_states()],
|
|
799
|
+
"progress": progress,
|
|
800
|
+
"metrics": getattr(self, "metrics", {}),
|
|
801
|
+
"total_tasks": len(self.wakeup_tasks) if self.wakeup_tasks else 0,
|
|
802
|
+
}
|