@studious-lms/server 1.13.0 → 1.14.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 (306) hide show
  1. package/.dockerignore +28 -0
  2. package/.env.example +5 -0
  3. package/.github/workflows/deploy.yml +123 -0
  4. package/Dockerfile +54 -0
  5. package/dist/index.js +5 -2
  6. package/dist/index.js.map +1 -1
  7. package/dist/lib/config/cors.d.ts.map +1 -1
  8. package/dist/lib/config/cors.js +31 -11
  9. package/dist/lib/config/cors.js.map +1 -1
  10. package/dist/lib/config/env.d.ts +17 -0
  11. package/dist/lib/config/env.d.ts.map +1 -1
  12. package/dist/lib/config/env.js +8 -2
  13. package/dist/lib/config/env.js.map +1 -1
  14. package/dist/lib/googleCloudStorage.d.ts +10 -0
  15. package/dist/lib/googleCloudStorage.d.ts.map +1 -1
  16. package/dist/lib/googleCloudStorage.js +22 -2
  17. package/dist/lib/googleCloudStorage.js.map +1 -1
  18. package/dist/lib/prisma.d.ts +104 -5
  19. package/dist/lib/prisma.d.ts.map +1 -1
  20. package/dist/lib/prisma.js +33 -2
  21. package/dist/lib/prisma.js.map +1 -1
  22. package/dist/models/agenda.d.ts +20 -20
  23. package/dist/models/announcement.d.ts +177 -69
  24. package/dist/models/announcement.d.ts.map +1 -1
  25. package/dist/models/assignment.d.ts +551 -353
  26. package/dist/models/assignment.d.ts.map +1 -1
  27. package/dist/models/attendance.d.ts +197 -71
  28. package/dist/models/attendance.d.ts.map +1 -1
  29. package/dist/models/auth.d.ts +348 -114
  30. package/dist/models/auth.d.ts.map +1 -1
  31. package/dist/models/class.d.ts +324 -198
  32. package/dist/models/class.d.ts.map +1 -1
  33. package/dist/models/class.js +2 -2
  34. package/dist/models/class.js.map +1 -1
  35. package/dist/models/cloudStorage.d.ts +146 -56
  36. package/dist/models/cloudStorage.d.ts.map +1 -1
  37. package/dist/models/comment.d.ts +267 -115
  38. package/dist/models/comment.d.ts.map +1 -1
  39. package/dist/models/conversation.d.ts +199 -73
  40. package/dist/models/conversation.d.ts.map +1 -1
  41. package/dist/models/department.d.ts +196 -70
  42. package/dist/models/department.d.ts.map +1 -1
  43. package/dist/models/event.d.ts +287 -125
  44. package/dist/models/event.d.ts.map +1 -1
  45. package/dist/models/file.d.ts +389 -263
  46. package/dist/models/file.d.ts.map +1 -1
  47. package/dist/models/folder.d.ts +433 -181
  48. package/dist/models/folder.d.ts.map +1 -1
  49. package/dist/models/labChat.d.ts +209 -83
  50. package/dist/models/labChat.d.ts.map +1 -1
  51. package/dist/models/marketing.d.ts +80 -26
  52. package/dist/models/marketing.d.ts.map +1 -1
  53. package/dist/models/message.d.ts +95 -41
  54. package/dist/models/message.d.ts.map +1 -1
  55. package/dist/models/newtonChat.d.ts +83 -29
  56. package/dist/models/newtonChat.d.ts.map +1 -1
  57. package/dist/models/notification.d.ts +61 -25
  58. package/dist/models/notification.d.ts.map +1 -1
  59. package/dist/models/school.d.ts +349 -133
  60. package/dist/models/school.d.ts.map +1 -1
  61. package/dist/models/section.d.ts +216 -72
  62. package/dist/models/section.d.ts.map +1 -1
  63. package/dist/models/tag.d.ts +156 -48
  64. package/dist/models/tag.d.ts.map +1 -1
  65. package/dist/models/user.d.ts +82 -28
  66. package/dist/models/user.d.ts.map +1 -1
  67. package/dist/models/worksheet.d.ts +1020 -411
  68. package/dist/models/worksheet.d.ts.map +1 -1
  69. package/dist/models/worksheet.js +8 -2
  70. package/dist/models/worksheet.js.map +1 -1
  71. package/dist/pipelines/aiLabChat.d.ts +0 -8
  72. package/dist/pipelines/aiLabChat.d.ts.map +1 -1
  73. package/dist/pipelines/aiLabChat.js +50 -67
  74. package/dist/pipelines/aiLabChat.js.map +1 -1
  75. package/dist/pipelines/aiLabChatContract.d.ts +393 -388
  76. package/dist/pipelines/aiLabChatContract.d.ts.map +1 -1
  77. package/dist/pipelines/aiLabChatContract.js +63 -69
  78. package/dist/pipelines/aiLabChatContract.js.map +1 -1
  79. package/dist/pipelines/aiNewtonChat.d.ts.map +1 -1
  80. package/dist/pipelines/aiNewtonChat.js +41 -41
  81. package/dist/pipelines/aiNewtonChat.js.map +1 -1
  82. package/dist/pipelines/gradeWorksheet.d.ts +8 -8
  83. package/dist/pipelines/labChatPrompt.d.ts +10 -8
  84. package/dist/pipelines/labChatPrompt.d.ts.map +1 -1
  85. package/dist/pipelines/labChatPrompt.js +47 -67
  86. package/dist/pipelines/labChatPrompt.js.map +1 -1
  87. package/dist/pipelines/pdfToWorksheet.d.ts +2 -2
  88. package/dist/routers/_app.d.ts +2203 -1957
  89. package/dist/routers/_app.d.ts.map +1 -1
  90. package/dist/routers/_app.js +4 -2
  91. package/dist/routers/_app.js.map +1 -1
  92. package/dist/routers/admin.d.ts +13 -13
  93. package/dist/routers/agenda.d.ts +18 -18
  94. package/dist/routers/announcement.d.ts +32 -32
  95. package/dist/routers/assignment.d.ts +335 -335
  96. package/dist/routers/attendance.d.ts +10 -10
  97. package/dist/routers/auth.d.ts +2 -2
  98. package/dist/routers/class.d.ts +147 -147
  99. package/dist/routers/comment.d.ts +22 -22
  100. package/dist/routers/conversation.d.ts +17 -17
  101. package/dist/routers/department.d.ts +34 -34
  102. package/dist/routers/discussion.d.ts +65 -53
  103. package/dist/routers/discussion.d.ts.map +1 -1
  104. package/dist/routers/discussion.js +6 -2
  105. package/dist/routers/discussion.js.map +1 -1
  106. package/dist/routers/embedding.d.ts +69 -0
  107. package/dist/routers/embedding.d.ts.map +1 -0
  108. package/dist/routers/embedding.js +143 -0
  109. package/dist/routers/embedding.js.map +1 -0
  110. package/dist/routers/event.d.ts +39 -39
  111. package/dist/routers/file.d.ts +12 -12
  112. package/dist/routers/folder.d.ts +38 -38
  113. package/dist/routers/labChat.d.ts +19 -19
  114. package/dist/routers/marketing.d.ts +2 -2
  115. package/dist/routers/message.d.ts +13 -13
  116. package/dist/routers/newtonChat.d.ts +4 -4
  117. package/dist/routers/notifications.d.ts +9 -9
  118. package/dist/routers/permissions.d.ts +14 -14
  119. package/dist/routers/school.d.ts +55 -55
  120. package/dist/routers/search.d.ts +22 -1
  121. package/dist/routers/search.d.ts.map +1 -1
  122. package/dist/routers/search.js +9 -3
  123. package/dist/routers/search.js.map +1 -1
  124. package/dist/routers/section.d.ts +4 -4
  125. package/dist/routers/studentProgress.d.ts +1 -1
  126. package/dist/routers/tag.d.ts +7 -7
  127. package/dist/routers/user.d.ts +10 -10
  128. package/dist/routers/worksheet.d.ts +95 -57
  129. package/dist/routers/worksheet.d.ts.map +1 -1
  130. package/dist/routers/worksheet.js +26 -2
  131. package/dist/routers/worksheet.js.map +1 -1
  132. package/dist/routes/aiStream.d.ts +2 -0
  133. package/dist/routes/aiStream.d.ts.map +1 -0
  134. package/dist/routes/aiStream.js +696 -0
  135. package/dist/routes/aiStream.js.map +1 -0
  136. package/dist/seedDatabase.d.ts +2 -2
  137. package/dist/seedDatabase.js +6 -6
  138. package/dist/seedDatabase.js.map +1 -1
  139. package/dist/services/adminInstitution.d.ts +8 -8
  140. package/dist/services/adminRunJob.d.ts +4 -4
  141. package/dist/services/agenda.d.ts +18 -18
  142. package/dist/services/aiChatStream.d.ts +68 -0
  143. package/dist/services/aiChatStream.d.ts.map +1 -0
  144. package/dist/services/aiChatStream.js +157 -0
  145. package/dist/services/aiChatStream.js.map +1 -0
  146. package/dist/services/aiModifierTools.d.ts +32 -0
  147. package/dist/services/aiModifierTools.d.ts.map +1 -0
  148. package/dist/services/aiModifierTools.js +165 -0
  149. package/dist/services/aiModifierTools.js.map +1 -0
  150. package/dist/services/aiProposalTools.d.ts +32 -0
  151. package/dist/services/aiProposalTools.d.ts.map +1 -0
  152. package/dist/services/aiProposalTools.js +207 -0
  153. package/dist/services/aiProposalTools.js.map +1 -0
  154. package/dist/services/aiStream.d.ts +22 -0
  155. package/dist/services/aiStream.d.ts.map +1 -0
  156. package/dist/services/aiStream.js +142 -0
  157. package/dist/services/aiStream.js.map +1 -0
  158. package/dist/services/aiTools.d.ts +16 -0
  159. package/dist/services/aiTools.d.ts.map +1 -0
  160. package/dist/services/aiTools.js +271 -0
  161. package/dist/services/aiTools.js.map +1 -0
  162. package/dist/services/announcement.d.ts +12 -12
  163. package/dist/services/announcement.d.ts.map +1 -1
  164. package/dist/services/announcement.js +7 -2
  165. package/dist/services/announcement.js.map +1 -1
  166. package/dist/services/assignment.d.ts +293 -293
  167. package/dist/services/assignment.d.ts.map +1 -1
  168. package/dist/services/assignment.js +28 -9
  169. package/dist/services/assignment.js.map +1 -1
  170. package/dist/services/attendance.d.ts +10 -10
  171. package/dist/services/auth.d.ts +2 -2
  172. package/dist/services/class.d.ts +138 -138
  173. package/dist/services/class.d.ts.map +1 -1
  174. package/dist/services/class.js +19 -3
  175. package/dist/services/class.js.map +1 -1
  176. package/dist/services/comment.d.ts +22 -22
  177. package/dist/services/conversation.d.ts +17 -17
  178. package/dist/services/department.d.ts +33 -33
  179. package/dist/services/discussion.d.ts +58 -58
  180. package/dist/services/discussion.d.ts.map +1 -1
  181. package/dist/services/discussion.js +8 -8
  182. package/dist/services/discussion.js.map +1 -1
  183. package/dist/services/discussionSummary.d.ts +21 -0
  184. package/dist/services/discussionSummary.d.ts.map +1 -0
  185. package/dist/services/discussionSummary.js +179 -0
  186. package/dist/services/discussionSummary.js.map +1 -0
  187. package/dist/services/embedding.d.ts +67 -0
  188. package/dist/services/embedding.d.ts.map +1 -0
  189. package/dist/services/embedding.js +226 -0
  190. package/dist/services/embedding.js.map +1 -0
  191. package/dist/services/event.d.ts +37 -37
  192. package/dist/services/file.d.ts +24 -24
  193. package/dist/services/folder.d.ts +36 -36
  194. package/dist/services/labChat.d.ts +19 -19
  195. package/dist/services/marketing.d.ts +2 -2
  196. package/dist/services/message.d.ts +11 -11
  197. package/dist/services/message.d.ts.map +1 -1
  198. package/dist/services/message.js +2 -2
  199. package/dist/services/message.js.map +1 -1
  200. package/dist/services/newtonChat.d.ts +4 -4
  201. package/dist/services/notification.d.ts +9 -9
  202. package/dist/services/notification.d.ts.map +1 -1
  203. package/dist/services/permissions.d.ts +14 -14
  204. package/dist/services/school.d.ts +50 -50
  205. package/dist/services/search.d.ts +12 -0
  206. package/dist/services/search.d.ts.map +1 -1
  207. package/dist/services/search.js +120 -2
  208. package/dist/services/search.js.map +1 -1
  209. package/dist/services/section.d.ts +3 -3
  210. package/dist/services/tag.d.ts +4 -4
  211. package/dist/services/user.d.ts +4 -4
  212. package/dist/services/user.d.ts.map +1 -1
  213. package/dist/services/user.js +10 -15
  214. package/dist/services/user.js.map +1 -1
  215. package/dist/services/worksheet.d.ts +60 -48
  216. package/dist/services/worksheet.d.ts.map +1 -1
  217. package/dist/services/worksheet.js +11 -4
  218. package/dist/services/worksheet.js.map +1 -1
  219. package/dist/utils/streamBroadcast.d.ts +11 -0
  220. package/dist/utils/streamBroadcast.d.ts.map +1 -0
  221. package/dist/utils/streamBroadcast.js +32 -0
  222. package/dist/utils/streamBroadcast.js.map +1 -0
  223. package/dist/workers/connection.d.ts +15 -0
  224. package/dist/workers/connection.d.ts.map +1 -1
  225. package/dist/workers/connection.js +20 -2
  226. package/dist/workers/connection.js.map +1 -1
  227. package/dist/workers/index.js +4 -2
  228. package/dist/workers/index.js.map +1 -1
  229. package/dist/workers/processors/createRunJobWorker.d.ts.map +1 -1
  230. package/dist/workers/processors/createRunJobWorker.js +31 -8
  231. package/dist/workers/processors/createRunJobWorker.js.map +1 -1
  232. package/dist/workers/processors/embedContent.d.ts +8 -0
  233. package/dist/workers/processors/embedContent.d.ts.map +1 -0
  234. package/dist/workers/processors/embedContent.js +76 -0
  235. package/dist/workers/processors/embedContent.js.map +1 -0
  236. package/dist/workers/queues.d.ts +6 -0
  237. package/dist/workers/queues.d.ts.map +1 -1
  238. package/dist/workers/queues.js +5 -3
  239. package/dist/workers/queues.js.map +1 -1
  240. package/package.json +5 -1
  241. package/prisma/migrations/20260609215135_init/migration.sql +1412 -0
  242. package/prisma/migrations/20260610130000_add_worksheet_tags/migration.sql +13 -0
  243. package/prisma/schema.prisma +38 -7
  244. package/src/index.ts +4 -0
  245. package/src/lib/config/cors.ts +32 -9
  246. package/src/lib/config/env.ts +6 -0
  247. package/src/lib/googleCloudStorage.ts +21 -0
  248. package/src/lib/prisma.ts +40 -1
  249. package/src/models/class.ts +3 -2
  250. package/src/models/worksheet.ts +5 -2
  251. package/src/pipelines/aiLabChat.ts +54 -79
  252. package/src/pipelines/aiLabChatContract.ts +69 -69
  253. package/src/pipelines/aiNewtonChat.ts +46 -43
  254. package/src/pipelines/labChatPrompt.ts +63 -88
  255. package/src/routers/_app.ts +2 -0
  256. package/src/routers/discussion.ts +7 -0
  257. package/src/routers/embedding.ts +159 -0
  258. package/src/routers/search.ts +10 -1
  259. package/src/routers/worksheet.ts +27 -0
  260. package/src/routes/aiStream.ts +789 -0
  261. package/src/seedDatabase.ts +4 -4
  262. package/src/services/aiChatStream.ts +219 -0
  263. package/src/services/aiModifierTools.ts +188 -0
  264. package/src/services/aiProposalTools.ts +272 -0
  265. package/src/services/aiStream.ts +175 -0
  266. package/src/services/aiTools.ts +290 -0
  267. package/src/services/announcement.ts +7 -0
  268. package/src/services/assignment.ts +28 -7
  269. package/src/services/class.ts +20 -1
  270. package/src/services/discussion.ts +9 -8
  271. package/src/services/discussionSummary.ts +226 -0
  272. package/src/services/embedding.ts +285 -0
  273. package/src/services/message.ts +2 -2
  274. package/src/services/search.ts +138 -0
  275. package/src/services/user.ts +9 -17
  276. package/src/services/worksheet.ts +9 -2
  277. package/src/utils/streamBroadcast.ts +48 -0
  278. package/src/workers/connection.ts +19 -0
  279. package/src/workers/index.ts +2 -0
  280. package/src/workers/processors/createRunJobWorker.ts +32 -6
  281. package/src/workers/processors/embedContent.ts +90 -0
  282. package/src/workers/queues.ts +5 -1
  283. package/tests/unit/pipelines/aiLabChatContract.test.ts +38 -21
  284. package/tests/unit/pipelines/labChatPrompt.test.ts +23 -36
  285. package/prisma/migrations/20250807062924_init/migration.sql +0 -436
  286. package/prisma/migrations/20250919063704_init2/migration.sql +0 -24
  287. package/prisma/migrations/20250920143543_add_profile_fields/migration.sql +0 -15
  288. package/prisma/migrations/20250922165147_add_chat_models/migration.sql +0 -68
  289. package/prisma/migrations/20250922165314_add_chat_roles/migration.sql +0 -5
  290. package/prisma/migrations/20250922171242_refactor_notification_system/migration.sql +0 -20
  291. package/prisma/migrations/20250922172208_add_mentions_system/migration.sql +0 -21
  292. package/prisma/migrations/20250925072732_add_lab_chat_system/migration.sql +0 -25
  293. package/prisma/migrations/20251020151505_add_upload_tracking_fields/migration.sql +0 -57
  294. package/prisma/migrations/20251109122857_annuoncements_comments/migration.sql +0 -30
  295. package/prisma/migrations/20251109135555_reactions_announcements_comments/migration.sql +0 -35
  296. package/prisma/migrations/20260410124000_add_submission_recommendation_state/migration.sql +0 -14
  297. package/prisma/migrations/20260415103500_add_session_type/migration.sql +0 -33
  298. package/prisma/migrations/20260415133000_add_ai_usage_logs/migration.sql +0 -19
  299. package/prisma/migrations/20260417083000_add_conversation_member_hidden_at/migration.sql +0 -2
  300. package/prisma/migrations/20260502230500_assignment_submission_comments/migration.sql +0 -60
  301. package/prisma/migrations/20260504071500_school_memberships/migration.sql +0 -81
  302. package/prisma/migrations/20260506162500_consolidate_run_job_and_unify_job_status/migration.sql +0 -166
  303. package/prisma/migrations/20260509220000_institution_overhaul/migration.sql +0 -184
  304. package/prisma/migrations/20260510170000_add_folder_permissions/migration.sql +0 -93
  305. package/prisma/migrations/20260510183000_add_discussions/migration.sql +0 -151
  306. /package/.github/workflows/{npm.yml → npm-publish.yml} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"worksheet.d.ts","sourceRoot":"/","sources":["models/worksheet.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worksheet.d.ts","sourceRoot":"/","sources":["models/worksheet.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,8 @@
1
+ /**
2
+ * Worksheet model – worksheets, questions, submissions, student progress, grading.
3
+ */
1
4
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a1e3405c-0bf6-5b87-8576-7f4928149b18")}catch(e){}}();
5
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="392edd40-7fcc-5f70-9f75-772cac189e55")}catch(e){}}();
3
6
  import { prisma } from "../lib/prisma.js";
