@ixo/common 1.1.0

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 (328) hide show
  1. package/.eslintrc.js +9 -0
  2. package/.prettierignore +3 -0
  3. package/.prettierrc.cjs +4 -0
  4. package/.turbo/turbo-build.log +4 -0
  5. package/CHANGELOG.md +76 -0
  6. package/README.md +245 -0
  7. package/dist/ai/checkpointer/index.d.ts +2 -0
  8. package/dist/ai/checkpointer/index.d.ts.map +1 -0
  9. package/dist/ai/checkpointer/index.js +2 -0
  10. package/dist/ai/checkpointer/index.js.map +1 -0
  11. package/dist/ai/index.d.ts +9 -0
  12. package/dist/ai/index.d.ts.map +1 -0
  13. package/dist/ai/index.js +9 -0
  14. package/dist/ai/index.js.map +1 -0
  15. package/dist/ai/models/index.d.ts +2 -0
  16. package/dist/ai/models/index.d.ts.map +1 -0
  17. package/dist/ai/models/index.js +2 -0
  18. package/dist/ai/models/index.js.map +1 -0
  19. package/dist/ai/models/openai.d.ts +10 -0
  20. package/dist/ai/models/openai.d.ts.map +1 -0
  21. package/dist/ai/models/openai.js +38 -0
  22. package/dist/ai/models/openai.js.map +1 -0
  23. package/dist/ai/models/openai.test.d.ts +2 -0
  24. package/dist/ai/models/openai.test.d.ts.map +1 -0
  25. package/dist/ai/models/openai.test.js +58 -0
  26. package/dist/ai/models/openai.test.js.map +1 -0
  27. package/dist/ai/nodes/create-fake-node.d.ts +2 -0
  28. package/dist/ai/nodes/create-fake-node.d.ts.map +1 -0
  29. package/dist/ai/nodes/create-fake-node.js +2 -0
  30. package/dist/ai/nodes/create-fake-node.js.map +1 -0
  31. package/dist/ai/nodes/find-docs/find-docs.prompt.d.ts +3 -0
  32. package/dist/ai/nodes/find-docs/find-docs.prompt.d.ts.map +1 -0
  33. package/dist/ai/nodes/find-docs/find-docs.prompt.js +61 -0
  34. package/dist/ai/nodes/find-docs/find-docs.prompt.js.map +1 -0
  35. package/dist/ai/nodes/find-docs/index.d.ts +3 -0
  36. package/dist/ai/nodes/find-docs/index.d.ts.map +1 -0
  37. package/dist/ai/nodes/find-docs/index.js +3 -0
  38. package/dist/ai/nodes/find-docs/index.js.map +1 -0
  39. package/dist/ai/nodes/find-docs/node.d.ts +17 -0
  40. package/dist/ai/nodes/find-docs/node.d.ts.map +1 -0
  41. package/dist/ai/nodes/find-docs/node.js +46 -0
  42. package/dist/ai/nodes/find-docs/node.js.map +1 -0
  43. package/dist/ai/nodes/generic-chat/generic-chat.node.d.ts +12 -0
  44. package/dist/ai/nodes/generic-chat/generic-chat.node.d.ts.map +1 -0
  45. package/dist/ai/nodes/generic-chat/generic-chat.node.js +34 -0
  46. package/dist/ai/nodes/generic-chat/generic-chat.node.js.map +1 -0
  47. package/dist/ai/nodes/generic-chat/generic-chat.prompt.d.ts +10 -0
  48. package/dist/ai/nodes/generic-chat/generic-chat.prompt.d.ts.map +1 -0
  49. package/dist/ai/nodes/generic-chat/generic-chat.prompt.js +58 -0
  50. package/dist/ai/nodes/generic-chat/generic-chat.prompt.js.map +1 -0
  51. package/dist/ai/nodes/generic-chat/index.d.ts +2 -0
  52. package/dist/ai/nodes/generic-chat/index.d.ts.map +1 -0
  53. package/dist/ai/nodes/generic-chat/index.js +2 -0
  54. package/dist/ai/nodes/generic-chat/index.js.map +1 -0
  55. package/dist/ai/nodes/index.d.ts +4 -0
  56. package/dist/ai/nodes/index.d.ts.map +1 -0
  57. package/dist/ai/nodes/index.js +4 -0
  58. package/dist/ai/nodes/index.js.map +1 -0
  59. package/dist/ai/semantic-router-factory/create-semantic-router.d.ts +7 -0
  60. package/dist/ai/semantic-router-factory/create-semantic-router.d.ts.map +1 -0
  61. package/dist/ai/semantic-router-factory/create-semantic-router.js +71 -0
  62. package/dist/ai/semantic-router-factory/create-semantic-router.js.map +1 -0
  63. package/dist/ai/semantic-router-factory/create-semantic-router.test.d.ts +2 -0
  64. package/dist/ai/semantic-router-factory/create-semantic-router.test.d.ts.map +1 -0
  65. package/dist/ai/semantic-router-factory/create-semantic-router.test.js +68 -0
  66. package/dist/ai/semantic-router-factory/create-semantic-router.test.js.map +1 -0
  67. package/dist/ai/semantic-router-factory/index.d.ts +4 -0
  68. package/dist/ai/semantic-router-factory/index.d.ts.map +1 -0
  69. package/dist/ai/semantic-router-factory/index.js +4 -0
  70. package/dist/ai/semantic-router-factory/index.js.map +1 -0
  71. package/dist/ai/semantic-router-factory/semantic-router-prompt.d.ts +2 -0
  72. package/dist/ai/semantic-router-factory/semantic-router-prompt.d.ts.map +1 -0
  73. package/dist/ai/semantic-router-factory/semantic-router-prompt.js +169 -0
  74. package/dist/ai/semantic-router-factory/semantic-router-prompt.js.map +1 -0
  75. package/dist/ai/semantic-router-factory/validate-routes.d.ts +2 -0
  76. package/dist/ai/semantic-router-factory/validate-routes.d.ts.map +1 -0
  77. package/dist/ai/semantic-router-factory/validate-routes.js +16 -0
  78. package/dist/ai/semantic-router-factory/validate-routes.js.map +1 -0
  79. package/dist/ai/tools/action-caller.d.ts +14 -0
  80. package/dist/ai/tools/action-caller.d.ts.map +1 -0
  81. package/dist/ai/tools/action-caller.js +12 -0
  82. package/dist/ai/tools/action-caller.js.map +1 -0
  83. package/dist/ai/tools/ask-ixo-guru/ask-ixo-guru.d.ts +25 -0
  84. package/dist/ai/tools/ask-ixo-guru/ask-ixo-guru.d.ts.map +1 -0
  85. package/dist/ai/tools/ask-ixo-guru/ask-ixo-guru.js +46 -0
  86. package/dist/ai/tools/ask-ixo-guru/ask-ixo-guru.js.map +1 -0
  87. package/dist/ai/tools/ask-ixo-guru/index.d.ts +2 -0
  88. package/dist/ai/tools/ask-ixo-guru/index.d.ts.map +1 -0
  89. package/dist/ai/tools/ask-ixo-guru/index.js +2 -0
  90. package/dist/ai/tools/ask-ixo-guru/index.js.map +1 -0
  91. package/dist/ai/tools/browser-tool-caller.d.ts +14 -0
  92. package/dist/ai/tools/browser-tool-caller.d.ts.map +1 -0
  93. package/dist/ai/tools/browser-tool-caller.js +12 -0
  94. package/dist/ai/tools/browser-tool-caller.js.map +1 -0
  95. package/dist/ai/tools/frontend-tool-caller.d.ts +10 -0
  96. package/dist/ai/tools/frontend-tool-caller.d.ts.map +1 -0
  97. package/dist/ai/tools/frontend-tool-caller.js +50 -0
  98. package/dist/ai/tools/frontend-tool-caller.js.map +1 -0
  99. package/dist/ai/tools/index.d.ts +11 -0
  100. package/dist/ai/tools/index.d.ts.map +1 -0
  101. package/dist/ai/tools/index.js +11 -0
  102. package/dist/ai/tools/index.js.map +1 -0
  103. package/dist/ai/tools/log-action-to-matrix.d.ts +13 -0
  104. package/dist/ai/tools/log-action-to-matrix.d.ts.map +1 -0
  105. package/dist/ai/tools/log-action-to-matrix.js +14 -0
  106. package/dist/ai/tools/log-action-to-matrix.js.map +1 -0
  107. package/dist/ai/tools/parser-action-tool.d.ts +8 -0
  108. package/dist/ai/tools/parser-action-tool.d.ts.map +1 -0
  109. package/dist/ai/tools/parser-action-tool.js +40 -0
  110. package/dist/ai/tools/parser-action-tool.js.map +1 -0
  111. package/dist/ai/tools/parser-browser-tool.d.ts +8 -0
  112. package/dist/ai/tools/parser-browser-tool.d.ts.map +1 -0
  113. package/dist/ai/tools/parser-browser-tool.js +38 -0
  114. package/dist/ai/tools/parser-browser-tool.js.map +1 -0
  115. package/dist/ai/tools/retriever-tool/index.d.ts +2 -0
  116. package/dist/ai/tools/retriever-tool/index.d.ts.map +1 -0
  117. package/dist/ai/tools/retriever-tool/index.js +2 -0
  118. package/dist/ai/tools/retriever-tool/index.js.map +1 -0
  119. package/dist/ai/tools/retriever-tool/retriever-tool.d.ts +18 -0
  120. package/dist/ai/tools/retriever-tool/retriever-tool.d.ts.map +1 -0
  121. package/dist/ai/tools/retriever-tool/retriever-tool.js +62 -0
  122. package/dist/ai/tools/retriever-tool/retriever-tool.js.map +1 -0
  123. package/dist/ai/tools/retriever-tool/retriever-tool.test.d.ts +2 -0
  124. package/dist/ai/tools/retriever-tool/retriever-tool.test.d.ts.map +1 -0
  125. package/dist/ai/tools/retriever-tool/retriever-tool.test.js +119 -0
  126. package/dist/ai/tools/retriever-tool/retriever-tool.test.js.map +1 -0
  127. package/dist/ai/tools/scrape-web-page.d.ts +7 -0
  128. package/dist/ai/tools/scrape-web-page.d.ts.map +1 -0
  129. package/dist/ai/tools/scrape-web-page.js +65 -0
  130. package/dist/ai/tools/scrape-web-page.js.map +1 -0
  131. package/dist/ai/tools/web-search-tool.d.ts +10 -0
  132. package/dist/ai/tools/web-search-tool.d.ts.map +1 -0
  133. package/dist/ai/tools/web-search-tool.js +30 -0
  134. package/dist/ai/tools/web-search-tool.js.map +1 -0
  135. package/dist/ai/types.d.ts +4 -0
  136. package/dist/ai/types.d.ts.map +1 -0
  137. package/dist/ai/types.js +2 -0
  138. package/dist/ai/types.js.map +1 -0
  139. package/dist/ai/utils/__tests__/chunk-arr.test.d.ts +2 -0
  140. package/dist/ai/utils/__tests__/chunk-arr.test.d.ts.map +1 -0
  141. package/dist/ai/utils/__tests__/chunk-arr.test.js +37 -0
  142. package/dist/ai/utils/__tests__/chunk-arr.test.js.map +1 -0
  143. package/dist/ai/utils/__tests__/doc-relevance-checker.test.d.ts +2 -0
  144. package/dist/ai/utils/__tests__/doc-relevance-checker.test.d.ts.map +1 -0
  145. package/dist/ai/utils/__tests__/doc-relevance-checker.test.js +80 -0
  146. package/dist/ai/utils/__tests__/doc-relevance-checker.test.js.map +1 -0
  147. package/dist/ai/utils/__tests__/doc-splitter.test.d.ts +2 -0
  148. package/dist/ai/utils/__tests__/doc-splitter.test.d.ts.map +1 -0
  149. package/dist/ai/utils/__tests__/doc-splitter.test.js +35 -0
  150. package/dist/ai/utils/__tests__/doc-splitter.test.js.map +1 -0
  151. package/dist/ai/utils/__tests__/filter-similarity-search-results.test.d.ts +2 -0
  152. package/dist/ai/utils/__tests__/filter-similarity-search-results.test.d.ts.map +1 -0
  153. package/dist/ai/utils/__tests__/filter-similarity-search-results.test.js +47 -0
  154. package/dist/ai/utils/__tests__/filter-similarity-search-results.test.js.map +1 -0
  155. package/dist/ai/utils/__tests__/json-to-yaml.test.d.ts +2 -0
  156. package/dist/ai/utils/__tests__/json-to-yaml.test.d.ts.map +1 -0
  157. package/dist/ai/utils/__tests__/json-to-yaml.test.js +63 -0
  158. package/dist/ai/utils/__tests__/json-to-yaml.test.js.map +1 -0
  159. package/dist/ai/utils/__tests__/stringify-docs.test.d.ts +2 -0
  160. package/dist/ai/utils/__tests__/stringify-docs.test.d.ts.map +1 -0
  161. package/dist/ai/utils/__tests__/stringify-docs.test.js +54 -0
  162. package/dist/ai/utils/__tests__/stringify-docs.test.js.map +1 -0
  163. package/dist/ai/utils/chunk-arr.d.ts +3 -0
  164. package/dist/ai/utils/chunk-arr.d.ts.map +1 -0
  165. package/dist/ai/utils/chunk-arr.js +13 -0
  166. package/dist/ai/utils/chunk-arr.js.map +1 -0
  167. package/dist/ai/utils/doc-relevance-checker.d.ts +10 -0
  168. package/dist/ai/utils/doc-relevance-checker.d.ts.map +1 -0
  169. package/dist/ai/utils/doc-relevance-checker.js +37 -0
  170. package/dist/ai/utils/doc-relevance-checker.js.map +1 -0
  171. package/dist/ai/utils/doc-splitter.d.ts +3 -0
  172. package/dist/ai/utils/doc-splitter.d.ts.map +1 -0
  173. package/dist/ai/utils/doc-splitter.js +20 -0
  174. package/dist/ai/utils/doc-splitter.js.map +1 -0
  175. package/dist/ai/utils/filter-similarity-search-results.d.ts +4 -0
  176. package/dist/ai/utils/filter-similarity-search-results.d.ts.map +1 -0
  177. package/dist/ai/utils/filter-similarity-search-results.js +11 -0
  178. package/dist/ai/utils/filter-similarity-search-results.js.map +1 -0
  179. package/dist/ai/utils/generate-questions-from-chunks.d.ts +15 -0
  180. package/dist/ai/utils/generate-questions-from-chunks.d.ts.map +1 -0
  181. package/dist/ai/utils/generate-questions-from-chunks.js +101 -0
  182. package/dist/ai/utils/generate-questions-from-chunks.js.map +1 -0
  183. package/dist/ai/utils/index.d.ts +11 -0
  184. package/dist/ai/utils/index.d.ts.map +1 -0
  185. package/dist/ai/utils/index.js +11 -0
  186. package/dist/ai/utils/index.js.map +1 -0
  187. package/dist/ai/utils/json-to-yaml.d.ts +2 -0
  188. package/dist/ai/utils/json-to-yaml.d.ts.map +1 -0
  189. package/dist/ai/utils/json-to-yaml.js +25 -0
  190. package/dist/ai/utils/json-to-yaml.js.map +1 -0
  191. package/dist/ai/utils/load-file.d.ts +3 -0
  192. package/dist/ai/utils/load-file.d.ts.map +1 -0
  193. package/dist/ai/utils/load-file.js +133 -0
  194. package/dist/ai/utils/load-file.js.map +1 -0
  195. package/dist/ai/utils/stringify-docs.d.ts +3 -0
  196. package/dist/ai/utils/stringify-docs.d.ts.map +1 -0
  197. package/dist/ai/utils/stringify-docs.js +6 -0
  198. package/dist/ai/utils/stringify-docs.js.map +1 -0
  199. package/dist/ai/utils/transformGraphStateMessageToListMessageResponse.d.ts +35 -0
  200. package/dist/ai/utils/transformGraphStateMessageToListMessageResponse.d.ts.map +1 -0
  201. package/dist/ai/utils/transformGraphStateMessageToListMessageResponse.js +55 -0
  202. package/dist/ai/utils/transformGraphStateMessageToListMessageResponse.js.map +1 -0
  203. package/dist/ai/utils/verify-matrix-openId-token.d.ts +6 -0
  204. package/dist/ai/utils/verify-matrix-openId-token.d.ts.map +1 -0
  205. package/dist/ai/utils/verify-matrix-openId-token.js +36 -0
  206. package/dist/ai/utils/verify-matrix-openId-token.js.map +1 -0
  207. package/dist/index.d.ts +4 -0
  208. package/dist/index.d.ts.map +1 -0
  209. package/dist/index.js +4 -0
  210. package/dist/index.js.map +1 -0
  211. package/dist/services/env/env-service.test.d.ts +2 -0
  212. package/dist/services/env/env-service.test.d.ts.map +1 -0
  213. package/dist/services/env/env-service.test.js +99 -0
  214. package/dist/services/env/env-service.test.js.map +1 -0
  215. package/dist/services/env/env.service.d.ts +11 -0
  216. package/dist/services/env/env.service.d.ts.map +1 -0
  217. package/dist/services/env/env.service.js +42 -0
  218. package/dist/services/env/env.service.js.map +1 -0
  219. package/dist/services/env/index.d.ts +2 -0
  220. package/dist/services/env/index.d.ts.map +1 -0
  221. package/dist/services/env/index.js +2 -0
  222. package/dist/services/env/index.js.map +1 -0
  223. package/dist/services/index.d.ts +5 -0
  224. package/dist/services/index.d.ts.map +1 -0
  225. package/dist/services/index.js +5 -0
  226. package/dist/services/index.js.map +1 -0
  227. package/dist/services/memory-engine/memory-engine.service.d.ts +35 -0
  228. package/dist/services/memory-engine/memory-engine.service.d.ts.map +1 -0
  229. package/dist/services/memory-engine/memory-engine.service.js +295 -0
  230. package/dist/services/memory-engine/memory-engine.service.js.map +1 -0
  231. package/dist/services/memory-engine/types.d.ts +88 -0
  232. package/dist/services/memory-engine/types.d.ts.map +1 -0
  233. package/dist/services/memory-engine/types.js +2 -0
  234. package/dist/services/memory-engine/types.js.map +1 -0
  235. package/dist/services/session-manager/dto.d.ts +40 -0
  236. package/dist/services/session-manager/dto.d.ts.map +1 -0
  237. package/dist/services/session-manager/dto.js +170 -0
  238. package/dist/services/session-manager/dto.js.map +1 -0
  239. package/dist/services/session-manager/errors.d.ts +22 -0
  240. package/dist/services/session-manager/errors.d.ts.map +1 -0
  241. package/dist/services/session-manager/errors.js +41 -0
  242. package/dist/services/session-manager/errors.js.map +1 -0
  243. package/dist/services/session-manager/index.d.ts +4 -0
  244. package/dist/services/session-manager/index.d.ts.map +1 -0
  245. package/dist/services/session-manager/index.js +4 -0
  246. package/dist/services/session-manager/index.js.map +1 -0
  247. package/dist/services/session-manager/session-manager.service.d.ts +40 -0
  248. package/dist/services/session-manager/session-manager.service.d.ts.map +1 -0
  249. package/dist/services/session-manager/session-manager.service.js +251 -0
  250. package/dist/services/session-manager/session-manager.service.js.map +1 -0
  251. package/dist/utils/get-user-subscription.d.ts +21 -0
  252. package/dist/utils/get-user-subscription.d.ts.map +1 -0
  253. package/dist/utils/get-user-subscription.js +44 -0
  254. package/dist/utils/get-user-subscription.js.map +1 -0
  255. package/dist/utils/index.d.ts +2 -0
  256. package/dist/utils/index.d.ts.map +1 -0
  257. package/dist/utils/index.js +2 -0
  258. package/dist/utils/index.js.map +1 -0
  259. package/docs/ai-module.md +84 -0
  260. package/docs/services.md +168 -0
  261. package/docs/tools.md +325 -0
  262. package/jest.config.js +6 -0
  263. package/package.json +81 -0
  264. package/src/ai/checkpointer/index.ts +1 -0
  265. package/src/ai/index.ts +8 -0
  266. package/src/ai/models/index.ts +1 -0
  267. package/src/ai/models/openai.test.ts +72 -0
  268. package/src/ai/models/openai.ts +54 -0
  269. package/src/ai/nodes/create-fake-node.ts +1 -0
  270. package/src/ai/nodes/find-docs/find-docs.prompt.ts +61 -0
  271. package/src/ai/nodes/find-docs/index.ts +2 -0
  272. package/src/ai/nodes/find-docs/node.ts +83 -0
  273. package/src/ai/nodes/generic-chat/generic-chat.node.ts +58 -0
  274. package/src/ai/nodes/generic-chat/generic-chat.prompt.ts +66 -0
  275. package/src/ai/nodes/generic-chat/index.ts +1 -0
  276. package/src/ai/nodes/index.ts +3 -0
  277. package/src/ai/semantic-router-factory/create-semantic-router.test.ts +98 -0
  278. package/src/ai/semantic-router-factory/create-semantic-router.ts +136 -0
  279. package/src/ai/semantic-router-factory/index.ts +3 -0
  280. package/src/ai/semantic-router-factory/semantic-router-prompt.ts +168 -0
  281. package/src/ai/semantic-router-factory/validate-routes.ts +26 -0
  282. package/src/ai/tools/action-caller.ts +37 -0
  283. package/src/ai/tools/ask-ixo-guru/ask-ixo-guru.ts +73 -0
  284. package/src/ai/tools/ask-ixo-guru/index.ts +1 -0
  285. package/src/ai/tools/browser-tool-caller.ts +37 -0
  286. package/src/ai/tools/frontend-tool-caller.ts +86 -0
  287. package/src/ai/tools/index.ts +10 -0
  288. package/src/ai/tools/log-action-to-matrix.ts +30 -0
  289. package/src/ai/tools/parser-action-tool.ts +61 -0
  290. package/src/ai/tools/parser-browser-tool.ts +55 -0
  291. package/src/ai/tools/retriever-tool/index.ts +1 -0
  292. package/src/ai/tools/retriever-tool/retriever-tool.test.ts +156 -0
  293. package/src/ai/tools/retriever-tool/retriever-tool.ts +107 -0
  294. package/src/ai/tools/scrape-web-page.ts +75 -0
  295. package/src/ai/tools/web-search-tool.ts +38 -0
  296. package/src/ai/types.ts +6 -0
  297. package/src/ai/utils/__tests__/chunk-arr.test.ts +46 -0
  298. package/src/ai/utils/__tests__/doc-relevance-checker.test.ts +90 -0
  299. package/src/ai/utils/__tests__/doc-splitter.test.ts +42 -0
  300. package/src/ai/utils/__tests__/filter-similarity-search-results.test.ts +57 -0
  301. package/src/ai/utils/__tests__/json-to-yaml.test.ts +70 -0
  302. package/src/ai/utils/__tests__/stringify-docs.test.ts +61 -0
  303. package/src/ai/utils/chunk-arr.ts +13 -0
  304. package/src/ai/utils/doc-relevance-checker.ts +58 -0
  305. package/src/ai/utils/doc-splitter.ts +28 -0
  306. package/src/ai/utils/filter-similarity-search-results.ts +15 -0
  307. package/src/ai/utils/generate-questions-from-chunks.ts +114 -0
  308. package/src/ai/utils/index.ts +10 -0
  309. package/src/ai/utils/json-to-yaml.ts +32 -0
  310. package/src/ai/utils/load-file.ts +170 -0
  311. package/src/ai/utils/stringify-docs.ts +14 -0
  312. package/src/ai/utils/transformGraphStateMessageToListMessageResponse.ts +108 -0
  313. package/src/ai/utils/verify-matrix-openId-token.ts +46 -0
  314. package/src/index.ts +3 -0
  315. package/src/services/env/env-service.test.ts +153 -0
  316. package/src/services/env/env.service.ts +65 -0
  317. package/src/services/env/index.ts +1 -0
  318. package/src/services/index.ts +4 -0
  319. package/src/services/memory-engine/memory-engine.service.ts +486 -0
  320. package/src/services/memory-engine/types.ts +208 -0
  321. package/src/services/session-manager/dto.ts +120 -0
  322. package/src/services/session-manager/errors.ts +56 -0
  323. package/src/services/session-manager/index.ts +3 -0
  324. package/src/services/session-manager/session-manager.service.ts +405 -0
  325. package/src/utils/get-user-subscription.ts +84 -0
  326. package/src/utils/index.ts +1 -0
  327. package/tsconfig.json +16 -0
  328. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,405 @@
