@thanh01.pmt/interactive-quiz-kit 1.0.66 → 1.0.68
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/HEADLESS.md +1 -1
- package/README.md +2 -2
- package/dist/{ai-ecosystem-DqFRlFU3.d.cts → ai-ecosystem-DyQYZbyX.d.cts} +3 -3
- package/dist/{ai-ecosystem-DqVlSO3r.d.ts → ai-ecosystem-Qa_SdE2T.d.ts} +3 -3
- package/dist/ai.cjs +60 -96
- package/dist/ai.d.cts +127 -127
- package/dist/ai.d.ts +127 -127
- package/dist/ai.mjs +60 -96
- package/dist/authoring.cjs +1499 -1260
- package/dist/authoring.d.cts +4 -4
- package/dist/authoring.d.ts +4 -4
- package/dist/authoring.mjs +1231 -993
- package/dist/index.cjs +22 -37
- package/dist/index.d.cts +24 -27
- package/dist/index.d.ts +24 -27
- package/dist/index.mjs +22 -37
- package/dist/player.cjs +9 -9
- package/dist/player.d.cts +1 -1
- package/dist/player.d.ts +1 -1
- package/dist/player.mjs +9 -9
- package/dist/{quiz-config-o4j2dfsu.d.cts → quiz-config-CwaP-pBs.d.cts} +1 -1
- package/dist/{quiz-config-o4j2dfsu.d.ts → quiz-config-CwaP-pBs.d.ts} +1 -1
- package/dist/react-ui.cjs +467 -244
- package/dist/react-ui.d.cts +6 -6
- package/dist/react-ui.d.ts +6 -6
- package/dist/react-ui.mjs +467 -245
- package/dist/{toaster-CKS4zoRY.d.cts → toaster-BVaUJA6E.d.ts} +65 -45
- package/dist/{toaster-DLJ_2W9u.d.ts → toaster-BWaJj0l-.d.cts} +65 -45
- package/package.json +1 -1
package/HEADLESS.md
CHANGED
|
@@ -179,7 +179,7 @@ async function createAIQuestion() {
|
|
|
179
179
|
console.log('Generating a Multiple Choice question about the Solar System...');
|
|
180
180
|
const result = await generateMCQQuestion({
|
|
181
181
|
topic: 'The Solar System',
|
|
182
|
-
difficulty: '
|
|
182
|
+
difficulty: 'Easy',
|
|
183
183
|
language: 'English'
|
|
184
184
|
}, 'YOUR_API_KEY');
|
|
185
185
|
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
**Interactive Quiz Kit** is a comprehensive TypeScript library built with React, designed to effortlessly create, manage, play, and distribute interactive quizzes. It provides a robust core logic (`QuizEngine`), reusable React UI components, and support for a wide variety of question types.
|
|
7
7
|
|
|
8
|
-
The library is architected for
|
|
8
|
+
The library is architected for Easy extension and integration, featuring a powerful authoring tool, AI-powered content generation (using Google's Genkit and Gemini), and SCORM packaging for seamless LMS integration.
|
|
9
9
|
|
|
10
10
|
## ✨ Features
|
|
11
11
|
|
|
@@ -167,7 +167,7 @@ async function createNewQuestion() {
|
|
|
167
167
|
try {
|
|
168
168
|
const { question } = await generateTrueFalseQuestion({
|
|
169
169
|
topic: "The history of the internet",
|
|
170
|
-
difficulty: "
|
|
170
|
+
difficulty: "Medium"
|
|
171
171
|
});
|
|
172
172
|
|
|
173
173
|
if (question) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { R as RichContentString, Q as QuestionTypeStrings, s as QuizConfig } from './quiz-config-
|
|
1
|
+
import { R as RichContentString, Q as QuestionTypeStrings, s as QuizConfig } from './quiz-config-CwaP-pBs.cjs';
|
|
2
2
|
|
|
3
3
|
interface TestCaseResult {
|
|
4
4
|
testCaseId: string;
|
|
@@ -103,7 +103,7 @@ interface Achievement {
|
|
|
103
103
|
}
|
|
104
104
|
type PracticeDifficulty = 'Very Easy' | 'Easy' | 'Medium' | 'Hard' | 'Expert';
|
|
105
105
|
interface PracticeSuggestionTopic {
|
|
106
|
-
|
|
106
|
+
code: string;
|
|
107
107
|
topicName: string;
|
|
108
108
|
reason: 'review' | 'explore';
|
|
109
109
|
suggestedDifficulty?: PracticeDifficulty;
|
|
@@ -175,7 +175,7 @@ interface RoadmapItem {
|
|
|
175
175
|
topicName: string;
|
|
176
176
|
reason: string;
|
|
177
177
|
suggestedDifficulty: PracticeDifficulty;
|
|
178
|
-
|
|
178
|
+
code: string;
|
|
179
179
|
isCompleted: boolean;
|
|
180
180
|
}
|
|
181
181
|
interface WeeklyRoadmap {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { R as RichContentString, Q as QuestionTypeStrings, s as QuizConfig } from './quiz-config-
|
|
1
|
+
import { R as RichContentString, Q as QuestionTypeStrings, s as QuizConfig } from './quiz-config-CwaP-pBs.js';
|
|
2
2
|
|
|
3
3
|
interface TestCaseResult {
|
|
4
4
|
testCaseId: string;
|
|
@@ -103,7 +103,7 @@ interface Achievement {
|
|
|
103
103
|
}
|
|
104
104
|
type PracticeDifficulty = 'Very Easy' | 'Easy' | 'Medium' | 'Hard' | 'Expert';
|
|
105
105
|
interface PracticeSuggestionTopic {
|
|
106
|
-
|
|
106
|
+
code: string;
|
|
107
107
|
topicName: string;
|
|
108
108
|
reason: 'review' | 'explore';
|
|
109
109
|
suggestedDifficulty?: PracticeDifficulty;
|
|
@@ -175,7 +175,7 @@ interface RoadmapItem {
|
|
|
175
175
|
topicName: string;
|
|
176
176
|
reason: string;
|
|
177
177
|
suggestedDifficulty: PracticeDifficulty;
|
|
178
|
-
|
|
178
|
+
code: string;
|
|
179
179
|
isCompleted: boolean;
|
|
180
180
|
}
|
|
181
181
|
interface WeeklyRoadmap {
|
package/dist/ai.cjs
CHANGED
|
@@ -94,12 +94,12 @@ var QuizContextSchema = zod.z.object({
|
|
|
94
94
|
originalSubject: zod.z.string().optional(),
|
|
95
95
|
originalCategory: zod.z.string().optional(),
|
|
96
96
|
originalTopic: zod.z.string().optional(),
|
|
97
|
-
|
|
97
|
+
description: zod.z.string().optional().describe("The full description of the learning objective for deep context."),
|
|
98
98
|
gradeBand: zod.z.string().optional()
|
|
99
99
|
});
|
|
100
100
|
var BaseQuestionGenerationClientInputSchema = zod.z.object({
|
|
101
101
|
language: zod.z.string().optional().default("English"),
|
|
102
|
-
difficulty: zod.z.enum(["
|
|
102
|
+
difficulty: zod.z.enum(["Easy", "Medium", "Hard"]),
|
|
103
103
|
quizContext: QuizContextSchema.optional(),
|
|
104
104
|
imageUrl: zod.z.string().url().optional().describe("Optional URL of an image to be used as context.")
|
|
105
105
|
});
|
|
@@ -108,7 +108,7 @@ var BaseQuestionZodSchema = zod.z.object({
|
|
|
108
108
|
prompt: zod.z.string().min(1),
|
|
109
109
|
points: zod.z.number().min(0).optional(),
|
|
110
110
|
explanation: zod.z.string().optional(),
|
|
111
|
-
difficulty: zod.z.enum(["
|
|
111
|
+
difficulty: zod.z.enum(["Easy", "Medium", "Hard"]).optional(),
|
|
112
112
|
topic: zod.z.string().optional(),
|
|
113
113
|
category: zod.z.string().optional(),
|
|
114
114
|
subject: zod.z.string().optional(),
|
|
@@ -204,7 +204,7 @@ var AITrueFalseOutputFieldsSchema = zod.z.object({
|
|
|
204
204
|
correctAnswer: zod.z.boolean(),
|
|
205
205
|
explanation: zod.z.string().optional().describe("An explanation of why the statement is true or false, especially important if false."),
|
|
206
206
|
points: zod.z.number().optional().default(10),
|
|
207
|
-
difficulty: zod.z.enum(["
|
|
207
|
+
difficulty: zod.z.enum(["Easy", "Medium", "Hard"]).optional(),
|
|
208
208
|
topic: zod.z.string().optional(),
|
|
209
209
|
verifiedCategory: zod.z.string().optional()
|
|
210
210
|
// Thêm để xác thực
|
|
@@ -225,7 +225,7 @@ Previous attempts failed. Ensure the JSON is valid and 'correctAnswer' is a bool
|
|
|
225
225
|
const misconceptionGuidance = quizContext?.targetMisconception ? `**Target Misconception:** The statement you create MUST be FALSE and based on this common mistake: "${quizContext.targetMisconception}"` : "";
|
|
226
226
|
const contextStrings = [
|
|
227
227
|
`**Required Category:** ${category}`,
|
|
228
|
-
quizContext?.
|
|
228
|
+
quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
|
|
229
229
|
imageContextInstruction,
|
|
230
230
|
quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
|
|
231
231
|
misconceptionGuidance,
|
|
@@ -236,7 +236,7 @@ Previous attempts failed. Ensure the JSON is valid and 'correctAnswer' is a bool
|
|
|
236
236
|
correctAnswer: true,
|
|
237
237
|
explanation: "Optional values in Swift represent the presence or absence of a value. To access the value when it exists, you must unwrap it using methods like 'if let', 'guard let', or the force unwrap operator '!'.",
|
|
238
238
|
points: 10,
|
|
239
|
-
difficulty: "
|
|
239
|
+
difficulty: "Easy",
|
|
240
240
|
topic: "Swift Optionals",
|
|
241
241
|
verifiedCategory: category
|
|
242
242
|
}, null, 2);
|
|
@@ -366,7 +366,7 @@ var AIMCQOutputFieldsSchema = zod.z.object({
|
|
|
366
366
|
correctTempOptionId: zod.z.string().describe("The temporary ID of the correct option from the generated options array."),
|
|
367
367
|
explanation: zod.z.string().optional().describe("A brief explanation of why the answer is correct."),
|
|
368
368
|
points: zod.z.number().optional().default(10),
|
|
369
|
-
difficulty: zod.z.enum(["
|
|
369
|
+
difficulty: zod.z.enum(["Easy", "Medium", "Hard"]).optional(),
|
|
370
370
|
topic: zod.z.string().optional(),
|
|
371
371
|
verifiedCategory: zod.z.string().optional().describe("The category this question actually addresses.")
|
|
372
372
|
});
|
|
@@ -385,7 +385,7 @@ Previous attempts failed...
|
|
|
385
385
|
const imageContextInstruction = imageUrl ? `**Image Context:** You MUST analyze the provided image. The question and options must be directly related to the content of this image.` : "";
|
|
386
386
|
const contextStrings = [
|
|
387
387
|
`**Required Category:** ${category}`,
|
|
388
|
-
quizContext?.
|
|
388
|
+
quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
|
|
389
389
|
imageContextInstruction,
|
|
390
390
|
quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
|
|
391
391
|
quizContext?.targetMisconception && `**Target Misconception:** Use this to create plausible incorrect answers: "${quizContext.targetMisconception}"`,
|
|
@@ -402,7 +402,7 @@ Previous attempts failed...
|
|
|
402
402
|
correctTempOptionId: "C",
|
|
403
403
|
explanation: `The 'guard' statement in ${category} provides an early exit from a scope (like a function) if a condition is false, enhancing code readability by handling required conditions upfront.`,
|
|
404
404
|
points: 10,
|
|
405
|
-
difficulty: "
|
|
405
|
+
difficulty: "Easy",
|
|
406
406
|
topic: `Control Flow in ${category}`,
|
|
407
407
|
verifiedCategory: category
|
|
408
408
|
}, null, 2);
|
|
@@ -544,7 +544,7 @@ var AIMRQOutputFieldsSchema = zod.z.object({
|
|
|
544
544
|
correctTempOptionIds: zod.z.array(zod.z.string()).min(1),
|
|
545
545
|
explanation: zod.z.string().optional(),
|
|
546
546
|
points: zod.z.number().optional().default(10),
|
|
547
|
-
difficulty: zod.z.enum(["
|
|
547
|
+
difficulty: zod.z.enum(["Easy", "Medium", "Hard"]).optional(),
|
|
548
548
|
topic: zod.z.string().optional(),
|
|
549
549
|
verifiedCategory: zod.z.string().optional().describe("The category this question actually addresses.")
|
|
550
550
|
});
|
|
@@ -563,7 +563,7 @@ Previous attempts failed due to validation errors. Pay close attention to the nu
|
|
|
563
563
|
const imageContextInstruction = imageUrl ? `**Image Context:** You MUST analyze the provided image. The question and options must be directly related to the content of this image.` : "";
|
|
564
564
|
const contextStrings = [
|
|
565
565
|
`**Required Category:** ${category} (This is the ONLY language to be used)`,
|
|
566
|
-
quizContext?.
|
|
566
|
+
quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
|
|
567
567
|
imageContextInstruction,
|
|
568
568
|
quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
|
|
569
569
|
quizContext?.targetMisconception && `**Target Misconception:** Use this to create plausible incorrect answers (distractors). The misconception is: "${quizContext.targetMisconception}"`,
|
|
@@ -581,7 +581,7 @@ Previous attempts failed due to validation errors. Pay close attention to the nu
|
|
|
581
581
|
correctTempOptionIds: ["A", "C", "D"],
|
|
582
582
|
explanation: "Object-Oriented, Functional, and Procedural are all major programming paradigms. Assembly is a low-level language, and Middleware is a type of software, not a paradigm.",
|
|
583
583
|
points: 10,
|
|
584
|
-
difficulty: "
|
|
584
|
+
difficulty: "Medium",
|
|
585
585
|
topic: "Programming Paradigms",
|
|
586
586
|
verifiedCategory: category
|
|
587
587
|
}, null, 2);
|
|
@@ -739,7 +739,7 @@ var AIShortAnswerOutputFieldsSchema = zod.z.object({
|
|
|
739
739
|
// isCaseSensitive không cần thiết ở đây, chúng ta sẽ quản lý nó ở phía client
|
|
740
740
|
explanation: zod.z.string().optional(),
|
|
741
741
|
points: zod.z.number().optional().default(10),
|
|
742
|
-
difficulty: zod.z.enum(["
|
|
742
|
+
difficulty: zod.z.enum(["Easy", "Medium", "Hard"]).optional(),
|
|
743
743
|
topic: zod.z.string().optional(),
|
|
744
744
|
verifiedCategory: zod.z.string().optional()
|
|
745
745
|
// Thêm để xác thực
|
|
@@ -759,7 +759,7 @@ Previous attempts failed. Ensure 'acceptedAnswers' is a non-empty array of strin
|
|
|
759
759
|
const imageContextInstruction = imageUrl ? `**Image Context:** You MUST analyze the provided image. The question and its short answer must be directly related to the content of this image.` : "";
|
|
760
760
|
const contextStrings = [
|
|
761
761
|
`**Required Category:** ${category}`,
|
|
762
|
-
quizContext?.
|
|
762
|
+
quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
|
|
763
763
|
imageContextInstruction,
|
|
764
764
|
quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
|
|
765
765
|
quizContext?.targetMisconception && `**Target Misconception:** The question should require an answer that corrects this specific misconception: "${quizContext.targetMisconception}"`
|
|
@@ -769,7 +769,7 @@ Previous attempts failed. Ensure 'acceptedAnswers' is a non-empty array of strin
|
|
|
769
769
|
acceptedAnswers: ["let"],
|
|
770
770
|
explanation: "The 'let' keyword is used to declare constants, which are values that cannot be changed after they are set. 'var' is used for variables.",
|
|
771
771
|
points: 10,
|
|
772
|
-
difficulty: "
|
|
772
|
+
difficulty: "Easy",
|
|
773
773
|
topic: "Swift Constants",
|
|
774
774
|
verifiedCategory: category
|
|
775
775
|
}, null, 2);
|
|
@@ -896,7 +896,7 @@ var AINumericOutputFieldsSchema = zod.z.object({
|
|
|
896
896
|
tolerance: zod.z.number().min(0).optional(),
|
|
897
897
|
explanation: zod.z.string().optional(),
|
|
898
898
|
points: zod.z.number().optional().default(10),
|
|
899
|
-
difficulty: zod.z.enum(["
|
|
899
|
+
difficulty: zod.z.enum(["Easy", "Medium", "Hard"]).optional(),
|
|
900
900
|
topic: zod.z.string().optional(),
|
|
901
901
|
verifiedCategory: zod.z.string().optional()
|
|
902
902
|
// Thêm để xác thực
|
|
@@ -916,7 +916,7 @@ Previous attempts failed. Ensure the 'answer' is a valid number and fits within
|
|
|
916
916
|
const imageContextInstruction = imageUrl ? `**Image Context:** You MUST analyze the provided image. The question and its numerical answer must be directly related to the content of this image.` : "";
|
|
917
917
|
const contextStrings = [
|
|
918
918
|
`**Required Category:** ${category}`,
|
|
919
|
-
quizContext?.
|
|
919
|
+
quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
|
|
920
920
|
imageContextInstruction,
|
|
921
921
|
quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
|
|
922
922
|
quizContext?.targetMisconception && `**Target Misconception:** The question should clarify this numerical error: "${quizContext.targetMisconception}"`
|
|
@@ -932,7 +932,7 @@ Previous attempts failed. Ensure the 'answer' is a valid number and fits within
|
|
|
932
932
|
tolerance: 0,
|
|
933
933
|
explanation: "An Int8 uses 8 bits. One bit is for the sign, leaving 7 bits for the value. The range is from -128 to 127 (2^7 - 1).",
|
|
934
934
|
points: 10,
|
|
935
|
-
difficulty: "
|
|
935
|
+
difficulty: "Medium",
|
|
936
936
|
topic: "Swift Data Types",
|
|
937
937
|
verifiedCategory: category
|
|
938
938
|
}, null, 2);
|
|
@@ -1076,7 +1076,7 @@ var AIFillInTheBlanksOutputFieldsSchema = zod.z.object({
|
|
|
1076
1076
|
})).min(1).describe("An array of text and blank segments representing the question."),
|
|
1077
1077
|
explanation: zod.z.string().optional(),
|
|
1078
1078
|
points: zod.z.number().optional().default(10),
|
|
1079
|
-
difficulty: zod.z.enum(["
|
|
1079
|
+
difficulty: zod.z.enum(["Easy", "Medium", "Hard"]).optional(),
|
|
1080
1080
|
topic: zod.z.string().optional(),
|
|
1081
1081
|
verifiedCategory: zod.z.string().optional()
|
|
1082
1082
|
// Thêm để xác thực
|
|
@@ -1096,7 +1096,7 @@ Previous attempts failed. Pay strict attention to the JSON schema, especially th
|
|
|
1096
1096
|
const imageContextInstruction = imageUrl ? `**Image Context:** You MUST analyze the provided image. The question and blanks must be directly related to the content of this image.` : "";
|
|
1097
1097
|
const contextStrings = [
|
|
1098
1098
|
`**Required Category:** ${category}`,
|
|
1099
|
-
quizContext?.
|
|
1099
|
+
quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
|
|
1100
1100
|
imageContextInstruction,
|
|
1101
1101
|
quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
|
|
1102
1102
|
quizContext?.targetMisconception && `**Target Misconception:** Design the blank to test this specific point: "${quizContext.targetMisconception}"`
|
|
@@ -1110,7 +1110,7 @@ Previous attempts failed. Pay strict attention to the JSON schema, especially th
|
|
|
1110
1110
|
],
|
|
1111
1111
|
explanation: "The 'func' keyword is used to declare a function in the Swift programming language.",
|
|
1112
1112
|
points: 10,
|
|
1113
|
-
difficulty: "
|
|
1113
|
+
difficulty: "Easy",
|
|
1114
1114
|
topic: "Swift Function Declaration",
|
|
1115
1115
|
verifiedCategory: category
|
|
1116
1116
|
}, null, 2);
|
|
@@ -1258,7 +1258,7 @@ var AISequenceOutputFieldsSchema = zod.z.object({
|
|
|
1258
1258
|
itemsInCorrectOrder: zod.z.array(zod.z.string().min(1)).min(2).describe("An array of strings, with each string representing an item to be sequenced. The array itself MUST be in the correct final order."),
|
|
1259
1259
|
explanation: zod.z.string().optional(),
|
|
1260
1260
|
points: zod.z.number().optional().default(10),
|
|
1261
|
-
difficulty: zod.z.enum(["
|
|
1261
|
+
difficulty: zod.z.enum(["Easy", "Medium", "Hard"]).optional(),
|
|
1262
1262
|
topic: zod.z.string().optional(),
|
|
1263
1263
|
verifiedCategory: zod.z.string().optional()
|
|
1264
1264
|
// Thêm để xác thực
|
|
@@ -1278,7 +1278,7 @@ Previous attempts failed. Ensure the 'itemsInCorrectOrder' array has exactly the
|
|
|
1278
1278
|
const imageContextInstruction = imageUrl ? `**Image Context:** You MUST analyze the provided image. The sequence of items must be directly related to the process or content shown in this image.` : "";
|
|
1279
1279
|
const contextStrings = [
|
|
1280
1280
|
`**Required Category:** ${category}`,
|
|
1281
|
-
quizContext?.
|
|
1281
|
+
quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
|
|
1282
1282
|
imageContextInstruction,
|
|
1283
1283
|
quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
|
|
1284
1284
|
quizContext?.targetMisconception && `**Target Misconception:** The sequence should clarify this specific process error: "${quizContext.targetMisconception}"`
|
|
@@ -1293,7 +1293,7 @@ Previous attempts failed. Ensure the 'itemsInCorrectOrder' array has exactly the
|
|
|
1293
1293
|
],
|
|
1294
1294
|
explanation: "This is the fundamental sequence for a basic data task in URLSession.",
|
|
1295
1295
|
points: 10,
|
|
1296
|
-
difficulty: "
|
|
1296
|
+
difficulty: "Medium",
|
|
1297
1297
|
topic: "Swift Networking",
|
|
1298
1298
|
verifiedCategory: category
|
|
1299
1299
|
}, null, 2);
|
|
@@ -1429,7 +1429,7 @@ var AIMatchingOutputFieldsSchema = zod.z.object({
|
|
|
1429
1429
|
})).min(2),
|
|
1430
1430
|
explanation: zod.z.string().optional(),
|
|
1431
1431
|
points: zod.z.number().optional().default(10),
|
|
1432
|
-
difficulty: zod.z.enum(["
|
|
1432
|
+
difficulty: zod.z.enum(["Easy", "Medium", "Hard"]).optional(),
|
|
1433
1433
|
topic: zod.z.string().optional(),
|
|
1434
1434
|
verifiedCategory: zod.z.string().optional()
|
|
1435
1435
|
// Thêm để xác thực
|
|
@@ -1449,7 +1449,7 @@ Previous attempts failed. Please ensure the 'correctPairs' array has exactly the
|
|
|
1449
1449
|
const imageContextInstruction = imageUrl ? `**Image Context:** You MUST analyze the provided image. The matching pairs must be directly related to the content of this image.` : "";
|
|
1450
1450
|
const contextStrings = [
|
|
1451
1451
|
`**Required Category:** ${category}`,
|
|
1452
|
-
quizContext?.
|
|
1452
|
+
quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
|
|
1453
1453
|
imageContextInstruction,
|
|
1454
1454
|
quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
|
|
1455
1455
|
quizContext?.targetMisconception && `**Target Misconception:** Design a pair that specifically tests this confusion: "${quizContext.targetMisconception}"`
|
|
@@ -1463,7 +1463,7 @@ Previous attempts failed. Please ensure the 'correctPairs' array has exactly the
|
|
|
1463
1463
|
],
|
|
1464
1464
|
explanation: "These are the fundamental characteristics of Swift's main collection types.",
|
|
1465
1465
|
points: 10,
|
|
1466
|
-
difficulty: "
|
|
1466
|
+
difficulty: "Easy",
|
|
1467
1467
|
topic: "Swift Collection Types",
|
|
1468
1468
|
verifiedCategory: category
|
|
1469
1469
|
}, null, 2);
|
|
@@ -1624,7 +1624,7 @@ Previous attempts failed. Pay strict attention to the JSON schema and all rules.
|
|
|
1624
1624
|
const imageContextInstruction = imageUrl ? `**Image Context:** You MUST analyze the provided image. The coding problem must be directly related to processing or interpreting the content of this image.` : "";
|
|
1625
1625
|
const contextStrings = [
|
|
1626
1626
|
`**Subject:** ${subject}`,
|
|
1627
|
-
quizContext?.
|
|
1627
|
+
quizContext?.description && `**Learning Objective:** ${quizContext.description}`,
|
|
1628
1628
|
imageContextInstruction,
|
|
1629
1629
|
quizContext?.plannedBloomLevel && `**Cognitive Level (Bloom's):** ${quizContext.plannedBloomLevel}`,
|
|
1630
1630
|
quizContext?.targetMisconception && `**Target Misconception:** The problem should test against this common error: "${quizContext.targetMisconception}"`
|
|
@@ -2496,10 +2496,6 @@ function validateConsecutiveTypes(quizPlan) {
|
|
|
2496
2496
|
|
|
2497
2497
|
// src/services/TopicDataService.ts
|
|
2498
2498
|
var TopicDataService = class {
|
|
2499
|
-
/**
|
|
2500
|
-
* Saves an array of LearningObjective objects to Local Storage, overwriting existing data.
|
|
2501
|
-
* @param data The array of learning objectives to save.
|
|
2502
|
-
*/
|
|
2503
2499
|
static saveData(data) {
|
|
2504
2500
|
try {
|
|
2505
2501
|
if (typeof window === "undefined") return;
|
|
@@ -2509,24 +2505,15 @@ var TopicDataService = class {
|
|
|
2509
2505
|
console.error("Error saving learning objectives to Local Storage:", error);
|
|
2510
2506
|
}
|
|
2511
2507
|
}
|
|
2512
|
-
/**
|
|
2513
|
-
* Merges a new set of learning objectives with the existing data in Local Storage.
|
|
2514
|
-
* If an LO ID from newData already exists, it will be updated. Otherwise, it will be added.
|
|
2515
|
-
* @param newData The array of new or updated learning objectives.
|
|
2516
|
-
*/
|
|
2517
2508
|
static mergeData(newData) {
|
|
2518
2509
|
const existingData = this.getData();
|
|
2519
|
-
const loMap = new Map(existingData.map((lo) => [lo.
|
|
2510
|
+
const loMap = new Map(existingData.map((lo) => [lo.code, lo]));
|
|
2520
2511
|
newData.forEach((newLo) => {
|
|
2521
|
-
loMap.set(newLo.
|
|
2512
|
+
loMap.set(newLo.code, newLo);
|
|
2522
2513
|
});
|
|
2523
2514
|
const mergedData = Array.from(loMap.values());
|
|
2524
2515
|
this.saveData(mergedData);
|
|
2525
2516
|
}
|
|
2526
|
-
/**
|
|
2527
|
-
* Retrieves the array of LearningObjective objects from Local Storage.
|
|
2528
|
-
* @returns An array of learning objectives, or an empty array if none are found or an error occurs.
|
|
2529
|
-
*/
|
|
2530
2517
|
static getData() {
|
|
2531
2518
|
try {
|
|
2532
2519
|
if (typeof window === "undefined") return [];
|
|
@@ -2538,9 +2525,6 @@ var TopicDataService = class {
|
|
|
2538
2525
|
return [];
|
|
2539
2526
|
}
|
|
2540
2527
|
}
|
|
2541
|
-
/**
|
|
2542
|
-
* Removes all learning objective data from Local Storage.
|
|
2543
|
-
*/
|
|
2544
2528
|
static clearData() {
|
|
2545
2529
|
try {
|
|
2546
2530
|
if (typeof window === "undefined") return;
|
|
@@ -2549,11 +2533,6 @@ var TopicDataService = class {
|
|
|
2549
2533
|
console.error("Error clearing learning objectives from Local Storage:", error);
|
|
2550
2534
|
}
|
|
2551
2535
|
}
|
|
2552
|
-
/**
|
|
2553
|
-
* Parses TSV content into an array of LearningObjective objects.
|
|
2554
|
-
* @param tsvContent The raw string content from a .tsv file.
|
|
2555
|
-
* @returns An object containing the successfully parsed data and any errors encountered.
|
|
2556
|
-
*/
|
|
2557
2536
|
static parseTSV(tsvContent) {
|
|
2558
2537
|
const lines = tsvContent.split("\n").filter((line) => line.trim() !== "");
|
|
2559
2538
|
if (lines.length < 2) {
|
|
@@ -2575,6 +2554,7 @@ var TopicDataService = class {
|
|
|
2575
2554
|
}
|
|
2576
2555
|
const [
|
|
2577
2556
|
loId,
|
|
2557
|
+
name,
|
|
2578
2558
|
loDescription,
|
|
2579
2559
|
subject,
|
|
2580
2560
|
category,
|
|
@@ -2584,18 +2564,21 @@ var TopicDataService = class {
|
|
|
2584
2564
|
stemElementsStr,
|
|
2585
2565
|
bloomLevelsStr
|
|
2586
2566
|
] = values;
|
|
2587
|
-
if (!loId || !subject || !category || !topic) {
|
|
2588
|
-
errors.push(`Line ${index + 2}: Missing required fields (LO ID, Subject, Category, or Topic).`);
|
|
2567
|
+
if (!loId || !loDescription || !subject || !category || !topic) {
|
|
2568
|
+
errors.push(`Line ${index + 2}: Missing required fields (LO ID, LO Description, Subject, Category, or Topic).`);
|
|
2589
2569
|
return;
|
|
2590
2570
|
}
|
|
2591
2571
|
const learningObjective = {
|
|
2592
|
-
|
|
2593
|
-
|
|
2572
|
+
id: generateUniqueId("lo_"),
|
|
2573
|
+
code: loId,
|
|
2574
|
+
name,
|
|
2575
|
+
description: loDescription,
|
|
2576
|
+
// Can be the same as name or enhanced later
|
|
2594
2577
|
subject,
|
|
2595
2578
|
category,
|
|
2596
2579
|
topic,
|
|
2597
|
-
keywords: keywordsStr.split(",").map((k) => k.trim()).filter(Boolean),
|
|
2598
2580
|
grade,
|
|
2581
|
+
keywords: keywordsStr.split(",").map((k) => k.trim()).filter(Boolean),
|
|
2599
2582
|
stemElements: stemElementsStr.split(",").map((s) => s.trim()).filter(Boolean),
|
|
2600
2583
|
bloomLevelsGuideline: bloomLevelsStr.split(",").map((b) => b.trim()).filter(Boolean)
|
|
2601
2584
|
};
|
|
@@ -2603,40 +2586,21 @@ var TopicDataService = class {
|
|
|
2603
2586
|
});
|
|
2604
2587
|
return { data, errors };
|
|
2605
2588
|
}
|
|
2606
|
-
/**
|
|
2607
|
-
* Gets a unique list of all subjects from the stored data.
|
|
2608
|
-
* @returns An array of subject strings.
|
|
2609
|
-
*/
|
|
2610
2589
|
static getSubjects() {
|
|
2611
2590
|
const data = this.getData();
|
|
2612
2591
|
const subjects = data.map((item) => item.subject);
|
|
2613
2592
|
return [...new Set(subjects)].sort();
|
|
2614
2593
|
}
|
|
2615
|
-
/**
|
|
2616
|
-
* Gets a unique list of categories for a given subject.
|
|
2617
|
-
* @param subject The subject to filter by.
|
|
2618
|
-
* @returns An array of category strings.
|
|
2619
|
-
*/
|
|
2620
2594
|
static getCategoriesBySubject(subject) {
|
|
2621
2595
|
const data = this.getData();
|
|
2622
2596
|
const categories = data.filter((item) => item.subject === subject).map((item) => item.category);
|
|
2623
2597
|
return [...new Set(categories)].sort();
|
|
2624
2598
|
}
|
|
2625
|
-
/**
|
|
2626
|
-
* Gets a unique list of topics for a given category.
|
|
2627
|
-
* @param category The category to filter by.
|
|
2628
|
-
* @returns An array of topic strings.
|
|
2629
|
-
*/
|
|
2630
2599
|
static getTopicsByCategory(category) {
|
|
2631
2600
|
const data = this.getData();
|
|
2632
2601
|
const topics = data.filter((item) => item.category === category).map((item) => item.topic);
|
|
2633
2602
|
return [...new Set(topics)].sort();
|
|
2634
2603
|
}
|
|
2635
|
-
/**
|
|
2636
|
-
* Retrieves all LearningObjective details for a given list of topics.
|
|
2637
|
-
* @param topics An array of topic strings to search for.
|
|
2638
|
-
* @returns An array of matching LearningObjective objects.
|
|
2639
|
-
*/
|
|
2640
2604
|
static getLearningObjectivesByTopics(topics) {
|
|
2641
2605
|
const data = this.getData();
|
|
2642
2606
|
const topicSet = new Set(topics);
|
|
@@ -2684,9 +2648,9 @@ var calculateCombinedDifficulty = (plannedQ) => {
|
|
|
2684
2648
|
break;
|
|
2685
2649
|
}
|
|
2686
2650
|
const totalScore = bloomScore + contextScore + questionTypeScore;
|
|
2687
|
-
if (totalScore <= 4) return "
|
|
2688
|
-
if (totalScore <= 7) return "
|
|
2689
|
-
return "
|
|
2651
|
+
if (totalScore <= 4) return "Easy";
|
|
2652
|
+
if (totalScore <= 7) return "Medium";
|
|
2653
|
+
return "Hard";
|
|
2690
2654
|
};
|
|
2691
2655
|
async function generateQuestionsFromQuizPlan(clientInput, apiKey) {
|
|
2692
2656
|
const { quizPlan, language, imageContexts } = clientInput;
|
|
@@ -2699,7 +2663,7 @@ async function generateQuestionsFromQuizPlan(clientInput, apiKey) {
|
|
|
2699
2663
|
let lastError = null;
|
|
2700
2664
|
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
|
|
2701
2665
|
try {
|
|
2702
|
-
const fullLO = plannedQ.originalLoId ? allLearningObjectives.find((lo) => lo.
|
|
2666
|
+
const fullLO = plannedQ.originalLoId ? allLearningObjectives.find((lo) => lo.code === plannedQ.originalLoId) : null;
|
|
2703
2667
|
const quizContext = {
|
|
2704
2668
|
plannedTopic: plannedQ.plannedTopic,
|
|
2705
2669
|
plannedQuestionType: plannedQ.plannedQuestionType,
|
|
@@ -2712,7 +2676,7 @@ async function generateQuestionsFromQuizPlan(clientInput, apiKey) {
|
|
|
2712
2676
|
originalSubject: plannedQ.originalSubject,
|
|
2713
2677
|
originalCategory: plannedQ.originalCategory,
|
|
2714
2678
|
originalTopic: plannedQ.originalTopic,
|
|
2715
|
-
|
|
2679
|
+
description: fullLO?.description || plannedQ.plannedTopic
|
|
2716
2680
|
};
|
|
2717
2681
|
const imageUrl = plannedQ.imageId && imageContexts ? imageContexts.find((ctx) => ctx.id === plannedQ.imageId)?.imageUrl : void 0;
|
|
2718
2682
|
const baseClientInput = {
|
|
@@ -2901,7 +2865,7 @@ zod.z.object({
|
|
|
2901
2865
|
}))
|
|
2902
2866
|
})).optional(),
|
|
2903
2867
|
allAvailableTopics: zod.z.array(zod.z.object({
|
|
2904
|
-
|
|
2868
|
+
code: zod.z.string(),
|
|
2905
2869
|
subject: zod.z.string(),
|
|
2906
2870
|
category: zod.z.string(),
|
|
2907
2871
|
topic: zod.z.string()
|
|
@@ -2910,7 +2874,7 @@ zod.z.object({
|
|
|
2910
2874
|
var PracticeSuggestionOutputSchema = zod.z.object({
|
|
2911
2875
|
suggestionText: zod.z.string().describe("The personalized message from the AI tutor in Markdown format."),
|
|
2912
2876
|
suggestedTopics: zod.z.array(zod.z.object({
|
|
2913
|
-
|
|
2877
|
+
code: zod.z.string(),
|
|
2914
2878
|
topicName: zod.z.string(),
|
|
2915
2879
|
reason: zod.z.enum(["review", "explore"]),
|
|
2916
2880
|
suggestedDifficulty: zod.z.enum(["Very Easy", "Easy", "Medium", "Hard", "Expert"])
|
|
@@ -2951,8 +2915,8 @@ Return a single, valid JSON object in this exact format. All text must be in ${l
|
|
|
2951
2915
|
{
|
|
2952
2916
|
"suggestionText": "Ch\xE0o ${userName || "b\u1EA1n"}, t\xF4i \u0111\xE3 xem qua k\u1EBFt qu\u1EA3 c\u1EE7a b\u1EA1n! \u0110\u1EC3 c\u1EE7ng c\u1ED1 ki\u1EBFn th\u1EE9c, ch\xFAng ta h\xE3y \xF4n l\u1EA1i ch\u1EE7 \u0111\u1EC1 [T\xEAn ch\u1EE7 \u0111\u1EC1 y\u1EBFu] \u1EDF m\u1EE9c \u0111\u1ED9 'Easy' nh\xE9. V\xEC b\u1EA1n \u0111\xE3 l\xE0m r\u1EA5t t\u1ED1t ph\u1EA7n [T\xEAn ch\u1EE7 \u0111\u1EC1 m\u1EA1nh], h\xE3y th\u1EED s\u1EE9c v\u1EDBi ch\u1EE7 \u0111\u1EC1 li\xEAn quan l\xE0 [T\xEAn ch\u1EE7 \u0111\u1EC1 kh\xE1m ph\xE1] \u1EDF m\u1EE9c \u0111\u1ED9 'Medium' xem sao!",
|
|
2953
2917
|
"suggestedTopics": [
|
|
2954
|
-
{ "
|
|
2955
|
-
{ "
|
|
2918
|
+
{ "code": "some-lo-id-1", "topicName": "[T\xEAn ch\u1EE7 \u0111\u1EC1 y\u1EBFu]", "reason": "review", "suggestedDifficulty": "Easy" },
|
|
2919
|
+
{ "code": "some-lo-id-2", "topicName": "[T\xEAn ch\u1EE7 \u0111\u1EC1 kh\xE1m ph\xE1]", "reason": "explore", "suggestedDifficulty": "Medium" }
|
|
2956
2920
|
]
|
|
2957
2921
|
}
|
|
2958
2922
|
|
|
@@ -2997,7 +2961,7 @@ zod.z.object({
|
|
|
2997
2961
|
startDate: zod.z.string().describe("The start date for the analysis period in ISO format (YYYY-MM-DD)."),
|
|
2998
2962
|
endDate: zod.z.string().describe("The end date for the analysis period in ISO format (YYYY-MM-DD)."),
|
|
2999
2963
|
allAvailableTopics: zod.z.array(zod.z.object({
|
|
3000
|
-
|
|
2964
|
+
code: zod.z.string(),
|
|
3001
2965
|
subject: zod.z.string(),
|
|
3002
2966
|
category: zod.z.string(),
|
|
3003
2967
|
topic: zod.z.string()
|
|
@@ -3008,7 +2972,7 @@ var RoadmapItemSchema = zod.z.object({
|
|
|
3008
2972
|
topicName: zod.z.string(),
|
|
3009
2973
|
reason: zod.z.string(),
|
|
3010
2974
|
suggestedDifficulty: zod.z.enum(["Very Easy", "Easy", "Medium", "Hard", "Expert"]),
|
|
3011
|
-
|
|
2975
|
+
code: zod.z.string(),
|
|
3012
2976
|
isCompleted: zod.z.boolean()
|
|
3013
2977
|
});
|
|
3014
2978
|
var WeeklyRoadmapSchema = zod.z.object({
|
|
@@ -3073,7 +3037,7 @@ All topic names and loIds in your "weeklyRoadmap" output MUST be chosen directly
|
|
|
3073
3037
|
- **gamificationRemarks**: Write an encouraging message mentioning their achievements.
|
|
3074
3038
|
2. **For "weeklyRoadmap":**
|
|
3075
3039
|
- Create a 5-item roadmap for the upcoming week.
|
|
3076
|
-
- Prioritize the "areasForImprovement" you identified. For each, find the corresponding entry in "All Available Topics" and use its "topicName" and "
|
|
3040
|
+
- Prioritize the "areasForImprovement" you identified. For each, find the corresponding entry in "All Available Topics" and use its "topicName" and "code".
|
|
3077
3041
|
- If more items are needed, select related topics from "All Available Topics".
|
|
3078
3042
|
|
|
3079
3043
|
**IF Practice History IS EMPTY:**
|
|
@@ -3084,7 +3048,7 @@ All topic names and loIds in your "weeklyRoadmap" output MUST be chosen directly
|
|
|
3084
3048
|
- **gamificationRemarks**: Write a general motivational message about starting to learn.
|
|
3085
3049
|
2. **For "weeklyRoadmap":**
|
|
3086
3050
|
- Create a 5-item "starter" roadmap.
|
|
3087
|
-
- Select 5 diverse and foundational topics directly from the "All Available Topics" list. Use their exact "topicName" and "
|
|
3051
|
+
- Select 5 diverse and foundational topics directly from the "All Available Topics" list. Use their exact "topicName" and "code".
|
|
3088
3052
|
- For the "reason", explain that this is a good starting point to explore the subject.
|
|
3089
3053
|
|
|
3090
3054
|
--- END LOGIC FLOW ---
|
|
@@ -3112,7 +3076,7 @@ The 'suggestedDifficulty' field MUST ALWAYS be one of these exact English string
|
|
|
3112
3076
|
"topicName": "Topic C",
|
|
3113
3077
|
"reason": "To strengthen your understanding of this key area.",
|
|
3114
3078
|
"suggestedDifficulty": "Easy",
|
|
3115
|
-
"
|
|
3079
|
+
"code": "lo-id-for-topic-c-from-the-list",
|
|
3116
3080
|
"isCompleted": false
|
|
3117
3081
|
}
|
|
3118
3082
|
]
|
|
@@ -3350,11 +3314,11 @@ Now, generate the JSON for the requested knowledge card.`;
|
|
|
3350
3314
|
}
|
|
3351
3315
|
}
|
|
3352
3316
|
var LearningObjectiveContextSchema = zod.z.object({
|
|
3353
|
-
|
|
3317
|
+
code: zod.z.string(),
|
|
3354
3318
|
subject: zod.z.string(),
|
|
3355
3319
|
category: zod.z.string(),
|
|
3356
3320
|
topic: zod.z.string(),
|
|
3357
|
-
|
|
3321
|
+
description: zod.z.string()
|
|
3358
3322
|
});
|
|
3359
3323
|
zod.z.object({
|
|
3360
3324
|
language: zod.z.string().default("English"),
|
|
@@ -3362,7 +3326,7 @@ zod.z.object({
|
|
|
3362
3326
|
learningObjectives: zod.z.array(LearningObjectiveContextSchema).min(1, { message: "At least one learning objective is required for mapping." })
|
|
3363
3327
|
});
|
|
3364
3328
|
var MappedLOSchema = zod.z.object({
|
|
3365
|
-
|
|
3329
|
+
code: zod.z.string().describe("The exact code from the provided learning objectives list that matches the document content."),
|
|
3366
3330
|
confidence: zod.z.number().min(0).max(100).describe("A confidence score (0-100) of how well the document maps to this LO."),
|
|
3367
3331
|
reasoning: zod.z.string().describe("A brief explanation for why this mapping is relevant.")
|
|
3368
3332
|
});
|
|
@@ -3398,7 +3362,7 @@ You are an expert curriculum analyst. Your task is to analyze a given document a
|
|
|
3398
3362
|
1. **Overall Relevance Assessment:** Read the document content and compare it against the entire list of LOs. Assign an overall "relevanceScore" from 0 (completely unrelated) to 100 (perfectly aligned with one or more LOs).
|
|
3399
3363
|
|
|
3400
3364
|
2. **Specific Mapping:** Identify which specific LOs from the list are directly addressed by the document. For each match you find, provide:
|
|
3401
|
-
- The exact "
|
|
3365
|
+
- The exact "code" of the matched LO.
|
|
3402
3366
|
- A "confidence" score (0-100) for that specific match.
|
|
3403
3367
|
- A brief "reasoning" in ${language} explaining why the document content maps to that LO.
|
|
3404
3368
|
|
|
@@ -3413,7 +3377,7 @@ Return a single, valid JSON object in this EXACT format. Do not include any othe
|
|
|
3413
3377
|
"isFreestyleRecommended": false,
|
|
3414
3378
|
"mappedLOs": [
|
|
3415
3379
|
{
|
|
3416
|
-
"
|
|
3380
|
+
"code": "SWIFT_FUNC_01",
|
|
3417
3381
|
"confidence": 95,
|
|
3418
3382
|
"reasoning": "The document provides a detailed explanation of function syntax and default parameters, which directly aligns with this learning objective."
|
|
3419
3383
|
}
|
|
@@ -3502,7 +3466,7 @@ Return the response as a single JSON object with a key "generatedQuestions" cont
|
|
|
3502
3466
|
"correctTempOptionId": "A",
|
|
3503
3467
|
"explanation": "The document states that mitochondria are the powerhouses of the cell, responsible for cellular respiration.",
|
|
3504
3468
|
"points": 10,
|
|
3505
|
-
"difficulty": "
|
|
3469
|
+
"difficulty": "Medium",
|
|
3506
3470
|
"topic": "Cell Biology"
|
|
3507
3471
|
},
|
|
3508
3472
|
{
|
|
@@ -3511,7 +3475,7 @@ Return the response as a single JSON object with a key "generatedQuestions" cont
|
|
|
3511
3475
|
"correctAnswer": false,
|
|
3512
3476
|
"explanation": "The text specifies that the cell wall is a feature of plant cells, not animal cells.",
|
|
3513
3477
|
"points": 10,
|
|
3514
|
-
"difficulty": "
|
|
3478
|
+
"difficulty": "Easy",
|
|
3515
3479
|
"topic": "Cell Biology"
|
|
3516
3480
|
}
|
|
3517
3481
|
]
|