4
7
  import { classMemberOrSchoolAdminWhere, classTeacherOrSchoolAdminWhere, } from "./access.js";
5
8
  const worksheetClassMemberWhere = (userId) => ({
@@ -34,6 +37,7 @@ export function findWorksheetByIdForClassMember(id, userId) {
34
37
  include: {
35
38
  questions: { orderBy: { order: "asc" } },
36
39
  class: true,
40
+ tags: true,
37
41
  },
38
42
  });
39
43
  }
@@ -47,6 +51,7 @@ export function findWorksheetByIdForTeacher(id, userId) {
47
51
  include: {
48
52
  questions: { orderBy: { order: "asc" } },
49
53
  class: true,
54
+ tags: true,
50
55
  },
51
56
  });
52
57
  }
@@ -56,6 +61,7 @@ export function findWorksheetsByClassId(classId) {
56
61
  where: { classId },
57
62
  include: {
58
63
  questions: { select: { id: true } },
64
+ tags: true,
59
65
  },
60
66
  orderBy: { createdAt: "desc" },
61
67
  });
@@ -418,4 +424,4 @@ export function createComment(data) {
418
424
  });
419
425
  }
420
426
  //# sourceMappingURL=worksheet.js.map
421
- //# debugId=a1e3405c-0bf6-5b87-8576-7f4928149b18
427
+ //# debugId=392edd40-7fcc-5f70-9f75-772cac189e55
@@ -1 +1 @@
1
- {"version":3,"file":"worksheet.js","sources":["models/worksheet.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Worksheet model – worksheets, questions, submissions, student progress, grading.\n */\nimport type { Prisma } from \"@prisma/client\";\nimport { prisma } from \"../lib/prisma.js\";\nimport type { WorksheetQuestionType, JobStatus } from \"@prisma/client\";\nimport {\n classMemberOrSchoolAdminWhere,\n classTeacherOrSchoolAdminWhere,\n} from \"./access.js\";\n\nconst worksheetClassMemberWhere = (userId: string) => ({\n class: classMemberOrSchoolAdminWhere(userId),\n});\n\nconst worksheetTeacherWhere = (userId: string) => ({\n class: classTeacherOrSchoolAdminWhere(userId),\n});\n\n/** @returns Worksheet with questions and class. */\nexport function findWorksheetById(id: string) {\n return prisma.worksheet.findUnique({\n where: { id },\n include: {\n questions: { orderBy: { order: \"asc\" as const } },\n class: true,\n },\n });\n}\n\n/** @returns Worksheet by ID (minimal). */\nexport function findWorksheetByIdMinimal(id: string) {\n return prisma.worksheet.findUnique({\n where: { id },\n });\n}\n\n/** @returns Worksheet by ID for an authorized class member. */\nexport function findWorksheetByIdForClassMember(id: string, userId: string) {\n return prisma.worksheet.findFirst({\n where: {\n id,\n ...worksheetClassMemberWhere(userId),\n },\n include: {\n questions: { orderBy: { order: \"asc\" as const } },\n class: true,\n },\n });\n}\n\n/** @returns Worksheet by ID for an authorized teacher. */\nexport function findWorksheetByIdForTeacher(id: string, userId: string) {\n return prisma.worksheet.findFirst({\n where: {\n id,\n ...worksheetTeacherWhere(userId),\n },\n include: {\n questions: { orderBy: { order: \"asc\" as const } },\n class: true,\n },\n });\n}\n\n/** @returns Worksheets for a class. */\nexport function findWorksheetsByClassId(classId: string) {\n return prisma.worksheet.findMany({\n where: { classId },\n include: {\n questions: { select: { id: true } },\n },\n orderBy: { createdAt: \"desc\" },\n });\n}\n\n/** @returns Worksheet question by ID for an authorized teacher. */\nexport function findWorksheetQuestionByIdForTeacher(id: string, userId: string) {\n return prisma.worksheetQuestion.findFirst({\n where: {\n id,\n worksheet: worksheetTeacherWhere(userId),\n },\n });\n}\n\n/** @returns Worksheet question scoped to a worksheet. */\nexport function findWorksheetQuestionByIdInWorksheet(\n id: string,\n worksheetId: string\n) {\n return prisma.worksheetQuestion.findFirst({\n where: { id, worksheetId },\n });\n}\n\n/** Create a worksheet. */\nexport function createWorksheet(data: { classId: string; name: string }) {\n return prisma.worksheet.create({\n data,\n });\n}\n\n/** Update worksheet name. */\nexport function updateWorksheet(id: string, data: { name?: string }) {\n return prisma.worksheet.update({\n where: { id },\n data,\n });\n}\n\n/** Delete a worksheet. */\nexport function deleteWorksheet(id: string) {\n return prisma.worksheet.delete({\n where: { id },\n });\n}\n\n/**\n * Clone a worksheet and its questions into another class with a new name.\n * Does not copy student responses or assignment links.\n */\nexport async function duplicateWorksheetWithClient(\n tx: Prisma.TransactionClient,\n sourceWorksheetId: string,\n targetClassId: string,\n name: string\n) {\n const source = await tx.worksheet.findUnique({\n where: { id: sourceWorksheetId },\n include: {\n questions: { orderBy: { order: \"asc\" } },\n },\n });\n\n if (!source) {\n return null;\n }\n\n const created = await tx.worksheet.create({\n data: { classId: targetClassId, name },\n });\n\n if (source.questions.length > 0) {\n await tx.worksheetQuestion.createMany({\n data: source.questions.map((q) => ({\n worksheetId: created.id,\n type: q.type,\n question: q.question,\n answer: q.answer,\n points: q.points,\n options: q.options ?? undefined,\n markScheme: q.markScheme ?? undefined,\n order: q.order,\n })),\n });\n }\n\n return created;\n}\n\nexport async function duplicateWorksheet(\n sourceWorksheetId: string,\n targetClassId: string,\n name: string\n) {\n return prisma.$transaction((tx) =>\n duplicateWorksheetWithClient(tx, sourceWorksheetId, targetClassId, name)\n );\n}\n\n/** @returns Questions for a worksheet. */\nexport function findQuestionsByWorksheetId(worksheetId: string) {\n return prisma.worksheetQuestion.findMany({\n where: { worksheetId },\n orderBy: { order: \"asc\" },\n });\n}\n\n/** Create a worksheet question. */\nexport function createWorksheetQuestion(data: {\n worksheetId: string;\n type: WorksheetQuestionType;\n question: string;\n answer: string;\n points?: number;\n options?: object;\n markScheme?: object;\n order?: number;\n}) {\n return prisma.worksheetQuestion.create({\n data,\n });\n}\n\n/** Update question order. */\nexport function updateWorksheetQuestionOrder(id: string, order: number) {\n return prisma.worksheetQuestion.update({\n where: { id },\n data: { order },\n });\n}\n\n/** Update a worksheet question. */\nexport function updateWorksheetQuestion(\n id: string,\n data: {\n question?: string;\n answer?: string;\n points?: number;\n options?: object;\n markScheme?: object;\n type?: WorksheetQuestionType;\n }\n) {\n return prisma.worksheetQuestion.update({\n where: { id },\n data,\n });\n}\n\n/** Delete a worksheet question. */\nexport function deleteWorksheetQuestion(id: string) {\n return prisma.worksheetQuestion.delete({\n where: { id },\n });\n}\n\n/** @returns Submission by ID. */\nexport function findSubmissionById(id: string) {\n return prisma.submission.findUnique({\n where: { id },\n });\n}\n\n/** @returns Submission if requester is the owning student or a class teacher for the worksheet. */\nexport function findSubmissionByIdForWorksheetAccess(\n id: string,\n worksheetId: string,\n worksheetClassId: string,\n userId: string\n) {\n return prisma.submission.findFirst({\n where: {\n id,\n assignment: {\n classId: worksheetClassId,\n worksheets: { some: { id: worksheetId } },\n },\n OR: [\n {\n studentId: userId,\n assignment: {\n class: {\n students: { some: { id: userId } },\n },\n },\n },\n {\n assignment: {\n class: classTeacherOrSchoolAdminWhere(userId),\n },\n },\n ],\n },\n select: {\n id: true,\n studentId: true,\n },\n });\n}\n\nconst worksheetResponseInclude = {\n responses: {\n include: {\n comments: {\n select: { id: true, isPinned: true },\n orderBy: [{ isPinned: \"desc\" as const }, { createdAt: \"asc\" as const }],\n },\n },\n },\n};\n\n/** @returns Worksheet response for submission and worksheet. */\nexport function findWorksheetResponseBySubmissionAndWorksheet(\n submissionId: string,\n worksheetId: string\n) {\n return prisma.studentWorksheetResponse.findFirst({\n where: { submissionId, worksheetId },\n include: worksheetResponseInclude,\n });\n}\n\n/** Get or create worksheet response for student. */\nexport async function findOrCreateWorksheetResponse(\n submissionId: string,\n worksheetId: string,\n studentId: string\n) {\n return prisma.$transaction(async (tx) => {\n const existing = await tx.studentWorksheetResponse.findFirst({\n where: { submissionId, worksheetId },\n include: worksheetResponseInclude,\n });\n if (existing) return existing;\n return tx.studentWorksheetResponse.create({\n data: { worksheetId, submissionId, studentId },\n include: worksheetResponseInclude,\n });\n });\n}\n\n/** Create a worksheet response. */\nexport function createWorksheetResponse(data: {\n worksheetId: string;\n submissionId: string;\n studentId: string;\n}) {\n return prisma.studentWorksheetResponse.create({\n data,\n include: {\n responses: {\n include: {\n comments: {\n select: { id: true, isPinned: true },\n orderBy: [{ isPinned: \"desc\" as const }, { createdAt: \"asc\" as const }],\n },\n },\n },\n },\n });\n}\n\n/** @returns Worksheet response by ID. */\nexport function findWorksheetResponseById(id: string) {\n return prisma.studentWorksheetResponse.findUnique({\n where: { id },\n include: { responses: true },\n });\n}\n\n/** @returns Worksheet response if requester is the owning student. */\nexport function findWorksheetResponseByIdForStudent(id: string, userId: string) {\n return prisma.studentWorksheetResponse.findFirst({\n where: {\n id,\n studentId: userId,\n worksheet: worksheetClassMemberWhere(userId),\n },\n include: { responses: true, worksheet: true },\n });\n}\n\n/** @returns Worksheet response if requester is a class teacher. */\nexport function findWorksheetResponseByIdForTeacher(id: string, userId: string) {\n return prisma.studentWorksheetResponse.findFirst({\n where: {\n id,\n worksheet: worksheetTeacherWhere(userId),\n },\n include: { responses: true, worksheet: true },\n });\n}\n\n/** @returns Worksheet response with question responses. */\nexport function findWorksheetResponseWithResponses(\n id: string,\n questionId?: string\n) {\n return prisma.studentWorksheetResponse.findUnique({\n where: { id },\n include: {\n responses: questionId\n ? { where: { questionId } }\n : true,\n },\n });\n}\n\n/** @returns Worksheet response with scoped responses if requester is the owning student. */\nexport function findWorksheetResponseWithResponsesForStudent(\n id: string,\n userId: string,\n questionId?: string\n) {\n return prisma.studentWorksheetResponse.findFirst({\n where: {\n id,\n studentId: userId,\n worksheet: worksheetClassMemberWhere(userId),\n },\n include: {\n worksheet: true,\n responses: questionId ? { where: { questionId } } : true,\n },\n });\n}\n\n/** @returns Worksheet response with scoped responses if requester is a class teacher. */\nexport function findWorksheetResponseWithResponsesForTeacher(\n id: string,\n userId: string,\n questionId?: string\n) {\n return prisma.studentWorksheetResponse.findFirst({\n where: {\n id,\n worksheet: worksheetTeacherWhere(userId),\n },\n include: {\n worksheet: true,\n responses: questionId ? { where: { questionId } } : true,\n },\n });\n}\n\n/** @returns Worksheet question by ID. */\nexport function findWorksheetQuestionById(id: string) {\n return prisma.worksheetQuestion.findUnique({\n where: { id },\n });\n}\n\n/** @returns Student question progress if requester is a class teacher. */\nexport function findStudentQuestionProgressByIdForTeacher(\n id: string,\n userId: string\n) {\n return prisma.studentQuestionProgress.findFirst({\n where: {\n id,\n question: {\n worksheet: worksheetTeacherWhere(userId),\n },\n },\n include: {\n question: true,\n studentWorksheetResponse: true,\n },\n });\n}\n\n/** @returns Student question progress by id and worksheet response if requester is a class teacher. */\nexport function findStudentQuestionProgressByIdForTeacherAndResponse(\n id: string,\n studentWorksheetResponseId: string,\n userId: string\n) {\n return prisma.studentQuestionProgress.findFirst({\n where: {\n id,\n studentWorksheetResponseId,\n question: {\n worksheet: worksheetTeacherWhere(userId),\n },\n },\n include: {\n question: true,\n studentWorksheetResponse: true,\n },\n });\n}\n\n/**\n * @returns Student question progress if requester is the answering student (class member) or a\n * class teacher / school admin for that worksheet.\n */\nexport function findStudentQuestionProgressByIdForStudentOrTeacher(\n id: string,\n userId: string\n) {\n return prisma.studentQuestionProgress.findFirst({\n where: {\n id,\n OR: [\n {\n studentId: userId,\n question: { worksheet: worksheetClassMemberWhere(userId) },\n },\n {\n question: { worksheet: worksheetTeacherWhere(userId) },\n },\n ],\n },\n include: {\n question: true,\n studentWorksheetResponse: true,\n },\n });\n}\n\n/** Update student's question progress. */\nexport function updateStudentQuestionProgress(\n id: string,\n data: {\n response?: string;\n isCorrect?: boolean;\n points?: number;\n status?: JobStatus;\n }\n) {\n return prisma.studentQuestionProgress.update({\n where: { id },\n data,\n });\n}\n\n/** Create student question progress. */\nexport function createStudentQuestionProgress(data: {\n studentId: string;\n questionId: string;\n studentWorksheetResponseId: string;\n response: string;\n isCorrect?: boolean;\n points?: number;\n}) {\n return prisma.studentQuestionProgress.create({\n data,\n });\n}\n\n/** @returns Student's progress for a question. */\nexport function findStudentQuestionProgress(\n studentId: string,\n questionId: string,\n studentWorksheetResponseId: string\n) {\n return prisma.studentQuestionProgress.findFirst({\n where: {\n studentId,\n questionId,\n studentWorksheetResponseId,\n },\n });\n}\n\n/** Update progress for grading (AI feedback, marks). */\nexport function updateStudentQuestionProgressForGrading(\n id: string,\n data: {\n isCorrect?: boolean;\n feedback?: string;\n markschemeState?: object;\n points?: number;\n response?: string;\n }\n) {\n return prisma.studentQuestionProgress.update({\n where: { id },\n data,\n });\n}\n\n/** Create progress record for grading pipeline. */\nexport function createStudentQuestionProgressForGrading(data: {\n studentId: string;\n questionId: string;\n studentWorksheetResponseId: string;\n response: string;\n isCorrect: boolean;\n feedback?: string;\n markschemeState?: object;\n points?: number;\n}) {\n return prisma.studentQuestionProgress.create({\n data,\n });\n}\n\n/** Create a comment on a worksheet response. */\nexport function createComment(data: {\n studentQuestionProgressId: string;\n content: string;\n authorId: string;\n}) {\n return prisma.comment.create({\n data,\n });\n}\n"],"names":[],"mappings":"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","debug_id":"a1e3405c-0bf6-5b87-8576-7f4928149b18"}
1
+ {"version":3,"file":"worksheet.js","sources":["models/worksheet.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Worksheet model – worksheets, questions, submissions, student progress, grading.\n */\nimport { prisma } from \"../lib/prisma.js\";\nimport type { AppTransactionClient } from \"../lib/prisma.js\";\nimport type { WorksheetQuestionType, JobStatus } from \"@prisma/client\";\nimport {\n classMemberOrSchoolAdminWhere,\n classTeacherOrSchoolAdminWhere,\n} from \"./access.js\";\n\nconst worksheetClassMemberWhere = (userId: string) => ({\n class: classMemberOrSchoolAdminWhere(userId),\n});\n\nconst worksheetTeacherWhere = (userId: string) => ({\n class: classTeacherOrSchoolAdminWhere(userId),\n});\n\n/** @returns Worksheet with questions and class. */\nexport function findWorksheetById(id: string) {\n return prisma.worksheet.findUnique({\n where: { id },\n include: {\n questions: { orderBy: { order: \"asc\" as const } },\n class: true,\n },\n });\n}\n\n/** @returns Worksheet by ID (minimal). */\nexport function findWorksheetByIdMinimal(id: string) {\n return prisma.worksheet.findUnique({\n where: { id },\n });\n}\n\n/** @returns Worksheet by ID for an authorized class member. */\nexport function findWorksheetByIdForClassMember(id: string, userId: string) {\n return prisma.worksheet.findFirst({\n where: {\n id,\n ...worksheetClassMemberWhere(userId),\n },\n include: {\n questions: { orderBy: { order: \"asc\" as const } },\n class: true,\n tags: true,\n },\n });\n}\n\n/** @returns Worksheet by ID for an authorized teacher. */\nexport function findWorksheetByIdForTeacher(id: string, userId: string) {\n return prisma.worksheet.findFirst({\n where: {\n id,\n ...worksheetTeacherWhere(userId),\n },\n include: {\n questions: { orderBy: { order: \"asc\" as const } },\n class: true,\n tags: true,\n },\n });\n}\n\n/** @returns Worksheets for a class. */\nexport function findWorksheetsByClassId(classId: string) {\n return prisma.worksheet.findMany({\n where: { classId },\n include: {\n questions: { select: { id: true } },\n tags: true,\n },\n orderBy: { createdAt: \"desc\" },\n });\n}\n\n/** @returns Worksheet question by ID for an authorized teacher. */\nexport function findWorksheetQuestionByIdForTeacher(id: string, userId: string) {\n return prisma.worksheetQuestion.findFirst({\n where: {\n id,\n worksheet: worksheetTeacherWhere(userId),\n },\n });\n}\n\n/** @returns Worksheet question scoped to a worksheet. */\nexport function findWorksheetQuestionByIdInWorksheet(\n id: string,\n worksheetId: string\n) {\n return prisma.worksheetQuestion.findFirst({\n where: { id, worksheetId },\n });\n}\n\n/** Create a worksheet. */\nexport function createWorksheet(data: { classId: string; name: string }) {\n return prisma.worksheet.create({\n data,\n });\n}\n\n/** Update worksheet name. */\nexport function updateWorksheet(id: string, data: { name?: string }) {\n return prisma.worksheet.update({\n where: { id },\n data,\n });\n}\n\n/** Delete a worksheet. */\nexport function deleteWorksheet(id: string) {\n return prisma.worksheet.delete({\n where: { id },\n });\n}\n\n/**\n * Clone a worksheet and its questions into another class with a new name.\n * Does not copy student responses or assignment links.\n */\nexport async function duplicateWorksheetWithClient(\n tx: AppTransactionClient,\n sourceWorksheetId: string,\n targetClassId: string,\n name: string\n) {\n const source = await tx.worksheet.findUnique({\n where: { id: sourceWorksheetId },\n include: {\n questions: { orderBy: { order: \"asc\" } },\n },\n });\n\n if (!source) {\n return null;\n }\n\n const created = await tx.worksheet.create({\n data: { classId: targetClassId, name },\n });\n\n if (source.questions.length > 0) {\n await tx.worksheetQuestion.createMany({\n data: source.questions.map((q) => ({\n worksheetId: created.id,\n type: q.type,\n question: q.question,\n answer: q.answer,\n points: q.points,\n options: q.options ?? undefined,\n markScheme: q.markScheme ?? undefined,\n order: q.order,\n })),\n });\n }\n\n return created;\n}\n\nexport async function duplicateWorksheet(\n sourceWorksheetId: string,\n targetClassId: string,\n name: string\n) {\n return prisma.$transaction((tx) =>\n duplicateWorksheetWithClient(tx, sourceWorksheetId, targetClassId, name)\n );\n}\n\n/** @returns Questions for a worksheet. */\nexport function findQuestionsByWorksheetId(worksheetId: string) {\n return prisma.worksheetQuestion.findMany({\n where: { worksheetId },\n orderBy: { order: \"asc\" },\n });\n}\n\n/** Create a worksheet question. */\nexport function createWorksheetQuestion(data: {\n worksheetId: string;\n type: WorksheetQuestionType;\n question: string;\n answer: string;\n points?: number;\n options?: object;\n markScheme?: object;\n order?: number;\n}) {\n return prisma.worksheetQuestion.create({\n data,\n });\n}\n\n/** Update question order. */\nexport function updateWorksheetQuestionOrder(id: string, order: number) {\n return prisma.worksheetQuestion.update({\n where: { id },\n data: { order },\n });\n}\n\n/** Update a worksheet question. */\nexport function updateWorksheetQuestion(\n id: string,\n data: {\n question?: string;\n answer?: string;\n points?: number;\n options?: object;\n markScheme?: object;\n type?: WorksheetQuestionType;\n }\n) {\n return prisma.worksheetQuestion.update({\n where: { id },\n data,\n });\n}\n\n/** Delete a worksheet question. */\nexport function deleteWorksheetQuestion(id: string) {\n return prisma.worksheetQuestion.delete({\n where: { id },\n });\n}\n\n/** @returns Submission by ID. */\nexport function findSubmissionById(id: string) {\n return prisma.submission.findUnique({\n where: { id },\n });\n}\n\n/** @returns Submission if requester is the owning student or a class teacher for the worksheet. */\nexport function findSubmissionByIdForWorksheetAccess(\n id: string,\n worksheetId: string,\n worksheetClassId: string,\n userId: string\n) {\n return prisma.submission.findFirst({\n where: {\n id,\n assignment: {\n classId: worksheetClassId,\n worksheets: { some: { id: worksheetId } },\n },\n OR: [\n {\n studentId: userId,\n assignment: {\n class: {\n students: { some: { id: userId } },\n },\n },\n },\n {\n assignment: {\n class: classTeacherOrSchoolAdminWhere(userId),\n },\n },\n ],\n },\n select: {\n id: true,\n studentId: true,\n },\n });\n}\n\nconst worksheetResponseInclude = {\n responses: {\n include: {\n comments: {\n select: { id: true, isPinned: true },\n orderBy: [{ isPinned: \"desc\" as const }, { createdAt: \"asc\" as const }],\n },\n },\n },\n};\n\n/** @returns Worksheet response for submission and worksheet. */\nexport function findWorksheetResponseBySubmissionAndWorksheet(\n submissionId: string,\n worksheetId: string\n) {\n return prisma.studentWorksheetResponse.findFirst({\n where: { submissionId, worksheetId },\n include: worksheetResponseInclude,\n });\n}\n\n/** Get or create worksheet response for student. */\nexport async function findOrCreateWorksheetResponse(\n submissionId: string,\n worksheetId: string,\n studentId: string\n) {\n return prisma.$transaction(async (tx) => {\n const existing = await tx.studentWorksheetResponse.findFirst({\n where: { submissionId, worksheetId },\n include: worksheetResponseInclude,\n });\n if (existing) return existing;\n return tx.studentWorksheetResponse.create({\n data: { worksheetId, submissionId, studentId },\n include: worksheetResponseInclude,\n });\n });\n}\n\n/** Create a worksheet response. */\nexport function createWorksheetResponse(data: {\n worksheetId: string;\n submissionId: string;\n studentId: string;\n}) {\n return prisma.studentWorksheetResponse.create({\n data,\n include: {\n responses: {\n include: {\n comments: {\n select: { id: true, isPinned: true },\n orderBy: [{ isPinned: \"desc\" as const }, { createdAt: \"asc\" as const }],\n },\n },\n },\n },\n });\n}\n\n/** @returns Worksheet response by ID. */\nexport function findWorksheetResponseById(id: string) {\n return prisma.studentWorksheetResponse.findUnique({\n where: { id },\n include: { responses: true },\n });\n}\n\n/** @returns Worksheet response if requester is the owning student. */\nexport function findWorksheetResponseByIdForStudent(id: string, userId: string) {\n return prisma.studentWorksheetResponse.findFirst({\n where: {\n id,\n studentId: userId,\n worksheet: worksheetClassMemberWhere(userId),\n },\n include: { responses: true, worksheet: true },\n });\n}\n\n/** @returns Worksheet response if requester is a class teacher. */\nexport function findWorksheetResponseByIdForTeacher(id: string, userId: string) {\n return prisma.studentWorksheetResponse.findFirst({\n where: {\n id,\n worksheet: worksheetTeacherWhere(userId),\n },\n include: { responses: true, worksheet: true },\n });\n}\n\n/** @returns Worksheet response with question responses. */\nexport function findWorksheetResponseWithResponses(\n id: string,\n questionId?: string\n) {\n return prisma.studentWorksheetResponse.findUnique({\n where: { id },\n include: {\n responses: questionId\n ? { where: { questionId } }\n : true,\n },\n });\n}\n\n/** @returns Worksheet response with scoped responses if requester is the owning student. */\nexport function findWorksheetResponseWithResponsesForStudent(\n id: string,\n userId: string,\n questionId?: string\n) {\n return prisma.studentWorksheetResponse.findFirst({\n where: {\n id,\n studentId: userId,\n worksheet: worksheetClassMemberWhere(userId),\n },\n include: {\n worksheet: true,\n responses: questionId ? { where: { questionId } } : true,\n },\n });\n}\n\n/** @returns Worksheet response with scoped responses if requester is a class teacher. */\nexport function findWorksheetResponseWithResponsesForTeacher(\n id: string,\n userId: string,\n questionId?: string\n) {\n return prisma.studentWorksheetResponse.findFirst({\n where: {\n id,\n worksheet: worksheetTeacherWhere(userId),\n },\n include: {\n worksheet: true,\n responses: questionId ? { where: { questionId } } : true,\n },\n });\n}\n\n/** @returns Worksheet question by ID. */\nexport function findWorksheetQuestionById(id: string) {\n return prisma.worksheetQuestion.findUnique({\n where: { id },\n });\n}\n\n/** @returns Student question progress if requester is a class teacher. */\nexport function findStudentQuestionProgressByIdForTeacher(\n id: string,\n userId: string\n) {\n return prisma.studentQuestionProgress.findFirst({\n where: {\n id,\n question: {\n worksheet: worksheetTeacherWhere(userId),\n },\n },\n include: {\n question: true,\n studentWorksheetResponse: true,\n },\n });\n}\n\n/** @returns Student question progress by id and worksheet response if requester is a class teacher. */\nexport function findStudentQuestionProgressByIdForTeacherAndResponse(\n id: string,\n studentWorksheetResponseId: string,\n userId: string\n) {\n return prisma.studentQuestionProgress.findFirst({\n where: {\n id,\n studentWorksheetResponseId,\n question: {\n worksheet: worksheetTeacherWhere(userId),\n },\n },\n include: {\n question: true,\n studentWorksheetResponse: true,\n },\n });\n}\n\n/**\n * @returns Student question progress if requester is the answering student (class member) or a\n * class teacher / school admin for that worksheet.\n */\nexport function findStudentQuestionProgressByIdForStudentOrTeacher(\n id: string,\n userId: string\n) {\n return prisma.studentQuestionProgress.findFirst({\n where: {\n id,\n OR: [\n {\n studentId: userId,\n question: { worksheet: worksheetClassMemberWhere(userId) },\n },\n {\n question: { worksheet: worksheetTeacherWhere(userId) },\n },\n ],\n },\n include: {\n question: true,\n studentWorksheetResponse: true,\n },\n });\n}\n\n/** Update student's question progress. */\nexport function updateStudentQuestionProgress(\n id: string,\n data: {\n response?: string;\n isCorrect?: boolean;\n points?: number;\n status?: JobStatus;\n }\n) {\n return prisma.studentQuestionProgress.update({\n where: { id },\n data,\n });\n}\n\n/** Create student question progress. */\nexport function createStudentQuestionProgress(data: {\n studentId: string;\n questionId: string;\n studentWorksheetResponseId: string;\n response: string;\n isCorrect?: boolean;\n points?: number;\n}) {\n return prisma.studentQuestionProgress.create({\n data,\n });\n}\n\n/** @returns Student's progress for a question. */\nexport function findStudentQuestionProgress(\n studentId: string,\n questionId: string,\n studentWorksheetResponseId: string\n) {\n return prisma.studentQuestionProgress.findFirst({\n where: {\n studentId,\n questionId,\n studentWorksheetResponseId,\n },\n });\n}\n\n/** Update progress for grading (AI feedback, marks). */\nexport function updateStudentQuestionProgressForGrading(\n id: string,\n data: {\n isCorrect?: boolean;\n feedback?: string;\n markschemeState?: object;\n points?: number;\n response?: string;\n }\n) {\n return prisma.studentQuestionProgress.update({\n where: { id },\n data,\n });\n}\n\n/** Create progress record for grading pipeline. */\nexport function createStudentQuestionProgressForGrading(data: {\n studentId: string;\n questionId: string;\n studentWorksheetResponseId: string;\n response: string;\n isCorrect: boolean;\n feedback?: string;\n markschemeState?: object;\n points?: number;\n}) {\n return prisma.studentQuestionProgress.create({\n data,\n });\n}\n\n/** Create a comment on a worksheet response. */\nexport function createComment(data: {\n studentQuestionProgressId: string;\n content: string;\n authorId: string;\n}) {\n return prisma.comment.create({\n data,\n });\n}\n"],"names":[],"mappings":"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","debug_id":"392edd40-7fcc-5f70-9f75-772cac189e55"}
@@ -73,14 +73,6 @@ export declare const buildClassContextForAI: (data: ClassContextData) => string;
73
73
  * @deprecated Use buildClassContextForAI for schema-aware context. Kept for compatibility.
