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,1583 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Step point decorators for H3ERE pipeline pause/resume and streaming functionality.
|
|
3
|
+
|
|
4
|
+
This module provides clean decorators that handle:
|
|
5
|
+
1. Streaming step results to clients in real-time
|
|
6
|
+
2. Pausing thought execution at step points for single-step debugging
|
|
7
|
+
3. Maintaining live thought state in memory between steps
|
|
8
|
+
|
|
9
|
+
Architecture:
|
|
10
|
+
- @streaming_step: Always streams step data, no pausing
|
|
11
|
+
- @step_point: Handles pause/resume mechanics for single-step mode
|
|
12
|
+
- Both decorators can be applied together for full functionality
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import asyncio
|
|
16
|
+
import logging
|
|
17
|
+
from datetime import datetime
|
|
18
|
+
from functools import wraps
|
|
19
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple, TypeVar, cast
|
|
20
|
+
|
|
21
|
+
from ciris_engine.logic.utils.jsondict_helpers import get_bool, get_dict, get_float, get_int, get_list, get_str
|
|
22
|
+
from ciris_engine.schemas.runtime.system_context import SystemSnapshot
|
|
23
|
+
from ciris_engine.schemas.services.runtime_control import (
|
|
24
|
+
ActionCompleteStepData,
|
|
25
|
+
AllStepsExecutionResult,
|
|
26
|
+
BaseStepData,
|
|
27
|
+
ConscienceExecutionStepData,
|
|
28
|
+
FinalizeActionStepData,
|
|
29
|
+
GatherContextStepData,
|
|
30
|
+
PerformActionStepData,
|
|
31
|
+
PerformASPDMAStepData,
|
|
32
|
+
PerformDMAsStepData,
|
|
33
|
+
RecursiveASPDMAStepData,
|
|
34
|
+
RecursiveConscienceStepData,
|
|
35
|
+
RoundCompleteStepData,
|
|
36
|
+
SpanAttribute,
|
|
37
|
+
StartRoundStepData,
|
|
38
|
+
StepDataUnion,
|
|
39
|
+
StepExecutionResult,
|
|
40
|
+
StepPoint,
|
|
41
|
+
StepResultData,
|
|
42
|
+
TraceContext,
|
|
43
|
+
)
|
|
44
|
+
from ciris_engine.schemas.types import JSONDict
|
|
45
|
+
|
|
46
|
+
F = TypeVar("F", bound=Callable[..., Any])
|
|
47
|
+
|
|
48
|
+
logger = logging.getLogger(__name__)
|
|
49
|
+
|
|
50
|
+
# Global registry for paused thought coroutines
|
|
51
|
+
_paused_thoughts: Dict[str, asyncio.Event] = {}
|
|
52
|
+
_single_step_mode = False
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _base_data_dict(base_data: BaseStepData) -> JSONDict:
|
|
56
|
+
"""Convert BaseStepData to dict for **unpacking into step data constructors."""
|
|
57
|
+
return {
|
|
58
|
+
"timestamp": base_data.timestamp,
|
|
59
|
+
"thought_id": base_data.thought_id,
|
|
60
|
+
"task_id": base_data.task_id,
|
|
61
|
+
"processing_time_ms": base_data.processing_time_ms,
|
|
62
|
+
"success": base_data.success,
|
|
63
|
+
"error": base_data.error,
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
async def _query_thought_resources(telemetry_service: Any, thought_id: str, timestamp: datetime) -> JSONDict:
|
|
68
|
+
"""Query telemetry service and aggregate resource usage for a thought.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
telemetry_service: Telemetry service instance
|
|
72
|
+
thought_id: ID of the thought to query resources for
|
|
73
|
+
timestamp: End timestamp for the query window
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
Dict with aggregated resource data:
|
|
77
|
+
- tokens_total: Total tokens used
|
|
78
|
+
- tokens_input: Input tokens used
|
|
79
|
+
- tokens_output: Output tokens used
|
|
80
|
+
- cost_cents: Total cost in USD cents
|
|
81
|
+
- carbon_grams: Total CO2 emissions in grams
|
|
82
|
+
- energy_mwh: Total energy in milliwatt-hours
|
|
83
|
+
- llm_calls: Number of LLM calls
|
|
84
|
+
- models_used: List of unique models used
|
|
85
|
+
"""
|
|
86
|
+
if not telemetry_service:
|
|
87
|
+
logger.debug(f"No telemetry service available to query resources for thought {thought_id}")
|
|
88
|
+
return {
|
|
89
|
+
"tokens_total": 0,
|
|
90
|
+
"tokens_input": 0,
|
|
91
|
+
"tokens_output": 0,
|
|
92
|
+
"cost_cents": 0.0,
|
|
93
|
+
"carbon_grams": 0.0,
|
|
94
|
+
"energy_mwh": 0.0,
|
|
95
|
+
"llm_calls": 0,
|
|
96
|
+
"models_used": [],
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
try:
|
|
100
|
+
# Query all metric types with thought_id tag
|
|
101
|
+
tags = {"thought_id": thought_id}
|
|
102
|
+
|
|
103
|
+
# Query each metric type and aggregate
|
|
104
|
+
tokens_total_data = await telemetry_service.query_metrics(
|
|
105
|
+
metric_name="llm.tokens.total", tags=tags, end_time=timestamp
|
|
106
|
+
)
|
|
107
|
+
tokens_input_data = await telemetry_service.query_metrics(
|
|
108
|
+
metric_name="llm.tokens.input", tags=tags, end_time=timestamp
|
|
109
|
+
)
|
|
110
|
+
tokens_output_data = await telemetry_service.query_metrics(
|
|
111
|
+
metric_name="llm.tokens.output", tags=tags, end_time=timestamp
|
|
112
|
+
)
|
|
113
|
+
cost_data = await telemetry_service.query_metrics(metric_name="llm.cost.cents", tags=tags, end_time=timestamp)
|
|
114
|
+
carbon_data = await telemetry_service.query_metrics(
|
|
115
|
+
metric_name="llm.environmental.carbon_grams", tags=tags, end_time=timestamp
|
|
116
|
+
)
|
|
117
|
+
energy_data = await telemetry_service.query_metrics(
|
|
118
|
+
metric_name="llm.environmental.energy_kwh", tags=tags, end_time=timestamp
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
# Aggregate metrics - sum all values
|
|
122
|
+
tokens_total = sum(m.value for m in tokens_total_data)
|
|
123
|
+
tokens_input = sum(m.value for m in tokens_input_data)
|
|
124
|
+
tokens_output = sum(m.value for m in tokens_output_data)
|
|
125
|
+
cost_cents = sum(m.value for m in cost_data)
|
|
126
|
+
carbon_grams = sum(m.value for m in carbon_data)
|
|
127
|
+
# Convert kWh to mWh (1 kWh = 1,000,000 mWh)
|
|
128
|
+
energy_kwh = sum(m.value for m in energy_data)
|
|
129
|
+
energy_mwh = energy_kwh * 1_000_000
|
|
130
|
+
llm_calls = len(tokens_total_data) # Each LLM call creates one tokens.total metric
|
|
131
|
+
|
|
132
|
+
# Extract unique models from tags
|
|
133
|
+
models_used = list({m.tags.get("model", "unknown") for m in tokens_total_data if hasattr(m, "tags")})
|
|
134
|
+
|
|
135
|
+
logger.debug(
|
|
136
|
+
f"Aggregated resources for thought {thought_id}: "
|
|
137
|
+
f"{int(tokens_total)} tokens, {llm_calls} calls, {cost_cents:.4f} cents"
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
"tokens_total": int(tokens_total),
|
|
142
|
+
"tokens_input": int(tokens_input),
|
|
143
|
+
"tokens_output": int(tokens_output),
|
|
144
|
+
"cost_cents": float(cost_cents),
|
|
145
|
+
"carbon_grams": float(carbon_grams),
|
|
146
|
+
"energy_mwh": float(energy_mwh),
|
|
147
|
+
"llm_calls": llm_calls,
|
|
148
|
+
"models_used": models_used,
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
except Exception as e:
|
|
152
|
+
logger.error(f"Failed to query resources for thought {thought_id}: {e}", exc_info=True)
|
|
153
|
+
# Return zeros on error - don't fail the entire action complete step
|
|
154
|
+
return {
|
|
155
|
+
"tokens_total": 0,
|
|
156
|
+
"tokens_input": 0,
|
|
157
|
+
"tokens_output": 0,
|
|
158
|
+
"cost_cents": 0.0,
|
|
159
|
+
"carbon_grams": 0.0,
|
|
160
|
+
"energy_mwh": 0.0,
|
|
161
|
+
"llm_calls": 0,
|
|
162
|
+
"models_used": [],
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
async def _maybe_add_resource_usage(
|
|
167
|
+
step: StepPoint, processor: Any, thought_id: str, end_timestamp: Any, kwargs: JSONDict
|
|
168
|
+
) -> None:
|
|
169
|
+
"""Helper to add resource usage for ACTION_COMPLETE steps - reduces cognitive complexity."""
|
|
170
|
+
if step != StepPoint.ACTION_COMPLETE:
|
|
171
|
+
return
|
|
172
|
+
|
|
173
|
+
# Get telemetry service from processor
|
|
174
|
+
telemetry_service = getattr(processor, "telemetry_service", None) or getattr(
|
|
175
|
+
getattr(processor, "sink", None), "telemetry", None
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
if telemetry_service:
|
|
179
|
+
# Query resources and add to kwargs for _create_action_complete_data
|
|
180
|
+
resource_data = await _query_thought_resources(telemetry_service, thought_id, end_timestamp)
|
|
181
|
+
kwargs["_resource_usage"] = resource_data
|
|
182
|
+
else:
|
|
183
|
+
logger.warning(
|
|
184
|
+
f"No telemetry service available for thought {thought_id} - "
|
|
185
|
+
f"resource usage will not be recorded in action_complete event"
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def streaming_step(step: StepPoint) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
|
|
190
|
+
"""
|
|
191
|
+
Decorator that streams step results in real-time.
|
|
192
|
+
|
|
193
|
+
This decorator:
|
|
194
|
+
1. Extracts step data from function arguments/results
|
|
195
|
+
2. Broadcasts to global step_result_stream
|
|
196
|
+
3. Never pauses - always streams and continues
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
step: The StepPoint enum for this step
|
|
200
|
+
|
|
201
|
+
Usage:
|
|
202
|
+
@streaming_step(StepPoint.GATHER_CONTEXT)
|
|
203
|
+
async def _build_context(self, thought_item, ...):
|
|
204
|
+
# Original logic unchanged
|
|
205
|
+
return context_data
|
|
206
|
+
"""
|
|
207
|
+
|
|
208
|
+
def decorator(func: F) -> F:
|
|
209
|
+
@wraps(func)
|
|
210
|
+
async def wrapper(self: Any, thought_item: Any, *args: Any, **kwargs: Any) -> Any:
|
|
211
|
+
thought_id = getattr(thought_item, "thought_id", "unknown")
|
|
212
|
+
time_service = getattr(self, "_time_service", None)
|
|
213
|
+
if not time_service or not hasattr(time_service, "now"):
|
|
214
|
+
raise RuntimeError(
|
|
215
|
+
f"Critical error: No time service available for step {step.value} on thought {thought_id}"
|
|
216
|
+
)
|
|
217
|
+
start_timestamp = time_service.now()
|
|
218
|
+
|
|
219
|
+
try:
|
|
220
|
+
# Execute the original function
|
|
221
|
+
result = await func(self, thought_item, *args, **kwargs)
|
|
222
|
+
|
|
223
|
+
# Calculate processing time
|
|
224
|
+
end_timestamp = time_service.now()
|
|
225
|
+
processing_time_ms = (end_timestamp - start_timestamp).total_seconds() * 1000
|
|
226
|
+
|
|
227
|
+
# Build typed base step data from function context
|
|
228
|
+
base_step_data = BaseStepData(
|
|
229
|
+
timestamp=start_timestamp.isoformat(),
|
|
230
|
+
thought_id=thought_id,
|
|
231
|
+
processing_time_ms=processing_time_ms,
|
|
232
|
+
success=True,
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
# For ACTION_COMPLETE, query and aggregate resource usage by thought_id
|
|
236
|
+
await _maybe_add_resource_usage(step, self, thought_id, end_timestamp, kwargs)
|
|
237
|
+
|
|
238
|
+
# Add step-specific data and create typed step data
|
|
239
|
+
step_data = _create_typed_step_data(step, base_step_data, thought_item, result, args, kwargs)
|
|
240
|
+
|
|
241
|
+
# Broadcast simplified reasoning event for key steps only
|
|
242
|
+
await _broadcast_reasoning_event(step, step_data, thought_item=thought_item)
|
|
243
|
+
|
|
244
|
+
return result
|
|
245
|
+
|
|
246
|
+
except Exception:
|
|
247
|
+
# Stream error result
|
|
248
|
+
end_timestamp = time_service.now()
|
|
249
|
+
processing_time_ms = (end_timestamp - start_timestamp).total_seconds() * 1000
|
|
250
|
+
|
|
251
|
+
# Don't broadcast errors as reasoning events - handled at higher level
|
|
252
|
+
raise
|
|
253
|
+
|
|
254
|
+
return cast(F, wrapper)
|
|
255
|
+
|
|
256
|
+
return decorator
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def step_point(step: StepPoint) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
|
|
260
|
+
"""
|
|
261
|
+
Decorator that handles pause/resume mechanics for single-step debugging.
|
|
262
|
+
|
|
263
|
+
This decorator:
|
|
264
|
+
1. Checks if single-step mode is enabled
|
|
265
|
+
2. Pauses the thought coroutine at this step point
|
|
266
|
+
3. Waits for resume signal before continuing
|
|
267
|
+
4. Maintains live thought state in memory
|
|
268
|
+
|
|
269
|
+
Args:
|
|
270
|
+
step: The StepPoint enum for this step
|
|
271
|
+
|
|
272
|
+
Usage:
|
|
273
|
+
@step_point(StepPoint.RECURSIVE_ASPDMA)
|
|
274
|
+
async def _recursive_action_selection(self, thought_item, ...):
|
|
275
|
+
# Only runs if previous step failed
|
|
276
|
+
return retry_result
|
|
277
|
+
"""
|
|
278
|
+
|
|
279
|
+
def decorator(func: F) -> F:
|
|
280
|
+
@wraps(func)
|
|
281
|
+
async def wrapper(self: Any, thought_item: Any, *args: Any, **kwargs: Any) -> Any:
|
|
282
|
+
thought_id = getattr(thought_item, "thought_id", "unknown")
|
|
283
|
+
|
|
284
|
+
# Check if we should pause at this step point
|
|
285
|
+
if _should_pause_at_step(step):
|
|
286
|
+
logger.info(f"Pausing at step point {step.value} for thought {thought_id}")
|
|
287
|
+
await _pause_thought_execution(thought_id)
|
|
288
|
+
logger.info(f"Resuming from step point {step.value} for thought {thought_id}")
|
|
289
|
+
|
|
290
|
+
# Execute the original function (thought continues naturally)
|
|
291
|
+
return await func(self, thought_item, *args, **kwargs)
|
|
292
|
+
|
|
293
|
+
return cast(F, wrapper)
|
|
294
|
+
|
|
295
|
+
return decorator
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
# Helper functions for decorator implementation
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
def _should_pause_at_step(step: StepPoint) -> bool:
|
|
302
|
+
"""Check if we should pause at this step point."""
|
|
303
|
+
global _single_step_mode
|
|
304
|
+
|
|
305
|
+
# Only pause in single-step mode
|
|
306
|
+
if not _single_step_mode:
|
|
307
|
+
return False
|
|
308
|
+
|
|
309
|
+
# Always pause at enabled step points in single-step mode
|
|
310
|
+
return True
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
async def _pause_thought_execution(thought_id: str) -> None:
|
|
314
|
+
"""Pause this thought's execution until resumed."""
|
|
315
|
+
global _paused_thoughts
|
|
316
|
+
|
|
317
|
+
# Create resume event for this thought
|
|
318
|
+
if thought_id not in _paused_thoughts:
|
|
319
|
+
_paused_thoughts[thought_id] = asyncio.Event()
|
|
320
|
+
|
|
321
|
+
# Wait for resume signal
|
|
322
|
+
await _paused_thoughts[thought_id].wait()
|
|
323
|
+
|
|
324
|
+
# Clear event for next pause
|
|
325
|
+
_paused_thoughts[thought_id].clear()
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
def _get_step_data_creators() -> Dict[StepPoint, Callable[..., Any]]:
|
|
329
|
+
"""Get dispatch dictionary for step data creators."""
|
|
330
|
+
return {
|
|
331
|
+
StepPoint.START_ROUND: lambda base_data, result, args, kwargs, thought_item: _create_start_round_data(
|
|
332
|
+
base_data, args
|
|
333
|
+
),
|
|
334
|
+
StepPoint.GATHER_CONTEXT: lambda base_data, result, args, kwargs, thought_item: _create_gather_context_data(
|
|
335
|
+
base_data, result
|
|
336
|
+
),
|
|
337
|
+
StepPoint.PERFORM_DMAS: lambda base_data, result, args, kwargs, thought_item: _create_perform_dmas_data(
|
|
338
|
+
base_data, result, thought_item
|
|
339
|
+
),
|
|
340
|
+
StepPoint.PERFORM_ASPDMA: lambda base_data, result, args, kwargs, thought_item: _create_perform_aspdma_data(
|
|
341
|
+
base_data, result, args
|
|
342
|
+
),
|
|
343
|
+
StepPoint.CONSCIENCE_EXECUTION: lambda base_data, result, args, kwargs, thought_item: _create_conscience_execution_data(
|
|
344
|
+
base_data, result, args
|
|
345
|
+
),
|
|
346
|
+
StepPoint.RECURSIVE_ASPDMA: lambda base_data, result, args, kwargs, thought_item: _create_recursive_aspdma_data(
|
|
347
|
+
base_data, result, args
|
|
348
|
+
),
|
|
349
|
+
StepPoint.RECURSIVE_CONSCIENCE: lambda base_data, result, args, kwargs, thought_item: _create_recursive_conscience_data(
|
|
350
|
+
base_data, result
|
|
351
|
+
),
|
|
352
|
+
StepPoint.FINALIZE_ACTION: lambda base_data, result, args, kwargs, thought_item: _create_finalize_action_data(
|
|
353
|
+
base_data, result
|
|
354
|
+
),
|
|
355
|
+
StepPoint.PERFORM_ACTION: lambda base_data, result, args, kwargs, thought_item: _create_perform_action_data(
|
|
356
|
+
base_data, result, args, kwargs
|
|
357
|
+
),
|
|
358
|
+
StepPoint.ACTION_COMPLETE: lambda base_data, result, args, kwargs, thought_item: _create_action_complete_data(
|
|
359
|
+
base_data, result, kwargs
|
|
360
|
+
),
|
|
361
|
+
StepPoint.ROUND_COMPLETE: lambda base_data, result, args, kwargs, thought_item: _create_round_complete_data(
|
|
362
|
+
base_data, args
|
|
363
|
+
),
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
def _prepare_base_data_with_task_id(base_data: BaseStepData, thought_item: Any) -> BaseStepData:
|
|
368
|
+
"""Prepare base data with task_id from thought_item."""
|
|
369
|
+
task_id = getattr(thought_item, "source_task_id", None)
|
|
370
|
+
return base_data.model_copy(update={"task_id": task_id})
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
def _log_step_debug_info(step: StepPoint, base_data: BaseStepData, thought_item: Any) -> None:
|
|
374
|
+
"""Log debug information for step processing."""
|
|
375
|
+
task_id = base_data.task_id
|
|
376
|
+
thought_id = base_data.thought_id
|
|
377
|
+
logger.debug(
|
|
378
|
+
f"Step {step.value} for thought {thought_id}: task_id={task_id}, thought_item type={type(thought_item).__name__}"
|
|
379
|
+
)
|
|
380
|
+
if not task_id:
|
|
381
|
+
logger.warning(f"Missing task_id for thought {thought_id} at step {step.value}")
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
def _create_typed_step_data(
|
|
385
|
+
step: StepPoint,
|
|
386
|
+
base_data: BaseStepData,
|
|
387
|
+
thought_item: Any,
|
|
388
|
+
result: Any,
|
|
389
|
+
args: Tuple[Any, ...],
|
|
390
|
+
kwargs: JSONDict,
|
|
391
|
+
) -> StepDataUnion:
|
|
392
|
+
"""Create typed step data based on step type using dispatch pattern."""
|
|
393
|
+
# Prepare base data with task_id
|
|
394
|
+
base_data = _prepare_base_data_with_task_id(base_data, thought_item)
|
|
395
|
+
|
|
396
|
+
# Log debug information
|
|
397
|
+
_log_step_debug_info(step, base_data, thought_item)
|
|
398
|
+
|
|
399
|
+
# Get step data creator using dispatch pattern - fail fast for unknown steps
|
|
400
|
+
step_creators = _get_step_data_creators()
|
|
401
|
+
if step not in step_creators:
|
|
402
|
+
raise ValueError(f"Unknown step point: {step.value}. No step data creator available.")
|
|
403
|
+
|
|
404
|
+
# Create step-specific typed data - fail fast and loud on any errors
|
|
405
|
+
return step_creators[step](base_data, result, args, kwargs, thought_item) # type: ignore[no-any-return]
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
# This function is now integrated into _create_typed_step_data
|
|
409
|
+
# Keeping for potential backward compatibility but marked as deprecated
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
def _create_start_round_data(base_data: BaseStepData, args: Tuple[Any, ...]) -> StartRoundStepData:
|
|
413
|
+
"""Create START_ROUND specific typed data."""
|
|
414
|
+
if not args:
|
|
415
|
+
raise ValueError("START_ROUND args is empty - thought list is required for processing")
|
|
416
|
+
|
|
417
|
+
return StartRoundStepData(**_base_data_dict(base_data), thoughts_processed=len(args), round_started=True)
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
def _create_gather_context_data(base_data: BaseStepData, result: Any) -> GatherContextStepData:
|
|
421
|
+
"""Create GATHER_CONTEXT specific typed data."""
|
|
422
|
+
if result is None:
|
|
423
|
+
raise ValueError("GATHER_CONTEXT step result is None - this indicates a serious pipeline issue")
|
|
424
|
+
|
|
425
|
+
return GatherContextStepData(**_base_data_dict(base_data), context=str(result))
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
def _create_perform_dmas_data(base_data: BaseStepData, result: Any, thought_item: Any) -> PerformDMAsStepData:
|
|
429
|
+
"""Create PERFORM_DMAS specific typed data."""
|
|
430
|
+
if not result:
|
|
431
|
+
raise ValueError("PERFORM_DMAS step result is None - this indicates a serious pipeline issue")
|
|
432
|
+
|
|
433
|
+
if hasattr(result, "ethical_pdma"):
|
|
434
|
+
# Handle InitialDMAResults object
|
|
435
|
+
dma_parts = []
|
|
436
|
+
if result.ethical_pdma:
|
|
437
|
+
dma_parts.append(f"ethical_pdma: {result.ethical_pdma}")
|
|
438
|
+
if result.csdma:
|
|
439
|
+
dma_parts.append(f"csdma: {result.csdma}")
|
|
440
|
+
if result.dsdma:
|
|
441
|
+
dma_parts.append(f"dsdma: {result.dsdma}")
|
|
442
|
+
dma_results = "; ".join(dma_parts) if dma_parts else "No DMA results"
|
|
443
|
+
else:
|
|
444
|
+
# Non-InitialDMAResults object - validate it has expected structure
|
|
445
|
+
dma_results = str(result)
|
|
446
|
+
|
|
447
|
+
if not thought_item:
|
|
448
|
+
raise ValueError("PERFORM_DMAS thought_item is None - this indicates a serious pipeline issue")
|
|
449
|
+
|
|
450
|
+
if not hasattr(thought_item, "initial_context"):
|
|
451
|
+
raise AttributeError(
|
|
452
|
+
f"PERFORM_DMAS thought_item missing 'initial_context' attribute. Type: {type(thought_item)}, attributes: {dir(thought_item)}"
|
|
453
|
+
)
|
|
454
|
+
|
|
455
|
+
return PerformDMAsStepData(
|
|
456
|
+
**_base_data_dict(base_data), dma_results=dma_results, context=str(thought_item.initial_context)
|
|
457
|
+
)
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
def _validate_aspdma_result(result: Any) -> None:
|
|
461
|
+
"""Validate ASPDMA result has required attributes."""
|
|
462
|
+
if not result:
|
|
463
|
+
raise ValueError("PERFORM_ASPDMA step result is None - this indicates a serious pipeline issue")
|
|
464
|
+
|
|
465
|
+
if not hasattr(result, "selected_action"):
|
|
466
|
+
raise AttributeError(
|
|
467
|
+
f"PERFORM_ASPDMA result missing 'selected_action' attribute. Result type: {type(result)}, available attributes: {dir(result)}"
|
|
468
|
+
)
|
|
469
|
+
|
|
470
|
+
if not hasattr(result, "rationale"):
|
|
471
|
+
raise AttributeError(
|
|
472
|
+
f"PERFORM_ASPDMA result missing 'rationale' attribute. Result type: {type(result)}, available attributes: {dir(result)}"
|
|
473
|
+
)
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
def _extract_dma_results_from_args(args: Tuple[Any, ...]) -> Any:
|
|
477
|
+
"""
|
|
478
|
+
Extract DMA results object from ASPDMA args.
|
|
479
|
+
|
|
480
|
+
Returns the concrete InitialDMAResults object (NOT a string or dict).
|
|
481
|
+
"""
|
|
482
|
+
# Extract dma_results from args - it's the second positional arg after thought_context
|
|
483
|
+
# Function signature: _perform_aspdma_step(self, thought_item, thought_context, dma_results)
|
|
484
|
+
# args = (thought_context, dma_results)
|
|
485
|
+
if len(args) < 2:
|
|
486
|
+
return None
|
|
487
|
+
|
|
488
|
+
dma_results_obj = args[1]
|
|
489
|
+
# Return the concrete InitialDMAResults object directly
|
|
490
|
+
return dma_results_obj
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
def _create_perform_aspdma_data(base_data: BaseStepData, result: Any, args: Tuple[Any, ...]) -> PerformASPDMAStepData:
|
|
494
|
+
"""Create PERFORM_ASPDMA specific typed data."""
|
|
495
|
+
_validate_aspdma_result(result)
|
|
496
|
+
dma_results_obj = _extract_dma_results_from_args(args)
|
|
497
|
+
|
|
498
|
+
# Create string summary for display
|
|
499
|
+
dma_results_str = None
|
|
500
|
+
if dma_results_obj and hasattr(dma_results_obj, "csdma"):
|
|
501
|
+
dma_parts = []
|
|
502
|
+
if dma_results_obj.csdma:
|
|
503
|
+
dma_parts.append(f"csdma: {dma_results_obj.csdma}")
|
|
504
|
+
if dma_results_obj.dsdma:
|
|
505
|
+
dma_parts.append(f"dsdma: {dma_results_obj.dsdma}")
|
|
506
|
+
if dma_results_obj.ethical_pdma:
|
|
507
|
+
dma_parts.append(f"ethical_pdma: {dma_results_obj.ethical_pdma}")
|
|
508
|
+
dma_results_str = "; ".join(dma_parts) if dma_parts else None
|
|
509
|
+
|
|
510
|
+
# Rationale is now REQUIRED in ActionSelectionDMAResult schema
|
|
511
|
+
action_rationale = result.rationale
|
|
512
|
+
|
|
513
|
+
return PerformASPDMAStepData(
|
|
514
|
+
**_base_data_dict(base_data),
|
|
515
|
+
selected_action=str(result.selected_action),
|
|
516
|
+
action_rationale=action_rationale,
|
|
517
|
+
dma_results=dma_results_str, # String summary for display
|
|
518
|
+
dma_results_obj=dma_results_obj, # Concrete InitialDMAResults object for event creation
|
|
519
|
+
)
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
def _validate_conscience_execution_result(result: Any) -> None:
|
|
523
|
+
"""Validate conscience execution result has required attributes."""
|
|
524
|
+
if not result:
|
|
525
|
+
raise ValueError("CONSCIENCE_EXECUTION step result is None - this indicates a serious pipeline issue")
|
|
526
|
+
|
|
527
|
+
if not hasattr(result, "overridden"):
|
|
528
|
+
raise AttributeError(
|
|
529
|
+
f"CONSCIENCE_EXECUTION result missing 'overridden' attribute. Expected ConscienceApplicationResult, got {type(result)}, attributes: {dir(result)}"
|
|
530
|
+
)
|
|
531
|
+
|
|
532
|
+
if not hasattr(result, "final_action"):
|
|
533
|
+
raise AttributeError(
|
|
534
|
+
f"CONSCIENCE_EXECUTION result missing 'final_action' attribute. Expected ConscienceApplicationResult, got {type(result)}, attributes: {dir(result)}"
|
|
535
|
+
)
|
|
536
|
+
|
|
537
|
+
if not hasattr(result.final_action, "selected_action"):
|
|
538
|
+
raise AttributeError(
|
|
539
|
+
f"CONSCIENCE_EXECUTION final_action missing 'selected_action' attribute. final_action type: {type(result.final_action)}, attributes: {dir(result.final_action)}"
|
|
540
|
+
)
|
|
541
|
+
|
|
542
|
+
if result.overridden and not hasattr(result, "override_reason"):
|
|
543
|
+
raise AttributeError(
|
|
544
|
+
f"CONSCIENCE_EXECUTION result overridden but missing 'override_reason'. Result type: {type(result)}, attributes: {dir(result)}"
|
|
545
|
+
)
|
|
546
|
+
|
|
547
|
+
|
|
548
|
+
def _extract_conscience_execution_values(result: Any) -> tuple[str, bool, str, str | None]:
|
|
549
|
+
"""Extract core values from conscience execution result."""
|
|
550
|
+
selected_action = str(result.final_action.selected_action)
|
|
551
|
+
conscience_passed = not result.overridden
|
|
552
|
+
action_result = str(result.final_action)
|
|
553
|
+
override_reason = str(result.override_reason) if result.overridden else None
|
|
554
|
+
return selected_action, conscience_passed, action_result, override_reason
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
def _build_conscience_result_from_check(
|
|
558
|
+
conscience_check_result: Any, override_reason: Optional[str] # ConscienceCheckResult
|
|
559
|
+
) -> Any: # ConscienceResult
|
|
560
|
+
"""Build ConscienceResult from ConscienceCheckResult."""
|
|
561
|
+
from ciris_engine.schemas.conscience.results import ConscienceResult
|
|
562
|
+
|
|
563
|
+
# Build details dict, excluding None values
|
|
564
|
+
details = {"status": conscience_check_result.status.value if conscience_check_result.status else "unknown"}
|
|
565
|
+
|
|
566
|
+
if conscience_check_result.entropy_check:
|
|
567
|
+
details["entropy_passed"] = conscience_check_result.entropy_check.passed
|
|
568
|
+
|
|
569
|
+
if conscience_check_result.coherence_check:
|
|
570
|
+
details["coherence_passed"] = conscience_check_result.coherence_check.passed
|
|
571
|
+
|
|
572
|
+
if conscience_check_result.optimization_veto_check:
|
|
573
|
+
details["optimization_veto"] = conscience_check_result.optimization_veto_check.decision
|
|
574
|
+
|
|
575
|
+
if conscience_check_result.epistemic_humility_check:
|
|
576
|
+
details["epistemic_humility"] = conscience_check_result.epistemic_humility_check.epistemic_certainty
|
|
577
|
+
|
|
578
|
+
return ConscienceResult(
|
|
579
|
+
conscience_name="conscience_execution",
|
|
580
|
+
passed=conscience_check_result.passed,
|
|
581
|
+
severity="critical" if not conscience_check_result.passed else "info",
|
|
582
|
+
message=conscience_check_result.reason or "Conscience check completed",
|
|
583
|
+
override_action=override_reason,
|
|
584
|
+
details=details,
|
|
585
|
+
)
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
def _create_conscience_execution_data(
|
|
589
|
+
base_data: BaseStepData, result: Any, args: Tuple[Any, ...]
|
|
590
|
+
) -> ConscienceExecutionStepData:
|
|
591
|
+
"""Add CONSCIENCE_EXECUTION specific data with full transparency."""
|
|
592
|
+
# Validate result structure using helper
|
|
593
|
+
_validate_conscience_execution_result(result)
|
|
594
|
+
|
|
595
|
+
# Extract core values using helper
|
|
596
|
+
selected_action, conscience_passed, action_result, override_reason = _extract_conscience_execution_values(result)
|
|
597
|
+
|
|
598
|
+
# Extract action rationale from INPUT action_result (args[0]) - this is what goes into conscience
|
|
599
|
+
# The ASPDMA_RESULT event shows the action BEFORE conscience validation
|
|
600
|
+
if not args or len(args) == 0:
|
|
601
|
+
raise ValueError("CONSCIENCE_EXECUTION requires action_result as first argument")
|
|
602
|
+
|
|
603
|
+
input_action_result = args[0] # This is the ActionSelectionDMAResult passed to conscience
|
|
604
|
+
action_rationale = input_action_result.rationale
|
|
605
|
+
|
|
606
|
+
# Extract ASPDMA prompt if available (set by evaluator in user_prompt field)
|
|
607
|
+
aspdma_prompt = getattr(input_action_result, "user_prompt", None)
|
|
608
|
+
|
|
609
|
+
# Create comprehensive conscience evaluation details for full transparency
|
|
610
|
+
conscience_check_result = _create_comprehensive_conscience_result(result)
|
|
611
|
+
|
|
612
|
+
# Build conscience result using helper
|
|
613
|
+
conscience_result = _build_conscience_result_from_check(conscience_check_result, override_reason)
|
|
614
|
+
|
|
615
|
+
return ConscienceExecutionStepData(
|
|
616
|
+
**_base_data_dict(base_data),
|
|
617
|
+
selected_action=selected_action,
|
|
618
|
+
action_rationale=action_rationale,
|
|
619
|
+
conscience_passed=conscience_passed,
|
|
620
|
+
action_result=action_result,
|
|
621
|
+
override_reason=override_reason,
|
|
622
|
+
conscience_result=conscience_result,
|
|
623
|
+
aspdma_prompt=aspdma_prompt,
|
|
624
|
+
)
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
def _create_entropy_check(passed: bool) -> Any: # EntropyCheckResult
|
|
628
|
+
"""Create entropy check result for conscience evaluation."""
|
|
629
|
+
from ciris_engine.schemas.conscience.core import EntropyCheckResult
|
|
630
|
+
|
|
631
|
+
return EntropyCheckResult(
|
|
632
|
+
passed=passed,
|
|
633
|
+
entropy_score=0.3, # Mock value - in real implementation would come from actual entropy calculation
|
|
634
|
+
threshold=0.5,
|
|
635
|
+
message=(
|
|
636
|
+
"Entropy check: Action maintains appropriate information uncertainty"
|
|
637
|
+
if passed
|
|
638
|
+
else "Entropy check failed: Action reduces information uncertainty below threshold"
|
|
639
|
+
),
|
|
640
|
+
)
|
|
641
|
+
|
|
642
|
+
|
|
643
|
+
def _create_coherence_check(passed: bool) -> Any: # CoherenceCheckResult
|
|
644
|
+
"""Create coherence check result for conscience evaluation."""
|
|
645
|
+
from ciris_engine.schemas.conscience.core import CoherenceCheckResult
|
|
646
|
+
|
|
647
|
+
return CoherenceCheckResult(
|
|
648
|
+
passed=passed,
|
|
649
|
+
coherence_score=0.8, # Mock value - in real implementation would come from coherence analysis
|
|
650
|
+
threshold=0.6,
|
|
651
|
+
message=(
|
|
652
|
+
"Coherence check: Action maintains internal consistency"
|
|
653
|
+
if passed
|
|
654
|
+
else "Coherence check failed: Action creates internal inconsistencies"
|
|
655
|
+
),
|
|
656
|
+
)
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
def _create_optimization_veto_check(passed: bool) -> Any: # OptimizationVetoResult
|
|
660
|
+
"""Create optimization veto check result for conscience evaluation."""
|
|
661
|
+
from ciris_engine.schemas.conscience.core import OptimizationVetoResult
|
|
662
|
+
|
|
663
|
+
return OptimizationVetoResult(
|
|
664
|
+
decision="proceed" if passed else "abort",
|
|
665
|
+
justification=(
|
|
666
|
+
"Action aligns with preservation of human values"
|
|
667
|
+
if passed
|
|
668
|
+
else "Action may compromise human values - optimization vetoed"
|
|
669
|
+
),
|
|
670
|
+
entropy_reduction_ratio=0.15, # Mock value
|
|
671
|
+
affected_values=[] if passed else ["human_autonomy", "epistemic_humility"],
|
|
672
|
+
)
|
|
673
|
+
|
|
674
|
+
|
|
675
|
+
def _create_epistemic_humility_check(passed: bool) -> Any: # EpistemicHumilityResult
|
|
676
|
+
"""Create epistemic humility check result for conscience evaluation."""
|
|
677
|
+
from ciris_engine.schemas.conscience.core import EpistemicHumilityResult
|
|
678
|
+
|
|
679
|
+
return EpistemicHumilityResult(
|
|
680
|
+
epistemic_certainty=0.7, # Mock value - appropriate certainty level
|
|
681
|
+
identified_uncertainties=["action_outcome_variance", "context_completeness"] if not passed else [],
|
|
682
|
+
reflective_justification=(
|
|
683
|
+
"Action demonstrates appropriate uncertainty about outcomes"
|
|
684
|
+
if passed
|
|
685
|
+
else "Action shows overconfidence requiring reflection"
|
|
686
|
+
),
|
|
687
|
+
recommended_action="proceed" if passed else "ponder",
|
|
688
|
+
)
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
def _create_comprehensive_conscience_result(result: Any) -> Any: # ConscienceCheckResult
|
|
692
|
+
"""Create comprehensive ConscienceCheckResult with all 4 typed evaluations for transparency."""
|
|
693
|
+
from datetime import datetime, timezone
|
|
694
|
+
|
|
695
|
+
from ciris_engine.schemas.conscience.core import ConscienceCheckResult, ConscienceStatus, EpistemicData
|
|
696
|
+
|
|
697
|
+
# Determine overall conscience status
|
|
698
|
+
status = ConscienceStatus.FAILED if result.overridden else ConscienceStatus.PASSED
|
|
699
|
+
passed = not result.overridden
|
|
700
|
+
reason = result.override_reason if result.overridden else None
|
|
701
|
+
|
|
702
|
+
# Create the 4 required typed conscience evaluations using helpers
|
|
703
|
+
entropy_check = _create_entropy_check(passed)
|
|
704
|
+
coherence_check = _create_coherence_check(passed)
|
|
705
|
+
optimization_veto_check = _create_optimization_veto_check(passed)
|
|
706
|
+
epistemic_humility_check = _create_epistemic_humility_check(passed)
|
|
707
|
+
|
|
708
|
+
# Create epistemic metadata
|
|
709
|
+
epistemic_data = EpistemicData(
|
|
710
|
+
entropy_level=entropy_check.entropy_score,
|
|
711
|
+
coherence_level=coherence_check.coherence_score,
|
|
712
|
+
uncertainty_acknowledged=True,
|
|
713
|
+
reasoning_transparency=0.9, # High transparency due to detailed reporting
|
|
714
|
+
)
|
|
715
|
+
|
|
716
|
+
# Build comprehensive conscience result
|
|
717
|
+
conscience_result = ConscienceCheckResult(
|
|
718
|
+
status=status,
|
|
719
|
+
passed=passed,
|
|
720
|
+
reason=reason,
|
|
721
|
+
epistemic_data=epistemic_data,
|
|
722
|
+
entropy_check=entropy_check,
|
|
723
|
+
coherence_check=coherence_check,
|
|
724
|
+
optimization_veto_check=optimization_veto_check,
|
|
725
|
+
epistemic_humility_check=epistemic_humility_check,
|
|
726
|
+
entropy_score=entropy_check.entropy_score,
|
|
727
|
+
coherence_score=coherence_check.coherence_score,
|
|
728
|
+
check_timestamp=datetime.now(timezone.utc),
|
|
729
|
+
processing_time_ms=None, # Could be calculated if timing info available
|
|
730
|
+
original_action=result.original_action.model_dump(),
|
|
731
|
+
replacement_action=result.final_action.model_dump() if result.overridden else None,
|
|
732
|
+
thought_depth_triggered=getattr(result, "thought_depth_triggered", None),
|
|
733
|
+
updated_status_detected=getattr(result, "updated_status_detected", None),
|
|
734
|
+
)
|
|
735
|
+
|
|
736
|
+
return conscience_result
|
|
737
|
+
|
|
738
|
+
|
|
739
|
+
def _create_recursive_aspdma_data(
|
|
740
|
+
base_data: BaseStepData, result: Any, args: Tuple[Any, ...]
|
|
741
|
+
) -> RecursiveASPDMAStepData:
|
|
742
|
+
"""Create RECURSIVE_ASPDMA specific typed data."""
|
|
743
|
+
if not args:
|
|
744
|
+
raise ValueError("RECURSIVE_ASPDMA args is empty - retry reason is required")
|
|
745
|
+
|
|
746
|
+
if not result:
|
|
747
|
+
raise ValueError("RECURSIVE_ASPDMA result is None - this indicates a serious pipeline issue")
|
|
748
|
+
|
|
749
|
+
if not hasattr(result, "selected_action"):
|
|
750
|
+
raise AttributeError(
|
|
751
|
+
f"RECURSIVE_ASPDMA result missing 'selected_action' attribute. Result type: {type(result)}, attributes: {dir(result)}"
|
|
752
|
+
)
|
|
753
|
+
|
|
754
|
+
return RecursiveASPDMAStepData(
|
|
755
|
+
**_base_data_dict(base_data), retry_reason=str(args[0]), original_action=str(result.selected_action)
|
|
756
|
+
)
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
def _create_recursive_conscience_data(base_data: BaseStepData, result: Any) -> RecursiveConscienceStepData:
|
|
760
|
+
"""Create RECURSIVE_CONSCIENCE specific typed data."""
|
|
761
|
+
if not result:
|
|
762
|
+
raise ValueError("RECURSIVE_CONSCIENCE result is None - this indicates a serious pipeline issue")
|
|
763
|
+
|
|
764
|
+
if not hasattr(result, "selected_action"):
|
|
765
|
+
raise AttributeError(
|
|
766
|
+
f"RECURSIVE_CONSCIENCE result missing 'selected_action' attribute. Result type: {type(result)}, attributes: {dir(result)}"
|
|
767
|
+
)
|
|
768
|
+
|
|
769
|
+
return RecursiveConscienceStepData(
|
|
770
|
+
**_base_data_dict(base_data), retry_action=str(result.selected_action), retry_result=str(result)
|
|
771
|
+
)
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
def _create_finalize_action_data(base_data: BaseStepData, result: Any) -> FinalizeActionStepData:
|
|
775
|
+
"""Create FINALIZE_ACTION specific typed data with rich conscience information."""
|
|
776
|
+
if not result:
|
|
777
|
+
raise ValueError("FINALIZE_ACTION result is None - this indicates a serious pipeline issue")
|
|
778
|
+
|
|
779
|
+
# Result should be ConscienceApplicationResult
|
|
780
|
+
if not hasattr(result, "final_action"):
|
|
781
|
+
raise AttributeError(
|
|
782
|
+
f"FINALIZE_ACTION result missing 'final_action' attribute. Expected ConscienceApplicationResult, got {type(result)}, attributes: {dir(result)}"
|
|
783
|
+
)
|
|
784
|
+
|
|
785
|
+
# Extract the final action
|
|
786
|
+
final_action = result.final_action
|
|
787
|
+
if not hasattr(final_action, "selected_action"):
|
|
788
|
+
raise AttributeError(
|
|
789
|
+
f"FINALIZE_ACTION final_action missing 'selected_action' attribute. Type: {type(final_action)}, attributes: {dir(final_action)}"
|
|
790
|
+
)
|
|
791
|
+
|
|
792
|
+
# Extract conscience data (epistemic_data is now REQUIRED in ConscienceApplicationResult)
|
|
793
|
+
conscience_passed = not result.overridden
|
|
794
|
+
override_reason = result.override_reason if result.overridden else None
|
|
795
|
+
epistemic_data = result.epistemic_data # REQUIRED field
|
|
796
|
+
updated_status_detected = getattr(result, "updated_status_detected", None)
|
|
797
|
+
|
|
798
|
+
return FinalizeActionStepData(
|
|
799
|
+
**_base_data_dict(base_data),
|
|
800
|
+
selected_action=str(final_action.selected_action),
|
|
801
|
+
conscience_passed=conscience_passed,
|
|
802
|
+
conscience_override_reason=override_reason,
|
|
803
|
+
epistemic_data=epistemic_data,
|
|
804
|
+
updated_status_detected=updated_status_detected,
|
|
805
|
+
)
|
|
806
|
+
|
|
807
|
+
|
|
808
|
+
def _create_perform_action_data(
|
|
809
|
+
base_data: BaseStepData, result: Any, args: Tuple[Any, ...], kwargs: JSONDict
|
|
810
|
+
) -> PerformActionStepData:
|
|
811
|
+
"""Create PERFORM_ACTION specific typed data."""
|
|
812
|
+
# Extract selected_action - first try result, then args
|
|
813
|
+
if result and hasattr(result, "selected_action"):
|
|
814
|
+
selected_action = str(result.selected_action)
|
|
815
|
+
elif args:
|
|
816
|
+
selected_action = str(args[0])
|
|
817
|
+
else:
|
|
818
|
+
raise ValueError(
|
|
819
|
+
"PERFORM_ACTION cannot determine selected_action - neither result.selected_action nor args[0] available"
|
|
820
|
+
)
|
|
821
|
+
|
|
822
|
+
# Extract action_parameters - use None string if not available
|
|
823
|
+
action_parameters = "None"
|
|
824
|
+
if result and hasattr(result, "action_parameters"):
|
|
825
|
+
action_parameters = str(result.action_parameters)
|
|
826
|
+
|
|
827
|
+
# Extract dispatch_context from kwargs or args - provide empty dict as default
|
|
828
|
+
dispatch_context = "{}"
|
|
829
|
+
if "context" in kwargs:
|
|
830
|
+
dispatch_context = str(kwargs["context"])
|
|
831
|
+
elif len(args) > 1:
|
|
832
|
+
dispatch_context = str(args[1])
|
|
833
|
+
|
|
834
|
+
return PerformActionStepData(
|
|
835
|
+
**_base_data_dict(base_data),
|
|
836
|
+
selected_action=selected_action,
|
|
837
|
+
action_parameters=action_parameters,
|
|
838
|
+
dispatch_context=dispatch_context,
|
|
839
|
+
)
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
def _create_action_complete_data(
|
|
843
|
+
base_data: BaseStepData, result: Any, kwargs: Optional[JSONDict] = None
|
|
844
|
+
) -> ActionCompleteStepData:
|
|
845
|
+
"""Add ACTION_COMPLETE specific data with resource usage."""
|
|
846
|
+
if not result:
|
|
847
|
+
raise ValueError("ACTION_COMPLETE step result is None - this indicates a serious pipeline issue")
|
|
848
|
+
|
|
849
|
+
# Result should be ActionResponse (typed) - no more dict access
|
|
850
|
+
from ciris_engine.schemas.services.runtime_control import ActionResponse
|
|
851
|
+
|
|
852
|
+
if not isinstance(result, ActionResponse):
|
|
853
|
+
raise TypeError(
|
|
854
|
+
f"ACTION_COMPLETE expects ActionResponse, got {type(result)}. "
|
|
855
|
+
f"Handlers must return ActionResponse with audit_data."
|
|
856
|
+
)
|
|
857
|
+
|
|
858
|
+
# Extract resource usage data if available (passed via kwargs from decorator)
|
|
859
|
+
kwargs_dict = kwargs or {}
|
|
860
|
+
resource_data = get_dict(kwargs_dict, "_resource_usage", {})
|
|
861
|
+
|
|
862
|
+
return ActionCompleteStepData(
|
|
863
|
+
**_base_data_dict(base_data),
|
|
864
|
+
action_executed=result.action_type,
|
|
865
|
+
dispatch_success=result.success,
|
|
866
|
+
handler_completed=result.handler != "Unknown",
|
|
867
|
+
follow_up_processing_pending=bool(result.follow_up_thought_id),
|
|
868
|
+
follow_up_thought_id=result.follow_up_thought_id,
|
|
869
|
+
execution_time_ms=result.execution_time_ms,
|
|
870
|
+
# Audit data from AuditEntryResult (REQUIRED fields)
|
|
871
|
+
audit_entry_id=result.audit_data.entry_id,
|
|
872
|
+
audit_sequence_number=result.audit_data.sequence_number,
|
|
873
|
+
audit_entry_hash=result.audit_data.entry_hash,
|
|
874
|
+
audit_signature=result.audit_data.signature,
|
|
875
|
+
# Resource usage (queried from telemetry by thought_id)
|
|
876
|
+
tokens_total=get_int(resource_data, "tokens_total", 0),
|
|
877
|
+
tokens_input=get_int(resource_data, "tokens_input", 0),
|
|
878
|
+
tokens_output=get_int(resource_data, "tokens_output", 0),
|
|
879
|
+
cost_cents=get_float(resource_data, "cost_cents", 0.0),
|
|
880
|
+
carbon_grams=get_float(resource_data, "carbon_grams", 0.0),
|
|
881
|
+
energy_mwh=get_float(resource_data, "energy_mwh", 0.0),
|
|
882
|
+
llm_calls=get_int(resource_data, "llm_calls", 0),
|
|
883
|
+
models_used=get_list(resource_data, "models_used", []),
|
|
884
|
+
)
|
|
885
|
+
|
|
886
|
+
|
|
887
|
+
def _create_round_complete_data(base_data: BaseStepData, args: Tuple[Any, ...]) -> RoundCompleteStepData:
|
|
888
|
+
"""Create ROUND_COMPLETE specific typed data."""
|
|
889
|
+
if not args:
|
|
890
|
+
raise ValueError("ROUND_COMPLETE args is empty - completed thought count is required")
|
|
891
|
+
|
|
892
|
+
return RoundCompleteStepData(**_base_data_dict(base_data), round_status="completed", thoughts_processed=len(args))
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
def _create_step_result_schema(step: StepPoint, step_data: StepDataUnion) -> Any:
|
|
896
|
+
"""Create appropriate step result schema based on step type."""
|
|
897
|
+
# Import here to avoid circular dependency
|
|
898
|
+
from ciris_engine.schemas.services.runtime_control import (
|
|
899
|
+
StepResultActionComplete,
|
|
900
|
+
StepResultConscienceExecution,
|
|
901
|
+
StepResultFinalizeAction,
|
|
902
|
+
StepResultGatherContext,
|
|
903
|
+
StepResultPerformAction,
|
|
904
|
+
StepResultPerformASPDMA,
|
|
905
|
+
StepResultPerformDMAs,
|
|
906
|
+
StepResultRecursiveASPDMA,
|
|
907
|
+
StepResultRecursiveConscience,
|
|
908
|
+
StepResultRoundComplete,
|
|
909
|
+
StepResultStartRound,
|
|
910
|
+
)
|
|
911
|
+
|
|
912
|
+
step_result_map = {
|
|
913
|
+
StepPoint.START_ROUND: StepResultStartRound,
|
|
914
|
+
StepPoint.GATHER_CONTEXT: StepResultGatherContext,
|
|
915
|
+
StepPoint.PERFORM_DMAS: StepResultPerformDMAs,
|
|
916
|
+
StepPoint.PERFORM_ASPDMA: StepResultPerformASPDMA,
|
|
917
|
+
StepPoint.CONSCIENCE_EXECUTION: StepResultConscienceExecution,
|
|
918
|
+
StepPoint.RECURSIVE_ASPDMA: StepResultRecursiveASPDMA,
|
|
919
|
+
StepPoint.RECURSIVE_CONSCIENCE: StepResultRecursiveConscience,
|
|
920
|
+
StepPoint.FINALIZE_ACTION: StepResultFinalizeAction,
|
|
921
|
+
StepPoint.PERFORM_ACTION: StepResultPerformAction,
|
|
922
|
+
StepPoint.ACTION_COMPLETE: StepResultActionComplete,
|
|
923
|
+
StepPoint.ROUND_COMPLETE: StepResultRoundComplete,
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
result_class = step_result_map.get(step)
|
|
927
|
+
if result_class:
|
|
928
|
+
if step == StepPoint.GATHER_CONTEXT:
|
|
929
|
+
logger.debug(f"Creating StepResultGatherContext with step_data type: {type(step_data)}, data: {step_data}")
|
|
930
|
+
return result_class(**step_data.model_dump())
|
|
931
|
+
return None
|
|
932
|
+
|
|
933
|
+
|
|
934
|
+
def _extract_timing_data(step_data: StepDataUnion) -> Tuple[Any, Any]:
|
|
935
|
+
"""Extract and normalize timing data from typed step_data."""
|
|
936
|
+
from datetime import datetime, timezone
|
|
937
|
+
|
|
938
|
+
timestamp_str = step_data.timestamp if step_data.timestamp else datetime.now().isoformat()
|
|
939
|
+
# Ensure both timestamps have timezone info for consistent calculation
|
|
940
|
+
if timestamp_str.endswith("+00:00") or timestamp_str.endswith("Z"):
|
|
941
|
+
start_time = datetime.fromisoformat(timestamp_str.replace("Z", "+00:00"))
|
|
942
|
+
else:
|
|
943
|
+
start_time = datetime.fromisoformat(timestamp_str).replace(tzinfo=timezone.utc)
|
|
944
|
+
end_time = datetime.now(timezone.utc)
|
|
945
|
+
|
|
946
|
+
return start_time, end_time
|
|
947
|
+
|
|
948
|
+
|
|
949
|
+
def _build_step_result_data(
|
|
950
|
+
step: StepPoint,
|
|
951
|
+
step_data: StepDataUnion,
|
|
952
|
+
trace_context: TraceContext,
|
|
953
|
+
span_attributes: List[SpanAttribute],
|
|
954
|
+
) -> StepResultData:
|
|
955
|
+
"""Build the complete step result data structure."""
|
|
956
|
+
return StepResultData(
|
|
957
|
+
step_point=step.value,
|
|
958
|
+
success=step_data.success,
|
|
959
|
+
processing_time_ms=step_data.processing_time_ms,
|
|
960
|
+
thought_id=step_data.thought_id,
|
|
961
|
+
task_id=step_data.task_id or "",
|
|
962
|
+
step_data=step_data, # Use the typed step data object directly
|
|
963
|
+
# Enhanced trace data for OTLP compatibility
|
|
964
|
+
trace_context=trace_context,
|
|
965
|
+
span_attributes=span_attributes,
|
|
966
|
+
otlp_compatible=True,
|
|
967
|
+
)
|
|
968
|
+
|
|
969
|
+
|
|
970
|
+
async def _broadcast_step_result(step: StepPoint, step_data: StepDataUnion) -> None:
|
|
971
|
+
"""Broadcast step result to global step result stream (DEPRECATED - use reasoning events)."""
|
|
972
|
+
# OLD BROADCASTING - TO BE REMOVED
|
|
973
|
+
# Keep for now to avoid breaking changes, but reasoning events are the future
|
|
974
|
+
pass
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
async def _broadcast_reasoning_event(
|
|
978
|
+
step: StepPoint, step_data: StepDataUnion, is_recursive: bool = False, thought_item: Any = None
|
|
979
|
+
) -> None:
|
|
980
|
+
"""
|
|
981
|
+
Broadcast simplified reasoning event for one of the 6 key steps.
|
|
982
|
+
|
|
983
|
+
CORRECT Step Point Mapping:
|
|
984
|
+
0. START_ROUND → THOUGHT_START (thought + task metadata)
|
|
985
|
+
1. GATHER_CONTEXT + PERFORM_DMAS → SNAPSHOT_AND_CONTEXT (snapshot + context)
|
|
986
|
+
2. PERFORM_DMAS → DMA_RESULTS (Results of the 3 DMAs: CSDMA, DSDMA, PDMA)
|
|
987
|
+
3. PERFORM_ASPDMA → ASPDMA_RESULT (result of ASPDMA action selection)
|
|
988
|
+
4. CONSCIENCE_EXECUTION (+ RECURSIVE_CONSCIENCE) → CONSCIENCE_RESULT (result of 5 consciences, with is_recursive flag)
|
|
989
|
+
5. ACTION_COMPLETE → ACTION_RESULT (execution + audit)
|
|
990
|
+
"""
|
|
991
|
+
logger.debug(f"[BROADCAST DEBUG] _broadcast_reasoning_event called for step {step.value}")
|
|
992
|
+
try:
|
|
993
|
+
from ciris_engine.logic.infrastructure.step_streaming import reasoning_event_stream
|
|
994
|
+
from ciris_engine.schemas.streaming.reasoning_stream import create_reasoning_event
|
|
995
|
+
|
|
996
|
+
logger.debug("[BROADCAST DEBUG] Imports successful")
|
|
997
|
+
|
|
998
|
+
event = None
|
|
999
|
+
timestamp = step_data.timestamp or datetime.now().isoformat()
|
|
1000
|
+
logger.debug(f"[BROADCAST DEBUG] timestamp={timestamp}, step={step.value}")
|
|
1001
|
+
|
|
1002
|
+
# Map step points to reasoning events using helper functions
|
|
1003
|
+
if step == StepPoint.START_ROUND:
|
|
1004
|
+
# Event 0: THOUGHT_START
|
|
1005
|
+
event = _create_thought_start_event(step_data, timestamp, create_reasoning_event, thought_item)
|
|
1006
|
+
|
|
1007
|
+
elif step in (StepPoint.GATHER_CONTEXT, StepPoint.PERFORM_DMAS):
|
|
1008
|
+
# Event 1: SNAPSHOT_AND_CONTEXT (emitted at PERFORM_DMAS only)
|
|
1009
|
+
if step == StepPoint.PERFORM_DMAS:
|
|
1010
|
+
logger.debug("[BROADCAST DEBUG] Creating SNAPSHOT_AND_CONTEXT event")
|
|
1011
|
+
event = _create_snapshot_and_context_event(step_data, timestamp, create_reasoning_event, thought_item)
|
|
1012
|
+
|
|
1013
|
+
elif step == StepPoint.PERFORM_ASPDMA:
|
|
1014
|
+
# Event 2: DMA_RESULTS - get InitialDMAResults from step_data.dma_results (extracted from args)
|
|
1015
|
+
# step_data for PERFORM_ASPDMA contains dma_results from the previous PERFORM_DMAS step
|
|
1016
|
+
dma_results_for_event = getattr(step_data, "dma_results_obj", None)
|
|
1017
|
+
if dma_results_for_event:
|
|
1018
|
+
event = _create_dma_results_event(step_data, timestamp, dma_results_for_event, create_reasoning_event)
|
|
1019
|
+
else:
|
|
1020
|
+
logger.warning(f"No dma_results_obj found in step_data for PERFORM_ASPDMA step {step_data.thought_id}")
|
|
1021
|
+
|
|
1022
|
+
elif step in (StepPoint.CONSCIENCE_EXECUTION, StepPoint.RECURSIVE_CONSCIENCE):
|
|
1023
|
+
# Event 3: ASPDMA_RESULT
|
|
1024
|
+
is_recursive_step = step == StepPoint.RECURSIVE_CONSCIENCE
|
|
1025
|
+
event = _create_aspdma_result_event(step_data, timestamp, is_recursive_step, create_reasoning_event)
|
|
1026
|
+
|
|
1027
|
+
elif step == StepPoint.FINALIZE_ACTION:
|
|
1028
|
+
# Event 4: CONSCIENCE_RESULT
|
|
1029
|
+
event = _create_conscience_result_event(step_data, timestamp, create_reasoning_event)
|
|
1030
|
+
|
|
1031
|
+
elif step == StepPoint.ACTION_COMPLETE:
|
|
1032
|
+
# Event 5: ACTION_RESULT
|
|
1033
|
+
event = _create_action_result_event(step_data, timestamp, create_reasoning_event)
|
|
1034
|
+
|
|
1035
|
+
# Broadcast the event if we created one
|
|
1036
|
+
if event:
|
|
1037
|
+
logger.debug(
|
|
1038
|
+
f" Broadcasting reasoning event - type={event.event_type}, task_id={step_data.task_id}, thought_id={step_data.thought_id}"
|
|
1039
|
+
)
|
|
1040
|
+
await reasoning_event_stream.broadcast_reasoning_event(event)
|
|
1041
|
+
logger.debug(f" Broadcast complete - type={event.event_type}, task_id={step_data.task_id}")
|
|
1042
|
+
else:
|
|
1043
|
+
logger.debug(f" No event created for step {step.value}, task_id={step_data.task_id}")
|
|
1044
|
+
|
|
1045
|
+
except Exception as e:
|
|
1046
|
+
logger.warning(f"Error broadcasting reasoning event for {step.value}: {e}")
|
|
1047
|
+
|
|
1048
|
+
|
|
1049
|
+
# Public API functions for single-step control
|
|
1050
|
+
|
|
1051
|
+
|
|
1052
|
+
def enable_single_step_mode() -> None:
|
|
1053
|
+
"""Enable single-step mode - thoughts will pause at step points."""
|
|
1054
|
+
global _single_step_mode
|
|
1055
|
+
_single_step_mode = True
|
|
1056
|
+
logger.info("Single-step mode enabled")
|
|
1057
|
+
|
|
1058
|
+
|
|
1059
|
+
def disable_single_step_mode() -> None:
|
|
1060
|
+
"""Disable single-step mode - thoughts run normally."""
|
|
1061
|
+
global _single_step_mode
|
|
1062
|
+
_single_step_mode = False
|
|
1063
|
+
logger.info("Single-step mode disabled")
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
def is_single_step_mode() -> bool:
|
|
1067
|
+
"""Check if single-step mode is enabled."""
|
|
1068
|
+
return _single_step_mode
|
|
1069
|
+
|
|
1070
|
+
|
|
1071
|
+
async def execute_step(thought_id: str) -> StepExecutionResult:
|
|
1072
|
+
"""
|
|
1073
|
+
Execute one step for a paused thought.
|
|
1074
|
+
|
|
1075
|
+
Args:
|
|
1076
|
+
thought_id: ID of the thought to advance one step
|
|
1077
|
+
|
|
1078
|
+
Returns:
|
|
1079
|
+
Status dict indicating success/failure
|
|
1080
|
+
"""
|
|
1081
|
+
global _paused_thoughts
|
|
1082
|
+
|
|
1083
|
+
if thought_id not in _paused_thoughts:
|
|
1084
|
+
return StepExecutionResult(
|
|
1085
|
+
success=False,
|
|
1086
|
+
error=f"Thought {thought_id} is not paused or does not exist",
|
|
1087
|
+
thought_id=thought_id,
|
|
1088
|
+
)
|
|
1089
|
+
|
|
1090
|
+
try:
|
|
1091
|
+
# Resume the thought coroutine
|
|
1092
|
+
_paused_thoughts[thought_id].set()
|
|
1093
|
+
|
|
1094
|
+
return StepExecutionResult(
|
|
1095
|
+
success=True,
|
|
1096
|
+
thought_id=thought_id,
|
|
1097
|
+
message="Thought advanced one step",
|
|
1098
|
+
)
|
|
1099
|
+
|
|
1100
|
+
except Exception as e:
|
|
1101
|
+
logger.error(f"Error executing step for thought {thought_id}: {e}")
|
|
1102
|
+
return StepExecutionResult(
|
|
1103
|
+
success=False,
|
|
1104
|
+
error=str(e),
|
|
1105
|
+
thought_id=thought_id,
|
|
1106
|
+
)
|
|
1107
|
+
|
|
1108
|
+
|
|
1109
|
+
async def execute_all_steps() -> AllStepsExecutionResult:
|
|
1110
|
+
"""
|
|
1111
|
+
Execute one step for all paused thoughts.
|
|
1112
|
+
|
|
1113
|
+
Returns:
|
|
1114
|
+
Status dict with count of thoughts advanced
|
|
1115
|
+
"""
|
|
1116
|
+
global _paused_thoughts
|
|
1117
|
+
|
|
1118
|
+
if not _paused_thoughts:
|
|
1119
|
+
return AllStepsExecutionResult(
|
|
1120
|
+
success=True,
|
|
1121
|
+
thoughts_advanced=0,
|
|
1122
|
+
message="No thoughts currently paused",
|
|
1123
|
+
)
|
|
1124
|
+
|
|
1125
|
+
try:
|
|
1126
|
+
# Resume all paused thoughts
|
|
1127
|
+
for event in _paused_thoughts.values():
|
|
1128
|
+
event.set()
|
|
1129
|
+
|
|
1130
|
+
count = len(_paused_thoughts)
|
|
1131
|
+
|
|
1132
|
+
return AllStepsExecutionResult(
|
|
1133
|
+
success=True,
|
|
1134
|
+
thoughts_advanced=count,
|
|
1135
|
+
message=f"Advanced {count} thoughts one step",
|
|
1136
|
+
)
|
|
1137
|
+
|
|
1138
|
+
except Exception as e:
|
|
1139
|
+
logger.error(f"Error executing steps for all thoughts: {e}")
|
|
1140
|
+
return AllStepsExecutionResult(
|
|
1141
|
+
success=False,
|
|
1142
|
+
error=str(e),
|
|
1143
|
+
thoughts_advanced=0,
|
|
1144
|
+
)
|
|
1145
|
+
|
|
1146
|
+
|
|
1147
|
+
def get_paused_thoughts() -> Dict[str, str]:
|
|
1148
|
+
"""
|
|
1149
|
+
Get list of currently paused thoughts.
|
|
1150
|
+
|
|
1151
|
+
Returns:
|
|
1152
|
+
Dict mapping thought_id to status
|
|
1153
|
+
"""
|
|
1154
|
+
global _paused_thoughts
|
|
1155
|
+
|
|
1156
|
+
return dict.fromkeys(_paused_thoughts.keys(), "paused_awaiting_resume")
|
|
1157
|
+
|
|
1158
|
+
|
|
1159
|
+
# Enhanced trace data builders for OTLP compatibility
|
|
1160
|
+
|
|
1161
|
+
|
|
1162
|
+
def _build_trace_context_dict(
|
|
1163
|
+
thought_id: str, task_id: Optional[str], step: StepPoint, start_time: Any, end_time: Any
|
|
1164
|
+
) -> TraceContext:
|
|
1165
|
+
"""
|
|
1166
|
+
Build trace context compatible with OTLP format.
|
|
1167
|
+
|
|
1168
|
+
This ensures streaming and OTLP traces have consistent trace correlation data.
|
|
1169
|
+
"""
|
|
1170
|
+
import hashlib
|
|
1171
|
+
import time
|
|
1172
|
+
|
|
1173
|
+
# Generate trace and span IDs using same logic as OTLP converter
|
|
1174
|
+
trace_base = f"{thought_id}_{task_id or 'no_task'}_{step.value}"
|
|
1175
|
+
trace_id = hashlib.sha256(trace_base.encode()).hexdigest()[:32].upper()
|
|
1176
|
+
|
|
1177
|
+
span_base = f"{trace_id}_{step.value}_{start_time.timestamp()}"
|
|
1178
|
+
span_id = hashlib.sha256(span_base.encode()).hexdigest()[:16].upper()
|
|
1179
|
+
|
|
1180
|
+
# Build parent span relationship - each step in the same thought is related
|
|
1181
|
+
parent_span_base = f"{thought_id}_pipeline_{task_id or 'no_task'}"
|
|
1182
|
+
parent_span_id = hashlib.sha256(parent_span_base.encode()).hexdigest()[:16].upper()
|
|
1183
|
+
|
|
1184
|
+
return TraceContext(
|
|
1185
|
+
trace_id=trace_id,
|
|
1186
|
+
span_id=span_id,
|
|
1187
|
+
parent_span_id=parent_span_id,
|
|
1188
|
+
span_name=f"h3ere.{step.value}",
|
|
1189
|
+
operation_name=f"H3ERE.{step.value}",
|
|
1190
|
+
start_time_ns=int(start_time.timestamp() * 1e9),
|
|
1191
|
+
end_time_ns=int(end_time.timestamp() * 1e9),
|
|
1192
|
+
duration_ns=int((end_time - start_time).total_seconds() * 1e9),
|
|
1193
|
+
span_kind="internal", # H3ERE pipeline steps are internal operations
|
|
1194
|
+
)
|
|
1195
|
+
|
|
1196
|
+
|
|
1197
|
+
def _extract_follow_up_thought_id(result: Any) -> Optional[str]:
|
|
1198
|
+
"""
|
|
1199
|
+
Extract follow-up thought ID from ACTION_COMPLETE result.
|
|
1200
|
+
|
|
1201
|
+
According to the requirement: Anything but DEFER, REJECT, or TASK_COMPLETE
|
|
1202
|
+
should have a follow-up thought created.
|
|
1203
|
+
|
|
1204
|
+
Args:
|
|
1205
|
+
result: The ACTION_COMPLETE step result (dict or object)
|
|
1206
|
+
|
|
1207
|
+
Returns:
|
|
1208
|
+
Follow-up thought ID if available, None otherwise
|
|
1209
|
+
"""
|
|
1210
|
+
# Terminal actions that don't create follow-ups
|
|
1211
|
+
TERMINAL_ACTIONS = {"DEFER", "REJECT", "TASK_COMPLETE"}
|
|
1212
|
+
|
|
1213
|
+
# Try to extract from dict format (primary path)
|
|
1214
|
+
if isinstance(result, dict):
|
|
1215
|
+
# Check action type FIRST to determine if follow-up should exist
|
|
1216
|
+
action_type = result.get("action_type", "").upper()
|
|
1217
|
+
|
|
1218
|
+
if action_type in TERMINAL_ACTIONS:
|
|
1219
|
+
# These actions should NOT have follow-ups, even if ID is present
|
|
1220
|
+
return None
|
|
1221
|
+
|
|
1222
|
+
# For non-terminal actions, extract the follow_up_thought_id
|
|
1223
|
+
return result.get("follow_up_thought_id")
|
|
1224
|
+
|
|
1225
|
+
# Try to extract from object format
|
|
1226
|
+
if hasattr(result, "follow_up_thought_id"):
|
|
1227
|
+
return str(result.follow_up_thought_id) if result.follow_up_thought_id else None
|
|
1228
|
+
|
|
1229
|
+
# Check for alternative attribute names
|
|
1230
|
+
if hasattr(result, "follow_up_id"):
|
|
1231
|
+
return str(result.follow_up_id) if result.follow_up_id else None
|
|
1232
|
+
|
|
1233
|
+
return None
|
|
1234
|
+
|
|
1235
|
+
|
|
1236
|
+
def _extract_lightweight_system_snapshot() -> SystemSnapshot:
|
|
1237
|
+
"""
|
|
1238
|
+
Extract lightweight system snapshot for reasoning event context.
|
|
1239
|
+
|
|
1240
|
+
Returns a proper SystemSnapshot object with minimal fields populated.
|
|
1241
|
+
This is used for SSE streaming and must be a concrete typed object.
|
|
1242
|
+
"""
|
|
1243
|
+
from datetime import timezone
|
|
1244
|
+
|
|
1245
|
+
# Create a minimal SystemSnapshot with current time
|
|
1246
|
+
snapshot = SystemSnapshot(
|
|
1247
|
+
current_time_utc=datetime.now(timezone.utc).isoformat(),
|
|
1248
|
+
)
|
|
1249
|
+
|
|
1250
|
+
return snapshot
|
|
1251
|
+
|
|
1252
|
+
|
|
1253
|
+
def _create_thought_start_event(
|
|
1254
|
+
step_data: StepDataUnion, timestamp: str, create_reasoning_event: Any, thought_item: Any = None
|
|
1255
|
+
) -> Any:
|
|
1256
|
+
"""Create THOUGHT_START reasoning event with thought and task metadata."""
|
|
1257
|
+
from ciris_engine.logic.persistence import get_task_by_id, get_thought_by_id
|
|
1258
|
+
from ciris_engine.schemas.services.runtime_control import ReasoningEvent
|
|
1259
|
+
|
|
1260
|
+
# Get occurrence_id from thought_item if available
|
|
1261
|
+
occurrence_id = getattr(thought_item, "agent_occurrence_id", "default") if thought_item else "default"
|
|
1262
|
+
|
|
1263
|
+
# Get full thought and task data from persistence
|
|
1264
|
+
thought = get_thought_by_id(step_data.thought_id, occurrence_id)
|
|
1265
|
+
task = get_task_by_id(step_data.task_id) if step_data.task_id else None
|
|
1266
|
+
|
|
1267
|
+
return create_reasoning_event(
|
|
1268
|
+
event_type=ReasoningEvent.THOUGHT_START,
|
|
1269
|
+
thought_id=step_data.thought_id,
|
|
1270
|
+
task_id=step_data.task_id or "",
|
|
1271
|
+
timestamp=timestamp,
|
|
1272
|
+
# Thought metadata
|
|
1273
|
+
thought_type=thought.thought_type.value if thought else "unknown",
|
|
1274
|
+
thought_content=thought.content if thought else "",
|
|
1275
|
+
thought_status=thought.status.value if thought else "unknown",
|
|
1276
|
+
round_number=thought.round_number if thought else 0,
|
|
1277
|
+
thought_depth=thought.thought_depth if thought else 0,
|
|
1278
|
+
parent_thought_id=thought.parent_thought_id if thought else None,
|
|
1279
|
+
# Task metadata
|
|
1280
|
+
task_description=task.description if task else "",
|
|
1281
|
+
task_priority=task.priority if task else 0,
|
|
1282
|
+
channel_id=task.channel_id if task else "",
|
|
1283
|
+
updated_info_available=task.updated_info_available if task else False,
|
|
1284
|
+
)
|
|
1285
|
+
|
|
1286
|
+
|
|
1287
|
+
def _create_snapshot_and_context_event(
|
|
1288
|
+
step_data: StepDataUnion, timestamp: str, create_reasoning_event: Any, thought_item: Any = None
|
|
1289
|
+
) -> Any:
|
|
1290
|
+
"""Create SNAPSHOT_AND_CONTEXT reasoning event with full system snapshot from thought context."""
|
|
1291
|
+
from ciris_engine.schemas.services.runtime_control import ReasoningEvent
|
|
1292
|
+
|
|
1293
|
+
# Extract full SystemSnapshot from thought_item.initial_context
|
|
1294
|
+
# Note: context string field removed - all data is in system_snapshot
|
|
1295
|
+
system_snapshot = None
|
|
1296
|
+
if thought_item and hasattr(thought_item, "initial_context"):
|
|
1297
|
+
initial_context = thought_item.initial_context
|
|
1298
|
+
if isinstance(initial_context, dict):
|
|
1299
|
+
# Extract system_snapshot from ProcessingThoughtContext dict
|
|
1300
|
+
system_snapshot = initial_context.get("system_snapshot")
|
|
1301
|
+
elif hasattr(initial_context, "system_snapshot"):
|
|
1302
|
+
# Extract from ProcessingThoughtContext object
|
|
1303
|
+
system_snapshot = initial_context.system_snapshot
|
|
1304
|
+
|
|
1305
|
+
# Fallback to minimal snapshot if we couldn't extract the full one
|
|
1306
|
+
if not system_snapshot:
|
|
1307
|
+
logger.warning("Could not extract full SystemSnapshot from thought_item, using minimal snapshot")
|
|
1308
|
+
system_snapshot = _extract_lightweight_system_snapshot()
|
|
1309
|
+
|
|
1310
|
+
return create_reasoning_event(
|
|
1311
|
+
event_type=ReasoningEvent.SNAPSHOT_AND_CONTEXT,
|
|
1312
|
+
thought_id=step_data.thought_id,
|
|
1313
|
+
task_id=step_data.task_id,
|
|
1314
|
+
timestamp=timestamp,
|
|
1315
|
+
system_snapshot=system_snapshot,
|
|
1316
|
+
)
|
|
1317
|
+
|
|
1318
|
+
|
|
1319
|
+
def _create_dma_results_event(
|
|
1320
|
+
step_data: StepDataUnion, timestamp: str, dma_results: Any, create_reasoning_event: Any
|
|
1321
|
+
) -> Any:
|
|
1322
|
+
"""
|
|
1323
|
+
Create DMA_RESULTS reasoning event from InitialDMAResults.
|
|
1324
|
+
|
|
1325
|
+
This event is broadcast at the START of PERFORM_ASPDMA step, using the
|
|
1326
|
+
result parameter which contains InitialDMAResults from PERFORM_DMAS.
|
|
1327
|
+
"""
|
|
1328
|
+
from ciris_engine.schemas.services.runtime_control import ReasoningEvent
|
|
1329
|
+
|
|
1330
|
+
# Extract the 3 DMA results from InitialDMAResults object - pass concrete typed objects
|
|
1331
|
+
if not dma_results:
|
|
1332
|
+
raise ValueError(f"DMA results is None or empty: {dma_results}")
|
|
1333
|
+
if not hasattr(dma_results, "csdma"):
|
|
1334
|
+
raise ValueError(
|
|
1335
|
+
f"DMA results missing 'csdma' attribute. Type: {type(dma_results)}, attributes: {dir(dma_results)}"
|
|
1336
|
+
)
|
|
1337
|
+
|
|
1338
|
+
# All 3 DMA results are required (non-optional)
|
|
1339
|
+
if not dma_results.csdma:
|
|
1340
|
+
raise ValueError(f"CSDMA result is None: {dma_results.csdma}")
|
|
1341
|
+
if not dma_results.dsdma:
|
|
1342
|
+
raise ValueError(f"DSDMA result is None: {dma_results.dsdma}")
|
|
1343
|
+
if not dma_results.ethical_pdma:
|
|
1344
|
+
raise ValueError(f"Ethical PDMA result is None: {dma_results.ethical_pdma}")
|
|
1345
|
+
|
|
1346
|
+
# Extract prompts if available (for debugging/transparency)
|
|
1347
|
+
csdma_prompt = getattr(dma_results, "csdma_prompt", None)
|
|
1348
|
+
dsdma_prompt = getattr(dma_results, "dsdma_prompt", None)
|
|
1349
|
+
pdma_prompt = getattr(dma_results, "ethical_pdma_prompt", None)
|
|
1350
|
+
|
|
1351
|
+
return create_reasoning_event(
|
|
1352
|
+
event_type=ReasoningEvent.DMA_RESULTS,
|
|
1353
|
+
thought_id=step_data.thought_id,
|
|
1354
|
+
task_id=step_data.task_id,
|
|
1355
|
+
timestamp=timestamp,
|
|
1356
|
+
csdma=dma_results.csdma, # Pass CSDMAResult object directly
|
|
1357
|
+
dsdma=dma_results.dsdma, # Pass DSDMAResult object directly
|
|
1358
|
+
pdma=dma_results.ethical_pdma, # Pass EthicalDMAResult object directly
|
|
1359
|
+
csdma_prompt=csdma_prompt, # User prompt passed to CSDMA
|
|
1360
|
+
dsdma_prompt=dsdma_prompt, # User prompt passed to DSDMA
|
|
1361
|
+
pdma_prompt=pdma_prompt, # User prompt passed to PDMA
|
|
1362
|
+
)
|
|
1363
|
+
|
|
1364
|
+
|
|
1365
|
+
def _create_aspdma_result_event(
|
|
1366
|
+
step_data: StepDataUnion, timestamp: str, is_recursive: bool, create_reasoning_event: Any
|
|
1367
|
+
) -> Any:
|
|
1368
|
+
"""Create ASPDMA_RESULT reasoning event."""
|
|
1369
|
+
from ciris_engine.schemas.services.runtime_control import ReasoningEvent
|
|
1370
|
+
|
|
1371
|
+
# Extract ASPDMA prompt if available (from ConscienceExecutionStepData)
|
|
1372
|
+
aspdma_prompt = getattr(step_data, "aspdma_prompt", None)
|
|
1373
|
+
|
|
1374
|
+
return create_reasoning_event(
|
|
1375
|
+
event_type=ReasoningEvent.ASPDMA_RESULT,
|
|
1376
|
+
thought_id=step_data.thought_id,
|
|
1377
|
+
task_id=step_data.task_id,
|
|
1378
|
+
timestamp=timestamp,
|
|
1379
|
+
is_recursive=is_recursive,
|
|
1380
|
+
selected_action=getattr(step_data, "selected_action", ""),
|
|
1381
|
+
action_rationale=getattr(step_data, "action_rationale", ""),
|
|
1382
|
+
aspdma_prompt=aspdma_prompt, # User prompt passed to ASPDMA
|
|
1383
|
+
)
|
|
1384
|
+
|
|
1385
|
+
|
|
1386
|
+
def _create_conscience_result_event(step_data: StepDataUnion, timestamp: str, create_reasoning_event: Any) -> Any:
|
|
1387
|
+
"""Create CONSCIENCE_RESULT reasoning event."""
|
|
1388
|
+
from ciris_engine.schemas.services.runtime_control import ReasoningEvent
|
|
1389
|
+
|
|
1390
|
+
return create_reasoning_event(
|
|
1391
|
+
event_type=ReasoningEvent.CONSCIENCE_RESULT,
|
|
1392
|
+
thought_id=step_data.thought_id,
|
|
1393
|
+
task_id=step_data.task_id,
|
|
1394
|
+
timestamp=timestamp,
|
|
1395
|
+
is_recursive=False, # FINALIZE_ACTION is never recursive
|
|
1396
|
+
conscience_passed=getattr(step_data, "conscience_passed", True),
|
|
1397
|
+
conscience_override_reason=getattr(step_data, "conscience_override_reason", None),
|
|
1398
|
+
epistemic_data=getattr(step_data, "epistemic_data", {}),
|
|
1399
|
+
final_action=getattr(step_data, "selected_action", ""),
|
|
1400
|
+
action_was_overridden=not getattr(step_data, "conscience_passed", True),
|
|
1401
|
+
updated_status_available=getattr(step_data, "updated_status_detected", None),
|
|
1402
|
+
)
|
|
1403
|
+
|
|
1404
|
+
|
|
1405
|
+
def _create_action_result_event(step_data: StepDataUnion, timestamp: str, create_reasoning_event: Any) -> Any:
|
|
1406
|
+
"""Create ACTION_RESULT reasoning event with audit trail, resource usage, and follow-up data."""
|
|
1407
|
+
from ciris_engine.schemas.services.runtime_control import ReasoningEvent
|
|
1408
|
+
|
|
1409
|
+
# Extract follow_up_thought_id from step_data (already populated from dispatch_result)
|
|
1410
|
+
follow_up_thought_id = getattr(step_data, "follow_up_thought_id", None)
|
|
1411
|
+
|
|
1412
|
+
return create_reasoning_event(
|
|
1413
|
+
event_type=ReasoningEvent.ACTION_RESULT,
|
|
1414
|
+
thought_id=step_data.thought_id,
|
|
1415
|
+
task_id=step_data.task_id,
|
|
1416
|
+
timestamp=timestamp,
|
|
1417
|
+
action_executed=getattr(step_data, "action_executed", ""),
|
|
1418
|
+
execution_success=getattr(step_data, "dispatch_success", True),
|
|
1419
|
+
execution_time_ms=getattr(step_data, "execution_time_ms", 0.0),
|
|
1420
|
+
follow_up_thought_id=follow_up_thought_id,
|
|
1421
|
+
error=None,
|
|
1422
|
+
audit_entry_id=getattr(step_data, "audit_entry_id", None),
|
|
1423
|
+
audit_sequence_number=getattr(step_data, "audit_sequence_number", None),
|
|
1424
|
+
audit_entry_hash=getattr(step_data, "audit_entry_hash", None),
|
|
1425
|
+
audit_signature=getattr(step_data, "audit_signature", None),
|
|
1426
|
+
# Resource usage fields (queried from telemetry by thought_id)
|
|
1427
|
+
tokens_total=getattr(step_data, "tokens_total", 0),
|
|
1428
|
+
tokens_input=getattr(step_data, "tokens_input", 0),
|
|
1429
|
+
tokens_output=getattr(step_data, "tokens_output", 0),
|
|
1430
|
+
cost_cents=getattr(step_data, "cost_cents", 0.0),
|
|
1431
|
+
carbon_grams=getattr(step_data, "carbon_grams", 0.0),
|
|
1432
|
+
energy_mwh=getattr(step_data, "energy_mwh", 0.0),
|
|
1433
|
+
llm_calls=getattr(step_data, "llm_calls", 0),
|
|
1434
|
+
models_used=getattr(step_data, "models_used", []),
|
|
1435
|
+
)
|
|
1436
|
+
|
|
1437
|
+
|
|
1438
|
+
def _build_span_attributes_dict(step: StepPoint, step_result: Any, step_data: StepDataUnion) -> List[SpanAttribute]:
|
|
1439
|
+
"""
|
|
1440
|
+
Build span attributes compatible with OTLP format.
|
|
1441
|
+
|
|
1442
|
+
This creates rich attribute data that's consistent between streaming and OTLP traces.
|
|
1443
|
+
"""
|
|
1444
|
+
thought_id = step_data.thought_id
|
|
1445
|
+
task_id = step_data.task_id
|
|
1446
|
+
|
|
1447
|
+
# Start with core CIRIS attributes (matching OTLP format)
|
|
1448
|
+
attributes = [
|
|
1449
|
+
SpanAttribute(key="ciris.step_point", value={"stringValue": step.value}),
|
|
1450
|
+
SpanAttribute(key="ciris.thought_id", value={"stringValue": thought_id}),
|
|
1451
|
+
SpanAttribute(key="operation.name", value={"stringValue": f"H3ERE.{step.value}"}),
|
|
1452
|
+
SpanAttribute(key="service.name", value={"stringValue": "ciris-h3ere-pipeline"}),
|
|
1453
|
+
SpanAttribute(key="service.component", value={"stringValue": "thought_processor"}),
|
|
1454
|
+
SpanAttribute(key="span.success", value={"boolValue": step_data.success}),
|
|
1455
|
+
SpanAttribute(key="processing_time_ms", value={"doubleValue": step_data.processing_time_ms}),
|
|
1456
|
+
]
|
|
1457
|
+
|
|
1458
|
+
# Add task_id if available - critical for correlation
|
|
1459
|
+
if task_id:
|
|
1460
|
+
attributes.append(SpanAttribute(key="ciris.task_id", value={"stringValue": str(task_id)}))
|
|
1461
|
+
|
|
1462
|
+
# Add step-specific attributes based on the typed step result
|
|
1463
|
+
if step_result and hasattr(step_result, "model_dump"):
|
|
1464
|
+
result_data = step_result.model_dump()
|
|
1465
|
+
_add_typed_step_attributes(attributes, step, result_data)
|
|
1466
|
+
|
|
1467
|
+
# Add error information if present
|
|
1468
|
+
error = step_data.error
|
|
1469
|
+
if error:
|
|
1470
|
+
attributes.extend(
|
|
1471
|
+
[
|
|
1472
|
+
SpanAttribute(key="error", value={"boolValue": True}),
|
|
1473
|
+
SpanAttribute(key="error.message", value={"stringValue": str(error)}),
|
|
1474
|
+
SpanAttribute(key="error.type", value={"stringValue": "ProcessingError"}),
|
|
1475
|
+
]
|
|
1476
|
+
)
|
|
1477
|
+
else:
|
|
1478
|
+
attributes.append(SpanAttribute(key="error", value={"boolValue": False}))
|
|
1479
|
+
|
|
1480
|
+
return attributes
|
|
1481
|
+
|
|
1482
|
+
|
|
1483
|
+
def _add_gather_context_attributes(attributes: List[SpanAttribute], result_data: JSONDict) -> None: # NOQA
|
|
1484
|
+
"""Add attributes specific to GATHER_CONTEXT step."""
|
|
1485
|
+
if "context" in result_data and result_data["context"]:
|
|
1486
|
+
context_size = len(str(result_data["context"]))
|
|
1487
|
+
attributes.extend(
|
|
1488
|
+
[
|
|
1489
|
+
SpanAttribute(key="context.size_bytes", value={"intValue": context_size}),
|
|
1490
|
+
SpanAttribute(key="context.available", value={"boolValue": True}),
|
|
1491
|
+
]
|
|
1492
|
+
)
|
|
1493
|
+
|
|
1494
|
+
|
|
1495
|
+
def _add_perform_dmas_attributes(attributes: List[SpanAttribute], result_data: JSONDict) -> None: # NOQA
|
|
1496
|
+
"""Add attributes specific to PERFORM_DMAS step."""
|
|
1497
|
+
if "dma_results" in result_data and result_data["dma_results"]:
|
|
1498
|
+
attributes.extend(
|
|
1499
|
+
[
|
|
1500
|
+
SpanAttribute(key="dma.results_available", value={"boolValue": True}),
|
|
1501
|
+
SpanAttribute(key="dma.results_size", value={"intValue": len(str(result_data["dma_results"]))}),
|
|
1502
|
+
]
|
|
1503
|
+
)
|
|
1504
|
+
if "context" in result_data:
|
|
1505
|
+
attributes.append(SpanAttribute(key="dma.context_provided", value={"boolValue": bool(result_data["context"])}))
|
|
1506
|
+
|
|
1507
|
+
|
|
1508
|
+
def _add_perform_aspdma_attributes(attributes: List[SpanAttribute], result_data: JSONDict) -> None: # NOQA
|
|
1509
|
+
"""Add attributes specific to PERFORM_ASPDMA step."""
|
|
1510
|
+
if "selected_action" in result_data:
|
|
1511
|
+
attributes.append(
|
|
1512
|
+
SpanAttribute(key="action.selected", value={"stringValue": str(result_data["selected_action"])})
|
|
1513
|
+
)
|
|
1514
|
+
if "action_rationale" in result_data:
|
|
1515
|
+
attributes.append(
|
|
1516
|
+
SpanAttribute(key="action.has_rationale", value={"boolValue": bool(result_data["action_rationale"])})
|
|
1517
|
+
)
|
|
1518
|
+
|
|
1519
|
+
|
|
1520
|
+
def _add_conscience_execution_attributes(attributes: List[SpanAttribute], result_data: JSONDict) -> None: # NOQA
|
|
1521
|
+
"""Add attributes specific to CONSCIENCE_EXECUTION step."""
|
|
1522
|
+
if "conscience_passed" in result_data:
|
|
1523
|
+
attributes.append(SpanAttribute(key="conscience.passed", value={"boolValue": result_data["conscience_passed"]}))
|
|
1524
|
+
if "selected_action" in result_data:
|
|
1525
|
+
attributes.append(
|
|
1526
|
+
SpanAttribute(key="conscience.action", value={"stringValue": str(result_data["selected_action"])})
|
|
1527
|
+
)
|
|
1528
|
+
|
|
1529
|
+
|
|
1530
|
+
def _add_finalize_action_attributes(attributes: List[SpanAttribute], result_data: JSONDict) -> None: # NOQA
|
|
1531
|
+
"""Add attributes specific to FINALIZE_ACTION step."""
|
|
1532
|
+
if "selected_action" in result_data:
|
|
1533
|
+
attributes.append(
|
|
1534
|
+
SpanAttribute(key="finalized.action", value={"stringValue": str(result_data["selected_action"])})
|
|
1535
|
+
)
|
|
1536
|
+
if "selection_reasoning" in result_data:
|
|
1537
|
+
attributes.append(
|
|
1538
|
+
SpanAttribute(key="finalized.has_reasoning", value={"boolValue": bool(result_data["selection_reasoning"])})
|
|
1539
|
+
)
|
|
1540
|
+
|
|
1541
|
+
|
|
1542
|
+
def _add_perform_action_attributes(attributes: List[SpanAttribute], result_data: JSONDict) -> None: # NOQA
|
|
1543
|
+
"""Add attributes specific to PERFORM_ACTION step."""
|
|
1544
|
+
if "action_executed" in result_data:
|
|
1545
|
+
attributes.append(
|
|
1546
|
+
SpanAttribute(key="action.executed", value={"stringValue": str(result_data["action_executed"])})
|
|
1547
|
+
)
|
|
1548
|
+
if "dispatch_success" in result_data:
|
|
1549
|
+
attributes.append(
|
|
1550
|
+
SpanAttribute(key="action.dispatch_success", value={"boolValue": result_data["dispatch_success"]})
|
|
1551
|
+
)
|
|
1552
|
+
|
|
1553
|
+
|
|
1554
|
+
def _add_action_complete_attributes(attributes: List[SpanAttribute], result_data: JSONDict) -> None: # NOQA
|
|
1555
|
+
"""Add attributes specific to ACTION_COMPLETE step."""
|
|
1556
|
+
if "handler_completed" in result_data:
|
|
1557
|
+
attributes.append(
|
|
1558
|
+
SpanAttribute(key="action.handler_completed", value={"boolValue": result_data["handler_completed"]})
|
|
1559
|
+
)
|
|
1560
|
+
if "execution_time_ms" in result_data:
|
|
1561
|
+
attributes.append(
|
|
1562
|
+
SpanAttribute(key="action.execution_time_ms", value={"doubleValue": result_data["execution_time_ms"]})
|
|
1563
|
+
)
|
|
1564
|
+
|
|
1565
|
+
|
|
1566
|
+
def _add_typed_step_attributes(attributes: List[SpanAttribute], step: StepPoint, result_data: JSONDict) -> None: # NOQA
|
|
1567
|
+
"""Add step-specific attributes based on typed step result data."""
|
|
1568
|
+
|
|
1569
|
+
# Map step types to their handler functions
|
|
1570
|
+
step_attribute_handlers = {
|
|
1571
|
+
StepPoint.GATHER_CONTEXT: _add_gather_context_attributes,
|
|
1572
|
+
StepPoint.PERFORM_DMAS: _add_perform_dmas_attributes,
|
|
1573
|
+
StepPoint.PERFORM_ASPDMA: _add_perform_aspdma_attributes,
|
|
1574
|
+
StepPoint.CONSCIENCE_EXECUTION: _add_conscience_execution_attributes,
|
|
1575
|
+
StepPoint.FINALIZE_ACTION: _add_finalize_action_attributes,
|
|
1576
|
+
StepPoint.PERFORM_ACTION: _add_perform_action_attributes,
|
|
1577
|
+
StepPoint.ACTION_COMPLETE: _add_action_complete_attributes,
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1580
|
+
# Call the appropriate handler function if one exists
|
|
1581
|
+
handler = step_attribute_handlers.get(step)
|
|
1582
|
+
if handler:
|
|
1583
|
+
handler(attributes, result_data)
|