@lenne.tech/nest-server 11.25.5 → 11.26.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 (341) hide show
  1. package/.claude/rules/configurable-features.md +2 -0
  2. package/CLAUDE.md +18 -0
  3. package/FRAMEWORK-API.md +48 -1
  4. package/dist/config.env.js +35 -1
  5. package/dist/config.env.js.map +1 -1
  6. package/dist/core/common/helpers/config.helper.js +2 -2
  7. package/dist/core/common/helpers/config.helper.js.map +1 -1
  8. package/dist/core/common/interceptors/check-security.interceptor.js +9 -2
  9. package/dist/core/common/interceptors/check-security.interceptor.js.map +1 -1
  10. package/dist/core/common/interfaces/server-options.interface.d.ts +89 -0
  11. package/dist/core/modules/ai/core-ai-mcp.controller.d.ts +21 -0
  12. package/dist/core/modules/ai/core-ai-mcp.controller.js +191 -0
  13. package/dist/core/modules/ai/core-ai-mcp.controller.js.map +1 -0
  14. package/dist/core/modules/ai/core-ai.controller.d.ts +90 -0
  15. package/dist/core/modules/ai/core-ai.controller.js +576 -0
  16. package/dist/core/modules/ai/core-ai.controller.js.map +1 -0
  17. package/dist/core/modules/ai/core-ai.module.d.ts +43 -0
  18. package/dist/core/modules/ai/core-ai.module.js +164 -0
  19. package/dist/core/modules/ai/core-ai.module.js.map +1 -0
  20. package/dist/core/modules/ai/core-ai.resolver.d.ts +84 -0
  21. package/dist/core/modules/ai/core-ai.resolver.js +530 -0
  22. package/dist/core/modules/ai/core-ai.resolver.js.map +1 -0
  23. package/dist/core/modules/ai/helpers/ai-mcp-oauth.helper.d.ts +7 -0
  24. package/dist/core/modules/ai/helpers/ai-mcp-oauth.helper.js +16 -0
  25. package/dist/core/modules/ai/helpers/ai-mcp-oauth.helper.js.map +1 -0
  26. package/dist/core/modules/ai/hooks/ai-hook.base.d.ts +10 -0
  27. package/dist/core/modules/ai/hooks/ai-hook.base.js +30 -0
  28. package/dist/core/modules/ai/hooks/ai-hook.base.js.map +1 -0
  29. package/dist/core/modules/ai/hooks/ai-hook.registry.d.ts +22 -0
  30. package/dist/core/modules/ai/hooks/ai-hook.registry.js +98 -0
  31. package/dist/core/modules/ai/hooks/ai-hook.registry.js.map +1 -0
  32. package/dist/core/modules/ai/index.d.ts +69 -0
  33. package/dist/core/modules/ai/index.js +86 -0
  34. package/dist/core/modules/ai/index.js.map +1 -0
  35. package/dist/core/modules/ai/inputs/core-ai-budget-limit-create.input.d.ts +5 -0
  36. package/dist/core/modules/ai/inputs/core-ai-budget-limit-create.input.js +43 -0
  37. package/dist/core/modules/ai/inputs/core-ai-budget-limit-create.input.js.map +1 -0
  38. package/dist/core/modules/ai/inputs/core-ai-budget-limit.input.d.ts +7 -0
  39. package/dist/core/modules/ai/inputs/core-ai-budget-limit.input.js +74 -0
  40. package/dist/core/modules/ai/inputs/core-ai-budget-limit.input.js.map +1 -0
  41. package/dist/core/modules/ai/inputs/core-ai-connection-create.input.d.ts +6 -0
  42. package/dist/core/modules/ai/inputs/core-ai-connection-create.input.js +49 -0
  43. package/dist/core/modules/ai/inputs/core-ai-connection-create.input.js.map +1 -0
  44. package/dist/core/modules/ai/inputs/core-ai-connection-preference.input.d.ts +6 -0
  45. package/dist/core/modules/ai/inputs/core-ai-connection-preference.input.js +60 -0
  46. package/dist/core/modules/ai/inputs/core-ai-connection-preference.input.js.map +1 -0
  47. package/dist/core/modules/ai/inputs/core-ai-connection.input.d.ts +23 -0
  48. package/dist/core/modules/ai/inputs/core-ai-connection.input.js +229 -0
  49. package/dist/core/modules/ai/inputs/core-ai-connection.input.js.map +1 -0
  50. package/dist/core/modules/ai/inputs/core-ai-conversation-create.input.d.ts +3 -0
  51. package/dist/core/modules/ai/inputs/core-ai-conversation-create.input.js +21 -0
  52. package/dist/core/modules/ai/inputs/core-ai-conversation-create.input.js.map +1 -0
  53. package/dist/core/modules/ai/inputs/core-ai-conversation.input.d.ts +4 -0
  54. package/dist/core/modules/ai/inputs/core-ai-conversation.input.js +42 -0
  55. package/dist/core/modules/ai/inputs/core-ai-conversation.input.js.map +1 -0
  56. package/dist/core/modules/ai/inputs/core-ai-prompt-create.input.d.ts +10 -0
  57. package/dist/core/modules/ai/inputs/core-ai-prompt-create.input.js +74 -0
  58. package/dist/core/modules/ai/inputs/core-ai-prompt-create.input.js.map +1 -0
  59. package/dist/core/modules/ai/inputs/core-ai-prompt-hint-create.input.d.ts +5 -0
  60. package/dist/core/modules/ai/inputs/core-ai-prompt-hint-create.input.js +41 -0
  61. package/dist/core/modules/ai/inputs/core-ai-prompt-hint-create.input.js.map +1 -0
  62. package/dist/core/modules/ai/inputs/core-ai-prompt-hint.input.d.ts +6 -0
  63. package/dist/core/modules/ai/inputs/core-ai-prompt-hint.input.js +63 -0
  64. package/dist/core/modules/ai/inputs/core-ai-prompt-hint.input.js.map +1 -0
  65. package/dist/core/modules/ai/inputs/core-ai-prompt-update.input.d.ts +10 -0
  66. package/dist/core/modules/ai/inputs/core-ai-prompt-update.input.js +70 -0
  67. package/dist/core/modules/ai/inputs/core-ai-prompt-update.input.js.map +1 -0
  68. package/dist/core/modules/ai/inputs/core-ai-prompt.input.d.ts +18 -0
  69. package/dist/core/modules/ai/inputs/core-ai-prompt.input.js +131 -0
  70. package/dist/core/modules/ai/inputs/core-ai-prompt.input.js.map +1 -0
  71. package/dist/core/modules/ai/inputs/core-ai-slot-create.input.d.ts +5 -0
  72. package/dist/core/modules/ai/inputs/core-ai-slot-create.input.js +41 -0
  73. package/dist/core/modules/ai/inputs/core-ai-slot-create.input.js.map +1 -0
  74. package/dist/core/modules/ai/inputs/core-ai-slot-update.input.d.ts +9 -0
  75. package/dist/core/modules/ai/inputs/core-ai-slot-update.input.js +91 -0
  76. package/dist/core/modules/ai/inputs/core-ai-slot-update.input.js.map +1 -0
  77. package/dist/core/modules/ai/interfaces/ai-hook.interface.d.ts +28 -0
  78. package/dist/core/modules/ai/interfaces/ai-hook.interface.js +3 -0
  79. package/dist/core/modules/ai/interfaces/ai-hook.interface.js.map +1 -0
  80. package/dist/core/modules/ai/interfaces/ai-placeholder.interface.d.ts +21 -0
  81. package/dist/core/modules/ai/interfaces/ai-placeholder.interface.js +3 -0
  82. package/dist/core/modules/ai/interfaces/ai-placeholder.interface.js.map +1 -0
  83. package/dist/core/modules/ai/interfaces/ai-tool.interface.d.ts +30 -0
  84. package/dist/core/modules/ai/interfaces/ai-tool.interface.js +3 -0
  85. package/dist/core/modules/ai/interfaces/ai-tool.interface.js.map +1 -0
  86. package/dist/core/modules/ai/interfaces/llm-provider.interface.d.ts +55 -0
  87. package/dist/core/modules/ai/interfaces/llm-provider.interface.js +3 -0
  88. package/dist/core/modules/ai/interfaces/llm-provider.interface.js.map +1 -0
  89. package/dist/core/modules/ai/interfaces/resolved-ai-connection.interface.d.ts +16 -0
  90. package/dist/core/modules/ai/interfaces/resolved-ai-connection.interface.js +3 -0
  91. package/dist/core/modules/ai/interfaces/resolved-ai-connection.interface.js.map +1 -0
  92. package/dist/core/modules/ai/models/core-ai-action.model.d.ts +6 -0
  93. package/dist/core/modules/ai/models/core-ai-action.model.js +44 -0
  94. package/dist/core/modules/ai/models/core-ai-action.model.js.map +1 -0
  95. package/dist/core/modules/ai/models/core-ai-available-connection.model.d.ts +8 -0
  96. package/dist/core/modules/ai/models/core-ai-available-connection.model.js +53 -0
  97. package/dist/core/modules/ai/models/core-ai-available-connection.model.js.map +1 -0
  98. package/dist/core/modules/ai/models/core-ai-budget-limit.model.d.ts +97 -0
  99. package/dist/core/modules/ai/models/core-ai-budget-limit.model.js +79 -0
  100. package/dist/core/modules/ai/models/core-ai-budget-limit.model.js.map +1 -0
  101. package/dist/core/modules/ai/models/core-ai-connection-preference.model.d.ts +91 -0
  102. package/dist/core/modules/ai/models/core-ai-connection-preference.model.js +67 -0
  103. package/dist/core/modules/ai/models/core-ai-connection-preference.model.js.map +1 -0
  104. package/dist/core/modules/ai/models/core-ai-connection.model.d.ts +200 -0
  105. package/dist/core/modules/ai/models/core-ai-connection.model.js +263 -0
  106. package/dist/core/modules/ai/models/core-ai-connection.model.js.map +1 -0
  107. package/dist/core/modules/ai/models/core-ai-conversation.model.d.ts +93 -0
  108. package/dist/core/modules/ai/models/core-ai-conversation.model.js +82 -0
  109. package/dist/core/modules/ai/models/core-ai-conversation.model.js.map +1 -0
  110. package/dist/core/modules/ai/models/core-ai-interaction.model.d.ts +133 -0
  111. package/dist/core/modules/ai/models/core-ai-interaction.model.js +137 -0
  112. package/dist/core/modules/ai/models/core-ai-interaction.model.js.map +1 -0
  113. package/dist/core/modules/ai/models/core-ai-message.model.d.ts +5 -0
  114. package/dist/core/modules/ai/models/core-ai-message.model.js +38 -0
  115. package/dist/core/modules/ai/models/core-ai-message.model.js.map +1 -0
  116. package/dist/core/modules/ai/models/core-ai-mode.model.d.ts +109 -0
  117. package/dist/core/modules/ai/models/core-ai-mode.model.js +100 -0
  118. package/dist/core/modules/ai/models/core-ai-mode.model.js.map +1 -0
  119. package/dist/core/modules/ai/models/core-ai-prompt-hint.model.d.ts +103 -0
  120. package/dist/core/modules/ai/models/core-ai-prompt-hint.model.js +89 -0
  121. package/dist/core/modules/ai/models/core-ai-prompt-hint.model.js.map +1 -0
  122. package/dist/core/modules/ai/models/core-ai-prompt.model.d.ts +122 -0
  123. package/dist/core/modules/ai/models/core-ai-prompt.model.js +117 -0
  124. package/dist/core/modules/ai/models/core-ai-prompt.model.js.map +1 -0
  125. package/dist/core/modules/ai/models/core-ai-response.model.d.ts +29 -0
  126. package/dist/core/modules/ai/models/core-ai-response.model.js +105 -0
  127. package/dist/core/modules/ai/models/core-ai-response.model.js.map +1 -0
  128. package/dist/core/modules/ai/models/core-ai-slot.model.d.ts +121 -0
  129. package/dist/core/modules/ai/models/core-ai-slot.model.js +119 -0
  130. package/dist/core/modules/ai/models/core-ai-slot.model.js.map +1 -0
  131. package/dist/core/modules/ai/models/core-ai-tool-grant.model.d.ts +103 -0
  132. package/dist/core/modules/ai/models/core-ai-tool-grant.model.js +88 -0
  133. package/dist/core/modules/ai/models/core-ai-tool-grant.model.js.map +1 -0
  134. package/dist/core/modules/ai/models/core-ai-tool-policy.model.d.ts +122 -0
  135. package/dist/core/modules/ai/models/core-ai-tool-policy.model.js +121 -0
  136. package/dist/core/modules/ai/models/core-ai-tool-policy.model.js.map +1 -0
  137. package/dist/core/modules/ai/models/core-ai-usage-info.model.d.ts +24 -0
  138. package/dist/core/modules/ai/models/core-ai-usage-info.model.js +127 -0
  139. package/dist/core/modules/ai/models/core-ai-usage-info.model.js.map +1 -0
  140. package/dist/core/modules/ai/models/core-ai-usage.model.d.ts +5 -0
  141. package/dist/core/modules/ai/models/core-ai-usage.model.js +38 -0
  142. package/dist/core/modules/ai/models/core-ai-usage.model.js.map +1 -0
  143. package/dist/core/modules/ai/providers/claude-cli.provider.d.ts +16 -0
  144. package/dist/core/modules/ai/providers/claude-cli.provider.js +151 -0
  145. package/dist/core/modules/ai/providers/claude-cli.provider.js.map +1 -0
  146. package/dist/core/modules/ai/providers/llm-provider.factory.d.ts +10 -0
  147. package/dist/core/modules/ai/providers/llm-provider.factory.js +45 -0
  148. package/dist/core/modules/ai/providers/llm-provider.factory.js.map +1 -0
  149. package/dist/core/modules/ai/providers/openai-compatible.provider.d.ts +32 -0
  150. package/dist/core/modules/ai/providers/openai-compatible.provider.js +236 -0
  151. package/dist/core/modules/ai/providers/openai-compatible.provider.js.map +1 -0
  152. package/dist/core/modules/ai/services/ai-crypto.service.d.ts +11 -0
  153. package/dist/core/modules/ai/services/ai-crypto.service.js +84 -0
  154. package/dist/core/modules/ai/services/ai-crypto.service.js.map +1 -0
  155. package/dist/core/modules/ai/services/core-ai-budget.service.d.ts +42 -0
  156. package/dist/core/modules/ai/services/core-ai-budget.service.js +211 -0
  157. package/dist/core/modules/ai/services/core-ai-budget.service.js.map +1 -0
  158. package/dist/core/modules/ai/services/core-ai-connection-preference.service.d.ts +18 -0
  159. package/dist/core/modules/ai/services/core-ai-connection-preference.service.js +53 -0
  160. package/dist/core/modules/ai/services/core-ai-connection-preference.service.js.map +1 -0
  161. package/dist/core/modules/ai/services/core-ai-connection-resolver.service.d.ts +55 -0
  162. package/dist/core/modules/ai/services/core-ai-connection-resolver.service.js +177 -0
  163. package/dist/core/modules/ai/services/core-ai-connection-resolver.service.js.map +1 -0
  164. package/dist/core/modules/ai/services/core-ai-connection.service.d.ts +43 -0
  165. package/dist/core/modules/ai/services/core-ai-connection.service.js +272 -0
  166. package/dist/core/modules/ai/services/core-ai-connection.service.js.map +1 -0
  167. package/dist/core/modules/ai/services/core-ai-conversation.service.d.ts +26 -0
  168. package/dist/core/modules/ai/services/core-ai-conversation.service.js +72 -0
  169. package/dist/core/modules/ai/services/core-ai-conversation.service.js.map +1 -0
  170. package/dist/core/modules/ai/services/core-ai-interaction.service.d.ts +13 -0
  171. package/dist/core/modules/ai/services/core-ai-interaction.service.js +52 -0
  172. package/dist/core/modules/ai/services/core-ai-interaction.service.js.map +1 -0
  173. package/dist/core/modules/ai/services/core-ai-mcp-client.service.d.ts +51 -0
  174. package/dist/core/modules/ai/services/core-ai-mcp-client.service.js +123 -0
  175. package/dist/core/modules/ai/services/core-ai-mcp-client.service.js.map +1 -0
  176. package/dist/core/modules/ai/services/core-ai-mcp-oauth.service.d.ts +68 -0
  177. package/dist/core/modules/ai/services/core-ai-mcp-oauth.service.js +279 -0
  178. package/dist/core/modules/ai/services/core-ai-mcp-oauth.service.js.map +1 -0
  179. package/dist/core/modules/ai/services/core-ai-mcp.service.d.ts +22 -0
  180. package/dist/core/modules/ai/services/core-ai-mcp.service.js +59 -0
  181. package/dist/core/modules/ai/services/core-ai-mcp.service.js.map +1 -0
  182. package/dist/core/modules/ai/services/core-ai-mode.service.d.ts +14 -0
  183. package/dist/core/modules/ai/services/core-ai-mode.service.js +56 -0
  184. package/dist/core/modules/ai/services/core-ai-mode.service.js.map +1 -0
  185. package/dist/core/modules/ai/services/core-ai-placeholder.registry.d.ts +15 -0
  186. package/dist/core/modules/ai/services/core-ai-placeholder.registry.js +102 -0
  187. package/dist/core/modules/ai/services/core-ai-placeholder.registry.js.map +1 -0
  188. package/dist/core/modules/ai/services/core-ai-prompt-builder.service.d.ts +42 -0
  189. package/dist/core/modules/ai/services/core-ai-prompt-builder.service.js +136 -0
  190. package/dist/core/modules/ai/services/core-ai-prompt-builder.service.js.map +1 -0
  191. package/dist/core/modules/ai/services/core-ai-prompt-hint.service.d.ts +29 -0
  192. package/dist/core/modules/ai/services/core-ai-prompt-hint.service.js +98 -0
  193. package/dist/core/modules/ai/services/core-ai-prompt-hint.service.js.map +1 -0
  194. package/dist/core/modules/ai/services/core-ai-prompt.service.d.ts +21 -0
  195. package/dist/core/modules/ai/services/core-ai-prompt.service.js +143 -0
  196. package/dist/core/modules/ai/services/core-ai-prompt.service.js.map +1 -0
  197. package/dist/core/modules/ai/services/core-ai-slot.service.d.ts +51 -0
  198. package/dist/core/modules/ai/services/core-ai-slot.service.js +372 -0
  199. package/dist/core/modules/ai/services/core-ai-slot.service.js.map +1 -0
  200. package/dist/core/modules/ai/services/core-ai-tool-grant.service.d.ts +22 -0
  201. package/dist/core/modules/ai/services/core-ai-tool-grant.service.js +97 -0
  202. package/dist/core/modules/ai/services/core-ai-tool-grant.service.js.map +1 -0
  203. package/dist/core/modules/ai/services/core-ai-tool-policy.service.d.ts +23 -0
  204. package/dist/core/modules/ai/services/core-ai-tool-policy.service.js +102 -0
  205. package/dist/core/modules/ai/services/core-ai-tool-policy.service.js.map +1 -0
  206. package/dist/core/modules/ai/services/core-ai.service.d.ts +144 -0
  207. package/dist/core/modules/ai/services/core-ai.service.js +991 -0
  208. package/dist/core/modules/ai/services/core-ai.service.js.map +1 -0
  209. package/dist/core/modules/ai/tools/ai-tool.base.d.ts +15 -0
  210. package/dist/core/modules/ai/tools/ai-tool.base.js +30 -0
  211. package/dist/core/modules/ai/tools/ai-tool.base.js.map +1 -0
  212. package/dist/core/modules/ai/tools/ai-tool.registry.d.ts +19 -0
  213. package/dist/core/modules/ai/tools/ai-tool.registry.js +71 -0
  214. package/dist/core/modules/ai/tools/ai-tool.registry.js.map +1 -0
  215. package/dist/core/modules/ai/tools/ask-user-question.tool.d.ts +38 -0
  216. package/dist/core/modules/ai/tools/ask-user-question.tool.js +65 -0
  217. package/dist/core/modules/ai/tools/ask-user-question.tool.js.map +1 -0
  218. package/dist/core/modules/ai/tools/search-tools.tool.d.ts +24 -0
  219. package/dist/core/modules/ai/tools/search-tools.tool.js +68 -0
  220. package/dist/core/modules/ai/tools/search-tools.tool.js.map +1 -0
  221. package/dist/core/modules/better-auth/core-better-auth-user.mapper.js +7 -1
  222. package/dist/core/modules/better-auth/core-better-auth-user.mapper.js.map +1 -1
  223. package/dist/core/modules/error-code/error-codes.d.ts +81 -0
  224. package/dist/core/modules/error-code/error-codes.js +72 -0
  225. package/dist/core/modules/error-code/error-codes.js.map +1 -1
  226. package/dist/core/modules/tenant/core-tenant.service.js +3 -3
  227. package/dist/core/modules/tenant/core-tenant.service.js.map +1 -1
  228. package/dist/core.module.js +8 -0
  229. package/dist/core.module.js.map +1 -1
  230. package/dist/index.d.ts +1 -0
  231. package/dist/index.js +1 -0
  232. package/dist/index.js.map +1 -1
  233. package/dist/server/modules/ai/ai-tools.module.d.ts +5 -0
  234. package/dist/server/modules/ai/ai-tools.module.js +36 -0
  235. package/dist/server/modules/ai/ai-tools.module.js.map +1 -0
  236. package/dist/server/modules/ai/tools/delete-user.tool.d.ts +30 -0
  237. package/dist/server/modules/ai/tools/delete-user.tool.js +49 -0
  238. package/dist/server/modules/ai/tools/delete-user.tool.js.map +1 -0
  239. package/dist/server/modules/ai/tools/find-users.tool.d.ts +30 -0
  240. package/dist/server/modules/ai/tools/find-users.tool.js +52 -0
  241. package/dist/server/modules/ai/tools/find-users.tool.js.map +1 -0
  242. package/dist/server/modules/ai/tools/get-user.tool.d.ts +26 -0
  243. package/dist/server/modules/ai/tools/get-user.tool.js +48 -0
  244. package/dist/server/modules/ai/tools/get-user.tool.js.map +1 -0
  245. package/dist/server/modules/ai/tools/update-user-job-title.tool.d.ts +32 -0
  246. package/dist/server/modules/ai/tools/update-user-job-title.tool.js +54 -0
  247. package/dist/server/modules/ai/tools/update-user-job-title.tool.js.map +1 -0
  248. package/dist/server/modules/error-code/error-codes.d.ts +9 -0
  249. package/dist/server/server.module.js +2 -0
  250. package/dist/server/server.module.js.map +1 -1
  251. package/dist/tsconfig.build.tsbuildinfo +1 -1
  252. package/docs/REQUEST-LIFECYCLE.md +10 -0
  253. package/migration-guides/11.25.x-to-11.26.0.md +278 -0
  254. package/package.json +44 -26
  255. package/src/config.env.ts +48 -1
  256. package/src/core/common/helpers/config.helper.ts +5 -2
  257. package/src/core/common/interceptors/check-security.interceptor.ts +13 -3
  258. package/src/core/common/interfaces/server-options.interface.ts +312 -0
  259. package/src/core/modules/ai/INTEGRATION-CHECKLIST.md +220 -0
  260. package/src/core/modules/ai/README.md +526 -0
  261. package/src/core/modules/ai/core-ai-mcp.controller.ts +223 -0
  262. package/src/core/modules/ai/core-ai.controller.ts +547 -0
  263. package/src/core/modules/ai/core-ai.module.ts +269 -0
  264. package/src/core/modules/ai/core-ai.resolver.ts +526 -0
  265. package/src/core/modules/ai/helpers/ai-mcp-oauth.helper.ts +35 -0
  266. package/src/core/modules/ai/hooks/ai-hook.base.ts +23 -0
  267. package/src/core/modules/ai/hooks/ai-hook.registry.ts +119 -0
  268. package/src/core/modules/ai/index.ts +70 -0
  269. package/src/core/modules/ai/inputs/core-ai-budget-limit-create.input.ts +27 -0
  270. package/src/core/modules/ai/inputs/core-ai-budget-limit.input.ts +52 -0
  271. package/src/core/modules/ai/inputs/core-ai-connection-create.input.ts +32 -0
  272. package/src/core/modules/ai/inputs/core-ai-connection-preference.input.ts +42 -0
  273. package/src/core/modules/ai/inputs/core-ai-connection.input.ts +235 -0
  274. package/src/core/modules/ai/inputs/core-ai-conversation-create.input.ts +13 -0
  275. package/src/core/modules/ai/inputs/core-ai-conversation.input.ts +33 -0
  276. package/src/core/modules/ai/inputs/core-ai-prompt-create.input.ts +50 -0
  277. package/src/core/modules/ai/inputs/core-ai-prompt-hint-create.input.ts +26 -0
  278. package/src/core/modules/ai/inputs/core-ai-prompt-hint.input.ts +43 -0
  279. package/src/core/modules/ai/inputs/core-ai-prompt-update.input.ts +42 -0
  280. package/src/core/modules/ai/inputs/core-ai-prompt.input.ts +144 -0
  281. package/src/core/modules/ai/inputs/core-ai-slot-create.input.ts +26 -0
  282. package/src/core/modules/ai/inputs/core-ai-slot-update.input.ts +65 -0
  283. package/src/core/modules/ai/interfaces/ai-hook.interface.ts +74 -0
  284. package/src/core/modules/ai/interfaces/ai-placeholder.interface.ts +49 -0
  285. package/src/core/modules/ai/interfaces/ai-tool.interface.ts +112 -0
  286. package/src/core/modules/ai/interfaces/llm-provider.interface.ts +187 -0
  287. package/src/core/modules/ai/interfaces/resolved-ai-connection.interface.ts +55 -0
  288. package/src/core/modules/ai/models/core-ai-action.model.ts +37 -0
  289. package/src/core/modules/ai/models/core-ai-available-connection.model.ts +42 -0
  290. package/src/core/modules/ai/models/core-ai-budget-limit.model.ts +82 -0
  291. package/src/core/modules/ai/models/core-ai-connection-preference.model.ts +72 -0
  292. package/src/core/modules/ai/models/core-ai-connection.model.ts +330 -0
  293. package/src/core/modules/ai/models/core-ai-conversation.model.ts +87 -0
  294. package/src/core/modules/ai/models/core-ai-interaction.model.ts +145 -0
  295. package/src/core/modules/ai/models/core-ai-message.model.ts +29 -0
  296. package/src/core/modules/ai/models/core-ai-mode.model.ts +93 -0
  297. package/src/core/modules/ai/models/core-ai-prompt-hint.model.ts +98 -0
  298. package/src/core/modules/ai/models/core-ai-prompt.model.ts +120 -0
  299. package/src/core/modules/ai/models/core-ai-response.model.ts +119 -0
  300. package/src/core/modules/ai/models/core-ai-slot.model.ts +146 -0
  301. package/src/core/modules/ai/models/core-ai-tool-grant.model.ts +87 -0
  302. package/src/core/modules/ai/models/core-ai-tool-policy.model.ts +115 -0
  303. package/src/core/modules/ai/models/core-ai-usage-info.model.ts +107 -0
  304. package/src/core/modules/ai/models/core-ai-usage.model.ts +29 -0
  305. package/src/core/modules/ai/providers/claude-cli.provider.ts +240 -0
  306. package/src/core/modules/ai/providers/llm-provider.factory.ts +63 -0
  307. package/src/core/modules/ai/providers/openai-compatible.provider.ts +329 -0
  308. package/src/core/modules/ai/services/ai-crypto.service.ts +120 -0
  309. package/src/core/modules/ai/services/core-ai-budget.service.ts +297 -0
  310. package/src/core/modules/ai/services/core-ai-connection-preference.service.ts +74 -0
  311. package/src/core/modules/ai/services/core-ai-connection-resolver.service.ts +308 -0
  312. package/src/core/modules/ai/services/core-ai-connection.service.ts +387 -0
  313. package/src/core/modules/ai/services/core-ai-conversation.service.ts +105 -0
  314. package/src/core/modules/ai/services/core-ai-interaction.service.ts +56 -0
  315. package/src/core/modules/ai/services/core-ai-mcp-client.service.ts +169 -0
  316. package/src/core/modules/ai/services/core-ai-mcp-oauth.service.ts +445 -0
  317. package/src/core/modules/ai/services/core-ai-mcp.service.ts +94 -0
  318. package/src/core/modules/ai/services/core-ai-mode.service.ts +43 -0
  319. package/src/core/modules/ai/services/core-ai-placeholder.registry.ts +123 -0
  320. package/src/core/modules/ai/services/core-ai-prompt-builder.service.ts +228 -0
  321. package/src/core/modules/ai/services/core-ai-prompt-hint.service.ts +133 -0
  322. package/src/core/modules/ai/services/core-ai-prompt.service.ts +164 -0
  323. package/src/core/modules/ai/services/core-ai-slot.service.ts +526 -0
  324. package/src/core/modules/ai/services/core-ai-tool-grant.service.ts +107 -0
  325. package/src/core/modules/ai/services/core-ai-tool-policy.service.ts +124 -0
  326. package/src/core/modules/ai/services/core-ai.service.ts +1396 -0
  327. package/src/core/modules/ai/tools/ai-tool.base.ts +46 -0
  328. package/src/core/modules/ai/tools/ai-tool.registry.ts +124 -0
  329. package/src/core/modules/ai/tools/ask-user-question.tool.ts +76 -0
  330. package/src/core/modules/ai/tools/search-tools.tool.ts +70 -0
  331. package/src/core/modules/better-auth/core-better-auth-user.mapper.ts +15 -2
  332. package/src/core/modules/error-code/error-codes.ts +86 -0
  333. package/src/core/modules/tenant/core-tenant.service.ts +3 -3
  334. package/src/core.module.ts +12 -0
  335. package/src/index.ts +6 -0
  336. package/src/server/modules/ai/ai-tools.module.ts +33 -0
  337. package/src/server/modules/ai/tools/delete-user.tool.ts +44 -0
  338. package/src/server/modules/ai/tools/find-users.tool.ts +49 -0
  339. package/src/server/modules/ai/tools/get-user.tool.ts +43 -0
  340. package/src/server/modules/ai/tools/update-user-job-title.tool.ts +62 -0
  341. package/src/server/server.module.ts +5 -0
