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.
Files changed (986) hide show
  1. ciris_adapters/README.md +113 -0
  2. ciris_adapters/__init__.py +30 -0
  3. ciris_adapters/ciris_covenant_metrics/README.md +144 -0
  4. ciris_adapters/ciris_covenant_metrics/__init__.py +36 -0
  5. ciris_adapters/ciris_covenant_metrics/adapter.py +249 -0
  6. ciris_adapters/ciris_covenant_metrics/manifest.json +152 -0
  7. ciris_adapters/ciris_covenant_metrics/services.py +403 -0
  8. ciris_adapters/ciris_hosted_tools/__init__.py +24 -0
  9. ciris_adapters/ciris_hosted_tools/adapter.py +169 -0
  10. ciris_adapters/ciris_hosted_tools/manifest.json +94 -0
  11. ciris_adapters/ciris_hosted_tools/services.py +744 -0
  12. ciris_adapters/external_data_sql/README.md +559 -0
  13. ciris_adapters/external_data_sql/__init__.py +43 -0
  14. ciris_adapters/external_data_sql/adapter.py +144 -0
  15. ciris_adapters/external_data_sql/configurable.py +315 -0
  16. ciris_adapters/external_data_sql/dialects/__init__.py +37 -0
  17. ciris_adapters/external_data_sql/dialects/base.py +133 -0
  18. ciris_adapters/external_data_sql/dialects/mysql.py +63 -0
  19. ciris_adapters/external_data_sql/dialects/postgresql.py +59 -0
  20. ciris_adapters/external_data_sql/dialects/sqlite.py +62 -0
  21. ciris_adapters/external_data_sql/example_config.json +88 -0
  22. ciris_adapters/external_data_sql/example_privacy_schema.yaml +127 -0
  23. ciris_adapters/external_data_sql/manifest.json +195 -0
  24. ciris_adapters/external_data_sql/privacy_schema_loader.py +189 -0
  25. ciris_adapters/external_data_sql/protocol.py +101 -0
  26. ciris_adapters/external_data_sql/schemas.py +146 -0
  27. ciris_adapters/external_data_sql/service.py +1547 -0
  28. ciris_adapters/external_data_sql/service_old.py +492 -0
  29. ciris_adapters/home_assistant/__init__.py +63 -0
  30. ciris_adapters/home_assistant/adapter.py +201 -0
  31. ciris_adapters/home_assistant/communication_service.py +347 -0
  32. ciris_adapters/home_assistant/configurable.py +667 -0
  33. ciris_adapters/home_assistant/manifest.json +203 -0
  34. ciris_adapters/home_assistant/schemas.py +129 -0
  35. ciris_adapters/home_assistant/service.py +751 -0
  36. ciris_adapters/home_assistant/tool_service.py +441 -0
  37. ciris_adapters/mcp_client/__init__.py +82 -0
  38. ciris_adapters/mcp_client/adapter.py +847 -0
  39. ciris_adapters/mcp_client/config.py +280 -0
  40. ciris_adapters/mcp_client/configurable.py +422 -0
  41. ciris_adapters/mcp_client/manifest.json +185 -0
  42. ciris_adapters/mcp_client/mcp_communication_service.py +393 -0
  43. ciris_adapters/mcp_client/mcp_tool_service.py +463 -0
  44. ciris_adapters/mcp_client/mcp_wise_service.py +394 -0
  45. ciris_adapters/mcp_client/schemas.py +149 -0
  46. ciris_adapters/mcp_client/security.py +592 -0
  47. ciris_adapters/mcp_common/__init__.py +44 -0
  48. ciris_adapters/mcp_common/manifest.json +25 -0
  49. ciris_adapters/mcp_common/protocol.py +315 -0
  50. ciris_adapters/mcp_common/schemas.py +225 -0
  51. ciris_adapters/mcp_server/__init__.py +47 -0
  52. ciris_adapters/mcp_server/adapter.py +581 -0
  53. ciris_adapters/mcp_server/config.py +260 -0
  54. ciris_adapters/mcp_server/configurable.py +393 -0
  55. ciris_adapters/mcp_server/handlers.py +663 -0
  56. ciris_adapters/mcp_server/manifest.json +211 -0
  57. ciris_adapters/mcp_server/security.py +500 -0
  58. ciris_adapters/mock_llm/README.md +117 -0
  59. ciris_adapters/mock_llm/__init__.py +21 -0
  60. ciris_adapters/mock_llm/adapter.py +131 -0
  61. ciris_adapters/mock_llm/configurable.py +237 -0
  62. ciris_adapters/mock_llm/manifest.json +106 -0
  63. ciris_adapters/mock_llm/protocol.py +37 -0
  64. ciris_adapters/mock_llm/responses.py +520 -0
  65. ciris_adapters/mock_llm/responses_action_selection.py +1041 -0
  66. ciris_adapters/mock_llm/responses_epistemic.py +17 -0
  67. ciris_adapters/mock_llm/responses_feedback.py +27 -0
  68. ciris_adapters/mock_llm/schemas.py +35 -0
  69. ciris_adapters/mock_llm/service.py +294 -0
  70. ciris_adapters/navigation/__init__.py +21 -0
  71. ciris_adapters/navigation/adapter.py +129 -0
  72. ciris_adapters/navigation/configurable.py +239 -0
  73. ciris_adapters/navigation/manifest.json +104 -0
  74. ciris_adapters/navigation/service.py +487 -0
  75. ciris_adapters/reddit/README.md +132 -0
  76. ciris_adapters/reddit/REDDIT_ADAPTER_ANALYSIS.md +715 -0
  77. ciris_adapters/reddit/REDDIT_ADAPTER_SUMMARY.txt +278 -0
  78. ciris_adapters/reddit/REDDIT_ANALYSIS_INDEX.md +307 -0
  79. ciris_adapters/reddit/REDDIT_PRODUCTION_READINESS_PLAN.md +518 -0
  80. ciris_adapters/reddit/__init__.py +15 -0
  81. ciris_adapters/reddit/adapter.py +189 -0
  82. ciris_adapters/reddit/configurable.py +274 -0
  83. ciris_adapters/reddit/error_handler.py +307 -0
  84. ciris_adapters/reddit/manifest.json +218 -0
  85. ciris_adapters/reddit/observer.py +532 -0
  86. ciris_adapters/reddit/protocol.py +34 -0
  87. ciris_adapters/reddit/schemas.py +433 -0
  88. ciris_adapters/reddit/service.py +1471 -0
  89. ciris_adapters/sample_adapter/README.md +474 -0
  90. ciris_adapters/sample_adapter/__init__.py +45 -0
  91. ciris_adapters/sample_adapter/adapter.py +208 -0
  92. ciris_adapters/sample_adapter/configurable.py +469 -0
  93. ciris_adapters/sample_adapter/manifest.json +247 -0
  94. ciris_adapters/sample_adapter/services.py +486 -0
  95. ciris_adapters/weather/__init__.py +16 -0
  96. ciris_adapters/weather/adapter.py +130 -0
  97. ciris_adapters/weather/configurable.py +240 -0
  98. ciris_adapters/weather/manifest.json +156 -0
  99. ciris_adapters/weather/service.py +600 -0
  100. ciris_agent-1.7.7.dist-info/METADATA +284 -0
  101. ciris_agent-1.7.7.dist-info/RECORD +986 -0
  102. ciris_agent-1.7.7.dist-info/WHEEL +5 -0
  103. ciris_agent-1.7.7.dist-info/entry_points.txt +15 -0
  104. ciris_agent-1.7.7.dist-info/licenses/LICENSE +205 -0
  105. ciris_agent-1.7.7.dist-info/licenses/NOTICE +82 -0
  106. ciris_agent-1.7.7.dist-info/top_level.txt +4 -0
  107. ciris_engine/__init__.py +15 -0
  108. ciris_engine/ciris_templates/ally.yaml +632 -0
  109. ciris_engine/ciris_templates/default.yaml +411 -0
  110. ciris_engine/ciris_templates/echo-core.yaml +629 -0
  111. ciris_engine/ciris_templates/echo-speculative.yaml +764 -0
  112. ciris_engine/ciris_templates/echo.yaml +647 -0
  113. ciris_engine/ciris_templates/sage.yaml +332 -0
  114. ciris_engine/ciris_templates/scout.yaml +338 -0
  115. ciris_engine/ciris_templates/test.yaml +168 -0
  116. ciris_engine/cli.py +42 -0
  117. ciris_engine/config/CIRIS_SERVICES.json +19 -0
  118. ciris_engine/config/MODEL_CAPABILITIES.json +419 -0
  119. ciris_engine/config/PRICING_DATA.json +179 -0
  120. ciris_engine/config/__init__.py +50 -0
  121. ciris_engine/config/ciris_services.py +113 -0
  122. ciris_engine/config/model_capabilities.py +388 -0
  123. ciris_engine/config/pricing_models.py +276 -0
  124. ciris_engine/constants.py +35 -0
  125. ciris_engine/data/__init__.py +1 -0
  126. ciris_engine/data/covenant_1.0b.txt +978 -0
  127. ciris_engine/gui_static/11steps.svg +107 -0
  128. ciris_engine/gui_static/2x-schematics.png +0 -0
  129. ciris_engine/gui_static/404/index.html +1 -0
  130. ciris_engine/gui_static/404.html +1 -0
  131. ciris_engine/gui_static/_next/static/0edhkwDxd5UccTsCmtaBi/_buildManifest.js +1 -0
  132. ciris_engine/gui_static/_next/static/0edhkwDxd5UccTsCmtaBi/_ssgManifest.js +1 -0
  133. ciris_engine/gui_static/_next/static/U-3xTQao7hc2wnAi-Uekm/_buildManifest.js +1 -0
  134. ciris_engine/gui_static/_next/static/U-3xTQao7hc2wnAi-Uekm/_ssgManifest.js +1 -0
  135. ciris_engine/gui_static/_next/static/chunks/3297-60e86ba0f8a7b040.js +1 -0
  136. ciris_engine/gui_static/_next/static/chunks/3835-2aad4b7f5f8e4643.js +1 -0
  137. ciris_engine/gui_static/_next/static/chunks/4499-99a0bc47de0b8975.js +1 -0
  138. ciris_engine/gui_static/_next/static/chunks/4534-af88cd4ba6e99bff.js +1 -0
  139. ciris_engine/gui_static/_next/static/chunks/4541-84b455f9e0dc4cfe.js +1 -0
  140. ciris_engine/gui_static/_next/static/chunks/4789-61412711484754bb.js +1 -0
  141. ciris_engine/gui_static/_next/static/chunks/6539-c6398bc9d7018430.js +1 -0
  142. ciris_engine/gui_static/_next/static/chunks/704-8e827b26cc8c2d32.js +1 -0
  143. ciris_engine/gui_static/_next/static/chunks/704-fb45d630f3192c6f.js +1 -0
  144. ciris_engine/gui_static/_next/static/chunks/8072-de4952a2e6d2b33f.js +1 -0
  145. ciris_engine/gui_static/_next/static/chunks/8315-b91d03a3949db0af.js +1 -0
  146. ciris_engine/gui_static/_next/static/chunks/8386-f93a83ccbd789bd9.js +1 -0
  147. ciris_engine/gui_static/_next/static/chunks/87c73c54-781a7f35148d5433.js +1 -0
  148. ciris_engine/gui_static/_next/static/chunks/8903-fefea3339a02d41b.js +1 -0
  149. ciris_engine/gui_static/_next/static/chunks/9090-e66485adf8d9d990.js +1 -0
  150. ciris_engine/gui_static/_next/static/chunks/app/_not-found/page-a67d9808462c23b1.js +1 -0
  151. ciris_engine/gui_static/_next/static/chunks/app/account/api-keys/page-2d7ee1583bbbd02e.js +1 -0
  152. ciris_engine/gui_static/_next/static/chunks/app/account/api-keys/page-6a3c2bae6fe92b7b.js +1 -0
  153. ciris_engine/gui_static/_next/static/chunks/app/account/consent/page-2ed3a035136bc4e8.js +1 -0
  154. ciris_engine/gui_static/_next/static/chunks/app/account/consent/page-b2f5c91844a32422.js +1 -0
  155. ciris_engine/gui_static/_next/static/chunks/app/account/page-25b90f89af3ea58c.js +1 -0
  156. ciris_engine/gui_static/_next/static/chunks/app/account/page-b65d16c94ecaf69c.js +1 -0
  157. ciris_engine/gui_static/_next/static/chunks/app/account/privacy/page-675b6d05c8f9184f.js +1 -0
  158. ciris_engine/gui_static/_next/static/chunks/app/account/privacy/page-cbee2e1c8ab52145.js +1 -0
  159. ciris_engine/gui_static/_next/static/chunks/app/account/settings/page-0f44da06697cf9f0.js +1 -0
  160. ciris_engine/gui_static/_next/static/chunks/app/account/settings/page-563420253577edbf.js +1 -0
  161. ciris_engine/gui_static/_next/static/chunks/app/adapters/page-1854631018bc32be.js +1 -0
  162. ciris_engine/gui_static/_next/static/chunks/app/agents/page-8353752c176a7c70.js +1 -0
  163. ciris_engine/gui_static/_next/static/chunks/app/agents/page-f61a529f110a6040.js +1 -0
  164. ciris_engine/gui_static/_next/static/chunks/app/api-demo/page-7f19b9d20d39be28.js +1 -0
  165. ciris_engine/gui_static/_next/static/chunks/app/api-demo/page-d1063938f249b8bd.js +1 -0
  166. ciris_engine/gui_static/_next/static/chunks/app/audit/page-321b6728b8fff0bb.js +1 -0
  167. ciris_engine/gui_static/_next/static/chunks/app/audit/page-ebac35ca961a1277.js +1 -0
  168. ciris_engine/gui_static/_next/static/chunks/app/billing/page-6f3dc3bd02924f8e.js +1 -0
  169. ciris_engine/gui_static/_next/static/chunks/app/billing/page-fa4a469f814c821a.js +1 -0
  170. ciris_engine/gui_static/_next/static/chunks/app/comms/page-0d4f734269addd8f.js +1 -0
  171. ciris_engine/gui_static/_next/static/chunks/app/comms/page-79227d426050089c.js +1 -0
  172. ciris_engine/gui_static/_next/static/chunks/app/config/page-018d21d683b6e5bc.js +1 -0
  173. ciris_engine/gui_static/_next/static/chunks/app/config/page-2aa5a5363ca2a371.js +1 -0
  174. ciris_engine/gui_static/_next/static/chunks/app/consent/page-198373205fd316e2.js +1 -0
  175. ciris_engine/gui_static/_next/static/chunks/app/consent/page-f2ca39e7713b13f8.js +1 -0
  176. ciris_engine/gui_static/_next/static/chunks/app/dashboard/page-1dd5a196f643c60d.js +1 -0
  177. ciris_engine/gui_static/_next/static/chunks/app/dashboard/page-530a04d3abbb8cda.js +1 -0
  178. ciris_engine/gui_static/_next/static/chunks/app/docs/page-3193b06d094ab654.js +1 -0
  179. ciris_engine/gui_static/_next/static/chunks/app/docs/page-330e996dedb87aba.js +1 -0
  180. ciris_engine/gui_static/_next/static/chunks/app/layout-0a70f5fc460298b1.js +1 -0
  181. ciris_engine/gui_static/_next/static/chunks/app/layout-21f2f99dd5b336e9.js +1 -0
  182. ciris_engine/gui_static/_next/static/chunks/app/login/page-33240e6c6034a49d.js +1 -0
  183. ciris_engine/gui_static/_next/static/chunks/app/login/page-68ffab6d54a7fdcd.js +1 -0
  184. ciris_engine/gui_static/_next/static/chunks/app/logs/page-8a6167aecc4a475c.js +1 -0
  185. ciris_engine/gui_static/_next/static/chunks/app/memory/page-9ca8c5d0056de3ff.js +1 -0
  186. ciris_engine/gui_static/_next/static/chunks/app/memory/page-e961226941c18f81.js +1 -0
  187. ciris_engine/gui_static/_next/static/chunks/app/page-6fdb065a787a4974.js +1 -0
  188. ciris_engine/gui_static/_next/static/chunks/app/page-89f87d431be6064a.js +1 -0
  189. ciris_engine/gui_static/_next/static/chunks/app/runtime/page-2e728b9c43aa164d.js +1 -0
  190. ciris_engine/gui_static/_next/static/chunks/app/runtime/page-c7dd033dc40a72f0.js +1 -0
  191. ciris_engine/gui_static/_next/static/chunks/app/services/page-ae9f0bdf11d01a95.js +1 -0
  192. ciris_engine/gui_static/_next/static/chunks/app/services/page-b10feb79ca5d75e5.js +1 -0
  193. ciris_engine/gui_static/_next/static/chunks/app/sessions/page-13ebe7ef1c16ae11.js +1 -0
  194. ciris_engine/gui_static/_next/static/chunks/app/sessions/page-e6c82b16d617f785.js +1 -0
  195. ciris_engine/gui_static/_next/static/chunks/app/setup/page-0beb5f5b5a5c20fc.js +1 -0
  196. ciris_engine/gui_static/_next/static/chunks/app/setup/page-2595e729eae30c0e.js +1 -0
  197. ciris_engine/gui_static/_next/static/chunks/app/status-dashboard/page-1037c987aecc3653.js +1 -0
  198. ciris_engine/gui_static/_next/static/chunks/app/status-dashboard/page-2ffd147f6d3162ff.js +1 -0
  199. ciris_engine/gui_static/_next/static/chunks/app/system/page-2c5798d58cafcd91.js +1 -0
  200. ciris_engine/gui_static/_next/static/chunks/app/system/page-505b1ba4eceb01c3.js +1 -0
  201. ciris_engine/gui_static/_next/static/chunks/app/test-auth/page-b0cad31d5cb1b2fa.js +1 -0
  202. ciris_engine/gui_static/_next/static/chunks/app/test-auth/page-f3ecd7a8012df230.js +1 -0
  203. ciris_engine/gui_static/_next/static/chunks/app/test-login/page-f35117fdc4105801.js +1 -0
  204. ciris_engine/gui_static/_next/static/chunks/app/test-login/page-fb583a7924114906.js +1 -0
  205. ciris_engine/gui_static/_next/static/chunks/app/test-sdk/page-50f116fd76935563.js +1 -0
  206. ciris_engine/gui_static/_next/static/chunks/app/test-sdk/page-c37d8aa5ba623a44.js +1 -0
  207. ciris_engine/gui_static/_next/static/chunks/app/tools/page-429aec7a707777ef.js +1 -0
  208. ciris_engine/gui_static/_next/static/chunks/app/tools/page-5f705aad60e0c04e.js +1 -0
  209. ciris_engine/gui_static/_next/static/chunks/app/users/page-13476b8b0f3808cc.js +1 -0
  210. ciris_engine/gui_static/_next/static/chunks/app/users/page-7e500d154ed5bba4.js +1 -0
  211. ciris_engine/gui_static/_next/static/chunks/app/wa/page-cc4a9d8a5cb44d08.js +1 -0
  212. ciris_engine/gui_static/_next/static/chunks/app/wa/page-ec3e429efbc79230.js +1 -0
  213. ciris_engine/gui_static/_next/static/chunks/framework-9d29490f5ba089ba.js +1 -0
  214. ciris_engine/gui_static/_next/static/chunks/main-1f554952e47a82c4.js +1 -0
  215. ciris_engine/gui_static/_next/static/chunks/main-app-26fa8aed029082e5.js +1 -0
  216. ciris_engine/gui_static/_next/static/chunks/main-app-97b0486ef6bcef25.js +1 -0
  217. ciris_engine/gui_static/_next/static/chunks/pages/_app-6ce685456e616eb2.js +1 -0
  218. ciris_engine/gui_static/_next/static/chunks/pages/_error-d4bce98d93fe21e7.js +1 -0
  219. ciris_engine/gui_static/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  220. ciris_engine/gui_static/_next/static/chunks/webpack-fcebd240b7f8477d.js +1 -0
  221. ciris_engine/gui_static/_next/static/css/16b94b1fe0cc6e37.css +3 -0
  222. ciris_engine/gui_static/_next/static/css/77a24ceaae86deff.css +3 -0
  223. ciris_engine/gui_static/_next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  224. ciris_engine/gui_static/_next/static/media/747892c23ea88013-s.woff2 +0 -0
  225. ciris_engine/gui_static/_next/static/media/8d697b304b401681-s.woff2 +0 -0
  226. ciris_engine/gui_static/_next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  227. ciris_engine/gui_static/_next/static/media/9610d9e46709d722-s.woff2 +0 -0
  228. ciris_engine/gui_static/_next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  229. ciris_engine/gui_static/_next/static/media/d8298875641ec7d4-s.p.woff2 +0 -0
  230. ciris_engine/gui_static/account/api-keys/index.html +1 -0
  231. ciris_engine/gui_static/account/api-keys/index.txt +27 -0
  232. ciris_engine/gui_static/account/consent/index.html +1 -0
  233. ciris_engine/gui_static/account/consent/index.txt +27 -0
  234. ciris_engine/gui_static/account/index.html +1 -0
  235. ciris_engine/gui_static/account/index.txt +27 -0
  236. ciris_engine/gui_static/account/privacy/index.html +1 -0
  237. ciris_engine/gui_static/account/privacy/index.txt +27 -0
  238. ciris_engine/gui_static/account/settings/index.html +1 -0
  239. ciris_engine/gui_static/account/settings/index.txt +27 -0
  240. ciris_engine/gui_static/adapters/index.html +1 -0
  241. ciris_engine/gui_static/adapters/index.txt +27 -0
  242. ciris_engine/gui_static/agents/index.html +1 -0
  243. ciris_engine/gui_static/agents/index.txt +27 -0
  244. ciris_engine/gui_static/andrew-roberts-euBRXcx57T4-unsplash.jpg +0 -0
  245. ciris_engine/gui_static/api-demo/index.html +1 -0
  246. ciris_engine/gui_static/api-demo/index.txt +27 -0
  247. ciris_engine/gui_static/audit/index.html +1 -0
  248. ciris_engine/gui_static/audit/index.txt +27 -0
  249. ciris_engine/gui_static/billing/index.html +1 -0
  250. ciris_engine/gui_static/billing/index.txt +27 -0
  251. ciris_engine/gui_static/blurryinfo.png +0 -0
  252. ciris_engine/gui_static/chip-vincent-PkQDwfl9Flc-unsplash.jpg +0 -0
  253. ciris_engine/gui_static/ciris-architecture.svg +338 -0
  254. ciris_engine/gui_static/comms/index.html +1 -0
  255. ciris_engine/gui_static/comms/index.txt +27 -0
  256. ciris_engine/gui_static/config/index.html +1 -0
  257. ciris_engine/gui_static/config/index.txt +27 -0
  258. ciris_engine/gui_static/consent/index.html +1 -0
  259. ciris_engine/gui_static/consent/index.txt +27 -0
  260. ciris_engine/gui_static/dashboard/index.html +1 -0
  261. ciris_engine/gui_static/dashboard/index.txt +27 -0
  262. ciris_engine/gui_static/docs/index.html +1 -0
  263. ciris_engine/gui_static/docs/index.txt +27 -0
  264. ciris_engine/gui_static/eric.png +0 -0
  265. ciris_engine/gui_static/file.svg +1 -0
  266. ciris_engine/gui_static/globe.svg +1 -0
  267. ciris_engine/gui_static/index.html +1 -0
  268. ciris_engine/gui_static/index.txt +27 -0
  269. ciris_engine/gui_static/infogfx-1@2x.png +0 -0
  270. ciris_engine/gui_static/infogfx-2.png +0 -0
  271. ciris_engine/gui_static/infogfx-dark-1.png +0 -0
  272. ciris_engine/gui_static/kelly-vohs-soSTXmIxTDU-unsplash.jpg +0 -0
  273. ciris_engine/gui_static/login/index.html +1 -0
  274. ciris_engine/gui_static/login/index.txt +27 -0
  275. ciris_engine/gui_static/logs/index.html +1 -0
  276. ciris_engine/gui_static/logs/index.txt +27 -0
  277. ciris_engine/gui_static/memory/index.html +1 -0
  278. ciris_engine/gui_static/memory/index.txt +27 -0
  279. ciris_engine/gui_static/nathan-farrish-ArcTfEoBgzs-unsplash.jpg +0 -0
  280. ciris_engine/gui_static/next.svg +1 -0
  281. ciris_engine/gui_static/overview.svg +512 -0
  282. ciris_engine/gui_static/overview1.svg +407 -0
  283. ciris_engine/gui_static/overview2.svg +370 -0
  284. ciris_engine/gui_static/pipeline-visualization.svg +278 -0
  285. ciris_engine/gui_static/privacy-policy.html +160 -0
  286. ciris_engine/gui_static/runtime/index.html +8 -0
  287. ciris_engine/gui_static/runtime/index.txt +27 -0
  288. ciris_engine/gui_static/services/index.html +1 -0
  289. ciris_engine/gui_static/services/index.txt +27 -0
  290. ciris_engine/gui_static/sessions/index.html +1 -0
  291. ciris_engine/gui_static/sessions/index.txt +27 -0
  292. ciris_engine/gui_static/setup/index.html +1 -0
  293. ciris_engine/gui_static/setup/index.txt +27 -0
  294. ciris_engine/gui_static/status-dashboard/index.html +1 -0
  295. ciris_engine/gui_static/status-dashboard/index.txt +27 -0
  296. ciris_engine/gui_static/system/index.html +1 -0
  297. ciris_engine/gui_static/system/index.txt +27 -0
  298. ciris_engine/gui_static/terms-of-service.html +174 -0
  299. ciris_engine/gui_static/test-auth/index.html +1 -0
  300. ciris_engine/gui_static/test-auth/index.txt +27 -0
  301. ciris_engine/gui_static/test-login/index.html +1 -0
  302. ciris_engine/gui_static/test-login/index.txt +27 -0
  303. ciris_engine/gui_static/test-sdk/index.html +1 -0
  304. ciris_engine/gui_static/test-sdk/index.txt +27 -0
  305. ciris_engine/gui_static/tools/index.html +1 -0
  306. ciris_engine/gui_static/tools/index.txt +27 -0
  307. ciris_engine/gui_static/users/index.html +1 -0
  308. ciris_engine/gui_static/users/index.txt +27 -0
  309. ciris_engine/gui_static/vercel.svg +1 -0
  310. ciris_engine/gui_static/videos/video1.mp4 +0 -0
  311. ciris_engine/gui_static/videos/video3.mp4 +0 -0
  312. ciris_engine/gui_static/wa/index.html +1 -0
  313. ciris_engine/gui_static/wa/index.txt +27 -0
  314. ciris_engine/gui_static/window.svg +1 -0
  315. ciris_engine/logic/__init__.py +8 -0
  316. ciris_engine/logic/adapters/__init__.py +74 -0
  317. ciris_engine/logic/adapters/api/__init__.py +5 -0
  318. ciris_engine/logic/adapters/api/adapter.py +1037 -0
  319. ciris_engine/logic/adapters/api/api_communication.py +370 -0
  320. ciris_engine/logic/adapters/api/api_document.py +330 -0
  321. ciris_engine/logic/adapters/api/api_observer.py +24 -0
  322. ciris_engine/logic/adapters/api/api_runtime_control.py +388 -0
  323. ciris_engine/logic/adapters/api/api_tools.py +299 -0
  324. ciris_engine/logic/adapters/api/api_vision.py +215 -0
  325. ciris_engine/logic/adapters/api/app.py +272 -0
  326. ciris_engine/logic/adapters/api/auth.py +159 -0
  327. ciris_engine/logic/adapters/api/config.py +101 -0
  328. ciris_engine/logic/adapters/api/constants.py +55 -0
  329. ciris_engine/logic/adapters/api/dependencies/__init__.py +1 -0
  330. ciris_engine/logic/adapters/api/dependencies/auth.py +260 -0
  331. ciris_engine/logic/adapters/api/endpoints/__init__.py +1 -0
  332. ciris_engine/logic/adapters/api/endpoints/emergency.py +86 -0
  333. ciris_engine/logic/adapters/api/middleware/__init__.py +1 -0
  334. ciris_engine/logic/adapters/api/middleware/rate_limiter.py +302 -0
  335. ciris_engine/logic/adapters/api/models.py +29 -0
  336. ciris_engine/logic/adapters/api/routes/__init__.py +52 -0
  337. ciris_engine/logic/adapters/api/routes/agent.py +1762 -0
  338. ciris_engine/logic/adapters/api/routes/audit.py +707 -0
  339. ciris_engine/logic/adapters/api/routes/auth.py +1745 -0
  340. ciris_engine/logic/adapters/api/routes/billing.py +895 -0
  341. ciris_engine/logic/adapters/api/routes/config.py +329 -0
  342. ciris_engine/logic/adapters/api/routes/connectors.py +534 -0
  343. ciris_engine/logic/adapters/api/routes/consent.py +637 -0
  344. ciris_engine/logic/adapters/api/routes/dsar.py +637 -0
  345. ciris_engine/logic/adapters/api/routes/dsar_multi_source.py +484 -0
  346. ciris_engine/logic/adapters/api/routes/emergency.py +302 -0
  347. ciris_engine/logic/adapters/api/routes/memory.py +733 -0
  348. ciris_engine/logic/adapters/api/routes/memory_filters.py +230 -0
  349. ciris_engine/logic/adapters/api/routes/memory_models.py +112 -0
  350. ciris_engine/logic/adapters/api/routes/memory_queries.py +236 -0
  351. ciris_engine/logic/adapters/api/routes/memory_query_helpers.py +394 -0
  352. ciris_engine/logic/adapters/api/routes/memory_visualization.py +359 -0
  353. ciris_engine/logic/adapters/api/routes/memory_visualization_helpers.py +110 -0
  354. ciris_engine/logic/adapters/api/routes/partnership.py +541 -0
  355. ciris_engine/logic/adapters/api/routes/setup.py +1374 -0
  356. ciris_engine/logic/adapters/api/routes/system.py +3049 -0
  357. ciris_engine/logic/adapters/api/routes/system_extensions.py +952 -0
  358. ciris_engine/logic/adapters/api/routes/telemetry.py +1987 -0
  359. ciris_engine/logic/adapters/api/routes/telemetry_converters.py +141 -0
  360. ciris_engine/logic/adapters/api/routes/telemetry_helpers.py +111 -0
  361. ciris_engine/logic/adapters/api/routes/telemetry_logs_reader.py +280 -0
  362. ciris_engine/logic/adapters/api/routes/telemetry_metrics.py +131 -0
  363. ciris_engine/logic/adapters/api/routes/telemetry_models.py +190 -0
  364. ciris_engine/logic/adapters/api/routes/telemetry_otlp.py +878 -0
  365. ciris_engine/logic/adapters/api/routes/telemetry_resource_helpers.py +191 -0
  366. ciris_engine/logic/adapters/api/routes/tickets.py +541 -0
  367. ciris_engine/logic/adapters/api/routes/tools.py +556 -0
  368. ciris_engine/logic/adapters/api/routes/transparency.py +281 -0
  369. ciris_engine/logic/adapters/api/routes/users.py +981 -0
  370. ciris_engine/logic/adapters/api/routes/verification.py +373 -0
  371. ciris_engine/logic/adapters/api/routes/wa.py +369 -0
  372. ciris_engine/logic/adapters/api/service_configuration.py +177 -0
  373. ciris_engine/logic/adapters/api/services/__init__.py +1 -0
  374. ciris_engine/logic/adapters/api/services/auth_service.py +1417 -0
  375. ciris_engine/logic/adapters/api/services/oauth_security.py +68 -0
  376. ciris_engine/logic/adapters/base.py +141 -0
  377. ciris_engine/logic/adapters/base_adapter.py +73 -0
  378. ciris_engine/logic/adapters/base_observer.py +1141 -0
  379. ciris_engine/logic/adapters/base_vision.py +312 -0
  380. ciris_engine/logic/adapters/cirisnode_client.py +307 -0
  381. ciris_engine/logic/adapters/cli/__init__.py +3 -0
  382. ciris_engine/logic/adapters/cli/adapter.py +207 -0
  383. ciris_engine/logic/adapters/cli/cli_adapter.py +902 -0
  384. ciris_engine/logic/adapters/cli/cli_observer.py +268 -0
  385. ciris_engine/logic/adapters/cli/cli_tools.py +427 -0
  386. ciris_engine/logic/adapters/cli/cli_wa_service.py +134 -0
  387. ciris_engine/logic/adapters/cli/config.py +73 -0
  388. ciris_engine/logic/adapters/discord/__init__.py +3 -0
  389. ciris_engine/logic/adapters/discord/adapter.py +783 -0
  390. ciris_engine/logic/adapters/discord/ciris_discord_client.py +159 -0
  391. ciris_engine/logic/adapters/discord/config.py +177 -0
  392. ciris_engine/logic/adapters/discord/constants.py +185 -0
  393. ciris_engine/logic/adapters/discord/discord-stubs.pyi +50 -0
  394. ciris_engine/logic/adapters/discord/discord_adapter.py +1584 -0
  395. ciris_engine/logic/adapters/discord/discord_audit.py +150 -0
  396. ciris_engine/logic/adapters/discord/discord_channel_manager.py +351 -0
  397. ciris_engine/logic/adapters/discord/discord_connection_manager.py +313 -0
  398. ciris_engine/logic/adapters/discord/discord_embed_formatter.py +369 -0
  399. ciris_engine/logic/adapters/discord/discord_error_classifier.py +302 -0
  400. ciris_engine/logic/adapters/discord/discord_error_handler.py +316 -0
  401. ciris_engine/logic/adapters/discord/discord_guidance_handler.py +460 -0
  402. ciris_engine/logic/adapters/discord/discord_message_handler.py +207 -0
  403. ciris_engine/logic/adapters/discord/discord_observer.py +670 -0
  404. ciris_engine/logic/adapters/discord/discord_rate_limiter.py +249 -0
  405. ciris_engine/logic/adapters/discord/discord_reaction_handler.py +278 -0
  406. ciris_engine/logic/adapters/discord/discord_tool_handler.py +465 -0
  407. ciris_engine/logic/adapters/discord/discord_tool_service.py +790 -0
  408. ciris_engine/logic/adapters/discord/discord_tools.py +90 -0
  409. ciris_engine/logic/adapters/discord/discord_vision_helper.py +148 -0
  410. ciris_engine/logic/adapters/discord/py.typed +0 -0
  411. ciris_engine/logic/adapters/document_parser.py +320 -0
  412. ciris_engine/logic/audit/__init__.py +10 -0
  413. ciris_engine/logic/audit/hash_chain.py +313 -0
  414. ciris_engine/logic/audit/signature_manager.py +352 -0
  415. ciris_engine/logic/audit/verifier.py +408 -0
  416. ciris_engine/logic/buses/__init__.py +21 -0
  417. ciris_engine/logic/buses/base_bus.py +178 -0
  418. ciris_engine/logic/buses/bus_manager.py +121 -0
  419. ciris_engine/logic/buses/communication_bus.py +387 -0
  420. ciris_engine/logic/buses/llm_bus.py +722 -0
  421. ciris_engine/logic/buses/memory_bus.py +577 -0
  422. ciris_engine/logic/buses/prohibitions.py +502 -0
  423. ciris_engine/logic/buses/runtime_control_bus.py +539 -0
  424. ciris_engine/logic/buses/tool_bus.py +482 -0
  425. ciris_engine/logic/buses/wise_bus.py +684 -0
  426. ciris_engine/logic/config/__init__.py +25 -0
  427. ciris_engine/logic/config/bootstrap.py +255 -0
  428. ciris_engine/logic/config/config_accessor.py +202 -0
  429. ciris_engine/logic/config/db_paths.py +194 -0
  430. ciris_engine/logic/config/env_utils.py +39 -0
  431. ciris_engine/logic/conscience/__init__.py +16 -0
  432. ciris_engine/logic/conscience/build_deferral_package.py +0 -0
  433. ciris_engine/logic/conscience/core.py +688 -0
  434. ciris_engine/logic/conscience/interface.py +33 -0
  435. ciris_engine/logic/conscience/registry.py +76 -0
  436. ciris_engine/logic/conscience/thought_depth_guardrail.py +231 -0
  437. ciris_engine/logic/conscience/updated_status_conscience.py +156 -0
  438. ciris_engine/logic/context/__init__.py +10 -0
  439. ciris_engine/logic/context/batch_context.py +550 -0
  440. ciris_engine/logic/context/builder.py +149 -0
  441. ciris_engine/logic/context/channel_resolution.py +136 -0
  442. ciris_engine/logic/context/secrets_snapshot.py +52 -0
  443. ciris_engine/logic/context/system_snapshot.py +116 -0
  444. ciris_engine/logic/context/system_snapshot_helpers.py +1651 -0
  445. ciris_engine/logic/covenant/__init__.py +33 -0
  446. ciris_engine/logic/covenant/executor.py +303 -0
  447. ciris_engine/logic/covenant/extractor.py +382 -0
  448. ciris_engine/logic/covenant/handler.py +241 -0
  449. ciris_engine/logic/covenant/verifier.py +383 -0
  450. ciris_engine/logic/dma/__init__.py +15 -0
  451. ciris_engine/logic/dma/action_selection/__init__.py +11 -0
  452. ciris_engine/logic/dma/action_selection/action_instruction_generator.py +444 -0
  453. ciris_engine/logic/dma/action_selection/context_builder.py +508 -0
  454. ciris_engine/logic/dma/action_selection/faculty_integration.py +193 -0
  455. ciris_engine/logic/dma/action_selection/special_cases.py +132 -0
  456. ciris_engine/logic/dma/action_selection_pdma.py +365 -0
  457. ciris_engine/logic/dma/base_dma.py +335 -0
  458. ciris_engine/logic/dma/csdma.py +239 -0
  459. ciris_engine/logic/dma/dma_executor.py +575 -0
  460. ciris_engine/logic/dma/dsdma_base.py +410 -0
  461. ciris_engine/logic/dma/exceptions.py +4 -0
  462. ciris_engine/logic/dma/factory.py +150 -0
  463. ciris_engine/logic/dma/pdma.py +120 -0
  464. ciris_engine/logic/dma/prompt_loader.py +189 -0
  465. ciris_engine/logic/dma/prompts/action_selection_pdma.yml +58 -0
  466. ciris_engine/logic/dma/prompts/csdma_common_sense.yml +28 -0
  467. ciris_engine/logic/dma/prompts/dsdma_base.yml +17 -0
  468. ciris_engine/logic/dma/prompts/pdma_ethical.yml +42 -0
  469. ciris_engine/logic/formatters/__init__.py +26 -0
  470. ciris_engine/logic/formatters/crisis_resources.py +80 -0
  471. ciris_engine/logic/formatters/escalation.py +21 -0
  472. ciris_engine/logic/formatters/identity.py +224 -0
  473. ciris_engine/logic/formatters/prompt_blocks.py +64 -0
  474. ciris_engine/logic/formatters/system_snapshot.py +193 -0
  475. ciris_engine/logic/formatters/user_profiles.py +108 -0
  476. ciris_engine/logic/handlers/__init__.py +1 -0
  477. ciris_engine/logic/handlers/control/__init__.py +1 -0
  478. ciris_engine/logic/handlers/control/defer_handler.py +195 -0
  479. ciris_engine/logic/handlers/control/ponder_handler.py +154 -0
  480. ciris_engine/logic/handlers/control/reject_handler.py +81 -0
  481. ciris_engine/logic/handlers/external/__init__.py +1 -0
  482. ciris_engine/logic/handlers/external/observe_handler.py +154 -0
  483. ciris_engine/logic/handlers/external/speak_handler.py +250 -0
  484. ciris_engine/logic/handlers/external/tool_handler.py +148 -0
  485. ciris_engine/logic/handlers/memory/__init__.py +1 -0
  486. ciris_engine/logic/handlers/memory/forget_handler.py +107 -0
  487. ciris_engine/logic/handlers/memory/memorize_handler.py +391 -0
  488. ciris_engine/logic/handlers/memory/recall_handler.py +213 -0
  489. ciris_engine/logic/handlers/terminal/__init__.py +1 -0
  490. ciris_engine/logic/handlers/terminal/task_complete_handler.py +299 -0
  491. ciris_engine/logic/infrastructure/__init__.py +1 -0
  492. ciris_engine/logic/infrastructure/handlers/__init__.py +8 -0
  493. ciris_engine/logic/infrastructure/handlers/action_dispatcher.py +382 -0
  494. ciris_engine/logic/infrastructure/handlers/base_handler.py +450 -0
  495. ciris_engine/logic/infrastructure/handlers/exceptions.py +2 -0
  496. ciris_engine/logic/infrastructure/handlers/handler_registry.py +59 -0
  497. ciris_engine/logic/infrastructure/handlers/helpers.py +55 -0
  498. ciris_engine/logic/infrastructure/step_streaming.py +149 -0
  499. ciris_engine/logic/infrastructure/sub_services/__init__.py +1 -0
  500. ciris_engine/logic/infrastructure/sub_services/identity_variance_monitor.py +1035 -0
  501. ciris_engine/logic/infrastructure/sub_services/pattern_analysis_loop.py +758 -0
  502. ciris_engine/logic/infrastructure/sub_services/wa_cli_bootstrap.py +229 -0
  503. ciris_engine/logic/infrastructure/sub_services/wa_cli_display.py +176 -0
  504. ciris_engine/logic/infrastructure/sub_services/wa_cli_oauth.py +404 -0
  505. ciris_engine/logic/infrastructure/sub_services/wa_cli_wizard.py +181 -0
  506. ciris_engine/logic/persistence/__init__.py +130 -0
  507. ciris_engine/logic/persistence/analytics.py +97 -0
  508. ciris_engine/logic/persistence/db/__init__.py +28 -0
  509. ciris_engine/logic/persistence/db/core.py +520 -0
  510. ciris_engine/logic/persistence/db/dialect.py +380 -0
  511. ciris_engine/logic/persistence/db/execution_helpers.py +216 -0
  512. ciris_engine/logic/persistence/db/migration_runner.py +191 -0
  513. ciris_engine/logic/persistence/db/operations.py +313 -0
  514. ciris_engine/logic/persistence/db/query_builder.py +232 -0
  515. ciris_engine/logic/persistence/db/retry.py +154 -0
  516. ciris_engine/logic/persistence/db/setup.py +18 -0
  517. ciris_engine/logic/persistence/migrations/postgres/001_initial_schema.sql +4 -0
  518. ciris_engine/logic/persistence/migrations/postgres/002_add_retry_status.sql +3 -0
  519. ciris_engine/logic/persistence/migrations/postgres/003_add_task_update_tracking.sql +8 -0
  520. ciris_engine/logic/persistence/migrations/postgres/004_add_occurrence_id.sql +54 -0
  521. ciris_engine/logic/persistence/migrations/postgres/005_add_consolidation_locks.sql +22 -0
  522. ciris_engine/logic/persistence/migrations/postgres/006_add_correlation_id_unique_index.sql +16 -0
  523. ciris_engine/logic/persistence/migrations/postgres/007_add_dsar_tickets.sql +39 -0
  524. ciris_engine/logic/persistence/migrations/postgres/008_rename_to_tickets_add_sop.sql +123 -0
  525. ciris_engine/logic/persistence/migrations/postgres/009_add_ticket_status_columns.sql +39 -0
  526. ciris_engine/logic/persistence/migrations/postgres/010_add_images_to_tasks.sql +5 -0
  527. ciris_engine/logic/persistence/migrations/sqlite/001_initial_schema.sql +357 -0
  528. ciris_engine/logic/persistence/migrations/sqlite/002_add_retry_status.sql +3 -0
  529. ciris_engine/logic/persistence/migrations/sqlite/003_add_task_update_tracking.sql +8 -0
  530. ciris_engine/logic/persistence/migrations/sqlite/004_add_occurrence_id.sql +45 -0
  531. ciris_engine/logic/persistence/migrations/sqlite/005_add_consolidation_locks.sql +22 -0
  532. ciris_engine/logic/persistence/migrations/sqlite/006_add_correlation_id_unique_index.sql +16 -0
  533. ciris_engine/logic/persistence/migrations/sqlite/007_add_dsar_tickets.sql +39 -0
  534. ciris_engine/logic/persistence/migrations/sqlite/008_rename_to_tickets_add_sop.sql +120 -0
  535. ciris_engine/logic/persistence/migrations/sqlite/009_add_ticket_status_columns.sql +129 -0
  536. ciris_engine/logic/persistence/migrations/sqlite/010_add_images_to_tasks.sql +17 -0
  537. ciris_engine/logic/persistence/models/__init__.py +141 -0
  538. ciris_engine/logic/persistence/models/correlations.py +881 -0
  539. ciris_engine/logic/persistence/models/deferral.py +68 -0
  540. ciris_engine/logic/persistence/models/dsar.py +286 -0
  541. ciris_engine/logic/persistence/models/graph.py +362 -0
  542. ciris_engine/logic/persistence/models/identity.py +264 -0
  543. ciris_engine/logic/persistence/models/queue_status.py +139 -0
  544. ciris_engine/logic/persistence/models/tasks.py +1043 -0
  545. ciris_engine/logic/persistence/models/thoughts.py +400 -0
  546. ciris_engine/logic/persistence/models/tickets.py +518 -0
  547. ciris_engine/logic/persistence/stores/__init__.py +13 -0
  548. ciris_engine/logic/persistence/stores/auth_helpers.py +117 -0
  549. ciris_engine/logic/persistence/stores/authentication_store.py +414 -0
  550. ciris_engine/logic/persistence/utils.py +212 -0
  551. ciris_engine/logic/processors/__init__.py +30 -0
  552. ciris_engine/logic/processors/core/__init__.py +1 -0
  553. ciris_engine/logic/processors/core/base_processor.py +280 -0
  554. ciris_engine/logic/processors/core/main_processor.py +1777 -0
  555. ciris_engine/logic/processors/core/step_decorators.py +1583 -0
  556. ciris_engine/logic/processors/core/thought_processor/__init__.py +20 -0
  557. ciris_engine/logic/processors/core/thought_processor/action_execution.py +49 -0
  558. ciris_engine/logic/processors/core/thought_processor/conscience_execution.py +382 -0
  559. ciris_engine/logic/processors/core/thought_processor/finalize_action.py +66 -0
  560. ciris_engine/logic/processors/core/thought_processor/gather_context.py +120 -0
  561. ciris_engine/logic/processors/core/thought_processor/main.py +920 -0
  562. ciris_engine/logic/processors/core/thought_processor/perform_aspdma.py +86 -0
  563. ciris_engine/logic/processors/core/thought_processor/perform_dmas.py +106 -0
  564. ciris_engine/logic/processors/core/thought_processor/recursive_processing.py +237 -0
  565. ciris_engine/logic/processors/core/thought_processor/round_complete.py +52 -0
  566. ciris_engine/logic/processors/core/thought_processor/start_round.py +64 -0
  567. ciris_engine/logic/processors/exceptions.py +59 -0
  568. ciris_engine/logic/processors/states/__init__.py +1 -0
  569. ciris_engine/logic/processors/states/dream_processor.py +1381 -0
  570. ciris_engine/logic/processors/states/play_processor.py +141 -0
  571. ciris_engine/logic/processors/states/shutdown_processor.py +623 -0
  572. ciris_engine/logic/processors/states/solitude_processor.py +305 -0
  573. ciris_engine/logic/processors/states/wakeup_processor.py +802 -0
  574. ciris_engine/logic/processors/states/work_processor.py +742 -0
  575. ciris_engine/logic/processors/support/__init__.py +1 -0
  576. ciris_engine/logic/processors/support/dma_orchestrator.py +336 -0
  577. ciris_engine/logic/processors/support/processing_queue.py +133 -0
  578. ciris_engine/logic/processors/support/shutdown_condition_evaluator.py +294 -0
  579. ciris_engine/logic/processors/support/state_manager.py +358 -0
  580. ciris_engine/logic/processors/support/task_manager.py +303 -0
  581. ciris_engine/logic/processors/support/thought_escalation.py +116 -0
  582. ciris_engine/logic/processors/support/thought_manager.py +328 -0
  583. ciris_engine/logic/processors/support/thought_manager_enhanced.py +105 -0
  584. ciris_engine/logic/registries/__init__.py +34 -0
  585. ciris_engine/logic/registries/base.py +653 -0
  586. ciris_engine/logic/registries/circuit_breaker.py +275 -0
  587. ciris_engine/logic/registries/typed_registries.py +184 -0
  588. ciris_engine/logic/runtime/__init__.py +7 -0
  589. ciris_engine/logic/runtime/adapter_loader.py +261 -0
  590. ciris_engine/logic/runtime/adapter_manager.py +1053 -0
  591. ciris_engine/logic/runtime/ciris_runtime.py +2342 -0
  592. ciris_engine/logic/runtime/ciris_runtime_helpers.py +923 -0
  593. ciris_engine/logic/runtime/component_builder.py +361 -0
  594. ciris_engine/logic/runtime/identity_manager.py +219 -0
  595. ciris_engine/logic/runtime/module_loader.py +207 -0
  596. ciris_engine/logic/runtime/prevent_sideeffects.py +30 -0
  597. ciris_engine/logic/runtime/runtime_interface.py +23 -0
  598. ciris_engine/logic/runtime/service_initializer.py +1623 -0
  599. ciris_engine/logic/secrets/__init__.py +30 -0
  600. ciris_engine/logic/secrets/encryption.py +175 -0
  601. ciris_engine/logic/secrets/filter.py +295 -0
  602. ciris_engine/logic/secrets/service.py +652 -0
  603. ciris_engine/logic/secrets/store.py +669 -0
  604. ciris_engine/logic/services/__init__.py +1 -0
  605. ciris_engine/logic/services/adaptation/__init__.py +3 -0
  606. ciris_engine/logic/services/base_graph_service.py +142 -0
  607. ciris_engine/logic/services/base_infrastructure_service.py +69 -0
  608. ciris_engine/logic/services/base_scheduled_service.py +136 -0
  609. ciris_engine/logic/services/base_service.py +247 -0
  610. ciris_engine/logic/services/governance/__init__.py +3 -0
  611. ciris_engine/logic/services/governance/adaptive_filter/__init__.py +14 -0
  612. ciris_engine/logic/services/governance/adaptive_filter/service.py +818 -0
  613. ciris_engine/logic/services/governance/consent/__init__.py +53 -0
  614. ciris_engine/logic/services/governance/consent/air.py +403 -0
  615. ciris_engine/logic/services/governance/consent/decay.py +324 -0
  616. ciris_engine/logic/services/governance/consent/dsar_automation.py +589 -0
  617. ciris_engine/logic/services/governance/consent/exceptions.py +106 -0
  618. ciris_engine/logic/services/governance/consent/metrics.py +270 -0
  619. ciris_engine/logic/services/governance/consent/partnership.py +533 -0
  620. ciris_engine/logic/services/governance/consent/service.py +1256 -0
  621. ciris_engine/logic/services/governance/dsar/__init__.py +29 -0
  622. ciris_engine/logic/services/governance/dsar/orchestrator.py +977 -0
  623. ciris_engine/logic/services/governance/dsar/schemas.py +141 -0
  624. ciris_engine/logic/services/governance/dsar/signature_service.py +283 -0
  625. ciris_engine/logic/services/governance/self_observation/__init__.py +20 -0
  626. ciris_engine/logic/services/governance/self_observation/service.py +1153 -0
  627. ciris_engine/logic/services/governance/visibility/__init__.py +17 -0
  628. ciris_engine/logic/services/governance/visibility/service.py +512 -0
  629. ciris_engine/logic/services/governance/wise_authority/__init__.py +15 -0
  630. ciris_engine/logic/services/governance/wise_authority/service.py +827 -0
  631. ciris_engine/logic/services/graph/__init__.py +5 -0
  632. ciris_engine/logic/services/graph/audit_service/__init__.py +5 -0
  633. ciris_engine/logic/services/graph/audit_service/service.py +1675 -0
  634. ciris_engine/logic/services/graph/base.py +208 -0
  635. ciris_engine/logic/services/graph/config_service/__init__.py +5 -0
  636. ciris_engine/logic/services/graph/config_service/service.py +372 -0
  637. ciris_engine/logic/services/graph/incident_service/__init__.py +5 -0
  638. ciris_engine/logic/services/graph/incident_service/service.py +803 -0
  639. ciris_engine/logic/services/graph/memory_service.py +1120 -0
  640. ciris_engine/logic/services/graph/telemetry_service/__init__.py +5 -0
  641. ciris_engine/logic/services/graph/telemetry_service/exceptions.py +104 -0
  642. ciris_engine/logic/services/graph/telemetry_service/helpers.py +1337 -0
  643. ciris_engine/logic/services/graph/telemetry_service/service.py +2429 -0
  644. ciris_engine/logic/services/graph/tsdb_consolidation/__init__.py +17 -0
  645. ciris_engine/logic/services/graph/tsdb_consolidation/aggregation_helpers.py +355 -0
  646. ciris_engine/logic/services/graph/tsdb_consolidation/cleanup_helpers.py +438 -0
  647. ciris_engine/logic/services/graph/tsdb_consolidation/compressor.py +260 -0
  648. ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/__init__.py +27 -0
  649. ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/audit.py +326 -0
  650. ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/conversation.py +291 -0
  651. ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/memory.py +197 -0
  652. ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/metrics.py +251 -0
  653. ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/task.py +257 -0
  654. ciris_engine/logic/services/graph/tsdb_consolidation/consolidators/trace.py +363 -0
  655. ciris_engine/logic/services/graph/tsdb_consolidation/data_converter.py +545 -0
  656. ciris_engine/logic/services/graph/tsdb_consolidation/date_calculation_helpers.py +193 -0
  657. ciris_engine/logic/services/graph/tsdb_consolidation/db_query_helpers.py +296 -0
  658. ciris_engine/logic/services/graph/tsdb_consolidation/edge_helpers.py +92 -0
  659. ciris_engine/logic/services/graph/tsdb_consolidation/edge_manager.py +896 -0
  660. ciris_engine/logic/services/graph/tsdb_consolidation/extensive_helpers.py +322 -0
  661. ciris_engine/logic/services/graph/tsdb_consolidation/period_manager.py +152 -0
  662. ciris_engine/logic/services/graph/tsdb_consolidation/profound_helpers.py +277 -0
  663. ciris_engine/logic/services/graph/tsdb_consolidation/query_manager.py +812 -0
  664. ciris_engine/logic/services/graph/tsdb_consolidation/service.py +1692 -0
  665. ciris_engine/logic/services/graph/tsdb_consolidation/sql_builders.py +363 -0
  666. ciris_engine/logic/services/infrastructure/__init__.py +1 -0
  667. ciris_engine/logic/services/infrastructure/authentication/__init__.py +5 -0
  668. ciris_engine/logic/services/infrastructure/authentication/service.py +1634 -0
  669. ciris_engine/logic/services/infrastructure/database_maintenance/__init__.py +15 -0
  670. ciris_engine/logic/services/infrastructure/database_maintenance/service.py +764 -0
  671. ciris_engine/logic/services/infrastructure/resource_monitor/__init__.py +7 -0
  672. ciris_engine/logic/services/infrastructure/resource_monitor/ciris_billing_provider.py +755 -0
  673. ciris_engine/logic/services/infrastructure/resource_monitor/service.py +409 -0
  674. ciris_engine/logic/services/infrastructure/resource_monitor/simple_credit_provider.py +129 -0
  675. ciris_engine/logic/services/lifecycle/__init__.py +3 -0
  676. ciris_engine/logic/services/lifecycle/initialization/__init__.py +10 -0
  677. ciris_engine/logic/services/lifecycle/initialization/service.py +312 -0
  678. ciris_engine/logic/services/lifecycle/scheduler/__init__.py +5 -0
  679. ciris_engine/logic/services/lifecycle/scheduler/service.py +607 -0
  680. ciris_engine/logic/services/lifecycle/shutdown/__init__.py +9 -0
  681. ciris_engine/logic/services/lifecycle/shutdown/service.py +378 -0
  682. ciris_engine/logic/services/lifecycle/time/__init__.py +15 -0
  683. ciris_engine/logic/services/lifecycle/time/service.py +259 -0
  684. ciris_engine/logic/services/memory_service/__init__.py +8 -0
  685. ciris_engine/logic/services/mixins/__init__.py +13 -0
  686. ciris_engine/logic/services/mixins/example_usage.py +200 -0
  687. ciris_engine/logic/services/mixins/request_metrics.py +179 -0
  688. ciris_engine/logic/services/runtime/__init__.py +3 -0
  689. ciris_engine/logic/services/runtime/adapter_configuration/__init__.py +16 -0
  690. ciris_engine/logic/services/runtime/adapter_configuration/service.py +674 -0
  691. ciris_engine/logic/services/runtime/adapter_configuration/session.py +67 -0
  692. ciris_engine/logic/services/runtime/control_service/__init__.py +5 -0
  693. ciris_engine/logic/services/runtime/control_service/service.py +2269 -0
  694. ciris_engine/logic/services/runtime/llm_service/__init__.py +14 -0
  695. ciris_engine/logic/services/runtime/llm_service/pricing_calculator.py +279 -0
  696. ciris_engine/logic/services/runtime/llm_service/service.py +930 -0
  697. ciris_engine/logic/services/tools/__init__.py +5 -0
  698. ciris_engine/logic/services/tools/core_tool_service/__init__.py +8 -0
  699. ciris_engine/logic/services/tools/core_tool_service/service.py +852 -0
  700. ciris_engine/logic/setup/__init__.py +1 -0
  701. ciris_engine/logic/setup/first_run.py +250 -0
  702. ciris_engine/logic/setup/wizard.py +327 -0
  703. ciris_engine/logic/telemetry/__init__.py +46 -0
  704. ciris_engine/logic/telemetry/core.py +239 -0
  705. ciris_engine/logic/telemetry/hot_cold_config.py +133 -0
  706. ciris_engine/logic/telemetry/log_collector.py +190 -0
  707. ciris_engine/logic/telemetry/resource_monitor.py +7 -0
  708. ciris_engine/logic/telemetry/security.py +79 -0
  709. ciris_engine/logic/utils/__init__.py +18 -0
  710. ciris_engine/logic/utils/channel_utils.py +75 -0
  711. ciris_engine/logic/utils/consent/__init__.py +1 -0
  712. ciris_engine/logic/utils/consent/partnership_utils.py +172 -0
  713. ciris_engine/logic/utils/constants.py +92 -0
  714. ciris_engine/logic/utils/context_utils.py +145 -0
  715. ciris_engine/logic/utils/directory_setup.py +533 -0
  716. ciris_engine/logic/utils/graphql_context_provider.py +152 -0
  717. ciris_engine/logic/utils/identity_resolution.py +843 -0
  718. ciris_engine/logic/utils/incident_capture_handler.py +303 -0
  719. ciris_engine/logic/utils/initialization_manager.py +74 -0
  720. ciris_engine/logic/utils/jsondict_helpers.py +290 -0
  721. ciris_engine/logic/utils/log_sanitizer.py +97 -0
  722. ciris_engine/logic/utils/logging_config.py +151 -0
  723. ciris_engine/logic/utils/observability_decorators.py +544 -0
  724. ciris_engine/logic/utils/occurrence_utils.py +155 -0
  725. ciris_engine/logic/utils/path_resolution.py +281 -0
  726. ciris_engine/logic/utils/platform_detection.py +286 -0
  727. ciris_engine/logic/utils/privacy.py +266 -0
  728. ciris_engine/logic/utils/profile_loader.py +124 -0
  729. ciris_engine/logic/utils/profile_manager.py +16 -0
  730. ciris_engine/logic/utils/runtime_utils.py +69 -0
  731. ciris_engine/logic/utils/shutdown_manager.py +107 -0
  732. ciris_engine/logic/utils/task_formatters.py +60 -0
  733. ciris_engine/logic/utils/task_thought_factory.py +404 -0
  734. ciris_engine/logic/utils/thought_utils.py +54 -0
  735. ciris_engine/logic/utils/user_utils.py +70 -0
  736. ciris_engine/protocols/__init__.py +0 -0
  737. ciris_engine/protocols/adapters/__init__.py +35 -0
  738. ciris_engine/protocols/adapters/base.py +149 -0
  739. ciris_engine/protocols/adapters/configurable.py +265 -0
  740. ciris_engine/protocols/adapters/message.py +90 -0
  741. ciris_engine/protocols/audit/__init__.py +1 -0
  742. ciris_engine/protocols/buses/__init__.py +1 -0
  743. ciris_engine/protocols/config/__init__.py +1 -0
  744. ciris_engine/protocols/conscience/__init__.py +1 -0
  745. ciris_engine/protocols/consent.py +88 -0
  746. ciris_engine/protocols/context/__init__.py +1 -0
  747. ciris_engine/protocols/data/__init__.py +1 -0
  748. ciris_engine/protocols/dma/__init__.py +1 -0
  749. ciris_engine/protocols/dma/base.py +107 -0
  750. ciris_engine/protocols/faculties.py +34 -0
  751. ciris_engine/protocols/formatters/__init__.py +1 -0
  752. ciris_engine/protocols/handlers/__init__.py +1 -0
  753. ciris_engine/protocols/infrastructure/__init__.py +25 -0
  754. ciris_engine/protocols/infrastructure/base.py +377 -0
  755. ciris_engine/protocols/persistence/__init__.py +1 -0
  756. ciris_engine/protocols/pipeline_control.py +609 -0
  757. ciris_engine/protocols/processors/__init__.py +19 -0
  758. ciris_engine/protocols/processors/agent.py +299 -0
  759. ciris_engine/protocols/processors/base.py +130 -0
  760. ciris_engine/protocols/processors/orchestration.py +62 -0
  761. ciris_engine/protocols/registries/__init__.py +1 -0
  762. ciris_engine/protocols/runtime/__init__.py +1 -0
  763. ciris_engine/protocols/runtime/base.py +163 -0
  764. ciris_engine/protocols/secrets/__init__.py +1 -0
  765. ciris_engine/protocols/services/__init__.py +80 -0
  766. ciris_engine/protocols/services/adaptation/__init__.py +7 -0
  767. ciris_engine/protocols/services/adaptation/self_observation.py +265 -0
  768. ciris_engine/protocols/services/governance/__init__.py +20 -0
  769. ciris_engine/protocols/services/governance/communication.py +58 -0
  770. ciris_engine/protocols/services/governance/filter.py +56 -0
  771. ciris_engine/protocols/services/governance/visibility.py +32 -0
  772. ciris_engine/protocols/services/governance/wa_auth.py +192 -0
  773. ciris_engine/protocols/services/governance/wise_authority.py +75 -0
  774. ciris_engine/protocols/services/graph/__init__.py +19 -0
  775. ciris_engine/protocols/services/graph/audit.py +92 -0
  776. ciris_engine/protocols/services/graph/config.py +54 -0
  777. ciris_engine/protocols/services/graph/incident_management.py +103 -0
  778. ciris_engine/protocols/services/graph/memory.py +110 -0
  779. ciris_engine/protocols/services/graph/telemetry.py +51 -0
  780. ciris_engine/protocols/services/graph/tsdb_consolidation.py +87 -0
  781. ciris_engine/protocols/services/infrastructure/__init__.py +11 -0
  782. ciris_engine/protocols/services/infrastructure/authentication.py +159 -0
  783. ciris_engine/protocols/services/infrastructure/credit_gate.py +46 -0
  784. ciris_engine/protocols/services/infrastructure/database_maintenance.py +25 -0
  785. ciris_engine/protocols/services/infrastructure/resource_monitor.py +83 -0
  786. ciris_engine/protocols/services/lifecycle/__init__.py +13 -0
  787. ciris_engine/protocols/services/lifecycle/initialization.py +41 -0
  788. ciris_engine/protocols/services/lifecycle/scheduler.py +42 -0
  789. ciris_engine/protocols/services/lifecycle/shutdown.py +50 -0
  790. ciris_engine/protocols/services/lifecycle/time.py +31 -0
  791. ciris_engine/protocols/services/runtime/__init__.py +13 -0
  792. ciris_engine/protocols/services/runtime/llm.py +50 -0
  793. ciris_engine/protocols/services/runtime/runtime_control.py +193 -0
  794. ciris_engine/protocols/services/runtime/secrets.py +100 -0
  795. ciris_engine/protocols/services/runtime/tool.py +123 -0
  796. ciris_engine/protocols/telemetry/__init__.py +1 -0
  797. ciris_engine/protocols/utils/__init__.py +1 -0
  798. ciris_engine/schemas/__init__.py +112 -0
  799. ciris_engine/schemas/actions/__init__.py +37 -0
  800. ciris_engine/schemas/actions/parameters.py +137 -0
  801. ciris_engine/schemas/adapters/__init__.py +13 -0
  802. ciris_engine/schemas/adapters/cirisnode.py +135 -0
  803. ciris_engine/schemas/adapters/cli.py +97 -0
  804. ciris_engine/schemas/adapters/cli_tools.py +98 -0
  805. ciris_engine/schemas/adapters/discord.py +125 -0
  806. ciris_engine/schemas/adapters/graphql_core.py +144 -0
  807. ciris_engine/schemas/adapters/registration.py +47 -0
  808. ciris_engine/schemas/adapters/runtime_context.py +48 -0
  809. ciris_engine/schemas/adapters/tool_execution.py +45 -0
  810. ciris_engine/schemas/adapters/tools.py +96 -0
  811. ciris_engine/schemas/api/__init__.py +1 -0
  812. ciris_engine/schemas/api/agent.py +50 -0
  813. ciris_engine/schemas/api/audit.py +38 -0
  814. ciris_engine/schemas/api/auth.py +351 -0
  815. ciris_engine/schemas/api/config_security.py +242 -0
  816. ciris_engine/schemas/api/emergency.py +111 -0
  817. ciris_engine/schemas/api/responses.py +72 -0
  818. ciris_engine/schemas/api/runtime.py +26 -0
  819. ciris_engine/schemas/api/telemetry.py +109 -0
  820. ciris_engine/schemas/api/wa.py +90 -0
  821. ciris_engine/schemas/audit/__init__.py +13 -0
  822. ciris_engine/schemas/audit/core.py +139 -0
  823. ciris_engine/schemas/audit/hash_chain.py +58 -0
  824. ciris_engine/schemas/audit/verification.py +131 -0
  825. ciris_engine/schemas/buses/__init__.py +1 -0
  826. ciris_engine/schemas/config/__init__.py +41 -0
  827. ciris_engine/schemas/config/agent.py +279 -0
  828. ciris_engine/schemas/config/cognitive_state_behaviors.py +194 -0
  829. ciris_engine/schemas/config/default_dsar_sops.py +178 -0
  830. ciris_engine/schemas/config/essential.py +195 -0
  831. ciris_engine/schemas/config/tickets.py +86 -0
  832. ciris_engine/schemas/conscience/__init__.py +25 -0
  833. ciris_engine/schemas/conscience/context.py +34 -0
  834. ciris_engine/schemas/conscience/core.py +145 -0
  835. ciris_engine/schemas/conscience/results.py +24 -0
  836. ciris_engine/schemas/consent/__init__.py +5 -0
  837. ciris_engine/schemas/consent/core.py +404 -0
  838. ciris_engine/schemas/context/__init__.py +1 -0
  839. ciris_engine/schemas/covenant.py +382 -0
  840. ciris_engine/schemas/data/__init__.py +1 -0
  841. ciris_engine/schemas/dma/__init__.py +16 -0
  842. ciris_engine/schemas/dma/core.py +199 -0
  843. ciris_engine/schemas/dma/faculty.py +192 -0
  844. ciris_engine/schemas/dma/prompts.py +172 -0
  845. ciris_engine/schemas/dma/results.py +103 -0
  846. ciris_engine/schemas/formatters/__init__.py +1 -0
  847. ciris_engine/schemas/handlers/__init__.py +10 -0
  848. ciris_engine/schemas/handlers/context.py +119 -0
  849. ciris_engine/schemas/handlers/contexts.py +100 -0
  850. ciris_engine/schemas/handlers/core.py +167 -0
  851. ciris_engine/schemas/handlers/memory_schemas.py +67 -0
  852. ciris_engine/schemas/handlers/schemas.py +95 -0
  853. ciris_engine/schemas/identity.py +149 -0
  854. ciris_engine/schemas/infrastructure/__init__.py +1 -0
  855. ciris_engine/schemas/infrastructure/base.py +256 -0
  856. ciris_engine/schemas/infrastructure/behavioral_patterns.py +129 -0
  857. ciris_engine/schemas/infrastructure/feedback_loop.py +57 -0
  858. ciris_engine/schemas/infrastructure/identity_variance.py +141 -0
  859. ciris_engine/schemas/infrastructure/oauth.py +175 -0
  860. ciris_engine/schemas/infrastructure/wa_cli_wizard.py +54 -0
  861. ciris_engine/schemas/persistence/__init__.py +34 -0
  862. ciris_engine/schemas/persistence/core.py +140 -0
  863. ciris_engine/schemas/persistence/correlations.py +73 -0
  864. ciris_engine/schemas/persistence/postgres/__init__.py +1 -0
  865. ciris_engine/schemas/persistence/postgres/tables.py +280 -0
  866. ciris_engine/schemas/persistence/sqlite/__init__.py +1 -0
  867. ciris_engine/schemas/persistence/sqlite/tables.py +281 -0
  868. ciris_engine/schemas/platform.py +149 -0
  869. ciris_engine/schemas/processors/__init__.py +26 -0
  870. ciris_engine/schemas/processors/base.py +130 -0
  871. ciris_engine/schemas/processors/cognitive.py +77 -0
  872. ciris_engine/schemas/processors/context.py +35 -0
  873. ciris_engine/schemas/processors/core.py +152 -0
  874. ciris_engine/schemas/processors/dma.py +105 -0
  875. ciris_engine/schemas/processors/error.py +122 -0
  876. ciris_engine/schemas/processors/main.py +109 -0
  877. ciris_engine/schemas/processors/phase_results.py +21 -0
  878. ciris_engine/schemas/processors/results.py +99 -0
  879. ciris_engine/schemas/processors/solitude.py +79 -0
  880. ciris_engine/schemas/processors/state.py +202 -0
  881. ciris_engine/schemas/processors/state_example.py +177 -0
  882. ciris_engine/schemas/processors/states.py +21 -0
  883. ciris_engine/schemas/processors/status.py +34 -0
  884. ciris_engine/schemas/registries/__init__.py +1 -0
  885. ciris_engine/schemas/registries/base.py +66 -0
  886. ciris_engine/schemas/resources/__init__.py +15 -0
  887. ciris_engine/schemas/resources/crisis.py +315 -0
  888. ciris_engine/schemas/runtime/__init__.py +42 -0
  889. ciris_engine/schemas/runtime/adapter_management.py +186 -0
  890. ciris_engine/schemas/runtime/api.py +58 -0
  891. ciris_engine/schemas/runtime/audit.py +50 -0
  892. ciris_engine/schemas/runtime/bootstrap.py +33 -0
  893. ciris_engine/schemas/runtime/contexts.py +61 -0
  894. ciris_engine/schemas/runtime/core.py +161 -0
  895. ciris_engine/schemas/runtime/enums.py +167 -0
  896. ciris_engine/schemas/runtime/extended.py +232 -0
  897. ciris_engine/schemas/runtime/manifest.py +311 -0
  898. ciris_engine/schemas/runtime/memory.py +60 -0
  899. ciris_engine/schemas/runtime/messages.py +108 -0
  900. ciris_engine/schemas/runtime/models.py +156 -0
  901. ciris_engine/schemas/runtime/processing_context.py +43 -0
  902. ciris_engine/schemas/runtime/protocols_core.py +96 -0
  903. ciris_engine/schemas/runtime/resources.py +33 -0
  904. ciris_engine/schemas/runtime/system_context.py +417 -0
  905. ciris_engine/schemas/secrets/__init__.py +1 -0
  906. ciris_engine/schemas/secrets/core.py +267 -0
  907. ciris_engine/schemas/secrets/service.py +95 -0
  908. ciris_engine/schemas/services/__init__.py +33 -0
  909. ciris_engine/schemas/services/audit_summary_node.py +172 -0
  910. ciris_engine/schemas/services/authority/__init__.py +39 -0
  911. ciris_engine/schemas/services/authority/jwt.py +158 -0
  912. ciris_engine/schemas/services/authority/wa_updates.py +138 -0
  913. ciris_engine/schemas/services/authority/wise_authority.py +163 -0
  914. ciris_engine/schemas/services/authority_core.py +370 -0
  915. ciris_engine/schemas/services/capabilities.py +72 -0
  916. ciris_engine/schemas/services/community_core.py +95 -0
  917. ciris_engine/schemas/services/context.py +111 -0
  918. ciris_engine/schemas/services/conversation_summary_node.py +189 -0
  919. ciris_engine/schemas/services/core/__init__.py +153 -0
  920. ciris_engine/schemas/services/core/runtime.py +262 -0
  921. ciris_engine/schemas/services/core/runtime_config.py +117 -0
  922. ciris_engine/schemas/services/core/secrets.py +65 -0
  923. ciris_engine/schemas/services/correlation_node.py +179 -0
  924. ciris_engine/schemas/services/credit_gate.py +92 -0
  925. ciris_engine/schemas/services/discord_nodes.py +299 -0
  926. ciris_engine/schemas/services/feedback_core.py +131 -0
  927. ciris_engine/schemas/services/filters_core.py +270 -0
  928. ciris_engine/schemas/services/governance.py +26 -0
  929. ciris_engine/schemas/services/graph/__init__.py +26 -0
  930. ciris_engine/schemas/services/graph/attributes.py +254 -0
  931. ciris_engine/schemas/services/graph/audit.py +98 -0
  932. ciris_engine/schemas/services/graph/consolidation.py +338 -0
  933. ciris_engine/schemas/services/graph/edge_types.py +43 -0
  934. ciris_engine/schemas/services/graph/edges.py +88 -0
  935. ciris_engine/schemas/services/graph/incident.py +312 -0
  936. ciris_engine/schemas/services/graph/memory.py +84 -0
  937. ciris_engine/schemas/services/graph/node_data.py +174 -0
  938. ciris_engine/schemas/services/graph/query_results.py +82 -0
  939. ciris_engine/schemas/services/graph/telemetry.py +250 -0
  940. ciris_engine/schemas/services/graph/tsdb_consolidation.py +27 -0
  941. ciris_engine/schemas/services/graph/tsdb_models.py +107 -0
  942. ciris_engine/schemas/services/graph_core.py +196 -0
  943. ciris_engine/schemas/services/graph_typed_nodes.py +194 -0
  944. ciris_engine/schemas/services/infrastructure/__init__.py +1 -0
  945. ciris_engine/schemas/services/infrastructure/resource_monitor.py +20 -0
  946. ciris_engine/schemas/services/lifecycle/__init__.py +9 -0
  947. ciris_engine/schemas/services/lifecycle/initialization.py +33 -0
  948. ciris_engine/schemas/services/lifecycle/time.py +50 -0
  949. ciris_engine/schemas/services/llm.py +187 -0
  950. ciris_engine/schemas/services/metadata.py +43 -0
  951. ciris_engine/schemas/services/nodes.py +704 -0
  952. ciris_engine/schemas/services/operations.py +126 -0
  953. ciris_engine/schemas/services/requests.py +128 -0
  954. ciris_engine/schemas/services/resources_core.py +182 -0
  955. ciris_engine/schemas/services/runtime_control.py +1010 -0
  956. ciris_engine/schemas/services/shutdown.py +88 -0
  957. ciris_engine/schemas/services/special/__init__.py +0 -0
  958. ciris_engine/schemas/services/special/self_observation.py +396 -0
  959. ciris_engine/schemas/services/trace_summary_node.py +199 -0
  960. ciris_engine/schemas/services/visibility.py +98 -0
  961. ciris_engine/schemas/streaming/__init__.py +10 -0
  962. ciris_engine/schemas/streaming/reasoning_stream.py +95 -0
  963. ciris_engine/schemas/telemetry/__init__.py +0 -0
  964. ciris_engine/schemas/telemetry/collector.py +67 -0
  965. ciris_engine/schemas/telemetry/core.py +252 -0
  966. ciris_engine/schemas/telemetry/unified.py +59 -0
  967. ciris_engine/schemas/tools.py +72 -0
  968. ciris_engine/schemas/types.py +47 -0
  969. ciris_engine/schemas/utils/__init__.py +1 -0
  970. ciris_engine/schemas/utils/config_validator.py +54 -0
  971. ciris_engine/utils/__init__.py +1 -0
  972. ciris_engine/utils/serialization.py +35 -0
  973. ciris_sdk/__init__.py +124 -0
  974. ciris_sdk/auth_store.py +261 -0
  975. ciris_sdk/client.py +261 -0
  976. ciris_sdk/exceptions.py +73 -0
  977. ciris_sdk/model_types.py +258 -0
  978. ciris_sdk/models.py +354 -0
  979. ciris_sdk/pagination.py +214 -0
  980. ciris_sdk/rate_limiter.py +188 -0
  981. ciris_sdk/setup.py +17 -0
  982. ciris_sdk/telemetry_models.py +257 -0
  983. ciris_sdk/telemetry_responses.py +199 -0
  984. ciris_sdk/transport.py +177 -0
  985. ciris_sdk/websocket.py +400 -0
  986. main.py +766 -0
