@studious-lms/server 1.2.45 → 1.2.47
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.
- package/.env.example +45 -0
- package/.env.test.example +37 -0
- package/README.md +34 -7
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/clover.xml +12110 -0
- package/coverage/coverage-final.json +44 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +221 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/server/index.html +116 -0
- package/coverage/server/src/exportType.ts.html +109 -0
- package/coverage/server/src/index.html +161 -0
- package/coverage/server/src/index.ts.html +1702 -0
- package/coverage/server/src/instrument.ts.html +130 -0
- package/coverage/server/src/lib/config/env.ts.html +448 -0
- package/coverage/server/src/lib/config/index.html +116 -0
- package/coverage/server/src/lib/fileUpload.ts.html +1138 -0
- package/coverage/server/src/lib/googleCloudStorage.ts.html +334 -0
- package/coverage/server/src/lib/index.html +206 -0
- package/coverage/server/src/lib/jsonConversion.ts.html +2323 -0
- package/coverage/server/src/lib/jsonStyles.ts.html +193 -0
- package/coverage/server/src/lib/notificationHandler.ts.html +193 -0
- package/coverage/server/src/lib/pusher.ts.html +121 -0
- package/coverage/server/src/lib/thumbnailGenerator.ts.html +592 -0
- package/coverage/server/src/middleware/auth.ts.html +646 -0
- package/coverage/server/src/middleware/index.html +146 -0
- package/coverage/server/src/middleware/logging.ts.html +244 -0
- package/coverage/server/src/middleware/security.ts.html +271 -0
- package/coverage/server/src/routers/_app.ts.html +232 -0
- package/coverage/server/src/routers/agenda.ts.html +319 -0
- package/coverage/server/src/routers/announcement.ts.html +3481 -0
- package/coverage/server/src/routers/assignment.ts.html +7633 -0
- package/coverage/server/src/routers/attendance.ts.html +1030 -0
- package/coverage/server/src/routers/auth.ts.html +1081 -0
- package/coverage/server/src/routers/class.ts.html +3535 -0
- package/coverage/server/src/routers/comment.ts.html +991 -0
- package/coverage/server/src/routers/conversation.ts.html +982 -0
- package/coverage/server/src/routers/event.ts.html +1609 -0
- package/coverage/server/src/routers/file.ts.html +1144 -0
- package/coverage/server/src/routers/folder.ts.html +2797 -0
- package/coverage/server/src/routers/index.html +386 -0
- package/coverage/server/src/routers/labChat.ts.html +3073 -0
- package/coverage/server/src/routers/marketing.ts.html +340 -0
- package/coverage/server/src/routers/message.ts.html +1912 -0
- package/coverage/server/src/routers/notifications.ts.html +364 -0
- package/coverage/server/src/routers/section.ts.html +1120 -0
- package/coverage/server/src/routers/user.ts.html +862 -0
- package/coverage/server/src/routers/worksheet.ts.html +1729 -0
- package/coverage/server/src/trpc.ts.html +397 -0
- package/coverage/server/src/types/index.html +116 -0
- package/coverage/server/src/types/trpc.ts.html +127 -0
- package/coverage/server/src/utils/aiUser.ts.html +280 -0
- package/coverage/server/src/utils/email.ts.html +121 -0
- package/coverage/server/src/utils/generateInviteCode.ts.html +106 -0
- package/coverage/server/src/utils/index.html +206 -0
- package/coverage/server/src/utils/inference.ts.html +709 -0
- package/coverage/server/src/utils/logger.ts.html +664 -0
- package/coverage/server/src/utils/prismaErrorHandler.ts.html +907 -0
- package/coverage/server/src/utils/prismaWrapper.ts.html +355 -0
- package/coverage/server/vitest.config.ts.html +196 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +83 -52
- package/dist/index.js.map +1 -1
- package/dist/instrument.js +15 -8
- package/dist/instrument.js.map +1 -1
- package/dist/lib/config/env.d.ts +169 -0
- package/dist/lib/config/env.d.ts.map +1 -0
- package/dist/lib/config/env.js +115 -0
- package/dist/lib/config/env.js.map +1 -0
- package/dist/lib/fileUpload.d.ts.map +1 -1
- package/dist/lib/fileUpload.js +5 -4
- package/dist/lib/fileUpload.js.map +1 -1
- package/dist/lib/googleCloudStorage.d.ts.map +1 -1
- package/dist/lib/googleCloudStorage.js +7 -8
- package/dist/lib/googleCloudStorage.js.map +1 -1
- package/dist/lib/jsonConversion.d.ts.map +1 -1
- package/dist/lib/jsonConversion.js +14 -16
- package/dist/lib/jsonConversion.js.map +1 -1
- package/dist/lib/notificationHandler.d.ts +2 -2
- package/dist/lib/prisma.d.ts +2 -2
- package/dist/lib/prisma.d.ts.map +1 -1
- package/dist/lib/prisma.js +22 -3
- package/dist/lib/prisma.js.map +1 -1
- package/dist/lib/pusher.d.ts.map +1 -1
- package/dist/lib/pusher.js +8 -7
- package/dist/lib/pusher.js.map +1 -1
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +7 -5
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/security.d.ts +5 -0
- package/dist/middleware/security.d.ts.map +1 -0
- package/dist/middleware/security.js +77 -0
- package/dist/middleware/security.js.map +1 -0
- package/dist/routers/_app.d.ts +368 -108
- package/dist/routers/_app.d.ts.map +1 -1
- package/dist/routers/_app.js +4 -2
- package/dist/routers/_app.js.map +1 -1
- package/dist/routers/agenda.d.ts.map +1 -1
- package/dist/routers/agenda.js +12 -9
- package/dist/routers/agenda.js.map +1 -1
- package/dist/routers/announcement.d.ts +8 -0
- package/dist/routers/announcement.d.ts.map +1 -1
- package/dist/routers/announcement.js +6 -4
- package/dist/routers/announcement.js.map +1 -1
- package/dist/routers/assignment.d.ts +17 -4
- package/dist/routers/assignment.d.ts.map +1 -1
- package/dist/routers/assignment.js +51 -19
- package/dist/routers/assignment.js.map +1 -1
- package/dist/routers/attendance.d.ts +1 -0
- package/dist/routers/attendance.d.ts.map +1 -1
- package/dist/routers/attendance.js +4 -4
- package/dist/routers/attendance.js.map +1 -1
- package/dist/routers/auth.d.ts +20 -0
- package/dist/routers/auth.d.ts.map +1 -1
- package/dist/routers/auth.js +132 -15
- package/dist/routers/auth.js.map +1 -1
- package/dist/routers/class.d.ts +10 -0
- package/dist/routers/class.d.ts.map +1 -1
- package/dist/routers/class.js +49 -5
- package/dist/routers/class.js.map +1 -1
- package/dist/routers/comment.d.ts +2 -0
- package/dist/routers/comment.d.ts.map +1 -1
- package/dist/routers/conversation.d.ts +2 -0
- package/dist/routers/conversation.d.ts.map +1 -1
- package/dist/routers/conversation.js +46 -31
- package/dist/routers/conversation.js.map +1 -1
- package/dist/routers/file.d.ts.map +1 -1
- package/dist/routers/file.js +30 -7
- package/dist/routers/file.js.map +1 -1
- package/dist/routers/labChat.d.ts +2 -0
- package/dist/routers/labChat.d.ts.map +1 -1
- package/dist/routers/labChat.js +5 -322
- package/dist/routers/labChat.js.map +1 -1
- package/dist/routers/marketing.d.ts +1 -1
- package/dist/routers/message.d.ts +1 -0
- package/dist/routers/message.d.ts.map +1 -1
- package/dist/routers/message.js +3 -2
- package/dist/routers/message.js.map +1 -1
- package/dist/routers/newtonChat.d.ts +55 -0
- package/dist/routers/newtonChat.d.ts.map +1 -0
- package/dist/routers/newtonChat.js +262 -0
- package/dist/routers/newtonChat.js.map +1 -0
- package/dist/routers/notifications.d.ts +4 -4
- package/dist/routers/section.d.ts +19 -4
- package/dist/routers/section.d.ts.map +1 -1
- package/dist/routers/section.js +26 -8
- package/dist/routers/section.js.map +1 -1
- package/dist/routers/user.d.ts.map +1 -1
- package/dist/routers/user.js +5 -4
- package/dist/routers/user.js.map +1 -1
- package/dist/routers/worksheet.d.ts +44 -41
- package/dist/routers/worksheet.d.ts.map +1 -1
- package/dist/routers/worksheet.js +25 -34
- package/dist/routers/worksheet.js.map +1 -1
- package/dist/seedDatabase.d.ts +1 -1
- package/dist/seedDatabase.js +275 -284
- package/dist/seedDatabase.js.map +1 -1
- package/dist/server/pipelines/aiLabChat.d.ts +21 -0
- package/dist/server/pipelines/aiLabChat.d.ts.map +1 -0
- package/dist/server/pipelines/aiLabChat.js +456 -0
- package/dist/server/pipelines/aiLabChat.js.map +1 -0
- package/dist/server/pipelines/aiNewtonChat.d.ts +30 -0
- package/dist/server/pipelines/aiNewtonChat.d.ts.map +1 -0
- package/dist/server/pipelines/aiNewtonChat.js +280 -0
- package/dist/server/pipelines/aiNewtonChat.js.map +1 -0
- package/dist/server/pipelines/gradeWorksheet.d.ts +15 -0
- package/dist/server/pipelines/gradeWorksheet.d.ts.map +1 -0
- package/dist/server/pipelines/gradeWorksheet.js +139 -0
- package/dist/server/pipelines/gradeWorksheet.js.map +1 -0
- package/dist/trpc.d.ts.map +1 -1
- package/dist/trpc.js +2 -2
- package/dist/trpc.js.map +1 -1
- package/dist/utils/email.d.ts +9 -1
- package/dist/utils/email.d.ts.map +1 -1
- package/dist/utils/email.js +20 -5
- package/dist/utils/email.js.map +1 -1
- package/dist/utils/inference.d.ts +5 -0
- package/dist/utils/inference.d.ts.map +1 -1
- package/dist/utils/inference.js +71 -7
- package/dist/utils/inference.js.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +3 -3
- package/dist/utils/logger.js.map +1 -1
- package/docker-compose.yml +14 -0
- package/package.json +13 -4
- package/prisma/schema.prisma +34 -5
- package/scripts/test-pre-push.ts +14 -0
- package/src/index.ts +98 -54
- package/src/instrument.ts +13 -6
- package/src/lib/config/env.ts +126 -0
- package/src/lib/fileUpload.ts +3 -2
- package/src/lib/googleCloudStorage.ts +6 -6
- package/src/lib/jsonConversion.ts +12 -14
- package/src/lib/prisma.ts +23 -2
- package/src/lib/pusher.ts +6 -5
- package/src/middleware/auth.ts +5 -3
- package/src/middleware/security.ts +80 -0
- package/src/routers/_app.ts +2 -0
- package/src/routers/agenda.ts +10 -7
- package/src/routers/announcement.ts +4 -2
- package/src/routers/assignment.ts +74 -41
- package/src/routers/attendance.ts +2 -2
- package/src/routers/auth.ts +143 -14
- package/src/routers/class.ts +52 -3
- package/src/routers/conversation.ts +49 -29
- package/src/routers/file.ts +29 -5
- package/src/routers/labChat.ts +3 -367
- package/src/routers/message.ts +1 -1
- package/src/routers/newtonChat.ts +299 -0
- package/src/routers/section.ts +26 -6
- package/src/routers/user.ts +3 -2
- package/src/routers/worksheet.ts +26 -38
- package/src/seedDatabase.ts +290 -283
- package/src/server/pipelines/aiLabChat.ts +507 -0
- package/src/server/pipelines/aiNewtonChat.ts +338 -0
- package/src/server/pipelines/gradeWorksheet.ts +151 -0
- package/src/trpc.ts +2 -0
- package/src/utils/email.ts +30 -3
- package/src/utils/inference.ts +85 -5
- package/src/utils/logger.ts +2 -1
- package/tests/announcement.test.ts +164 -0
- package/tests/assignment.test.ts +296 -0
- package/tests/attendance.test.ts +168 -0
- package/tests/auth.test.ts +33 -10
- package/tests/class.test.ts +34 -9
- package/tests/event.test.ts +228 -0
- package/tests/section.test.ts +216 -0
- package/tests/setup.ts +70 -16
- package/tests/user.test.ts +158 -0
- package/vitest.config.ts +26 -0
- package/API_SPECIFICATION.md +0 -1597
- package/BASE64_REMOVAL_SUMMARY.md +0 -164
- package/CHAT_API_SPEC.md +0 -579
- package/LAB_CHAT_API_SPEC.md +0 -518
- package/dist/routers/school.d.ts +0 -208
- package/dist/routers/school.d.ts.map +0 -1
- package/dist/routers/school.js +0 -483
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import OpenAI from 'openai';
|
|
2
|
+
import { ZodSchema } from 'zod';
|
|
2
3
|
export declare const inferenceClient: OpenAI;
|
|
4
|
+
export declare const openAIClient: OpenAI;
|
|
3
5
|
export interface LabChatContext {
|
|
4
6
|
subject: string;
|
|
5
7
|
topic: string;
|
|
@@ -28,6 +30,7 @@ export declare function sendAIMessage(content: string, conversationId: string, o
|
|
|
28
30
|
id: string;
|
|
29
31
|
}[];
|
|
30
32
|
};
|
|
33
|
+
meta?: Record<string, any>;
|
|
31
34
|
customSender?: {
|
|
32
35
|
displayName: string;
|
|
33
36
|
profilePicture?: string | null;
|
|
@@ -38,7 +41,9 @@ export declare function sendAIMessage(content: string, conversationId: string, o
|
|
|
38
41
|
senderId: string;
|
|
39
42
|
conversationId: string;
|
|
40
43
|
createdAt: Date;
|
|
44
|
+
meta?: Record<string, any>;
|
|
41
45
|
}>;
|
|
46
|
+
export declare function inference<T>(content: string | OpenAI.Chat.Completions.ChatCompletionMessageParam[], format?: ZodSchema): Promise<T>;
|
|
42
47
|
/**
|
|
43
48
|
* Simple inference function for general use
|
|
44
49
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inference.d.ts","sourceRoot":"/","sources":["utils/inference.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"inference.d.ts","sourceRoot":"/","sources":["utils/inference.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAM5B,OAAO,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAKhC,eAAO,MAAM,eAAe,QAG1B,CAAC;AAEH,eAAO,MAAM,YAAY,QAAe,CAAC;AAGzC,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,UAAU,GAAG,cAAc,GAAG,UAAU,CAAC;IACrD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,EACtB,OAAO,GAAE;IACP,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE;QACZ,OAAO,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;KAC3B,CAAC;IACF,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,YAAY,CAAC,EAAE;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAChC,CAAC;CACE,GACL,OAAO,CAAC;IACT,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,IAAI,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC5B,CAAC,CAwED;AAED,wBAAsB,SAAS,CAAC,CAAC,EAC/B,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,0BAA0B,EAAE,EACtE,MAAM,CAAC,EAAE,SAAS,GACjB,OAAO,CAAC,CAAC,CAAC,CA8DZ;AAED;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IACP,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACf,GACL,OAAO,CAAC,iBAAiB,CAAC,CAsC5B;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAMjD;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAW5D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGvD"}
|
package/dist/utils/inference.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
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]="
|
|
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]="c078a743-460b-5c3a-ac46-6d32cb065ff1")}catch(e){}}();
|
|
3
3
|
import OpenAI from 'openai';
|
|
4
4
|
import { logger } from './logger.js';
|
|
5
5
|
import { prisma } from '../lib/prisma.js';
|
|
6
6
|
import { pusher } from '../lib/pusher.js';
|
|
7
7
|
import { ensureAIUserExists, getAIUserId } from './aiUser.js';
|
|
8
|
+
import { env } from '../lib/config/env.js';
|
|
9
|
+
import { zodTextFormat } from "openai/helpers/zod";
|
|
8
10
|
export const inferenceClient = new OpenAI({
|
|
9
|
-
apiKey:
|
|
10
|
-
baseURL:
|
|
11
|
+
apiKey: env.INFERENCE_API_KEY,
|
|
12
|
+
baseURL: env.INFERENCE_API_BASE_URL,
|
|
11
13
|
});
|
|
14
|
+
export const openAIClient = new OpenAI();
|
|
12
15
|
/**
|
|
13
16
|
* Centralized function to send AI messages to conversations
|
|
14
17
|
* Handles database storage and Pusher broadcasting
|
|
@@ -27,6 +30,9 @@ export async function sendAIMessage(content, conversationId, options = {}) {
|
|
|
27
30
|
connect: options.attachments.connect,
|
|
28
31
|
},
|
|
29
32
|
}),
|
|
33
|
+
...(options.meta && {
|
|
34
|
+
meta: options.meta,
|
|
35
|
+
}),
|
|
30
36
|
},
|
|
31
37
|
include: {
|
|
32
38
|
attachments: true,
|
|
@@ -56,6 +62,7 @@ export async function sendAIMessage(content, conversationId, options = {}) {
|
|
|
56
62
|
createdAt: aiMessage.createdAt,
|
|
57
63
|
sender: senderInfo,
|
|
58
64
|
mentionedUserIds: [],
|
|
65
|
+
meta: aiMessage.meta,
|
|
59
66
|
attachments: aiMessage.attachments.map(attachment => ({
|
|
60
67
|
id: attachment.id,
|
|
61
68
|
attachmentId: attachment.id,
|
|
@@ -75,15 +82,72 @@ export async function sendAIMessage(content, conversationId, options = {}) {
|
|
|
75
82
|
senderId: getAIUserId(),
|
|
76
83
|
conversationId: aiMessage.conversationId,
|
|
77
84
|
createdAt: aiMessage.createdAt,
|
|
85
|
+
meta: aiMessage.meta,
|
|
78
86
|
};
|
|
79
87
|
}
|
|
88
|
+
export async function inference(content, format) {
|
|
89
|
+
try {
|
|
90
|
+
if (!format) {
|
|
91
|
+
const completion = await openAIClient.chat.completions.create({
|
|
92
|
+
model: 'gpt-5-nano',
|
|
93
|
+
messages: typeof content === 'string' ? [
|
|
94
|
+
{
|
|
95
|
+
role: 'user',
|
|
96
|
+
content: content,
|
|
97
|
+
},
|
|
98
|
+
] : content,
|
|
99
|
+
});
|
|
100
|
+
return completion.choices[0]?.message?.content;
|
|
101
|
+
}
|
|
102
|
+
const completion = await openAIClient.responses.parse({
|
|
103
|
+
model: 'gpt-5-nano',
|
|
104
|
+
input: typeof content === 'string' ? [
|
|
105
|
+
{
|
|
106
|
+
role: 'user',
|
|
107
|
+
content: content,
|
|
108
|
+
},
|
|
109
|
+
] : content,
|
|
110
|
+
...(format ? { text: {
|
|
111
|
+
format: zodTextFormat(format, "newton_response_format"),
|
|
112
|
+
},
|
|
113
|
+
} : {}),
|
|
114
|
+
});
|
|
115
|
+
console.log({
|
|
116
|
+
model: 'gpt-5-nano',
|
|
117
|
+
input: typeof content === 'string' ? [
|
|
118
|
+
{
|
|
119
|
+
role: 'user',
|
|
120
|
+
content: content,
|
|
121
|
+
},
|
|
122
|
+
] : content,
|
|
123
|
+
...(format ? { text: {
|
|
124
|
+
format: zodTextFormat(format, "newton_response_format"),
|
|
125
|
+
},
|
|
126
|
+
} : {}),
|
|
127
|
+
});
|
|
128
|
+
if (!completion) {
|
|
129
|
+
throw new Error('No response generated from inference API');
|
|
130
|
+
}
|
|
131
|
+
// if (format) {
|
|
132
|
+
// if (typeof completion.output === 'string') {
|
|
133
|
+
// return JSON.parse(completion.output);
|
|
134
|
+
// }
|
|
135
|
+
// return JSON.parse(completion.output);
|
|
136
|
+
// }
|
|
137
|
+
return completion.output_parsed;
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
logger.error('Failed to generate inference response', { error });
|
|
141
|
+
throw error;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
80
144
|
/**
|
|
81
145
|
* Simple inference function for general use
|
|
82
146
|
*/
|
|
83
147
|
export async function generateInferenceResponse(subject, question, options = {}) {
|
|
84
|
-
const { model = '
|
|
148
|
+
const { model = 'gpt-5-nano', maxTokens = 500 } = options;
|
|
85
149
|
try {
|
|
86
|
-
const completion = await
|
|
150
|
+
const completion = await openAIClient.chat.completions.create({
|
|
87
151
|
model,
|
|
88
152
|
messages: [
|
|
89
153
|
{
|
|
@@ -119,7 +183,7 @@ export async function generateInferenceResponse(subject, question, options = {})
|
|
|
119
183
|
* Validate inference configuration
|
|
120
184
|
*/
|
|
121
185
|
export function validateInferenceConfig() {
|
|
122
|
-
if (!
|
|
186
|
+
if (!env.INFERENCE_API_KEY) {
|
|
123
187
|
logger.error('Inference API key not configured for Cohere');
|
|
124
188
|
return false;
|
|
125
189
|
}
|
|
@@ -149,4 +213,4 @@ export function estimateTokenCount(text) {
|
|
|
149
213
|
return Math.ceil(text.length / 4);
|
|
150
214
|
}
|
|
151
215
|
//# sourceMappingURL=inference.js.map
|
|
152
|
-
//# debugId=
|
|
216
|
+
//# debugId=c078a743-460b-5c3a-ac46-6d32cb065ff1
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inference.js","sources":["utils/inference.ts"],"sourceRoot":"/","sourcesContent":["import OpenAI from 'openai';\nimport { logger } from './logger.js';\nimport { prisma } from '../lib/prisma.js';\nimport { pusher } from '../lib/pusher.js';\nimport { ensureAIUserExists, getAIUserId } from './aiUser.js';\n\n\nexport const inferenceClient = new OpenAI({\n apiKey: process.env.INFERENCE_API_KEY,\n baseURL: process.env.INFERENCE_API_BASE_URL,\n});\n\n// Types for lab chat context\nexport interface LabChatContext {\n subject: string;\n topic: string;\n difficulty: 'beginner' | 'intermediate' | 'advanced';\n objectives: string[];\n resources?: string[];\n persona: string;\n constraints: string[];\n examples?: any[];\n metadata?: Record<string, any>;\n}\n\nexport interface InferenceResponse {\n content: string;\n model: string;\n tokensUsed: number;\n finishReason: string;\n}\n\n/**\n * Centralized function to send AI messages to conversations\n * Handles database storage and Pusher broadcasting\n */\nexport async function sendAIMessage(\n content: string,\n conversationId: string,\n options: {\n subject?: string;\n attachments?: {\n connect: { id: string }[];\n };\n customSender?: {\n displayName: string;\n profilePicture?: string | null;\n };\n } = {}\n): Promise<{\n id: string;\n content: string;\n senderId: string;\n conversationId: string;\n createdAt: Date;\n}> {\n // Ensure AI user exists\n await ensureAIUserExists();\n\n // Create message in database\n const aiMessage = await prisma.message.create({\n data: {\n content,\n senderId: getAIUserId(),\n conversationId,\n ...(options.attachments && {\n attachments: {\n connect: options.attachments.connect,\n },\n }),\n },\n include: {\n attachments: true,\n },\n });\n\n logger.info('AI Message sent', {\n messageId: aiMessage.id,\n conversationId,\n contentLength: content.length,\n });\n\n // Prepare sender info\n const senderInfo = {\n id: getAIUserId(),\n username: 'Newton_AI',\n profile: {\n displayName: \"Newton AI\",\n profilePicture: options.customSender?.profilePicture || null,\n },\n };\n\n // Broadcast via Pusher\n try {\n await pusher.trigger(`conversation-${conversationId}`, 'new-message', {\n id: aiMessage.id,\n content: aiMessage.content,\n senderId: getAIUserId(),\n conversationId: aiMessage.conversationId,\n createdAt: aiMessage.createdAt,\n sender: senderInfo,\n mentionedUserIds: [],\n attachments: aiMessage.attachments.map(attachment => ({\n id: attachment.id,\n attachmentId: attachment.id,\n name: attachment.name,\n type: attachment.type,\n size: attachment.size,\n path: attachment.path,\n })),\n });\n } catch (error) {\n logger.error('Failed to broadcast AI message:', { error, messageId: aiMessage.id });\n }\n\n return {\n id: aiMessage.id,\n content: aiMessage.content,\n senderId: getAIUserId(),\n conversationId: aiMessage.conversationId,\n createdAt: aiMessage.createdAt,\n };\n}\n\n/**\n * Simple inference function for general use\n */\nexport async function generateInferenceResponse(\n subject: string,\n question: string,\n options: {\n model?: string;\n maxTokens?: number;\n } = {}\n): Promise<InferenceResponse> {\n const { model = 'command-r-plus', maxTokens = 500 } = options;\n\n try {\n const completion = await inferenceClient.chat.completions.create({\n model,\n messages: [\n {\n role: 'system',\n content: `You are a helpful educational assistant for ${subject}. Provide clear, concise, and accurate answers. Keep responses educational and appropriate for students.`,\n },\n {\n role: 'user',\n content: question,\n },\n ],\n max_tokens: maxTokens,\n temperature: 0.5,\n // Remove OpenAI-specific parameters for Cohere compatibility\n });\n\n const response = completion.choices[0]?.message?.content;\n \n if (!response) {\n throw new Error('No response generated from inference API');\n }\n\n return {\n content: response,\n model,\n tokensUsed: completion.usage?.total_tokens || 0,\n finishReason: completion.choices[0]?.finish_reason || 'unknown',\n };\n\n } catch (error) {\n logger.error('Failed to generate inference response', { error, subject, question: question.substring(0, 50) + '...' });\n throw error;\n }\n}\n\n/**\n * Validate inference configuration\n */\nexport function validateInferenceConfig(): boolean {\n if (!process.env.INFERENCE_API_KEY) {\n logger.error('Inference API key not configured for Cohere');\n return false;\n }\n return true;\n}\n\n/**\n * Get available inference models (for admin/config purposes)\n */\nexport async function getAvailableModels(): Promise<string[]> {\n try {\n const models = await inferenceClient.models.list();\n return models.data\n .filter(model => model.id.includes('command'))\n .map(model => model.id)\n .sort();\n } catch (error) {\n logger.error('Failed to fetch inference models', { error });\n return ['command-r-plus', 'command-r', 'command-light']; // Fallback Cohere models\n }\n}\n\n/**\n * Estimate token count for a message (rough approximation)\n */\nexport function estimateTokenCount(text: string): number {\n // Rough approximation: 1 token ≈ 4 characters for English text\n return Math.ceil(text.length / 4);\n}"],"names":[],"mappings":"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","debug_id":"52f0ec7b-6543-5ebc-bde6-cbbfeac779aa"}
|
|
1
|
+
{"version":3,"file":"inference.js","sources":["utils/inference.ts"],"sourceRoot":"/","sourcesContent":["import OpenAI from 'openai';\nimport { logger } from './logger.js';\nimport { prisma } from '../lib/prisma.js';\nimport { pusher } from '../lib/pusher.js';\nimport { ensureAIUserExists, getAIUserId } from './aiUser.js';\nimport { env } from '../lib/config/env.js';\nimport { ZodSchema } from 'zod';\nimport { zodTextFormat } from \"openai/helpers/zod\";\n\n\n\nexport const inferenceClient = new OpenAI({\n apiKey: env.INFERENCE_API_KEY,\n baseURL: env.INFERENCE_API_BASE_URL,\n});\n\nexport const openAIClient = new OpenAI();\n\n// Types for lab chat context\nexport interface LabChatContext {\n subject: string;\n topic: string;\n difficulty: 'beginner' | 'intermediate' | 'advanced';\n objectives: string[];\n resources?: string[];\n persona: string;\n constraints: string[];\n examples?: any[];\n metadata?: Record<string, any>;\n}\n\nexport interface InferenceResponse {\n content: string;\n model: string;\n tokensUsed: number;\n finishReason: string;\n}\n\n/**\n * Centralized function to send AI messages to conversations\n * Handles database storage and Pusher broadcasting\n */\nexport async function sendAIMessage(\n content: string,\n conversationId: string,\n options: {\n subject?: string;\n attachments?: {\n connect: { id: string }[];\n };\n meta?: Record<string, any>;\n customSender?: {\n displayName: string;\n profilePicture?: string | null;\n };\n } = {}\n): Promise<{\n id: string;\n content: string;\n senderId: string;\n conversationId: string;\n createdAt: Date;\n meta?: Record<string, any>;\n}> {\n // Ensure AI user exists\n await ensureAIUserExists();\n\n // Create message in database\n const aiMessage = await prisma.message.create({\n data: {\n content,\n senderId: getAIUserId(),\n conversationId,\n ...(options.attachments && {\n attachments: {\n connect: options.attachments.connect,\n },\n }),\n ...(options.meta && {\n meta: options.meta,\n }),\n },\n include: {\n attachments: true,\n },\n });\n\n logger.info('AI Message sent', {\n messageId: aiMessage.id,\n conversationId,\n contentLength: content.length,\n });\n\n // Prepare sender info\n const senderInfo = {\n id: getAIUserId(),\n username: 'Newton_AI',\n profile: {\n displayName: \"Newton AI\",\n profilePicture: options.customSender?.profilePicture || null,\n },\n };\n\n // Broadcast via Pusher\n try {\n await pusher.trigger(`conversation-${conversationId}`, 'new-message', {\n id: aiMessage.id,\n content: aiMessage.content,\n senderId: getAIUserId(),\n conversationId: aiMessage.conversationId,\n createdAt: aiMessage.createdAt,\n sender: senderInfo,\n mentionedUserIds: [],\n meta: aiMessage.meta,\n attachments: aiMessage.attachments.map(attachment => ({\n id: attachment.id,\n attachmentId: attachment.id,\n name: attachment.name,\n type: attachment.type,\n size: attachment.size,\n path: attachment.path,\n })),\n });\n } catch (error) {\n logger.error('Failed to broadcast AI message:', { error, messageId: aiMessage.id });\n }\n\n return {\n id: aiMessage.id,\n content: aiMessage.content,\n senderId: getAIUserId(),\n conversationId: aiMessage.conversationId,\n createdAt: aiMessage.createdAt,\n meta: aiMessage.meta as Record<string, any>,\n };\n}\n\nexport async function inference<T>(\n content: string | OpenAI.Chat.Completions.ChatCompletionMessageParam[],\n format?: ZodSchema\n): Promise<T> {\n try {\n\n if (!format) {\n const completion = await openAIClient.chat.completions.create({\n model: 'gpt-5-nano',\n messages: typeof content === 'string' ? [\n {\n role: 'user',\n content: content,\n },\n ] : content as Array<{ role: 'user' | 'assistant' | 'system'; content: string }>,\n });\n\n return completion.choices[0]?.message?.content as T;\n }\n\n const completion = await openAIClient.responses.parse({\n model: 'gpt-5-nano',\n input: typeof content === 'string' ? [\n {\n role: 'user',\n content: content,\n },\n ] : content as Array<{ role: 'user' | 'assistant' | 'system'; content: string }>,\n ...(format ? { text: {\n format: zodTextFormat(format, \"newton_response_format\"),\n },\n } : {}),\n });\n\n console.log({\n model: 'gpt-5-nano',\n input: typeof content === 'string' ? [\n {\n role: 'user',\n content: content,\n },\n ] : content as Array<{ role: 'user' | 'assistant' | 'system'; content: string }>,\n ...(format ? { text: {\n format: zodTextFormat(format, \"newton_response_format\"),\n },\n } : {}),\n });\n\n\n if (!completion) {\n throw new Error('No response generated from inference API');\n }\n\n // if (format) {\n // if (typeof completion.output === 'string') {\n // return JSON.parse(completion.output);\n // }\n // return JSON.parse(completion.output);\n // }\n\n return completion.output_parsed;\n } catch (error) {\n logger.error('Failed to generate inference response', { error });\n throw error;\n }\n}\n\n/**\n * Simple inference function for general use\n */\nexport async function generateInferenceResponse(\n subject: string,\n question: string,\n options: {\n model?: string;\n maxTokens?: number;\n } = {}\n): Promise<InferenceResponse> {\n const { model = 'gpt-5-nano', maxTokens = 500 } = options;\n\n try {\n const completion = await openAIClient.chat.completions.create({\n model,\n messages: [\n {\n role: 'system',\n content: `You are a helpful educational assistant for ${subject}. Provide clear, concise, and accurate answers. Keep responses educational and appropriate for students.`,\n },\n {\n role: 'user',\n content: question,\n },\n ],\n max_tokens: maxTokens,\n temperature: 0.5,\n // Remove OpenAI-specific parameters for Cohere compatibility\n });\n\n const response = completion.choices[0]?.message?.content;\n \n if (!response) {\n throw new Error('No response generated from inference API');\n }\n\n return {\n content: response,\n model,\n tokensUsed: completion.usage?.total_tokens || 0,\n finishReason: completion.choices[0]?.finish_reason || 'unknown',\n };\n\n } catch (error) {\n logger.error('Failed to generate inference response', { error, subject, question: question.substring(0, 50) + '...' });\n throw error;\n }\n}\n\n/**\n * Validate inference configuration\n */\nexport function validateInferenceConfig(): boolean {\n if (!env.INFERENCE_API_KEY) {\n logger.error('Inference API key not configured for Cohere');\n return false;\n }\n return true;\n}\n\n/**\n * Get available inference models (for admin/config purposes)\n */\nexport async function getAvailableModels(): Promise<string[]> {\n try {\n const models = await inferenceClient.models.list();\n return models.data\n .filter(model => model.id.includes('command'))\n .map(model => model.id)\n .sort();\n } catch (error) {\n logger.error('Failed to fetch inference models', { error });\n return ['command-r-plus', 'command-r', 'command-light']; // Fallback Cohere models\n }\n}\n\n/**\n * Estimate token count for a message (rough approximation)\n */\nexport function estimateTokenCount(text: string): number {\n // Rough approximation: 1 token ≈ 4 characters for English text\n return Math.ceil(text.length / 4);\n}"],"names":[],"mappings":"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","debug_id":"c078a743-460b-5c3a-ac46-6d32cb065ff1"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"/","sources":["utils/logger.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"/","sources":["utils/logger.ts"],"names":[],"mappings":"AACA,oBAAY,QAAQ;IAClB,IAAI,SAAS;IACb,IAAI,SAAS;IACb,KAAK,UAAU;IACf,KAAK,UAAU;CAChB;AAED,KAAK,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAyC3D,cAAM,MAAM;IACV,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAS;IAChC,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,IAAI,CAAU;IACtB,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,aAAa,CAA2B;IAChD,OAAO,CAAC,WAAW,CAA2B;IAE9C,OAAO;WA8BO,WAAW,IAAI,MAAM;IAO5B,OAAO,CAAC,IAAI,EAAE,OAAO;IAI5B,OAAO,CAAC,SAAS;IAsBjB,OAAO,CAAC,aAAa;IAmBrB,OAAO,CAAC,GAAG;IAqCJ,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAInD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAInD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAIpD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAG5D;AAED,eAAO,MAAM,MAAM,QAAuB,CAAC"}
|
package/dist/utils/logger.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
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]="
|
|
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]="3ad19480-6fd4-5009-abf4-d8f8caeb9a0e")}catch(e){}}();
|
|
3
3
|
export var LogLevel;
|
|
4
4
|
(function (LogLevel) {
|
|
5
5
|
LogLevel["INFO"] = "info";
|
|
@@ -42,7 +42,7 @@ class Logger {
|
|
|
42
42
|
constructor() {
|
|
43
43
|
// this.isDevelopment = process.env.NODE_ENV === 'development';
|
|
44
44
|
this.isDevelopment = true;
|
|
45
|
-
this.mode = process.env.LOG_MODE || 'normal';
|
|
45
|
+
this.mode = (process.env.NODE_ENV === 'test' ? 'silent' : (process.env.LOG_MODE || 'normal'));
|
|
46
46
|
this.levelColors = {
|
|
47
47
|
[LogLevel.INFO]: colors.blue,
|
|
48
48
|
[LogLevel.WARN]: colors.yellow,
|
|
@@ -154,4 +154,4 @@ class Logger {
|
|
|
154
154
|
}
|
|
155
155
|
export const logger = Logger.getInstance();
|
|
156
156
|
//# sourceMappingURL=logger.js.map
|
|
157
|
-
//# debugId=
|
|
157
|
+
//# debugId=3ad19480-6fd4-5009-abf4-d8f8caeb9a0e
|
package/dist/utils/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sources":["utils/logger.ts"],"sourceRoot":"/","sourcesContent":["
|
|
1
|
+
{"version":3,"file":"logger.js","sources":["utils/logger.ts"],"sourceRoot":"/","sourcesContent":["\nexport enum LogLevel {\n INFO = 'info',\n WARN = 'warn',\n ERROR = 'error',\n DEBUG = 'debug'\n}\n\ntype LogMode = 'silent' | 'minimal' | 'normal' | 'verbose';\n\ninterface LogMessage {\n level: LogLevel;\n message: string;\n timestamp: string;\n context?: Record<string, any>;\n}\n\n// ANSI color codes\nconst colors = {\n reset: '\\x1b[0m',\n bright: '\\x1b[1m',\n dim: '\\x1b[2m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n magenta: '\\x1b[35m',\n cyan: '\\x1b[36m',\n white: '\\x1b[37m',\n gray: '\\x1b[90m',\n // Background colors\n bgRed: '\\x1b[41m',\n bgGreen: '\\x1b[42m',\n bgYellow: '\\x1b[43m',\n bgBlue: '\\x1b[44m',\n bgMagenta: '\\x1b[45m',\n bgCyan: '\\x1b[46m',\n bgWhite: '\\x1b[47m',\n bgGray: '\\x1b[100m',\n // Bright background colors\n bgBrightRed: '\\x1b[101m',\n bgBrightGreen: '\\x1b[102m',\n bgBrightYellow: '\\x1b[103m',\n bgBrightBlue: '\\x1b[104m',\n bgBrightMagenta: '\\x1b[105m',\n bgBrightCyan: '\\x1b[106m',\n bgBrightWhite: '\\x1b[107m'\n};\n\nclass Logger {\n private static instance: Logger;\n private isDevelopment: boolean;\n private mode: LogMode;\n private levelColors: Record<LogLevel, string>;\n private levelBgColors: Record<LogLevel, string>;\n private levelEmojis: Record<LogLevel, string>;\n\n private constructor() {\n\n // this.isDevelopment = process.env.NODE_ENV === 'development';\n this.isDevelopment = true;\n\n this.mode = (process.env.NODE_ENV === 'test' ? 'silent' : ((process.env.LOG_MODE as LogMode) || 'normal'));\n \n\n this.levelColors = {\n [LogLevel.INFO]: colors.blue,\n [LogLevel.WARN]: colors.yellow,\n [LogLevel.ERROR]: colors.red,\n [LogLevel.DEBUG]: colors.magenta\n };\n\n this.levelBgColors = {\n [LogLevel.INFO]: colors.bgBlue,\n [LogLevel.WARN]: colors.bgYellow,\n [LogLevel.ERROR]: colors.bgRed,\n [LogLevel.DEBUG]: colors.bgMagenta\n };\n\n this.levelEmojis = {\n [LogLevel.INFO]: 'ℹ️',\n [LogLevel.WARN]: '⚠️',\n [LogLevel.ERROR]: '❌',\n [LogLevel.DEBUG]: '🔍'\n };\n }\n\n public static getInstance(): Logger {\n if (!Logger.instance) {\n Logger.instance = new Logger();\n }\n return Logger.instance;\n }\n\n public setMode(mode: LogMode) {\n this.mode = mode;\n }\n\n private shouldLog(level: LogLevel): boolean {\n const silent = [\n LogLevel.ERROR,\n ];\n\n const minimal = [\n LogLevel.ERROR,\n LogLevel.WARN,\n ];\n\n const normal = [\n LogLevel.ERROR,\n LogLevel.WARN,\n LogLevel.INFO,\n ];\n\n if (this.mode === 'silent') return silent.includes(level);\n if (this.mode === 'minimal') return minimal.includes(level);\n if (this.mode === 'normal') return normal.includes(level);\n return true; // verbose mode\n }\n\n private formatMessage(logMessage: LogMessage): string {\n const { level, message, timestamp, context } = logMessage;\n const color = this.levelColors[level];\n const bgColor = this.levelBgColors[level];\n const emoji = this.levelEmojis[level];\n \n const timestampStr = colors.gray + `[${timestamp}]` + colors.reset;\n // Use background color for level badge like Vitest\n const levelStr = colors.white + bgColor + ` ${level.toUpperCase()} ` + colors.reset;\n const emojiStr = emoji + ' ';\n const messageStr = colors.bright + message + colors.reset;\n \n const contextStr = context \n ? '\\n' + colors.dim + 'Context: ' + JSON.stringify(context, null, 2) + colors.reset\n : '';\n\n return `${timestampStr} ${levelStr} ${emojiStr}${messageStr}${contextStr}`;\n }\n\n private log(level: LogLevel, message: string, context?: Record<string, any>) {\n if (!this.shouldLog(level)) \n return; \n\n if (level == LogLevel.WARN || level == LogLevel.ERROR) {\n if (level == LogLevel.ERROR) {\n // alert me\n }\n // store in database\n }\n \n const logMessage: LogMessage = {\n level,\n message,\n timestamp: new Date().toISOString(),\n context\n };\n\n const formattedMessage = this.formatMessage(logMessage);\n\n switch (level) {\n case LogLevel.ERROR:\n console.error(formattedMessage);\n break;\n case LogLevel.WARN:\n console.warn(formattedMessage);\n break;\n case LogLevel.DEBUG:\n if (this.isDevelopment) {\n console.debug(formattedMessage);\n }\n break;\n default:\n console.log(formattedMessage);\n }\n }\n\n public info(message: string, context?: Record<string, any>) {\n this.log(LogLevel.INFO, message, context);\n }\n\n public warn(message: string, context?: Record<string, any>) {\n this.log(LogLevel.WARN, message, context);\n }\n\n public error(message: string, context?: Record<string, any>) {\n this.log(LogLevel.ERROR, message, context);\n }\n\n public debug(message: string, context?: Record<string, any>) {\n this.log(LogLevel.DEBUG, message, context);\n }\n}\n\nexport const logger = Logger.getInstance(); "],"names":[],"mappings":"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","debug_id":"3ad19480-6fd4-5009-abf4-d8f8caeb9a0e"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@studious-lms/server",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.47",
|
|
4
4
|
"description": "Backend server for Studious application",
|
|
5
5
|
"main": "dist/exportType.js",
|
|
6
6
|
"types": "dist/exportType.d.ts",
|
|
@@ -17,8 +17,12 @@
|
|
|
17
17
|
"start": "node dist/index.js",
|
|
18
18
|
"generate": "npx prisma generate",
|
|
19
19
|
"prepublishOnly": "npm run generate && npm run build",
|
|
20
|
-
"test": "
|
|
21
|
-
"
|
|
20
|
+
"test:pre": "NODE_ENV=test tsx scripts/test-pre-push.ts",
|
|
21
|
+
"test": "npm run test:pre && NODE_ENV=test vitest",
|
|
22
|
+
"test:run": "NODE_ENV=test vitest run",
|
|
23
|
+
"test:watch": "NODE_ENV=test vitest watch",
|
|
24
|
+
"test:coverage": "NODE_ENV=test vitest run --coverage",
|
|
25
|
+
"db:seed": "tsx src/seedDatabase.ts",
|
|
22
26
|
"sentry:sourcemaps": "sentry-cli sourcemaps inject --org studious-fp --project server ./dist && sentry-cli sourcemaps upload --org studious-fp --project server ./dist"
|
|
23
27
|
},
|
|
24
28
|
"dependencies": {
|
|
@@ -28,11 +32,15 @@
|
|
|
28
32
|
"@sentry/cli": "^2.58.2",
|
|
29
33
|
"@sentry/node": "^10.26.0",
|
|
30
34
|
"@trpc/server": "^11.4.3",
|
|
35
|
+
"@unkey/ratelimit": "^2.1.3",
|
|
31
36
|
"bcryptjs": "^3.0.2",
|
|
37
|
+
"compression": "^1.8.1",
|
|
32
38
|
"cors": "^2.8.5",
|
|
33
39
|
"date-fns": "^4.1.0",
|
|
34
40
|
"dotenv": "^16.5.0",
|
|
35
41
|
"express": "^4.18.3",
|
|
42
|
+
"express-rate-limit": "^8.2.1",
|
|
43
|
+
"helmet": "^8.1.0",
|
|
36
44
|
"nodemailer": "^7.0.4",
|
|
37
45
|
"openai": "^5.23.0",
|
|
38
46
|
"pdf-lib": "^1.17.1",
|
|
@@ -41,17 +49,18 @@
|
|
|
41
49
|
"sharp": "^0.34.2",
|
|
42
50
|
"socket.io": "^4.8.1",
|
|
43
51
|
"superjson": "^2.2.2",
|
|
44
|
-
"trpc-panel": "^1.3.4",
|
|
45
52
|
"uuid": "^11.1.0",
|
|
46
53
|
"zod": "^3.22.4"
|
|
47
54
|
},
|
|
48
55
|
"devDependencies": {
|
|
56
|
+
"@types/compression": "^1.8.1",
|
|
49
57
|
"@types/cors": "^2.8.17",
|
|
50
58
|
"@types/express": "^4.17.21",
|
|
51
59
|
"@types/node": "^20.11.24",
|
|
52
60
|
"@types/nodemailer": "^6.4.17",
|
|
53
61
|
"@types/supertest": "^6.0.3",
|
|
54
62
|
"@types/uuid": "^10.0.0",
|
|
63
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
55
64
|
"supertest": "^7.1.4",
|
|
56
65
|
"trpc-ui": "^1.0.15",
|
|
57
66
|
"ts-node": "^10.9.2",
|
package/prisma/schema.prisma
CHANGED
|
@@ -9,6 +9,11 @@ generator client {
|
|
|
9
9
|
// output = "../generated/prisma"
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
// @todo: add type safety to json fields.
|
|
13
|
+
// generator json {
|
|
14
|
+
// provider = "prisma-json-types-generator"
|
|
15
|
+
// }
|
|
16
|
+
|
|
12
17
|
datasource db {
|
|
13
18
|
provider = "postgresql"
|
|
14
19
|
url = env("DATABASE_URL")
|
|
@@ -42,6 +47,15 @@ enum UploadStatus {
|
|
|
42
47
|
CANCELLED
|
|
43
48
|
}
|
|
44
49
|
|
|
50
|
+
enum GenerationStatus {
|
|
51
|
+
NOT_STARTED
|
|
52
|
+
PENDING
|
|
53
|
+
GENERATING
|
|
54
|
+
COMPLETED
|
|
55
|
+
FAILED
|
|
56
|
+
CANCELLED
|
|
57
|
+
}
|
|
58
|
+
|
|
45
59
|
enum WorksheetQuestionType {
|
|
46
60
|
MULTIPLE_CHOICE
|
|
47
61
|
TRUE_FALSE
|
|
@@ -305,6 +319,7 @@ model Comment {
|
|
|
305
319
|
announcementId String?
|
|
306
320
|
parentComment Comment? @relation("CommentReplies", fields: [parentCommentId], references: [id], onDelete: Cascade)
|
|
307
321
|
parentCommentId String?
|
|
322
|
+
status GenerationStatus?
|
|
308
323
|
replies Comment[] @relation("CommentReplies")
|
|
309
324
|
reactions Reaction[]
|
|
310
325
|
createdAt DateTime @default(now())
|
|
@@ -345,7 +360,6 @@ model Submission {
|
|
|
345
360
|
annotations File[] @relation("SubmissionAnnotations")
|
|
346
361
|
worksheetResponses StudentWorksheetResponse[]
|
|
347
362
|
extendedResponse String?
|
|
348
|
-
|
|
349
363
|
gradeReceived Int?
|
|
350
364
|
|
|
351
365
|
rubricState String?
|
|
@@ -354,6 +368,18 @@ model Submission {
|
|
|
354
368
|
submittedAt DateTime?
|
|
355
369
|
submitted Boolean? @default(false)
|
|
356
370
|
returned Boolean? @default(false)
|
|
371
|
+
newtonTutors NewtonChat[]
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
model NewtonChat {
|
|
375
|
+
id String @id @default(uuid())
|
|
376
|
+
submissionId String
|
|
377
|
+
submission Submission @relation(fields: [submissionId], references: [id], onDelete: Cascade)
|
|
378
|
+
conversationId String @unique
|
|
379
|
+
conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
|
|
380
|
+
createdAt DateTime @default(now())
|
|
381
|
+
updatedAt DateTime @updatedAt
|
|
382
|
+
title String @default("Session with Newton Tutor")
|
|
357
383
|
}
|
|
358
384
|
|
|
359
385
|
model Section {
|
|
@@ -441,6 +467,7 @@ model Conversation {
|
|
|
441
467
|
members ConversationMember[]
|
|
442
468
|
messages Message[]
|
|
443
469
|
labChat LabChat?
|
|
470
|
+
newtonChat NewtonChat?
|
|
444
471
|
}
|
|
445
472
|
|
|
446
473
|
model LabChat {
|
|
@@ -451,8 +478,7 @@ model LabChat {
|
|
|
451
478
|
conversationId String @unique
|
|
452
479
|
createdById String // Teacher who created the lab
|
|
453
480
|
createdAt DateTime @default(now())
|
|
454
|
-
updatedAt DateTime @updatedAt
|
|
455
|
-
|
|
481
|
+
updatedAt DateTime @updatedAt
|
|
456
482
|
class Class @relation("ClassLabChats", fields: [classId], references: [id], onDelete: Cascade)
|
|
457
483
|
conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
|
|
458
484
|
createdBy User @relation("CreatedLabChats", fields: [createdById], references: [id], onDelete: NoAction)
|
|
@@ -479,11 +505,13 @@ model Message {
|
|
|
479
505
|
senderId String
|
|
480
506
|
conversationId String
|
|
481
507
|
createdAt DateTime @default(now())
|
|
482
|
-
|
|
508
|
+
status GenerationStatus? @default(NOT_STARTED)
|
|
483
509
|
sender User @relation("SentMessages", fields: [senderId], references: [id], onDelete: Cascade)
|
|
484
510
|
conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
|
|
485
511
|
mentions Mention[]
|
|
486
512
|
attachments File[] @relation("MessageAttachments")
|
|
513
|
+
|
|
514
|
+
meta Json? @default("{}")
|
|
487
515
|
}
|
|
488
516
|
|
|
489
517
|
model Mention {
|
|
@@ -557,6 +585,7 @@ model StudentQuestionProgress {
|
|
|
557
585
|
updatedAt DateTime? @updatedAt
|
|
558
586
|
studentWorksheetResponseId String?
|
|
559
587
|
studentWorksheetResponse StudentWorksheetResponse? @relation(fields: [studentWorksheetResponseId], references: [id], onDelete: Cascade)
|
|
588
|
+
status GenerationStatus? @default(NOT_STARTED)
|
|
560
589
|
|
|
561
590
|
@@index([studentId, questionId])
|
|
562
591
|
}
|
|
@@ -582,7 +611,7 @@ model SchoolDevelopementProgram {
|
|
|
582
611
|
submittedAt DateTime? @default(now())
|
|
583
612
|
reviewedAt DateTime?
|
|
584
613
|
|
|
585
|
-
status String @default("
|
|
614
|
+
status String @default("NOT_STARTED") // NOT_STARTED, PENDING, APPROVED, REJECTED, REFERRED
|
|
586
615
|
|
|
587
616
|
supportingDocumentation File[] @relation("SchoolDevelopementProgramSupportingDocumentation")
|
|
588
617
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import { logger } from '../src/utils/logger';
|
|
3
|
+
import dotenv from 'dotenv';
|
|
4
|
+
import { resolve } from 'path';
|
|
5
|
+
|
|
6
|
+
dotenv.config({ path: resolve(process.cwd(), '.env.test') });
|
|
7
|
+
|
|
8
|
+
logger.info("Syncing Prisma schema to test database...");
|
|
9
|
+
|
|
10
|
+
execSync("npx prisma db push --force-reset --skip-generate", {
|
|
11
|
+
stdio: 'inherit',
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
logger.info("Test database is ready!");
|