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,783 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
from typing import Any, Dict, List, Optional, TypedDict, Union, cast
|
|
4
|
+
|
|
5
|
+
import discord # Ensure discord.py is available
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
from ciris_engine.logic.adapters.base import Service
|
|
9
|
+
from ciris_engine.logic.adapters.discord.ciris_discord_client import CIRISDiscordClient
|
|
10
|
+
from ciris_engine.logic.adapters.discord.discord_adapter import DiscordAdapter
|
|
11
|
+
from ciris_engine.logic.adapters.discord.discord_observer import DiscordObserver
|
|
12
|
+
from ciris_engine.logic.adapters.discord.discord_tool_service import DiscordToolService
|
|
13
|
+
from ciris_engine.logic.registries.base import Priority
|
|
14
|
+
from ciris_engine.schemas.adapters import AdapterServiceRegistration
|
|
15
|
+
from ciris_engine.schemas.adapters.discord import DiscordChannelInfo
|
|
16
|
+
from ciris_engine.schemas.runtime.enums import ServiceType
|
|
17
|
+
from ciris_engine.schemas.runtime.messages import DiscordMessage
|
|
18
|
+
|
|
19
|
+
from .config import DiscordAdapterConfig
|
|
20
|
+
|
|
21
|
+
# from ciris_engine.logic.adapters.discord.discord_tools import register_discord_tools
|
|
22
|
+
|
|
23
|
+
logger = logging.getLogger(__name__)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class DiscordPlatformKwargs(TypedDict, total=False):
|
|
27
|
+
"""Type-safe kwargs for DiscordPlatform initialization."""
|
|
28
|
+
|
|
29
|
+
adapter_config: Union[DiscordAdapterConfig, dict[str, Any]]
|
|
30
|
+
bot_token: Optional[str]
|
|
31
|
+
channel_id: Optional[str]
|
|
32
|
+
server_id: Optional[str]
|
|
33
|
+
deferral_channel_id: Optional[str]
|
|
34
|
+
admin_user_ids: Optional[List[str]]
|
|
35
|
+
discord_bot_token: Optional[str]
|
|
36
|
+
discord_monitored_channel_ids: Optional[List[str]]
|
|
37
|
+
discord_monitored_channel_id: Optional[str]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class DiscordTaskErrorContext(BaseModel):
|
|
41
|
+
"""Error context for Discord task lifecycle failures."""
|
|
42
|
+
|
|
43
|
+
task_exists: bool = Field(..., description="Whether Discord task exists")
|
|
44
|
+
task_done: Optional[bool] = Field(None, description="Whether Discord task is done")
|
|
45
|
+
task_cancelled: Optional[bool] = Field(None, description="Whether Discord task was cancelled")
|
|
46
|
+
task_exception: Optional[str] = Field(None, description="Exception from Discord task if available")
|
|
47
|
+
client_closed: Optional[bool] = Field(None, description="Whether Discord client is closed")
|
|
48
|
+
client_user: Optional[str] = Field(None, description="Discord client user if available")
|
|
49
|
+
reconnect_attempts: int = Field(..., description="Number of reconnection attempts")
|
|
50
|
+
agent_task_name: str = Field(..., description="Name of the agent task")
|
|
51
|
+
agent_task_done: bool = Field(..., description="Whether agent task is done")
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class DiscordPlatform(Service):
|
|
55
|
+
def __init__(self, runtime: Any, context: Optional[Any] = None, **kwargs: Any) -> None:
|
|
56
|
+
"""Initialize Discord platform adapter."""
|
|
57
|
+
# Initialize Service base class (manages service_name for logging)
|
|
58
|
+
super().__init__(config=None)
|
|
59
|
+
|
|
60
|
+
self.runtime = runtime
|
|
61
|
+
self.context = context
|
|
62
|
+
self.config: DiscordAdapterConfig # type: ignore[assignment]
|
|
63
|
+
|
|
64
|
+
# Cast kwargs to typed dict for type safety
|
|
65
|
+
typed_kwargs = cast(DiscordPlatformKwargs, kwargs)
|
|
66
|
+
|
|
67
|
+
# Initialize configuration from various sources
|
|
68
|
+
self._initialize_config(runtime, typed_kwargs)
|
|
69
|
+
|
|
70
|
+
# Create Discord client and adapter
|
|
71
|
+
self._initialize_discord_client()
|
|
72
|
+
self._initialize_discord_adapter(typed_kwargs)
|
|
73
|
+
|
|
74
|
+
# Initialize state
|
|
75
|
+
self.discord_observer: Optional[DiscordObserver] = None
|
|
76
|
+
self._discord_client_task: Optional[asyncio.Task[Any]] = None
|
|
77
|
+
self._reconnect_attempts = 0
|
|
78
|
+
self._max_reconnect_attempts = 10
|
|
79
|
+
|
|
80
|
+
def _initialize_config(self, runtime: Any, kwargs: DiscordPlatformKwargs) -> None:
|
|
81
|
+
"""Initialize adapter configuration from kwargs, template, or environment."""
|
|
82
|
+
# Load config from the highest priority source available
|
|
83
|
+
if "adapter_config" in kwargs and kwargs["adapter_config"] is not None:
|
|
84
|
+
self._load_config_from_adapter_config(kwargs["adapter_config"])
|
|
85
|
+
else:
|
|
86
|
+
self._load_config_from_kwargs_or_default(kwargs)
|
|
87
|
+
self._load_config_from_template(runtime)
|
|
88
|
+
|
|
89
|
+
# Finalize configuration with validation
|
|
90
|
+
self._finalize_config()
|
|
91
|
+
|
|
92
|
+
def _load_config_from_adapter_config(
|
|
93
|
+
self, adapter_config: Union[DiscordAdapterConfig, dict[str, Any], Any]
|
|
94
|
+
) -> None:
|
|
95
|
+
"""Load configuration from adapter_config parameter."""
|
|
96
|
+
if isinstance(adapter_config, DiscordAdapterConfig):
|
|
97
|
+
self.config = adapter_config
|
|
98
|
+
elif isinstance(adapter_config, dict):
|
|
99
|
+
self.config = DiscordAdapterConfig(**adapter_config)
|
|
100
|
+
else:
|
|
101
|
+
logger.warning(f"Invalid adapter_config type: {type(adapter_config)}. Creating default config.")
|
|
102
|
+
self.config = DiscordAdapterConfig()
|
|
103
|
+
|
|
104
|
+
# ALWAYS load environment variables to fill in any missing values
|
|
105
|
+
logger.info(
|
|
106
|
+
f"DEBUG: Before load_env_vars in adapter_config branch, monitored_channel_ids = {self.config.monitored_channel_ids}"
|
|
107
|
+
)
|
|
108
|
+
self.config.load_env_vars()
|
|
109
|
+
logger.info(
|
|
110
|
+
f"Discord adapter using provided config with env vars loaded: channels={self.config.monitored_channel_ids}"
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
def _load_config_from_kwargs_or_default(self, kwargs: DiscordPlatformKwargs) -> None:
|
|
114
|
+
"""Load configuration from direct kwargs or create default."""
|
|
115
|
+
# Check if config values are passed directly as kwargs (from API load_adapter)
|
|
116
|
+
if self._has_direct_config_kwargs(kwargs):
|
|
117
|
+
self.config = self._build_config_from_direct_kwargs(kwargs)
|
|
118
|
+
logger.info(
|
|
119
|
+
f"Discord adapter created config from direct kwargs: bot_token={'***' if self.config.bot_token else 'None'}, channels={self.config.monitored_channel_ids}"
|
|
120
|
+
)
|
|
121
|
+
else:
|
|
122
|
+
# Create default config with fallback bot token
|
|
123
|
+
self.config = DiscordAdapterConfig()
|
|
124
|
+
if "discord_bot_token" in kwargs:
|
|
125
|
+
self.config.bot_token = kwargs["discord_bot_token"]
|
|
126
|
+
|
|
127
|
+
def _has_direct_config_kwargs(self, kwargs: DiscordPlatformKwargs) -> bool:
|
|
128
|
+
"""Check if kwargs contains direct configuration parameters."""
|
|
129
|
+
return "bot_token" in kwargs or "channel_id" in kwargs or "server_id" in kwargs
|
|
130
|
+
|
|
131
|
+
def _build_config_from_direct_kwargs(self, kwargs: DiscordPlatformKwargs) -> DiscordAdapterConfig:
|
|
132
|
+
"""Build configuration from direct kwargs parameters."""
|
|
133
|
+
config_dict: dict[str, Any] = {}
|
|
134
|
+
|
|
135
|
+
if "bot_token" in kwargs:
|
|
136
|
+
config_dict["bot_token"] = kwargs["bot_token"]
|
|
137
|
+
|
|
138
|
+
if "channel_id" in kwargs:
|
|
139
|
+
config_dict["monitored_channel_ids"] = [kwargs["channel_id"]]
|
|
140
|
+
config_dict["home_channel_id"] = kwargs["channel_id"]
|
|
141
|
+
|
|
142
|
+
if "server_id" in kwargs:
|
|
143
|
+
config_dict["server_id"] = kwargs["server_id"]
|
|
144
|
+
|
|
145
|
+
# Add other config fields if present
|
|
146
|
+
kwargs_dict = cast(dict[str, Any], kwargs)
|
|
147
|
+
for key in ["deferral_channel_id", "admin_user_ids"]:
|
|
148
|
+
if key in kwargs_dict:
|
|
149
|
+
config_dict[key] = kwargs_dict[key]
|
|
150
|
+
|
|
151
|
+
return DiscordAdapterConfig(**config_dict)
|
|
152
|
+
|
|
153
|
+
def _load_config_from_template(self, runtime: Any) -> None:
|
|
154
|
+
"""Load configuration from runtime template if available."""
|
|
155
|
+
template = getattr(runtime, "template", None)
|
|
156
|
+
if not template or not hasattr(template, "discord_config") or not template.discord_config:
|
|
157
|
+
self.config.load_env_vars()
|
|
158
|
+
logger.info(
|
|
159
|
+
f"DEBUG: After load_env_vars in else branch, monitored_channel_ids = {self.config.monitored_channel_ids}"
|
|
160
|
+
)
|
|
161
|
+
return
|
|
162
|
+
|
|
163
|
+
try:
|
|
164
|
+
config_dict = template.discord_config.model_dump() if hasattr(template.discord_config, "model_dump") else {}
|
|
165
|
+
for key, value in config_dict.items():
|
|
166
|
+
if hasattr(self.config, key):
|
|
167
|
+
setattr(self.config, key, value)
|
|
168
|
+
logger.debug(f"DiscordPlatform: Set config {key} = {value} from template")
|
|
169
|
+
except Exception as e:
|
|
170
|
+
logger.debug(f"DiscordPlatform: Could not load config from template: {e}")
|
|
171
|
+
|
|
172
|
+
self.config.load_env_vars()
|
|
173
|
+
logger.info(
|
|
174
|
+
f"DEBUG: After load_env_vars in else branch, monitored_channel_ids = {self.config.monitored_channel_ids}"
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
def _finalize_config(self) -> None:
|
|
178
|
+
"""Validate and finalize configuration."""
|
|
179
|
+
if not self.config.bot_token:
|
|
180
|
+
logger.error("DiscordPlatform: 'bot_token' not found in config. This is required.")
|
|
181
|
+
raise ValueError("DiscordPlatform requires 'bot_token' in configuration.")
|
|
182
|
+
|
|
183
|
+
# Validate configuration
|
|
184
|
+
self.token = self.config.bot_token
|
|
185
|
+
|
|
186
|
+
def _initialize_discord_client(self) -> None:
|
|
187
|
+
"""Create and configure the Discord client."""
|
|
188
|
+
intents = self.config.get_intents()
|
|
189
|
+
self.client = CIRISDiscordClient(platform=self, intents=intents)
|
|
190
|
+
|
|
191
|
+
# Generate adapter_id - will be updated with actual guild_id when bot connects
|
|
192
|
+
# The adapter_id is used by AuthenticationService for observer persistence
|
|
193
|
+
self.adapter_id = "discord_pending"
|
|
194
|
+
|
|
195
|
+
def _initialize_discord_adapter(self, kwargs: DiscordPlatformKwargs) -> None:
|
|
196
|
+
"""Create and configure the Discord adapter and tool service."""
|
|
197
|
+
# Get runtime services
|
|
198
|
+
time_service = getattr(self.runtime, "time_service", None)
|
|
199
|
+
bus_manager = getattr(self.runtime, "bus_manager", None)
|
|
200
|
+
|
|
201
|
+
# Create tool service for Discord tools
|
|
202
|
+
self.tool_service = DiscordToolService(client=self.client, time_service=time_service)
|
|
203
|
+
|
|
204
|
+
# Create Discord adapter
|
|
205
|
+
self.discord_adapter = DiscordAdapter(
|
|
206
|
+
token=self.token,
|
|
207
|
+
bot=self.client,
|
|
208
|
+
on_message=self._handle_discord_message_event, # type: ignore[arg-type]
|
|
209
|
+
time_service=time_service,
|
|
210
|
+
bus_manager=bus_manager,
|
|
211
|
+
config=self.config,
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
# Attach adapter to client
|
|
215
|
+
if hasattr(self.discord_adapter, "attach_to_client"):
|
|
216
|
+
self.discord_adapter.attach_to_client(self.client)
|
|
217
|
+
else:
|
|
218
|
+
logger.warning("DiscordPlatform: DiscordAdapter may not have 'attach_to_client' method.")
|
|
219
|
+
|
|
220
|
+
# Configure monitored channels from kwargs
|
|
221
|
+
self._configure_monitored_channels(kwargs)
|
|
222
|
+
|
|
223
|
+
def _configure_monitored_channels(self, kwargs: DiscordPlatformKwargs) -> None:
|
|
224
|
+
"""Configure monitored channels from kwargs and validate configuration."""
|
|
225
|
+
kwargs_channel_ids = kwargs.get("discord_monitored_channel_ids", [])
|
|
226
|
+
kwargs_channel_id = kwargs.get("discord_monitored_channel_id")
|
|
227
|
+
|
|
228
|
+
if kwargs_channel_ids:
|
|
229
|
+
self.config.monitored_channel_ids.extend(kwargs_channel_ids)
|
|
230
|
+
if kwargs_channel_id and kwargs_channel_id not in self.config.monitored_channel_ids:
|
|
231
|
+
self.config.monitored_channel_ids.append(kwargs_channel_id)
|
|
232
|
+
if not self.config.home_channel_id:
|
|
233
|
+
self.config.home_channel_id = kwargs_channel_id
|
|
234
|
+
|
|
235
|
+
if not self.config.monitored_channel_ids:
|
|
236
|
+
logger.warning(
|
|
237
|
+
"DiscordPlatform: No channel configuration found. Please provide channel IDs via constructor kwargs or environment variables."
|
|
238
|
+
)
|
|
239
|
+
elif self.config.monitored_channel_ids:
|
|
240
|
+
logger.info(
|
|
241
|
+
f"DiscordPlatform: Using {len(self.config.monitored_channel_ids)} channels: {self.config.monitored_channel_ids}"
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
def get_channel_info(self) -> Dict[str, str]:
|
|
245
|
+
"""Provide guild info for authentication."""
|
|
246
|
+
# Get first guild if connected
|
|
247
|
+
try:
|
|
248
|
+
if self.client and hasattr(self.client, "guilds") and self.client.guilds:
|
|
249
|
+
guild_id = str(self.client.guilds[0].id)
|
|
250
|
+
# Update adapter_id with actual guild for observer persistence
|
|
251
|
+
self.adapter_id = f"discord_{guild_id}"
|
|
252
|
+
logger.info(f"Discord adapter updated with guild-specific adapter_id: {self.adapter_id}")
|
|
253
|
+
return {"guild_id": guild_id}
|
|
254
|
+
except (AttributeError, IndexError, TypeError) as e:
|
|
255
|
+
logger.debug(f"Could not get guild info: {e}")
|
|
256
|
+
return {"guild_id": "unknown"}
|
|
257
|
+
|
|
258
|
+
async def _handle_discord_message_event(self, msg: DiscordMessage) -> None:
|
|
259
|
+
logger.debug(f"DiscordPlatform: Received message from DiscordAdapter: {msg.message_id if msg else 'None'}")
|
|
260
|
+
if not self.discord_observer:
|
|
261
|
+
logger.warning("DiscordPlatform: DiscordObserver not available.")
|
|
262
|
+
return
|
|
263
|
+
# msg is already typed as DiscordMessage
|
|
264
|
+
await self.discord_observer.handle_incoming_message(msg)
|
|
265
|
+
|
|
266
|
+
def get_services_to_register(self) -> List[AdapterServiceRegistration]:
|
|
267
|
+
"""Register Discord services."""
|
|
268
|
+
comm_handlers = ["SpeakHandler", "ObserveHandler", "ToolHandler"]
|
|
269
|
+
wa_handlers = ["DeferHandler", "SpeakHandler"]
|
|
270
|
+
|
|
271
|
+
registrations = [
|
|
272
|
+
AdapterServiceRegistration(
|
|
273
|
+
service_type=ServiceType.COMMUNICATION,
|
|
274
|
+
provider=self.discord_adapter,
|
|
275
|
+
priority=Priority.NORMAL,
|
|
276
|
+
handlers=comm_handlers,
|
|
277
|
+
capabilities=["send_message", "fetch_messages"],
|
|
278
|
+
),
|
|
279
|
+
AdapterServiceRegistration(
|
|
280
|
+
service_type=ServiceType.WISE_AUTHORITY,
|
|
281
|
+
provider=self.discord_adapter,
|
|
282
|
+
priority=Priority.NORMAL,
|
|
283
|
+
handlers=wa_handlers,
|
|
284
|
+
capabilities=["fetch_guidance", "send_deferral"],
|
|
285
|
+
),
|
|
286
|
+
AdapterServiceRegistration(
|
|
287
|
+
service_type=ServiceType.TOOL,
|
|
288
|
+
provider=self.tool_service,
|
|
289
|
+
priority=Priority.NORMAL,
|
|
290
|
+
handlers=["ToolHandler"],
|
|
291
|
+
capabilities=[
|
|
292
|
+
"execute_tool",
|
|
293
|
+
"get_available_tools",
|
|
294
|
+
"get_tool_result",
|
|
295
|
+
"validate_parameters",
|
|
296
|
+
"get_tool_info",
|
|
297
|
+
"get_all_tool_info",
|
|
298
|
+
],
|
|
299
|
+
),
|
|
300
|
+
]
|
|
301
|
+
logger.info(f"DiscordPlatform: Registering {len(registrations)} services for adapter: {self.adapter_id}")
|
|
302
|
+
return registrations
|
|
303
|
+
|
|
304
|
+
async def start(self) -> None:
|
|
305
|
+
logger.info("DiscordPlatform: Starting internal components...")
|
|
306
|
+
|
|
307
|
+
# Create observer now that services are available
|
|
308
|
+
secrets_service = getattr(self.runtime, "secrets_service", None)
|
|
309
|
+
if not secrets_service:
|
|
310
|
+
logger.error("CRITICAL: secrets_service not available at start time!")
|
|
311
|
+
else:
|
|
312
|
+
logger.info("Found secrets_service from runtime")
|
|
313
|
+
|
|
314
|
+
# Get time_service from runtime
|
|
315
|
+
time_service = getattr(self.runtime, "time_service", None)
|
|
316
|
+
|
|
317
|
+
logger.info(
|
|
318
|
+
f"DEBUG: About to create DiscordObserver with monitored_channel_ids = {self.config.monitored_channel_ids}"
|
|
319
|
+
)
|
|
320
|
+
self.discord_observer = DiscordObserver(
|
|
321
|
+
monitored_channel_ids=self.config.monitored_channel_ids,
|
|
322
|
+
deferral_channel_id=self.config.deferral_channel_id,
|
|
323
|
+
wa_user_ids=self.config.admin_user_ids,
|
|
324
|
+
memory_service=getattr(self.runtime, "memory_service", None),
|
|
325
|
+
agent_id=getattr(self.runtime, "agent_id", None),
|
|
326
|
+
bus_manager=getattr(self.runtime, "bus_manager", None),
|
|
327
|
+
filter_service=getattr(self.runtime, "adaptive_filter_service", None),
|
|
328
|
+
secrets_service=secrets_service,
|
|
329
|
+
communication_service=self.discord_adapter,
|
|
330
|
+
time_service=time_service,
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
# Secrets tools are now registered globally by SecretsToolService
|
|
334
|
+
|
|
335
|
+
if hasattr(self.discord_observer, "start"):
|
|
336
|
+
if self.discord_observer:
|
|
337
|
+
await self.discord_observer.start()
|
|
338
|
+
if self.tool_service and hasattr(self.tool_service, "start"):
|
|
339
|
+
await self.tool_service.start()
|
|
340
|
+
if hasattr(self.discord_adapter, "start"):
|
|
341
|
+
await self.discord_adapter.start()
|
|
342
|
+
logger.info(
|
|
343
|
+
"DiscordPlatform: Internal components started. Discord client connection deferred to run_lifecycle."
|
|
344
|
+
)
|
|
345
|
+
|
|
346
|
+
async def _wait_for_discord_reconnect(self) -> None:
|
|
347
|
+
"""Wait for Discord.py to reconnect automatically."""
|
|
348
|
+
logger.info("Waiting for Discord.py to handle reconnection...")
|
|
349
|
+
|
|
350
|
+
# Discord.py handles reconnection internally when using start() with reconnect=True
|
|
351
|
+
# We just need to wait for the client to be ready again
|
|
352
|
+
max_wait = 300 # 5 minutes max
|
|
353
|
+
start_time = asyncio.get_event_loop().time()
|
|
354
|
+
|
|
355
|
+
while asyncio.get_event_loop().time() - start_time < max_wait:
|
|
356
|
+
if self.client and not self.client.is_closed() and self.client.is_ready():
|
|
357
|
+
logger.info(f"Discord client reconnected! Logged in as: {self.client.user}")
|
|
358
|
+
self._reconnect_attempts = 0 # Reset on successful reconnection
|
|
359
|
+
return
|
|
360
|
+
|
|
361
|
+
await asyncio.sleep(1.0)
|
|
362
|
+
|
|
363
|
+
raise TimeoutError("Discord client failed to reconnect within timeout")
|
|
364
|
+
|
|
365
|
+
def _build_error_context(self, current_agent_task: asyncio.Task[Any]) -> DiscordTaskErrorContext:
|
|
366
|
+
"""Build rich error context for troubleshooting Discord issues."""
|
|
367
|
+
return DiscordTaskErrorContext(
|
|
368
|
+
task_exists=self._discord_client_task is not None,
|
|
369
|
+
task_done=self._discord_client_task.done() if self._discord_client_task else None,
|
|
370
|
+
task_cancelled=self._discord_client_task.cancelled() if self._discord_client_task else None,
|
|
371
|
+
task_exception=(
|
|
372
|
+
str(self._discord_client_task.exception())
|
|
373
|
+
if self._discord_client_task and self._discord_client_task.done()
|
|
374
|
+
else None
|
|
375
|
+
),
|
|
376
|
+
client_closed=self.client.is_closed() if self.client else None,
|
|
377
|
+
client_user=str(self.client.user) if self.client and hasattr(self.client, "user") else None,
|
|
378
|
+
reconnect_attempts=self._reconnect_attempts,
|
|
379
|
+
agent_task_name=current_agent_task.get_name(),
|
|
380
|
+
agent_task_done=current_agent_task.done(),
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
async def _recreate_discord_task(self, context: DiscordTaskErrorContext) -> bool:
|
|
384
|
+
"""
|
|
385
|
+
Recreate Discord client task when it dies unexpectedly.
|
|
386
|
+
|
|
387
|
+
Returns:
|
|
388
|
+
True if recreation succeeded, False if should continue with backoff
|
|
389
|
+
"""
|
|
390
|
+
try:
|
|
391
|
+
# If client is closed, we rely on recreating the task with client.start()
|
|
392
|
+
# Full client recreation is not needed since discord.py handles reconnection internally
|
|
393
|
+
if self.client and self.client.is_closed():
|
|
394
|
+
logger.warning("Discord client is closed - will recreate task with client.start()")
|
|
395
|
+
|
|
396
|
+
self._discord_client_task = asyncio.create_task(
|
|
397
|
+
self.client.start(self.token, reconnect=True), name="DiscordClientTask"
|
|
398
|
+
)
|
|
399
|
+
logger.info(f"Discord client task recreated successfully. Context: {context.model_dump()}")
|
|
400
|
+
return True
|
|
401
|
+
|
|
402
|
+
except Exception as recreate_error:
|
|
403
|
+
logger.error(
|
|
404
|
+
f"Failed to recreate Discord client task: {recreate_error}. Context: {context.model_dump()}",
|
|
405
|
+
exc_info=True,
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
# Exponential backoff to avoid tight loop
|
|
409
|
+
backoff_time = min(5.0 * (2 ** min(self._reconnect_attempts, 6)), 60.0)
|
|
410
|
+
logger.info(f"Waiting {backoff_time:.1f}s before retry (attempt {self._reconnect_attempts + 1})")
|
|
411
|
+
await asyncio.sleep(backoff_time)
|
|
412
|
+
return False
|
|
413
|
+
|
|
414
|
+
def _check_task_health(self, current_agent_task: asyncio.Task[Any]) -> bool:
|
|
415
|
+
"""
|
|
416
|
+
Check if Discord task needs recreation.
|
|
417
|
+
|
|
418
|
+
Returns:
|
|
419
|
+
True if task is healthy, False if needs recreation
|
|
420
|
+
"""
|
|
421
|
+
if not self._discord_client_task or self._discord_client_task.done():
|
|
422
|
+
context = self._build_error_context(current_agent_task)
|
|
423
|
+
|
|
424
|
+
if not self._discord_client_task:
|
|
425
|
+
logger.warning(f"Discord client task is None - recreating. Context: {context}")
|
|
426
|
+
else:
|
|
427
|
+
logger.warning(f"Discord client task died unexpectedly - recreating. Context: {context}")
|
|
428
|
+
|
|
429
|
+
return False
|
|
430
|
+
return True
|
|
431
|
+
|
|
432
|
+
def _handle_timeout_scenario(self) -> bool:
|
|
433
|
+
"""
|
|
434
|
+
Handle timeout when no tasks complete within expected timeframe.
|
|
435
|
+
|
|
436
|
+
Returns:
|
|
437
|
+
True to continue monitoring, False to force task recreation
|
|
438
|
+
"""
|
|
439
|
+
# Check if Discord client is still responsive first
|
|
440
|
+
if self.client and not self.client.is_closed():
|
|
441
|
+
logger.debug("No tasks completed within 30s timeout - Discord client appears healthy, continuing...")
|
|
442
|
+
return True
|
|
443
|
+
else:
|
|
444
|
+
logger.warning(
|
|
445
|
+
"No tasks completed within 30s timeout - Discord client appears closed/unresponsive, will recreate task on next iteration"
|
|
446
|
+
)
|
|
447
|
+
if self._discord_client_task and not self._discord_client_task.done():
|
|
448
|
+
self._discord_client_task.cancel()
|
|
449
|
+
self._discord_client_task = None # Force recreation
|
|
450
|
+
return False
|
|
451
|
+
|
|
452
|
+
async def _handle_discord_task_failure(self, exc: Exception, current_agent_task: asyncio.Task[Any]) -> bool:
|
|
453
|
+
"""
|
|
454
|
+
Handle Discord task failure with structured error classification and circuit breaker.
|
|
455
|
+
|
|
456
|
+
Returns:
|
|
457
|
+
True to continue monitoring, False to break from monitoring loop
|
|
458
|
+
"""
|
|
459
|
+
task_name = (
|
|
460
|
+
self._discord_client_task.get_name()
|
|
461
|
+
if self._discord_client_task and hasattr(self._discord_client_task, "get_name")
|
|
462
|
+
else "DiscordClientTask"
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
# Rich error context for troubleshooting Discord SDK issues
|
|
466
|
+
error_context = {
|
|
467
|
+
"task_name": task_name,
|
|
468
|
+
"exception_type": type(exc).__name__,
|
|
469
|
+
"exception_message": str(exc),
|
|
470
|
+
"client_closed": self.client.is_closed() if self.client else None,
|
|
471
|
+
"client_user": str(self.client.user) if self.client and hasattr(self.client, "user") else None,
|
|
472
|
+
"reconnect_attempts": self._reconnect_attempts,
|
|
473
|
+
"token_suffix": self.token[-10:] if self.token else None,
|
|
474
|
+
"agent_task_name": current_agent_task.get_name(),
|
|
475
|
+
"agent_task_done": current_agent_task.done(),
|
|
476
|
+
"task_cancelled": self._discord_client_task.cancelled() if self._discord_client_task else None,
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
logger.error(f"Discord task failed with rich context: {error_context}", exc_info=exc)
|
|
480
|
+
|
|
481
|
+
# Use DiscordErrorClassifier to determine retry strategy
|
|
482
|
+
from .discord_error_classifier import DiscordErrorClassifier
|
|
483
|
+
|
|
484
|
+
classification = DiscordErrorClassifier.classify_error(exc, self._reconnect_attempts)
|
|
485
|
+
DiscordErrorClassifier.log_error_classification(classification, self._reconnect_attempts + 1)
|
|
486
|
+
|
|
487
|
+
if not classification.should_retry:
|
|
488
|
+
logger.error(f"Discord client encountered non-retryable error: {classification.description}")
|
|
489
|
+
return False
|
|
490
|
+
|
|
491
|
+
# Handle retry with circuit breaker
|
|
492
|
+
if self._reconnect_attempts >= classification.max_retries:
|
|
493
|
+
logger.error(
|
|
494
|
+
f"Exceeded maximum reconnect attempts ({classification.max_retries}). "
|
|
495
|
+
f"Context: {error_context}. Entering circuit breaker mode (longer delays)."
|
|
496
|
+
)
|
|
497
|
+
# Don't give up entirely - use circuit breaker pattern with longer delays
|
|
498
|
+
circuit_breaker_delay = min(300.0, 60.0 * (self._reconnect_attempts - classification.max_retries + 1))
|
|
499
|
+
logger.warning(f"Circuit breaker: waiting {circuit_breaker_delay:.1f}s before next attempt")
|
|
500
|
+
await asyncio.sleep(circuit_breaker_delay)
|
|
501
|
+
|
|
502
|
+
# Reset attempts periodically to allow recovery
|
|
503
|
+
if self._reconnect_attempts > classification.max_retries + 5:
|
|
504
|
+
logger.info("Resetting reconnect attempts after extended circuit breaker period")
|
|
505
|
+
self._reconnect_attempts = classification.max_retries // 2
|
|
506
|
+
|
|
507
|
+
self._reconnect_attempts += 1
|
|
508
|
+
|
|
509
|
+
# Wait with classifier-determined delay
|
|
510
|
+
logger.info(f"Waiting {classification.retry_delay:.1f} seconds before checking connection status...")
|
|
511
|
+
await asyncio.sleep(classification.retry_delay)
|
|
512
|
+
|
|
513
|
+
# Discord.py with reconnect=True will handle reconnection internally
|
|
514
|
+
# We just need to create a new task to wait for it
|
|
515
|
+
self._discord_client_task = asyncio.create_task(self._wait_for_discord_reconnect(), name="DiscordReconnectWait")
|
|
516
|
+
|
|
517
|
+
return True
|
|
518
|
+
|
|
519
|
+
async def _handle_top_level_exception(self, exc: Exception, agent_run_task: asyncio.Task[Any]) -> None:
|
|
520
|
+
"""Handle top-level exceptions in run_lifecycle with recovery attempts."""
|
|
521
|
+
logger.error(f"DiscordPlatform: Unexpected error in run_lifecycle: {exc}", exc_info=True)
|
|
522
|
+
error_type = type(exc).__name__
|
|
523
|
+
|
|
524
|
+
# Even top-level errors might be transient - try one more time
|
|
525
|
+
if self._reconnect_attempts < self._max_reconnect_attempts:
|
|
526
|
+
self._reconnect_attempts += 1
|
|
527
|
+
logger.warning(f"Attempting to recover from lifecycle error ({error_type}). Restarting lifecycle...")
|
|
528
|
+
|
|
529
|
+
# Wait before retrying
|
|
530
|
+
await asyncio.sleep(10.0)
|
|
531
|
+
|
|
532
|
+
# Recursively call run_lifecycle to retry
|
|
533
|
+
try:
|
|
534
|
+
await self.run_lifecycle(agent_run_task)
|
|
535
|
+
return # If successful, exit
|
|
536
|
+
except Exception as retry_exc:
|
|
537
|
+
logger.error(f"Failed to recover from lifecycle error: {retry_exc}")
|
|
538
|
+
|
|
539
|
+
# If we get here, we've failed to recover
|
|
540
|
+
if not agent_run_task.done():
|
|
541
|
+
agent_run_task.cancel()
|
|
542
|
+
|
|
543
|
+
async def _cleanup_discord_resources(self) -> None:
|
|
544
|
+
"""Clean up Discord client and task resources."""
|
|
545
|
+
logger.info("DiscordPlatform: Lifecycle ending. Cleaning up Discord connection.")
|
|
546
|
+
|
|
547
|
+
# Cancel Discord client task if it's still running
|
|
548
|
+
if self._discord_client_task and not self._discord_client_task.done():
|
|
549
|
+
logger.info("DiscordPlatform: Cancelling Discord client task")
|
|
550
|
+
self._discord_client_task.cancel()
|
|
551
|
+
try:
|
|
552
|
+
await self._discord_client_task
|
|
553
|
+
except asyncio.CancelledError:
|
|
554
|
+
# Only re-raise if we're being cancelled ourselves
|
|
555
|
+
current = asyncio.current_task()
|
|
556
|
+
if current and current.cancelled():
|
|
557
|
+
raise
|
|
558
|
+
# Otherwise, this is a normal stop - don't propagate the cancellation
|
|
559
|
+
except Exception as e:
|
|
560
|
+
logger.error(f"Error while cancelling Discord client task: {e}")
|
|
561
|
+
|
|
562
|
+
# Close the client if it's still open
|
|
563
|
+
if self.client and not self.client.is_closed():
|
|
564
|
+
logger.info("DiscordPlatform: Closing Discord client")
|
|
565
|
+
try:
|
|
566
|
+
await self.client.close()
|
|
567
|
+
except Exception as e:
|
|
568
|
+
logger.error(f"Error while closing Discord client: {e}")
|
|
569
|
+
|
|
570
|
+
logger.info("DiscordPlatform: Discord lifecycle complete")
|
|
571
|
+
|
|
572
|
+
def _validate_lifecycle_preconditions(self, agent_run_task: asyncio.Task[Any]) -> None:
|
|
573
|
+
"""Validate preconditions before running lifecycle."""
|
|
574
|
+
if not self.client:
|
|
575
|
+
raise RuntimeError("Discord client not initialized - check adapter configuration")
|
|
576
|
+
if not self.token:
|
|
577
|
+
raise RuntimeError("Discord token not provided - check environment variables")
|
|
578
|
+
if not agent_run_task:
|
|
579
|
+
raise ValueError("Agent task is None - caller must provide valid task")
|
|
580
|
+
if agent_run_task.done():
|
|
581
|
+
raise ValueError(f"Agent task is already done (cancelled={agent_run_task.cancelled()})")
|
|
582
|
+
if agent_run_task.get_name() == "AgentPlaceholderTask":
|
|
583
|
+
raise ValueError(
|
|
584
|
+
"Placeholder tasks are no longer supported. "
|
|
585
|
+
"Pass the real agent task directly to run_lifecycle. "
|
|
586
|
+
"This eliminates race conditions and simplifies the codebase."
|
|
587
|
+
)
|
|
588
|
+
|
|
589
|
+
async def _connect_to_discord(self) -> bool:
|
|
590
|
+
"""
|
|
591
|
+
Start Discord client and wait for ready state.
|
|
592
|
+
|
|
593
|
+
Returns:
|
|
594
|
+
True if connection successful, False otherwise
|
|
595
|
+
"""
|
|
596
|
+
logger.info(f"DiscordPlatform: Starting Discord client with token ending in ...{self.token[-10:]}")
|
|
597
|
+
self._discord_client_task = asyncio.create_task(
|
|
598
|
+
self.client.start(self.token, reconnect=True), name="DiscordClientTask"
|
|
599
|
+
)
|
|
600
|
+
logger.info("DiscordPlatform: Discord client start initiated.")
|
|
601
|
+
|
|
602
|
+
# Give the client time to initialize
|
|
603
|
+
await asyncio.sleep(3.0)
|
|
604
|
+
|
|
605
|
+
# Wait for Discord client to be ready
|
|
606
|
+
logger.info("DiscordPlatform: Waiting for Discord client to be ready...")
|
|
607
|
+
ready = await self.discord_adapter.wait_until_ready(timeout=30.0)
|
|
608
|
+
|
|
609
|
+
if not ready:
|
|
610
|
+
logger.error("DiscordPlatform: Discord client failed to become ready within timeout")
|
|
611
|
+
return False
|
|
612
|
+
|
|
613
|
+
logger.info(f"DiscordPlatform: Discord client ready! Logged in as: {self.client.user}")
|
|
614
|
+
self._reconnect_attempts = 0
|
|
615
|
+
return True
|
|
616
|
+
|
|
617
|
+
async def _handle_agent_task_completion(self) -> None:
|
|
618
|
+
"""Handle normal shutdown when agent task completes."""
|
|
619
|
+
if self._discord_client_task and not self._discord_client_task.done():
|
|
620
|
+
self._discord_client_task.cancel()
|
|
621
|
+
try:
|
|
622
|
+
await self._discord_client_task
|
|
623
|
+
except asyncio.CancelledError:
|
|
624
|
+
raise
|
|
625
|
+
|
|
626
|
+
async def _process_monitoring_iteration(self, current_agent_task: asyncio.Task[Any]) -> tuple[bool, bool]:
|
|
627
|
+
"""
|
|
628
|
+
Process one iteration of the monitoring loop.
|
|
629
|
+
|
|
630
|
+
Returns:
|
|
631
|
+
(should_continue, should_break) tuple
|
|
632
|
+
"""
|
|
633
|
+
# Check if Discord task needs recreation
|
|
634
|
+
if not self._check_task_health(current_agent_task):
|
|
635
|
+
context = self._build_error_context(current_agent_task)
|
|
636
|
+
recreation_success = await self._recreate_discord_task(context)
|
|
637
|
+
if not recreation_success:
|
|
638
|
+
return (True, False) # Continue without breaking
|
|
639
|
+
|
|
640
|
+
# Type guard: After _check_task_health and potential recreation, task should exist
|
|
641
|
+
if not self._discord_client_task:
|
|
642
|
+
logger.error("Discord task is None after health check - this should not happen")
|
|
643
|
+
return (True, False) # Continue
|
|
644
|
+
|
|
645
|
+
# Wait for either task to complete
|
|
646
|
+
done, pending = await asyncio.wait(
|
|
647
|
+
[current_agent_task, self._discord_client_task], return_when=asyncio.FIRST_COMPLETED, timeout=30.0
|
|
648
|
+
)
|
|
649
|
+
|
|
650
|
+
# Agent task completed - normal shutdown
|
|
651
|
+
if current_agent_task in done:
|
|
652
|
+
await self._handle_agent_task_completion()
|
|
653
|
+
return (False, True) # Break from loop
|
|
654
|
+
|
|
655
|
+
# Handle timeout
|
|
656
|
+
if not done:
|
|
657
|
+
self._handle_timeout_scenario()
|
|
658
|
+
return (True, False) # Continue
|
|
659
|
+
|
|
660
|
+
# Handle Discord task failure
|
|
661
|
+
if self._discord_client_task in done and self._discord_client_task.exception():
|
|
662
|
+
exc = self._discord_client_task.exception()
|
|
663
|
+
if exc and isinstance(exc, Exception):
|
|
664
|
+
should_continue = await self._handle_discord_task_failure(exc, current_agent_task)
|
|
665
|
+
return (should_continue, not should_continue)
|
|
666
|
+
return (False, True) # Break on non-exception error
|
|
667
|
+
|
|
668
|
+
return (True, False) # Continue by default
|
|
669
|
+
|
|
670
|
+
async def _run_monitoring_loop(self, current_agent_task: asyncio.Task[Any]) -> None:
|
|
671
|
+
"""Run the main monitoring loop for Discord and agent tasks."""
|
|
672
|
+
while not current_agent_task.done():
|
|
673
|
+
should_continue, should_break = await self._process_monitoring_iteration(current_agent_task)
|
|
674
|
+
|
|
675
|
+
if should_break:
|
|
676
|
+
break
|
|
677
|
+
if should_continue:
|
|
678
|
+
continue
|
|
679
|
+
|
|
680
|
+
async def _handle_login_failure(self, error: discord.LoginFailure, agent_run_task: asyncio.Task[Any]) -> None:
|
|
681
|
+
"""Handle Discord login failures."""
|
|
682
|
+
logger.error(f"DiscordPlatform: Discord login failed: {error}. Check token and intents.", exc_info=True)
|
|
683
|
+
if hasattr(self.runtime, "request_shutdown"):
|
|
684
|
+
self.runtime.request_shutdown("Discord login failure")
|
|
685
|
+
if not agent_run_task.done():
|
|
686
|
+
agent_run_task.cancel()
|
|
687
|
+
|
|
688
|
+
async def run_lifecycle(self, agent_run_task: asyncio.Task[Any]) -> None:
|
|
689
|
+
"""Run Discord lifecycle with simplified best practices."""
|
|
690
|
+
logger.info("DiscordPlatform: Running lifecycle - attempting to start Discord client.")
|
|
691
|
+
|
|
692
|
+
# Validate preconditions
|
|
693
|
+
self._validate_lifecycle_preconditions(agent_run_task)
|
|
694
|
+
|
|
695
|
+
logger.info(f"Managing lifecycle for agent task '{agent_run_task.get_name()}'")
|
|
696
|
+
|
|
697
|
+
# Store the real agent task
|
|
698
|
+
current_agent_task = agent_run_task
|
|
699
|
+
self._current_agent_task = current_agent_task
|
|
700
|
+
|
|
701
|
+
try:
|
|
702
|
+
# Connect to Discord
|
|
703
|
+
connected = await self._connect_to_discord()
|
|
704
|
+
if not connected:
|
|
705
|
+
if not current_agent_task.done():
|
|
706
|
+
current_agent_task.cancel()
|
|
707
|
+
return
|
|
708
|
+
|
|
709
|
+
# Run monitoring loop
|
|
710
|
+
await self._run_monitoring_loop(current_agent_task)
|
|
711
|
+
|
|
712
|
+
except discord.LoginFailure as e:
|
|
713
|
+
await self._handle_login_failure(e, agent_run_task)
|
|
714
|
+
except Exception as e:
|
|
715
|
+
await self._handle_top_level_exception(e, agent_run_task)
|
|
716
|
+
finally:
|
|
717
|
+
await self._cleanup_discord_resources()
|
|
718
|
+
|
|
719
|
+
async def stop(self) -> None:
|
|
720
|
+
logger.info("DiscordPlatform: Stopping...")
|
|
721
|
+
|
|
722
|
+
# Stop observer, tool service and adapter first
|
|
723
|
+
if hasattr(self.discord_observer, "stop"):
|
|
724
|
+
if self.discord_observer:
|
|
725
|
+
await self.discord_observer.stop()
|
|
726
|
+
if hasattr(self.tool_service, "stop"):
|
|
727
|
+
await self.tool_service.stop()
|
|
728
|
+
if hasattr(self.discord_adapter, "stop"):
|
|
729
|
+
await self.discord_adapter.stop()
|
|
730
|
+
|
|
731
|
+
# Close the Discord client before cancelling the task
|
|
732
|
+
if self.client and not self.client.is_closed():
|
|
733
|
+
logger.info("DiscordPlatform: Closing Discord client connection.")
|
|
734
|
+
try:
|
|
735
|
+
await self.client.close()
|
|
736
|
+
logger.info("DiscordPlatform: Discord client connection closed.")
|
|
737
|
+
except Exception as e:
|
|
738
|
+
logger.error(f"DiscordPlatform: Error while closing Discord client: {e}", exc_info=True)
|
|
739
|
+
|
|
740
|
+
# Then cancel the task
|
|
741
|
+
if self._discord_client_task and not self._discord_client_task.done():
|
|
742
|
+
logger.info("DiscordPlatform: Cancelling active Discord client task.")
|
|
743
|
+
self._discord_client_task.cancel()
|
|
744
|
+
try:
|
|
745
|
+
await self._discord_client_task
|
|
746
|
+
except asyncio.CancelledError:
|
|
747
|
+
logger.info("DiscordPlatform: Discord client task successfully cancelled.")
|
|
748
|
+
# Only re-raise if our current task is being cancelled
|
|
749
|
+
current_task = asyncio.current_task()
|
|
750
|
+
if current_task and current_task.cancelled():
|
|
751
|
+
raise
|
|
752
|
+
# Otherwise, we're in normal shutdown - don't propagate the cancellation
|
|
753
|
+
|
|
754
|
+
logger.info("DiscordPlatform: Stopped.")
|
|
755
|
+
|
|
756
|
+
async def is_healthy(self) -> bool: # NOSONAR: Protocol requires async signature
|
|
757
|
+
"""Check if the Discord adapter is healthy"""
|
|
758
|
+
try:
|
|
759
|
+
# Check if Discord client is connected and ready
|
|
760
|
+
if not self.client:
|
|
761
|
+
return False
|
|
762
|
+
|
|
763
|
+
if self.client.is_closed():
|
|
764
|
+
return False
|
|
765
|
+
|
|
766
|
+
# If client exists and is not closed, we're healthy
|
|
767
|
+
# The client.is_ready() check happens during connection
|
|
768
|
+
# and we log "Discord client ready!" when it's true
|
|
769
|
+
return True
|
|
770
|
+
except Exception as e:
|
|
771
|
+
logger.warning(f"Discord health check failed: {e}")
|
|
772
|
+
return False
|
|
773
|
+
|
|
774
|
+
async def get_active_channels(self) -> List[DiscordChannelInfo]: # NOSONAR: Protocol requires async signature
|
|
775
|
+
"""Get list of active Discord channels."""
|
|
776
|
+
logger.info("[DISCORD_PLATFORM] get_active_channels called on wrapper")
|
|
777
|
+
if hasattr(self.discord_adapter, "get_active_channels"):
|
|
778
|
+
logger.info("[DISCORD_PLATFORM] Calling discord_adapter.get_active_channels")
|
|
779
|
+
result = self.discord_adapter.get_active_channels()
|
|
780
|
+
logger.info(f"[DISCORD_PLATFORM] Got {len(result)} channels from adapter")
|
|
781
|
+
return result
|
|
782
|
+
logger.warning("[DISCORD_PLATFORM] discord_adapter doesn't have get_active_channels")
|
|
783
|
+
return []
|