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,895 @@
1
+ """
2
+ Billing endpoints for CIRIS API.
3
+
4
+ Frontend proxy endpoints to CIRIS Billing backend.
5
+ Frontend should NEVER call the billing backend directly.
6
+ """
7
+
8
+ import logging
9
+ import re
10
+ from typing import Any, Dict, Optional
11
+ from urllib.parse import quote
12
+
13
+ import httpx
14
+ from fastapi import APIRouter, Depends, HTTPException, Request
15
+ from pydantic import BaseModel, Field
16
+
17
+ from ciris_engine.config.ciris_services import get_billing_url
18
+ from ciris_engine.schemas.api.auth import AuthContext
19
+ from ciris_engine.schemas.types import JSONDict
20
+
21
+ from ..dependencies.auth import require_observer
22
+
23
+ logger = logging.getLogger(__name__)
24
+
25
+ router = APIRouter(prefix="/api/billing", tags=["billing"])
26
+
27
+
28
+ # Error message constants (avoid duplication)
29
+ ERROR_RESOURCE_MONITOR_UNAVAILABLE = "Resource monitor not available"
30
+ ERROR_CREDIT_PROVIDER_NOT_CONFIGURED = "Credit provider not configured"
31
+ ERROR_BILLING_SERVICE_UNAVAILABLE = "Billing service unavailable"
32
+ ERROR_INVALID_PAYMENT_ID = "Invalid payment ID format"
33
+
34
+ # Regex pattern for valid payment IDs (Stripe format: pi_xxx or similar alphanumeric with underscores)
35
+ PAYMENT_ID_PATTERN = re.compile(r"^[a-zA-Z0-9_-]{1,128}$")
36
+
37
+
38
+ # Request/Response schemas
39
+
40
+
41
+ class CreditStatusResponse(BaseModel):
42
+ """Credit status for frontend display."""
43
+
44
+ has_credit: bool = Field(..., description="Whether user has available credit")
45
+ credits_remaining: int = Field(..., description="Remaining paid credits")
46
+ free_uses_remaining: int = Field(..., description="Remaining free uses")
47
+ daily_free_uses_remaining: int = Field(0, description="Remaining daily free uses")
48
+ total_uses: int = Field(..., description="Total uses so far")
49
+ plan_name: Optional[str] = Field(None, description="Current plan name")
50
+ purchase_required: bool = Field(..., description="Whether purchase is required to continue")
51
+ purchase_options: Optional[JSONDict] = Field(None, description="Purchase options if required")
52
+
53
+
54
+ class PurchaseInitiateRequest(BaseModel):
55
+ """Request to initiate purchase flow."""
56
+
57
+ return_url: Optional[str] = Field(None, description="URL to return to after payment")
58
+
59
+
60
+ class PurchaseInitiateResponse(BaseModel):
61
+ """Response with Stripe payment intent."""
62
+
63
+ payment_id: str = Field(..., description="Payment intent ID")
64
+ client_secret: str = Field(..., description="Stripe client secret for frontend")
65
+ amount_minor: int = Field(..., description="Amount in minor units (cents)")
66
+ currency: str = Field(..., description="Currency code (USD)")
67
+ uses_purchased: int = Field(..., description="Number of uses being purchased")
68
+ publishable_key: str = Field(..., description="Stripe publishable key")
69
+
70
+
71
+ class PurchaseStatusResponse(BaseModel):
72
+ """Purchase status response."""
73
+
74
+ status: str = Field(..., description="Payment status (succeeded, pending, failed)")
75
+ credits_added: int = Field(..., description="Credits added (0 if not completed)")
76
+ balance_after: Optional[int] = Field(None, description="Balance after credits added")
77
+
78
+
79
+ class TransactionItem(BaseModel):
80
+ """Individual transaction (charge or credit)."""
81
+
82
+ transaction_id: str = Field(..., description="Unique transaction ID")
83
+ type: str = Field(..., description="Transaction type: charge or credit")
84
+ amount_minor: int = Field(..., description="Amount in minor units (negative for charges, positive for credits)")
85
+ currency: str = Field(..., description="Currency code (USD)")
86
+ description: str = Field(..., description="Transaction description")
87
+ created_at: str = Field(..., description="Transaction timestamp (ISO format)")
88
+ balance_after: int = Field(..., description="Account balance after this transaction")
89
+ metadata: Optional[JSONDict] = Field(None, description="Additional metadata for charges")
90
+ transaction_type: Optional[str] = Field(None, description="Type of credit transaction (purchase, refund, etc)")
91
+ external_transaction_id: Optional[str] = Field(
92
+ None, description="External payment ID (e.g., Stripe payment intent)"
93
+ )
94
+
95
+
96
+ class TransactionListResponse(BaseModel):
97
+ """Transaction history response."""
98
+
99
+ transactions: list[TransactionItem] = Field(..., description="List of transactions")
100
+ total_count: int = Field(..., description="Total number of transactions")
101
+ has_more: bool = Field(..., description="Whether more transactions are available")
102
+
103
+
104
+ # Helper functions
105
+
106
+
107
+ def _get_billing_client(request: Request, google_id_token: Optional[str] = None) -> httpx.AsyncClient:
108
+ """Get billing API client from app state.
109
+
110
+ Supports two authentication modes:
111
+ 1. Server mode: Uses CIRIS_BILLING_API_KEY env var (for agents.ciris.ai)
112
+ 2. JWT pass-through mode: Uses Google ID token from request (for Android/native)
113
+
114
+ Args:
115
+ request: FastAPI request object
116
+ google_id_token: Optional Google ID token for JWT pass-through mode
117
+ """
118
+ import os
119
+
120
+ # Check if billing client already exists in app state (for testing or pre-configured)
121
+ if hasattr(request.app.state, "billing_client") and request.app.state.billing_client is not None:
122
+ existing_client: httpx.AsyncClient = request.app.state.billing_client
123
+ return existing_client
124
+
125
+ billing_url = get_billing_url()
126
+ api_key = os.getenv("CIRIS_BILLING_API_KEY")
127
+
128
+ # Determine authentication mode
129
+ if api_key:
130
+ # Server mode: use API key (cached client)
131
+ if not hasattr(request.app.state, "billing_client"):
132
+ headers = {
133
+ "X-API-Key": api_key,
134
+ "User-Agent": "CIRIS-Agent-Frontend/1.0",
135
+ }
136
+ new_client = httpx.AsyncClient(base_url=billing_url, timeout=10.0, headers=headers)
137
+ request.app.state.billing_client = new_client
138
+ client: httpx.AsyncClient = request.app.state.billing_client
139
+ return client
140
+ elif google_id_token:
141
+ # JWT pass-through mode: create new client with Google ID token as Bearer
142
+ # Don't cache this client since token changes per request
143
+ headers = {
144
+ "Authorization": f"Bearer {google_id_token}",
145
+ "User-Agent": "CIRIS-Mobile/1.0",
146
+ }
147
+ logger.info(
148
+ f"[BILLING_JWT] Creating JWT pass-through client with Google ID token ({len(google_id_token)} chars)"
149
+ )
150
+ return httpx.AsyncClient(base_url=billing_url, timeout=10.0, headers=headers)
151
+ else:
152
+ raise HTTPException(
153
+ status_code=500,
154
+ detail="Billing not configured: set CIRIS_BILLING_API_KEY or provide X-Google-ID-Token header",
155
+ )
156
+
157
+
158
+ def _extract_user_identity(auth: AuthContext, request: Request) -> JSONDict:
159
+ """Extract user identity from auth context including marketing opt-in preference and email."""
160
+ # Extract user information from auth service
161
+ marketing_opt_in = False
162
+ user_email = None
163
+ oauth_provider = None
164
+ external_id = None
165
+
166
+ if hasattr(request.app.state, "auth_service") and request.app.state.auth_service is not None:
167
+ auth_service = request.app.state.auth_service
168
+ user = auth_service.get_user(auth.user_id)
169
+ if user:
170
+ marketing_opt_in = user.marketing_opt_in
171
+ user_email = user.oauth_email
172
+ # Get OAuth provider and external_id from user object (stored in database)
173
+ if user.oauth_provider and user.oauth_external_id:
174
+ oauth_provider = user.oauth_provider
175
+ external_id = user.oauth_external_id
176
+
177
+ # Fallback: Try to parse from user_id format (e.g., "google:115300315355793131383")
178
+ if not oauth_provider or not external_id:
179
+ if ":" in auth.user_id and not auth.user_id.startswith("wa-"):
180
+ parts = auth.user_id.split(":", 1)
181
+ oauth_provider = parts[0] # e.g., "google", "discord"
182
+ external_id = parts[1] # e.g., "115300315355793131383"
183
+ else:
184
+ # Internal/API user without OAuth
185
+ oauth_provider = "api:internal"
186
+ external_id = auth.user_id
187
+
188
+ # Format oauth_provider with "oauth:" prefix for billing backend
189
+ if not oauth_provider.startswith("oauth:"):
190
+ oauth_provider = f"oauth:{oauth_provider}"
191
+
192
+ identity = {
193
+ "oauth_provider": oauth_provider,
194
+ "external_id": external_id,
195
+ "wa_id": auth.user_id,
196
+ "tenant_id": None,
197
+ "marketing_opt_in": marketing_opt_in,
198
+ "customer_email": user_email, # CRITICAL: Never use fallback - let validation catch missing email
199
+ "user_role": auth.role.value.lower(), # Use actual user role from auth context
200
+ }
201
+ logger.debug(
202
+ f"[BILLING_IDENTITY] Extracted identity: has_provider={oauth_provider is not None}, "
203
+ f"has_external_id={external_id is not None}, has_email={user_email is not None}, "
204
+ f"marketing_opt_in={marketing_opt_in}"
205
+ )
206
+ return identity
207
+
208
+
209
+ # Endpoints
210
+
211
+
212
+ def _get_unlimited_credit_response() -> CreditStatusResponse:
213
+ """Return unlimited credit response when no credit provider configured."""
214
+ return CreditStatusResponse(
215
+ has_credit=True,
216
+ credits_remaining=999,
217
+ free_uses_remaining=999,
218
+ total_uses=0,
219
+ plan_name="unlimited",
220
+ purchase_required=False,
221
+ purchase_options=None,
222
+ )
223
+
224
+
225
+ def _get_simple_provider_response(has_credit: bool) -> CreditStatusResponse:
226
+ """Return credit response for SimpleCreditProvider (1 free use)."""
227
+ if has_credit:
228
+ # Still have free credit
229
+ return CreditStatusResponse(
230
+ has_credit=True,
231
+ credits_remaining=0,
232
+ free_uses_remaining=1,
233
+ total_uses=0,
234
+ plan_name="free",
235
+ purchase_required=False,
236
+ purchase_options=None,
237
+ )
238
+ else:
239
+ # Free credit exhausted, billing not enabled
240
+ return CreditStatusResponse(
241
+ has_credit=False,
242
+ credits_remaining=0,
243
+ free_uses_remaining=0,
244
+ total_uses=1,
245
+ plan_name="free",
246
+ purchase_required=False, # Can't purchase when billing disabled
247
+ purchase_options={
248
+ "price_minor": 0,
249
+ "uses": 0,
250
+ "currency": "USD",
251
+ "message": "Contact administrator to enable billing",
252
+ },
253
+ )
254
+
255
+
256
+ def _build_credit_check_payload(user_identity: JSONDict, context: Any) -> JSONDict:
257
+ """Build payload for billing backend credit check."""
258
+ check_payload = {
259
+ "oauth_provider": user_identity["oauth_provider"],
260
+ "external_id": user_identity["external_id"],
261
+ }
262
+ if user_identity.get("wa_id"):
263
+ check_payload["wa_id"] = user_identity["wa_id"]
264
+ if user_identity.get("tenant_id"):
265
+ check_payload["tenant_id"] = user_identity["tenant_id"]
266
+
267
+ # Add agent_id at top level (not in context)
268
+ check_payload["agent_id"] = context.agent_id
269
+
270
+ # Add minimal context
271
+ check_payload["context"] = {
272
+ "channel_id": context.channel_id,
273
+ "request_id": context.request_id,
274
+ }
275
+
276
+ return check_payload
277
+
278
+
279
+ async def _query_billing_backend(billing_client: httpx.AsyncClient, check_payload: JSONDict) -> JSONDict:
280
+ """Query billing backend for credit status."""
281
+ try:
282
+ response = await billing_client.post(
283
+ "/v1/billing/credits/check",
284
+ json=check_payload,
285
+ )
286
+ response.raise_for_status()
287
+ result: JSONDict = response.json()
288
+ return result
289
+
290
+ except (httpx.HTTPStatusError, httpx.RequestError) as e:
291
+ logger.error(f"Billing API error: {e}", exc_info=True)
292
+ raise HTTPException(status_code=503, detail=ERROR_BILLING_SERVICE_UNAVAILABLE)
293
+
294
+
295
+ def _format_billing_response(credit_data: JSONDict) -> CreditStatusResponse:
296
+ """Format billing backend response for frontend."""
297
+ purchase_options = None
298
+ if credit_data.get("purchase_required"):
299
+ purchase_options = {
300
+ "price_minor": credit_data.get("purchase_price_minor"),
301
+ "uses": credit_data.get("purchase_uses"),
302
+ "currency": "USD",
303
+ }
304
+
305
+ return CreditStatusResponse(
306
+ has_credit=credit_data["has_credit"],
307
+ credits_remaining=credit_data.get("credits_remaining", 0),
308
+ free_uses_remaining=credit_data.get("free_uses_remaining", 0),
309
+ daily_free_uses_remaining=credit_data.get("daily_free_uses_remaining", 0),
310
+ total_uses=credit_data.get("total_uses", 0),
311
+ plan_name=credit_data.get("plan_name"),
312
+ purchase_required=credit_data.get("purchase_required", False),
313
+ purchase_options=purchase_options,
314
+ )
315
+
316
+
317
+ def _get_agent_id(request: Request) -> str:
318
+ """Extract agent_id from request runtime."""
319
+ if hasattr(request.app.state, "runtime") and request.app.state.runtime.agent_identity:
320
+ agent_id: str = request.app.state.runtime.agent_identity.agent_id
321
+ return agent_id
322
+ return "pending"
323
+
324
+
325
+ def _get_credit_provider(request: Request) -> Optional[Any]:
326
+ """Get credit provider from resource monitor, lazily initializing if token is available.
327
+
328
+ This enables the billing provider to be created when:
329
+ 1. Server starts without token
330
+ 2. User logs in (Kotlin writes token to .env)
331
+ 3. Next API call triggers lazy initialization
332
+
333
+ Returns:
334
+ Credit provider instance or None if unavailable and no token to initialize.
335
+ """
336
+ if not hasattr(request.app.state, "resource_monitor"):
337
+ return None
338
+ resource_monitor = request.app.state.resource_monitor
339
+ if not hasattr(resource_monitor, "credit_provider"):
340
+ return None
341
+
342
+ # Return existing provider if available
343
+ if resource_monitor.credit_provider is not None:
344
+ return resource_monitor.credit_provider
345
+
346
+ # Lazy initialization: Try to create billing provider if token is now available
347
+ return _try_lazy_init_billing_provider(request, resource_monitor)
348
+
349
+
350
+ def _try_lazy_init_billing_provider(request: Request, resource_monitor: Any) -> Optional[Any]:
351
+ """Attempt to lazily initialize the billing provider if a token is now available.
352
+
353
+ This handles the case where the Python server starts before the user logs in,
354
+ and the token is written to .env after server startup.
355
+
356
+ Args:
357
+ request: FastAPI request with app state
358
+ resource_monitor: Resource monitor instance to attach provider to
359
+
360
+ Returns:
361
+ Newly created billing provider or None if initialization fails
362
+ """
363
+ import os
364
+
365
+ from dotenv import load_dotenv
366
+
367
+ from ciris_engine.logic.services.infrastructure.resource_monitor.ciris_billing_provider import CIRISBillingProvider
368
+
369
+ # Reload .env to pick up any new values written by Kotlin
370
+ ciris_home = os.environ.get("CIRIS_HOME", "")
371
+ if ciris_home:
372
+ env_path = os.path.join(ciris_home, ".env")
373
+ if os.path.exists(env_path):
374
+ load_dotenv(env_path, override=True)
375
+ logger.debug("[BILLING_LAZY_INIT] Reloaded .env from %s", env_path)
376
+
377
+ # Check for Google ID token (written by Kotlin when user logs in)
378
+ google_token = os.environ.get("CIRIS_BILLING_GOOGLE_ID_TOKEN", "")
379
+ if not google_token:
380
+ logger.debug("[BILLING_LAZY_INIT] No CIRIS_BILLING_GOOGLE_ID_TOKEN in environment")
381
+ return None
382
+
383
+ # Get billing URL from central config (checks env var first)
384
+ billing_url = get_billing_url()
385
+
386
+ logger.info(
387
+ "[BILLING_LAZY_INIT] Token found (%d chars), creating CIRISBillingProvider...",
388
+ len(google_token),
389
+ )
390
+
391
+ try:
392
+ # Create the billing provider with JWT auth
393
+ provider = CIRISBillingProvider(
394
+ google_id_token=google_token,
395
+ base_url=billing_url,
396
+ fail_open=False, # Don't fail open - we want accurate billing status
397
+ cache_ttl_seconds=15,
398
+ )
399
+
400
+ # Attach to resource monitor
401
+ resource_monitor.credit_provider = provider
402
+ logger.info(
403
+ "[BILLING_LAZY_INIT] Successfully created CIRISBillingProvider: base_url=%s, token_length=%d",
404
+ billing_url,
405
+ len(google_token),
406
+ )
407
+ return provider
408
+
409
+ except Exception as exc:
410
+ logger.error("[BILLING_LAZY_INIT] Failed to create CIRISBillingProvider: %s", exc, exc_info=True)
411
+ return None
412
+
413
+
414
+ def _build_mobile_credit_response(result: Any) -> CreditStatusResponse:
415
+ """Build credit response for mobile/JWT mode (no API key)."""
416
+ return CreditStatusResponse(
417
+ has_credit=result.has_credit,
418
+ credits_remaining=result.credits_remaining or 0,
419
+ free_uses_remaining=result.free_uses_remaining or 0,
420
+ daily_free_uses_remaining=result.daily_free_uses_remaining or 0,
421
+ total_uses=0,
422
+ plan_name="CIRIS Mobile",
423
+ purchase_required=not result.has_credit,
424
+ purchase_options={"price_minor": 499, "uses": 100, "currency": "USD"} if not result.has_credit else None,
425
+ )
426
+
427
+
428
+ @router.get("/credits", response_model=CreditStatusResponse)
429
+ async def get_credits(
430
+ request: Request,
431
+ auth: AuthContext = Depends(require_observer),
432
+ ) -> CreditStatusResponse:
433
+ """
434
+ Get user's credit balance and status.
435
+
436
+ Works with both:
437
+ - SimpleCreditProvider (1 free credit per OAuth user, no billing backend needed)
438
+ - CIRISBillingProvider (full billing backend with paid credits)
439
+
440
+ The frontend calls this to display credit status.
441
+ """
442
+ import os
443
+
444
+ from ciris_engine.logic.adapters.api.routes.agent import _derive_credit_account
445
+ from ciris_engine.schemas.services.credit_gate import CreditContext
446
+
447
+ logger.info("[BILLING_API] get_credits called for user_id=%s", auth.user_id)
448
+ user_identity = _extract_user_identity(auth, request)
449
+ agent_id = _get_agent_id(request)
450
+ logger.info("[BILLING_API] agent_id=%s, user_identity=%s", agent_id, user_identity)
451
+
452
+ # Check credit provider availability
453
+ credit_provider = _get_credit_provider(request)
454
+ if credit_provider is None:
455
+ if not hasattr(request.app.state, "resource_monitor"):
456
+ logger.error("[BILLING_API] No resource_monitor on app.state")
457
+ raise HTTPException(status_code=503, detail=ERROR_RESOURCE_MONITOR_UNAVAILABLE)
458
+ logger.info("[BILLING_API] No credit provider, returning unlimited response")
459
+ return _get_unlimited_credit_response()
460
+
461
+ # Query credit provider
462
+ resource_monitor = request.app.state.resource_monitor
463
+ account, _ = _derive_credit_account(auth, request)
464
+ context = CreditContext(agent_id=agent_id, channel_id="api:frontend", request_id=None)
465
+
466
+ try:
467
+ result = await resource_monitor.check_credit(account, context)
468
+ except Exception as e:
469
+ logger.error("Credit check error: %s", e, exc_info=True)
470
+ raise HTTPException(status_code=503, detail=f"Credit check failed: {type(e).__name__}: {e!s}")
471
+
472
+ # Handle SimpleCreditProvider
473
+ if credit_provider.__class__.__name__ == "SimpleCreditProvider":
474
+ return _get_simple_provider_response(result.has_credit)
475
+
476
+ # CIRISBillingProvider: mobile mode (no API key) or server mode
477
+ if not os.getenv("CIRIS_BILLING_API_KEY"):
478
+ logger.info(
479
+ "[BILLING_CREDITS] Using CreditCheckResult (no API key): " "free=%s, paid=%s, has_credit=%s",
480
+ result.free_uses_remaining,
481
+ result.credits_remaining,
482
+ result.has_credit,
483
+ )
484
+ return _build_mobile_credit_response(result)
485
+
486
+ # Server mode with API key - query billing backend
487
+ billing_client = _get_billing_client(request)
488
+ credit_data = await _query_billing_backend(billing_client, _build_credit_check_payload(user_identity, context))
489
+ response = _format_billing_response(credit_data)
490
+ logger.info(
491
+ "[BILLING_CREDITS] Credit check complete: free=%s, paid=%s, has_credit=%s",
492
+ response.free_uses_remaining,
493
+ response.credits_remaining,
494
+ response.has_credit,
495
+ )
496
+ return response
497
+
498
+
499
+ @router.post("/purchase/initiate", response_model=PurchaseInitiateResponse)
500
+ async def initiate_purchase(
501
+ request: Request,
502
+ body: PurchaseInitiateRequest,
503
+ auth: AuthContext = Depends(require_observer),
504
+ ) -> PurchaseInitiateResponse:
505
+ """
506
+ Initiate credit purchase (creates Stripe payment intent).
507
+
508
+ Only works when CIRIS_BILLING_ENABLED=true (CIRISBillingProvider).
509
+ Returns error when SimpleCreditProvider is active (billing disabled).
510
+ """
511
+ # Check if billing is enabled (CIRISBillingProvider vs SimpleCreditProvider)
512
+ if not hasattr(request.app.state, "resource_monitor"):
513
+ raise HTTPException(status_code=503, detail=ERROR_RESOURCE_MONITOR_UNAVAILABLE)
514
+
515
+ resource_monitor = request.app.state.resource_monitor
516
+
517
+ if not hasattr(resource_monitor, "credit_provider") or resource_monitor.credit_provider is None:
518
+ raise HTTPException(status_code=503, detail=ERROR_CREDIT_PROVIDER_NOT_CONFIGURED)
519
+
520
+ is_simple_provider = resource_monitor.credit_provider.__class__.__name__ == "SimpleCreditProvider"
521
+
522
+ if is_simple_provider:
523
+ # Billing not enabled - can't purchase
524
+ raise HTTPException(
525
+ status_code=403,
526
+ detail="Billing not enabled. Contact administrator to enable paid credits.",
527
+ )
528
+
529
+ # Billing enabled - proceed with purchase
530
+ billing_client = _get_billing_client(request)
531
+ user_identity = _extract_user_identity(auth, request)
532
+ agent_id = (
533
+ request.app.state.runtime.agent_identity.agent_id
534
+ if hasattr(request.app.state, "runtime") and request.app.state.runtime.agent_identity
535
+ else "pending"
536
+ )
537
+
538
+ # Get user email (needed for Stripe) - extract from OAuth profile
539
+ customer_email = user_identity.get("customer_email")
540
+ logger.debug(f"Purchase initiate for user_id={auth.user_id} on agent {agent_id}")
541
+ if not customer_email:
542
+ raise HTTPException(
543
+ status_code=400,
544
+ detail="Email address required for purchase. Please authenticate with OAuth provider.",
545
+ )
546
+
547
+ try:
548
+ # Create payment intent via billing backend
549
+ response = await billing_client.post(
550
+ "/v1/billing/purchases",
551
+ json={
552
+ **user_identity,
553
+ "customer_email": customer_email,
554
+ "return_url": body.return_url,
555
+ },
556
+ )
557
+ response.raise_for_status()
558
+ purchase_data = response.json()
559
+
560
+ except httpx.HTTPStatusError as e:
561
+ logger.error(f"Billing API error: {e.response.status_code} - {e.response.text}")
562
+ if e.response.status_code == 400:
563
+ raise HTTPException(status_code=400, detail="Invalid purchase request")
564
+ raise HTTPException(status_code=503, detail="Billing service unavailable")
565
+ except httpx.RequestError as e:
566
+ logger.error(f"Billing API request error: {e}")
567
+ raise HTTPException(status_code=503, detail="Cannot reach billing service")
568
+
569
+ # Get Stripe publishable key from billing backend response (single source of truth)
570
+ publishable_key = purchase_data.get("publishable_key", "pk_test_not_configured")
571
+
572
+ return PurchaseInitiateResponse(
573
+ payment_id=purchase_data["payment_id"],
574
+ client_secret=purchase_data["client_secret"],
575
+ amount_minor=purchase_data["amount_minor"],
576
+ currency=purchase_data["currency"],
577
+ uses_purchased=purchase_data["uses_purchased"],
578
+ publishable_key=publishable_key,
579
+ )
580
+
581
+
582
+ @router.get("/purchase/status/{payment_id}", response_model=PurchaseStatusResponse)
583
+ async def get_purchase_status(
584
+ payment_id: str,
585
+ request: Request,
586
+ auth: AuthContext = Depends(require_observer),
587
+ ) -> PurchaseStatusResponse:
588
+ """
589
+ Check payment status (optional - for polling after payment).
590
+
591
+ Frontend can poll this after initiating payment to confirm credits were added.
592
+ Only works when CIRIS_BILLING_ENABLED=true (CIRISBillingProvider).
593
+ """
594
+ # Validate payment_id to prevent path traversal attacks
595
+ if not PAYMENT_ID_PATTERN.match(payment_id):
596
+ raise HTTPException(status_code=400, detail=ERROR_INVALID_PAYMENT_ID)
597
+
598
+ # Check if billing is enabled
599
+ if not hasattr(request.app.state, "resource_monitor"):
600
+ raise HTTPException(status_code=503, detail=ERROR_RESOURCE_MONITOR_UNAVAILABLE)
601
+
602
+ resource_monitor = request.app.state.resource_monitor
603
+
604
+ if not hasattr(resource_monitor, "credit_provider") or resource_monitor.credit_provider is None:
605
+ raise HTTPException(status_code=503, detail=ERROR_CREDIT_PROVIDER_NOT_CONFIGURED)
606
+
607
+ is_simple_provider = resource_monitor.credit_provider.__class__.__name__ == "SimpleCreditProvider"
608
+
609
+ if is_simple_provider:
610
+ # No purchases possible with SimpleCreditProvider
611
+ raise HTTPException(
612
+ status_code=404,
613
+ detail="Payment not found. Billing not enabled.",
614
+ )
615
+
616
+ # Billing enabled - check payment status
617
+ billing_client = _get_billing_client(request)
618
+ user_identity = _extract_user_identity(auth, request)
619
+
620
+ payment_data = None
621
+ credit_data = None
622
+
623
+ try:
624
+ from typing import Mapping, cast
625
+
626
+ # Query billing backend for specific payment status
627
+ # URL-encode payment_id to prevent path traversal (already validated by PAYMENT_ID_PATTERN)
628
+ safe_payment_id = quote(payment_id, safe="")
629
+ payment_response = await billing_client.get(
630
+ f"/v1/billing/purchases/{safe_payment_id}/status",
631
+ params=cast(Mapping[str, str | int | float | bool | None], user_identity),
632
+ )
633
+ payment_response.raise_for_status()
634
+ payment_data = payment_response.json()
635
+
636
+ # Get updated credit balance
637
+ credits_response = await billing_client.post(
638
+ "/v1/billing/credits/check",
639
+ json={
640
+ **user_identity,
641
+ "context": {"source": "purchase_status_check"},
642
+ },
643
+ )
644
+ credits_response.raise_for_status()
645
+ credit_data = credits_response.json()
646
+
647
+ except httpx.HTTPStatusError as e:
648
+ # If payment not found, return pending status
649
+ if e.response.status_code == 404:
650
+ return PurchaseStatusResponse(
651
+ status="pending",
652
+ credits_added=0,
653
+ balance_after=None,
654
+ )
655
+ logger.error(f"Billing API error: {e}")
656
+ raise HTTPException(status_code=503, detail=ERROR_BILLING_SERVICE_UNAVAILABLE)
657
+ except httpx.RequestError as e:
658
+ logger.error(f"Billing API request error: {e}")
659
+ raise HTTPException(status_code=503, detail=ERROR_BILLING_SERVICE_UNAVAILABLE)
660
+
661
+ # Extract payment status and amount from billing backend response
662
+ payment_status = payment_data.get("status", "unknown")
663
+ credits_added = payment_data.get("credits_added", 0)
664
+
665
+ return PurchaseStatusResponse(
666
+ status=payment_status,
667
+ credits_added=credits_added,
668
+ balance_after=credit_data.get("credits_remaining"),
669
+ )
670
+
671
+
672
+ @router.get("/transactions", response_model=TransactionListResponse)
673
+ async def get_transactions(
674
+ request: Request,
675
+ auth: AuthContext = Depends(require_observer),
676
+ limit: int = 50,
677
+ offset: int = 0,
678
+ ) -> TransactionListResponse:
679
+ """
680
+ Get transaction history for the current user.
681
+
682
+ Returns a paginated list of all transactions (charges and credits) in reverse chronological order.
683
+
684
+ Only works when CIRIS_BILLING_ENABLED=true (CIRISBillingProvider).
685
+ Returns empty list when SimpleCreditProvider is active (billing disabled).
686
+ """
687
+ # Check if billing is enabled (CIRISBillingProvider vs SimpleCreditProvider)
688
+ if not hasattr(request.app.state, "resource_monitor"):
689
+ raise HTTPException(status_code=503, detail=ERROR_RESOURCE_MONITOR_UNAVAILABLE)
690
+
691
+ resource_monitor = request.app.state.resource_monitor
692
+
693
+ if not hasattr(resource_monitor, "credit_provider") or resource_monitor.credit_provider is None:
694
+ # No credit provider - return empty list
695
+ return TransactionListResponse(transactions=[], total_count=0, has_more=False)
696
+
697
+ is_simple_provider = resource_monitor.credit_provider.__class__.__name__ == "SimpleCreditProvider"
698
+
699
+ if is_simple_provider:
700
+ # SimpleCreditProvider doesn't track transactions - return empty list
701
+ return TransactionListResponse(transactions=[], total_count=0, has_more=False)
702
+
703
+ # CIRISBillingProvider - query billing backend for transaction history
704
+ logger.info(f"[BILLING_TRANSACTIONS] Fetching transactions (limit={limit}, offset={offset})")
705
+ billing_client = _get_billing_client(request)
706
+ user_identity = _extract_user_identity(auth, request)
707
+
708
+ try:
709
+ from typing import Mapping, cast
710
+
711
+ # Build query parameters for billing backend - cast to expected types
712
+ oauth_provider = str(user_identity["oauth_provider"])
713
+ external_id = str(user_identity["external_id"])
714
+
715
+ params: dict[str, str | int] = {
716
+ "oauth_provider": oauth_provider,
717
+ "external_id": external_id,
718
+ "limit": limit,
719
+ "offset": offset,
720
+ }
721
+
722
+ # Add optional parameters if present
723
+ wa_id = user_identity.get("wa_id")
724
+ if wa_id:
725
+ params["wa_id"] = str(wa_id)
726
+ tenant_id = user_identity.get("tenant_id")
727
+ if tenant_id:
728
+ params["tenant_id"] = str(tenant_id)
729
+
730
+ # Log request details for debugging (without PII)
731
+ logger.debug(
732
+ f"[BILLING_TRANSACTIONS] Request to billing backend: "
733
+ f"oauth_provider={params.get('oauth_provider')}, "
734
+ f"external_id={params.get('external_id')}, "
735
+ f"wa_id={params.get('wa_id')}, "
736
+ f"has_email={user_identity.get('customer_email') is not None}"
737
+ )
738
+
739
+ # Query billing backend
740
+ response = await billing_client.get(
741
+ "/v1/billing/transactions",
742
+ params=cast(Mapping[str, str | int | float | bool | None], params),
743
+ )
744
+ response.raise_for_status()
745
+ transaction_data: JSONDict = response.json()
746
+
747
+ # Map backend response to our schema - safely extract and validate transactions list
748
+ transactions_raw = transaction_data.get("transactions", [])
749
+ if not isinstance(transactions_raw, list):
750
+ transactions_raw = []
751
+ transactions = [TransactionItem(**txn) for txn in transactions_raw if isinstance(txn, dict)]
752
+
753
+ logger.info(
754
+ f"[BILLING_TRANSACTIONS] Returning {len(transactions)} transactions "
755
+ f"(total={transaction_data.get('total_count', 0)}, has_more={transaction_data.get('has_more', False)})"
756
+ )
757
+ return TransactionListResponse(
758
+ transactions=transactions,
759
+ total_count=transaction_data.get("total_count", 0),
760
+ has_more=transaction_data.get("has_more", False),
761
+ )
762
+
763
+ except httpx.HTTPStatusError as e:
764
+ # Safely extract request details for logging
765
+ try:
766
+ headers_str = str(dict(e.request.headers))
767
+ except (TypeError, AttributeError):
768
+ headers_str = "<unavailable>"
769
+
770
+ logger.error(
771
+ f"Billing API error fetching transactions: {e.response.status_code} - {e.response.text}\n"
772
+ f"Request URL: {e.request.url}\n"
773
+ f"Request headers: {headers_str}"
774
+ )
775
+ if e.response.status_code == 404:
776
+ # Account not found - return empty list
777
+ return TransactionListResponse(transactions=[], total_count=0, has_more=False)
778
+ if e.response.status_code == 401:
779
+ # Authentication failed - log details and return empty
780
+ logger.error("401 Unauthorized - API key may be invalid or missing")
781
+ return TransactionListResponse(transactions=[], total_count=0, has_more=False)
782
+ raise HTTPException(status_code=503, detail=ERROR_BILLING_SERVICE_UNAVAILABLE)
783
+ except httpx.RequestError as e:
784
+ logger.error(f"Billing API request error: {e}")
785
+ raise HTTPException(status_code=503, detail=ERROR_BILLING_SERVICE_UNAVAILABLE)
786
+
787
+
788
+ # Google Play verification models
789
+
790
+
791
+ class GooglePlayVerifyRequest(BaseModel):
792
+ """Request to verify a Google Play purchase."""
793
+
794
+ purchase_token: str = Field(..., description="Google Play purchase token")
795
+ product_id: str = Field(..., description="Product SKU (e.g., 'credits_100')")
796
+ package_name: str = Field(..., description="App package name")
797
+
798
+
799
+ class GooglePlayVerifyResponse(BaseModel):
800
+ """Response from Google Play purchase verification."""
801
+
802
+ success: bool = Field(..., description="Whether verification succeeded")
803
+ credits_added: int = Field(0, description="Credits added from this purchase")
804
+ new_balance: int = Field(0, description="New credit balance after purchase")
805
+ already_processed: bool = Field(False, description="Whether purchase was already processed")
806
+ error: Optional[str] = Field(None, description="Error message if verification failed")
807
+
808
+
809
+ @router.post("/google-play/verify", response_model=GooglePlayVerifyResponse)
810
+ async def verify_google_play_purchase(
811
+ request: Request,
812
+ body: GooglePlayVerifyRequest,
813
+ auth: AuthContext = Depends(require_observer),
814
+ ) -> GooglePlayVerifyResponse:
815
+ """
816
+ Verify a Google Play purchase and add credits.
817
+
818
+ This endpoint proxies the verification request to the billing backend,
819
+ which validates the purchase token with Google Play and adds credits.
820
+
821
+ Supports two authentication modes:
822
+ 1. Server mode: Uses CIRIS_BILLING_API_KEY (agents.ciris.ai)
823
+ 2. JWT pass-through: Uses Bearer token from request (Android/native)
824
+
825
+ Only works when CIRISBillingProvider is configured.
826
+ """
827
+ logger.info(f"[GOOGLE_PLAY_VERIFY] Verifying purchase for user_id={auth.user_id}, product={body.product_id}")
828
+
829
+ # Check if billing is enabled
830
+ if not hasattr(request.app.state, "resource_monitor"):
831
+ return GooglePlayVerifyResponse(success=False, error=ERROR_RESOURCE_MONITOR_UNAVAILABLE)
832
+
833
+ resource_monitor = request.app.state.resource_monitor
834
+
835
+ if not hasattr(resource_monitor, "credit_provider") or resource_monitor.credit_provider is None:
836
+ return GooglePlayVerifyResponse(success=False, error=ERROR_CREDIT_PROVIDER_NOT_CONFIGURED)
837
+
838
+ is_simple_provider = resource_monitor.credit_provider.__class__.__name__ == "SimpleCreditProvider"
839
+
840
+ if is_simple_provider:
841
+ return GooglePlayVerifyResponse(
842
+ success=False, error="Google Play purchases not supported - billing backend not configured"
843
+ )
844
+
845
+ # Extract user identity for billing backend
846
+ user_identity = _extract_user_identity(auth, request)
847
+
848
+ # Build verification request for billing backend
849
+ verify_payload = {
850
+ "oauth_provider": user_identity["oauth_provider"],
851
+ "external_id": user_identity["external_id"],
852
+ "email": user_identity.get("customer_email"),
853
+ "display_name": None, # Not needed for verification
854
+ "purchase_token": body.purchase_token,
855
+ "product_id": body.product_id,
856
+ "package_name": body.package_name,
857
+ }
858
+
859
+ logger.info(
860
+ f"[GOOGLE_PLAY_VERIFY] Sending to billing backend: oauth_provider={verify_payload['oauth_provider']}"
861
+ ) # NOSONAR - provider type not secret
862
+
863
+ # Get Google ID token for JWT pass-through mode (Android/native)
864
+ # Android sends this in X-Google-ID-Token header for billing backend auth
865
+ google_id_token = request.headers.get("X-Google-ID-Token")
866
+ if google_id_token:
867
+ logger.info(f"[GOOGLE_PLAY_VERIFY] Using JWT pass-through with Google ID token ({len(google_id_token)} chars)")
868
+ billing_client = _get_billing_client(request, google_id_token=google_id_token)
869
+
870
+ try:
871
+ response = await billing_client.post(
872
+ "/v1/billing/google-play/verify",
873
+ json=verify_payload,
874
+ )
875
+ response.raise_for_status()
876
+ result = response.json()
877
+
878
+ logger.info(
879
+ f"[GOOGLE_PLAY_VERIFY] Success: credits_added={result.get('credits_added')}, "
880
+ f"new_balance={result.get('new_balance')}, already_processed={result.get('already_processed')}"
881
+ )
882
+
883
+ return GooglePlayVerifyResponse(
884
+ success=result.get("success", False),
885
+ credits_added=result.get("credits_added", 0),
886
+ new_balance=result.get("new_balance", 0),
887
+ already_processed=result.get("already_processed", False),
888
+ )
889
+
890
+ except httpx.HTTPStatusError as e:
891
+ logger.error(f"[GOOGLE_PLAY_VERIFY] Billing API error: {e.response.status_code} - {e.response.text}")
892
+ return GooglePlayVerifyResponse(success=False, error=f"Verification failed: {e.response.status_code}")
893
+ except httpx.RequestError as e:
894
+ logger.error(f"[GOOGLE_PLAY_VERIFY] Request error: {e}")
895
+ return GooglePlayVerifyResponse(success=False, error=f"Network error: {str(e)}")