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,930 @@
1
+ """OpenAI Compatible LLM Service with Circuit Breaker Integration."""
2
+
3
+ import json
4
+ import logging
5
+ import os
6
+ import re
7
+ import time
8
+ from typing import Any, Awaitable, Callable, Dict, List, Optional, Tuple, Type, cast
9
+
10
+ import instructor
11
+ from openai import (
12
+ APIConnectionError,
13
+ APIStatusError,
14
+ AsyncOpenAI,
15
+ AuthenticationError,
16
+ InternalServerError,
17
+ RateLimitError,
18
+ )
19
+ from pydantic import BaseModel, ConfigDict, Field
20
+
21
+ from ciris_engine.logic.registries.circuit_breaker import CircuitBreaker, CircuitBreakerConfig, CircuitBreakerError
22
+ from ciris_engine.logic.services.base_service import BaseService
23
+ from ciris_engine.protocols.services import LLMService as LLMServiceProtocol
24
+ from ciris_engine.protocols.services.graph.telemetry import TelemetryServiceProtocol
25
+ from ciris_engine.protocols.services.lifecycle.time import TimeServiceProtocol
26
+ from ciris_engine.protocols.services.runtime.llm import MessageDict
27
+ from ciris_engine.schemas.runtime.enums import ServiceType
28
+ from ciris_engine.schemas.runtime.protocols_core import LLMStatus, LLMUsageStatistics
29
+ from ciris_engine.schemas.runtime.resources import ResourceUsage
30
+ from ciris_engine.schemas.services.capabilities import LLMCapabilities
31
+ from ciris_engine.schemas.services.core import ServiceCapabilities
32
+ from ciris_engine.schemas.services.llm import ExtractedJSONData, JSONExtractionResult
33
+
34
+ from .pricing_calculator import LLMPricingCalculator
35
+
36
+
37
+ # Configuration class for OpenAI-compatible LLM services
38
+ class OpenAIConfig(BaseModel):
39
+ api_key: str = Field(default="")
40
+ model_name: str = Field(default="gpt-4o-mini")
41
+ base_url: Optional[str] = Field(default=None)
42
+ instructor_mode: str = Field(default="JSON")
43
+ max_retries: int = Field(default=3)
44
+ timeout_seconds: int = Field(default=5)
45
+
46
+ model_config = ConfigDict(protected_namespaces=())
47
+
48
+
49
+ logger = logging.getLogger(__name__)
50
+
51
+ # Type for structured call functions that can be retried
52
+ StructuredCallFunc = Callable[
53
+ [List[MessageDict], Type[BaseModel], int, float], Awaitable[Tuple[BaseModel, ResourceUsage]]
54
+ ]
55
+
56
+
57
+ class OpenAICompatibleClient(BaseService, LLMServiceProtocol):
58
+ """Client for interacting with OpenAI-compatible APIs with circuit breaker protection."""
59
+
60
+ def __init__(
61
+ self,
62
+ *, # Force keyword-only arguments
63
+ config: Optional[OpenAIConfig] = None,
64
+ telemetry_service: Optional[TelemetryServiceProtocol] = None,
65
+ time_service: Optional[TimeServiceProtocol] = None,
66
+ service_name: Optional[str] = None,
67
+ version: str = "1.0.0",
68
+ ) -> None:
69
+ # Set telemetry_service before calling super().__init__
70
+ # because _register_dependencies is called in the base constructor
71
+ self.telemetry_service = telemetry_service
72
+
73
+ # Initialize config BEFORE calling super().__init__
74
+ # This ensures openai_config exists when _check_dependencies is called
75
+ if config is None:
76
+ # Use default config - should be injected
77
+ self.openai_config = OpenAIConfig()
78
+ else:
79
+ self.openai_config = config
80
+
81
+ # Initialize circuit breaker BEFORE calling super().__init__
82
+ circuit_config = CircuitBreakerConfig(
83
+ failure_threshold=5, # Open after 5 consecutive failures
84
+ recovery_timeout=60.0, # Wait 60 seconds before testing recovery
85
+ success_threshold=2, # Close after 2 successful calls
86
+ timeout_duration=5.0, # 5 second API timeout
87
+ )
88
+ self.circuit_breaker = CircuitBreaker("llm_service", circuit_config)
89
+
90
+ # Initialize base service
91
+ super().__init__(time_service=time_service, service_name=service_name or "llm_service", version=version)
92
+
93
+ # CRITICAL: Check if we're in mock LLM mode
94
+ import os
95
+ import sys
96
+
97
+ if os.environ.get("MOCK_LLM") or "--mock-llm" in " ".join(sys.argv):
98
+ raise RuntimeError(
99
+ "CRITICAL BUG: OpenAICompatibleClient is being initialized while mock LLM is enabled!\n"
100
+ "This should never happen - the mock LLM module should prevent this initialization.\n"
101
+ "Stack trace will show where this is being called from."
102
+ )
103
+
104
+ # Initialize retry configuration
105
+ self.max_retries = min(getattr(self.openai_config, "max_retries", 3), 3)
106
+ self.base_delay = 1.0
107
+ self.max_delay = 30.0
108
+ self.retryable_exceptions = (APIConnectionError, RateLimitError)
109
+ # Note: We can't check for instructor.exceptions.InstructorRetryException at import time
110
+ # because it might not exist. We'll check it at runtime instead.
111
+ self.non_retryable_exceptions = (APIStatusError,)
112
+
113
+ api_key = self.openai_config.api_key
114
+ base_url = self.openai_config.base_url
115
+ model_name = self.openai_config.model_name or "gpt-4o-mini"
116
+
117
+ # Require API key - no automatic fallback to mock
118
+ if not api_key:
119
+ raise RuntimeError("No OpenAI API key found. Please set OPENAI_API_KEY environment variable.")
120
+
121
+ # Initialize OpenAI client
122
+ self.model_name = model_name
123
+ timeout = self.openai_config.timeout_seconds # Use the configured timeout value
124
+ max_retries = 0 # Disable OpenAI client retries - we handle our own
125
+
126
+ try:
127
+ self.client = AsyncOpenAI(api_key=api_key, base_url=base_url, timeout=timeout, max_retries=max_retries)
128
+
129
+ instructor_mode = getattr(self.openai_config, "instructor_mode", "json").lower()
130
+ mode_map = {
131
+ "json": instructor.Mode.JSON,
132
+ "tools": instructor.Mode.TOOLS,
133
+ "md_json": instructor.Mode.MD_JSON,
134
+ }
135
+ selected_mode = mode_map.get(instructor_mode, instructor.Mode.JSON)
136
+ self.instruct_client = instructor.from_openai(self.client, mode=selected_mode)
137
+ except Exception as e:
138
+ raise RuntimeError(f"Failed to initialize OpenAI client: {e}")
139
+
140
+ # Metrics tracking (no caching - we never cache LLM responses)
141
+ self._response_times: List[float] = [] # List of response times in ms
142
+ self._max_response_history = 100 # Keep last 100 response times
143
+ self._total_api_calls = 0
144
+ self._successful_api_calls = 0
145
+
146
+ # LLM-specific metrics tracking for v1.4.3 telemetry
147
+ self._total_requests = 0
148
+ self._total_input_tokens = 0
149
+ self._total_output_tokens = 0
150
+ self._total_cost_cents = 0.0
151
+ self._total_errors = 0
152
+
153
+ # Initialize pricing calculator for accurate cost and impact calculation
154
+ self.pricing_calculator = LLMPricingCalculator()
155
+
156
+ # Required BaseService abstract methods
157
+
158
+ def get_service_type(self) -> ServiceType:
159
+ """Get the service type enum value."""
160
+ return ServiceType.LLM
161
+
162
+ def _get_actions(self) -> List[str]:
163
+ """Get list of actions this service provides."""
164
+ return [LLMCapabilities.CALL_LLM_STRUCTURED.value]
165
+
166
+ def _check_dependencies(self) -> bool:
167
+ """Check if all required dependencies are available."""
168
+ # LLM service requires API key and circuit breaker to be functional
169
+ has_api_key = bool(self.openai_config.api_key)
170
+ circuit_breaker_ready = self.circuit_breaker is not None
171
+ return has_api_key and circuit_breaker_ready
172
+
173
+ # Override optional BaseService methods
174
+
175
+ def _register_dependencies(self) -> None:
176
+ """Register service dependencies."""
177
+ super()._register_dependencies()
178
+ if self.telemetry_service:
179
+ self._dependencies.add("TelemetryService")
180
+
181
+ async def _on_start(self) -> None:
182
+ """Custom startup logic for LLM service."""
183
+ logger.info(f"OpenAI Compatible LLM Service started with model: {self.model_name}")
184
+ logger.info(f"Circuit breaker initialized: {self.circuit_breaker.get_stats()}")
185
+
186
+ async def _on_stop(self) -> None:
187
+ """Custom cleanup logic for LLM service."""
188
+ await self.client.close()
189
+ logger.info("OpenAI Compatible LLM Service stopped")
190
+
191
+ def update_api_key(self, new_api_key: str) -> None:
192
+ """Update the API key and reset circuit breaker.
193
+
194
+ Called when Android TokenRefreshManager provides a fresh Google ID token.
195
+ This is critical for ciris.ai proxy authentication which uses JWT tokens
196
+ that expire after ~1 hour.
197
+ """
198
+ if not new_api_key:
199
+ logger.warning("[LLM_TOKEN] Attempted to update with empty API key - ignoring")
200
+ return
201
+
202
+ old_key_preview = self.openai_config.api_key[:20] + "..." if self.openai_config.api_key else "None"
203
+ new_key_preview = new_api_key[:20] + "..."
204
+
205
+ # Update config
206
+ self.openai_config.api_key = new_api_key
207
+
208
+ # Update the OpenAI client's API key
209
+ # The AsyncOpenAI client stores the key and uses it for all requests
210
+ self.client.api_key = new_api_key
211
+
212
+ # Also update instructor client if it has a reference to the key
213
+ if hasattr(self.instruct_client, "client") and hasattr(self.instruct_client.client, "api_key"):
214
+ self.instruct_client.client.api_key = new_api_key
215
+
216
+ # Reset circuit breaker to allow immediate retry
217
+ self.circuit_breaker.reset()
218
+
219
+ logger.info(
220
+ "[LLM_TOKEN] API key updated and circuit breaker reset:\n"
221
+ " Old key: %s\n"
222
+ " New key: %s\n"
223
+ " Circuit breaker state: %s",
224
+ old_key_preview,
225
+ new_key_preview,
226
+ self.circuit_breaker.get_stats().get("state", "unknown"),
227
+ )
228
+
229
+ async def handle_token_refreshed(self, signal: str, resource: str) -> None:
230
+ """Handle token_refreshed signal from ResourceMonitor.
231
+
232
+ Called when Android's TokenRefreshManager has updated .env with a fresh
233
+ Google ID token and the ResourceMonitor has reloaded environment variables.
234
+
235
+ This is the signal handler registered with ResourceMonitor.signal_bus.
236
+
237
+ Args:
238
+ signal: The signal name ("token_refreshed")
239
+ resource: The resource that was refreshed ("openai_api_key")
240
+ """
241
+ logger.info("[LLM_TOKEN] Received token_refreshed signal: %s for %s", signal, resource)
242
+
243
+ # Read fresh API key from environment
244
+ new_api_key = os.environ.get("OPENAI_API_KEY", "")
245
+
246
+ if not new_api_key:
247
+ logger.warning("[LLM_TOKEN] No OPENAI_API_KEY found in environment after refresh")
248
+ return
249
+
250
+ # Check if key actually changed
251
+ if new_api_key == self.openai_config.api_key:
252
+ logger.info("[LLM_TOKEN] API key unchanged after refresh - just resetting circuit breaker")
253
+ self.circuit_breaker.reset()
254
+ return
255
+
256
+ # Update the key
257
+ self.update_api_key(new_api_key)
258
+ logger.info("[LLM_TOKEN] Token refresh complete - LLM service ready for requests")
259
+
260
+ def _get_client(self) -> AsyncOpenAI:
261
+ """Return the OpenAI client instance (private method)."""
262
+ return self.client
263
+
264
+ async def is_healthy(self) -> bool:
265
+ """Check if service is healthy - used by buses and registries."""
266
+ # Call parent class health check first
267
+ base_healthy = await super().is_healthy()
268
+ # Also check circuit breaker status
269
+ return base_healthy and self.circuit_breaker.is_available()
270
+
271
+ def get_capabilities(self) -> ServiceCapabilities:
272
+ """Get service capabilities with custom metadata."""
273
+ # Get base capabilities
274
+ capabilities = super().get_capabilities()
275
+
276
+ # Add custom metadata using model_copy
277
+ if capabilities.metadata:
278
+ capabilities.metadata = capabilities.metadata.model_copy(
279
+ update={
280
+ "model": self.model_name,
281
+ "instructor_mode": getattr(self.openai_config, "instructor_mode", "JSON"),
282
+ "timeout_seconds": getattr(self.openai_config, "timeout_seconds", 30),
283
+ "max_retries": self.max_retries,
284
+ "circuit_breaker_state": self.circuit_breaker.get_stats().get("state", "unknown"),
285
+ }
286
+ )
287
+
288
+ return capabilities
289
+
290
+ def _collect_custom_metrics(self) -> Dict[str, float]:
291
+ """Collect service-specific metrics."""
292
+ cb_stats = self.circuit_breaker.get_stats()
293
+
294
+ # Calculate average response time
295
+ avg_response_time_ms = 0.0
296
+ if self._response_times:
297
+ avg_response_time_ms = sum(self._response_times) / len(self._response_times)
298
+
299
+ # Calculate API success rate
300
+ api_success_rate = 0.0
301
+ if self._total_api_calls > 0:
302
+ api_success_rate = self._successful_api_calls / self._total_api_calls
303
+
304
+ # Build custom metrics
305
+ metrics = {
306
+ # Circuit breaker metrics
307
+ "circuit_breaker_state": (
308
+ 1.0 if cb_stats.get("state") == "open" else (0.5 if cb_stats.get("state") == "half_open" else 0.0)
309
+ ),
310
+ "consecutive_failures": float(cb_stats.get("consecutive_failures", 0)),
311
+ "recovery_attempts": float(cb_stats.get("recovery_attempts", 0)),
312
+ "last_failure_age_seconds": float(cb_stats.get("last_failure_age", 0)),
313
+ "success_rate": cb_stats.get("success_rate", 1.0),
314
+ "call_count": float(cb_stats.get("call_count", 0)),
315
+ "failure_count": float(cb_stats.get("failure_count", 0)),
316
+ # Performance metrics (no caching)
317
+ "avg_response_time_ms": avg_response_time_ms,
318
+ "max_response_time_ms": max(self._response_times) if self._response_times else 0.0,
319
+ "min_response_time_ms": min(self._response_times) if self._response_times else 0.0,
320
+ "total_api_calls": float(self._total_api_calls),
321
+ "successful_api_calls": float(self._successful_api_calls),
322
+ "api_success_rate": api_success_rate,
323
+ # Model pricing info
324
+ "model_cost_per_1k_tokens": 0.15 if "gpt-4o-mini" in self.model_name else 2.5, # Cents
325
+ "retry_delay_base": self.base_delay,
326
+ "retry_delay_max": self.max_delay,
327
+ # Model configuration
328
+ "model_timeout_seconds": float(getattr(self.openai_config, "timeout_seconds", 30)),
329
+ "model_max_retries": float(self.max_retries),
330
+ }
331
+
332
+ return metrics
333
+
334
+ async def get_metrics(self) -> Dict[str, float]:
335
+ """
336
+ Get all LLM metrics including base, custom, and v1.4.3 specific metrics.
337
+ """
338
+ # Get all base + custom metrics
339
+ metrics = self._collect_metrics()
340
+
341
+ # Add v1.4.3 specific LLM metrics
342
+ metrics.update(
343
+ {
344
+ "llm_requests_total": float(self._total_requests),
345
+ "llm_tokens_input": float(self._total_input_tokens),
346
+ "llm_tokens_output": float(self._total_output_tokens),
347
+ "llm_tokens_total": float(self._total_input_tokens + self._total_output_tokens),
348
+ "llm_cost_cents": self._total_cost_cents,
349
+ "llm_errors_total": float(self._total_errors),
350
+ "llm_uptime_seconds": self._calculate_uptime(),
351
+ }
352
+ )
353
+
354
+ return metrics
355
+
356
+ def _extract_json_from_response(self, raw: str) -> JSONExtractionResult:
357
+ """Extract and parse JSON from LLM response (private method)."""
358
+ return self._extract_json(raw)
359
+
360
+ @classmethod
361
+ def _extract_json(cls, raw: str) -> JSONExtractionResult:
362
+ """Extract and parse JSON from LLM response (private method)."""
363
+ json_pattern = r"```json\s*(\{.*?\})\s*```"
364
+ match = re.search(json_pattern, raw, re.DOTALL)
365
+
366
+ if match:
367
+ json_str = match.group(1)
368
+ else:
369
+ json_str = raw.strip()
370
+ try:
371
+ parsed = json.loads(json_str)
372
+ return JSONExtractionResult(success=True, data=ExtractedJSONData(**parsed))
373
+ except json.JSONDecodeError:
374
+ try:
375
+ parsed_retry = json.loads(json_str.replace("'", '"'))
376
+ return JSONExtractionResult(success=True, data=ExtractedJSONData(**parsed_retry))
377
+ except json.JSONDecodeError:
378
+ return JSONExtractionResult(
379
+ success=False, error="Failed to parse JSON", raw_content=raw[:200] # First 200 chars
380
+ )
381
+
382
+ async def call_llm_structured(
383
+ self,
384
+ messages: List[MessageDict],
385
+ response_model: Type[BaseModel],
386
+ max_tokens: int = 1024,
387
+ temperature: float = 0.0,
388
+ thought_id: Optional[str] = None,
389
+ task_id: Optional[str] = None,
390
+ ) -> Tuple[BaseModel, ResourceUsage]:
391
+ """Make a structured LLM call with circuit breaker protection.
392
+
393
+ Args:
394
+ messages: List of message dicts for the LLM
395
+ response_model: Pydantic model for structured response
396
+ max_tokens: Maximum tokens in response
397
+ temperature: Sampling temperature
398
+ thought_id: Optional thought ID for tracing (last 8 chars used)
399
+ task_id: Optional task ID for tracing (last 8 chars used)
400
+ """
401
+ # Track the request
402
+ self._track_request()
403
+ # Track LLM-specific request
404
+ self._total_requests += 1
405
+
406
+ # No mock service integration - LLMService and MockLLMService are separate
407
+ logger.debug(f"Structured LLM call for {response_model.__name__}")
408
+
409
+ # Check circuit breaker before making call
410
+ self.circuit_breaker.check_and_raise()
411
+
412
+ # Track retry state for metadata
413
+ retry_state: Dict[str, Any] = {"count": 0, "previous_error": None, "original_request_id": None}
414
+
415
+ async def _make_structured_call(
416
+ msg_list: List[MessageDict],
417
+ resp_model: Type[BaseModel],
418
+ max_toks: int,
419
+ temp: float,
420
+ ) -> Tuple[BaseModel, ResourceUsage]:
421
+
422
+ try:
423
+ # Use instructor but capture the completion for usage data
424
+ # Note: We cast to Any because instructor expects OpenAI-specific message types
425
+ # but we use our own MessageDict protocol for type safety at the service boundary
426
+
427
+ # Build extra kwargs for CIRIS proxy (requires interaction_id)
428
+ # NOTE: CIRIS proxy charges per unique interaction_id, so we use task_id only
429
+ # All thoughts within the same task share one credit
430
+ extra_kwargs: Dict[str, Any] = {}
431
+ base_url = self.openai_config.base_url or ""
432
+ if "ciris.ai" in base_url or "ciris-services" in base_url:
433
+ # Hash task_id for billing (irreversible, same task = same hash = 1 credit)
434
+ import hashlib
435
+ import uuid
436
+
437
+ if not task_id:
438
+ raise RuntimeError(
439
+ f"BILLING BUG: task_id is required for CIRIS proxy but was None "
440
+ f"(thought_id={thought_id}, model={resp_model.__name__})"
441
+ )
442
+ interaction_id = hashlib.sha256(task_id.encode()).hexdigest()[:32]
443
+
444
+ # Build metadata for CIRIS proxy
445
+ metadata: Dict[str, Any] = {"interaction_id": interaction_id}
446
+
447
+ # Add retry info if this is a retry attempt
448
+ if retry_state["count"] > 0:
449
+ metadata["retry_count"] = retry_state["count"]
450
+ if retry_state["previous_error"]:
451
+ metadata["previous_error"] = retry_state["previous_error"]
452
+ if retry_state["original_request_id"]:
453
+ metadata["original_request_id"] = retry_state["original_request_id"]
454
+ logger.info(
455
+ f"[LLM_RETRY] attempt={retry_state['count']} "
456
+ f"prev_error={retry_state['previous_error']} "
457
+ f"interaction_id={interaction_id}"
458
+ )
459
+ else:
460
+ # First attempt - generate request ID for correlation
461
+ retry_state["original_request_id"] = uuid.uuid4().hex[:12]
462
+ metadata["request_id"] = retry_state["original_request_id"]
463
+ logger.info(
464
+ f"[LLM_REQUEST] interaction_id={interaction_id} "
465
+ f"request_id={retry_state['original_request_id']} "
466
+ f"thought_id={thought_id} model={resp_model.__name__}"
467
+ )
468
+
469
+ extra_kwargs["extra_body"] = {"metadata": metadata}
470
+
471
+ # DEBUG: Log multimodal content details for proxy team diagnostics
472
+ image_count = 0
473
+ total_image_bytes = 0
474
+ for msg in msg_list:
475
+ content = msg.get("content", "")
476
+ if isinstance(content, list):
477
+ for block in content:
478
+ if isinstance(block, dict) and block.get("type") == "image_url":
479
+ image_count += 1
480
+ url = block.get("image_url", {}).get("url", "")
481
+ if url.startswith("data:image"):
482
+ total_image_bytes += len(url)
483
+ if image_count > 0:
484
+ logger.info(
485
+ f"[VISION_DEBUG] Sending to proxy: model={self.model_name}, "
486
+ f"images={image_count}, image_data_bytes={total_image_bytes}, "
487
+ f"thought_id={thought_id}, response_model={resp_model.__name__}"
488
+ )
489
+
490
+ response, completion = await self.instruct_client.chat.completions.create_with_completion(
491
+ model=self.model_name,
492
+ messages=cast(Any, msg_list),
493
+ response_model=resp_model,
494
+ max_retries=0, # Disable instructor retries completely
495
+ max_tokens=max_toks,
496
+ temperature=temp,
497
+ **extra_kwargs,
498
+ )
499
+
500
+ # DEBUG: Log proxy response details
501
+ if image_count > 0:
502
+ actual_model = getattr(completion, "model", "unknown")
503
+ logger.info(
504
+ f"[VISION_DEBUG] Proxy response: requested={self.model_name}, "
505
+ f"actual_model={actual_model}, thought_id={thought_id}"
506
+ )
507
+
508
+ # Extract usage data from completion
509
+ usage = completion.usage
510
+
511
+ # Record success with circuit breaker
512
+ self.circuit_breaker.record_success()
513
+
514
+ # Extract token counts
515
+ prompt_tokens = getattr(usage, "prompt_tokens", 0)
516
+ completion_tokens = getattr(usage, "completion_tokens", 0)
517
+
518
+ # Calculate costs and environmental impact using pricing calculator
519
+ usage_obj = self.pricing_calculator.calculate_cost_and_impact(
520
+ model_name=self.model_name,
521
+ prompt_tokens=prompt_tokens,
522
+ completion_tokens=completion_tokens,
523
+ provider_name="openai", # Since this is OpenAI-compatible client
524
+ )
525
+
526
+ # Track metrics for get_metrics() method
527
+ self._total_input_tokens += prompt_tokens
528
+ self._total_output_tokens += completion_tokens
529
+ self._total_cost_cents += usage_obj.cost_cents
530
+
531
+ # Record token usage in telemetry
532
+ if self.telemetry_service and usage_obj.tokens_used > 0:
533
+ await self.telemetry_service.record_metric("llm_tokens_used", usage_obj.tokens_used)
534
+ await self.telemetry_service.record_metric("llm_api_call_structured")
535
+
536
+ return response, usage_obj
537
+
538
+ except AuthenticationError as e:
539
+ # Handle 401 Unauthorized - likely expired token or billing issue for ciris.ai
540
+ self._track_error(e)
541
+ self._total_errors += 1
542
+
543
+ base_url = self.openai_config.base_url or ""
544
+ if "ciris.ai" in base_url:
545
+ # Force circuit breaker open immediately (don't wait for failure threshold)
546
+ # This prevents burning credits on repeated failures
547
+ self.circuit_breaker.force_open(reason="ciris.ai 401 - billing or token error")
548
+ # Write signal file for Android to trigger token refresh
549
+ logger.error(
550
+ f"LLM AUTHENTICATION ERROR (401) - ciris.ai billing or token error.\n"
551
+ f" Model: {self.model_name}\n"
552
+ f" Provider: {base_url}\n"
553
+ f" Circuit breaker forced open immediately.\n"
554
+ f" Writing token refresh signal..."
555
+ )
556
+ self._signal_token_refresh_needed()
557
+ else:
558
+ self.circuit_breaker.record_failure()
559
+ logger.error(
560
+ f"LLM AUTHENTICATION ERROR (401) - Invalid API key.\n"
561
+ f" Model: {self.model_name}\n"
562
+ f" Provider: {base_url}\n"
563
+ f" Error: {e}"
564
+ )
565
+ raise
566
+
567
+ except (APIConnectionError, RateLimitError, InternalServerError) as e:
568
+ # Record failure with circuit breaker
569
+ self.circuit_breaker.record_failure()
570
+ # Track error in base service
571
+ self._track_error(e)
572
+ # Track LLM-specific error
573
+ self._total_errors += 1
574
+
575
+ # Enhanced error logging for provider errors
576
+ error_type = type(e).__name__
577
+ error_details = {
578
+ "error_type": error_type,
579
+ "model": self.model_name,
580
+ "base_url": self.openai_config.base_url or "default",
581
+ "circuit_breaker_state": self.circuit_breaker.state.value,
582
+ }
583
+
584
+ if isinstance(e, RateLimitError):
585
+ logger.error(
586
+ f"LLM RATE LIMIT ERROR - Provider: {error_details['base_url']}, "
587
+ f"Model: {error_details['model']}, CB State: {error_details['circuit_breaker_state']}. "
588
+ f"Error: {e}"
589
+ )
590
+ elif isinstance(e, InternalServerError):
591
+ error_str = str(e).lower()
592
+ # Check for billing service errors - should be surfaced to user
593
+ if "billing service error" in error_str or "billing error" in error_str:
594
+ from ciris_engine.logic.adapters.base_observer import BillingServiceError
595
+
596
+ # Force circuit breaker open - don't retry billing errors
597
+ self.circuit_breaker.force_open(reason="Billing service error")
598
+ logger.error(
599
+ f"LLM BILLING ERROR - Provider: {error_details['base_url']}, "
600
+ f"Model: {error_details['model']}. Billing service returned error: {e}"
601
+ )
602
+ raise BillingServiceError(
603
+ message=f"LLM billing service error. Please check your account status or try again later. Details: {e}",
604
+ status_code=402,
605
+ ) from e
606
+ else:
607
+ logger.error(
608
+ f"LLM PROVIDER ERROR (500) - Provider: {error_details['base_url']}, "
609
+ f"Model: {error_details['model']}, CB State: {error_details['circuit_breaker_state']}. "
610
+ f"Provider returned internal server error: {e}"
611
+ )
612
+ elif isinstance(e, APIConnectionError):
613
+ logger.error(
614
+ f"LLM CONNECTION ERROR - Provider: {error_details['base_url']}, "
615
+ f"Model: {error_details['model']}, CB State: {error_details['circuit_breaker_state']}. "
616
+ f"Failed to connect to provider: {e}"
617
+ )
618
+ else:
619
+ logger.error(
620
+ f"LLM API ERROR ({error_type}) - Provider: {error_details['base_url']}, "
621
+ f"Model: {error_details['model']}, CB State: {error_details['circuit_breaker_state']}. "
622
+ f"Error: {e}"
623
+ )
624
+ raise
625
+ except Exception as e:
626
+ # Check if this is an instructor retry exception (includes timeouts, 503 errors, rate limits, etc.)
627
+ if hasattr(instructor, "exceptions") and hasattr(instructor.exceptions, "InstructorRetryException"):
628
+ if isinstance(e, instructor.exceptions.InstructorRetryException):
629
+ # Record failure for circuit breaker regardless of specific error type
630
+ self.circuit_breaker.record_failure()
631
+ self._track_error(e)
632
+ # Track LLM-specific error
633
+ self._total_errors += 1
634
+
635
+ # Build error context for better debugging
636
+ error_context = {
637
+ "model": self.model_name,
638
+ "provider": self.openai_config.base_url or "default",
639
+ "response_model": resp_model.__name__,
640
+ "circuit_breaker_state": self.circuit_breaker.state.value,
641
+ "consecutive_failures": self.circuit_breaker.consecutive_failures,
642
+ }
643
+
644
+ # Provide specific error messages for different failure types
645
+ error_str = str(e).lower()
646
+ full_error = str(e)
647
+
648
+ # Check for schema validation errors
649
+ if "validation" in error_str or "validationerror" in error_str:
650
+ # Extract validation details
651
+ logger.error(
652
+ f"LLM SCHEMA VALIDATION ERROR - Response did not match expected schema.\n"
653
+ f" Model: {error_context['model']}\n"
654
+ f" Provider: {error_context['provider']}\n"
655
+ f" Expected Schema: {error_context['response_model']}\n"
656
+ f" CB State: {error_context['circuit_breaker_state']} "
657
+ f"({error_context['consecutive_failures']} consecutive failures)\n"
658
+ f" Validation Details: {full_error[:500]}"
659
+ )
660
+ raise RuntimeError(
661
+ f"LLM response validation failed for {resp_model.__name__} - "
662
+ "circuit breaker activated for failover"
663
+ ) from e
664
+
665
+ # Check for timeout errors
666
+ elif "timed out" in error_str or "timeout" in error_str:
667
+ logger.error(
668
+ f"LLM TIMEOUT ERROR - Request exceeded {self.openai_config.timeout_seconds}s timeout.\n"
669
+ f" Model: {error_context['model']}\n"
670
+ f" Provider: {error_context['provider']}\n"
671
+ f" CB State: {error_context['circuit_breaker_state']} "
672
+ f"({error_context['consecutive_failures']} consecutive failures)\n"
673
+ f" Error: {full_error[:300]}"
674
+ )
675
+ raise TimeoutError(
676
+ f"LLM API timeout ({self.openai_config.timeout_seconds}s) "
677
+ "- circuit breaker activated"
678
+ ) from e
679
+
680
+ # Check for service unavailable / 503 errors
681
+ elif "service unavailable" in error_str or "503" in error_str:
682
+ logger.error(
683
+ f"LLM SERVICE UNAVAILABLE (503) - Provider temporarily down.\n"
684
+ f" Model: {error_context['model']}\n"
685
+ f" Provider: {error_context['provider']}\n"
686
+ f" CB State: {error_context['circuit_breaker_state']} "
687
+ f"({error_context['consecutive_failures']} consecutive failures)\n"
688
+ f" Error: {full_error[:300]}"
689
+ )
690
+ raise RuntimeError(
691
+ "LLM service unavailable (503) - circuit breaker activated for failover"
692
+ ) from e
693
+
694
+ # Check for rate limit / 429 errors
695
+ elif "rate limit" in error_str or "429" in error_str:
696
+ logger.error(
697
+ f"LLM RATE LIMIT (429) - Provider quota exceeded.\n"
698
+ f" Model: {error_context['model']}\n"
699
+ f" Provider: {error_context['provider']}\n"
700
+ f" CB State: {error_context['circuit_breaker_state']} "
701
+ f"({error_context['consecutive_failures']} consecutive failures)\n"
702
+ f" Error: {full_error[:300]}"
703
+ )
704
+ raise RuntimeError(
705
+ "LLM rate limit exceeded (429) - circuit breaker activated for failover"
706
+ ) from e
707
+
708
+ # Check for context length / token limit exceeded errors (400)
709
+ elif (
710
+ "context_length" in error_str
711
+ or "maximum context" in error_str
712
+ or "context length" in error_str
713
+ or "token limit" in error_str
714
+ or "too many tokens" in error_str
715
+ or "max_tokens" in error_str
716
+ and "exceed" in error_str
717
+ ):
718
+ logger.error(
719
+ f"LLM CONTEXT_LENGTH_EXCEEDED - Input too long for model.\n"
720
+ f" Model: {error_context['model']}\n"
721
+ f" Provider: {error_context['provider']}\n"
722
+ f" CB State: {error_context['circuit_breaker_state']} "
723
+ f"({error_context['consecutive_failures']} consecutive failures)\n"
724
+ f" Error: {full_error[:500]}"
725
+ )
726
+ raise RuntimeError(
727
+ "CONTEXT_LENGTH_EXCEEDED: Input too long - reduce message history or context"
728
+ ) from e
729
+
730
+ # Check for content filtering / guardrail errors
731
+ elif "content_filter" in error_str or "content policy" in error_str or "safety" in error_str:
732
+ logger.error(
733
+ f"LLM CONTENT FILTER / GUARDRAIL - Request blocked by provider safety systems.\n"
734
+ f" Model: {error_context['model']}\n"
735
+ f" Provider: {error_context['provider']}\n"
736
+ f" CB State: {error_context['circuit_breaker_state']} "
737
+ f"({error_context['consecutive_failures']} consecutive failures)\n"
738
+ f" Error: {full_error[:300]}"
739
+ )
740
+ raise RuntimeError(
741
+ "LLM content filter triggered - circuit breaker activated for failover"
742
+ ) from e
743
+
744
+ # Generic instructor error with enhanced logging
745
+ else:
746
+ logger.error(
747
+ f"LLM INSTRUCTOR ERROR - Unspecified failure.\n"
748
+ f" Model: {error_context['model']}\n"
749
+ f" Provider: {error_context['provider']}\n"
750
+ f" Expected Schema: {error_context['response_model']}\n"
751
+ f" CB State: {error_context['circuit_breaker_state']} "
752
+ f"({error_context['consecutive_failures']} consecutive failures)\n"
753
+ f" Error Type: {type(e).__name__}\n"
754
+ f" Error: {full_error[:500]}"
755
+ )
756
+ raise RuntimeError("LLM API call failed - circuit breaker activated for failover") from e
757
+ # Re-raise other exceptions
758
+ raise
759
+
760
+ # Implement retry logic with OpenAI-specific error handling
761
+ try:
762
+ return await self._retry_with_backoff(
763
+ _make_structured_call,
764
+ messages,
765
+ response_model,
766
+ max_tokens,
767
+ temperature,
768
+ retry_state=retry_state, # Pass retry state for CIRIS proxy metadata
769
+ )
770
+ except CircuitBreakerError:
771
+ # Don't retry if circuit breaker is open
772
+ logger.warning("LLM service circuit breaker is open, failing fast")
773
+ raise
774
+ except TimeoutError:
775
+ # Don't retry timeout errors to prevent cascades
776
+ logger.warning("LLM structured service timeout, failing fast to prevent retry cascade")
777
+ raise
778
+
779
+ def _get_status(self) -> LLMStatus:
780
+ """Get detailed status including circuit breaker metrics (private method)."""
781
+ # Get circuit breaker stats
782
+ cb_stats = self.circuit_breaker.get_stats()
783
+
784
+ # Calculate average response time if we have metrics
785
+ avg_response_time = None
786
+ if hasattr(self, "_response_times") and self._response_times:
787
+ avg_response_time = sum(self._response_times) / len(self._response_times)
788
+
789
+ return LLMStatus(
790
+ available=self.circuit_breaker.is_available(),
791
+ model=self.model_name,
792
+ usage=LLMUsageStatistics(
793
+ total_calls=cb_stats.get("call_count", 0),
794
+ failed_calls=cb_stats.get("failure_count", 0),
795
+ success_rate=cb_stats.get("success_rate", 1.0),
796
+ ),
797
+ rate_limit_remaining=None, # Would need to track from API responses
798
+ response_time_avg=avg_response_time,
799
+ )
800
+
801
+ async def _retry_with_backoff(
802
+ self,
803
+ func: StructuredCallFunc,
804
+ messages: List[MessageDict],
805
+ response_model: Type[BaseModel],
806
+ max_tokens: int,
807
+ temperature: float,
808
+ retry_state: Optional[Dict[str, Any]] = None,
809
+ ) -> Tuple[BaseModel, ResourceUsage]:
810
+ """Retry with exponential backoff (private method).
811
+
812
+ Args:
813
+ func: The callable to retry
814
+ messages: LLM messages
815
+ response_model: Pydantic response model
816
+ max_tokens: Max tokens
817
+ temperature: Temperature
818
+ retry_state: Optional dict to track retry info for CIRIS proxy metadata
819
+ {"count": int, "previous_error": str, "original_request_id": str}
820
+ """
821
+ last_exception = None
822
+ for attempt in range(self.max_retries):
823
+ try:
824
+ return await func(messages, response_model, max_tokens, temperature)
825
+ except self.retryable_exceptions as e:
826
+ last_exception = e
827
+
828
+ # Categorize error for retry metadata
829
+ error_category = self._categorize_llm_error(e)
830
+
831
+ # Update retry state for next attempt's metadata
832
+ if retry_state is not None:
833
+ retry_state["count"] = attempt + 1
834
+ retry_state["previous_error"] = error_category
835
+
836
+ if attempt < self.max_retries - 1:
837
+ delay = min(self.base_delay * (2**attempt), self.max_delay)
838
+ logger.warning(
839
+ f"[LLM_RETRY_SCHEDULED] attempt={attempt + 1}/{self.max_retries} "
840
+ f"error={error_category} delay={delay:.1f}s"
841
+ )
842
+ import asyncio
843
+
844
+ await asyncio.sleep(delay)
845
+ continue
846
+ raise
847
+ except self.non_retryable_exceptions:
848
+ raise
849
+
850
+ if last_exception:
851
+ raise last_exception
852
+ raise RuntimeError("Retry logic failed without exception")
853
+
854
+ @staticmethod
855
+ def _categorize_llm_error(error: Exception) -> str:
856
+ """Categorize an LLM error for retry metadata.
857
+
858
+ Returns error category string for proxy correlation:
859
+ - TIMEOUT: Request timed out
860
+ - CONNECTION_ERROR: Could not connect
861
+ - RATE_LIMIT: Rate limit exceeded (429)
862
+ - CONTEXT_LENGTH_EXCEEDED: Input too long (400)
863
+ - VALIDATION_ERROR: Response didn't match schema
864
+ - AUTH_ERROR: Authentication failed (401)
865
+ - INTERNAL_ERROR: Provider error (500/503)
866
+ - UNKNOWN: Unrecognized error
867
+ """
868
+ error_str = str(error).lower()
869
+
870
+ # Check for timeout errors
871
+ if "timeout" in error_str or "timed out" in error_str:
872
+ return "TIMEOUT"
873
+
874
+ # Check for connection errors
875
+ if isinstance(error, APIConnectionError):
876
+ if "timeout" in error_str:
877
+ return "TIMEOUT"
878
+ return "CONNECTION_ERROR"
879
+
880
+ # Check for rate limit
881
+ if isinstance(error, RateLimitError) or "rate limit" in error_str or "429" in error_str:
882
+ return "RATE_LIMIT"
883
+
884
+ # Check for context length exceeded
885
+ if (
886
+ "context_length" in error_str
887
+ or "maximum context" in error_str
888
+ or "context length" in error_str
889
+ or "token limit" in error_str
890
+ or "too many tokens" in error_str
891
+ ):
892
+ return "CONTEXT_LENGTH_EXCEEDED"
893
+
894
+ # Check for validation errors
895
+ if "validation" in error_str or "validationerror" in error_str:
896
+ return "VALIDATION_ERROR"
897
+
898
+ # Check for auth errors
899
+ if isinstance(error, AuthenticationError) or "401" in error_str or "unauthorized" in error_str:
900
+ return "AUTH_ERROR"
901
+
902
+ # Check for server errors
903
+ if isinstance(error, InternalServerError) or "500" in error_str or "503" in error_str:
904
+ return "INTERNAL_ERROR"
905
+
906
+ return "UNKNOWN"
907
+
908
+ def _signal_token_refresh_needed(self) -> None:
909
+ """Write a signal file to indicate token refresh is needed (for ciris.ai).
910
+
911
+ This file is monitored by the Android app to trigger Google silentSignIn().
912
+ The signal file is written to CIRIS_HOME/.token_refresh_needed
913
+ """
914
+ import os
915
+ from pathlib import Path
916
+
917
+ try:
918
+ # Get CIRIS_HOME from environment (set by mobile_main.py on Android)
919
+ ciris_home = os.getenv("CIRIS_HOME")
920
+ if not ciris_home:
921
+ # Fallback for non-Android environments
922
+ from ciris_engine.logic.utils.path_resolution import get_ciris_home
923
+
924
+ ciris_home = str(get_ciris_home())
925
+
926
+ signal_file = Path(ciris_home) / ".token_refresh_needed"
927
+ signal_file.write_text(str(time.time()))
928
+ logger.info(f"Token refresh signal written to: {signal_file}")
929
+ except Exception as e:
930
+ logger.error(f"Failed to write token refresh signal: {e}")