74
74
  */
75
75
  export declare const getBaseSystemPrompt: (context: Class, members: User[], assignments: Assignment[], files: File[], sections: Section[]) => string;
76
- /**
77
- * Generate labchat responses
78
- * Allow for the generation of the following:
79
- * - Assignment(s) either individual or bulk as an lesson / course plan.
80
- * - Worksheet(s) either individual or bulk as an lesson / course plan.
81
- * - Files (PDFs)
82
- * @param labChatId
83
- */
84
76
  /**
85
77
  * Fill the AI introduction placeholder for a brand-new lab chat.
86
78
  *
@@ -1 +1 @@
1
- {"version":3,"file":"aiLabChat.d.ts","sourceRoot":"/","sources":["pipelines/aiLabChat.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"aiLabChat.d.ts","sourceRoot":"/","sources":["pipelines/aiLabChat.ts"],"names":[],"mappings":"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"}
@@ -3,17 +3,20 @@
3
3
  * Can create worksheets, sections, assignments, and PDF docs from AI output.
4
4
  */
5
5
 
6
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="e57f7401-27fd-5eac-a76a-cb84f699b776")}catch(e){}}();
6
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="4bfeb1af-edc2-540a-acc7-d36c999b18a3")}catch(e){}}();
7
7
  import { isAIUser } from "../utils/aiUser.js";
