@studious-lms/server 1.14.0 → 1.16.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 (129) hide show
  1. package/dist/lib/inferDocumentFormat.d.ts +10 -0
  2. package/dist/lib/inferDocumentFormat.d.ts.map +1 -0
  3. package/dist/lib/inferDocumentFormat.js +48 -0
  4. package/dist/lib/inferDocumentFormat.js.map +1 -0
  5. package/dist/models/announcement.d.ts +45 -45
  6. package/dist/models/assignment.d.ts +75 -75
  7. package/dist/models/class.d.ts +13 -13
  8. package/dist/models/comment.d.ts +6 -6
  9. package/dist/models/conversation.d.ts +23 -23
  10. package/dist/models/event.d.ts +18 -18
  11. package/dist/models/file.d.ts +9 -9
  12. package/dist/models/labChat.d.ts +4 -4
  13. package/dist/models/message.d.ts +13 -13
  14. package/dist/models/newtonChat.d.ts +3 -3
  15. package/dist/models/notification.d.ts +4 -4
  16. package/dist/models/worksheet.d.ts +121 -121
  17. package/dist/pipelines/aiLabChat.d.ts +7 -1
  18. package/dist/pipelines/aiLabChat.d.ts.map +1 -1
  19. package/dist/pipelines/aiLabChat.js +145 -67
  20. package/dist/pipelines/aiLabChat.js.map +1 -1
  21. package/dist/pipelines/aiLabChatContract.d.ts +34 -195
  22. package/dist/pipelines/aiLabChatContract.d.ts.map +1 -1
  23. package/dist/pipelines/aiLabChatContract.js +9 -19
  24. package/dist/pipelines/aiLabChatContract.js.map +1 -1
  25. package/dist/pipelines/gradeWorksheet.d.ts +6 -6
  26. package/dist/pipelines/gradeWorksheet.d.ts.map +1 -1
  27. package/dist/pipelines/gradeWorksheet.js +75 -36
  28. package/dist/pipelines/gradeWorksheet.js.map +1 -1
  29. package/dist/pipelines/labChatPrompt.d.ts +8 -3
  30. package/dist/pipelines/labChatPrompt.d.ts.map +1 -1
  31. package/dist/pipelines/labChatPrompt.js +49 -14
  32. package/dist/pipelines/labChatPrompt.js.map +1 -1
  33. package/dist/pipelines/pdfToWorksheet.d.ts +1 -1
  34. package/dist/routers/_app.d.ts +524 -516
  35. package/dist/routers/_app.d.ts.map +1 -1
  36. package/dist/routers/announcement.d.ts +40 -40
  37. package/dist/routers/assignment.d.ts +121 -121
  38. package/dist/routers/class.d.ts +8 -8
  39. package/dist/routers/comment.d.ts +5 -5
  40. package/dist/routers/conversation.d.ts +6 -6
  41. package/dist/routers/discussion.d.ts +3 -3
  42. package/dist/routers/embedding.d.ts +6 -2
  43. package/dist/routers/embedding.d.ts.map +1 -1
  44. package/dist/routers/embedding.js +44 -36
  45. package/dist/routers/embedding.js.map +1 -1
  46. package/dist/routers/event.d.ts +18 -18
  47. package/dist/routers/file.d.ts +2 -2
  48. package/dist/routers/labChat.d.ts +3 -3
  49. package/dist/routers/notifications.d.ts +4 -4
  50. package/dist/routers/search.d.ts +2 -2
  51. package/dist/routers/worksheet.d.ts +44 -44
  52. package/dist/routes/aiStream.d.ts.map +1 -1
  53. package/dist/routes/aiStream.js +41 -11
  54. package/dist/routes/aiStream.js.map +1 -1
  55. package/dist/seedDatabase.d.ts +1 -1
  56. package/dist/services/aiChatStream.d.ts +18 -0
  57. package/dist/services/aiChatStream.d.ts.map +1 -1
  58. package/dist/services/aiChatStream.js +81 -11
  59. package/dist/services/aiChatStream.js.map +1 -1
  60. package/dist/services/aiModifierTools.d.ts +0 -16
  61. package/dist/services/aiModifierTools.d.ts.map +1 -1
  62. package/dist/services/aiModifierTools.js +112 -3
  63. package/dist/services/aiModifierTools.js.map +1 -1
  64. package/dist/services/aiProposalTools.d.ts.map +1 -1
  65. package/dist/services/aiProposalTools.js +25 -25
  66. package/dist/services/aiProposalTools.js.map +1 -1
  67. package/dist/services/announcement.d.ts +34 -34
  68. package/dist/services/assignment.d.ts +111 -111
  69. package/dist/services/assignment.d.ts.map +1 -1
  70. package/dist/services/assignment.js +4 -2
  71. package/dist/services/assignment.js.map +1 -1
  72. package/dist/services/class.d.ts +6 -6
  73. package/dist/services/class.d.ts.map +1 -1
  74. package/dist/services/class.js +7 -3
  75. package/dist/services/class.js.map +1 -1
  76. package/dist/services/comment.d.ts +5 -5
  77. package/dist/services/conversation.d.ts +6 -6
  78. package/dist/services/discussion.d.ts.map +1 -1
  79. package/dist/services/discussion.js +9 -2
  80. package/dist/services/discussion.js.map +1 -1
  81. package/dist/services/embedding.d.ts +19 -1
  82. package/dist/services/embedding.d.ts.map +1 -1
  83. package/dist/services/embedding.js +154 -8
  84. package/dist/services/embedding.js.map +1 -1
  85. package/dist/services/event.d.ts +18 -18
  86. package/dist/services/file.d.ts +4 -4
  87. package/dist/services/folder.d.ts.map +1 -1
  88. package/dist/services/folder.js +32 -2
  89. package/dist/services/folder.js.map +1 -1
  90. package/dist/services/labChat.d.ts +3 -3
  91. package/dist/services/notification.d.ts +4 -4
  92. package/dist/services/openaiDocumentGen.d.ts +25 -0
  93. package/dist/services/openaiDocumentGen.d.ts.map +1 -0
  94. package/dist/services/openaiDocumentGen.js +195 -0
  95. package/dist/services/openaiDocumentGen.js.map +1 -0
  96. package/dist/services/search.d.ts +1 -1
  97. package/dist/services/search.d.ts.map +1 -1
  98. package/dist/services/search.js +27 -2
  99. package/dist/services/search.js.map +1 -1
  100. package/dist/services/worksheet.d.ts +66 -49
  101. package/dist/services/worksheet.d.ts.map +1 -1
  102. package/dist/services/worksheet.js +48 -3
  103. package/dist/services/worksheet.js.map +1 -1
  104. package/dist/workers/processors/embedContent.d.ts.map +1 -1
  105. package/dist/workers/processors/embedContent.js +16 -25
  106. package/dist/workers/processors/embedContent.js.map +1 -1
  107. package/package.json +1 -1
  108. package/prisma/migrations/20260610140000_expand_embedding_source_types/migration.sql +4 -0
  109. package/prisma/schema.prisma +3 -0
  110. package/src/lib/inferDocumentFormat.ts +58 -0
  111. package/src/pipelines/aiLabChat.ts +185 -74
  112. package/src/pipelines/aiLabChatContract.ts +7 -17
  113. package/src/pipelines/gradeWorksheet.ts +95 -38
  114. package/src/pipelines/labChatPrompt.ts +61 -14
  115. package/src/routers/embedding.ts +44 -39
  116. package/src/routes/aiStream.ts +47 -9
  117. package/src/services/aiChatStream.ts +103 -8
  118. package/src/services/aiModifierTools.ts +154 -1
  119. package/src/services/aiProposalTools.ts +26 -25
  120. package/src/services/assignment.ts +3 -0
  121. package/src/services/class.ts +7 -1
  122. package/src/services/discussion.ts +13 -0
  123. package/src/services/embedding.ts +167 -6
  124. package/src/services/folder.ts +31 -0
  125. package/src/services/openaiDocumentGen.ts +237 -0
  126. package/src/services/search.ts +25 -1
  127. package/src/services/worksheet.ts +68 -1
  128. package/src/workers/processors/embedContent.ts +18 -22
  129. package/tests/unit/lib/inferDocumentFormat.test.ts +33 -0
