@zhouchangui/math-ati 0.1.2 → 0.1.4

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 (35) hide show
  1. package/AGENTS.md +4 -1
  2. package/README.md +11 -0
  3. package/bin/math-ati.js +136 -5
  4. package/dist/assets/{index-CGZslJ0a.css → index-DOg8CQsE.css} +1 -1
  5. package/dist/assets/index-DyfeTKmg.js +22 -0
  6. package/dist/index.html +3 -3
  7. package/package.json +9 -5
  8. package/prompts/geometry-practice-experience.md +44 -0
  9. package/prompts/grading.system.md +3 -1
  10. package/prompts/knowledge-extract.system.md +35 -54
  11. package/prompts/knowledge-structure.system.md +75 -0
  12. package/prompts/knowledge-summarize.system.md +21 -7
  13. package/prompts/pdf-grading.system.md +4 -1
  14. package/prompts/pdf-recheck.system.md +2 -0
  15. package/prompts/practice-answers.system.md +154 -0
  16. package/prompts/practice-coverage-repair.system.md +112 -0
  17. package/prompts/practice-generate.system.md +51 -9
  18. package/prompts/practice-review.system.md +4 -2
  19. package/prompts/practice-revise.system.md +5 -4
  20. package/prompts/practice-rules.md +61 -0
  21. package/prompts/svg-figure-review.system.md +13 -0
  22. package/prompts/svg-figure-revise.system.md +21 -0
  23. package/server/agentClient.js +179 -10
  24. package/server/coveragePlanner.js +174 -0
  25. package/server/fileStore.js +49 -9
  26. package/server/index.js +78 -1
  27. package/server/knowledgeExtractor.js +717 -120
  28. package/server/knowledgeFeedback.js +69 -0
  29. package/server/practiceGenerator.js +637 -116
  30. package/server/practicePaperHtml.js +105 -35
  31. package/server/practiceService.js +27 -2
  32. package/server/promptStore.js +14 -0
  33. package/server/submissionService.js +1 -1
  34. package/server/svgFigureVerifier.js +315 -0
  35. package/dist/assets/index-CGfjl7nO.js +0 -22
@@ -295,5 +295,74 @@ export async function syncKnowledgeMasteryMarkers(chapterId) {
295
295
  const marker = `\n\n<!-- mastery-updated-at: ${new Date().toISOString()} -->\n`;
296
296
  await writeFile(docPath, `${currentMarkdown.replace(/\n\n<!-- mastery-updated-at: .*? -->\n?$/s, '').trim()}${marker}`, 'utf8');
297
297
  await syncGlobalIndexes();
298
+ await updateStudentLearningState();
298
299
  return chapterMastery;
299
300
  }
301
+
302
+ export async function updateStudentLearningState() {
303
+ const profile = await readJson(paths.profile, {});
304
+ const accuracyHistoryPath = path.join(paths.rootDir, 'data', 'global', '.accuracy_history.json');
305
+ let accuracyHistory = await readJson(accuracyHistoryPath, []);
306
+
307
+ // Collect accuracy from recent chapter mastery snapshots
308
+ const chapters = await readJson(paths.chapters, []);
309
+ let latestAccuracy = null;
310
+ for (const chapter of chapters) {
311
+ const chapterPaths = chapterDataPaths(chapter.id);
312
+ const chapterMastery = await readJson(chapterPaths.mastery, null);
313
+ if (!chapterMastery?.coverage) continue;
314
+ const { totalQuestions = 0, correctQuestions = 0 } = chapterMastery.coverage;
315
+ if (totalQuestions > 0) {
316
+ latestAccuracy = Math.round((correctQuestions / totalQuestions) * 100);
317
+ break;
318
+ }
319
+ }
320
+
321
+ if (latestAccuracy !== null) {
322
+ accuracyHistory.push({
323
+ date: new Date().toISOString(),
324
+ accuracy: latestAccuracy
325
+ });
326
+ // Keep last 10 entries
327
+ if (accuracyHistory.length > 10) {
328
+ accuracyHistory = accuracyHistory.slice(-10);
329
+ }
330
+ await writeJson(accuracyHistoryPath, accuracyHistory);
331
+ }
332
+
333
+ // Derive trend from last 3 entries
334
+ const recent = accuracyHistory.slice(-3);
335
+ let recentAccuracyTrend = 'stable';
336
+ if (recent.length >= 2) {
337
+ const first = recent[0].accuracy;
338
+ const last = recent[recent.length - 1].accuracy;
339
+ if (last >= first + 10) recentAccuracyTrend = 'improving';
340
+ else if (last <= first - 10) recentAccuracyTrend = 'declining';
341
+ }
342
+
343
+ // Update frustration topics based on mastery stats
344
+ const frustrationTopics = [];
345
+ const allMasteryPoints = [];
346
+ for (const chapter of chapters) {
347
+ const chapterPaths = chapterDataPaths(chapter.id);
348
+ const chapterMastery = await readJson(chapterPaths.mastery, null);
349
+ if (chapterMastery?.points) {
350
+ allMasteryPoints.push(...Object.values(chapterMastery.points));
351
+ }
352
+ }
353
+ for (const point of allMasteryPoints) {
354
+ if (point.status === 'needs_review' && (point.wrongCount || 0) >= 3) {
355
+ frustrationTopics.push(point.id);
356
+ }
357
+ }
358
+
359
+ const learningState = {
360
+ ...(profile.learningState || {}),
361
+ recentAccuracyTrend: recentAccuracyTrend || profile.learningState?.recentAccuracyTrend || 'stable',
362
+ frustrationTopics: frustrationTopics.slice(0, 5),
363
+ preferredPace: profile.learningState?.preferredPace || 'steady',
364
+ lastSessionFatigue: profile.learningState?.lastSessionFatigue || 'medium'
365
+ };
366
+
367
+ await writeJson(paths.profile, { ...profile, learningState, updatedAt: new Date().toISOString() });
368
+ }