8
8
  import { prisma } from "../lib/prisma.js";
9
9
  import { pusher, teacherChannel } from "../lib/pusher.js";
10
- import { inference, completePendingAIMessage, failPendingAIMessage, } from "../utils/inference.js";
10
+ import { completePendingAIMessage, failPendingAIMessage, } from "../utils/inference.js";
11
11
  import { logger } from "../utils/logger.js";
12
12
  import { createPdf } from "../lib/jsonConversion.js";
13
13
  import { v4 } from "uuid";
14
14
  import { bucket } from "../lib/googleCloudStorage.js";
15
- import { labChatResponseSchema } from "./aiLabChatContract.js";
16
- import { buildLabChatResponseMessages } from "./labChatPrompt.js";
15
+ import { broadcastTextChunks, broadcastStreamComplete } from "../utils/streamBroadcast.js";
16
+ import { buildLabChatAgentMessages } from "./labChatPrompt.js";
17
+ import { streamChatResponse } from "../services/aiChatStream.js";
18
+ import { aiTools } from "../services/aiTools.js";
19
+ import { labProposalTools, createLabProposals } from "../services/aiProposalTools.js";
17
20
  /** Cap model wait time; leave headroom after inference for PDF/GCS/DB within Vercel maxDuration (500s). */
18
21
  const LAB_CHAT_RESPONSE_TIMEOUT_MS = 400000;
19
22
  const withTimeout = async (task, timeoutMs, operationName) => {
@@ -224,28 +227,6 @@ export const getBaseSystemPrompt = (context, members, assignments, files, sectio
224
227
  assignments,
225
228
  });
226
229
  };