@@ -0,0 +1,10 @@
1
+ import type { DocumentFormat } from '../services/openaiDocumentGen.js';
2
+ /**
3
+ * Resolve the output format for a generated document.
4
+ *
5
+ * The lab model often passes `format: "pdf"` even for presentations/spreadsheets.
6
+ * Keyword signals from the teacher request, title, and body take precedence over
7
+ * a generic pdf default; a non-pdf explicit format is always respected.
8
+ */
9
+ export declare function inferDocumentFormat(title: string, content: string, explicit?: string | null, userRequest?: string | null): DocumentFormat;
10
+ //# sourceMappingURL=inferDocumentFormat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inferDocumentFormat.d.ts","sourceRoot":"/","sources":["lib/inferDocumentFormat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AA2BvE;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,EACxB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,GAC1B,cAAc,CAkBhB"}
@@ -0,0 +1,48 @@
1
+
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]="4c92c09b-87d0-5b2a-b970-6fe3b548d588")}catch(e){}}();
3
+ import { normalizeDocumentFormat } from '../services/openaiDocumentGen.js';
4
+ /** Ordered most-specific first. */
5
+ const FORMAT_RULES = [
6
+ { format: 'pptx', pattern: /\b(presentation|powerpoint|power point|slides?|slide deck|deck|pptx|\.pptx)\b/i },
7
+ { format: 'xlsx', pattern: /\b(spreadsheet|excel|workbook|xlsx|gradebook|grade book|\.xlsx)\b/i },
8
+ { format: 'csv', pattern: /\b(csv|comma[- ]separated|\.csv)\b/i },
9
+ { format: 'docx', pattern: /\b(word doc(ument)?|docx|editable handout|\.docx)\b/i },
10
+ { format: 'png', pattern: /\b(diagram|chart|graph|plot|figure|infographic|\.png)\b/i },
11
+ { format: 'md', pattern: /\b(markdown|readme|\.md)\b/i },
12
+ { format: 'html', pattern: /\b(html|web ?page|\.html)\b/i },
13
+ { format: 'txt', pattern: /\b(plain text|text file|\.txt)\b/i },
14
+ ];
15
+ function inferFromText(...parts) {
16
+ const hay = parts.filter(Boolean).join('\n');
17
+ if (!hay.trim())
18
+ return null;
19
+ for (const { format, pattern } of FORMAT_RULES) {
20
+ if (pattern.test(hay))
21
+ return format;
22
+ }
23
+ return null;
24
+ }
25
+ /**
26
+ * Resolve the output format for a generated document.
27
+ *
28
+ * The lab model often passes `format: "pdf"` even for presentations/spreadsheets.
29
+ * Keyword signals from the teacher request, title, and body take precedence over
30
+ * a generic pdf default; a non-pdf explicit format is always respected.
31
+ */
32
+ export function inferDocumentFormat(title, content, explicit, userRequest) {
33
+ const explicitNorm = explicit?.trim()
34
+ ? normalizeDocumentFormat(explicit)
35
+ : null;
36
+ const fromKeywords = inferFromText(userRequest, title, content);
37
+ // Non-pdf explicit choice wins (model or tool args).
38
+ if (explicitNorm && explicitNorm !== 'pdf') {
39
+ return explicitNorm;
40
+ }
41
+ // Override pdf when the request clearly asks for slides, spreadsheets, etc.
42
+ if (fromKeywords && fromKeywords !== 'pdf') {
43
+ return fromKeywords;
44
+ }
45
+ return explicitNorm ?? 'pdf';
46
+ }
47
+ //# sourceMappingURL=inferDocumentFormat.js.map
48
+ //# debugId=4c92c09b-87d0-5b2a-b970-6fe3b548d588
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inferDocumentFormat.js","sources":["lib/inferDocumentFormat.ts"],"sourceRoot":"/","sourcesContent":["import type { DocumentFormat } from '../services/openaiDocumentGen.js';\nimport { normalizeDocumentFormat } from '../services/openaiDocumentGen.js';\n\ntype FormatRule = { format: DocumentFormat; pattern: RegExp };\n\n/** Ordered most-specific first. */\nconst FORMAT_RULES: FormatRule[] = [\n { format: 'pptx', pattern: /\\b(presentation|powerpoint|power point|slides?|slide deck|deck|pptx|\\.pptx)\\b/i },\n { format: 'xlsx', pattern: /\\b(spreadsheet|excel|workbook|xlsx|gradebook|grade book|\\.xlsx)\\b/i },\n { format: 'csv', pattern: /\\b(csv|comma[- ]separated|\\.csv)\\b/i },\n { format: 'docx', pattern: /\\b(word doc(ument)?|docx|editable handout|\\.docx)\\b/i },\n { format: 'png', pattern: /\\b(diagram|chart|graph|plot|figure|infographic|\\.png)\\b/i },\n { format: 'md', pattern: /\\b(markdown|readme|\\.md)\\b/i },\n { format: 'html', pattern: /\\b(html|web ?page|\\.html)\\b/i },\n { format: 'txt', pattern: /\\b(plain text|text file|\\.txt)\\b/i },\n];\n\nfunction inferFromText(...parts: Array<string | null | undefined>): DocumentFormat | null {\n const hay = parts.filter(Boolean).join('\\n');\n if (!hay.trim()) return null;\n\n for (const { format, pattern } of FORMAT_RULES) {\n if (pattern.test(hay)) return format;\n }\n return null;\n}\n\n/**\n * Resolve the output format for a generated document.\n *\n * The lab model often passes `format: \"pdf\"` even for presentations/spreadsheets.\n * Keyword signals from the teacher request, title, and body take precedence over\n * a generic pdf default; a non-pdf explicit format is always respected.\n */\nexport function inferDocumentFormat(\n title: string,\n content: string,\n explicit?: string | null,\n userRequest?: string | null,\n): DocumentFormat {\n const explicitNorm = explicit?.trim()\n ? normalizeDocumentFormat(explicit)\n : null;\n\n const fromKeywords = inferFromText(userRequest, title, content);\n\n // Non-pdf explicit choice wins (model or tool args).\n if (explicitNorm && explicitNorm !== 'pdf') {\n return explicitNorm;\n }\n\n // Override pdf when the request clearly asks for slides, spreadsheets, etc.\n if (fromKeywords && fromKeywords !== 'pdf') {\n return fromKeywords;\n }\n\n return explicitNorm ?? 'pdf';\n}\n"],"names":[],"mappings":";;AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAI3E,mCAAmC;AACnC,MAAM,YAAY,GAAiB;IACjC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,gFAAgF,EAAE;IAC7G,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,oEAAoE,EAAE;IACjG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,qCAAqC,EAAE;IACjE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,sDAAsD,EAAE;IACnF,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,0DAA0D,EAAE;IACtF,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,6BAA6B,EAAE;IACxD,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,8BAA8B,EAAE;IAC3D,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,mCAAmC,EAAE;CAChE,CAAC;AAEF,SAAS,aAAa,CAAC,GAAG,KAAuC;IAC/D,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;QAAE,OAAO,IAAI,CAAC;IAE7B,KAAK,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,YAAY,EAAE,CAAC;QAC/C,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO,MAAM,CAAC;IACvC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,KAAa,EACb,OAAe,EACf,QAAwB,EACxB,WAA2B;IAE3B,MAAM,YAAY,GAAG,QAAQ,EAAE,IAAI,EAAE;QACnC,CAAC,CAAC,uBAAuB,CAAC,QAAQ,CAAC;QACnC,CAAC,CAAC,IAAI,CAAC;IAET,MAAM,YAAY,GAAG,aAAa,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAEhE,qDAAqD;IACrD,IAAI,YAAY,IAAI,YAAY,KAAK,KAAK,EAAE,CAAC;QAC3C,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,4EAA4E;IAC5E,IAAI,YAAY,IAAI,YAAY,KAAK,KAAK,EAAE,CAAC;QAC3C,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,OAAO,YAAY,IAAI,KAAK,CAAC;AAC/B,CAAC","debug_id":"4c92c09b-87d0-5b2a-b970-6fe3b548d588"}
@@ -36,6 +36,15 @@ export declare function findAnnouncementsByClassId(classId: string): import("@pr
36
36
  comments: number;
37
37
  };
38
38
  remarks: string;
39
+ attachments: {
40
+ path: string;
41
+ type: string;
42
+ id: string;
43
+ name: string;
44
+ size: number | null;
45
+ uploadedAt: Date | null;
46
+ thumbnailId: string | null;
47
+ }[];
39
48
  modifiedAt: Date | null;
40
49
  teacher: {
41
50
  id: string;
@@ -46,15 +55,6 @@ export declare function findAnnouncementsByClassId(classId: string): import("@pr
46
55
  profilePictureThumbnail: string | null;
47
56
  } | null;
48
57
  };
49
- attachments: {
50
- path: string;
51
- type: string;
52
- id: string;
53
- name: string;
54
- size: number | null;
55
- uploadedAt: Date | null;
56
- thumbnailId: string | null;
57
- }[];
58
58
  }[]>;