@@ -0,0 +1,526 @@
1
+ import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
2
+
3
+ import { FilterArgs } from '../../common/args/filter.args';
4
+ import { GraphQLServiceOptions } from '../../common/decorators/graphql-service-options.decorator';
5
+ import { Roles } from '../../common/decorators/roles.decorator';
6
+ import { RoleEnum } from '../../common/enums/role.enum';
7
+ import { ServiceOptions } from '../../common/interfaces/service-options.interface';
8
+ import { RequestContext } from '../../common/services/request-context.service';
9
+ import { CoreAiBudgetLimitCreateInput } from './inputs/core-ai-budget-limit-create.input';
10
+ import { CoreAiBudgetLimitInput } from './inputs/core-ai-budget-limit.input';
11
+ import { CoreAiConnectionCreateInput } from './inputs/core-ai-connection-create.input';
12
+ import { CoreAiConnectionPreferenceInput } from './inputs/core-ai-connection-preference.input';
13
+ import { CoreAiConnectionInput } from './inputs/core-ai-connection.input';
14
+ import { CoreAiConversationCreateInput } from './inputs/core-ai-conversation-create.input';
15
+ import { CoreAiPromptHintCreateInput } from './inputs/core-ai-prompt-hint-create.input';
16
+ import { CoreAiPromptHintInput } from './inputs/core-ai-prompt-hint.input';
17
+ import { CoreAiPromptCreateInput } from './inputs/core-ai-prompt-create.input';
18
+ import { CoreAiPromptUpdateInput } from './inputs/core-ai-prompt-update.input';
19
+ import { CoreAiSlotCreateInput } from './inputs/core-ai-slot-create.input';
20
+ import { CoreAiSlotUpdateInput } from './inputs/core-ai-slot-update.input';
21
+ import { CoreAiPromptInput } from './inputs/core-ai-prompt.input';
22
+ import { CoreAiAvailableConnection } from './models/core-ai-available-connection.model';
23
+ import { CoreAiBudgetLimit } from './models/core-ai-budget-limit.model';
24
+ import { CoreAiConnectionPreference } from './models/core-ai-connection-preference.model';
25
+ import { CoreAiConnection } from './models/core-ai-connection.model';
26
+ import { CoreAiConversation } from './models/core-ai-conversation.model';
27
+ import { CoreAiInteraction } from './models/core-ai-interaction.model';
28
+ import { CoreAiPromptHint } from './models/core-ai-prompt-hint.model';
29
+ import { CoreAiPrompt } from './models/core-ai-prompt.model';
30
+ import { CoreAiSlot } from './models/core-ai-slot.model';
31
+ import { CoreAiResponse } from './models/core-ai-response.model';
32
+ import { CoreAiUsageInfo } from './models/core-ai-usage-info.model';
33
+ import { CoreAiBudgetService } from './services/core-ai-budget.service';
34
+ import { CoreAiConnectionPreferenceService } from './services/core-ai-connection-preference.service';
35
+ import { CoreAiConnectionResolverService } from './services/core-ai-connection-resolver.service';
36
+ import { CoreAiConnectionService } from './services/core-ai-connection.service';
37
+ import { CoreAiConversationService } from './services/core-ai-conversation.service';
38
+ import { CoreAiInteractionService } from './services/core-ai-interaction.service';
39
+ import { CoreAiPromptHintService } from './services/core-ai-prompt-hint.service';
40
+ import { CoreAiPromptService } from './services/core-ai-prompt.service';
41
+ import { CoreAiSlotService } from './services/core-ai-slot.service';
42
+ import { CoreAiService } from './services/core-ai.service';
43
+
44
+ /**
45
+ * GraphQL resolver for AI prompts and connection management.
46
+ *
47
+ * - `aiPrompt`: any authenticated user (tools are filtered by the user's roles).
48
+ * - connection queries/mutations: admin only (the model is `@Restricted(ADMIN)`).
49
+ *
50
+ * Extend this resolver in a project and pass it via `CoreAiModule.forRoot({ resolver })`.
51
+ * When overriding methods, re-declare ALL decorators (`@Query`/`@Mutation`/`@Roles`)
52
+ * because the GraphQL schema is built from decorators at compile time.
53
+ */
54
+ @Resolver(() => CoreAiResponse)
55
+ @Roles(RoleEnum.ADMIN)
56
+ export class CoreAiResolver {
57
+ constructor(
58
+ protected readonly aiService: CoreAiService,
59
+ protected readonly connectionService: CoreAiConnectionService,
60
+ protected readonly conversationService: CoreAiConversationService,
61
+ protected readonly interactionService: CoreAiInteractionService,
62
+ protected readonly budgetService: CoreAiBudgetService,
63
+ protected readonly connectionResolver: CoreAiConnectionResolverService,
64
+ protected readonly preferenceService: CoreAiConnectionPreferenceService,
65
+ protected readonly slotService: CoreAiSlotService,
66
+ protected readonly promptHintService: CoreAiPromptHintService,
67
+ protected readonly promptService: CoreAiPromptService,
68
+ ) {}
69
+
70
+ // ===================================================================================================================
71
+ // Prompt
72
+ // ===================================================================================================================
73
+
74
+ /**
75
+ * Send a prompt to the AI assistant.
76
+ */
77
+ @Mutation(() => CoreAiResponse, { description: 'Send a prompt to the AI assistant' })
78
+ @Roles(RoleEnum.S_USER)
79
+ async aiPrompt(
80
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
81
+ @Args('input') input: CoreAiPromptInput,
82
+ ): Promise<CoreAiResponse> {
83
+ return this.aiService.prompt(input, serviceOptions);
84
+ }
85
+
86
+ // ===================================================================================================================
87
+ // Connection management (admin)
88
+ // ===================================================================================================================
89
+
90
+ /**
91
+ * Create a new AI connection.
92
+ */
93
+ @Mutation(() => CoreAiConnection, { description: 'Create a new AI connection' })
94
+ @Roles(RoleEnum.ADMIN)
95
+ async createAiConnection(
96
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
97
+ @Args('input') input: CoreAiConnectionCreateInput,
98
+ ): Promise<CoreAiConnection> {
99
+ return this.connectionService.create(input, { ...serviceOptions, inputType: CoreAiConnectionCreateInput });
100
+ }
101
+
102
+ /**
103
+ * Delete an AI connection.
104
+ */
105
+ @Mutation(() => CoreAiConnection, { description: 'Delete an AI connection' })
106
+ @Roles(RoleEnum.ADMIN)
107
+ async deleteAiConnection(
108
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
109
+ @Args('id') id: string,
110
+ ): Promise<CoreAiConnection> {
111
+ return this.connectionService.delete(id, serviceOptions);
112
+ }
113
+
114
+ /**
115
+ * Get a single AI connection by id.
116
+ */
117
+ @Query(() => CoreAiConnection, { description: 'Get an AI connection by id' })
118
+ @Roles(RoleEnum.ADMIN)
119
+ async getAiConnection(
120
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
121
+ @Args('id') id: string,
122
+ ): Promise<CoreAiConnection> {
123
+ return this.connectionService.get(id, serviceOptions);
124
+ }
125
+
126
+ /**
127
+ * Find AI connections (via filter).
128
+ */
129
+ @Query(() => [CoreAiConnection], { description: 'Find AI connections' })
130
+ @Roles(RoleEnum.ADMIN)
131
+ async findAiConnections(
132
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
133
+ @Args() args?: FilterArgs,
134
+ ): Promise<CoreAiConnection[]> {
135
+ return this.connectionService.find(args, { ...serviceOptions, inputType: FilterArgs });
136
+ }
137
+
138
+ /**
139
+ * Probe an AI connection's endpoint to auto-detect and persist its capabilities
140
+ * (JSON / native tools) for any flag left undefined.
141
+ */
142
+ @Mutation(() => CoreAiConnection, { description: 'Auto-detect and persist AI connection capabilities' })
143
+ @Roles(RoleEnum.ADMIN)
144
+ async detectAiConnectionCapabilities(
145
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
146
+ @Args('id') id: string,
147
+ ): Promise<CoreAiConnection> {
148
+ await this.connectionService.detectAndPersistCapabilities(id);
149
+ return this.connectionService.get(id, serviceOptions);
150
+ }
151
+
152
+ /**
153
+ * Update an AI connection.
154
+ */
155
+ @Mutation(() => CoreAiConnection, { description: 'Update an AI connection' })
156
+ @Roles(RoleEnum.ADMIN)
157
+ async updateAiConnection(
158
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
159
+ @Args('id') id: string,
160
+ @Args('input') input: CoreAiConnectionInput,
161
+ ): Promise<CoreAiConnection> {
162
+ return this.connectionService.update(id, input, { ...serviceOptions, inputType: CoreAiConnectionInput });
163
+ }
164
+
165
+ // ===================================================================================================================
166
+ // Connection selection (user self-service + admin preferences)
167
+ // ===================================================================================================================
168
+
169
+ /**
170
+ * List the AI connections the current user/tenant may use (non-sensitive), with
171
+ * the currently resolved one flagged and whether the selection is locked.
172
+ */
173
+ @Query(() => [CoreAiAvailableConnection], { description: 'List AI connections available to the current user' })
174
+ @Roles(RoleEnum.S_USER)
175
+ async aiAvailableConnections(
176
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
177
+ ): Promise<CoreAiAvailableConnection[]> {
178
+ return this.connectionResolver.listAvailable({
179
+ tenantId: RequestContext.getTenantId(),
180
+ userId: serviceOptions?.currentUser?.id,
181
+ });
182
+ }
183
+
184
+ /**
185
+ * Set the current user's own default AI connection (validated against availability).
186
+ * Returns the updated available list.
187
+ */
188
+ @Mutation(() => [CoreAiAvailableConnection], { description: 'Set the current user default AI connection' })
189
+ @Roles(RoleEnum.S_USER)
190
+ async aiSetUserConnection(
191
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
192
+ @Args('connectionId') connectionId: string,
193
+ ): Promise<CoreAiAvailableConnection[]> {
194
+ const tenantId = RequestContext.getTenantId();
195
+ const userId = serviceOptions?.currentUser?.id;
196
+ await this.connectionResolver.setUserConnection(userId, connectionId, tenantId);
197
+ return this.connectionResolver.listAvailable({ tenantId, userId });
198
+ }
199
+
200
+ /**
201
+ * Upsert a tenant/user connection preference (admin). Use for tenant defaults,
202
+ * tenant-enforced selection or managing a user's default.
203
+ */
204
+ @Mutation(() => CoreAiConnectionPreference, { description: 'Upsert an AI connection preference' })
205
+ @Roles(RoleEnum.ADMIN)
206
+ async setAiConnectionPreference(
207
+ @Args('input') input: CoreAiConnectionPreferenceInput,
208
+ ): Promise<CoreAiConnectionPreference> {
209
+ return this.connectionResolver.setPreference(
210
+ input.scope as 'tenant' | 'user',
211
+ input.refId,
212
+ input.connectionId,
213
+ input.enforced ?? false,
214
+ );
215
+ }
216
+
217
+ /**
218
+ * Find AI connection preferences (admin).
219
+ */
220
+ @Query(() => [CoreAiConnectionPreference], { description: 'Find AI connection preferences' })
221
+ @Roles(RoleEnum.ADMIN)
222
+ async findAiConnectionPreferences(
223
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
224
+ @Args() args?: FilterArgs,
225
+ ): Promise<CoreAiConnectionPreference[]> {
226
+ return this.preferenceService.find(args, { ...serviceOptions, inputType: FilterArgs });
227
+ }
228
+
229
+ /**
230
+ * Delete an AI connection preference by id (admin).
231
+ */
232
+ @Mutation(() => CoreAiConnectionPreference, { description: 'Delete an AI connection preference' })
233
+ @Roles(RoleEnum.ADMIN)
234
+ async deleteAiConnectionPreference(
235
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
236
+ @Args('id') id: string,
237
+ ): Promise<CoreAiConnectionPreference> {
238
+ return this.preferenceService.delete(id, serviceOptions);
239
+ }
240
+
241
+ // ===================================================================================================================
242
+ // Conversations (owner-scoped)
243
+ // ===================================================================================================================
244
+
245
+ /**
246
+ * Create a new AI conversation for the current user.
247
+ */
248
+ @Mutation(() => CoreAiConversation, { description: 'Create a new AI conversation' })
249
+ @Roles(RoleEnum.S_USER)
250
+ async createAiConversation(
251
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
252
+ @Args('input') input: CoreAiConversationCreateInput,
253
+ ): Promise<CoreAiConversation> {
254
+ return this.conversationService.create(input, { ...serviceOptions, inputType: CoreAiConversationCreateInput });
255
+ }
256
+
257
+ /**
258
+ * Delete an AI conversation (owner or admin).
259
+ */
260
+ @Mutation(() => CoreAiConversation, { description: 'Delete an AI conversation' })
261
+ @Roles(RoleEnum.S_USER)
262
+ async deleteAiConversation(
263
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
264
+ @Args('id') id: string,
265
+ ): Promise<CoreAiConversation> {
266
+ return this.conversationService.delete(id, {
267
+ ...serviceOptions,
268
+ roles: [RoleEnum.ADMIN, RoleEnum.S_CREATOR, RoleEnum.S_SELF],
269
+ });
270
+ }
271
+
272
+ /**
273
+ * Find the current user's AI conversations (admins see all).
274
+ *
275
+ * The `messages` subdocument array is excluded from the list result — clients
276
+ * fetching the conversation detail via `getAiConversation` get the full message
277
+ * history. List payloads stay small even for users with many long conversations.
278
+ */
279
+ @Query(() => [CoreAiConversation], { description: 'Find AI conversations of the current user' })
280
+ @Roles(RoleEnum.S_USER)
281
+ async findAiConversations(@GraphQLServiceOptions() serviceOptions: ServiceOptions): Promise<CoreAiConversation[]> {
282
+ const currentUser = serviceOptions?.currentUser;
283
+ const filterQuery = currentUser?.roles?.includes(RoleEnum.ADMIN) ? {} : { createdBy: currentUser?.id };
284
+ return this.conversationService.find(
285
+ { filterQuery },
286
+ { ...serviceOptions, roles: [RoleEnum.ADMIN, RoleEnum.S_CREATOR, RoleEnum.S_SELF], select: '-messages' },
287
+ );
288
+ }
289
+
290
+ /**
291
+ * Get a single AI conversation by id (owner or admin).
292
+ */
293
+ @Query(() => CoreAiConversation, { description: 'Get an AI conversation by id' })
294
+ @Roles(RoleEnum.S_USER)
295
+ async getAiConversation(
296
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
297
+ @Args('id') id: string,
298
+ ): Promise<CoreAiConversation> {
299
+ return this.conversationService.get(id, {
300
+ ...serviceOptions,
301
+ roles: [RoleEnum.ADMIN, RoleEnum.S_CREATOR, RoleEnum.S_SELF],
302
+ });
303
+ }
304
+
305
+ // ===================================================================================================================
306
+ // Audit (admin)
307
+ // ===================================================================================================================
308
+
309
+ /**
310
+ * Find AI interaction audit records (via filter).
311
+ */
312
+ @Query(() => [CoreAiInteraction], { description: 'Find AI interaction audit records' })
313
+ @Roles(RoleEnum.ADMIN)
314
+ async findAiInteractions(
315
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
316
+ @Args() args?: FilterArgs,
317
+ ): Promise<CoreAiInteraction[]> {
318
+ return this.interactionService.find(args, { ...serviceOptions, inputType: FilterArgs });
319
+ }
320
+
321
+ /**
322
+ * Get a single AI interaction audit record by id.
323
+ */
324
+ @Query(() => CoreAiInteraction, { description: 'Get an AI interaction audit record by id' })
325
+ @Roles(RoleEnum.ADMIN)
326
+ async getAiInteraction(
327
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
328
+ @Args('id') id: string,
329
+ ): Promise<CoreAiInteraction> {
330
+ return this.interactionService.get(id, serviceOptions);
331
+ }
332
+
333
+ // ===================================================================================================================
334
+ // Token usage + budget limits
335
+ // ===================================================================================================================
336
+
337
+ /**
338
+ * Full token usage for the current user (and tenant) until the next reset.
339
+ */
340
+ @Query(() => CoreAiUsageInfo, { description: 'Token usage for the current user (and tenant)' })
341
+ @Roles(RoleEnum.S_USER)
342
+ async aiUsage(@GraphQLServiceOptions() serviceOptions: ServiceOptions): Promise<CoreAiUsageInfo> {
343
+ return this.budgetService.getUsageInfo(serviceOptions?.currentUser?.id, RequestContext.getTenantId());
344
+ }
345
+
346
+ /**
347
+ * Create an AI budget limit (admin).
348
+ */
349
+ @Mutation(() => CoreAiBudgetLimit, { description: 'Create an AI budget limit' })
350
+ @Roles(RoleEnum.ADMIN)
351
+ async createAiBudgetLimit(
352
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
353
+ @Args('input') input: CoreAiBudgetLimitCreateInput,
354
+ ): Promise<CoreAiBudgetLimit> {
355
+ return this.budgetService.create(input, { ...serviceOptions, inputType: CoreAiBudgetLimitCreateInput });
356
+ }
357
+
358
+ /**
359
+ * Delete an AI budget limit (admin).
360
+ */
361
+ @Mutation(() => CoreAiBudgetLimit, { description: 'Delete an AI budget limit' })
362
+ @Roles(RoleEnum.ADMIN)
363
+ async deleteAiBudgetLimit(
364
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
365
+ @Args('id') id: string,
366
+ ): Promise<CoreAiBudgetLimit> {
367
+ return this.budgetService.delete(id, serviceOptions);
368
+ }
369
+
370
+ /**
371
+ * Find AI budget limits (admin).
372
+ */
373
+ @Query(() => [CoreAiBudgetLimit], { description: 'Find AI budget limits' })
374
+ @Roles(RoleEnum.ADMIN)
375
+ async findAiBudgetLimits(
376
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
377
+ @Args() args?: FilterArgs,
378
+ ): Promise<CoreAiBudgetLimit[]> {
379
+ return this.budgetService.find(args, { ...serviceOptions, inputType: FilterArgs });
380
+ }
381
+
382
+ /**
383
+ * Update an AI budget limit (admin).
384
+ */
385
+ @Mutation(() => CoreAiBudgetLimit, { description: 'Update an AI budget limit' })
386
+ @Roles(RoleEnum.ADMIN)
387
+ async updateAiBudgetLimit(
388
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
389
+ @Args('id') id: string,
390
+ @Args('input') input: CoreAiBudgetLimitInput,
391
+ ): Promise<CoreAiBudgetLimit> {
392
+ return this.budgetService.update(id, input, { ...serviceOptions, inputType: CoreAiBudgetLimitInput });
393
+ }
394
+
395
+ // ===================================================================================================================
396
+ // Prompt templates (admin-editable prompt building blocks)
397
+ // ===================================================================================================================
398
+
399
+ /** Create a prompt template fragment (admin). */
400
+ @Mutation(() => CoreAiSlot, { description: 'Create an AI prompt template fragment' })
401
+ @Roles(RoleEnum.ADMIN)
402
+ async createAiSlot(
403
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
404
+ @Args('input') input: CoreAiSlotCreateInput,
405
+ ): Promise<CoreAiSlot> {
406
+ return this.slotService.create(input, { ...serviceOptions, inputType: CoreAiSlotCreateInput });
407
+ }
408
+
409
+ /** Delete a prompt template fragment (admin). */
410
+ @Mutation(() => CoreAiSlot, { description: 'Delete an AI prompt template fragment' })
411
+ @Roles(RoleEnum.ADMIN)
412
+ async deleteAiSlot(
413
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
414
+ @Args('id') id: string,
415
+ ): Promise<CoreAiSlot> {
416
+ return this.slotService.delete(id, serviceOptions);
417
+ }
418
+
419
+ /** Find prompt template fragments (admin). */
420
+ @Query(() => [CoreAiSlot], { description: 'Find AI prompt template fragments' })
421
+ @Roles(RoleEnum.ADMIN)
422
+ async findAiSlots(
423
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
424
+ @Args() args?: FilterArgs,
425
+ ): Promise<CoreAiSlot[]> {
426
+ return this.slotService.find(args, { ...serviceOptions, inputType: FilterArgs });
427
+ }
428
+
429
+ /** Update a prompt template fragment (admin). */
430
+ @Mutation(() => CoreAiSlot, { description: 'Update an AI prompt template fragment' })
431
+ @Roles(RoleEnum.ADMIN)
432
+ async updateAiSlot(
433
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
434
+ @Args('id') id: string,
435
+ @Args('input') input: CoreAiSlotUpdateInput,
436
+ ): Promise<CoreAiSlot> {
437
+ return this.slotService.update(id, input, { ...serviceOptions, inputType: CoreAiSlotUpdateInput });
438
+ }
439
+
440
+ // ===================================================================================================================
441
+ // Learned prompt hints (governed self-improvement loop)
442
+ // ===================================================================================================================
443
+
444
+ /** Create a learned prompt hint manually (admin). */
445
+ @Mutation(() => CoreAiPromptHint, { description: 'Create a learned AI prompt hint' })
446
+ @Roles(RoleEnum.ADMIN)
447
+ async createAiPromptHint(
448
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
449
+ @Args('input') input: CoreAiPromptHintCreateInput,
450
+ ): Promise<CoreAiPromptHint> {
451
+ return this.promptHintService.create(input, { ...serviceOptions, inputType: CoreAiPromptHintCreateInput });
452
+ }
453
+
454
+ /** Delete a learned prompt hint (admin). */
455
+ @Mutation(() => CoreAiPromptHint, { description: 'Delete a learned AI prompt hint' })
456
+ @Roles(RoleEnum.ADMIN)
457
+ async deleteAiPromptHint(
458
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
459
+ @Args('id') id: string,
460
+ ): Promise<CoreAiPromptHint> {
461
+ return this.promptHintService.delete(id, serviceOptions);
462
+ }
463
+
464
+ /** Find learned prompt hints (admin) — review/approve/reject the learning loop. */
465
+ @Query(() => [CoreAiPromptHint], { description: 'Find learned AI prompt hints' })
466
+ @Roles(RoleEnum.ADMIN)
467
+ async findAiPromptHints(
468
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
469
+ @Args() args?: FilterArgs,
470
+ ): Promise<CoreAiPromptHint[]> {
471
+ return this.promptHintService.find(args, { ...serviceOptions, inputType: FilterArgs });
472
+ }
473
+
474
+ /** Update a learned prompt hint (admin) — typically approve/reject or edit. */
475
+ @Mutation(() => CoreAiPromptHint, { description: 'Update a learned AI prompt hint' })
476
+ @Roles(RoleEnum.ADMIN)
477
+ async updateAiPromptHint(
478
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
479
+ @Args('id') id: string,
480
+ @Args('input') input: CoreAiPromptHintInput,
481
+ ): Promise<CoreAiPromptHint> {
482
+ return this.promptHintService.update(id, input, { ...serviceOptions, inputType: CoreAiPromptHintInput });
483
+ }
484
+
485
+ // ===================================================================================================================
486
+ // User-facing user prompts ("Vorlagen") — own / tenant / global
487
+ // ===================================================================================================================
488
+
489
+ /** List user prompts visible to the current user (own + tenant + global). */
490
+ @Query(() => [CoreAiPrompt], { description: 'List AI user prompts visible to the current user' })
491
+ @Roles(RoleEnum.S_USER)
492
+ async findAiPrompts(@GraphQLServiceOptions() serviceOptions: ServiceOptions): Promise<CoreAiPrompt[]> {
493
+ return this.promptService.listVisible(serviceOptions);
494
+ }
495
+
496
+ /** Create a user prompt for the current user / tenant (global requires admin). */
497
+ @Mutation(() => CoreAiPrompt, { description: 'Create an AI user prompt' })
498
+ @Roles(RoleEnum.S_USER)
499
+ async createAiPrompt(
500
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
501
+ @Args('input') input: CoreAiPromptCreateInput,
502
+ ): Promise<CoreAiPrompt> {
503
+ return this.promptService.create(input, { ...serviceOptions, inputType: CoreAiPromptCreateInput });
504
+ }
505
+
506
+ /** Update a user prompt (owner only; admins via standard admin pipeline). */
507
+ @Mutation(() => CoreAiPrompt, { description: 'Update an AI user prompt' })
508
+ @Roles(RoleEnum.S_USER)
509
+ async updateAiPrompt(
510
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
511
+ @Args('id') id: string,
512
+ @Args('input') input: CoreAiPromptUpdateInput,
513
+ ): Promise<CoreAiPrompt> {
514
+ return this.promptService.update(id, input, { ...serviceOptions, inputType: CoreAiPromptUpdateInput });
515
+ }
516
+
517
+ /** Delete a user prompt (owner only; admins via standard admin pipeline). */
518
+ @Mutation(() => CoreAiPrompt, { description: 'Delete an AI user prompt' })
519
+ @Roles(RoleEnum.S_USER)
520
+ async deleteAiPrompt(
521
+ @GraphQLServiceOptions() serviceOptions: ServiceOptions,
522
+ @Args('id') id: string,
523
+ ): Promise<CoreAiPrompt> {
524
+ return this.promptService.delete(id, serviceOptions);
525
+ }
526
+ }
@@ -0,0 +1,35 @@
1
+ import { CoreAiMcpOAuthService } from '../services/core-ai-mcp-oauth.service';
2
+
3
+ /**
4
+ * Mount the MCP OAuth 2.1 router (`mcpAuthRouter`) on a NestJS application.
5
+ *
6
+ * Call this in `main.ts` AFTER `app.init()` when `ai.mcp.oauth` is enabled. It
7
+ * lazy-imports `@modelcontextprotocol/sdk` and wires the OAuth provider built from
8
+ * {@link CoreAiMcpOAuthService}, exposing the standard discovery + token endpoints
9
+ * (`/.well-known/oauth-*`, `/authorize`, `/token`, `/register`, `/revoke`).
10
+ *
11
+ * The interactive consent step requires `CoreAiMcpOAuthService.authorizeConsent`
12
+ * to be overridden with your login/consent UI (see INTEGRATION-CHECKLIST).
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * // main.ts, after app.init()
17
+ * await mountAiMcpOAuth(app, { baseUrl: process.env.BASE_URL });
18
+ * ```
19
+ */
20
+ export async function mountAiMcpOAuth(
21
+ app: { get: (token: any) => any; use: (...args: any[]) => any },
22
+ options: { baseUrl: string; mcpPath?: string },
23
+ ): Promise<void> {
24
+ const { mcpAuthRouter } = await import('@modelcontextprotocol/sdk/server/auth/router.js');
25
+ const oauthService: CoreAiMcpOAuthService = app.get(CoreAiMcpOAuthService);
26
+ const mcpPath = options.mcpPath ?? '/ai/mcp';
27
+
28
+ const router = mcpAuthRouter({
29
+ issuerUrl: new URL(options.baseUrl),
30
+ provider: oauthService.buildOAuthProvider() as any,
31
+ resourceServerUrl: new URL(`${options.baseUrl.replace(/\/$/, '')}${mcpPath}`),
32
+ });
33
+
34
+ app.use(router);
35
+ }
@@ -0,0 +1,23 @@
1
+ import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
2
+
3
+ import { IAiHook } from '../interfaces/ai-hook.interface';
4
+ import { AiHookRegistry } from './ai-hook.registry';
5
+
6
+ /**
7
+ * Convenience base class for AI lifecycle hooks. Extend it, declare the class as
8
+ * a NestJS provider in your module, and override one or more of
9
+ * {@link IAiHook.preToolUse} / `postToolUse` / `sessionStart` / `stop`. The hook
10
+ * auto-registers in the global {@link AiHookRegistry} on module init.
11
+ */
12
+ @Injectable()
13
+ export abstract class AiHookBase implements IAiHook, OnModuleInit {
14
+ protected readonly logger = new Logger(this.constructor.name);
15
+
16
+ abstract readonly name: string;
17
+
18
+ protected constructor(protected readonly registry: AiHookRegistry) {}
19
+
20
+ onModuleInit(): void {
21
+ this.registry.register(this);
22
+ }
23
+ }