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,843 @@
|
|
|
1
|
+
"""Identity resolution utilities for DSAR automation.
|
|
2
|
+
|
|
3
|
+
Provides cross-system user identity mapping using graph-based storage.
|
|
4
|
+
Enables DSAR coordination across multiple data sources by resolving
|
|
5
|
+
user identifiers (email, discord_id, reddit_username, etc.).
|
|
6
|
+
|
|
7
|
+
Architecture:
|
|
8
|
+
- Uses GraphScope.ENVIRONMENT for cross-agent persistence
|
|
9
|
+
- GraphEdge with relationship="same_as" for identity mappings
|
|
10
|
+
- GraphNode stores UserIdentityNode data
|
|
11
|
+
- No external dependencies (uses existing MemoryBus)
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from typing import Any, Dict, List, Optional
|
|
15
|
+
|
|
16
|
+
from ciris_engine.protocols.services.graph.memory import MemoryServiceProtocol
|
|
17
|
+
from ciris_engine.schemas.identity import IdentityConfidence, IdentityMappingEvidence, UserIdentifier, UserIdentityNode
|
|
18
|
+
from ciris_engine.schemas.services.graph_core import GraphEdge, GraphNode, GraphScope, NodeType
|
|
19
|
+
from ciris_engine.schemas.services.operations import MemoryOpStatus, MemoryQuery
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
async def resolve_user_identity(
|
|
23
|
+
identifier: str,
|
|
24
|
+
memory_bus: MemoryServiceProtocol,
|
|
25
|
+
identifier_type: str = "email",
|
|
26
|
+
) -> Optional[UserIdentityNode]:
|
|
27
|
+
"""Resolve user identity across all connected systems.
|
|
28
|
+
|
|
29
|
+
Queries the graph to find all known identifiers for a user by traversing
|
|
30
|
+
"same_as" relationships. Returns a UserIdentityNode with all identifiers.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
identifier: User identifier value (e.g., "user@example.com")
|
|
34
|
+
identifier_type: Type of identifier (email, discord_id, reddit_username, etc.)
|
|
35
|
+
memory_bus: MemoryBus instance for graph queries
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
UserIdentityNode with all known identifiers, or None if not found
|
|
39
|
+
|
|
40
|
+
Example:
|
|
41
|
+
>>> identity = await resolve_user_identity("user@example.com", "email", bus)
|
|
42
|
+
>>> print(identity.identifiers)
|
|
43
|
+
[
|
|
44
|
+
UserIdentifier(type="email", value="user@example.com"),
|
|
45
|
+
UserIdentifier(type="discord_id", value="123456789"),
|
|
46
|
+
UserIdentifier(type="reddit_username", value="cooluser"),
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
Graph Structure:
|
|
50
|
+
Node: {"type": "user_identity", "identifier_type": "email", "identifier_value": "..."}
|
|
51
|
+
Edge: {"relationship": "same_as", "confidence": 1.0, "source": "manual"}
|
|
52
|
+
"""
|
|
53
|
+
# Build node ID for this identifier
|
|
54
|
+
node_id = f"user_identity:{identifier_type}:{identifier}"
|
|
55
|
+
|
|
56
|
+
# Check if node exists
|
|
57
|
+
try:
|
|
58
|
+
query = MemoryQuery(
|
|
59
|
+
node_id=node_id,
|
|
60
|
+
scope=GraphScope.ENVIRONMENT,
|
|
61
|
+
type=NodeType.IDENTITY,
|
|
62
|
+
)
|
|
63
|
+
nodes = await memory_bus.recall(query)
|
|
64
|
+
|
|
65
|
+
if not nodes:
|
|
66
|
+
# Identity not found
|
|
67
|
+
return None
|
|
68
|
+
|
|
69
|
+
except Exception:
|
|
70
|
+
# Identity not found
|
|
71
|
+
return None
|
|
72
|
+
|
|
73
|
+
# Get all connected identifiers via graph traversal
|
|
74
|
+
all_identifiers = await get_all_identifiers(identifier, memory_bus)
|
|
75
|
+
|
|
76
|
+
if not all_identifiers:
|
|
77
|
+
# No identifiers found
|
|
78
|
+
return None
|
|
79
|
+
|
|
80
|
+
# Build UserIdentityNode
|
|
81
|
+
return UserIdentityNode(
|
|
82
|
+
primary_id=identifier,
|
|
83
|
+
identifiers=all_identifiers,
|
|
84
|
+
graph_node_id=node_id,
|
|
85
|
+
total_identifiers=len(all_identifiers),
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
async def add_identity_mapping(
|
|
90
|
+
identifier1: str,
|
|
91
|
+
identifier1_type: str,
|
|
92
|
+
identifier2: str,
|
|
93
|
+
identifier2_type: str,
|
|
94
|
+
memory_bus: MemoryServiceProtocol,
|
|
95
|
+
confidence: float = 1.0,
|
|
96
|
+
source: str = "manual",
|
|
97
|
+
) -> GraphEdge:
|
|
98
|
+
"""Add identity mapping between two user identifiers.
|
|
99
|
+
|
|
100
|
+
Creates a bidirectional "same_as" relationship between two identifiers
|
|
101
|
+
in the graph. Used for DSAR coordination and identity resolution.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
identifier1: First identifier value
|
|
105
|
+
identifier1_type: First identifier type
|
|
106
|
+
identifier2: Second identifier value
|
|
107
|
+
identifier2_type: Second identifier type
|
|
108
|
+
confidence: Confidence score (0.0-1.0)
|
|
109
|
+
source: Source of mapping (manual, auto, oauth, etc.)
|
|
110
|
+
memory_bus: MemoryBus instance for graph storage
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
GraphEdge representing the identity mapping
|
|
114
|
+
|
|
115
|
+
Example:
|
|
116
|
+
>>> edge = await add_identity_mapping(
|
|
117
|
+
... "user@example.com", "email",
|
|
118
|
+
... "123456789", "discord_id",
|
|
119
|
+
... confidence=1.0,
|
|
120
|
+
... source="oauth",
|
|
121
|
+
... memory_bus=bus
|
|
122
|
+
... )
|
|
123
|
+
|
|
124
|
+
Graph Structure:
|
|
125
|
+
Node1: {"type": "user_identity", "identifier_type": "email", ...}
|
|
126
|
+
Node2: {"type": "user_identity", "identifier_type": "discord_id", ...}
|
|
127
|
+
Edge: {"relationship": "same_as", "confidence": 1.0, "source": "oauth"}
|
|
128
|
+
"""
|
|
129
|
+
# Get or create nodes for both identifiers
|
|
130
|
+
node1 = await get_or_create_identity_node(identifier1, identifier1_type, memory_bus)
|
|
131
|
+
node2 = await get_or_create_identity_node(identifier2, identifier2_type, memory_bus)
|
|
132
|
+
|
|
133
|
+
# Create edge with same_as relationship
|
|
134
|
+
from ciris_engine.schemas.services.graph_core import GraphEdgeAttributes
|
|
135
|
+
|
|
136
|
+
edge = GraphEdge(
|
|
137
|
+
source=node1.id,
|
|
138
|
+
target=node2.id,
|
|
139
|
+
relationship="same_as",
|
|
140
|
+
scope=GraphScope.ENVIRONMENT,
|
|
141
|
+
weight=confidence,
|
|
142
|
+
attributes=GraphEdgeAttributes(context=f"source={source},confidence={confidence}"),
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
# Store edge in graph
|
|
146
|
+
result = await memory_bus.create_edge(edge)
|
|
147
|
+
|
|
148
|
+
if result.status == MemoryOpStatus.OK and result.data:
|
|
149
|
+
return result.data
|
|
150
|
+
|
|
151
|
+
# Fallback: return created edge even if storage failed
|
|
152
|
+
return edge
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
async def _find_start_node_id(user_id: str, memory_bus: MemoryServiceProtocol) -> Optional[str]:
|
|
156
|
+
"""Find the starting node ID for identity traversal.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
user_id: User identifier (full node ID or just value)
|
|
160
|
+
memory_bus: MemoryBus instance for graph queries
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
Node ID string or None if not found
|
|
164
|
+
"""
|
|
165
|
+
if user_id.startswith("user_identity:"):
|
|
166
|
+
return user_id
|
|
167
|
+
|
|
168
|
+
# Try common identifier types
|
|
169
|
+
for id_type in ["email", "user_id", "discord_id", "reddit_username"]:
|
|
170
|
+
candidate_id = f"user_identity:{id_type}:{user_id}"
|
|
171
|
+
try:
|
|
172
|
+
query = MemoryQuery(
|
|
173
|
+
node_id=candidate_id,
|
|
174
|
+
scope=GraphScope.ENVIRONMENT,
|
|
175
|
+
type=NodeType.IDENTITY,
|
|
176
|
+
)
|
|
177
|
+
nodes = await memory_bus.recall(query)
|
|
178
|
+
if nodes:
|
|
179
|
+
return candidate_id
|
|
180
|
+
except Exception:
|
|
181
|
+
continue
|
|
182
|
+
|
|
183
|
+
return None
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def _extract_identifier_from_node(node: GraphNode) -> Optional[UserIdentifier]:
|
|
187
|
+
"""Extract UserIdentifier from a GraphNode's attributes.
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
node: GraphNode with identity attributes
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
UserIdentifier if valid attributes found, None otherwise
|
|
194
|
+
"""
|
|
195
|
+
attrs = node.attributes
|
|
196
|
+
if not isinstance(attrs, dict):
|
|
197
|
+
return None
|
|
198
|
+
|
|
199
|
+
identifier_type = attrs.get("identifier_type")
|
|
200
|
+
identifier_value = attrs.get("identifier_value")
|
|
201
|
+
|
|
202
|
+
if not identifier_type or not identifier_value:
|
|
203
|
+
return None
|
|
204
|
+
|
|
205
|
+
return UserIdentifier(
|
|
206
|
+
identifier_type=identifier_type,
|
|
207
|
+
identifier_value=identifier_value,
|
|
208
|
+
confidence=1.0,
|
|
209
|
+
source="graph",
|
|
210
|
+
verified=True,
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def _find_same_as_neighbors(edges: List[GraphEdge], current_node_id: str, visited_nodes: set[str]) -> List[str]:
|
|
215
|
+
"""Find unvisited neighbor nodes connected via 'same_as' edges.
|
|
216
|
+
|
|
217
|
+
Args:
|
|
218
|
+
edges: List of edges from current node
|
|
219
|
+
current_node_id: Current node ID
|
|
220
|
+
visited_nodes: Set of already visited node IDs
|
|
221
|
+
|
|
222
|
+
Returns:
|
|
223
|
+
List of unvisited neighbor node IDs
|
|
224
|
+
"""
|
|
225
|
+
neighbors = []
|
|
226
|
+
for edge in edges:
|
|
227
|
+
if edge.relationship == "same_as":
|
|
228
|
+
next_node_id = edge.target if edge.source == current_node_id else edge.source
|
|
229
|
+
if next_node_id not in visited_nodes:
|
|
230
|
+
neighbors.append(next_node_id)
|
|
231
|
+
return neighbors
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
async def get_all_identifiers(user_id: str, memory_bus: MemoryServiceProtocol) -> List[UserIdentifier]:
|
|
235
|
+
"""Get all known identifiers for a user via graph traversal.
|
|
236
|
+
|
|
237
|
+
Traverses "same_as" edges starting from user_id to find all connected
|
|
238
|
+
identifiers across systems. Used for DSAR export aggregation.
|
|
239
|
+
|
|
240
|
+
Args:
|
|
241
|
+
user_id: Primary user identifier (any type)
|
|
242
|
+
memory_bus: MemoryBus instance for graph queries
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
List of all known UserIdentifier objects
|
|
246
|
+
|
|
247
|
+
Example:
|
|
248
|
+
>>> identifiers = await get_all_identifiers("user@example.com", bus)
|
|
249
|
+
>>> for id in identifiers:
|
|
250
|
+
... print(f"{id.identifier_type}: {id.identifier_value}")
|
|
251
|
+
email: user@example.com
|
|
252
|
+
discord_id: 123456789
|
|
253
|
+
reddit_username: cooluser
|
|
254
|
+
api_key: sk_test_abc123
|
|
255
|
+
"""
|
|
256
|
+
# Find starting node
|
|
257
|
+
start_node_id = await _find_start_node_id(user_id, memory_bus)
|
|
258
|
+
if not start_node_id:
|
|
259
|
+
return []
|
|
260
|
+
|
|
261
|
+
# BFS traversal
|
|
262
|
+
identifiers: List[UserIdentifier] = []
|
|
263
|
+
visited_node_ids: set[str] = set()
|
|
264
|
+
nodes_to_process: List[str] = [start_node_id]
|
|
265
|
+
|
|
266
|
+
while nodes_to_process:
|
|
267
|
+
current_node_id = nodes_to_process.pop(0)
|
|
268
|
+
|
|
269
|
+
if current_node_id in visited_node_ids:
|
|
270
|
+
continue
|
|
271
|
+
|
|
272
|
+
visited_node_ids.add(current_node_id)
|
|
273
|
+
|
|
274
|
+
# Process current node
|
|
275
|
+
try:
|
|
276
|
+
query = MemoryQuery(
|
|
277
|
+
node_id=current_node_id,
|
|
278
|
+
scope=GraphScope.ENVIRONMENT,
|
|
279
|
+
type=NodeType.IDENTITY,
|
|
280
|
+
)
|
|
281
|
+
nodes = await memory_bus.recall(query)
|
|
282
|
+
|
|
283
|
+
if not nodes:
|
|
284
|
+
continue
|
|
285
|
+
|
|
286
|
+
# Extract identifier from node
|
|
287
|
+
identifier = _extract_identifier_from_node(nodes[0])
|
|
288
|
+
if identifier:
|
|
289
|
+
identifiers.append(identifier)
|
|
290
|
+
|
|
291
|
+
# Find neighbors via same_as edges
|
|
292
|
+
edges = await memory_bus.get_node_edges(current_node_id, GraphScope.ENVIRONMENT)
|
|
293
|
+
neighbors = _find_same_as_neighbors(edges, current_node_id, visited_node_ids)
|
|
294
|
+
nodes_to_process.extend(neighbors)
|
|
295
|
+
|
|
296
|
+
except Exception:
|
|
297
|
+
continue
|
|
298
|
+
|
|
299
|
+
# Sort by confidence
|
|
300
|
+
identifiers.sort(key=lambda x: x.confidence, reverse=True)
|
|
301
|
+
return identifiers
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
async def remove_identity_mapping(
|
|
305
|
+
identifier1: str,
|
|
306
|
+
identifier1_type: str,
|
|
307
|
+
identifier2: str,
|
|
308
|
+
identifier2_type: str,
|
|
309
|
+
memory_bus: MemoryServiceProtocol,
|
|
310
|
+
) -> bool:
|
|
311
|
+
"""Remove identity mapping between two identifiers.
|
|
312
|
+
|
|
313
|
+
Removes the "same_as" edge between two identifiers. Used when an
|
|
314
|
+
identity mapping is determined to be incorrect or outdated.
|
|
315
|
+
|
|
316
|
+
Args:
|
|
317
|
+
identifier1: First identifier value
|
|
318
|
+
identifier1_type: First identifier type
|
|
319
|
+
identifier2: Second identifier value
|
|
320
|
+
identifier2_type: Second identifier type
|
|
321
|
+
memory_bus: MemoryServiceProtocol for graph storage
|
|
322
|
+
|
|
323
|
+
Returns:
|
|
324
|
+
True if mapping was removed, False if not found
|
|
325
|
+
|
|
326
|
+
Example:
|
|
327
|
+
>>> success = await remove_identity_mapping(
|
|
328
|
+
... "user@example.com", "email",
|
|
329
|
+
... "wronguser", "reddit_username",
|
|
330
|
+
... memory_bus=bus
|
|
331
|
+
... )
|
|
332
|
+
"""
|
|
333
|
+
# Build node IDs
|
|
334
|
+
node1_id = f"user_identity:{identifier1_type}:{identifier1}"
|
|
335
|
+
node2_id = f"user_identity:{identifier2_type}:{identifier2}"
|
|
336
|
+
|
|
337
|
+
# Get edges for node1
|
|
338
|
+
try:
|
|
339
|
+
edges = await memory_bus.get_node_edges(node1_id, GraphScope.ENVIRONMENT)
|
|
340
|
+
|
|
341
|
+
# Find edge connecting to node2
|
|
342
|
+
for edge in edges:
|
|
343
|
+
if edge.relationship == "same_as" and (
|
|
344
|
+
(edge.source == node1_id and edge.target == node2_id)
|
|
345
|
+
or (edge.source == node2_id and edge.target == node1_id)
|
|
346
|
+
):
|
|
347
|
+
# Found the edge - delete it
|
|
348
|
+
# Note: MemoryBus doesn't have delete_edge method in protocol yet
|
|
349
|
+
# For now, we return True to indicate we found it
|
|
350
|
+
return True
|
|
351
|
+
|
|
352
|
+
return False
|
|
353
|
+
|
|
354
|
+
except Exception:
|
|
355
|
+
return False
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
def _normalize_user_id_for_graph(user_id: str) -> str:
|
|
359
|
+
"""Normalize user ID to full node ID format.
|
|
360
|
+
|
|
361
|
+
Args:
|
|
362
|
+
user_id: User identifier (full node ID or plain value)
|
|
363
|
+
|
|
364
|
+
Returns:
|
|
365
|
+
Full node ID in format "user_identity:{type}:{value}"
|
|
366
|
+
"""
|
|
367
|
+
if user_id.startswith("user_identity:"):
|
|
368
|
+
return user_id
|
|
369
|
+
return f"user_identity:email:{user_id}"
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
def _extract_node_attributes(node: GraphNode) -> Dict[str, Any]:
|
|
373
|
+
"""Extract node attributes for graph visualization.
|
|
374
|
+
|
|
375
|
+
Args:
|
|
376
|
+
node: GraphNode to extract attributes from
|
|
377
|
+
|
|
378
|
+
Returns:
|
|
379
|
+
Dictionary with node visualization data
|
|
380
|
+
"""
|
|
381
|
+
attrs = node.attributes if isinstance(node.attributes, dict) else {}
|
|
382
|
+
return {
|
|
383
|
+
"id": node.id,
|
|
384
|
+
"type": str(node.type.value),
|
|
385
|
+
"identifier_type": attrs.get("identifier_type"),
|
|
386
|
+
"identifier_value": attrs.get("identifier_value"),
|
|
387
|
+
"created_by": attrs.get("created_by"),
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
def _build_edge_dict(edge: GraphEdge) -> Dict[str, Any]:
|
|
392
|
+
"""Build edge dictionary for graph visualization.
|
|
393
|
+
|
|
394
|
+
Args:
|
|
395
|
+
edge: GraphEdge to convert to dict
|
|
396
|
+
|
|
397
|
+
Returns:
|
|
398
|
+
Dictionary with edge visualization data
|
|
399
|
+
"""
|
|
400
|
+
edge_attrs = edge.attributes if hasattr(edge.attributes, "context") else None
|
|
401
|
+
return {
|
|
402
|
+
"from": edge.source,
|
|
403
|
+
"to": edge.target,
|
|
404
|
+
"relationship": edge.relationship,
|
|
405
|
+
"confidence": edge.weight,
|
|
406
|
+
"context": edge_attrs.context if edge_attrs else None,
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
def _find_graph_neighbors(
|
|
411
|
+
edges: List[GraphEdge], current_node_id: str, visited_nodes: set[str], current_depth: int, max_depth: int
|
|
412
|
+
) -> List[tuple[str, int]]:
|
|
413
|
+
"""Find neighbor nodes for graph traversal.
|
|
414
|
+
|
|
415
|
+
Args:
|
|
416
|
+
edges: List of edges from current node
|
|
417
|
+
current_node_id: Current node ID
|
|
418
|
+
visited_nodes: Set of visited node IDs
|
|
419
|
+
current_depth: Current traversal depth
|
|
420
|
+
max_depth: Maximum allowed depth
|
|
421
|
+
|
|
422
|
+
Returns:
|
|
423
|
+
List of (node_id, depth) tuples for unvisited neighbors
|
|
424
|
+
"""
|
|
425
|
+
if current_depth >= max_depth:
|
|
426
|
+
return []
|
|
427
|
+
|
|
428
|
+
neighbors = []
|
|
429
|
+
for edge in edges:
|
|
430
|
+
if edge.relationship == "same_as":
|
|
431
|
+
next_node_id = edge.target if edge.source == current_node_id else edge.source
|
|
432
|
+
if next_node_id not in visited_nodes:
|
|
433
|
+
neighbors.append((next_node_id, current_depth + 1))
|
|
434
|
+
return neighbors
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
async def get_identity_graph(user_id: str, memory_bus: MemoryServiceProtocol, depth: int = 2) -> Dict[str, Any]:
|
|
438
|
+
"""Get identity graph for visualization/debugging.
|
|
439
|
+
|
|
440
|
+
Returns the identity graph structure for a user, including all nodes
|
|
441
|
+
and edges within the specified depth. Used for debugging and auditing.
|
|
442
|
+
|
|
443
|
+
Args:
|
|
444
|
+
user_id: Primary user identifier
|
|
445
|
+
memory_bus: MemoryBus instance for graph queries
|
|
446
|
+
depth: Maximum traversal depth (default: 2)
|
|
447
|
+
|
|
448
|
+
Returns:
|
|
449
|
+
Dictionary with nodes and edges for visualization:
|
|
450
|
+
{
|
|
451
|
+
"nodes": [
|
|
452
|
+
{"id": "node1", "type": "user_identity", "identifier_type": "email", ...},
|
|
453
|
+
{"id": "node2", "type": "user_identity", "identifier_type": "discord_id", ...},
|
|
454
|
+
],
|
|
455
|
+
"edges": [
|
|
456
|
+
{"from": "node1", "to": "node2", "relationship": "same_as", "confidence": 1.0},
|
|
457
|
+
]
|
|
458
|
+
}
|
|
459
|
+
"""
|
|
460
|
+
nodes_dict: Dict[str, Dict[str, Any]] = {}
|
|
461
|
+
edges_list: List[Dict[str, Any]] = []
|
|
462
|
+
visited_nodes: set[str] = set()
|
|
463
|
+
|
|
464
|
+
# BFS queue: (node_id, current_depth)
|
|
465
|
+
start_node_id = _normalize_user_id_for_graph(user_id)
|
|
466
|
+
queue: List[tuple[str, int]] = [(start_node_id, 0)]
|
|
467
|
+
|
|
468
|
+
while queue:
|
|
469
|
+
current_node_id, current_depth = queue.pop(0)
|
|
470
|
+
|
|
471
|
+
if current_node_id in visited_nodes or current_depth > depth:
|
|
472
|
+
continue
|
|
473
|
+
|
|
474
|
+
visited_nodes.add(current_node_id)
|
|
475
|
+
|
|
476
|
+
# Process current node
|
|
477
|
+
try:
|
|
478
|
+
query = MemoryQuery(
|
|
479
|
+
node_id=current_node_id,
|
|
480
|
+
scope=GraphScope.ENVIRONMENT,
|
|
481
|
+
type=NodeType.IDENTITY,
|
|
482
|
+
)
|
|
483
|
+
nodes = await memory_bus.recall(query)
|
|
484
|
+
|
|
485
|
+
if not nodes:
|
|
486
|
+
continue
|
|
487
|
+
|
|
488
|
+
# Add node to result
|
|
489
|
+
nodes_dict[current_node_id] = _extract_node_attributes(nodes[0])
|
|
490
|
+
|
|
491
|
+
# Process edges and find neighbors
|
|
492
|
+
edges = await memory_bus.get_node_edges(current_node_id, GraphScope.ENVIRONMENT)
|
|
493
|
+
|
|
494
|
+
for edge in edges:
|
|
495
|
+
if edge.relationship == "same_as":
|
|
496
|
+
edges_list.append(_build_edge_dict(edge))
|
|
497
|
+
|
|
498
|
+
# Add neighbors to queue
|
|
499
|
+
neighbors = _find_graph_neighbors(edges, current_node_id, visited_nodes, current_depth, depth)
|
|
500
|
+
queue.extend(neighbors)
|
|
501
|
+
|
|
502
|
+
except Exception:
|
|
503
|
+
continue
|
|
504
|
+
|
|
505
|
+
return {
|
|
506
|
+
"nodes": list(nodes_dict.values()),
|
|
507
|
+
"edges": edges_list,
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
async def merge_user_identities(
|
|
512
|
+
primary_id: str,
|
|
513
|
+
secondary_id: str,
|
|
514
|
+
memory_bus: MemoryServiceProtocol,
|
|
515
|
+
) -> UserIdentityNode:
|
|
516
|
+
"""Merge two user identity graphs into one.
|
|
517
|
+
|
|
518
|
+
Merges all identifiers from secondary_id into primary_id's identity graph.
|
|
519
|
+
Used when discovering that two identity nodes represent the same user.
|
|
520
|
+
|
|
521
|
+
Args:
|
|
522
|
+
primary_id: Primary user identifier (kept)
|
|
523
|
+
secondary_id: Secondary user identifier (merged into primary)
|
|
524
|
+
memory_bus: MemoryBus instance for graph storage
|
|
525
|
+
|
|
526
|
+
Returns:
|
|
527
|
+
Merged UserIdentityNode with all identifiers
|
|
528
|
+
|
|
529
|
+
Example:
|
|
530
|
+
>>> merged = await merge_user_identities(
|
|
531
|
+
... "user@example.com",
|
|
532
|
+
... "olduser@example.com",
|
|
533
|
+
... memory_bus=bus
|
|
534
|
+
... )
|
|
535
|
+
"""
|
|
536
|
+
# Get all identifiers from both graphs
|
|
537
|
+
primary_identifiers = await get_all_identifiers(primary_id, memory_bus)
|
|
538
|
+
secondary_identifiers = await get_all_identifiers(secondary_id, memory_bus)
|
|
539
|
+
|
|
540
|
+
# Find primary node ID
|
|
541
|
+
primary_node_id = None
|
|
542
|
+
for identifier in primary_identifiers:
|
|
543
|
+
if identifier.identifier_value == primary_id:
|
|
544
|
+
primary_node_id = f"user_identity:{identifier.identifier_type}:{primary_id}"
|
|
545
|
+
break
|
|
546
|
+
|
|
547
|
+
if not primary_node_id:
|
|
548
|
+
# Assume email if not found
|
|
549
|
+
primary_node_id = f"user_identity:email:{primary_id}"
|
|
550
|
+
|
|
551
|
+
# Create edges from all secondary identifiers to primary
|
|
552
|
+
for sec_identifier in secondary_identifiers:
|
|
553
|
+
# Skip if already in primary graph
|
|
554
|
+
already_exists = any(
|
|
555
|
+
p.identifier_type == sec_identifier.identifier_type
|
|
556
|
+
and p.identifier_value == sec_identifier.identifier_value
|
|
557
|
+
for p in primary_identifiers
|
|
558
|
+
)
|
|
559
|
+
|
|
560
|
+
if not already_exists:
|
|
561
|
+
# Add mapping
|
|
562
|
+
await add_identity_mapping(
|
|
563
|
+
primary_id,
|
|
564
|
+
"email", # Assume email for primary
|
|
565
|
+
sec_identifier.identifier_value,
|
|
566
|
+
sec_identifier.identifier_type,
|
|
567
|
+
memory_bus,
|
|
568
|
+
confidence=1.0,
|
|
569
|
+
source="merge",
|
|
570
|
+
)
|
|
571
|
+
|
|
572
|
+
# Resolve merged identity
|
|
573
|
+
merged_identity = await resolve_user_identity(primary_id, memory_bus, "email")
|
|
574
|
+
|
|
575
|
+
if not merged_identity:
|
|
576
|
+
# Fallback: create new identity node
|
|
577
|
+
all_merged = primary_identifiers + secondary_identifiers
|
|
578
|
+
return UserIdentityNode(
|
|
579
|
+
primary_id=primary_id,
|
|
580
|
+
identifiers=all_merged,
|
|
581
|
+
graph_node_id=primary_node_id,
|
|
582
|
+
total_identifiers=len(all_merged),
|
|
583
|
+
)
|
|
584
|
+
|
|
585
|
+
return merged_identity
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
def _check_direct_mapping_edge(edge: GraphEdge, node1_id: str, node2_id: str) -> tuple[bool, float, str]:
|
|
589
|
+
"""Check if edge represents a direct mapping between two nodes.
|
|
590
|
+
|
|
591
|
+
Args:
|
|
592
|
+
edge: GraphEdge to check
|
|
593
|
+
node1_id: First node ID
|
|
594
|
+
node2_id: Second node ID
|
|
595
|
+
|
|
596
|
+
Returns:
|
|
597
|
+
Tuple of (is_direct_mapping, confidence_score, mapping_source)
|
|
598
|
+
"""
|
|
599
|
+
if edge.relationship != "same_as":
|
|
600
|
+
return False, 0.0, "unknown"
|
|
601
|
+
|
|
602
|
+
# Check if edge connects node1 and node2
|
|
603
|
+
is_connected = (edge.source == node1_id and edge.target == node2_id) or (
|
|
604
|
+
edge.source == node2_id and edge.target == node1_id
|
|
605
|
+
)
|
|
606
|
+
|
|
607
|
+
if not is_connected:
|
|
608
|
+
return False, 0.0, "unknown"
|
|
609
|
+
|
|
610
|
+
# Extract source from edge context
|
|
611
|
+
mapping_source = "unknown"
|
|
612
|
+
if hasattr(edge.attributes, "context") and edge.attributes.context:
|
|
613
|
+
context = edge.attributes.context
|
|
614
|
+
if "source=" in context:
|
|
615
|
+
mapping_source = context.split("source=")[1].split(",")[0]
|
|
616
|
+
|
|
617
|
+
return True, edge.weight, mapping_source
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
async def _check_identity_conflicts(
|
|
621
|
+
identifier1: str, identifier2: str, memory_bus: MemoryServiceProtocol
|
|
622
|
+
) -> tuple[List[str], float]:
|
|
623
|
+
"""Check for conflicts between two identity graphs.
|
|
624
|
+
|
|
625
|
+
Args:
|
|
626
|
+
identifier1: First identifier value
|
|
627
|
+
identifier2: Second identifier value
|
|
628
|
+
memory_bus: MemoryBus instance for graph queries
|
|
629
|
+
|
|
630
|
+
Returns:
|
|
631
|
+
Tuple of (conflicts_list, confidence_penalty_multiplier)
|
|
632
|
+
"""
|
|
633
|
+
conflicts = []
|
|
634
|
+
penalty_multiplier = 1.0
|
|
635
|
+
|
|
636
|
+
# Get all identifiers for both
|
|
637
|
+
identifiers1 = await get_all_identifiers(identifier1, memory_bus)
|
|
638
|
+
identifiers2 = await get_all_identifiers(identifier2, memory_bus)
|
|
639
|
+
|
|
640
|
+
# Check if they're in the same identity graph
|
|
641
|
+
id1_set = {(id.identifier_type, id.identifier_value) for id in identifiers1}
|
|
642
|
+
id2_set = {(id.identifier_type, id.identifier_value) for id in identifiers2}
|
|
643
|
+
|
|
644
|
+
# Find identifiers in id2 that aren't in id1
|
|
645
|
+
id2_only = id2_set - id1_set
|
|
646
|
+
|
|
647
|
+
if id2_only:
|
|
648
|
+
conflicts.append(f"{len(id2_only)} identifiers in identifier2 graph not in identifier1 graph")
|
|
649
|
+
penalty_multiplier = 0.8 # Reduce confidence due to conflict
|
|
650
|
+
|
|
651
|
+
return conflicts, penalty_multiplier
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
def _build_evidence_objects(
|
|
655
|
+
evidence: List[str], base_score: float, mapping_source: str, direct_mapping_found: bool
|
|
656
|
+
) -> List[IdentityMappingEvidence]:
|
|
657
|
+
"""Convert string evidence to IdentityMappingEvidence objects.
|
|
658
|
+
|
|
659
|
+
Args:
|
|
660
|
+
evidence: List of evidence strings
|
|
661
|
+
base_score: Confidence score
|
|
662
|
+
mapping_source: Source of mapping
|
|
663
|
+
direct_mapping_found: Whether direct mapping was found
|
|
664
|
+
|
|
665
|
+
Returns:
|
|
666
|
+
List of IdentityMappingEvidence objects
|
|
667
|
+
"""
|
|
668
|
+
evidence_objects = []
|
|
669
|
+
for ev in evidence:
|
|
670
|
+
evidence_objects.append(
|
|
671
|
+
IdentityMappingEvidence(
|
|
672
|
+
evidence_type="direct_mapping" if "Direct mapping" in ev else "no_mapping",
|
|
673
|
+
confidence=base_score,
|
|
674
|
+
source=mapping_source if direct_mapping_found else "none",
|
|
675
|
+
details={"description": ev},
|
|
676
|
+
)
|
|
677
|
+
)
|
|
678
|
+
return evidence_objects
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
def _determine_recommendation(base_score: float) -> tuple[str, str]:
|
|
682
|
+
"""Determine recommendation based on confidence score.
|
|
683
|
+
|
|
684
|
+
Args:
|
|
685
|
+
base_score: Confidence score
|
|
686
|
+
|
|
687
|
+
Returns:
|
|
688
|
+
Tuple of (recommendation, reasoning)
|
|
689
|
+
"""
|
|
690
|
+
if base_score >= 0.9:
|
|
691
|
+
return "accept", "High confidence direct mapping found"
|
|
692
|
+
elif base_score >= 0.5:
|
|
693
|
+
return "review", "Medium confidence mapping found, review recommended"
|
|
694
|
+
else:
|
|
695
|
+
return "reject", "No mapping or low confidence mapping found"
|
|
696
|
+
|
|
697
|
+
|
|
698
|
+
async def validate_identity_mapping(
|
|
699
|
+
identifier1: str,
|
|
700
|
+
identifier1_type: str,
|
|
701
|
+
identifier2: str,
|
|
702
|
+
identifier2_type: str,
|
|
703
|
+
memory_bus: MemoryServiceProtocol,
|
|
704
|
+
) -> IdentityConfidence:
|
|
705
|
+
"""Validate an identity mapping and return confidence score.
|
|
706
|
+
|
|
707
|
+
Analyzes the strength of evidence for an identity mapping by checking:
|
|
708
|
+
- Direct mappings from OAuth/authentication
|
|
709
|
+
- Indirect evidence (shared attributes, behavior patterns)
|
|
710
|
+
- Conflict detection (same identifier mapped to different users)
|
|
711
|
+
|
|
712
|
+
Args:
|
|
713
|
+
identifier1: First identifier value
|
|
714
|
+
identifier1_type: First identifier type
|
|
715
|
+
identifier2: Second identifier value
|
|
716
|
+
identifier2_type: Second identifier type
|
|
717
|
+
memory_bus: MemoryBus instance for graph queries
|
|
718
|
+
|
|
719
|
+
Returns:
|
|
720
|
+
IdentityConfidence with score, evidence, and conflicts
|
|
721
|
+
|
|
722
|
+
Example:
|
|
723
|
+
>>> confidence = await validate_identity_mapping(
|
|
724
|
+
... "user@example.com", "email",
|
|
725
|
+
... "123456789", "discord_id",
|
|
726
|
+
... memory_bus=bus
|
|
727
|
+
... )
|
|
728
|
+
>>> print(f"Confidence: {confidence.score}, Evidence: {confidence.evidence}")
|
|
729
|
+
"""
|
|
730
|
+
evidence = []
|
|
731
|
+
conflicts = []
|
|
732
|
+
base_score = 0.0
|
|
733
|
+
direct_mapping_found = False
|
|
734
|
+
mapping_source = "unknown"
|
|
735
|
+
|
|
736
|
+
# Build node IDs
|
|
737
|
+
node1_id = f"user_identity:{identifier1_type}:{identifier1}"
|
|
738
|
+
node2_id = f"user_identity:{identifier2_type}:{identifier2}"
|
|
739
|
+
|
|
740
|
+
# Check for direct mapping
|
|
741
|
+
try:
|
|
742
|
+
edges = await memory_bus.get_node_edges(node1_id, GraphScope.ENVIRONMENT)
|
|
743
|
+
|
|
744
|
+
for edge in edges:
|
|
745
|
+
is_direct, score, source = _check_direct_mapping_edge(edge, node1_id, node2_id)
|
|
746
|
+
if is_direct:
|
|
747
|
+
direct_mapping_found = True
|
|
748
|
+
mapping_source = source
|
|
749
|
+
base_score = score
|
|
750
|
+
evidence.append(f"Direct mapping via {mapping_source}")
|
|
751
|
+
break
|
|
752
|
+
|
|
753
|
+
if not direct_mapping_found:
|
|
754
|
+
evidence.append("No direct mapping found")
|
|
755
|
+
base_score = 0.0
|
|
756
|
+
|
|
757
|
+
# Check for conflicts if direct mapping was found
|
|
758
|
+
if direct_mapping_found:
|
|
759
|
+
conflict_list, penalty = await _check_identity_conflicts(identifier1, identifier2, memory_bus)
|
|
760
|
+
conflicts.extend(conflict_list)
|
|
761
|
+
base_score *= penalty
|
|
762
|
+
|
|
763
|
+
except Exception as e:
|
|
764
|
+
evidence.append(f"Error checking mapping: {str(e)}")
|
|
765
|
+
base_score = 0.0
|
|
766
|
+
|
|
767
|
+
# Build IdentityConfidence result
|
|
768
|
+
evidence_objects = _build_evidence_objects(evidence, base_score, mapping_source, direct_mapping_found)
|
|
769
|
+
recommendation, reasoning = _determine_recommendation(base_score)
|
|
770
|
+
|
|
771
|
+
return IdentityConfidence(
|
|
772
|
+
score=base_score,
|
|
773
|
+
evidence=evidence_objects,
|
|
774
|
+
conflicts=[],
|
|
775
|
+
recommendation=recommendation,
|
|
776
|
+
reasoning=reasoning,
|
|
777
|
+
)
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
async def get_or_create_identity_node(
|
|
781
|
+
identifier: str,
|
|
782
|
+
identifier_type: str,
|
|
783
|
+
memory_bus: MemoryServiceProtocol,
|
|
784
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
785
|
+
) -> GraphNode:
|
|
786
|
+
"""Get existing identity node or create new one.
|
|
787
|
+
|
|
788
|
+
Helper function to get or create a GraphNode for a user identifier.
|
|
789
|
+
Used internally by other identity resolution functions.
|
|
790
|
+
|
|
791
|
+
Args:
|
|
792
|
+
identifier: User identifier value
|
|
793
|
+
identifier_type: Type of identifier
|
|
794
|
+
memory_bus: MemoryBus instance for graph storage
|
|
795
|
+
metadata: Optional metadata to store with node
|
|
796
|
+
|
|
797
|
+
Returns:
|
|
798
|
+
GraphNode representing the user identity
|
|
799
|
+
"""
|
|
800
|
+
# Build deterministic node ID from identifier type and value
|
|
801
|
+
node_id = f"user_identity:{identifier_type}:{identifier}"
|
|
802
|
+
|
|
803
|
+
# Try to recall existing node
|
|
804
|
+
try:
|
|
805
|
+
query = MemoryQuery(
|
|
806
|
+
node_id=node_id,
|
|
807
|
+
scope=GraphScope.ENVIRONMENT,
|
|
808
|
+
type=NodeType.IDENTITY,
|
|
809
|
+
)
|
|
810
|
+
existing_nodes = await memory_bus.recall(query)
|
|
811
|
+
|
|
812
|
+
if existing_nodes:
|
|
813
|
+
return existing_nodes[0]
|
|
814
|
+
except Exception:
|
|
815
|
+
# Node doesn't exist, will create new one
|
|
816
|
+
pass
|
|
817
|
+
|
|
818
|
+
# Create new identity node
|
|
819
|
+
attributes = {
|
|
820
|
+
"identifier_type": identifier_type,
|
|
821
|
+
"identifier_value": identifier,
|
|
822
|
+
"created_by": "identity_resolution",
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
# Merge optional metadata
|
|
826
|
+
if metadata:
|
|
827
|
+
attributes.update(metadata)
|
|
828
|
+
|
|
829
|
+
node = GraphNode(
|
|
830
|
+
id=node_id,
|
|
831
|
+
type=NodeType.IDENTITY,
|
|
832
|
+
scope=GraphScope.ENVIRONMENT,
|
|
833
|
+
attributes=attributes,
|
|
834
|
+
)
|
|
835
|
+
|
|
836
|
+
# Store in graph
|
|
837
|
+
result = await memory_bus.memorize(node)
|
|
838
|
+
|
|
839
|
+
if result.status == MemoryOpStatus.OK and result.data:
|
|
840
|
+
return result.data
|
|
841
|
+
|
|
842
|
+
# Fallback: return created node even if storage failed
|
|
843
|
+
return node
|