59
59
  /** @returns Announcement by ID and class. */
60
60
  export declare function findAnnouncementByIdAndClass(id: string, classId: string): import("@prisma/client/runtime/library.js").DynamicModelExtensionFluentApi<import(".prisma/client").Prisma.TypeMap<import("@prisma/client/runtime/library.js").InternalArgs & {
@@ -85,6 +85,15 @@ export declare function findAnnouncementByIdAndClass(id: string, classId: string
85
85
  id: string;
86
86
  createdAt: Date;
87
87
  remarks: string;
88
+ attachments: {
89
+ path: string;
90
+ type: string;
91
+ id: string;
92
+ name: string;
93
+ size: number | null;
94
+ uploadedAt: Date | null;
95
+ thumbnailId: string | null;
96
+ }[];
88
97
  modifiedAt: Date | null;
89
98
  teacher: {
90
99
  id: string;
@@ -95,15 +104,6 @@ export declare function findAnnouncementByIdAndClass(id: string, classId: string
95
104
  profilePictureThumbnail: string | null;
96
105
  } | null;
97
106
  };
98
- attachments: {
99
- path: string;
100
- type: string;
101
- id: string;
102
- name: string;
103
- size: number | null;
104
- uploadedAt: Date | null;
105
- thumbnailId: string | null;
106
- }[];
107
107
  } | null>;
108
108
  /** @returns Announcement by ID with class teachers and school admins. */
109
109
  export declare function findAnnouncementWithClass(id: string): import("@prisma/client/runtime/library.js").DynamicModelExtensionFluentApi<import(".prisma/client").Prisma.TypeMap<import("@prisma/client/runtime/library.js").InternalArgs & {
@@ -221,6 +221,15 @@ export declare function createAnnouncement(data: {
221
221
  id: string;
222
222
  createdAt: Date;
223
223
  remarks: string;
224
+ attachments: {
225
+ path: string;
226
+ type: string;
227
+ id: string;
228
+ name: string;
229
+ size: number | null;
230
+ uploadedAt: Date | null;
231
+ thumbnailId: string | null;
232
+ }[];
224
233
  modifiedAt: Date | null;
225
234
  teacher: {
226
235
  id: string;
@@ -231,15 +240,6 @@ export declare function createAnnouncement(data: {
231
240
  profilePictureThumbnail: string | null;
232
241
  } | null;
233
242
  };
234
- attachments: {
235
- path: string;
236
- type: string;
237
- id: string;
238
- name: string;
239
- size: number | null;
240
- uploadedAt: Date | null;
241
- thumbnailId: string | null;
242
- }[];
243
243
  }>;
244
244
  /** Update announcement attachments. */
245
245
  export declare function updateAnnouncementAttachments(id: string, data: {
@@ -279,6 +279,15 @@ export declare function updateAnnouncementAttachments(id: string, data: {
279
279
  id: string;
280
280
  createdAt: Date;
281
281
  remarks: string;
282
+ attachments: {
283
+ path: string;
284
+ type: string;
285
+ id: string;
286
+ name: string;
287
+ size: number | null;
288
+ uploadedAt: Date | null;
289
+ thumbnailId: string | null;
290
+ }[];
282
291
  modifiedAt: Date | null;
283
292
  teacher: {
284
293
  id: string;
@@ -289,15 +298,6 @@ export declare function updateAnnouncementAttachments(id: string, data: {
289
298
  profilePictureThumbnail: string | null;
290
299
  } | null;
291
300
  };
292
- attachments: {
293
- path: string;
294
- type: string;
295
- id: string;
296
- name: string;
297
- size: number | null;
298
- uploadedAt: Date | null;
299
- thumbnailId: string | null;
300
- }[];
301
301
  }>;
302
302
  /** Update announcement remarks. */
303
303
  export declare function updateAnnouncement(id: string, data: {
@@ -330,6 +330,15 @@ export declare function updateAnnouncement(id: string, data: {
330
330
  id: string;
331
331
  createdAt: Date;
332
332
  remarks: string;
333
+ attachments: {
334
+ path: string;
335
+ type: string;
336
+ id: string;
337
+ name: string;
338
+ size: number | null;
339
+ uploadedAt: Date | null;
340
+ thumbnailId: string | null;
341
+ }[];
333
342
  modifiedAt: Date | null;
334
343
  teacher: {
335
344
  id: string;
@@ -340,15 +349,6 @@ export declare function updateAnnouncement(id: string, data: {
340
349
  profilePictureThumbnail: string | null;
341
350
  } | null;
342
351
  };
343
- attachments: {
344
- path: string;
345
- type: string;
346
- id: string;
347
- name: string;
348
- size: number | null;
349
- uploadedAt: Date | null;
350
- thumbnailId: string | null;
351
- }[];
352
352
  }>;
353
353
  /** Delete an announcement. */
354
354
  export declare function deleteAnnouncement(id: string): import("@prisma/client/runtime/library.js").DynamicModelExtensionFluentApi<import(".prisma/client").Prisma.TypeMap<import("@prisma/client/runtime/library.js").InternalArgs & {