@@ -0,0 +1,1043 @@
1
+ import json
2
+ import logging
3
+ from typing import TYPE_CHECKING, Any, List, Optional
4
+
5
+ from ciris_engine.logic.persistence.db import get_db_connection
6
+ from ciris_engine.logic.persistence.db.dialect import get_adapter
7
+ from ciris_engine.logic.persistence.utils import map_row_to_task
8
+ from ciris_engine.protocols.services.graph.audit import AuditServiceProtocol
9
+ from ciris_engine.protocols.services.lifecycle.time import TimeServiceProtocol
10
+ from ciris_engine.schemas.runtime.enums import HandlerActionType, TaskStatus, ThoughtStatus
11
+ from ciris_engine.schemas.runtime.models import Task, TaskContext
12
+
13
+ if TYPE_CHECKING:
14
+ from ciris_engine.protocols.services.infrastructure.authentication import AuthenticationServiceProtocol
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ def get_task_by_id_any_occurrence(task_id: str, db_path: Optional[str] = None) -> Optional[Task]:
20
+ """
21
+ Get a task by ID without filtering by occurrence_id.
22
+
23
+ This is needed for task completion handlers that need to read the task's
24
+ actual occurrence_id before updating it. Unlike get_task_by_id() which filters
25
+ by occurrence_id, this function retrieves the task regardless of occurrence.
26
+
27
+ Args:
28
+ task_id: The task ID to look up
29
+ db_path: Optional database path (defaults to main database)
30
+
31
+ Returns:
32
+ The Task object, or None if task not found
33
+
34
+ Examples:
35
+ >>> task = get_task_by_id_any_occurrence("SHUTDOWN_SHARED_20251031")
36
+ >>> task.agent_occurrence_id
37
+ '__shared__'
38
+ """
39
+ sql = "SELECT * FROM tasks WHERE task_id = ? LIMIT 1"
40
+ try:
41
+ with get_db_connection(db_path) as conn:
42
+ cursor = conn.cursor()
43
+ cursor.execute(sql, (task_id,))
44
+ row = cursor.fetchone()
45
+ if row:
46
+ return map_row_to_task(row)
47
+ logger.warning(f"Task {task_id} not found (any occurrence)")
48
+ return None
49
+ except Exception as e:
50
+ logger.exception(f"Failed to get task {task_id} (any occurrence): {e}")
51
+ return None
52
+
53
+
54
+ def get_task_occurrence_id_for_update(task_id: str, db_path: Optional[str] = None) -> Optional[str]:
55
+ """
56
+ Get the correct occurrence_id for updating a task's status.
57
+
58
+ This handles 6 scenarios robustly:
59
+ 1. SQLite single agent (default) - returns "default"
60
+ 2. SQLite multi-occurrence claiming agent - returns actual occurrence_id
61
+ 3. SQLite multi-occurrence non-claimant - returns "__shared__"
62
+ 4. PostgreSQL single agent (default) - returns "default"
63
+ 5. PostgreSQL multi-occurrence claiming agent - returns actual occurrence_id
64
+ 6. PostgreSQL multi-occurrence non-claimant - returns "__shared__"
65
+
66
+ Args:
67
+ task_id: The task ID to look up
68
+ db_path: Optional database path (defaults to main database)
69
+
70
+ Returns:
71
+ The occurrence_id to use for UPDATE queries, or None if task not found
72
+
73
+ Examples:
74
+ >>> get_task_occurrence_id_for_update("SHUTDOWN_SHARED_20251031")
75
+ '__shared__'
76
+ >>> get_task_occurrence_id_for_update("regular-task-123")
77
+ 'default'
78
+ """
79
+ sql = "SELECT agent_occurrence_id FROM tasks WHERE task_id = ? LIMIT 1"
80
+ try:
81
+ with get_db_connection(db_path) as conn:
82
+ cursor = conn.cursor()
83
+ cursor.execute(sql, (task_id,))
84
+ row = cursor.fetchone()
85
+ if row:
86
+ return str(row[0])
87
+ logger.warning(f"Task {task_id} not found when looking up occurrence_id for update")
88
+ return None
89
+ except Exception as e:
90
+ logger.exception(f"Failed to get occurrence_id for task {task_id}: {e}")
91
+ return None
92
+
93
+
94
+ def get_tasks_by_status(
95
+ status: TaskStatus, occurrence_id: str = "default", db_path: Optional[str] = None
96
+ ) -> List[Task]:
97
+ """Returns all tasks with the given status and occurrence from the tasks table as Task objects."""
98
+ if not isinstance(status, TaskStatus):
99
+ raise TypeError(f"Expected TaskStatus enum, got {type(status)}: {status}")
100
+ status_val = status.value
101
+ sql = "SELECT * FROM tasks WHERE status = ? AND agent_occurrence_id = ? ORDER BY created_at ASC"
102
+ tasks_list: List[Any] = []
103
+ try:
104
+ with get_db_connection(db_path) as conn:
105
+ cursor = conn.cursor()
106
+ cursor.execute(sql, (status_val, occurrence_id))
107
+ rows = cursor.fetchall()
108
+ for row in rows:
109
+ tasks_list.append(map_row_to_task(row))
110
+ except Exception as e:
111
+ logger.exception(f"Failed to get tasks with status {status_val} for occurrence {occurrence_id}: {e}")
112
+ return tasks_list
113
+
114
+
115
+ def get_all_tasks(occurrence_id: str = "default", db_path: Optional[str] = None) -> List[Task]:
116
+ sql = "SELECT * FROM tasks WHERE agent_occurrence_id = ? ORDER BY created_at ASC"
117
+ tasks_list: List[Any] = []
118
+ try:
119
+ with get_db_connection(db_path) as conn:
120
+ cursor = conn.cursor()
121
+ cursor.execute(sql, (occurrence_id,))
122
+ rows = cursor.fetchall()
123
+ for row in rows:
124
+ tasks_list.append(map_row_to_task(row))
125
+ except Exception as e:
126
+ logger.exception(f"Failed to get all tasks for occurrence {occurrence_id}: {e}")
127
+ return tasks_list
128
+
129
+
130
+ def _is_correlation_id_constraint_violation(error_msg: str) -> bool:
131
+ """
132
+ Check if error message indicates a unique constraint violation on correlation_id.
133
+
134
+ Args:
135
+ error_msg: Lowercase error message from database exception
136
+
137
+ Returns:
138
+ True if this is a correlation_id constraint violation
139
+ """
140
+ return "unique constraint" in error_msg and ("correlation" in error_msg or "json_extract" in error_msg)
141
+
142
+
143
+ def _get_correlation_id_from_task(task: Task) -> Optional[str]:
144
+ """
145
+ Extract correlation_id from task context if available.
146
+
147
+ Args:
148
+ task: Task object to extract correlation_id from
149
+
150
+ Returns:
151
+ correlation_id if present, None otherwise
152
+ """
153
+ if not task.context:
154
+ return None
155
+ return getattr(task.context, "correlation_id", None)
156
+
157
+
158
+ def _handle_duplicate_task(task: Task, db_path: Optional[str]) -> str:
159
+ """
160
+ Handle duplicate task detection by returning existing task_id.
161
+
162
+ Args:
163
+ task: Task that triggered duplicate constraint
164
+ db_path: Optional database path
165
+
166
+ Returns:
167
+ Existing task_id if found, otherwise the attempted task_id
168
+ """
169
+ correlation_id = _get_correlation_id_from_task(task)
170
+ logger.info(
171
+ f"Task with correlation_id={correlation_id} already exists for occurrence {task.agent_occurrence_id}, "
172
+ "skipping duplicate (race condition prevented)"
173
+ )
174
+
175
+ # Treat empty string as None
176
+ if not correlation_id:
177
+ return task.task_id
178
+
179
+ existing_task = get_task_by_correlation_id(correlation_id, task.agent_occurrence_id, db_path)
180
+ if existing_task:
181
+ return existing_task.task_id
182
+
183
+ return task.task_id
184
+
185
+
186
+ def add_task(task: Task, db_path: Optional[str] = None) -> str:
187
+ task_dict = task.model_dump(mode="json")
188
+
189
+ # Serialize images for storage
190
+ images_data = task_dict.get("images", [])
191
+ images_json = json.dumps(images_data) if images_data else None
192
+
193
+ sql = """
194
+ INSERT INTO tasks (task_id, channel_id, agent_occurrence_id, description, status, priority,
195
+ created_at, updated_at, parent_task_id, context_json, outcome_json,
196
+ signed_by, signature, signed_at, updated_info_available, updated_info_content,
197
+ images_json)
198
+ VALUES (:task_id, :channel_id, :agent_occurrence_id, :description, :status, :priority,
199
+ :created_at, :updated_at, :parent_task_id, :context, :outcome,
200
+ :signed_by, :signature, :signed_at, :updated_info_available, :updated_info_content,
201
+ :images)
202
+ """
203
+ params = {
204
+ **task_dict,
205
+ "status": task.status.value,
206
+ "agent_occurrence_id": task.agent_occurrence_id,
207
+ "context": json.dumps(task_dict.get("context")) if task_dict.get("context") is not None else None,
208
+ "outcome": json.dumps(task_dict.get("outcome")) if task_dict.get("outcome") is not None else None,
209
+ "signed_by": task_dict.get("signed_by"),
210
+ "signature": task_dict.get("signature"),
211
+ "signed_at": task_dict.get("signed_at"),
212
+ "updated_info_available": 1 if task_dict.get("updated_info_available") else 0,
213
+ "updated_info_content": task_dict.get("updated_info_content"),
214
+ "images": images_json,
215
+ }
216
+ try:
217
+ with get_db_connection(db_path) as conn:
218
+ conn.execute(sql, params)
219
+ conn.commit()
220
+ image_count = len(images_data) if images_data else 0
221
+ if image_count > 0:
222
+ logger.info(
223
+ f"Added task ID {task.task_id} (occurrence: {task.agent_occurrence_id}) with {image_count} images."
224
+ )
225
+ else:
226
+ logger.info(f"Added task ID {task.task_id} (occurrence: {task.agent_occurrence_id}) to database.")
227
+ return task.task_id
228
+ except Exception as e:
229
+ error_msg = str(e).lower()
230
+ if _is_correlation_id_constraint_violation(error_msg):
231
+ return _handle_duplicate_task(task, db_path)
232
+ logger.exception(f"Failed to add task {task.task_id}: {e}")
233
+ raise
234
+
235
+
236
+ def get_task_by_id(task_id: str, occurrence_id: str = "default", db_path: Optional[str] = None) -> Optional[Task]:
237
+ sql = "SELECT * FROM tasks WHERE task_id = ? AND agent_occurrence_id = ?"
238
+ try:
239
+ with get_db_connection(db_path) as conn:
240
+ cursor = conn.cursor()
241
+ cursor.execute(sql, (task_id, occurrence_id))
242
+ row = cursor.fetchone()
243
+ if row:
244
+ return map_row_to_task(row)
245
+ return None
246
+ except Exception as e:
247
+ logger.exception(f"Failed to get task {task_id} for occurrence {occurrence_id}: {e}")
248
+ return None
249
+
250
+
251
+ def update_task_status(
252
+ task_id: str,
253
+ new_status: TaskStatus,
254
+ occurrence_id: str,
255
+ time_service: TimeServiceProtocol,
256
+ db_path: Optional[str] = None,
257
+ ) -> bool:
258
+ sql = "UPDATE tasks SET status = ?, updated_at = ? WHERE task_id = ? AND agent_occurrence_id = ?"
259
+ params = (new_status.value, time_service.now_iso(), task_id, occurrence_id)
260
+ try:
261
+ with get_db_connection(db_path) as conn:
262
+ cursor = conn.execute(sql, params)
263
+ conn.commit()
264
+ if cursor.rowcount > 0:
265
+ logger.info(f"Updated status of task ID {task_id} to {new_status.value}.")
266
+ return True
267
+ logger.warning(f"Task ID {task_id} not found for status update in occurrence {occurrence_id}.")
268
+ return False
269
+ except Exception as e:
270
+ logger.exception(f"Failed to update task status for {task_id}: {e}")
271
+ return False
272
+
273
+
274
+ def transfer_task_ownership(
275
+ task_id: str,
276
+ from_occurrence_id: str,
277
+ to_occurrence_id: str,
278
+ time_service: TimeServiceProtocol,
279
+ audit_service: AuditServiceProtocol,
280
+ db_path: Optional[str] = None,
281
+ ) -> bool:
282
+ """Transfer task ownership from one occurrence to another.
283
+
284
+ This is used when claiming shared tasks to transfer ownership from '__shared__'
285
+ to the claiming occurrence so seed thoughts can be processed.
286
+
287
+ Args:
288
+ task_id: The task ID to transfer
289
+ from_occurrence_id: Current occurrence ID (typically '__shared__')
290
+ to_occurrence_id: New occurrence ID (the claiming occurrence)
291
+ time_service: Time service for timestamp
292
+ audit_service: Audit service for logging ownership transfer events
293
+ db_path: Optional database path
294
+
295
+ Returns:
296
+ True if transfer successful, False otherwise
297
+ """
298
+ sql = "UPDATE tasks SET agent_occurrence_id = ?, updated_at = ? WHERE task_id = ? AND agent_occurrence_id = ?"
299
+ params = (to_occurrence_id, time_service.now_iso(), task_id, from_occurrence_id)
300
+
301
+ success = False
302
+ try:
303
+ with get_db_connection(db_path) as conn:
304
+ cursor = conn.execute(sql, params)
305
+ conn.commit()
306
+ if cursor.rowcount > 0:
307
+ logger.info(f"Transferred ownership of task {task_id} from {from_occurrence_id} to {to_occurrence_id}")
308
+ success = True
309
+ else:
310
+ logger.warning(f"Task {task_id} not found with occurrence {from_occurrence_id} for ownership transfer")
311
+ except Exception as e:
312
+ logger.exception(f"Failed to transfer task ownership for {task_id}: {e}")
313
+ success = False
314
+
315
+ # Log audit event for ownership transfer (fire and forget)
316
+ import asyncio
317
+ from typing import cast
318
+
319
+ from ciris_engine.schemas.audit.core import EventPayload
320
+ from ciris_engine.schemas.services.graph.audit import AuditEventData
321
+
322
+ audit_event = AuditEventData(
323
+ entity_id=task_id,
324
+ actor="system",
325
+ outcome="success" if success else "failed",
326
+ severity="info",
327
+ action="task_ownership_transfer",
328
+ resource="task",
329
+ metadata={
330
+ "task_id": task_id,
331
+ "from_occurrence_id": from_occurrence_id,
332
+ "to_occurrence_id": to_occurrence_id,
333
+ "task_type": "shared_coordination",
334
+ },
335
+ )
336
+
337
+ try:
338
+ # Try to get the running event loop
339
+ loop = asyncio.get_running_loop()
340
+ # Schedule the audit event as a task - cast to EventPayload for protocol compatibility
341
+ loop.create_task(audit_service.log_event("task_ownership_transfer", cast(EventPayload, audit_event)))
342
+ except RuntimeError:
343
+ # No event loop running - this is expected in sync contexts like tests
344
+ # The audit service will still track the call via the mock
345
+ logger.debug("No event loop running, audit logging deferred")
346
+
347
+ return success
348
+
349
+
350
+ def update_task_context_and_signing(
351
+ task_id: str,
352
+ occurrence_id: str,
353
+ context: TaskContext,
354
+ time_service: TimeServiceProtocol,
355
+ signed_by: Optional[str] = None,
356
+ signature: Optional[str] = None,
357
+ signed_at: Optional[str] = None,
358
+ db_path: Optional[str] = None,
359
+ ) -> bool:
360
+ """Update the context and signing metadata for an existing task."""
361
+
362
+ context_json = json.dumps(context.model_dump(mode="json"))
363
+ sql = """
364
+ UPDATE tasks
365
+ SET context_json = ?,
366
+ signed_by = ?,
367
+ signature = ?,
368
+ signed_at = ?,
369
+ updated_at = ?
370
+ WHERE task_id = ? AND agent_occurrence_id = ?
371
+ """
372
+ params = (
373
+ context_json,
374
+ signed_by,
375
+ signature,
376
+ signed_at,
377
+ time_service.now_iso(),
378
+ task_id,
379
+ occurrence_id,
380
+ )
381
+
382
+ try:
383
+ with get_db_connection(db_path) as conn:
384
+ cursor = conn.execute(sql, params)
385
+ conn.commit()
386
+ if cursor.rowcount > 0:
387
+ logger.info(
388
+ "Updated context and signing metadata for task %s (occurrence: %s)",
389
+ task_id,
390
+ occurrence_id,
391
+ )
392
+ return True
393
+ logger.warning(
394
+ "Task %s not found when updating context/signature for occurrence %s",
395
+ task_id,
396
+ occurrence_id,
397
+ )
398
+ return False
399
+ except Exception as e:
400
+ logger.exception(
401
+ "Failed to update context/signature for task %s (occurrence: %s): %s",
402
+ task_id,
403
+ occurrence_id,
404
+ e,
405
+ )
406
+ return False
407
+
408
+
409
+ def clear_task_images(
410
+ task_id: str,
411
+ occurrence_id: str,
412
+ time_service: TimeServiceProtocol,
413
+ db_path: Optional[str] = None,
414
+ ) -> bool:
415
+ """Clear images from a task (for privacy/storage cleanup on completion).
416
+
417
+ Args:
418
+ task_id: The task ID to clear images from
419
+ occurrence_id: The occurrence ID for the task
420
+ time_service: Time service for timestamp
421
+ db_path: Optional database path
422
+
423
+ Returns:
424
+ True if images were cleared, False otherwise
425
+ """
426
+ sql = "UPDATE tasks SET images_json = NULL, updated_at = ? WHERE task_id = ? AND agent_occurrence_id = ?"
427
+ params = (time_service.now_iso(), task_id, occurrence_id)
428
+
429
+ try:
430
+ with get_db_connection(db_path) as conn:
431
+ cursor = conn.execute(sql, params)
432
+ conn.commit()
433
+ if cursor.rowcount > 0:
434
+ logger.info(f"Cleared images from task {task_id} (occurrence: {occurrence_id})")
435
+ return True
436
+ logger.debug(f"Task {task_id} not found or no images to clear (occurrence: {occurrence_id})")
437
+ return False
438
+ except Exception as e:
439
+ logger.exception(f"Failed to clear images for task {task_id}: {e}")
440
+ return False
441
+
442
+
443
+ def task_exists(task_id: str, db_path: Optional[str] = None) -> bool:
444
+ return get_task_by_id(task_id, db_path=db_path) is not None
445
+
446
+
447
+ async def add_system_task(
448
+ task: Task, auth_service: Optional["AuthenticationServiceProtocol"] = None, db_path: Optional[str] = None
449
+ ) -> str:
450
+ """Add a system task with automatic signing by the system WA.
451
+
452
+ This should be used by authorized processors (wakeup, dream, shutdown) to create
453
+ system tasks that are properly signed.
454
+
455
+ Args:
456
+ task: The task to add
457
+ auth_service: Authentication service for signing (optional)
458
+ db_path: Database path (optional)
459
+
460
+ Returns:
461
+ The task ID
462
+ """
463
+ # If auth service is available, sign the task
464
+ if auth_service:
465
+ try:
466
+ system_wa_id = await auth_service.get_system_wa_id()
467
+ if system_wa_id:
468
+ signature, signed_at = await auth_service.sign_task(task, system_wa_id)
469
+ task.signed_by = system_wa_id
470
+ task.signature = signature
471
+ task.signed_at = signed_at
472
+ logger.info(f"Signed system task {task.task_id} with system WA {system_wa_id}")
473
+ else:
474
+ logger.warning("No system WA available for signing task")
475
+ except Exception as e:
476
+ logger.error(f"Failed to sign system task: {e}")
477
+ # Continue without signature
478
+
479
+ # Add the task (with or without signature)
480
+ return add_task(task, db_path=db_path)
481
+
482
+
483
+ def get_recent_completed_tasks(
484
+ occurrence_id: str = "default", limit: int = 10, db_path: Optional[str] = None
485
+ ) -> List[Task]:
486
+ tasks_list = get_all_tasks(occurrence_id, db_path=db_path)
487
+ completed = [t for t in tasks_list if getattr(t, "status", None) == TaskStatus.COMPLETED]
488
+ completed_sorted = sorted(completed, key=lambda t: getattr(t, "updated_at", ""), reverse=True)
489
+ return completed_sorted[:limit]
490
+
491
+
492
+ def get_top_tasks(occurrence_id: str = "default", limit: int = 10, db_path: Optional[str] = None) -> List[Task]:
493
+ """Get top pending tasks for occurrence ordered by priority (highest first) then by creation date."""
494
+ tasks_list = get_all_tasks(occurrence_id, db_path=db_path)
495
+ # Filter to PENDING tasks only - exclude COMPLETED, DEFERRED, FAILED, REJECTED
496
+ pending = [t for t in tasks_list if getattr(t, "status", None) == TaskStatus.PENDING]
497
+ sorted_tasks = sorted(pending, key=lambda t: (-getattr(t, "priority", 0), getattr(t, "created_at", "")))
498
+ return sorted_tasks[:limit]
499
+
500
+
501
+ def get_pending_tasks_for_activation(
502
+ occurrence_id: str = "default", limit: int = 10, db_path: Optional[str] = None
503
+ ) -> List[Task]:
504
+ """Get pending tasks for occurrence ordered by priority (highest first) then by creation date, with optional limit."""
505
+ pending_tasks = get_tasks_by_status(TaskStatus.PENDING, occurrence_id, db_path=db_path)
506
+ # Sort by priority (descending) then by created_at (ascending for oldest first)
507
+ sorted_tasks = sorted(pending_tasks, key=lambda t: (-getattr(t, "priority", 0), getattr(t, "created_at", "")))
508
+ return sorted_tasks[:limit]
509
+
510
+
511
+ def count_tasks(
512
+ status: Optional[TaskStatus] = None, occurrence_id: str = "default", db_path: Optional[str] = None
513
+ ) -> int:
514
+ """
515
+ Count tasks using SQL COUNT(*) for performance.
516
+
517
+ This function uses a SQL COUNT(*) query instead of loading all tasks into memory,
518
+ which prevents event loop blocking when counting large numbers of tasks.
519
+
520
+ Args:
521
+ status: Optional task status to filter by
522
+ occurrence_id: Agent occurrence ID (default: "default")
523
+ db_path: Optional database path
524
+
525
+ Returns:
526
+ Number of tasks matching the criteria
527
+ """
528
+ try:
529
+ with get_db_connection(db_path) as conn:
530
+ # Get adapter AFTER connection is established to ensure correct dialect
531
+ # (get_db_connection calls init_dialect which sets the global adapter)
532
+ adapter = get_adapter()
533
+ cursor = conn.cursor()
534
+
535
+ if status:
536
+ sql = adapter.translate_placeholders(
537
+ "SELECT COUNT(*) FROM tasks WHERE agent_occurrence_id = ? AND status = ?"
538
+ )
539
+ cursor.execute(sql, (occurrence_id, status.value))
540
+ else:
541
+ sql = adapter.translate_placeholders("SELECT COUNT(*) FROM tasks WHERE agent_occurrence_id = ?")
542
+ cursor.execute(sql, (occurrence_id,))
543
+
544
+ result = cursor.fetchone()
545
+ return adapter.extract_scalar(result) or 0
546
+ except Exception as e:
547
+ logger.exception(f"Failed to count tasks for occurrence {occurrence_id}: {e}")
548
+ return 0
549
+
550
+
551
+ def delete_tasks_by_ids(task_ids: List[str], db_path: Optional[str] = None) -> bool:
552
+ """Deletes tasks and their associated thoughts and feedback_mappings with the given IDs from the database."""
553
+ if not task_ids:
554
+ logger.warning("No task IDs provided for deletion.")
555
+ return False
556
+
557
+ logger.warning(f"DELETE_OPERATION: delete_tasks_by_ids called with {len(task_ids)} tasks: {task_ids}")
558
+ import traceback
559
+
560
+ logger.warning(f"DELETE_OPERATION: Called from: {''.join(traceback.format_stack()[-3:-1])}")
561
+
562
+ placeholders = ",".join("?" for _ in task_ids)
563
+
564
+ sql_get_thought_ids = f"SELECT thought_id FROM thoughts WHERE source_task_id IN ({placeholders})" # nosec B608 - placeholders are '?' strings
565
+ sql_delete_feedback_mappings = "DELETE FROM feedback_mappings WHERE target_thought_id IN ({})"
566
+ sql_delete_thoughts = (
567
+ f"DELETE FROM thoughts WHERE source_task_id IN ({placeholders})" # nosec B608 - placeholders are '?' strings
568
+ )
569
+ sql_delete_tasks = (
570
+ f"DELETE FROM tasks WHERE task_id IN ({placeholders})" # nosec B608 - placeholders are '?' strings
571
+ )
572
+
573
+ deleted_count = 0
574
+ try:
575
+ with get_db_connection(db_path) as conn:
576
+ cursor = conn.cursor()
577
+
578
+ cursor.execute(sql_get_thought_ids, task_ids)
579
+ thought_rows = cursor.fetchall()
580
+ thought_ids_to_delete = [row["thought_id"] for row in thought_rows]
581
+
582
+ if thought_ids_to_delete:
583
+ feedback_placeholders = ",".join("?" for _ in thought_ids_to_delete)
584
+ current_sql_delete_feedback_mappings = sql_delete_feedback_mappings.format(
585
+ feedback_placeholders
586
+ ) # nosec B608 - placeholders are '?' strings
587
+ cursor.execute(current_sql_delete_feedback_mappings, thought_ids_to_delete)
588
+ logger.info(
589
+ f"Deleted {cursor.rowcount} associated feedback mappings for thought IDs: {thought_ids_to_delete}."
590
+ )
591
+ else:
592
+ logger.info(f"No associated feedback mappings found for task IDs: {task_ids}.")
593
+
594
+ cursor.execute(sql_delete_thoughts, task_ids)
595
+ thoughts_deleted = cursor.rowcount
596
+ logger.warning(f"DELETE_OPERATION: Deleted {thoughts_deleted} thoughts for tasks: {task_ids}")
597
+ logger.info(f"Deleted {thoughts_deleted} associated thoughts for task IDs: {task_ids}.")
598
+
599
+ cursor.execute(sql_delete_tasks, task_ids)
600
+ deleted_count = cursor.rowcount
601
+
602
+ conn.commit()
603
+
604
+ if deleted_count > 0:
605
+ logger.info(f"Successfully deleted {deleted_count} task(s) with IDs: {task_ids}.")
606
+ return True
607
+ logger.warning(f"No tasks found with IDs: {task_ids} for deletion (or they were already deleted).")
608
+ return False
609
+ except Exception as e:
610
+ logger.exception(f"Failed to delete tasks with IDs {task_ids}: {e}")
611
+ return False
612
+
613
+
614
+ def get_tasks_older_than(
615
+ older_than_timestamp: str, occurrence_id: str = "default", db_path: Optional[str] = None
616
+ ) -> List[Task]:
617
+ """Get all tasks for occurrence with created_at older than the given ISO timestamp, returning Task objects."""
618
+ sql = "SELECT * FROM tasks WHERE created_at < ? AND agent_occurrence_id = ?"
619
+ tasks_list: List[Any] = []
620
+ try:
621
+ with get_db_connection(db_path) as conn:
622
+ cursor = conn.cursor()
623
+ cursor.execute(sql, (older_than_timestamp, occurrence_id))
624
+ rows = cursor.fetchall()
625
+ for row in rows:
626
+ tasks_list.append(map_row_to_task(row))
627
+ except Exception as e:
628
+ logger.exception(f"Failed to get tasks older than {older_than_timestamp} for occurrence {occurrence_id}: {e}")
629
+ return tasks_list
630
+
631
+
632
+ def get_active_task_for_channel(
633
+ channel_id: str, occurrence_id: str = "default", db_path: Optional[str] = None
634
+ ) -> Optional[Task]:
635
+ """Get the active task for a specific channel and occurrence, if one exists.
636
+
637
+ Args:
638
+ channel_id: The channel to check
639
+ occurrence_id: Runtime occurrence ID (default: "default")
640
+ db_path: Optional database path
641
+
642
+ Returns:
643
+ The active task for the channel in this occurrence, or None if no active task exists
644
+ """
645
+ sql = """SELECT * FROM tasks
646
+ WHERE channel_id = ? AND status = ? AND agent_occurrence_id = ?
647
+ ORDER BY created_at DESC LIMIT 1"""
648
+ try:
649
+ with get_db_connection(db_path) as conn:
650
+ cursor = conn.cursor()
651
+ cursor.execute(sql, (channel_id, TaskStatus.ACTIVE.value, occurrence_id))
652
+ row = cursor.fetchone()
653
+ if row:
654
+ task = map_row_to_task(row)
655
+ logger.info(
656
+ f"[GET_ACTIVE_TASK] Found active task for channel {channel_id}: task_id={task.task_id}, description={task.description[:100] if task.description else 'N/A'}"
657
+ )
658
+ return task
659
+ else:
660
+ logger.info(f"[GET_ACTIVE_TASK] No active task found for channel {channel_id}")
661
+ return None
662
+ except Exception as e:
663
+ logger.exception(f"Failed to get active task for channel {channel_id} occurrence {occurrence_id}: {e}")
664
+ return None
665
+
666
+
667
+ def set_task_updated_info_flag(
668
+ task_id: str,
669
+ updated_content: str,
670
+ occurrence_id: str,
671
+ time_service: TimeServiceProtocol,
672
+ db_path: Optional[str] = None,
673
+ ) -> bool:
674
+ """Set the updated_info_available flag on a task with new observation content.
675
+
676
+ This function checks if the task has already passed conscience checks. If the task
677
+ has passed conscience with any action OTHER than PONDER, it returns False (too late).
678
+ If the task hasn't passed conscience yet, or passed with PONDER, it sets the flag
679
+ and returns True.
680
+
681
+ Args:
682
+ task_id: The task to update
683
+ updated_content: The new observation content
684
+ occurrence_id: Runtime occurrence ID for safety check
685
+ time_service: Time service for timestamps
686
+ db_path: Optional database path
687
+
688
+ Returns:
689
+ True if flag was set successfully, False if task already committed to action or
690
+ doesn't belong to this occurrence
691
+ """
692
+ # First, verify the task belongs to this occurrence
693
+ task = get_task_by_id(task_id, occurrence_id, db_path)
694
+ if not task or task.agent_occurrence_id != occurrence_id:
695
+ logger.warning(
696
+ f"Task {task_id} does not belong to occurrence {occurrence_id}, cannot set updated_info_available flag"
697
+ )
698
+ return False
699
+
700
+ # Check if task has any completed thoughts with non-PONDER action
701
+ from ciris_engine.logic.persistence.models.thoughts import get_thoughts_by_task_id
702
+
703
+ thoughts = get_thoughts_by_task_id(task_id, occurrence_id, db_path)
704
+
705
+ # Check if any thought is completed with a non-PONDER action
706
+ for thought in thoughts:
707
+ if thought.status == ThoughtStatus.COMPLETED: # Thoughts use ThoughtStatus enum
708
+ # Check if final_action exists and is not PONDER
709
+ if thought.final_action:
710
+ action_type = thought.final_action.action_type
711
+ # If action is anything other than PONDER, it's too late
712
+ if action_type != "PONDER" and action_type != HandlerActionType.PONDER.value:
713
+ logger.info(
714
+ f"Task {task_id} already committed to action {action_type}, "
715
+ f"cannot set updated_info_available flag"
716
+ )
717
+ return False
718
+
719
+ # Safe to update - either no thoughts completed yet, or only PONDER actions
720
+ sql = """
721
+ UPDATE tasks
722
+ SET updated_info_available = 1,
723
+ updated_info_content = ?,
724
+ updated_at = ?
725
+ WHERE task_id = ? AND agent_occurrence_id = ?
726
+ """
727
+ params = (updated_content, time_service.now_iso(), task_id, occurrence_id)
728
+ try:
729
+ with get_db_connection(db_path) as conn:
730
+ cursor = conn.execute(sql, params)
731
+ conn.commit()
732
+ if cursor.rowcount > 0:
733
+ logger.info(f"Set updated_info_available flag for task {task_id}")
734
+ return True
735
+ logger.warning(f"Task {task_id} not found for update in occurrence {occurrence_id}")
736
+ return False
737
+ except Exception as e:
738
+ logger.exception(f"Failed to set updated_info_available flag for task {task_id}: {e}")
739
+ return False
740
+
741
+
742
+ # ==================== Multi-Occurrence Shared Task Functions ====================
743
+
744
+
745
+ def try_claim_shared_task(
746
+ task_type: str,
747
+ channel_id: str,
748
+ description: str,
749
+ priority: int,
750
+ time_service: TimeServiceProtocol,
751
+ db_path: Optional[str] = None,
752
+ ) -> tuple[Task, bool]:
753
+ """Atomically create or retrieve a shared agent-level task.
754
+
755
+ Uses deterministic task_id based on date to prevent race conditions when
756
+ multiple occurrences try to create the same shared task simultaneously.
757
+
758
+ The task is created with agent_occurrence_id="__shared__" to make it visible
759
+ to all occurrences of the agent.
760
+
761
+ Args:
762
+ task_type: Type of task (e.g., "wakeup", "shutdown")
763
+ channel_id: Channel where task originated
764
+ description: Task description
765
+ priority: Task priority (0-10)
766
+ time_service: Time service for timestamps
767
+ db_path: Optional database path
768
+
769
+ Returns:
770
+ Tuple of (Task, was_created) where was_created=True if this call created
771
+ the task, False if it already existed.
772
+
773
+ Example:
774
+ >>> task, created = try_claim_shared_task("wakeup", "system", "Identity affirmation", 10, time_service)
775
+ >>> if created:
776
+ ... print("This occurrence will process wakeup")
777
+ ... else:
778
+ ... print("Another occurrence already claimed wakeup")
779
+ """
780
+ from datetime import datetime, timezone
781
+
782
+ # Create deterministic task ID based on type and date
783
+ date_str = datetime.now(timezone.utc).strftime("%Y%m%d")
784
+ task_id = f"{task_type.upper()}_SHARED_{date_str}"
785
+
786
+ # First, check if task already exists
787
+ existing = get_task_by_id(task_id, "__shared__", db_path)
788
+ if existing:
789
+ # CRITICAL: Only reuse task if it's in a valid reusable state
790
+ # Stale tasks (completed, failed, or very old active tasks) should NOT be reused
791
+ # This prevents infinite loops from reusing tasks with completed seed thoughts
792
+
793
+ from datetime import timedelta
794
+
795
+ # Parse created_at string to datetime for age calculation
796
+ created_at = datetime.fromisoformat(existing.created_at.replace("Z", "+00:00"))
797
+ task_age = time_service.now() - created_at
798
+ is_fresh = task_age < timedelta(minutes=10) # Fresh if created within last 10 minutes
799
+ is_reusable_status = existing.status in [TaskStatus.PENDING, TaskStatus.ACTIVE]
800
+
801
+ if not is_reusable_status:
802
+ logger.warning(
803
+ f"Shared task {task_id} exists but has terminal status {existing.status.value}. "
804
+ "This stale task should have been cleaned up. Creating new task instead."
805
+ )
806
+ # Delete the stale task and create a new one
807
+ delete_tasks_by_ids([task_id], db_path)
808
+ elif not is_fresh:
809
+ logger.warning(
810
+ f"Shared task {task_id} exists but is stale (age: {task_age}). "
811
+ "This old active task should have been cleaned up. Creating new task instead."
812
+ )
813
+ # Delete the stale task and create a new one
814
+ delete_tasks_by_ids([task_id], db_path)
815
+ else:
816
+ # Task is fresh and in valid state - safe to reuse
817
+ logger.info(
818
+ f"Shared task {task_id} already exists (status={existing.status.value}, age={task_age}), "
819
+ "returning existing task"
820
+ )
821
+ return (existing, False)
822
+
823
+ # Try to create the task with INSERT OR IGNORE for race safety
824
+ # Use dialect adapter for database compatibility
825
+ from ciris_engine.logic.persistence.db.dialect import get_adapter
826
+
827
+ adapter = get_adapter()
828
+ now = time_service.now_iso()
829
+
830
+ columns = [
831
+ "task_id",
832
+ "channel_id",
833
+ "agent_occurrence_id",
834
+ "description",
835
+ "status",
836
+ "priority",
837
+ "created_at",
838
+ "updated_at",
839
+ "parent_task_id",
840
+ "context_json",
841
+ "outcome_json",
842
+ "signed_by",
843
+ "signature",
844
+ "signed_at",
845
+ "updated_info_available",
846
+ "updated_info_content",
847
+ "images_json",
848
+ ]
849
+ conflict_columns = ["task_id"] # Primary key constraint (task_id only)
850
+
851
+ sql = adapter.insert_or_ignore("tasks", columns, conflict_columns)
852
+ params = (
853
+ task_id,
854
+ channel_id,
855
+ "__shared__",
856
+ description,
857
+ TaskStatus.PENDING.value,
858
+ priority,
859
+ now,
860
+ now,
861
+ None, # parent_task_id
862
+ None, # context_json
863
+ None, # outcome_json
864
+ None, # signed_by
865
+ None, # signature
866
+ None, # signed_at
867
+ 0, # updated_info_available
868
+ None, # updated_info_content
869
+ None, # images_json (shared tasks don't have images)
870
+ )
871
+
872
+ try:
873
+ with get_db_connection(db_path) as conn:
874
+ cursor = conn.execute(sql, params)
875
+ conn.commit()
876
+
877
+ if cursor.rowcount > 0:
878
+ # We successfully created the task
879
+ logger.info(f"Successfully claimed shared task {task_id}")
880
+ created_task = get_task_by_id(task_id, "__shared__", db_path)
881
+ if created_task:
882
+ return (created_task, True)
883
+ else:
884
+ # This shouldn't happen, but handle gracefully
885
+ logger.error(f"Created shared task {task_id} but couldn't retrieve it")
886
+ raise RuntimeError(f"Failed to retrieve newly created shared task {task_id}")
887
+ else:
888
+ # INSERT OR IGNORE returned 0 rows - another occurrence created it between our check and insert
889
+ logger.info(f"Another occurrence claimed shared task {task_id} during race")
890
+ existing = get_task_by_id(task_id, "__shared__", db_path)
891
+ if existing:
892
+ return (existing, False)
893
+ else:
894
+ # This shouldn't happen, but handle gracefully
895
+ logger.error(f"INSERT OR IGNORE for {task_id} returned 0 rows but task doesn't exist")
896
+ raise RuntimeError(f"Shared task {task_id} creation race condition failed")
897
+
898
+ except Exception as e:
899
+ logger.exception(f"Failed to claim shared task {task_id}: {e}")
900
+ raise
901
+
902
+
903
+ def get_shared_task_status(
904
+ task_type: str, within_hours: int = 24, db_path: Optional[str] = None
905
+ ) -> Optional[TaskStatus]:
906
+ """Get the status of the most recent shared task of a given type.
907
+
908
+ Args:
909
+ task_type: Type of task (e.g., "wakeup", "shutdown")
910
+ within_hours: Only consider tasks created within this many hours (default: 24)
911
+ db_path: Optional database path
912
+
913
+ Returns:
914
+ TaskStatus enum if task found, None if no recent task exists
915
+ """
916
+ from datetime import datetime, timedelta, timezone
917
+
918
+ cutoff_time = datetime.now(timezone.utc) - timedelta(hours=within_hours)
919
+ cutoff_iso = cutoff_time.isoformat()
920
+
921
+ sql = """
922
+ SELECT status FROM tasks
923
+ WHERE agent_occurrence_id = '__shared__'
924
+ AND task_id LIKE ?
925
+ AND created_at > ?
926
+ ORDER BY created_at DESC
927
+ LIMIT 1
928
+ """
929
+ pattern = f"{task_type.upper()}_SHARED_%"
930
+
931
+ try:
932
+ with get_db_connection(db_path) as conn:
933
+ cursor = conn.cursor()
934
+ # Note: PostgreSQLCursorWrapper automatically translates ? to %s
935
+ cursor.execute(sql, (pattern, cutoff_iso))
936
+ row = cursor.fetchone()
937
+ if row:
938
+ return TaskStatus(row["status"])
939
+ return None
940
+ except Exception as e:
941
+ logger.exception(f"Failed to get shared task status for {task_type}: {e}")
942
+ return None
943
+
944
+
945
+ def is_shared_task_completed(task_type: str, within_hours: int = 24, db_path: Optional[str] = None) -> bool:
946
+ """Check if a shared task of the given type has been completed recently.
947
+
948
+ Args:
949
+ task_type: Type of task (e.g., "wakeup", "shutdown")
950
+ within_hours: Only consider tasks created within this many hours (default: 24)
951
+ db_path: Optional database path
952
+
953
+ Returns:
954
+ True if a completed task exists, False otherwise
955
+ """
956
+ status = get_shared_task_status(task_type, within_hours, db_path)
957
+ return status == TaskStatus.COMPLETED if status else False
958
+
959
+
960
+ def get_latest_shared_task(task_type: str, within_hours: int = 24, db_path: Optional[str] = None) -> Optional[Task]:
961
+ """Get the most recent shared task of a given type.
962
+
963
+ Args:
964
+ task_type: Type of task (e.g., "wakeup", "shutdown")
965
+ within_hours: Only consider tasks created within this many hours (default: 24)
966
+ db_path: Optional database path
967
+
968
+ Returns:
969
+ Task object if found, None otherwise
970
+ """
971
+ from datetime import datetime, timedelta, timezone
972
+
973
+ cutoff_time = datetime.now(timezone.utc) - timedelta(hours=within_hours)
974
+ cutoff_iso = cutoff_time.isoformat()
975
+
976
+ sql = """
977
+ SELECT * FROM tasks
978
+ WHERE agent_occurrence_id = '__shared__'
979
+ AND task_id LIKE ?
980
+ AND created_at > ?
981
+ ORDER BY created_at DESC
982
+ LIMIT 1
983
+ """
984
+ pattern = f"{task_type.upper()}_SHARED_%"
985
+
986
+ try:
987
+ with get_db_connection(db_path) as conn:
988
+ cursor = conn.cursor()
989
+ # Note: PostgreSQLCursorWrapper automatically translates ? to %s
990
+ cursor.execute(sql, (pattern, cutoff_iso))
991
+ row = cursor.fetchone()
992
+ if row:
993
+ return map_row_to_task(row)
994
+ return None
995
+ except Exception as e:
996
+ logger.exception(f"Failed to get latest shared task for {task_type}: {e}")
997
+ return None
998
+
999
+
1000
+ def get_task_by_correlation_id(
1001
+ correlation_id: str, occurrence_id: str = "default", db_path: Optional[str] = None
1002
+ ) -> Optional[Task]:
1003
+ """
1004
+ Query for a task by correlation_id (e.g., Reddit post/comment ID).
1005
+
1006
+ Args:
1007
+ correlation_id: The correlation ID to search for (stored in context_json)
1008
+ occurrence_id: Agent occurrence ID (default: "default")
1009
+ db_path: Optional database path
1010
+
1011
+ Returns:
1012
+ Task if found, None otherwise
1013
+ """
1014
+ from ciris_engine.logic.config.db_paths import get_sqlite_db_full_path
1015
+ from ciris_engine.logic.persistence.db.dialect import get_adapter, init_dialect
1016
+
1017
+ # Initialize dialect based on db_path BEFORE building SQL
1018
+ # This ensures the correct dialect (SQLite or PostgreSQL) is used
1019
+ init_dialect(db_path if db_path else get_sqlite_db_full_path())
1020
+
1021
+ # Use dialect adapter for JSON extraction (SQLite vs PostgreSQL)
1022
+ adapter = get_adapter()
1023
+ json_expr = adapter.json_extract("context_json", "$.correlation_id")
1024
+
1025
+ sql = f"""
1026
+ SELECT * FROM tasks
1027
+ WHERE agent_occurrence_id = {adapter.placeholder()}
1028
+ AND {json_expr} = {adapter.placeholder()}
1029
+ ORDER BY created_at DESC
1030
+ LIMIT 1
1031
+ """
1032
+
1033
+ try:
1034
+ with get_db_connection(db_path) as conn:
1035
+ cursor = conn.cursor()
1036
+ cursor.execute(sql, (occurrence_id, correlation_id))
1037
+ row = cursor.fetchone()
1038
+ if row:
1039
+ return map_row_to_task(row)
1040
+ return None
1041
+ except Exception as e:
1042
+ logger.exception(f"Failed to get task by correlation_id {correlation_id}: {e}")
1043
+ return None