You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

199 lines
5.2 KiB

11 months ago
  1. const { safeJsonParse } = require("../utils/http");
  2. const prisma = require("../utils/prisma");
  3. /**
  4. * @typedef {Object} EmbedChat
  5. * @property {number} id
  6. * @property {number} embed_id
  7. * @property {string} prompt
  8. * @property {string} response
  9. * @property {string} connection_information
  10. * @property {string} session_id
  11. * @property {boolean} include
  12. */
  13. const EmbedChats = {
  14. new: async function ({
  15. embedId,
  16. prompt,
  17. response = {},
  18. connection_information = {},
  19. sessionId,
  20. }) {
  21. try {
  22. const chat = await prisma.embed_chats.create({
  23. data: {
  24. prompt,
  25. embed_id: Number(embedId),
  26. response: JSON.stringify(response),
  27. connection_information: JSON.stringify(connection_information),
  28. session_id: String(sessionId),
  29. },
  30. });
  31. return { chat, message: null };
  32. } catch (error) {
  33. console.error(error.message);
  34. return { chat: null, message: error.message };
  35. }
  36. },
  37. /**
  38. * Loops through each chat and filters out the sources from the response object.
  39. * We do this when returning /history of an embed to the frontend to prevent inadvertent leaking
  40. * of private sources the user may not have intended to share with users.
  41. * @param {EmbedChat[]} chats
  42. * @returns {EmbedChat[]} Returns a new array of chats with the sources filtered out of responses
  43. */
  44. filterSources: function (chats) {
  45. return chats.map((chat) => {
  46. const { response, ...rest } = chat;
  47. const { sources, ...responseRest } = safeJsonParse(response);
  48. return { ...rest, response: JSON.stringify(responseRest) };
  49. });
  50. },
  51. /**
  52. * Fetches chats for a given embed and session id.
  53. * @param {number} embedId the id of the embed to fetch chats for
  54. * @param {string} sessionId the id of the session to fetch chats for
  55. * @param {number|null} limit the maximum number of chats to fetch
  56. * @param {string|null} orderBy the order to fetch chats in
  57. * @param {boolean} filterSources whether to filter out the sources from the response (default: false)
  58. * @returns {Promise<EmbedChat[]>} Returns an array of chats for the given embed and session
  59. */
  60. forEmbedByUser: async function (
  61. embedId = null,
  62. sessionId = null,
  63. limit = null,
  64. orderBy = null,
  65. filterSources = false
  66. ) {
  67. if (!embedId || !sessionId) return [];
  68. try {
  69. const chats = await prisma.embed_chats.findMany({
  70. where: {
  71. embed_id: Number(embedId),
  72. session_id: String(sessionId),
  73. include: true,
  74. },
  75. ...(limit !== null ? { take: limit } : {}),
  76. ...(orderBy !== null ? { orderBy } : { orderBy: { id: "asc" } }),
  77. });
  78. return filterSources ? this.filterSources(chats) : chats;
  79. } catch (error) {
  80. console.error(error.message);
  81. return [];
  82. }
  83. },
  84. markHistoryInvalid: async function (embedId = null, sessionId = null) {
  85. if (!embedId || !sessionId) return [];
  86. try {
  87. await prisma.embed_chats.updateMany({
  88. where: {
  89. embed_id: Number(embedId),
  90. session_id: String(sessionId),
  91. },
  92. data: {
  93. include: false,
  94. },
  95. });
  96. return;
  97. } catch (error) {
  98. console.error(error.message);
  99. }
  100. },
  101. get: async function (clause = {}, limit = null, orderBy = null) {
  102. try {
  103. const chat = await prisma.embed_chats.findFirst({
  104. where: clause,
  105. ...(limit !== null ? { take: limit } : {}),
  106. ...(orderBy !== null ? { orderBy } : {}),
  107. });
  108. return chat || null;
  109. } catch (error) {
  110. console.error(error.message);
  111. return null;
  112. }
  113. },
  114. delete: async function (clause = {}) {
  115. try {
  116. await prisma.embed_chats.deleteMany({
  117. where: clause,
  118. });
  119. return true;
  120. } catch (error) {
  121. console.error(error.message);
  122. return false;
  123. }
  124. },
  125. where: async function (
  126. clause = {},
  127. limit = null,
  128. orderBy = null,
  129. offset = null
  130. ) {
  131. try {
  132. const chats = await prisma.embed_chats.findMany({
  133. where: clause,
  134. ...(limit !== null ? { take: limit } : {}),
  135. ...(offset !== null ? { skip: offset } : {}),
  136. ...(orderBy !== null ? { orderBy } : {}),
  137. });
  138. return chats;
  139. } catch (error) {
  140. console.error(error.message);
  141. return [];
  142. }
  143. },
  144. whereWithEmbedAndWorkspace: async function (
  145. clause = {},
  146. limit = null,
  147. orderBy = null,
  148. offset = null
  149. ) {
  150. try {
  151. const chats = await prisma.embed_chats.findMany({
  152. where: clause,
  153. include: {
  154. embed_config: {
  155. select: {
  156. workspace: {
  157. select: {
  158. name: true,
  159. },
  160. },
  161. },
  162. },
  163. },
  164. ...(limit !== null ? { take: limit } : {}),
  165. ...(offset !== null ? { skip: offset } : {}),
  166. ...(orderBy !== null ? { orderBy } : {}),
  167. });
  168. return chats;
  169. } catch (error) {
  170. console.error(error.message);
  171. return [];
  172. }
  173. },
  174. count: async function (clause = {}) {
  175. try {
  176. const count = await prisma.embed_chats.count({
  177. where: clause,
  178. });
  179. return count;
  180. } catch (error) {
  181. console.error(error.message);
  182. return 0;
  183. }
  184. },
  185. };
  186. module.exports = { EmbedChats };