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,1053 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Runtime Adapter Management
|
|
3
|
+
|
|
4
|
+
Provides dynamic adapter loading/unloading capabilities during runtime,
|
|
5
|
+
extending the existing processor control capabilities with adapter lifecycle management.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
import logging
|
|
10
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
|
|
11
|
+
|
|
12
|
+
import aiofiles
|
|
13
|
+
|
|
14
|
+
from ciris_engine.schemas.types import JSONDict
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from ciris_engine.logic.runtime.ciris_runtime import CIRISRuntime
|
|
18
|
+
|
|
19
|
+
from dataclasses import dataclass, field
|
|
20
|
+
from datetime import datetime
|
|
21
|
+
|
|
22
|
+
from ciris_engine.logic.adapters import load_adapter
|
|
23
|
+
from ciris_engine.logic.config import ConfigBootstrap
|
|
24
|
+
from ciris_engine.logic.registries.base import Priority, SelectionStrategy
|
|
25
|
+
from ciris_engine.protocols.services.lifecycle.time import TimeServiceProtocol
|
|
26
|
+
from ciris_engine.schemas.adapters.registration import AdapterServiceRegistration
|
|
27
|
+
from ciris_engine.schemas.adapters.runtime_context import AdapterStartupContext
|
|
28
|
+
from ciris_engine.schemas.infrastructure.base import ServiceRegistration
|
|
29
|
+
from ciris_engine.schemas.runtime.adapter_management import (
|
|
30
|
+
AdapterConfig,
|
|
31
|
+
AdapterInfo,
|
|
32
|
+
AdapterMetrics,
|
|
33
|
+
AdapterOperationResult,
|
|
34
|
+
CommunicationAdapterInfo,
|
|
35
|
+
CommunicationAdapterStatus,
|
|
36
|
+
RuntimeAdapterStatus,
|
|
37
|
+
)
|
|
38
|
+
from ciris_engine.schemas.runtime.enums import ServiceType
|
|
39
|
+
|
|
40
|
+
logger = logging.getLogger(__name__)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@dataclass
|
|
44
|
+
class AdapterInstance:
|
|
45
|
+
"""Information about a loaded adapter instance"""
|
|
46
|
+
|
|
47
|
+
adapter_id: str
|
|
48
|
+
adapter_type: str
|
|
49
|
+
adapter: Any # Actually Service but also needs BaseAdapterProtocol methods
|
|
50
|
+
config_params: AdapterConfig # Adapter-specific settings
|
|
51
|
+
loaded_at: datetime
|
|
52
|
+
is_running: bool = False
|
|
53
|
+
services_registered: List[str] = field(default_factory=list)
|
|
54
|
+
lifecycle_task: Optional[asyncio.Task[Any]] = field(default=None, init=False)
|
|
55
|
+
lifecycle_runner: Optional[asyncio.Task[Any]] = field(default=None, init=False)
|
|
56
|
+
|
|
57
|
+
def __post_init__(self) -> None:
|
|
58
|
+
# services_registered is now properly initialized with default_factory
|
|
59
|
+
pass
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class AdapterManagerInterface:
|
|
63
|
+
"""Interface for runtime adapter management operations"""
|
|
64
|
+
|
|
65
|
+
async def load_adapter(
|
|
66
|
+
self, adapter_type: str, adapter_id: str, config_params: Optional[AdapterConfig] = None
|
|
67
|
+
) -> AdapterOperationResult:
|
|
68
|
+
"""Load and start a new adapter instance"""
|
|
69
|
+
raise NotImplementedError("This is an interface method")
|
|
70
|
+
|
|
71
|
+
async def unload_adapter(self, adapter_id: str) -> AdapterOperationResult:
|
|
72
|
+
"""Stop and unload an adapter instance"""
|
|
73
|
+
raise NotImplementedError("This is an interface method")
|
|
74
|
+
|
|
75
|
+
async def reload_adapter(
|
|
76
|
+
self, adapter_id: str, config_params: Optional[AdapterConfig] = None
|
|
77
|
+
) -> AdapterOperationResult:
|
|
78
|
+
"""Reload an adapter with new configuration"""
|
|
79
|
+
raise NotImplementedError("This is an interface method")
|
|
80
|
+
|
|
81
|
+
async def list_adapters(self) -> List[RuntimeAdapterStatus]:
|
|
82
|
+
"""List all loaded adapter instances"""
|
|
83
|
+
raise NotImplementedError("This is an interface method")
|
|
84
|
+
|
|
85
|
+
async def get_adapter_status(self, adapter_id: str) -> Optional[RuntimeAdapterStatus]:
|
|
86
|
+
"""Get detailed status of a specific adapter"""
|
|
87
|
+
raise NotImplementedError("This is an interface method")
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class RuntimeAdapterManager(AdapterManagerInterface):
|
|
91
|
+
"""Manages runtime adapter lifecycle with configuration support"""
|
|
92
|
+
|
|
93
|
+
def __init__(self, runtime: "CIRISRuntime", time_service: TimeServiceProtocol) -> None:
|
|
94
|
+
self.runtime = runtime
|
|
95
|
+
self.time_service = time_service
|
|
96
|
+
self.loaded_adapters: Dict[str, AdapterInstance] = {}
|
|
97
|
+
self._adapter_counter = 0
|
|
98
|
+
self._config_listener_registered = False
|
|
99
|
+
|
|
100
|
+
# Register for config changes after initialization
|
|
101
|
+
self._register_config_listener()
|
|
102
|
+
|
|
103
|
+
async def load_adapter(
|
|
104
|
+
self, adapter_type: str, adapter_id: str, config_params: Optional[AdapterConfig] = None
|
|
105
|
+
) -> AdapterOperationResult:
|
|
106
|
+
"""Load and start a new adapter instance
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
adapter_type: Adapter type (cli, discord, api, etc.)
|
|
110
|
+
adapter_id: Unique ID for the adapter
|
|
111
|
+
config_params: Optional configuration parameters
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
Dict with success status and details
|
|
115
|
+
"""
|
|
116
|
+
try:
|
|
117
|
+
if adapter_id in self.loaded_adapters:
|
|
118
|
+
logger.warning(f"Adapter with ID '{adapter_id}' already exists")
|
|
119
|
+
return AdapterOperationResult(
|
|
120
|
+
success=False,
|
|
121
|
+
adapter_id=adapter_id,
|
|
122
|
+
adapter_type=adapter_type,
|
|
123
|
+
message=f"Adapter with ID '{adapter_id}' already exists",
|
|
124
|
+
error=f"Adapter with ID '{adapter_id}' already exists",
|
|
125
|
+
details={},
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
logger.info(f"Loading adapter: type={adapter_type}, id={adapter_id}, params={config_params}")
|
|
129
|
+
|
|
130
|
+
adapter_class = load_adapter(adapter_type)
|
|
131
|
+
|
|
132
|
+
# Create AdapterStartupContext for the adapter
|
|
133
|
+
from ciris_engine.schemas.config.essential import EssentialConfig
|
|
134
|
+
|
|
135
|
+
# Get essential_config - it must exist
|
|
136
|
+
essential_config = getattr(self.runtime, "essential_config", None)
|
|
137
|
+
if not essential_config:
|
|
138
|
+
# Create minimal essential config if not present (all fields have defaults)
|
|
139
|
+
essential_config = EssentialConfig()
|
|
140
|
+
|
|
141
|
+
startup_context = AdapterStartupContext(
|
|
142
|
+
essential_config=essential_config,
|
|
143
|
+
modules_to_load=getattr(self.runtime, "modules_to_load", []),
|
|
144
|
+
startup_channel_id=getattr(self.runtime, "startup_channel_id", ""),
|
|
145
|
+
debug=getattr(self.runtime, "debug", False),
|
|
146
|
+
bus_manager=getattr(self.runtime, "bus_manager", None),
|
|
147
|
+
time_service=self.time_service,
|
|
148
|
+
service_registry=getattr(self.runtime, "service_registry", None),
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
# Build adapter kwargs from config
|
|
152
|
+
# For complex adapters (MCP), use adapter_config for nested structures
|
|
153
|
+
# For simple adapters, use settings for flat primitives
|
|
154
|
+
adapter_kwargs: Dict[str, Any] = {}
|
|
155
|
+
if config_params:
|
|
156
|
+
# First add simple settings as kwargs
|
|
157
|
+
if config_params.settings:
|
|
158
|
+
adapter_kwargs.update(config_params.settings)
|
|
159
|
+
# For adapters that need nested configs (MCP), pass adapter_config
|
|
160
|
+
if config_params.adapter_config:
|
|
161
|
+
adapter_kwargs["adapter_config"] = config_params.adapter_config
|
|
162
|
+
|
|
163
|
+
# All adapters must support context - no fallback
|
|
164
|
+
# Type ignore: adapter_class is dynamically loaded, mypy can't verify constructor signature
|
|
165
|
+
adapter = adapter_class(self.runtime, context=startup_context, **adapter_kwargs) # type: ignore[call-arg]
|
|
166
|
+
|
|
167
|
+
instance = AdapterInstance(
|
|
168
|
+
adapter_id=adapter_id,
|
|
169
|
+
adapter_type=adapter_type,
|
|
170
|
+
adapter=adapter,
|
|
171
|
+
config_params=config_params or AdapterConfig(adapter_type=adapter_type, enabled=True),
|
|
172
|
+
loaded_at=self.time_service.now(),
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
await adapter.start()
|
|
176
|
+
|
|
177
|
+
# For Discord adapters, we need to run the lifecycle to establish connection
|
|
178
|
+
if adapter_type == "discord" and hasattr(adapter, "run_lifecycle"):
|
|
179
|
+
logger.info(f"Starting lifecycle for Discord adapter {adapter_id}")
|
|
180
|
+
# Create a task that the Discord adapter will wait on
|
|
181
|
+
# This mimics the behavior when running from main.py
|
|
182
|
+
agent_task = asyncio.create_task(asyncio.Event().wait())
|
|
183
|
+
instance.lifecycle_task = agent_task
|
|
184
|
+
|
|
185
|
+
# Store the lifecycle runner task
|
|
186
|
+
instance.lifecycle_runner = asyncio.create_task(
|
|
187
|
+
adapter.run_lifecycle(agent_task), name=f"discord_lifecycle_{adapter_id}"
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
# Don't wait here - let it run in the background
|
|
191
|
+
logger.info(f"Discord adapter {adapter_id} lifecycle started in background")
|
|
192
|
+
|
|
193
|
+
instance.is_running = True
|
|
194
|
+
|
|
195
|
+
self._register_adapter_services(instance)
|
|
196
|
+
|
|
197
|
+
# Save adapter config to graph
|
|
198
|
+
await self._save_adapter_config_to_graph(
|
|
199
|
+
adapter_id, adapter_type, config_params or AdapterConfig(adapter_type=adapter_type, enabled=True)
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
# Don't add dynamically loaded adapters to runtime.adapters
|
|
203
|
+
# to avoid duplicate bootstrap entries in control_service
|
|
204
|
+
# self.runtime.adapters.append(adapter)
|
|
205
|
+
self.loaded_adapters[adapter_id] = instance
|
|
206
|
+
|
|
207
|
+
logger.info(f"Successfully loaded and started adapter {adapter_id} (adapter_manager id: {id(self)})")
|
|
208
|
+
return AdapterOperationResult(
|
|
209
|
+
success=True,
|
|
210
|
+
adapter_id=adapter_id,
|
|
211
|
+
adapter_type=adapter_type,
|
|
212
|
+
message=f"Successfully loaded adapter with {len(instance.services_registered)} services",
|
|
213
|
+
error=None,
|
|
214
|
+
details={"loaded_at": instance.loaded_at.isoformat(), "services": len(instance.services_registered)},
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
except Exception as e:
|
|
218
|
+
logger.error(f"Failed to load adapter {adapter_type} with ID {adapter_id}: {e}", exc_info=True)
|
|
219
|
+
return AdapterOperationResult(
|
|
220
|
+
success=False,
|
|
221
|
+
adapter_id=adapter_id,
|
|
222
|
+
adapter_type=adapter_type,
|
|
223
|
+
message=f"Failed to load adapter: {str(e)}",
|
|
224
|
+
error=str(e),
|
|
225
|
+
details={},
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
def _create_adapter_operation_result(
|
|
229
|
+
self,
|
|
230
|
+
success: bool,
|
|
231
|
+
adapter_id: str,
|
|
232
|
+
adapter_type: str,
|
|
233
|
+
message: str,
|
|
234
|
+
error: Optional[str] = None,
|
|
235
|
+
details: Optional[JSONDict] = None,
|
|
236
|
+
) -> AdapterOperationResult:
|
|
237
|
+
"""Factory method for consistent AdapterOperationResult creation with strict typing."""
|
|
238
|
+
return AdapterOperationResult(
|
|
239
|
+
success=success,
|
|
240
|
+
adapter_id=adapter_id,
|
|
241
|
+
adapter_type=adapter_type,
|
|
242
|
+
message=message,
|
|
243
|
+
error=error,
|
|
244
|
+
details=details or {},
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
def _validate_adapter_unload_eligibility(self, adapter_id: str) -> Optional[AdapterOperationResult]:
|
|
248
|
+
"""Check if adapter can be safely unloaded - fail fast if not eligible.
|
|
249
|
+
|
|
250
|
+
Returns None if eligible, AdapterOperationResult with error if not eligible.
|
|
251
|
+
"""
|
|
252
|
+
if adapter_id not in self.loaded_adapters:
|
|
253
|
+
logger.warning(
|
|
254
|
+
f"Adapter unload failed: '{adapter_id}' not found. "
|
|
255
|
+
f"Loaded adapters: {list(self.loaded_adapters.keys())}. "
|
|
256
|
+
f"adapter_manager id: {id(self)}"
|
|
257
|
+
)
|
|
258
|
+
return self._create_adapter_operation_result(
|
|
259
|
+
success=False,
|
|
260
|
+
adapter_id=adapter_id,
|
|
261
|
+
adapter_type="unknown",
|
|
262
|
+
message=f"Adapter with ID '{adapter_id}' not found",
|
|
263
|
+
error=f"Adapter with ID '{adapter_id}' not found",
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
instance = self.loaded_adapters[adapter_id]
|
|
267
|
+
communication_adapter_types = {"discord", "api", "cli"}
|
|
268
|
+
|
|
269
|
+
if instance.adapter_type not in communication_adapter_types:
|
|
270
|
+
return None # Non-communication adapters are always eligible
|
|
271
|
+
|
|
272
|
+
# Count remaining communication adapters from dynamically loaded adapters
|
|
273
|
+
remaining_comm_adapters = sum(
|
|
274
|
+
1
|
|
275
|
+
for aid, inst in self.loaded_adapters.items()
|
|
276
|
+
if aid != adapter_id and inst.adapter_type in communication_adapter_types
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
# Also count bootstrap adapters from runtime.adapters (these are NOT in loaded_adapters)
|
|
280
|
+
if hasattr(self.runtime, "adapters") and self.runtime.adapters:
|
|
281
|
+
for bootstrap_adapter in self.runtime.adapters:
|
|
282
|
+
adapter_type = getattr(bootstrap_adapter, "adapter_type", None)
|
|
283
|
+
adapter_class = type(bootstrap_adapter).__name__
|
|
284
|
+
logger.warning(f"Bootstrap adapter check: class={adapter_class}, adapter_type={adapter_type}")
|
|
285
|
+
# Check both adapter_type attribute and class name patterns
|
|
286
|
+
if adapter_type in communication_adapter_types:
|
|
287
|
+
remaining_comm_adapters += 1
|
|
288
|
+
elif (
|
|
289
|
+
"api" in adapter_class.lower()
|
|
290
|
+
or "cli" in adapter_class.lower()
|
|
291
|
+
or "discord" in adapter_class.lower()
|
|
292
|
+
):
|
|
293
|
+
remaining_comm_adapters += 1
|
|
294
|
+
logger.warning(f"Counted bootstrap adapter {adapter_class} based on class name")
|
|
295
|
+
|
|
296
|
+
logger.warning(
|
|
297
|
+
f"Adapter unload eligibility check: adapter_id={adapter_id}, "
|
|
298
|
+
f"remaining_comm_adapters={remaining_comm_adapters}"
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
if remaining_comm_adapters == 0:
|
|
302
|
+
error_msg = f"Unable to unload last adapter providing COMM service: {adapter_id}"
|
|
303
|
+
logger.error(error_msg)
|
|
304
|
+
return self._create_adapter_operation_result(
|
|
305
|
+
success=False,
|
|
306
|
+
adapter_id=adapter_id,
|
|
307
|
+
adapter_type=instance.adapter_type,
|
|
308
|
+
message=error_msg,
|
|
309
|
+
error=error_msg,
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
return None # Eligible for unload
|
|
313
|
+
|
|
314
|
+
async def _cancel_adapter_lifecycle_tasks(self, adapter_id: str, instance: AdapterInstance) -> None:
|
|
315
|
+
"""Cancel all lifecycle tasks for an adapter instance - no fallbacks, strict cancellation."""
|
|
316
|
+
if hasattr(instance, "lifecycle_runner") and instance.lifecycle_runner is not None:
|
|
317
|
+
logger.debug(f"Cancelling lifecycle runner for {adapter_id}")
|
|
318
|
+
instance.lifecycle_runner.cancel()
|
|
319
|
+
try:
|
|
320
|
+
await instance.lifecycle_runner
|
|
321
|
+
except asyncio.CancelledError:
|
|
322
|
+
# Expected when we cancel the task - this is the only acceptable exception
|
|
323
|
+
pass
|
|
324
|
+
|
|
325
|
+
if hasattr(instance, "lifecycle_task") and instance.lifecycle_task is not None:
|
|
326
|
+
logger.debug(f"Cancelling lifecycle task for {adapter_id}")
|
|
327
|
+
instance.lifecycle_task.cancel()
|
|
328
|
+
try:
|
|
329
|
+
await instance.lifecycle_task
|
|
330
|
+
except asyncio.CancelledError:
|
|
331
|
+
# Expected when we cancel the task - this is the only acceptable exception
|
|
332
|
+
pass
|
|
333
|
+
|
|
334
|
+
async def _cleanup_adapter_from_runtime(self, adapter_id: str, instance: AdapterInstance) -> None:
|
|
335
|
+
"""Remove adapter from runtime.adapters list and clean up references - fail fast on issues."""
|
|
336
|
+
# Stop adapter if running
|
|
337
|
+
if instance.is_running:
|
|
338
|
+
await instance.adapter.stop()
|
|
339
|
+
instance.is_running = False
|
|
340
|
+
|
|
341
|
+
# Unregister services
|
|
342
|
+
self._unregister_adapter_services(instance)
|
|
343
|
+
|
|
344
|
+
# Remove from runtime adapters list (if present)
|
|
345
|
+
if hasattr(self.runtime, "adapters"):
|
|
346
|
+
for i, adapter in enumerate(self.runtime.adapters):
|
|
347
|
+
if adapter is instance.adapter:
|
|
348
|
+
self.runtime.adapters.pop(i)
|
|
349
|
+
break
|
|
350
|
+
|
|
351
|
+
# Remove adapter config from graph
|
|
352
|
+
await self._remove_adapter_config_from_graph(adapter_id)
|
|
353
|
+
|
|
354
|
+
# Remove from loaded adapters
|
|
355
|
+
del self.loaded_adapters[adapter_id]
|
|
356
|
+
|
|
357
|
+
async def unload_adapter(self, adapter_id: str) -> AdapterOperationResult:
|
|
358
|
+
"""Stop and unload an adapter instance using helper functions for reduced complexity.
|
|
359
|
+
|
|
360
|
+
Args:
|
|
361
|
+
adapter_id: Unique identifier of the adapter to unload
|
|
362
|
+
|
|
363
|
+
Returns:
|
|
364
|
+
AdapterOperationResult with success status and details
|
|
365
|
+
"""
|
|
366
|
+
logger.warning(
|
|
367
|
+
f"RuntimeAdapterManager.unload_adapter called: adapter_id={adapter_id}, "
|
|
368
|
+
f"loaded_adapters={list(self.loaded_adapters.keys())}, "
|
|
369
|
+
f"adapter_manager_id={id(self)}"
|
|
370
|
+
)
|
|
371
|
+
try:
|
|
372
|
+
# Validate adapter eligibility - fail fast if not eligible
|
|
373
|
+
eligibility_error = self._validate_adapter_unload_eligibility(adapter_id)
|
|
374
|
+
if eligibility_error is not None:
|
|
375
|
+
return eligibility_error
|
|
376
|
+
|
|
377
|
+
# Get instance (guaranteed to exist after validation)
|
|
378
|
+
instance = self.loaded_adapters[adapter_id]
|
|
379
|
+
logger.info(f"Unloading adapter {adapter_id}")
|
|
380
|
+
|
|
381
|
+
# Cancel lifecycle tasks
|
|
382
|
+
await self._cancel_adapter_lifecycle_tasks(adapter_id, instance)
|
|
383
|
+
|
|
384
|
+
# Clean up adapter from runtime
|
|
385
|
+
await self._cleanup_adapter_from_runtime(adapter_id, instance)
|
|
386
|
+
|
|
387
|
+
logger.info(f"Successfully unloaded adapter {adapter_id}")
|
|
388
|
+
return self._create_adapter_operation_result(
|
|
389
|
+
success=True,
|
|
390
|
+
adapter_id=adapter_id,
|
|
391
|
+
adapter_type=instance.adapter_type,
|
|
392
|
+
message=f"Successfully unloaded adapter with {len(instance.services_registered)} services unregistered",
|
|
393
|
+
details={"services_unregistered": len(instance.services_registered), "was_running": True},
|
|
394
|
+
)
|
|
395
|
+
|
|
396
|
+
except asyncio.CancelledError:
|
|
397
|
+
# Re-raise CancelledError to properly propagate cancellation - no logging needed
|
|
398
|
+
logger.debug(f"Adapter unload for {adapter_id} was cancelled")
|
|
399
|
+
raise
|
|
400
|
+
except Exception as e:
|
|
401
|
+
logger.error(f"Failed to unload adapter {adapter_id}: {e}", exc_info=True)
|
|
402
|
+
return self._create_adapter_operation_result(
|
|
403
|
+
success=False,
|
|
404
|
+
adapter_id=adapter_id,
|
|
405
|
+
adapter_type="unknown",
|
|
406
|
+
message=f"Failed to unload adapter: {str(e)}",
|
|
407
|
+
error=str(e),
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
async def reload_adapter(
|
|
411
|
+
self, adapter_id: str, config_params: Optional[AdapterConfig] = None
|
|
412
|
+
) -> AdapterOperationResult:
|
|
413
|
+
"""Reload an adapter with new configuration
|
|
414
|
+
|
|
415
|
+
Args:
|
|
416
|
+
adapter_id: Unique identifier of the adapter to reload
|
|
417
|
+
config_params: New configuration parameters
|
|
418
|
+
|
|
419
|
+
Returns:
|
|
420
|
+
Dict with success status and details
|
|
421
|
+
"""
|
|
422
|
+
try:
|
|
423
|
+
if adapter_id not in self.loaded_adapters:
|
|
424
|
+
return AdapterOperationResult(
|
|
425
|
+
success=False,
|
|
426
|
+
adapter_id=adapter_id,
|
|
427
|
+
adapter_type="unknown",
|
|
428
|
+
message=f"Adapter with ID '{adapter_id}' not found",
|
|
429
|
+
error=f"Adapter with ID '{adapter_id}' not found",
|
|
430
|
+
details={},
|
|
431
|
+
)
|
|
432
|
+
|
|
433
|
+
instance = self.loaded_adapters[adapter_id]
|
|
434
|
+
adapter_type = instance.adapter_type
|
|
435
|
+
|
|
436
|
+
logger.info(f"Reloading adapter {adapter_id} with new config")
|
|
437
|
+
|
|
438
|
+
unload_result = await self.unload_adapter(adapter_id)
|
|
439
|
+
if not unload_result.success:
|
|
440
|
+
return unload_result
|
|
441
|
+
|
|
442
|
+
load_result = await self.load_adapter(adapter_type, adapter_id, config_params)
|
|
443
|
+
|
|
444
|
+
if load_result.success:
|
|
445
|
+
logger.info(f"Successfully reloaded adapter {adapter_id}")
|
|
446
|
+
|
|
447
|
+
return load_result
|
|
448
|
+
|
|
449
|
+
except Exception as e:
|
|
450
|
+
logger.error(f"Failed to reload adapter {adapter_id}: {e}", exc_info=True)
|
|
451
|
+
return AdapterOperationResult(
|
|
452
|
+
success=False,
|
|
453
|
+
adapter_id=adapter_id,
|
|
454
|
+
adapter_type="unknown",
|
|
455
|
+
message=f"Failed to reload adapter: {str(e)}",
|
|
456
|
+
error=str(e),
|
|
457
|
+
details={},
|
|
458
|
+
)
|
|
459
|
+
|
|
460
|
+
async def list_adapters(self) -> List[RuntimeAdapterStatus]:
|
|
461
|
+
"""List all loaded adapter instances
|
|
462
|
+
|
|
463
|
+
Returns:
|
|
464
|
+
List of adapter information dictionaries
|
|
465
|
+
"""
|
|
466
|
+
try:
|
|
467
|
+
adapters = []
|
|
468
|
+
for adapter_id, instance in self.loaded_adapters.items():
|
|
469
|
+
try:
|
|
470
|
+
if hasattr(instance.adapter, "is_healthy"):
|
|
471
|
+
is_healthy = await instance.adapter.is_healthy()
|
|
472
|
+
health_status = "healthy" if is_healthy else "error"
|
|
473
|
+
elif instance.is_running:
|
|
474
|
+
health_status = "active"
|
|
475
|
+
else:
|
|
476
|
+
health_status = "stopped"
|
|
477
|
+
except Exception:
|
|
478
|
+
health_status = "error"
|
|
479
|
+
|
|
480
|
+
metrics: Optional[AdapterMetrics] = None
|
|
481
|
+
if health_status == "healthy":
|
|
482
|
+
uptime_seconds = (self.time_service.now() - instance.loaded_at).total_seconds()
|
|
483
|
+
metrics = AdapterMetrics(
|
|
484
|
+
uptime_seconds=uptime_seconds,
|
|
485
|
+
messages_processed=0, # Would need to track this
|
|
486
|
+
errors_count=0, # Would need to track this
|
|
487
|
+
)
|
|
488
|
+
|
|
489
|
+
# Get tools from adapter if it has a tool service
|
|
490
|
+
tools = None
|
|
491
|
+
try:
|
|
492
|
+
if hasattr(instance.adapter, "tool_service") and instance.adapter.tool_service:
|
|
493
|
+
tool_service = instance.adapter.tool_service
|
|
494
|
+
if hasattr(tool_service, "get_all_tool_info"):
|
|
495
|
+
tool_infos = await tool_service.get_all_tool_info()
|
|
496
|
+
tools = tool_infos # Pass ToolInfo objects directly, not just names
|
|
497
|
+
elif hasattr(tool_service, "list_tools"):
|
|
498
|
+
tool_names = await tool_service.list_tools()
|
|
499
|
+
# Convert string names to ToolInfo objects for schema compliance
|
|
500
|
+
from ciris_engine.schemas.adapters.tools import ToolInfo, ToolParameterSchema
|
|
501
|
+
|
|
502
|
+
tools = [
|
|
503
|
+
ToolInfo(
|
|
504
|
+
name=name,
|
|
505
|
+
description="",
|
|
506
|
+
parameters=ToolParameterSchema(type="object", properties={}, required=[]),
|
|
507
|
+
)
|
|
508
|
+
for name in tool_names
|
|
509
|
+
]
|
|
510
|
+
except Exception as e:
|
|
511
|
+
logger.warning(f"Failed to get tools for adapter {adapter_id}: {e}")
|
|
512
|
+
|
|
513
|
+
adapters.append(
|
|
514
|
+
RuntimeAdapterStatus(
|
|
515
|
+
adapter_id=adapter_id,
|
|
516
|
+
adapter_type=instance.adapter_type,
|
|
517
|
+
is_running=instance.is_running,
|
|
518
|
+
loaded_at=instance.loaded_at,
|
|
519
|
+
services_registered=instance.services_registered,
|
|
520
|
+
config_params=self._sanitize_config_params(instance.adapter_type, instance.config_params),
|
|
521
|
+
metrics=metrics,
|
|
522
|
+
last_activity=None,
|
|
523
|
+
tools=tools,
|
|
524
|
+
)
|
|
525
|
+
)
|
|
526
|
+
|
|
527
|
+
return adapters
|
|
528
|
+
|
|
529
|
+
except Exception as e:
|
|
530
|
+
logger.error(f"Failed to list adapters: {e}", exc_info=True)
|
|
531
|
+
return []
|
|
532
|
+
|
|
533
|
+
async def _determine_adapter_health_status(self, instance: AdapterInstance) -> tuple[str, JSONDict]:
|
|
534
|
+
"""Determine adapter health status and details - fail fast on issues."""
|
|
535
|
+
health_details: JSONDict = {}
|
|
536
|
+
|
|
537
|
+
try:
|
|
538
|
+
if hasattr(instance.adapter, "is_healthy"):
|
|
539
|
+
is_healthy = await instance.adapter.is_healthy()
|
|
540
|
+
health_status = "healthy" if is_healthy else "error"
|
|
541
|
+
elif instance.is_running:
|
|
542
|
+
health_status = "active"
|
|
543
|
+
else:
|
|
544
|
+
health_status = "stopped"
|
|
545
|
+
except Exception as e:
|
|
546
|
+
health_status = "error"
|
|
547
|
+
health_details["error"] = str(e)
|
|
548
|
+
|
|
549
|
+
return health_status, health_details
|
|
550
|
+
|
|
551
|
+
def _extract_adapter_service_details(self, instance: AdapterInstance) -> List[JSONDict]:
|
|
552
|
+
"""Extract service registration details from adapter - fail fast on invalid data."""
|
|
553
|
+
try:
|
|
554
|
+
if not hasattr(instance.adapter, "get_services_to_register"):
|
|
555
|
+
return [{"info": "Adapter does not provide service registration details"}]
|
|
556
|
+
|
|
557
|
+
registrations = instance.adapter.get_services_to_register()
|
|
558
|
+
service_details = []
|
|
559
|
+
|
|
560
|
+
for reg in registrations:
|
|
561
|
+
service_details.append(
|
|
562
|
+
{
|
|
563
|
+
"service_type": (
|
|
564
|
+
reg.service_type.value if hasattr(reg.service_type, "value") else str(reg.service_type)
|
|
565
|
+
),
|
|
566
|
+
"priority": reg.priority.name if hasattr(reg.priority, "name") else str(reg.priority),
|
|
567
|
+
"handlers": reg.handlers,
|
|
568
|
+
"capabilities": reg.capabilities,
|
|
569
|
+
}
|
|
570
|
+
)
|
|
571
|
+
|
|
572
|
+
return service_details
|
|
573
|
+
|
|
574
|
+
except Exception as e:
|
|
575
|
+
return [{"error": f"Failed to get service registrations: {e}"}]
|
|
576
|
+
|
|
577
|
+
async def _get_adapter_tools_info(self, adapter_id: str, instance: AdapterInstance) -> Optional[List[Any]]:
|
|
578
|
+
"""Get tool information from adapter if available - strict typing, no fallbacks."""
|
|
579
|
+
try:
|
|
580
|
+
if not (hasattr(instance.adapter, "tool_service") and instance.adapter.tool_service):
|
|
581
|
+
return None
|
|
582
|
+
|
|
583
|
+
tool_service = instance.adapter.tool_service
|
|
584
|
+
|
|
585
|
+
if hasattr(tool_service, "get_all_tool_info"):
|
|
586
|
+
tool_infos = await tool_service.get_all_tool_info()
|
|
587
|
+
# Type checking: tool_infos should be List[ToolInfo]
|
|
588
|
+
return list(tool_infos) if tool_infos else None # Pass ToolInfo objects directly
|
|
589
|
+
elif hasattr(tool_service, "list_tools"):
|
|
590
|
+
tool_names = await tool_service.list_tools()
|
|
591
|
+
# Convert string names to ToolInfo objects for schema compliance
|
|
592
|
+
from ciris_engine.schemas.adapters.tools import ToolInfo, ToolParameterSchema
|
|
593
|
+
|
|
594
|
+
return [
|
|
595
|
+
ToolInfo(
|
|
596
|
+
name=name,
|
|
597
|
+
description="",
|
|
598
|
+
parameters=ToolParameterSchema(type="object", properties={}, required=[]),
|
|
599
|
+
)
|
|
600
|
+
for name in tool_names
|
|
601
|
+
]
|
|
602
|
+
else:
|
|
603
|
+
return None
|
|
604
|
+
|
|
605
|
+
except Exception as e:
|
|
606
|
+
logger.warning(f"Failed to get tools for adapter {adapter_id}: {e}")
|
|
607
|
+
return None
|
|
608
|
+
|
|
609
|
+
def _create_adapter_metrics(self, instance: AdapterInstance, health_status: str) -> Optional[AdapterMetrics]:
|
|
610
|
+
"""Create adapter metrics based on health status - strict typing."""
|
|
611
|
+
if health_status != "healthy":
|
|
612
|
+
return None
|
|
613
|
+
|
|
614
|
+
uptime_seconds = (self.time_service.now() - instance.loaded_at).total_seconds()
|
|
615
|
+
|
|
616
|
+
return AdapterMetrics(
|
|
617
|
+
uptime_seconds=uptime_seconds,
|
|
618
|
+
messages_processed=0, # Would need to track this in real implementation
|
|
619
|
+
errors_count=0, # Would need to track this in real implementation
|
|
620
|
+
last_error=None,
|
|
621
|
+
)
|
|
622
|
+
|
|
623
|
+
async def get_adapter_status(self, adapter_id: str) -> Optional[RuntimeAdapterStatus]:
|
|
624
|
+
"""Get detailed status of a specific adapter
|
|
625
|
+
|
|
626
|
+
Args:
|
|
627
|
+
adapter_id: Unique identifier of the adapter
|
|
628
|
+
|
|
629
|
+
Returns:
|
|
630
|
+
Dict with detailed adapter status information
|
|
631
|
+
"""
|
|
632
|
+
if adapter_id not in self.loaded_adapters:
|
|
633
|
+
return None
|
|
634
|
+
|
|
635
|
+
try:
|
|
636
|
+
instance = self.loaded_adapters[adapter_id]
|
|
637
|
+
|
|
638
|
+
# Determine health status using helper
|
|
639
|
+
health_status, _ = await self._determine_adapter_health_status(instance)
|
|
640
|
+
|
|
641
|
+
# Extract service details using helper
|
|
642
|
+
_ = self._extract_adapter_service_details(instance)
|
|
643
|
+
|
|
644
|
+
# Get tools information using helper
|
|
645
|
+
tools = await self._get_adapter_tools_info(adapter_id, instance)
|
|
646
|
+
|
|
647
|
+
# Create metrics using helper
|
|
648
|
+
metrics = self._create_adapter_metrics(instance, health_status)
|
|
649
|
+
|
|
650
|
+
return RuntimeAdapterStatus(
|
|
651
|
+
adapter_id=adapter_id,
|
|
652
|
+
adapter_type=instance.adapter_type,
|
|
653
|
+
is_running=instance.is_running,
|
|
654
|
+
loaded_at=instance.loaded_at,
|
|
655
|
+
services_registered=instance.services_registered,
|
|
656
|
+
config_params=self._sanitize_config_params(instance.adapter_type, instance.config_params),
|
|
657
|
+
metrics=metrics,
|
|
658
|
+
last_activity=None,
|
|
659
|
+
tools=tools,
|
|
660
|
+
)
|
|
661
|
+
|
|
662
|
+
except Exception as e:
|
|
663
|
+
logger.error(f"Failed to get adapter status for {adapter_id}: {e}", exc_info=True)
|
|
664
|
+
return None
|
|
665
|
+
|
|
666
|
+
def _sanitize_config_params(self, adapter_type: str, config_params: Optional[AdapterConfig]) -> AdapterConfig:
|
|
667
|
+
"""Sanitize config parameters to remove sensitive information.
|
|
668
|
+
|
|
669
|
+
Args:
|
|
670
|
+
adapter_type: Type of adapter (discord, api, etc.)
|
|
671
|
+
config_params: Raw configuration parameters
|
|
672
|
+
|
|
673
|
+
Returns:
|
|
674
|
+
Sanitized configuration with sensitive fields masked
|
|
675
|
+
"""
|
|
676
|
+
if not config_params:
|
|
677
|
+
return AdapterConfig(adapter_type=adapter_type, enabled=False)
|
|
678
|
+
|
|
679
|
+
# Define sensitive fields per adapter type
|
|
680
|
+
sensitive_fields = {
|
|
681
|
+
"discord": ["bot_token", "token", "api_key", "secret"],
|
|
682
|
+
"api": ["api_key", "secret_key", "auth_token", "password"],
|
|
683
|
+
"cli": ["password", "secret"],
|
|
684
|
+
# Add more adapter types and their sensitive fields as needed
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
# Get sensitive fields for this adapter type
|
|
688
|
+
fields_to_mask = sensitive_fields.get(adapter_type, ["token", "password", "secret", "api_key"])
|
|
689
|
+
|
|
690
|
+
# Create a sanitized copy of the settings
|
|
691
|
+
sanitized_settings: Dict[str, Optional[Union[str, int, float, bool, List[str]]]] = {}
|
|
692
|
+
for key, value in config_params.settings.items():
|
|
693
|
+
# Check if this field should be masked
|
|
694
|
+
if any(sensitive in key.lower() for sensitive in fields_to_mask):
|
|
695
|
+
# Mask the value but show it exists
|
|
696
|
+
if value:
|
|
697
|
+
sanitized_settings[key] = "***MASKED***"
|
|
698
|
+
else:
|
|
699
|
+
sanitized_settings[key] = None
|
|
700
|
+
else:
|
|
701
|
+
# Keep non-sensitive values as-is
|
|
702
|
+
sanitized_settings[key] = value
|
|
703
|
+
|
|
704
|
+
# Return a new AdapterConfig with sanitized settings
|
|
705
|
+
return AdapterConfig(
|
|
706
|
+
adapter_type=config_params.adapter_type, enabled=config_params.enabled, settings=sanitized_settings
|
|
707
|
+
)
|
|
708
|
+
|
|
709
|
+
async def load_adapter_from_template(
|
|
710
|
+
self, template_name: str, adapter_id: Optional[str] = None
|
|
711
|
+
) -> AdapterOperationResult:
|
|
712
|
+
"""Load adapter configuration from an agent template
|
|
713
|
+
|
|
714
|
+
Args:
|
|
715
|
+
template_name: Name of the agent template to load
|
|
716
|
+
adapter_id: Optional unique ID for the adapter
|
|
717
|
+
|
|
718
|
+
Returns:
|
|
719
|
+
Dict with load results
|
|
720
|
+
"""
|
|
721
|
+
try:
|
|
722
|
+
from pathlib import Path
|
|
723
|
+
|
|
724
|
+
import yaml
|
|
725
|
+
|
|
726
|
+
template_overlay_path = Path("ciris_templates") / f"{template_name}.yaml"
|
|
727
|
+
adapter_types = []
|
|
728
|
+
|
|
729
|
+
if template_overlay_path.exists():
|
|
730
|
+
try:
|
|
731
|
+
async with aiofiles.open(template_overlay_path, "r") as f:
|
|
732
|
+
content = await f.read()
|
|
733
|
+
template_data = yaml.safe_load(content) or {}
|
|
734
|
+
|
|
735
|
+
if "discord_config" in template_data or template_data.get("discord_config"):
|
|
736
|
+
adapter_types.append("discord")
|
|
737
|
+
if "api_config" in template_data or template_data.get("api_config"):
|
|
738
|
+
adapter_types.append("api")
|
|
739
|
+
if "cli_config" in template_data or template_data.get("cli_config"):
|
|
740
|
+
adapter_types.append("cli")
|
|
741
|
+
except Exception:
|
|
742
|
+
adapter_types = ["discord", "api", "cli"]
|
|
743
|
+
|
|
744
|
+
# Load template configuration
|
|
745
|
+
bootstrap = ConfigBootstrap()
|
|
746
|
+
_config = await bootstrap.load_essential_config()
|
|
747
|
+
|
|
748
|
+
# Templates are not part of essential config anymore
|
|
749
|
+
# This functionality has been removed
|
|
750
|
+
return AdapterOperationResult(
|
|
751
|
+
success=False,
|
|
752
|
+
adapter_id=adapter_id or "template",
|
|
753
|
+
adapter_type="template",
|
|
754
|
+
message="Template loading has been removed. Use direct adapter configuration instead.",
|
|
755
|
+
error="Template loading has been removed. Use direct adapter configuration instead.",
|
|
756
|
+
details={},
|
|
757
|
+
)
|
|
758
|
+
|
|
759
|
+
except Exception as e:
|
|
760
|
+
logger.error(f"Failed to load adapters from template {template_name}: {e}", exc_info=True)
|
|
761
|
+
return AdapterOperationResult(
|
|
762
|
+
success=False,
|
|
763
|
+
adapter_id=adapter_id or "template",
|
|
764
|
+
adapter_type="template", # Default to "template" since this is template loading
|
|
765
|
+
message=f"Failed to load template: {str(e)}",
|
|
766
|
+
error=str(e),
|
|
767
|
+
details={},
|
|
768
|
+
)
|
|
769
|
+
|
|
770
|
+
def _get_service_type_value(self, reg: Any) -> ServiceType:
|
|
771
|
+
"""Extract ServiceType enum from registration."""
|
|
772
|
+
if hasattr(reg, "service_type") and isinstance(reg.service_type, ServiceType):
|
|
773
|
+
return reg.service_type
|
|
774
|
+
return ServiceType(str(reg.service_type))
|
|
775
|
+
|
|
776
|
+
def _build_service_key(self, reg: Any, instance: AdapterInstance) -> str:
|
|
777
|
+
"""Build service key from registration."""
|
|
778
|
+
service_type_str = reg.service_type.value if hasattr(reg.service_type, "value") else str(reg.service_type)
|
|
779
|
+
provider_name = (
|
|
780
|
+
reg.provider.__class__.__name__ if hasattr(reg, "provider") else instance.adapter.__class__.__name__
|
|
781
|
+
)
|
|
782
|
+
return f"{service_type_str}:{provider_name}"
|
|
783
|
+
|
|
784
|
+
def _register_single_service(self, reg: Any, instance: AdapterInstance) -> None:
|
|
785
|
+
"""Register a single service from registration."""
|
|
786
|
+
if not self.runtime.service_registry:
|
|
787
|
+
return
|
|
788
|
+
|
|
789
|
+
service_key = self._build_service_key(reg, instance)
|
|
790
|
+
provider = getattr(reg, "provider", instance.adapter)
|
|
791
|
+
priority = getattr(reg, "priority", Priority.NORMAL)
|
|
792
|
+
capabilities = getattr(reg, "capabilities", [])
|
|
793
|
+
|
|
794
|
+
if not hasattr(provider, "adapter_id"):
|
|
795
|
+
provider.adapter_id = instance.adapter_id
|
|
796
|
+
|
|
797
|
+
self.runtime.service_registry.register_service(
|
|
798
|
+
service_type=self._get_service_type_value(reg),
|
|
799
|
+
provider=provider,
|
|
800
|
+
priority=priority,
|
|
801
|
+
capabilities=capabilities,
|
|
802
|
+
priority_group=getattr(reg, "priority_group", 0),
|
|
803
|
+
strategy=getattr(reg, "strategy", SelectionStrategy.FALLBACK),
|
|
804
|
+
)
|
|
805
|
+
instance.services_registered.append(f"global:{service_key}")
|
|
806
|
+
logger.info(f"Registered {service_key} from adapter {instance.adapter_id}")
|
|
807
|
+
|
|
808
|
+
def _register_adapter_services(self, instance: AdapterInstance) -> None:
|
|
809
|
+
"""Register services for an adapter instance"""
|
|
810
|
+
try:
|
|
811
|
+
if not self.runtime.service_registry:
|
|
812
|
+
logger.error("ServiceRegistry not initialized. Cannot register adapter services.")
|
|
813
|
+
return
|
|
814
|
+
|
|
815
|
+
if not hasattr(instance.adapter, "get_services_to_register"):
|
|
816
|
+
logger.warning(f"Adapter {instance.adapter_id} does not provide services to register")
|
|
817
|
+
return
|
|
818
|
+
|
|
819
|
+
registrations = instance.adapter.get_services_to_register()
|
|
820
|
+
for reg in registrations:
|
|
821
|
+
if not isinstance(reg, (ServiceRegistration, AdapterServiceRegistration)):
|
|
822
|
+
logger.error(
|
|
823
|
+
f"Adapter {instance.adapter.__class__.__name__} provided invalid ServiceRegistration: {reg}"
|
|
824
|
+
)
|
|
825
|
+
continue
|
|
826
|
+
self._register_single_service(reg, instance)
|
|
827
|
+
|
|
828
|
+
except Exception as e:
|
|
829
|
+
logger.error(f"Error registering services for adapter {instance.adapter_id}: {e}", exc_info=True)
|
|
830
|
+
|
|
831
|
+
def _unregister_adapter_services(self, instance: AdapterInstance) -> None:
|
|
832
|
+
"""Unregister services for an adapter instance"""
|
|
833
|
+
try:
|
|
834
|
+
if not self.runtime.service_registry:
|
|
835
|
+
logger.warning("ServiceRegistry not available. Cannot unregister adapter services.")
|
|
836
|
+
return
|
|
837
|
+
|
|
838
|
+
for service_key in instance.services_registered:
|
|
839
|
+
logger.info(f"Would unregister service: {service_key} from adapter {instance.adapter_id}")
|
|
840
|
+
|
|
841
|
+
instance.services_registered.clear()
|
|
842
|
+
|
|
843
|
+
except Exception as e:
|
|
844
|
+
logger.error(f"Error unregistering services for adapter {instance.adapter_id}: {e}", exc_info=True)
|
|
845
|
+
|
|
846
|
+
def get_adapter_info(self, adapter_id: str) -> Optional[AdapterInfo]:
|
|
847
|
+
"""Get detailed information about a specific adapter."""
|
|
848
|
+
if adapter_id not in self.loaded_adapters:
|
|
849
|
+
return None
|
|
850
|
+
|
|
851
|
+
try:
|
|
852
|
+
instance = self.loaded_adapters[adapter_id]
|
|
853
|
+
|
|
854
|
+
return AdapterInfo(
|
|
855
|
+
adapter_id=adapter_id,
|
|
856
|
+
adapter_type=instance.adapter_type,
|
|
857
|
+
config=instance.config_params,
|
|
858
|
+
load_time=instance.loaded_at.isoformat(),
|
|
859
|
+
is_running=instance.is_running,
|
|
860
|
+
)
|
|
861
|
+
|
|
862
|
+
except Exception as e:
|
|
863
|
+
logger.error(f"Failed to get adapter info for {adapter_id}: {e}", exc_info=True)
|
|
864
|
+
return None
|
|
865
|
+
|
|
866
|
+
def get_communication_adapter_status(self) -> CommunicationAdapterStatus:
|
|
867
|
+
"""Get status of communication adapters."""
|
|
868
|
+
communication_adapter_types = {"discord", "api", "cli"} # Known communication adapter types
|
|
869
|
+
|
|
870
|
+
communication_adapters: List[CommunicationAdapterInfo] = []
|
|
871
|
+
running_count = 0
|
|
872
|
+
|
|
873
|
+
for adapter_id, instance in self.loaded_adapters.items():
|
|
874
|
+
if instance.adapter_type in communication_adapter_types:
|
|
875
|
+
communication_adapters.append(
|
|
876
|
+
CommunicationAdapterInfo(
|
|
877
|
+
adapter_id=adapter_id, adapter_type=instance.adapter_type, is_running=instance.is_running
|
|
878
|
+
)
|
|
879
|
+
)
|
|
880
|
+
if instance.is_running:
|
|
881
|
+
running_count += 1
|
|
882
|
+
|
|
883
|
+
total_count = len(communication_adapters)
|
|
884
|
+
safe_to_unload = total_count > 1 # Safe if more than one communication adapter
|
|
885
|
+
|
|
886
|
+
warning_message = None
|
|
887
|
+
if total_count == 1:
|
|
888
|
+
warning_message = "Only one communication adapter remaining. Unloading it will disable communication."
|
|
889
|
+
elif total_count == 0:
|
|
890
|
+
warning_message = "No communication adapters are loaded."
|
|
891
|
+
|
|
892
|
+
return CommunicationAdapterStatus(
|
|
893
|
+
total_communication_adapters=total_count,
|
|
894
|
+
running_communication_adapters=running_count,
|
|
895
|
+
communication_adapters=communication_adapters,
|
|
896
|
+
safe_to_unload=safe_to_unload,
|
|
897
|
+
warning_message=warning_message,
|
|
898
|
+
)
|
|
899
|
+
|
|
900
|
+
async def _save_adapter_config_to_graph(
|
|
901
|
+
self, adapter_id: str, adapter_type: str, config_params: AdapterConfig
|
|
902
|
+
) -> None:
|
|
903
|
+
"""Save adapter configuration to graph config service."""
|
|
904
|
+
try:
|
|
905
|
+
# Get config service from runtime
|
|
906
|
+
config_service = None
|
|
907
|
+
if hasattr(self.runtime, "service_initializer") and self.runtime.service_initializer:
|
|
908
|
+
config_service = getattr(self.runtime.service_initializer, "config_service", None)
|
|
909
|
+
|
|
910
|
+
if not config_service:
|
|
911
|
+
logger.warning(f"Cannot save adapter config for {adapter_id} - GraphConfigService not available")
|
|
912
|
+
return
|
|
913
|
+
|
|
914
|
+
# Store the full config object
|
|
915
|
+
await config_service.set_config(
|
|
916
|
+
key=f"adapter.{adapter_id}.config", value=config_params, updated_by="runtime_adapter_manager"
|
|
917
|
+
)
|
|
918
|
+
|
|
919
|
+
# Store adapter type separately for easy identification
|
|
920
|
+
await config_service.set_config(
|
|
921
|
+
key=f"adapter.{adapter_id}.type", value=adapter_type, updated_by="runtime_adapter_manager"
|
|
922
|
+
)
|
|
923
|
+
|
|
924
|
+
# Also store individual config values for easy access
|
|
925
|
+
if isinstance(config_params, dict):
|
|
926
|
+
for key, value in config_params.items():
|
|
927
|
+
# Skip complex objects that might not serialize well
|
|
928
|
+
if isinstance(value, (str, int, float, bool, list)):
|
|
929
|
+
await config_service.set_config(
|
|
930
|
+
key=f"adapter.{adapter_id}.{key}", value=value, updated_by="runtime_adapter_manager"
|
|
931
|
+
)
|
|
932
|
+
|
|
933
|
+
logger.info(f"Saved adapter config for {adapter_id} to graph")
|
|
934
|
+
|
|
935
|
+
except Exception as e:
|
|
936
|
+
logger.error(f"Failed to save adapter config for {adapter_id}: {e}")
|
|
937
|
+
|
|
938
|
+
async def _remove_adapter_config_from_graph(self, adapter_id: str) -> None:
|
|
939
|
+
"""Remove adapter configuration from graph config service."""
|
|
940
|
+
try:
|
|
941
|
+
# Get config service from runtime
|
|
942
|
+
config_service = None
|
|
943
|
+
if hasattr(self.runtime, "service_initializer") and self.runtime.service_initializer:
|
|
944
|
+
config_service = getattr(self.runtime.service_initializer, "config_service", None)
|
|
945
|
+
|
|
946
|
+
if not config_service:
|
|
947
|
+
logger.warning(f"Cannot remove adapter config for {adapter_id} - GraphConfigService not available")
|
|
948
|
+
return
|
|
949
|
+
|
|
950
|
+
# List all configs with adapter prefix
|
|
951
|
+
adapter_prefix = f"adapter.{adapter_id}"
|
|
952
|
+
all_configs = await config_service.list_configs(prefix=adapter_prefix)
|
|
953
|
+
|
|
954
|
+
# Remove all config entries for this adapter by setting them to None
|
|
955
|
+
# Note: GraphConfigService doesn't have delete, so we set to None to clear
|
|
956
|
+
for config_key in all_configs.keys():
|
|
957
|
+
await config_service.set_config(config_key, None, updated_by="adapter_manager")
|
|
958
|
+
logger.debug(f"Removed config key: {config_key}")
|
|
959
|
+
|
|
960
|
+
logger.info(f"Removed adapter config for {adapter_id} from graph")
|
|
961
|
+
|
|
962
|
+
except Exception as e:
|
|
963
|
+
logger.error(f"Failed to remove adapter config for {adapter_id}: {e}")
|
|
964
|
+
|
|
965
|
+
def _register_config_listener(self) -> None:
|
|
966
|
+
"""Register to listen for adapter config changes."""
|
|
967
|
+
if self._config_listener_registered:
|
|
968
|
+
return
|
|
969
|
+
|
|
970
|
+
try:
|
|
971
|
+
# Get config service from runtime
|
|
972
|
+
if hasattr(self.runtime, "service_initializer") and self.runtime.service_initializer:
|
|
973
|
+
config_service = self.runtime.service_initializer.config_service
|
|
974
|
+
if config_service:
|
|
975
|
+
# Register for all adapter config changes
|
|
976
|
+
config_service.register_config_listener("adapter.*", self._on_adapter_config_change)
|
|
977
|
+
self._config_listener_registered = True
|
|
978
|
+
logger.info("RuntimeAdapterManager registered for adapter config changes")
|
|
979
|
+
else:
|
|
980
|
+
logger.debug("Config service not available yet for adapter manager")
|
|
981
|
+
else:
|
|
982
|
+
logger.debug("Runtime service initializer not available yet")
|
|
983
|
+
except Exception as e:
|
|
984
|
+
logger.error(f"Failed to register config listener: {e}")
|
|
985
|
+
|
|
986
|
+
async def _on_adapter_config_change(self, key: str, old_value: Any, new_value: Any) -> None:
|
|
987
|
+
"""Handle adapter configuration changes.
|
|
988
|
+
|
|
989
|
+
This is called by the config service when adapter configs change.
|
|
990
|
+
"""
|
|
991
|
+
# Extract adapter_id from key (e.g., "adapter.api_bootstrap.host" -> "api_bootstrap")
|
|
992
|
+
parts = key.split(".")
|
|
993
|
+
if len(parts) < 2 or parts[0] != "adapter":
|
|
994
|
+
return
|
|
995
|
+
|
|
996
|
+
adapter_id = parts[1]
|
|
997
|
+
|
|
998
|
+
# Check if this adapter is loaded
|
|
999
|
+
if adapter_id not in self.loaded_adapters:
|
|
1000
|
+
logger.debug(f"Config change for unloaded adapter {adapter_id}, ignoring")
|
|
1001
|
+
return
|
|
1002
|
+
|
|
1003
|
+
# Get the adapter instance
|
|
1004
|
+
instance = self.loaded_adapters[adapter_id]
|
|
1005
|
+
|
|
1006
|
+
# If it's a full config update (adapter.X.config), reload the adapter
|
|
1007
|
+
if len(parts) == 3 and parts[2] == "config":
|
|
1008
|
+
logger.info(f"Full config update detected for adapter {adapter_id}, reloading adapter")
|
|
1009
|
+
# Convert dict to AdapterConfig if valid
|
|
1010
|
+
config_param = None
|
|
1011
|
+
if isinstance(new_value, dict):
|
|
1012
|
+
config_param = AdapterConfig(
|
|
1013
|
+
adapter_type=instance.adapter_type,
|
|
1014
|
+
enabled=new_value.get("enabled", True),
|
|
1015
|
+
settings=new_value.get("settings", {}),
|
|
1016
|
+
)
|
|
1017
|
+
await self.reload_adapter(adapter_id, config_param)
|
|
1018
|
+
return
|
|
1019
|
+
|
|
1020
|
+
# For individual config values, check if the adapter supports hot reload
|
|
1021
|
+
if hasattr(instance.adapter, "update_config"):
|
|
1022
|
+
try:
|
|
1023
|
+
# Extract the specific config key (e.g., "host" from "adapter.api_bootstrap.host")
|
|
1024
|
+
config_key = parts[2] if len(parts) > 2 else None
|
|
1025
|
+
if config_key:
|
|
1026
|
+
logger.info(f"Updating {config_key} for adapter {adapter_id}")
|
|
1027
|
+
await instance.adapter.update_config({config_key: new_value})
|
|
1028
|
+
except Exception as e:
|
|
1029
|
+
logger.error(f"Failed to update config for adapter {adapter_id}: {e}")
|
|
1030
|
+
else:
|
|
1031
|
+
logger.info(f"Adapter {adapter_id} doesn't support hot config updates, consider reloading")
|
|
1032
|
+
|
|
1033
|
+
def register_config_listener(self) -> None:
|
|
1034
|
+
"""Register to listen for adapter config changes."""
|
|
1035
|
+
if self._config_listener_registered:
|
|
1036
|
+
return
|
|
1037
|
+
|
|
1038
|
+
try:
|
|
1039
|
+
# Get config service from runtime
|
|
1040
|
+
config_service = None
|
|
1041
|
+
if hasattr(self.runtime, "service_initializer") and self.runtime.service_initializer:
|
|
1042
|
+
config_service = getattr(self.runtime.service_initializer, "config_service", None)
|
|
1043
|
+
|
|
1044
|
+
if config_service:
|
|
1045
|
+
# Register to listen for all adapter config changes
|
|
1046
|
+
config_service.register_config_listener("adapter.*", self._on_adapter_config_change)
|
|
1047
|
+
self._config_listener_registered = True
|
|
1048
|
+
logger.info("Adapter manager registered for config change notifications")
|
|
1049
|
+
else:
|
|
1050
|
+
logger.warning("Cannot register for config changes - GraphConfigService not available")
|
|
1051
|
+
|
|
1052
|
+
except Exception as e:
|
|
1053
|
+
logger.error(f"Failed to register config listener: {e}")
|