227
- /**
228
- * Generate labchat responses
229
- * Allow for the generation of the following:
230
- * - Assignment(s) either individual or bulk as an lesson / course plan.
231
- * - Worksheet(s) either individual or bulk as an lesson / course plan.
232
- * - Files (PDFs)
233
- * @param labChatId
234
- */
235
- // export const sendAiLabChatResponsePipeline = async (labChatId: string) => {
236
- // const message = await prisma?.message.create({
237
- // data: {
238
- // content: "GENERATING_CONTENT",
239
- // senderId: getAIUserId(),
240
- // conversationId: labChatId,
241
- // status: JobStatus.PENDING,
242
- // },
243
- // });
244
- // try {
245
- // inference(`
246
- // `)
247
- // }
248
- // };
249
230
  /**
250
231
  * Fill the AI introduction placeholder for a brand-new lab chat.
251
232
  *
@@ -256,6 +237,7 @@ export const getBaseSystemPrompt = (context, members, assignments, files, sectio
256
237
  export const generateAndSendLabIntroduction = async (labChatId, conversationId, _contextString, _subject, aiMessageId) => {
257
238
  const introMessage = "Hello teaching team! I'm your AI assistant for course material development. I'll help you create educational content - when you have a clear request, I'll produce it directly. I only ask questions when I need to clarify the topic or scope. What would you like to work on?";
258
239
  try {
240
+ await broadcastTextChunks(conversationId, aiMessageId, introMessage);
259
241
  await completePendingAIMessage(aiMessageId, introMessage);
260
242
  logger.info('AI Introduction sent', { labChatId, conversationId, aiMessageId });
261
243
  }
@@ -366,38 +348,41 @@ export const generateAndSendLabResponse = async (labChatId, _teacherMessage, emi
366
348
  teachers: classData.teachers,
367
349
  assignments: classData.assignments,
368
350
  });
369
- const messages = buildLabChatResponseMessages({
351
+ const { system, messages } = buildLabChatAgentMessages({
370
352
  context: fullLabChat.context,
371
353
  classContext,
372
354
  recentMessages: recentMessages.reverse(),
373
355
  isAIUser,
374
356
  });
375
- // const completion = await inferenceClient.chat.completions.create({
376
- // model: 'command-a-03-2025',
377
- // messages,
378
- // temperature: 0.7,
379
- // response_format: zodTextFormat(labChatResponseSchema, "lab_chat_response_format"),
380
- // });
381
- const response = await withTimeout(inference(messages, labChatResponseSchema, {
382
- reason: 'lab_chat_response',
383
- metadata: {
384
- labChatId,
385
- conversationId,
386
- classId: fullLabChat.classId,
387
- aiMessageId: emitOptions.aiMessageId,
388
- },
357
+ // Genuine agentic generation: the model streams prose token-by-token and
358
+ // calls real tools inline — read-only RAG lookups plus "propose_*" tools
359
+ // that record create-actions into `proposals`. `streamChatResponse`
360
+ // broadcasts the real text chunks and tool-call events as they happen.
361
+ const proposals = createLabProposals();
362
+ const tools = {
363
+ ...aiTools(fullLabChat.classId),
364
+ ...labProposalTools(proposals),
365
+ };
366
+ const { text: streamedText, parts: streamParts } = await withTimeout(streamChatResponse({
367
+ conversationId,
368
+ aiMessageId: emitOptions.aiMessageId,
369
+ system,
370
+ messages,
371
+ tools,
372
+ temperature: 0.7,
373
+ maxOutputTokens: 4096,
374
+ maxSteps: 8,
389
375
  }), LAB_CHAT_RESPONSE_TIMEOUT_MS, "Lab chat response generation");
390
- if (!response) {
391
- throw new Error('No response generated from inference API');
392
- }
393
- // Parse the JSON response and generate PDF if docs are provided
376
+ // Real text + tool-call events were already broadcast inline (in order)
377
+ // during the stream by `streamChatResponse`. Just close the stream.
378
+ await broadcastStreamComplete(conversationId, emitOptions.aiMessageId);
379
+ // Generate PDFs for any proposed documents and persist the message.
394
380
  try {
395
- const jsonData = response;
396
381
  const attachmentIds = [];
397
- // Generate PDFs if docs are provided
398
- if (jsonData.docs && Array.isArray(jsonData.docs)) {
399
- for (let i = 0; i < jsonData.docs.length; i++) {
400
- const doc = jsonData.docs[i];
382
+ // Generate PDFs if docs were proposed
383
+ if (proposals.docs.length > 0) {
384
+ for (let i = 0; i < proposals.docs.length; i++) {
385
+ const doc = proposals.docs[i];
401
386
  if (!doc.title || !doc.blocks || !Array.isArray(doc.blocks)) {
402
387
  logger.error(`Document ${i + 1} is missing title or blocks`);
403
388
  continue;
@@ -451,31 +436,29 @@ export const generateAndSendLabResponse = async (labChatId, _teacherMessage, emi
451
436
  }
452
437
  }
453
438
  }
454
- await completePendingAIMessage(emitOptions.aiMessageId, jsonData.text, {
439
+ await completePendingAIMessage(emitOptions.aiMessageId, streamedText, {
455
440
  attachments: {
456
441
  connect: attachmentIds.map(id => ({ id })),
457
442
  },
458
443
  meta: {
459
- assignmentsToCreate: jsonData.assignmentsToCreate?.map(assignment => ({
460
- ...assignment,
461
- id: v4(),
462
- })) || null,
463
- worksheetsToCreate: jsonData.worksheetsToCreate?.map(worksheet => ({
464
- ...worksheet,
465
- id: v4(),
466
- })) || null,
467
- sectionsToCreate: jsonData.sectionsToCreate?.map(section => ({
468
- ...section,
469
- id: v4(),
470
- })) || null,
444
+ assignmentsToCreate: proposals.assignments.length > 0
445
+ ? proposals.assignments.map(assignment => ({ ...assignment, id: v4() }))
446
+ : null,
447
+ worksheetsToCreate: proposals.worksheets.length > 0
448
+ ? proposals.worksheets.map(worksheet => ({ ...worksheet, id: v4() }))
449
+ : null,
450
+ sectionsToCreate: proposals.sections.length > 0
451
+ ? proposals.sections.map(section => ({ ...section, id: v4() }))
452
+ : null,
453
+ streamParts: streamParts.length > 0 ? streamParts : null,
471
454
  },
472
455
  });
473
456
  }
474
- catch (parseError) {
475
- logger.error('Failed to parse AI response or generate PDF:', { error: parseError, labChatId });
457
+ catch (persistError) {
458
+ logger.error('Failed to persist AI response or generate PDF:', { error: persistError, labChatId });
476
459
  // Fallback: complete the placeholder with the raw text so the
477
460
  // teacher still sees something useful instead of FAILED.
478
- await completePendingAIMessage(emitOptions.aiMessageId, response.text);
461
+ await completePendingAIMessage(emitOptions.aiMessageId, streamedText);
479
462
  }
480
463
  try {
481
464
  await pusher.trigger(teacherChannel(emitOptions.classId), "lab-response-completed", {
@@ -516,4 +499,4 @@ export const generateAndSendLabResponse = async (labChatId, _teacherMessage, emi
516
499
  }
517
500
  };
518
501
  //# sourceMappingURL=aiLabChat.js.map
519
- //# debugId=e57f7401-27fd-5eac-a76a-cb84f699b776
502
+ //# debugId=4bfeb1af-edc2-540a-acc7-d36c999b18a3
@@ -1 +1 @@
1
- {"version":3,"file":"aiLabChat.js","sources":["pipelines/aiLabChat.ts"],"sourceRoot":"/","sourcesContent":["/**\n * AI lab chat pipeline – generates lab introductions and responses.\n * Can create worksheets, sections, assignments, and PDF docs from AI output.\n */\nimport { isAIUser } from \"../utils/aiUser.js\";\nimport { prisma } from \"../lib/prisma.js\";\nimport { pusher, teacherChannel } from \"../lib/pusher.js\";\nimport type { Assignment, Class, File, Section, User } from \"@prisma/client\";\nimport {\n inference,\n completePendingAIMessage,\n failPendingAIMessage,\n} from \"../utils/inference.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { createPdf } from \"../lib/jsonConversion.js\";\nimport { v4 } from \"uuid\";\nimport { bucket } from \"../lib/googleCloudStorage.js\";\nimport { DocumentBlock } from \"../lib/jsonStyles.js\";\nimport { type LabChatResponse, labChatResponseSchema } from \"./aiLabChatContract.js\";\nimport { buildLabChatResponseMessages } from \"./labChatPrompt.js\";\n\n/** Cap model wait time; leave headroom after inference for PDF/GCS/DB within Vercel maxDuration (500s). */\nconst LAB_CHAT_RESPONSE_TIMEOUT_MS = 400_000;\n\nconst withTimeout = async <T>(\n task: Promise<T>,\n timeoutMs: number,\n operationName: string,\n): Promise<T> => {\n let timeoutHandle: NodeJS.Timeout | undefined;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutHandle = setTimeout(() => {\n reject(new Error(`${operationName} timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n });\n\n try {\n return await Promise.race([task, timeoutPromise]);\n } finally {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }\n};\n\n/** Extended class data for AI context (schema-aware) */\ntype ClassContextData = {\n class: Class;\n sections: Section[];\n markSchemes: { id: string; structured: string }[];\n gradingBoundaries: { id: string; structured: string }[];\n worksheets: { id: string; name: string; questionCount: number }[];\n files: File[];\n students: { id: string; username: string; profile?: { displayName: string | null } | null }[];\n teachers: { id: string; username: string; profile?: { displayName: string | null } | null }[];\n assignments: (Assignment & {\n section?: { id: string; name: string; order?: number | null } | null;\n markScheme?: { id: string } | null;\n gradingBoundary?: { id: string } | null;\n })[];\n};\n\ntype RecentLabChatMessage = {\n id: string;\n content: string;\n senderId: string;\n createdAt: Date;\n sender: {\n id: string;\n username: string | null;\n profile: {\n displayName: string | null;\n } | null;\n } | null;\n};\n\n/**\n * `messages` must be ordered newest-first.\n * When `anchorMessageId` is provided, `sliceMessagesThroughAnchor` returns the\n * anchor message and older messages only, capped to `limit`.\n */\nexport const sliceMessagesThroughAnchor = (\n messages: RecentLabChatMessage[],\n anchorMessageId?: string,\n limit = 10,\n) => {\n if (!anchorMessageId) {\n return messages.slice(0, limit);\n }\n\n const anchorIndex = messages.findIndex((message) => message.id === anchorMessageId);\n if (anchorIndex === -1) {\n return messages.slice(0, limit);\n }\n\n return messages.slice(anchorIndex, anchorIndex + limit);\n};\n\nconst loadRecentLabChatMessages = async (\n conversationId: string,\n anchorMessageId?: string,\n): Promise<RecentLabChatMessage[]> => {\n const limit = 10;\n const baseQuery = {\n conversationId,\n };\n const include = {\n sender: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n },\n },\n },\n },\n };\n\n const newestMessages = await prisma.message.findMany({\n where: baseQuery,\n include,\n orderBy: {\n createdAt: 'desc',\n },\n take: 25,\n });\n\n const anchoredMessages = sliceMessagesThroughAnchor(newestMessages, anchorMessageId, limit);\n if (!anchorMessageId || anchoredMessages.some((message) => message.id === anchorMessageId)) {\n return anchoredMessages;\n }\n\n const anchorMessage = await prisma.message.findUnique({\n where: { id: anchorMessageId },\n include,\n });\n\n if (!anchorMessage) {\n throw new Error(`Anchor message ${anchorMessageId} not found`);\n }\n\n if (anchorMessage.conversationId !== conversationId) {\n throw new Error(`Anchor message ${anchorMessageId} does not belong to conversation ${conversationId}`);\n }\n\n const olderMessages = await prisma.message.findMany({\n where: {\n conversationId,\n createdAt: {\n lte: anchorMessage.createdAt,\n },\n },\n include,\n orderBy: {\n createdAt: 'desc',\n },\n take: limit,\n });\n\n const dedupedMessages = new Map<string, RecentLabChatMessage>();\n dedupedMessages.set(anchorMessage.id, anchorMessage);\n\n olderMessages.forEach((message) => {\n if (!dedupedMessages.has(message.id)) {\n dedupedMessages.set(message.id, message);\n }\n });\n\n return Array.from(dedupedMessages.values())\n .sort((left, right) => {\n const timeDelta = right.createdAt.getTime() - left.createdAt.getTime();\n if (timeDelta !== 0) {\n return timeDelta;\n }\n if (left.id === anchorMessage.id) {\n return -1;\n }\n if (right.id === anchorMessage.id) {\n return 1;\n }\n\n return right.id.localeCompare(left.id);\n })\n .slice(0, limit);\n};\n\n/**\n * Builds schema-aware context for the AI from class data.\n * Formats entities with IDs so the model can reference them when creating assignments.\n */\nexport const buildClassContextForAI = (data: ClassContextData): string => {\n const { class: cls, sections, markSchemes, gradingBoundaries, worksheets, files, students, assignments } = data;\n\n const sectionList = sections\n .sort((a, b) => (a.order ?? 999) - (b.order ?? 999))\n .map((s) => ` - id: ${s.id} | name: \"${s.name}\" | color: ${s.color ?? \"default\"}`)\n .join(\"\\n\");\n\n const markSchemeList = markSchemes\n .map((ms) => {\n let preview = \"structured rubric\";\n try {\n const parsed = JSON.parse(ms.structured || \"{}\");\n preview = parsed.name || Object.keys(parsed).slice(0, 2).join(\", \") || \"rubric\";\n } catch {\n /* ignore */\n }\n return ` - id: ${ms.id} | ${preview}`;\n })\n .join(\"\\n\");\n\n const gradingBoundaryList = gradingBoundaries\n .map((gb) => {\n let preview = \"grading scale\";\n try {\n const parsed = JSON.parse(gb.structured || \"{}\");\n preview = parsed.name || Object.keys(parsed).slice(0, 2).join(\", \") || \"scale\";\n } catch {\n /* ignore */\n }\n return ` - id: ${gb.id} | ${preview}`;\n })\n .join(\"\\n\");\n\n const worksheetList = worksheets\n .map((w) => ` - id: ${w.id} | name: \"${w.name}\" | questions: ${w.questionCount}`)\n .join(\"\\n\");\n\n const fileList = files\n .filter((f) => f.type === \"application/pdf\" || f.type?.includes(\"document\"))\n .map((f) => ` - id: ${f.id} | name: \"${f.name}\" | type: ${f.type}`)\n .join(\"\\n\");\n const otherFiles = files.filter((f) => f.type !== \"application/pdf\" && !f.type?.includes(\"document\"));\n const otherFileList = otherFiles.length\n ? otherFiles.map((f) => ` - id: ${f.id} | name: \"${f.name}\"`).join(\"\\n\")\n : \" (none)\";\n\n const studentList = students\n .map((u) => ` - id: ${u.id} | username: ${u.username} | displayName: ${u.profile?.displayName ?? \"—\"}`)\n .join(\"\\n\");\n\n const assignmentSummary = assignments\n .map((a) => {\n const sectionName = a.section?.name ?? \"—\";\n return ` - id: ${a.id} | title: \"${a.title}\" | type: ${a.type} | section: \"${sectionName}\" | due: ${a.dueDate.toISOString().slice(0, 10)}`;\n })\n .join(\"\\n\");\n\n return `\nCLASS: ${cls.name} | Subject: ${cls.subject} | Section: ${cls.section}\nSyllabus: ${cls.syllabus ? cls.syllabus.slice(0, 200) + (cls.syllabus.length > 200 ? \"…\" : \"\") : \"(none)\"}\n\nSECTIONS (use sectionId when creating assignments):\n${sectionList || \" (none - suggest sectionsToCreate first)\"}\n\nMARK SCHEMES (use markSchemeId when creating assignments):\n${markSchemeList || \" (none - suggest creating one or omit markSchemeId)\"}\n\nGRADING BOUNDARIES (use gradingBoundaryId when creating assignments):\n${gradingBoundaryList || \" (none - suggest creating one or omit gradingBoundaryId)\"}\n\nWORKSHEETS (use worksheetIds when acceptWorksheet is true):\n${worksheetList || \" (none - use worksheetsToCreate or create via docs first)\"}\n\nFILES - PDFs/Documents (for assignment attachments):\n${fileList || \" (none)\"}\n\nFILES - Other (for assignment attachments):\n${otherFileList}\n\nSTUDENTS (use studentIds for specific assignment; empty array = all students):\n${studentList || \" (none)\"}\n\nEXISTING ASSIGNMENTS (for reference, avoid duplicates):\n${assignmentSummary || \" (none)\"}\n`.trim();\n};\n\n/**\n * @deprecated Use buildClassContextForAI for schema-aware context. Kept for compatibility.\n */\nexport const getBaseSystemPrompt = (\n context: Class,\n members: User[],\n assignments: Assignment[],\n files: File[],\n sections: Section[]\n): string => {\n return buildClassContextForAI({\n class: context,\n sections,\n markSchemes: [],\n gradingBoundaries: [],\n worksheets: [],\n files,\n students: members,\n teachers: [],\n assignments,\n });\n};\n\n\n\n/**\n * Generate labchat responses\n * Allow for the generation of the following:\n * - Assignment(s) either individual or bulk as an lesson / course plan.\n * - Worksheet(s) either individual or bulk as an lesson / course plan.\n * - Files (PDFs)\n * @param labChatId \n */\n// export const sendAiLabChatResponsePipeline = async (labChatId: string) => {\n// const message = await prisma?.message.create({\n// data: {\n// content: \"GENERATING_CONTENT\",\n// senderId: getAIUserId(),\n// conversationId: labChatId,\n// status: JobStatus.PENDING,\n// },\n// });\n\n// try {\n\n// inference(`\n// `)\n// }\n \n// };\n\n\n/**\n * Fill the AI introduction placeholder for a brand-new lab chat.\n *\n * The caller (service layer) must have already created a PENDING AI Message\n * row — `aiMessageId` is that placeholder. This function flips it to\n * COMPLETED with the intro content, or to FAILED on a hard error.\n */\nexport const generateAndSendLabIntroduction = async (\n labChatId: string,\n conversationId: string,\n _contextString: string,\n _subject: string,\n aiMessageId: string,\n ): Promise<void> => {\n const introMessage =\n \"Hello teaching team! I'm your AI assistant for course material development. I'll help you create educational content - when you have a clear request, I'll produce it directly. I only ask questions when I need to clarify the topic or scope. What would you like to work on?\";\n\n try {\n await completePendingAIMessage(aiMessageId, introMessage);\n logger.info('AI Introduction sent', { labChatId, conversationId, aiMessageId });\n } catch (error) {\n logger.error('Failed to complete AI introduction placeholder:', {\n error,\n labChatId,\n aiMessageId,\n });\n await failPendingAIMessage(aiMessageId, { reason: 'lab_intro_complete_failed' });\n }\n }\n \n /**\n * Fill the AI response placeholder for a teacher reply in a lab chat.\n *\n * `aiMessageId` is the PENDING AI Message row created by the service\n * layer; the pipeline flips it to COMPLETED with content / attachments /\n * meta, or FAILED on error. Teacher-channel `lab-response-{pending,\n * completed,failed}` events fire alongside the chat-channel status flips\n * (which `completePendingAIMessage` / `failPendingAIMessage` already\n * broadcast) so the lab list \"AI busy\" indicator stays accurate.\n *\n * `_teacherMessage` is retained for caller compatibility — the actual\n * conversation history is reloaded from the DB anchored on the AI\n * placeholder.\n */\n export const generateAndSendLabResponse = async (\n labChatId: string,\n _teacherMessage: string,\n emitOptions: { classId: string; aiMessageId: string }\n ): Promise<void> => {\n try {\n // Get lab context from database\n const fullLabChat = await prisma.labChat.findUnique({\n where: { id: labChatId },\n include: {\n class: {\n select: {\n name: true,\n subject: true,\n },\n },\n },\n });\n \n if (!fullLabChat) {\n throw new Error('Lab chat not found');\n }\n \n const conversationId = fullLabChat.conversationId;\n \n // Anchor history on the AI placeholder — the slice will include the\n // placeholder itself (empty content) at the top; drop it so the model\n // does not see an empty assistant turn at the very end.\n const anchoredMessages = await loadRecentLabChatMessages(\n conversationId,\n emitOptions.aiMessageId,\n );\n const recentMessages = anchoredMessages.filter(\n (msg) => msg.id !== emitOptions.aiMessageId,\n );\n \n const classData = await prisma.class.findUnique({\n where: {\n id: fullLabChat.classId,\n },\n include: {\n assignments: {\n include: {\n section: { select: { id: true, name: true, order: true } },\n markScheme: { select: { id: true } },\n gradingBoundary: { select: { id: true } },\n },\n },\n sections: true,\n markSchemes: { select: { id: true, structured: true } },\n gradingBoundaries: { select: { id: true, structured: true } },\n worksheets: {\n select: {\n id: true,\n name: true,\n _count: { select: { questions: true } },\n },\n },\n students: {\n select: {\n id: true,\n username: true,\n profile: { select: { displayName: true } },\n },\n },\n teachers: {\n select: {\n id: true,\n username: true,\n profile: { select: { displayName: true } },\n },\n },\n classFiles: {\n include: {\n files: true,\n },\n },\n },\n });\n\n if (!classData) {\n throw new Error('Class not found');\n }\n\n const classContext = buildClassContextForAI({\n class: classData,\n sections: classData.sections,\n markSchemes: classData.markSchemes,\n gradingBoundaries: classData.gradingBoundaries,\n worksheets: classData.worksheets.map((w) => ({\n id: w.id,\n name: w.name,\n questionCount: w._count.questions,\n })),\n files: classData.classFiles?.files ?? [],\n students: classData.students,\n teachers: classData.teachers,\n assignments: classData.assignments,\n });\n\n const messages = buildLabChatResponseMessages({\n context: fullLabChat.context,\n classContext,\n recentMessages: recentMessages.reverse(),\n isAIUser,\n });\n \n \n // const completion = await inferenceClient.chat.completions.create({\n // model: 'command-a-03-2025',\n // messages,\n // temperature: 0.7,\n // response_format: zodTextFormat(labChatResponseSchema, \"lab_chat_response_format\"),\n // });\n\n const response = await withTimeout(\n inference<LabChatResponse>(messages, labChatResponseSchema, {\n reason: 'lab_chat_response',\n metadata: {\n labChatId,\n conversationId,\n classId: fullLabChat.classId,\n aiMessageId: emitOptions.aiMessageId,\n },\n }),\n LAB_CHAT_RESPONSE_TIMEOUT_MS,\n \"Lab chat response generation\",\n );\n \n if (!response) {\n throw new Error('No response generated from inference API');\n }\n // Parse the JSON response and generate PDF if docs are provided\n try {\n const jsonData = response;\n \n \n const attachmentIds: string[] = [];\n // Generate PDFs if docs are provided\n if (jsonData.docs && Array.isArray(jsonData.docs)) {\n \n \n for (let i = 0; i < jsonData.docs.length; i++) {\n const doc = jsonData.docs[i];\n if (!doc.title || !doc.blocks || !Array.isArray(doc.blocks)) {\n logger.error(`Document ${i + 1} is missing title or blocks`);\n continue;\n } \n \n \n try {\n let pdfBytes = await createPdf(doc.blocks as DocumentBlock[]); \n if (pdfBytes) {\n // Sanitize filename - remove special characters and limit length\n const sanitizedTitle = doc.title\n .replace(/[^a-zA-Z0-9\\s\\-_]/g, '')\n .replace(/\\s+/g, '_')\n .substring(0, 50);\n \n const filename = `${sanitizedTitle}_${v4().substring(0, 8)}.pdf`;\n const filePath = `class/generated/${fullLabChat.classId}/${filename}`;\n \n logger.info(`PDF ${i + 1} generated successfully`, { labChatId, title: doc.title });\n \n // Upload directly to Google Cloud Storage\n const gcsFile = bucket.file(filePath);\n await gcsFile.save(Buffer.from(pdfBytes), {\n metadata: {\n contentType: 'application/pdf',\n }\n });\n \n logger.info(`PDF ${i + 1} uploaded successfully`, { labChatId, filename });\n \n const file = await prisma.file.create({\n data: {\n name: filename,\n path: filePath,\n type: 'application/pdf',\n size: pdfBytes.length,\n userId: fullLabChat.createdById,\n uploadStatus: 'COMPLETED',\n uploadedAt: new Date(),\n },\n });\n attachmentIds.push(file.id);\n } else {\n logger.error(`PDF ${i + 1} creation returned undefined/null`, { labChatId, title: doc.title });\n }\n } catch (pdfError) {\n logger.error(`PDF creation threw an error for document ${i + 1}:`, { \n error: pdfError instanceof Error ? {\n message: pdfError.message,\n stack: pdfError.stack,\n name: pdfError.name\n } : pdfError, \n labChatId,\n title: doc.title\n });\n }\n }\n }\n \n await completePendingAIMessage(emitOptions.aiMessageId, jsonData.text, {\n attachments: {\n connect: attachmentIds.map(id => ({ id })),\n },\n meta: {\n assignmentsToCreate: jsonData.assignmentsToCreate?.map(assignment => ({\n ...assignment,\n id: v4(),\n })) || null,\n worksheetsToCreate: jsonData.worksheetsToCreate?.map(worksheet => ({\n ...worksheet,\n id: v4(),\n })) || null,\n sectionsToCreate: jsonData.sectionsToCreate?.map(section => ({\n ...section,\n id: v4(),\n })) || null,\n },\n });\n } catch (parseError) {\n logger.error('Failed to parse AI response or generate PDF:', { error: parseError, labChatId });\n // Fallback: complete the placeholder with the raw text so the\n // teacher still sees something useful instead of FAILED.\n await completePendingAIMessage(emitOptions.aiMessageId, response.text);\n }\n\n try {\n await pusher.trigger(teacherChannel(emitOptions.classId), \"lab-response-completed\", {\n labChatId,\n messageId: emitOptions.aiMessageId,\n });\n } catch (broadcastError) {\n logger.error(\"Failed to broadcast lab response completed:\", { error: broadcastError });\n }\n\n logger.info('AI response sent', { labChatId, conversationId, aiMessageId: emitOptions.aiMessageId });\n\n } catch (error) {\n console.error('Full error object:', error);\n logger.error('Failed to generate AI response:', {\n error: error instanceof Error ? {\n message: error.message,\n stack: error.stack,\n name: error.name\n } : error,\n labChatId,\n aiMessageId: emitOptions.aiMessageId,\n });\n\n await failPendingAIMessage(emitOptions.aiMessageId, {\n reason: 'lab_response_generation_failed',\n });\n\n try {\n await pusher.trigger(teacherChannel(emitOptions.classId), \"lab-response-failed\", {\n labChatId,\n messageId: emitOptions.aiMessageId,\n error: \"AI response generation failed\",\n });\n } catch (broadcastError) {\n logger.error(\"Failed to broadcast lab response failed:\", { error: broadcastError });\n }\n\n throw error; // Re-throw to see the full error in the calling function\n }\n }\n"],"names":[],"mappings":"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","debug_id":"e57f7401-27fd-5eac-a76a-cb84f699b776"}
1
+ {"version":3,"file":"aiLabChat.js","sources":["pipelines/aiLabChat.ts"],"sourceRoot":"/","sourcesContent":["/**\n * AI lab chat pipeline – generates lab introductions and responses.\n * Can create worksheets, sections, assignments, and PDF docs from AI output.\n */\nimport { isAIUser } from \"../utils/aiUser.js\";\nimport { prisma } from \"../lib/prisma.js\";\nimport { pusher, teacherChannel } from \"../lib/pusher.js\";\nimport type { Assignment, Class, File, Section, User } from \"@prisma/client\";\nimport {\n completePendingAIMessage,\n failPendingAIMessage,\n} from \"../utils/inference.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { createPdf } from \"../lib/jsonConversion.js\";\nimport { v4 } from \"uuid\";\nimport { bucket } from \"../lib/googleCloudStorage.js\";\nimport { DocumentBlock } from \"../lib/jsonStyles.js\";\nimport { broadcastTextChunks, broadcastStreamComplete } from \"../utils/streamBroadcast.js\";\nimport { buildLabChatAgentMessages } from \"./labChatPrompt.js\";\nimport { streamChatResponse } from \"../services/aiChatStream.js\";\nimport { aiTools } from \"../services/aiTools.js\";\nimport { labProposalTools, createLabProposals } from \"../services/aiProposalTools.js\";\n\n/** Cap model wait time; leave headroom after inference for PDF/GCS/DB within Vercel maxDuration (500s). */\nconst LAB_CHAT_RESPONSE_TIMEOUT_MS = 400_000;\n\nconst withTimeout = async <T>(\n task: Promise<T>,\n timeoutMs: number,\n operationName: string,\n): Promise<T> => {\n let timeoutHandle: NodeJS.Timeout | undefined;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutHandle = setTimeout(() => {\n reject(new Error(`${operationName} timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n });\n\n try {\n return await Promise.race([task, timeoutPromise]);\n } finally {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }\n};\n\n/** Extended class data for AI context (schema-aware) */\ntype ClassContextData = {\n class: Class;\n sections: Section[];\n markSchemes: { id: string; structured: string }[];\n gradingBoundaries: { id: string; structured: string }[];\n worksheets: { id: string; name: string; questionCount: number }[];\n files: File[];\n students: { id: string; username: string; profile?: { displayName: string | null } | null }[];\n teachers: { id: string; username: string; profile?: { displayName: string | null } | null }[];\n assignments: (Assignment & {\n section?: { id: string; name: string; order?: number | null } | null;\n markScheme?: { id: string } | null;\n gradingBoundary?: { id: string } | null;\n })[];\n};\n\ntype RecentLabChatMessage = {\n id: string;\n content: string;\n senderId: string;\n createdAt: Date;\n sender: {\n id: string;\n username: string | null;\n profile: {\n displayName: string | null;\n } | null;\n } | null;\n};\n\n/**\n * `messages` must be ordered newest-first.\n * When `anchorMessageId` is provided, `sliceMessagesThroughAnchor` returns the\n * anchor message and older messages only, capped to `limit`.\n */\nexport const sliceMessagesThroughAnchor = (\n messages: RecentLabChatMessage[],\n anchorMessageId?: string,\n limit = 10,\n) => {\n if (!anchorMessageId) {\n return messages.slice(0, limit);\n }\n\n const anchorIndex = messages.findIndex((message) => message.id === anchorMessageId);\n if (anchorIndex === -1) {\n return messages.slice(0, limit);\n }\n\n return messages.slice(anchorIndex, anchorIndex + limit);\n};\n\nconst loadRecentLabChatMessages = async (\n conversationId: string,\n anchorMessageId?: string,\n): Promise<RecentLabChatMessage[]> => {\n const limit = 10;\n const baseQuery = {\n conversationId,\n };\n const include = {\n sender: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n },\n },\n },\n },\n };\n\n const newestMessages = await prisma.message.findMany({\n where: baseQuery,\n include,\n orderBy: {\n createdAt: 'desc',\n },\n take: 25,\n });\n\n const anchoredMessages = sliceMessagesThroughAnchor(newestMessages, anchorMessageId, limit);\n if (!anchorMessageId || anchoredMessages.some((message) => message.id === anchorMessageId)) {\n return anchoredMessages;\n }\n\n const anchorMessage = await prisma.message.findUnique({\n where: { id: anchorMessageId },\n include,\n });\n\n if (!anchorMessage) {\n throw new Error(`Anchor message ${anchorMessageId} not found`);\n }\n\n if (anchorMessage.conversationId !== conversationId) {\n throw new Error(`Anchor message ${anchorMessageId} does not belong to conversation ${conversationId}`);\n }\n\n const olderMessages = await prisma.message.findMany({\n where: {\n conversationId,\n createdAt: {\n lte: anchorMessage.createdAt,\n },\n },\n include,\n orderBy: {\n createdAt: 'desc',\n },\n take: limit,\n });\n\n const dedupedMessages = new Map<string, RecentLabChatMessage>();\n dedupedMessages.set(anchorMessage.id, anchorMessage);\n\n olderMessages.forEach((message) => {\n if (!dedupedMessages.has(message.id)) {\n dedupedMessages.set(message.id, message);\n }\n });\n\n return Array.from(dedupedMessages.values())\n .sort((left, right) => {\n const timeDelta = right.createdAt.getTime() - left.createdAt.getTime();\n if (timeDelta !== 0) {\n return timeDelta;\n }\n if (left.id === anchorMessage.id) {\n return -1;\n }\n if (right.id === anchorMessage.id) {\n return 1;\n }\n\n return right.id.localeCompare(left.id);\n })\n .slice(0, limit);\n};\n\n/**\n * Builds schema-aware context for the AI from class data.\n * Formats entities with IDs so the model can reference them when creating assignments.\n */\nexport const buildClassContextForAI = (data: ClassContextData): string => {\n const { class: cls, sections, markSchemes, gradingBoundaries, worksheets, files, students, assignments } = data;\n\n const sectionList = sections\n .sort((a, b) => (a.order ?? 999) - (b.order ?? 999))\n .map((s) => ` - id: ${s.id} | name: \"${s.name}\" | color: ${s.color ?? \"default\"}`)\n .join(\"\\n\");\n\n const markSchemeList = markSchemes\n .map((ms) => {\n let preview = \"structured rubric\";\n try {\n const parsed = JSON.parse(ms.structured || \"{}\");\n preview = parsed.name || Object.keys(parsed).slice(0, 2).join(\", \") || \"rubric\";\n } catch {\n /* ignore */\n }\n return ` - id: ${ms.id} | ${preview}`;\n })\n .join(\"\\n\");\n\n const gradingBoundaryList = gradingBoundaries\n .map((gb) => {\n let preview = \"grading scale\";\n try {\n const parsed = JSON.parse(gb.structured || \"{}\");\n preview = parsed.name || Object.keys(parsed).slice(0, 2).join(\", \") || \"scale\";\n } catch {\n /* ignore */\n }\n return ` - id: ${gb.id} | ${preview}`;\n })\n .join(\"\\n\");\n\n const worksheetList = worksheets\n .map((w) => ` - id: ${w.id} | name: \"${w.name}\" | questions: ${w.questionCount}`)\n .join(\"\\n\");\n\n const fileList = files\n .filter((f) => f.type === \"application/pdf\" || f.type?.includes(\"document\"))\n .map((f) => ` - id: ${f.id} | name: \"${f.name}\" | type: ${f.type}`)\n .join(\"\\n\");\n const otherFiles = files.filter((f) => f.type !== \"application/pdf\" && !f.type?.includes(\"document\"));\n const otherFileList = otherFiles.length\n ? otherFiles.map((f) => ` - id: ${f.id} | name: \"${f.name}\"`).join(\"\\n\")\n : \" (none)\";\n\n const studentList = students\n .map((u) => ` - id: ${u.id} | username: ${u.username} | displayName: ${u.profile?.displayName ?? \"—\"}`)\n .join(\"\\n\");\n\n const assignmentSummary = assignments\n .map((a) => {\n const sectionName = a.section?.name ?? \"—\";\n return ` - id: ${a.id} | title: \"${a.title}\" | type: ${a.type} | section: \"${sectionName}\" | due: ${a.dueDate.toISOString().slice(0, 10)}`;\n })\n .join(\"\\n\");\n\n return `\nCLASS: ${cls.name} | Subject: ${cls.subject} | Section: ${cls.section}\nSyllabus: ${cls.syllabus ? cls.syllabus.slice(0, 200) + (cls.syllabus.length > 200 ? \"…\" : \"\") : \"(none)\"}\n\nSECTIONS (use sectionId when creating assignments):\n${sectionList || \" (none - suggest sectionsToCreate first)\"}\n\nMARK SCHEMES (use markSchemeId when creating assignments):\n${markSchemeList || \" (none - suggest creating one or omit markSchemeId)\"}\n\nGRADING BOUNDARIES (use gradingBoundaryId when creating assignments):\n${gradingBoundaryList || \" (none - suggest creating one or omit gradingBoundaryId)\"}\n\nWORKSHEETS (use worksheetIds when acceptWorksheet is true):\n${worksheetList || \" (none - use worksheetsToCreate or create via docs first)\"}\n\nFILES - PDFs/Documents (for assignment attachments):\n${fileList || \" (none)\"}\n\nFILES - Other (for assignment attachments):\n${otherFileList}\n\nSTUDENTS (use studentIds for specific assignment; empty array = all students):\n${studentList || \" (none)\"}\n\nEXISTING ASSIGNMENTS (for reference, avoid duplicates):\n${assignmentSummary || \" (none)\"}\n`.trim();\n};\n\n/**\n * @deprecated Use buildClassContextForAI for schema-aware context. Kept for compatibility.\n */\nexport const getBaseSystemPrompt = (\n context: Class,\n members: User[],\n assignments: Assignment[],\n files: File[],\n sections: Section[]\n): string => {\n return buildClassContextForAI({\n class: context,\n sections,\n markSchemes: [],\n gradingBoundaries: [],\n worksheets: [],\n files,\n students: members,\n teachers: [],\n assignments,\n });\n};\n\n\n\n/**\n * Fill the AI introduction placeholder for a brand-new lab chat.\n *\n * The caller (service layer) must have already created a PENDING AI Message\n * row — `aiMessageId` is that placeholder. This function flips it to\n * COMPLETED with the intro content, or to FAILED on a hard error.\n */\nexport const generateAndSendLabIntroduction = async (\n labChatId: string,\n conversationId: string,\n _contextString: string,\n _subject: string,\n aiMessageId: string,\n ): Promise<void> => {\n const introMessage =\n \"Hello teaching team! I'm your AI assistant for course material development. I'll help you create educational content - when you have a clear request, I'll produce it directly. I only ask questions when I need to clarify the topic or scope. What would you like to work on?\";\n\n try {\n await broadcastTextChunks(conversationId, aiMessageId, introMessage);\n await completePendingAIMessage(aiMessageId, introMessage);\n logger.info('AI Introduction sent', { labChatId, conversationId, aiMessageId });\n } catch (error) {\n logger.error('Failed to complete AI introduction placeholder:', {\n error,\n labChatId,\n aiMessageId,\n });\n await failPendingAIMessage(aiMessageId, { reason: 'lab_intro_complete_failed' });\n }\n }\n \n /**\n * Fill the AI response placeholder for a teacher reply in a lab chat.\n *\n * `aiMessageId` is the PENDING AI Message row created by the service\n * layer; the pipeline flips it to COMPLETED with content / attachments /\n * meta, or FAILED on error. Teacher-channel `lab-response-{pending,\n * completed,failed}` events fire alongside the chat-channel status flips\n * (which `completePendingAIMessage` / `failPendingAIMessage` already\n * broadcast) so the lab list \"AI busy\" indicator stays accurate.\n *\n * `_teacherMessage` is retained for caller compatibility — the actual\n * conversation history is reloaded from the DB anchored on the AI\n * placeholder.\n */\n export const generateAndSendLabResponse = async (\n labChatId: string,\n _teacherMessage: string,\n emitOptions: { classId: string; aiMessageId: string }\n ): Promise<void> => {\n try {\n // Get lab context from database\n const fullLabChat = await prisma.labChat.findUnique({\n where: { id: labChatId },\n include: {\n class: {\n select: {\n name: true,\n subject: true,\n },\n },\n },\n });\n \n if (!fullLabChat) {\n throw new Error('Lab chat not found');\n }\n \n const conversationId = fullLabChat.conversationId;\n \n // Anchor history on the AI placeholder — the slice will include the\n // placeholder itself (empty content) at the top; drop it so the model\n // does not see an empty assistant turn at the very end.\n const anchoredMessages = await loadRecentLabChatMessages(\n conversationId,\n emitOptions.aiMessageId,\n );\n const recentMessages = anchoredMessages.filter(\n (msg) => msg.id !== emitOptions.aiMessageId,\n );\n \n const classData = await prisma.class.findUnique({\n where: {\n id: fullLabChat.classId,\n },\n include: {\n assignments: {\n include: {\n section: { select: { id: true, name: true, order: true } },\n markScheme: { select: { id: true } },\n gradingBoundary: { select: { id: true } },\n },\n },\n sections: true,\n markSchemes: { select: { id: true, structured: true } },\n gradingBoundaries: { select: { id: true, structured: true } },\n worksheets: {\n select: {\n id: true,\n name: true,\n _count: { select: { questions: true } },\n },\n },\n students: {\n select: {\n id: true,\n username: true,\n profile: { select: { displayName: true } },\n },\n },\n teachers: {\n select: {\n id: true,\n username: true,\n profile: { select: { displayName: true } },\n },\n },\n classFiles: {\n include: {\n files: true,\n },\n },\n },\n });\n\n if (!classData) {\n throw new Error('Class not found');\n }\n\n const classContext = buildClassContextForAI({\n class: classData,\n sections: classData.sections,\n markSchemes: classData.markSchemes,\n gradingBoundaries: classData.gradingBoundaries,\n worksheets: classData.worksheets.map((w) => ({\n id: w.id,\n name: w.name,\n questionCount: w._count.questions,\n })),\n files: classData.classFiles?.files ?? [],\n students: classData.students,\n teachers: classData.teachers,\n assignments: classData.assignments,\n });\n\n const { system, messages } = buildLabChatAgentMessages({\n context: fullLabChat.context,\n classContext,\n recentMessages: recentMessages.reverse(),\n isAIUser,\n });\n\n // Genuine agentic generation: the model streams prose token-by-token and\n // calls real tools inline — read-only RAG lookups plus \"propose_*\" tools\n // that record create-actions into `proposals`. `streamChatResponse`\n // broadcasts the real text chunks and tool-call events as they happen.\n const proposals = createLabProposals();\n const tools = {\n ...aiTools(fullLabChat.classId),\n ...labProposalTools(proposals),\n };\n\n const { text: streamedText, parts: streamParts } = await withTimeout(\n streamChatResponse({\n conversationId,\n aiMessageId: emitOptions.aiMessageId,\n system,\n messages,\n tools,\n temperature: 0.7,\n maxOutputTokens: 4096,\n maxSteps: 8,\n }),\n LAB_CHAT_RESPONSE_TIMEOUT_MS,\n \"Lab chat response generation\",\n );\n\n // Real text + tool-call events were already broadcast inline (in order)\n // during the stream by `streamChatResponse`. Just close the stream.\n await broadcastStreamComplete(conversationId, emitOptions.aiMessageId);\n\n // Generate PDFs for any proposed documents and persist the message.\n try {\n const attachmentIds: string[] = [];\n // Generate PDFs if docs were proposed\n if (proposals.docs.length > 0) {\n \n \n for (let i = 0; i < proposals.docs.length; i++) {\n const doc = proposals.docs[i];\n if (!doc.title || !doc.blocks || !Array.isArray(doc.blocks)) {\n logger.error(`Document ${i + 1} is missing title or blocks`);\n continue;\n } \n \n \n try {\n let pdfBytes = await createPdf(doc.blocks as DocumentBlock[]); \n if (pdfBytes) {\n // Sanitize filename - remove special characters and limit length\n const sanitizedTitle = doc.title\n .replace(/[^a-zA-Z0-9\\s\\-_]/g, '')\n .replace(/\\s+/g, '_')\n .substring(0, 50);\n \n const filename = `${sanitizedTitle}_${v4().substring(0, 8)}.pdf`;\n const filePath = `class/generated/${fullLabChat.classId}/${filename}`;\n \n logger.info(`PDF ${i + 1} generated successfully`, { labChatId, title: doc.title });\n \n // Upload directly to Google Cloud Storage\n const gcsFile = bucket.file(filePath);\n await gcsFile.save(Buffer.from(pdfBytes), {\n metadata: {\n contentType: 'application/pdf',\n }\n });\n \n logger.info(`PDF ${i + 1} uploaded successfully`, { labChatId, filename });\n \n const file = await prisma.file.create({\n data: {\n name: filename,\n path: filePath,\n type: 'application/pdf',\n size: pdfBytes.length,\n userId: fullLabChat.createdById,\n uploadStatus: 'COMPLETED',\n uploadedAt: new Date(),\n },\n });\n attachmentIds.push(file.id);\n } else {\n logger.error(`PDF ${i + 1} creation returned undefined/null`, { labChatId, title: doc.title });\n }\n } catch (pdfError) {\n logger.error(`PDF creation threw an error for document ${i + 1}:`, { \n error: pdfError instanceof Error ? {\n message: pdfError.message,\n stack: pdfError.stack,\n name: pdfError.name\n } : pdfError, \n labChatId,\n title: doc.title\n });\n }\n }\n }\n \n await completePendingAIMessage(emitOptions.aiMessageId, streamedText, {\n attachments: {\n connect: attachmentIds.map(id => ({ id })),\n },\n meta: {\n assignmentsToCreate: proposals.assignments.length > 0\n ? proposals.assignments.map(assignment => ({ ...assignment, id: v4() }))\n : null,\n worksheetsToCreate: proposals.worksheets.length > 0\n ? proposals.worksheets.map(worksheet => ({ ...worksheet, id: v4() }))\n : null,\n sectionsToCreate: proposals.sections.length > 0\n ? proposals.sections.map(section => ({ ...section, id: v4() }))\n : null,\n streamParts: streamParts.length > 0 ? streamParts : null,\n },\n });\n } catch (persistError) {\n logger.error('Failed to persist AI response or generate PDF:', { error: persistError, labChatId });\n // Fallback: complete the placeholder with the raw text so the\n // teacher still sees something useful instead of FAILED.\n await completePendingAIMessage(emitOptions.aiMessageId, streamedText);\n }\n\n try {\n await pusher.trigger(teacherChannel(emitOptions.classId), \"lab-response-completed\", {\n labChatId,\n messageId: emitOptions.aiMessageId,\n });\n } catch (broadcastError) {\n logger.error(\"Failed to broadcast lab response completed:\", { error: broadcastError });\n }\n\n logger.info('AI response sent', { labChatId, conversationId, aiMessageId: emitOptions.aiMessageId });\n\n } catch (error) {\n console.error('Full error object:', error);\n logger.error('Failed to generate AI response:', {\n error: error instanceof Error ? {\n message: error.message,\n stack: error.stack,\n name: error.name\n } : error,\n labChatId,\n aiMessageId: emitOptions.aiMessageId,\n });\n\n await failPendingAIMessage(emitOptions.aiMessageId, {\n reason: 'lab_response_generation_failed',\n });\n\n try {\n await pusher.trigger(teacherChannel(emitOptions.classId), \"lab-response-failed\", {\n labChatId,\n messageId: emitOptions.aiMessageId,\n error: \"AI response generation failed\",\n });\n } catch (broadcastError) {\n logger.error(\"Failed to broadcast lab response failed:\", { error: broadcastError });\n }\n\n throw error; // Re-throw to see the full error in the calling function\n }\n }\n"],"names":[],"mappings":"AAAA;;;GAGG;;;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,EACL,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAEtD,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAC3F,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEtF,2GAA2G;AAC3G,MAAM,4BAA4B,GAAG,MAAO,CAAC;AAE7C,MAAM,WAAW,GAAG,KAAK,EACvB,IAAgB,EAChB,SAAiB,EACjB,aAAqB,EACT,EAAE;IACd,IAAI,aAAyC,CAAC;IAC9C,MAAM,cAAc,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QACtD,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,aAAa,oBAAoB,SAAS,IAAI,CAAC,CAAC,CAAC;QACvE,CAAC,EAAE,SAAS,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;IACpD,CAAC;YAAS,CAAC;QACT,IAAI,aAAa,EAAE,CAAC;YAClB,YAAY,CAAC,aAAa,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAiCF;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CACxC,QAAgC,EAChC,eAAwB,EACxB,KAAK,GAAG,EAAE,EACV,EAAE;IACF,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,eAAe,CAAC,CAAC;IACpF,IAAI,WAAW,KAAK,CAAC,CAAC,EAAE,CAAC;QACvB,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,WAAW,GAAG,KAAK,CAAC,CAAC;AAC1D,CAAC,CAAC;AAEF,MAAM,yBAAyB,GAAG,KAAK,EACrC,cAAsB,EACtB,eAAwB,EACS,EAAE;IACnC,MAAM,KAAK,GAAG,EAAE,CAAC;IACjB,MAAM,SAAS,GAAG;QAChB,cAAc;KACf,CAAC;IACF,MAAM,OAAO,GAAG;QACd,MAAM,EAAE;YACN,MAAM,EAAE;gBACN,EAAE,EAAE,IAAI;gBACR,QAAQ,EAAE,IAAI;gBACd,OAAO,EAAE;oBACP,MAAM,EAAE;wBACN,WAAW,EAAE,IAAI;qBAClB;iBACF;aACF;SACF;KACF,CAAC;IAEF,MAAM,cAAc,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;QACnD,KAAK,EAAE,SAAS;QAChB,OAAO;QACP,OAAO,EAAE;YACP,SAAS,EAAE,MAAM;SAClB;QACD,IAAI,EAAE,EAAE;KACT,CAAC,CAAC;IAEH,MAAM,gBAAgB,GAAG,0BAA0B,CAAC,cAAc,EAAE,eAAe,EAAE,KAAK,CAAC,CAAC;IAC5F,IAAI,CAAC,eAAe,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,eAAe,CAAC,EAAE,CAAC;QAC3F,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;QACpD,KAAK,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE;QAC9B,OAAO;KACR,CAAC,CAAC;IAEH,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,kBAAkB,eAAe,YAAY,CAAC,CAAC;IACjE,CAAC;IAED,IAAI,aAAa,CAAC,cAAc,KAAK,cAAc,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,kBAAkB,eAAe,oCAAoC,cAAc,EAAE,CAAC,CAAC;IACzG,CAAC;IAED,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;QAClD,KAAK,EAAE;YACL,cAAc;YACd,SAAS,EAAE;gBACT,GAAG,EAAE,aAAa,CAAC,SAAS;aAC7B;SACF;QACD,OAAO;QACP,OAAO,EAAE;YACP,SAAS,EAAE,MAAM;SAClB;QACD,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;IAEH,MAAM,eAAe,GAAG,IAAI,GAAG,EAAgC,CAAC;IAChE,eAAe,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;IAErD,aAAa,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAChC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;YACrC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC;SACxC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QACpB,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QACvE,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;YACpB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,IAAI,IAAI,CAAC,EAAE,KAAK,aAAa,CAAC,EAAE,EAAE,CAAC;YACjC,OAAO,CAAC,CAAC,CAAC;QACZ,CAAC;QACD,IAAI,KAAK,CAAC,EAAE,KAAK,aAAa,CAAC,EAAE,EAAE,CAAC;YAClC,OAAO,CAAC,CAAC;QACX,CAAC;QAED,OAAO,KAAK,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzC,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AACrB,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,IAAsB,EAAU,EAAE;IACvE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE,iBAAiB,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IAEhH,MAAM,WAAW,GAAG,QAAQ;SACzB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC;SACnD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,KAAK,IAAI,SAAS,EAAE,CAAC;SAClF,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,cAAc,GAAG,WAAW;SAC/B,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;QACV,IAAI,OAAO,GAAG,mBAAmB,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,IAAI,IAAI,CAAC,CAAC;YACjD,OAAO,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC;QAClF,CAAC;QAAC,MAAM,CAAC;YACP,YAAY;QACd,CAAC;QACD,OAAO,WAAW,EAAE,CAAC,EAAE,MAAM,OAAO,EAAE,CAAC;IACzC,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,mBAAmB,GAAG,iBAAiB;SAC1C,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;QACV,IAAI,OAAO,GAAG,eAAe,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,IAAI,IAAI,CAAC,CAAC;YACjD,OAAO,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC;QACjF,CAAC;QAAC,MAAM,CAAC;YACP,YAAY;QACd,CAAC;QACD,OAAO,WAAW,EAAE,CAAC,EAAE,MAAM,OAAO,EAAE,CAAC;IACzC,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,aAAa,GAAG,UAAU;SAC7B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,IAAI,kBAAkB,CAAC,CAAC,aAAa,EAAE,CAAC;SACjF,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,QAAQ,GAAG,KAAK;SACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,iBAAiB,IAAI,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;SAC3E,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,IAAI,EAAE,CAAC;SACnE,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,iBAAiB,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;IACtG,MAAM,aAAa,GAAG,UAAU,CAAC,MAAM;QACrC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACzE,CAAC,CAAC,UAAU,CAAC;IAEf,MAAM,WAAW,GAAG,QAAQ;SACzB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,QAAQ,mBAAmB,CAAC,CAAC,OAAO,EAAE,WAAW,IAAI,GAAG,EAAE,CAAC;SACvG,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,iBAAiB,GAAG,WAAW;SAClC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,WAAW,GAAG,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,GAAG,CAAC;QAC3C,OAAO,WAAW,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,KAAK,aAAa,CAAC,CAAC,IAAI,gBAAgB,WAAW,YAAY,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;IAC9I,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO;SACA,GAAG,CAAC,IAAI,eAAe,GAAG,CAAC,OAAO,eAAe,GAAG,CAAC,OAAO;YACzD,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ;;;EAGvG,WAAW,IAAI,2CAA2C;;;EAG1D,cAAc,IAAI,sDAAsD;;;EAGxE,mBAAmB,IAAI,2DAA2D;;;EAGlF,aAAa,IAAI,4DAA4D;;;EAG7E,QAAQ,IAAI,UAAU;;;EAGtB,aAAa;;;EAGb,WAAW,IAAI,UAAU;;;EAGzB,iBAAiB,IAAI,UAAU;CAChC,CAAC,IAAI,EAAE,CAAC;AACT,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,OAAc,EACd,OAAe,EACf,WAAyB,EACzB,KAAa,EACb,QAAmB,EACX,EAAE;IACV,OAAO,sBAAsB,CAAC;QAC5B,KAAK,EAAE,OAAO;QACd,QAAQ;QACR,WAAW,EAAE,EAAE;QACf,iBAAiB,EAAE,EAAE;QACrB,UAAU,EAAE,EAAE;QACd,KAAK;QACL,QAAQ,EAAE,OAAO;QACjB,QAAQ,EAAE,EAAE;QACZ,WAAW;KACZ,CAAC,CAAC;AACL,CAAC,CAAC;AAIF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,KAAK,EAC/C,SAAiB,EACjB,cAAsB,EACtB,cAAsB,EACtB,QAAgB,EAChB,WAAmB,EACJ,EAAE;IACjB,MAAM,YAAY,GAChB,iRAAiR,CAAC;IAEpR,IAAI,CAAC;QACH,MAAM,mBAAmB,CAAC,cAAc,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;QACrE,MAAM,wBAAwB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QAC1D,MAAM,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;IAClF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,iDAAiD,EAAE;YAC9D,KAAK;YACL,SAAS;YACT,WAAW;SACZ,CAAC,CAAC;QACH,MAAM,oBAAoB,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,2BAA2B,EAAE,CAAC,CAAC;IACnF,CAAC;AACH,CAAC,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,KAAK,EAC7C,SAAiB,EACjB,eAAuB,EACvB,WAAqD,EACtC,EAAE;IACjB,IAAI,CAAC;QACH,gCAAgC;QAChC,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;YAClD,KAAK,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE;YACxB,OAAO,EAAE;gBACP,KAAK,EAAE;oBACL,MAAM,EAAE;wBACN,IAAI,EAAE,IAAI;wBACV,OAAO,EAAE,IAAI;qBACd;iBACF;aACF;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACxC,CAAC;QAED,MAAM,cAAc,GAAG,WAAW,CAAC,cAAc,CAAC;QAElD,oEAAoE;QACpE,sEAAsE;QACtE,wDAAwD;QACxD,MAAM,gBAAgB,GAAG,MAAM,yBAAyB,CACtD,cAAc,EACd,WAAW,CAAC,WAAW,CACxB,CAAC;QACF,MAAM,cAAc,GAAG,gBAAgB,CAAC,MAAM,CAC5C,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,WAAW,CAAC,WAAW,CAC5C,CAAC;QAEF,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC;YAC9C,KAAK,EAAE;gBACL,EAAE,EAAE,WAAW,CAAC,OAAO;aACxB;YACD,OAAO,EAAE;gBACP,WAAW,EAAE;oBACX,OAAO,EAAE;wBACP,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;wBAC1D,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE;wBACpC,eAAe,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE;qBAC1C;iBACF;gBACD,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE;gBACvD,iBAAiB,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE;gBAC7D,UAAU,EAAE;oBACV,MAAM,EAAE;wBACN,EAAE,EAAE,IAAI;wBACR,IAAI,EAAE,IAAI;wBACV,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE;qBACxC;iBACF;gBACD,QAAQ,EAAE;oBACR,MAAM,EAAE;wBACN,EAAE,EAAE,IAAI;wBACR,QAAQ,EAAE,IAAI;wBACd,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE;qBAC3C;iBACF;gBACD,QAAQ,EAAE;oBACR,MAAM,EAAE;wBACN,EAAE,EAAE,IAAI;wBACR,QAAQ,EAAE,IAAI;wBACd,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE;qBAC3C;iBACF;gBACD,UAAU,EAAE;oBACV,OAAO,EAAE;wBACP,KAAK,EAAE,IAAI;qBACZ;iBACF;aACF;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACrC,CAAC;QAED,MAAM,YAAY,GAAG,sBAAsB,CAAC;YAC1C,KAAK,EAAE,SAAS;YAChB,QAAQ,EAAE,SAAS,CAAC,QAAQ;YAC5B,WAAW,EAAE,SAAS,CAAC,WAAW;YAClC,iBAAiB,EAAE,SAAS,CAAC,iBAAiB;YAC9C,UAAU,EAAE,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC3C,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,aAAa,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS;aAClC,CAAC,CAAC;YACH,KAAK,EAAE,SAAS,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE;YACxC,QAAQ,EAAE,SAAS,CAAC,QAAQ;YAC5B,QAAQ,EAAE,SAAS,CAAC,QAAQ;YAC5B,WAAW,EAAE,SAAS,CAAC,WAAW;SACnC,CAAC,CAAC;QAEH,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,yBAAyB,CAAC;YACrD,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,YAAY;YACZ,cAAc,EAAE,cAAc,CAAC,OAAO,EAAE;YACxC,QAAQ;SACT,CAAC,CAAC;QAEH,yEAAyE;QACzE,yEAAyE;QACzE,oEAAoE;QACpE,uEAAuE;QACvE,MAAM,SAAS,GAAG,kBAAkB,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG;YACZ,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC;YAC/B,GAAG,gBAAgB,CAAC,SAAS,CAAC;SAC/B,CAAC;QAEF,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,WAAW,CAClE,kBAAkB,CAAC;YACjB,cAAc;YACd,WAAW,EAAE,WAAW,CAAC,WAAW;YACpC,MAAM;YACN,QAAQ;YACR,KAAK;YACL,WAAW,EAAE,GAAG;YAChB,eAAe,EAAE,IAAI;YACrB,QAAQ,EAAE,CAAC;SACZ,CAAC,EACF,4BAA4B,EAC5B,8BAA8B,CAC/B,CAAC;QAEF,wEAAwE;QACxE,oEAAoE;QACpE,MAAM,uBAAuB,CAAC,cAAc,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;QAEvE,oEAAoE;QACpE,IAAI,CAAC;YACH,MAAM,aAAa,GAAa,EAAE,CAAC;YACnC,sCAAsC;YACtC,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAG9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC/C,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAC9B,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;wBAC5D,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;wBAC7D,SAAS;oBACX,CAAC;oBAGD,IAAI,CAAC;wBACH,IAAI,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,MAAyB,CAAC,CAAC;wBAC9D,IAAI,QAAQ,EAAE,CAAC;4BACb,iEAAiE;4BACjE,MAAM,cAAc,GAAG,GAAG,CAAC,KAAK;iCAC7B,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC;iCACjC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;iCACpB,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;4BAEpB,MAAM,QAAQ,GAAG,GAAG,cAAc,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;4BACjE,MAAM,QAAQ,GAAG,mBAAmB,WAAW,CAAC,OAAO,IAAI,QAAQ,EAAE,CAAC;4BAEtE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;4BAEpF,0CAA0C;4BAC1C,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;4BACtC,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;gCACxC,QAAQ,EAAE;oCACR,WAAW,EAAE,iBAAiB;iCAC/B;6BACF,CAAC,CAAC;4BAEH,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;4BAE3E,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;gCACpC,IAAI,EAAE;oCACJ,IAAI,EAAE,QAAQ;oCACd,IAAI,EAAE,QAAQ;oCACd,IAAI,EAAE,iBAAiB;oCACvB,IAAI,EAAE,QAAQ,CAAC,MAAM;oCACrB,MAAM,EAAE,WAAW,CAAC,WAAW;oCAC/B,YAAY,EAAE,WAAW;oCACzB,UAAU,EAAE,IAAI,IAAI,EAAE;iCACvB;6BACF,CAAC,CAAC;4BACH,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;wBAC9B,CAAC;6BAAM,CAAC;4BACN,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,mCAAmC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;wBACjG,CAAC;oBACH,CAAC;oBAAC,OAAO,QAAQ,EAAE,CAAC;wBAClB,MAAM,CAAC,KAAK,CAAC,4CAA4C,CAAC,GAAG,CAAC,GAAG,EAAE;4BACjE,KAAK,EAAE,QAAQ,YAAY,KAAK,CAAC,CAAC,CAAC;gCACjC,OAAO,EAAE,QAAQ,CAAC,OAAO;gCACzB,KAAK,EAAE,QAAQ,CAAC,KAAK;gCACrB,IAAI,EAAE,QAAQ,CAAC,IAAI;6BACpB,CAAC,CAAC,CAAC,QAAQ;4BACZ,SAAS;4BACT,KAAK,EAAE,GAAG,CAAC,KAAK;yBACjB,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;YAED,MAAM,wBAAwB,CAAC,WAAW,CAAC,WAAW,EAAE,YAAY,EAAE;gBACpE,WAAW,EAAE;oBACX,OAAO,EAAE,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;iBAC3C;gBACD,IAAI,EAAE;oBACJ,mBAAmB,EAAE,SAAS,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;wBACnD,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,UAAU,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;wBACxE,CAAC,CAAC,IAAI;oBACR,kBAAkB,EAAE,SAAS,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;wBACjD,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,SAAS,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;wBACrE,CAAC,CAAC,IAAI;oBACR,gBAAgB,EAAE,SAAS,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;wBAC7C,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;wBAC/D,CAAC,CAAC,IAAI;oBACR,WAAW,EAAE,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;iBACzD;aACF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,YAAY,EAAE,CAAC;YACtB,MAAM,CAAC,KAAK,CAAC,gDAAgD,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,CAAC;YACnG,8DAA8D;YAC9D,yDAAyD;YACzD,MAAM,wBAAwB,CAAC,WAAW,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QACxE,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,wBAAwB,EAAE;gBAClF,SAAS;gBACT,SAAS,EAAE,WAAW,CAAC,WAAW;aACnC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,cAAc,EAAE,CAAC;YACxB,MAAM,CAAC,KAAK,CAAC,6CAA6C,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QACzF,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC;IAEvG,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,iCAAiC,EAAE;YAC9C,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC;gBAC9B,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,IAAI,EAAE,KAAK,CAAC,IAAI;aACjB,CAAC,CAAC,CAAC,KAAK;YACT,SAAS;YACT,WAAW,EAAE,WAAW,CAAC,WAAW;SACrC,CAAC,CAAC;QAEH,MAAM,oBAAoB,CAAC,WAAW,CAAC,WAAW,EAAE;YAClD,MAAM,EAAE,gCAAgC;SACzC,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,qBAAqB,EAAE;gBAC/E,SAAS;gBACT,SAAS,EAAE,WAAW,CAAC,WAAW;gBAClC,KAAK,EAAE,+BAA+B;aACvC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,cAAc,EAAE,CAAC;YACxB,MAAM,CAAC,KAAK,CAAC,0CAA0C,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QACtF,CAAC;QAED,MAAM,KAAK,CAAC,CAAC,yDAAyD;IACxE,CAAC;AACH,CAAC,CAAA","debug_id":"4bfeb1af-edc2-540a-acc7-d36c999b18a3"}