1
+ import { Logger } from '@ixo/logger';
2
+ import { MatrixManager } from '@ixo/matrix';
3
+ import { getMatrixHomeServerCroppedForDid } from '@ixo/oracles-chain-client';
4
+ import { Database } from 'better-sqlite3';
5
+ import { getChatOpenAiModel } from '../../ai/index.js';
6
+ import { MemoryEngineService } from '../memory-engine/memory-engine.service.js';
7
+ import { type UserContextData } from '../memory-engine/types.js';
8
+ import {
9
+ type ChatSession,
10
+ type CreateChatSessionDto,
11
+ type CreateChatSessionResponseDto,
12
+ type DeleteChatSessionDto,
13
+ type ListChatSessionsDto,
14
+ type ListChatSessionsResponseDto,
15
+ } from './dto.js';
16
+
17
+ export interface IDatabaseSyncService {
18
+ getUserDatabase(userDid: string): Promise<Database>;
19
+ }
20
+
21
+ export class SessionManagerService {
22
+ constructor(
23
+ private readonly syncService: IDatabaseSyncService,
24
+ public readonly matrixManger = MatrixManager.getInstance(),
25
+ private readonly memoryEngineService?: MemoryEngineService,
26
+ ) {}
27
+
28
+ public getSessionsStateKey({
29
+ oracleEntityDid,
30
+ }: {
31
+ oracleEntityDid: string;
32
+ }): `${string}_${string}` {
33
+ return `${oracleEntityDid}_sessions`;
34
+ }
35
+
36
+ private async createMessageTitle({
37
+ messages,
38
+ }: {
39
+ messages: string[];
40
+ }): Promise<string> {
41
+ if (messages.length === 0) {
42
+ return 'Untitled';
43
+ }
44
+ const llm = getChatOpenAiModel({
45
+ model: 'meta-llama/llama-3.1-8b-instruct',
46
+ temperature: 0.3,
47
+ apiKey: process.env.OPEN_ROUTER_API_KEY,
48
+ timeout: 20 * 1000 * 60, // 20 minutes
49
+ configuration: {
50
+ baseURL: 'https://openrouter.ai/api/v1',
51
+ },
52
+ });
53
+ const response = await llm.invoke(
54
+ `Based on this messages messages, Add a title for this convo and only based on the messages? MAKE SURE TO ONLY RESPOND WITH THE TITLE.
55
+
56
+ ## RESPONSE FORMAT
57
+ ONLY RESPOND WITH THE TITLE not anything else that title will be saved to the store directly from your response so generated based on the messages.
58
+
59
+ EXample
60
+
61
+ Input:
62
+ <messages>
63
+ Hello, how are you?
64
+ I'm good, thank you!
65
+ did u see the new feature i added?
66
+ yes but i didn't like it
67
+ </messages>
68
+
69
+ Output:
70
+ Conversation about a new feature
71
+
72
+ ___________________________________________________________
73
+
74
+ Input:
75
+ <messages>
76
+ What are the store opening hours?
77
+ We are open from 9am to 5pm, Monday to Friday.
78
+ </messages>
79
+
80
+ Output:
81
+ Store Opening Hours Information
82
+ ___________________________________________________________
83
+ Input:
84
+ <messages>
85
+ Can you help me reset my password?
86
+ Sure, I can assist you with that.
87
+ </messages>
88
+
89
+ Output:
90
+ Password Reset Assistance
91
+
92
+ ___________________________________________________________
93
+ # the out put should be only the title not anything else that title will be saved to the store directly from your response so generated based on the messages.
94
+
95
+ USER MESSAGES:
96
+ <messages>
97
+ ${messages.join('\n\n')}
98
+ </messages>
99
+ `,
100
+ );
101
+
102
+ const title = response.content.toString();
103
+ return title;
104
+ }
105
+
106
+ public async updateLastProcessedCount({
107
+ sessionId,
108
+ did,
109
+ lastProcessedCount,
110
+ }: {
111
+ sessionId: string;
112
+ did: string;
113
+ lastProcessedCount: number;
114
+ }): Promise<void> {
115
+ const db = await this.syncService.getUserDatabase(did);
116
+ db.prepare(
117
+ 'UPDATE sessions SET last_processed_count = ? WHERE session_id = ?',
118
+ ).run(lastProcessedCount, sessionId);
119
+ return;
120
+ }
121
+
122
+ public async syncSessionSet({
123
+ sessionId,
124
+ did,
125
+ messages,
126
+ oracleEntityDid,
127
+ oracleName,
128
+ roomId: _roomId,
129
+ lastProcessedCount,
130
+ oracleDid,
131
+ userContext,
132
+ slackThreadTs,
133
+ }: {
134
+ sessionId: string;
135
+ did: string;
136
+ messages: string[];
137
+ oracleEntityDid: string;
138
+ oracleName: string;
139
+ roomId?: string;
140
+ lastProcessedCount?: number;
141
+ oracleDid: string;
142
+ userContext?: UserContextData;
143
+ slackThreadTs?: string;
144
+ }): Promise<ChatSession> {
145
+ const db = await this.syncService.getUserDatabase(did);
146
+
147
+ const selectedSession = await this.getSession(sessionId, did, false);
148
+
149
+ if (!selectedSession) {
150
+ const session: ChatSession = {
151
+ sessionId,
152
+ oracleName,
153
+ title: await this.createMessageTitle({
154
+ messages,
155
+ }),
156
+ lastUpdatedAt: new Date().toISOString(),
157
+ createdAt: new Date().toISOString(),
158
+ oracleEntityDid,
159
+ oracleDid,
160
+ userContext,
161
+ slackThreadTs,
162
+ };
163
+
164
+ // Always use SQLite
165
+ db.prepare(
166
+ `
167
+ INSERT INTO sessions (
168
+ session_id, title, last_updated_at, created_at, oracle_name,
169
+ oracle_did, oracle_entity_did, last_processed_count,
170
+ user_context, room_id, slack_thread_ts
171
+ )
172
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
173
+ `,
174
+ ).run(
175
+ session.sessionId,
176
+ session.title ?? null,
177
+ session.lastUpdatedAt,
178
+ session.createdAt,
179
+ session.oracleName,
180
+ session.oracleDid,
181
+ session.oracleEntityDid,
182
+ session.lastProcessedCount ?? null,
183
+ session.userContext ? JSON.stringify(session.userContext) : null,
184
+ session.roomId ?? null,
185
+ session.slackThreadTs ?? null,
186
+ );
187
+
188
+ return session;
189
+ }
190
+
191
+ // 1. We have at least 2 messages (enough to generate a meaningful title)
192
+ // 2. AND the current title is "Untitled" or undefined (hasn't been set yet)
193
+ const hasEnoughMessages = messages.length >= 2;
194
+ const needsTitleUpdate =
195
+ !selectedSession.title ||
196
+ selectedSession.title.toLowerCase() === 'untitled' ||
197
+ (selectedSession.title && selectedSession.title.trim() === '');
198
+
199
+ const allowTitleUpdate = hasEnoughMessages && needsTitleUpdate; // update the session
200
+ const title = allowTitleUpdate
201
+ ? await this.createMessageTitle({
202
+ messages,
203
+ })
204
+ : selectedSession.title;
205
+
206
+ const lastUpdatedAt = new Date().toISOString();
207
+ const updatedSession: ChatSession = {
208
+ ...selectedSession,
209
+ title,
210
+ lastUpdatedAt,
211
+ lastProcessedCount,
212
+ slackThreadTs,
213
+ };
214
+
215
+ db.prepare(
216
+ `
217
+ UPDATE sessions
218
+ SET title = ?, last_updated_at = ?, last_processed_count = ?, slack_thread_ts = ?
219
+ WHERE session_id = ?
220
+ `,
221
+ ).run(
222
+ updatedSession.title ?? null,
223
+ lastUpdatedAt,
224
+ updatedSession.lastProcessedCount ?? null,
225
+ updatedSession.slackThreadTs ?? null,
226
+ sessionId,
227
+ );
228
+
229
+ return updatedSession;
230
+ }
231
+
232
+ public async getSession(
233
+ sessionId: string,
234
+ did: string,
235
+ throwOnNotFound: boolean = true,
236
+ ): Promise<ChatSession | undefined> {
237
+ const db = await this.syncService.getUserDatabase(did);
238
+ const row = db
239
+ .prepare(
240
+ `SELECT
241
+ session_id, title, last_updated_at, created_at, oracle_name,
242
+ oracle_did, oracle_entity_did, last_processed_count,
243
+ user_context, room_id, slack_thread_ts
244
+ FROM sessions
245
+ WHERE session_id = ?`,
246
+ )
247
+ .get(sessionId) as
248
+ | {
249
+ session_id: string;
250
+ title: string | null;
251
+ last_updated_at: string;
252
+ created_at: string;
253
+ oracle_name: string;
254
+ oracle_did: string;
255
+ oracle_entity_did: string;
256
+ last_processed_count: number | null;
257
+ user_context: string | null;
258
+ room_id: string | null;
259
+ slack_thread_ts: string | null;
260
+ }
261
+ | undefined;
262
+
263
+ const selectedSession = row
264
+ ? {
265
+ sessionId: row.session_id,
266
+ title: row.title ?? undefined,
267
+ lastUpdatedAt: row.last_updated_at,
268
+ createdAt: row.created_at,
269
+ oracleName: row.oracle_name,
270
+ oracleDid: row.oracle_did,
271
+ oracleEntityDid: row.oracle_entity_did,
272
+ lastProcessedCount: row.last_processed_count ?? undefined,
273
+ userContext: row.user_context
274
+ ? (JSON.parse(row.user_context) as UserContextData)
275
+ : undefined,
276
+ roomId: row.room_id ?? undefined,
277
+ slackThreadTs: row.slack_thread_ts ?? undefined,
278
+ }
279
+ : undefined;
280
+
281
+ if (!selectedSession) {
282
+ if (throwOnNotFound) {
283
+ throw new Error('Session not found');
284
+ }
285
+ return undefined;
286
+ }
287
+
288
+ return selectedSession;
289
+ }
290
+
291
+ public async listSessions(
292
+ listSessionsDto: ListChatSessionsDto,
293
+ ): Promise<ListChatSessionsResponseDto> {
294
+ const db = await this.syncService.getUserDatabase(listSessionsDto.did);
295
+
296
+ // Set default pagination values
297
+ const limit = listSessionsDto.limit ?? 20;
298
+ const offset = listSessionsDto.offset ?? 0;
299
+
300
+ // Get paginated sessions with total count
301
+ const rows = db
302
+ .prepare(
303
+ `SELECT
304
+ session_id, title, last_updated_at, created_at, oracle_name,
305
+ oracle_did, oracle_entity_did, last_processed_count,
306
+ user_context, room_id, slack_thread_ts,
307
+ COUNT(*) OVER() as total
308
+ FROM sessions
309
+ ORDER BY last_updated_at DESC
310
+ LIMIT ? OFFSET ?`,
311
+ )
312
+ .all(limit, offset) as Array<{
313
+ session_id: string;
314
+ title: string | null;
315
+ last_updated_at: string;
316
+ created_at: string;
317
+ oracle_name: string;
318
+ oracle_did: string;
319
+ oracle_entity_did: string;
320
+ last_processed_count: number | null;
321
+ user_context: string | null;
322
+ room_id: string | null;
323
+ slack_thread_ts: string | null;
324
+ total: number;
325
+ }>;
326
+ const total = rows[0]?.total ?? 0;
327
+
328
+ const sessions: ChatSession[] = rows.map((row) => ({
329
+ sessionId: row.session_id,
330
+ title: row.title ?? undefined,
331
+ lastUpdatedAt: row.last_updated_at,
332
+ createdAt: row.created_at,
333
+ oracleName: row.oracle_name,
334
+ oracleDid: row.oracle_did,
335
+ oracleEntityDid: row.oracle_entity_did,
336
+ lastProcessedCount: row.last_processed_count ?? undefined,
337
+ userContext: row.user_context
338
+ ? (JSON.parse(row.user_context) as UserContextData)
339
+ : undefined,
340
+ roomId: row.room_id ?? undefined,
341
+ slackThreadTs: row.slack_thread_ts ?? undefined,
342
+ }));
343
+
344
+ return { sessions, total };
345
+ }
346
+
347
+ public async createSession(
348
+ createSessionDto: CreateChatSessionDto,
349
+ ): Promise<CreateChatSessionResponseDto> {
350
+ const userHomeServer = createSessionDto.homeServer || await getMatrixHomeServerCroppedForDid(createSessionDto.did);
351
+ const { roomId } = await this.matrixManger.getOracleRoomIdWithHomeServer({
352
+ userDid: createSessionDto.did,
353
+ oracleEntityDid: createSessionDto.oracleEntityDid,
354
+ userHomeServer,
355
+ });
356
+
357
+ if (!roomId) {
358
+ throw new Error('Room ID not found');
359
+ }
360
+ const eventId = await this.matrixManger.sendMessage({
361
+ message: 'New Conversation Started',
362
+ roomId,
363
+ isOracleAdmin: true,
364
+ });
365
+
366
+ // Gather user context from Memory Engine
367
+ let userContext: UserContextData | undefined;
368
+ if (this.memoryEngineService) {
369
+ try {
370
+ Logger.debug('Gathering user context from Memory Engine');
371
+ userContext = await this.memoryEngineService.gatherUserContext({
372
+ oracleDid: createSessionDto.oracleDid,
373
+ userDid: createSessionDto.did,
374
+ roomId,
375
+ });
376
+ } catch (error) {
377
+ Logger.error('Failed to gather user context:', error);
378
+ throw error;
379
+ }
380
+ }
381
+
382
+ const session = await this.syncSessionSet({
383
+ sessionId: eventId,
384
+ oracleName: createSessionDto.oracleName,
385
+ did: createSessionDto.did,
386
+ oracleEntityDid: createSessionDto.oracleEntityDid,
387
+ oracleDid: createSessionDto.oracleDid,
388
+ messages: [],
389
+ roomId,
390
+ userContext,
391
+ slackThreadTs: createSessionDto.slackThreadTs,
392
+ });
393
+
394
+ return session;
395
+ }
396
+
397
+ public async deleteSession(
398
+ deleteSessionDto: DeleteChatSessionDto,
399
+ ): Promise<void> {
400
+ const db = await this.syncService.getUserDatabase(deleteSessionDto.did);
401
+ db.prepare('DELETE FROM sessions WHERE session_id = ?').run(
402
+ deleteSessionDto.sessionId,
403
+ );
404
+ }
405
+ }
@@ -0,0 +1,84 @@
1
+ import { Logger } from '@ixo/logger';
2
+
3
+ export const getSubscriptionUrlByNetwork = (
4
+ network: 'mainnet' | 'testnet' | 'devnet',
5
+ ) => {
6
+ return {
7
+ mainnet: 'https://subscriptions-api-mainnet.ixo-api.workers.dev',
8
+ testnet: 'https://subscriptions-api-testnet.ixo-api.workers.dev',
9
+ devnet: 'https://subscriptions-api.ixo-api.workers.dev',
10
+ }[network];
11
+ };
12
+
13
+ export interface ClaimCollectionsDto {
14
+ oracleClaimsCollectionId?: string;
15
+
16
+ subscriptionClaimsCollectionId?: string;
17
+ }
18
+
19
+ export interface GetMySubscriptionsResponseDto {
20
+ claimCollections: ClaimCollectionsDto;
21
+ currentPlan: string;
22
+ currentPlanName: string;
23
+ totalCredits: number;
24
+ planCredits: number;
25
+ status: 'active' | 'inactive' | 'processing' | 'trial';
26
+ adminAddress: string;
27
+ }
28
+
29
+ interface GetUserSubscriptionResponse extends GetMySubscriptionsResponseDto {
30
+ manageSubscriptionUrl: string;
31
+ }
32
+
33
+ export interface GetUserSubscriptionParams {
34
+ network: 'mainnet' | 'testnet' | 'devnet';
35
+ bearerToken: string;
36
+ subscriptionUrl?: string;
37
+ }
38
+
39
+ export const getUserSubscription = async ({
40
+ bearerToken,
41
+ network,
42
+ subscriptionUrl: _subscriptionUrl,
43
+ }: GetUserSubscriptionParams): Promise<GetMySubscriptionsResponseDto | null> => {
44
+ const subscriptionUrl =
45
+ _subscriptionUrl ?? getSubscriptionUrlByNetwork(network);
46
+ try {
47
+ Logger.debug('Fetching user subscription from:', subscriptionUrl);
48
+ const response = await fetch(
49
+ `${subscriptionUrl.endsWith('/') ? subscriptionUrl.slice(0, -1) : subscriptionUrl}/api/v1/subscriptions`,
50
+ {
51
+ method: 'GET',
52
+ headers: {
53
+ Authorization: `Bearer ${bearerToken}`,
54
+ 'Content-Type': 'application/json',
55
+ },
56
+ },
57
+ );
58
+
59
+ if (!response.ok) {
60
+ console.error(
61
+ `Failed to fetch user subscription: ${response.status} ${response.statusText}`,
62
+ );
63
+ return null;
64
+ }
65
+
66
+ const data = await response.json();
67
+ if (!data) {
68
+ return null;
69
+ }
70
+ const subscription = data as GetUserSubscriptionResponse;
71
+ return {
72
+ claimCollections: subscription.claimCollections,
73
+ currentPlan: subscription.currentPlan,
74
+ currentPlanName: subscription.currentPlanName,
75
+ totalCredits: subscription.totalCredits,
76
+ planCredits: subscription.planCredits,
77
+ status: subscription.status,
78
+ adminAddress: subscription.adminAddress,
79
+ };
80
+ } catch (error) {
81
+ console.error('Error fetching user subscription:', error);
82
+ return null;
83
+ }
84
+ };
@@ -0,0 +1 @@
1
+ export * from './get-user-subscription.js';
package/tsconfig.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "extends": "@ixo/typescript-config/nestjs.json",
3
+ "compilerOptions": {
4
+ "baseUrl": "./",
5
+ "outDir": "dist",
6
+ "rootDir": "src",
7
+ "module": "NodeNext",
8
+ "moduleResolution": "NodeNext",
9
+ "esModuleInterop": true,
10
+ "paths": {
11
+ "src/*": ["src/*"]
12
+ }
13
+ },
14
+ "include": ["src/**/*", "src/**/*.test.ts"],
15
+ "exclude": ["node_modules", "dist", "integration", "**/*.spec.ts"]
16
+ }