learngraph 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/dist/cjs/api/routes/analytics.js +288 -0
  2. package/dist/cjs/api/routes/analytics.js.map +1 -0
  3. package/dist/cjs/api/routes/assessments.js +269 -0
  4. package/dist/cjs/api/routes/assessments.js.map +1 -0
  5. package/dist/cjs/api/routes/curriculum.js +345 -0
  6. package/dist/cjs/api/routes/curriculum.js.map +1 -0
  7. package/dist/cjs/api/routes/edges.js +162 -0
  8. package/dist/cjs/api/routes/edges.js.map +1 -0
  9. package/dist/cjs/api/routes/explore.js +224 -0
  10. package/dist/cjs/api/routes/explore.js.map +1 -0
  11. package/dist/cjs/api/routes/learners.js +324 -0
  12. package/dist/cjs/api/routes/learners.js.map +1 -0
  13. package/dist/cjs/api/routes/me.js +404 -0
  14. package/dist/cjs/api/routes/me.js.map +1 -0
  15. package/dist/cjs/api/routes/skills.js +319 -0
  16. package/dist/cjs/api/routes/skills.js.map +1 -0
  17. package/dist/cjs/api/server.js +185 -0
  18. package/dist/cjs/api/server.js.map +1 -0
  19. package/dist/cjs/api/types.js +10 -0
  20. package/dist/cjs/api/types.js.map +1 -0
  21. package/dist/cjs/assessment/adaptive.js +390 -0
  22. package/dist/cjs/assessment/adaptive.js.map +1 -0
  23. package/dist/cjs/assessment/bkt.js +362 -0
  24. package/dist/cjs/assessment/bkt.js.map +1 -0
  25. package/dist/cjs/assessment/index.js +54 -0
  26. package/dist/cjs/assessment/index.js.map +1 -0
  27. package/dist/cjs/assessment/irt.js +420 -0
  28. package/dist/cjs/assessment/irt.js.map +1 -0
  29. package/dist/cjs/assessment/mastery-engine.js +411 -0
  30. package/dist/cjs/assessment/mastery-engine.js.map +1 -0
  31. package/dist/cjs/components/LearningPathView.js +320 -0
  32. package/dist/cjs/components/LearningPathView.js.map +1 -0
  33. package/dist/cjs/components/ProgressDashboard.js +308 -0
  34. package/dist/cjs/components/ProgressDashboard.js.map +1 -0
  35. package/dist/cjs/components/SkillCard.js +264 -0
  36. package/dist/cjs/components/SkillCard.js.map +1 -0
  37. package/dist/cjs/components/SkillExplorer.js +401 -0
  38. package/dist/cjs/components/SkillExplorer.js.map +1 -0
  39. package/dist/cjs/components/SkillGraph.js +435 -0
  40. package/dist/cjs/components/SkillGraph.js.map +1 -0
  41. package/dist/cjs/components/hooks.js +510 -0
  42. package/dist/cjs/components/hooks.js.map +1 -0
  43. package/dist/cjs/components/index.js +77 -0
  44. package/dist/cjs/components/index.js.map +1 -0
  45. package/dist/cjs/components/types.js +34 -0
  46. package/dist/cjs/components/types.js.map +1 -0
  47. package/dist/cjs/index.js +35 -1
  48. package/dist/cjs/index.js.map +1 -1
  49. package/dist/cjs/llm/adapters/anthropic.js +91 -3
  50. package/dist/cjs/llm/adapters/anthropic.js.map +1 -1
  51. package/dist/cjs/llm/adapters/gemini.js +101 -8
  52. package/dist/cjs/llm/adapters/gemini.js.map +1 -1
  53. package/dist/cjs/llm/adapters/index.js +42 -1
  54. package/dist/cjs/llm/adapters/index.js.map +1 -1
  55. package/dist/cjs/llm/adapters/ollama.js +120 -3
  56. package/dist/cjs/llm/adapters/ollama.js.map +1 -1
  57. package/dist/cjs/llm/adapters/openai.js +108 -2
  58. package/dist/cjs/llm/adapters/openai.js.map +1 -1
  59. package/dist/cjs/mcp/cli.js +302 -0
  60. package/dist/cjs/mcp/cli.js.map +1 -0
  61. package/dist/cjs/mcp/index.js +79 -0
  62. package/dist/cjs/mcp/index.js.map +1 -0
  63. package/dist/cjs/mcp/prompts.js +425 -0
  64. package/dist/cjs/mcp/prompts.js.map +1 -0
  65. package/dist/cjs/mcp/resources.js +371 -0
  66. package/dist/cjs/mcp/resources.js.map +1 -0
  67. package/dist/cjs/mcp/server.js +410 -0
  68. package/dist/cjs/mcp/server.js.map +1 -0
  69. package/dist/cjs/mcp/tools.js +612 -0
  70. package/dist/cjs/mcp/tools.js.map +1 -0
  71. package/dist/cjs/mcp/types.js +10 -0
  72. package/dist/cjs/mcp/types.js.map +1 -0
  73. package/dist/cjs/types/assessment.js +46 -0
  74. package/dist/cjs/types/assessment.js.map +1 -0
  75. package/dist/cjs/types/bloom.js +12 -1
  76. package/dist/cjs/types/bloom.js.map +1 -1
  77. package/dist/cjs/types/index.js +7 -1
  78. package/dist/cjs/types/index.js.map +1 -1
  79. package/dist/esm/api/routes/analytics.js +285 -0
  80. package/dist/esm/api/routes/analytics.js.map +1 -0
  81. package/dist/esm/api/routes/assessments.js +266 -0
  82. package/dist/esm/api/routes/assessments.js.map +1 -0
  83. package/dist/esm/api/routes/curriculum.js +342 -0
  84. package/dist/esm/api/routes/curriculum.js.map +1 -0
  85. package/dist/esm/api/routes/edges.js +159 -0
  86. package/dist/esm/api/routes/edges.js.map +1 -0
  87. package/dist/esm/api/routes/explore.js +221 -0
  88. package/dist/esm/api/routes/explore.js.map +1 -0
  89. package/dist/esm/api/routes/learners.js +321 -0
  90. package/dist/esm/api/routes/learners.js.map +1 -0
  91. package/dist/esm/api/routes/me.js +401 -0
  92. package/dist/esm/api/routes/me.js.map +1 -0
  93. package/dist/esm/api/routes/skills.js +316 -0
  94. package/dist/esm/api/routes/skills.js.map +1 -0
  95. package/dist/esm/api/server.js +179 -0
  96. package/dist/esm/api/server.js.map +1 -0
  97. package/dist/esm/api/types.js +9 -0
  98. package/dist/esm/api/types.js.map +1 -0
  99. package/dist/esm/assessment/adaptive.js +384 -0
  100. package/dist/esm/assessment/adaptive.js.map +1 -0
  101. package/dist/esm/assessment/bkt.js +354 -0
  102. package/dist/esm/assessment/bkt.js.map +1 -0
  103. package/dist/esm/assessment/index.js +21 -0
  104. package/dist/esm/assessment/index.js.map +1 -0
  105. package/dist/esm/assessment/irt.js +406 -0
  106. package/dist/esm/assessment/irt.js.map +1 -0
  107. package/dist/esm/assessment/mastery-engine.js +406 -0
  108. package/dist/esm/assessment/mastery-engine.js.map +1 -0
  109. package/dist/esm/components/LearningPathView.js +316 -0
  110. package/dist/esm/components/LearningPathView.js.map +1 -0
  111. package/dist/esm/components/ProgressDashboard.js +304 -0
  112. package/dist/esm/components/ProgressDashboard.js.map +1 -0
  113. package/dist/esm/components/SkillCard.js +260 -0
  114. package/dist/esm/components/SkillCard.js.map +1 -0
  115. package/dist/esm/components/SkillExplorer.js +397 -0
  116. package/dist/esm/components/SkillExplorer.js.map +1 -0
  117. package/dist/esm/components/SkillGraph.js +398 -0
  118. package/dist/esm/components/SkillGraph.js.map +1 -0
  119. package/dist/esm/components/hooks.js +502 -0
  120. package/dist/esm/components/hooks.js.map +1 -0
  121. package/dist/esm/components/index.js +61 -0
  122. package/dist/esm/components/index.js.map +1 -0
  123. package/dist/esm/components/types.js +31 -0
  124. package/dist/esm/components/types.js.map +1 -0
  125. package/dist/esm/index.js +12 -0
  126. package/dist/esm/index.js.map +1 -1
  127. package/dist/esm/llm/adapters/anthropic.js +88 -2
  128. package/dist/esm/llm/adapters/anthropic.js.map +1 -1
  129. package/dist/esm/llm/adapters/gemini.js +98 -7
  130. package/dist/esm/llm/adapters/gemini.js.map +1 -1
  131. package/dist/esm/llm/adapters/index.js +15 -4
  132. package/dist/esm/llm/adapters/index.js.map +1 -1
  133. package/dist/esm/llm/adapters/ollama.js +117 -2
  134. package/dist/esm/llm/adapters/ollama.js.map +1 -1
  135. package/dist/esm/llm/adapters/openai.js +105 -1
  136. package/dist/esm/llm/adapters/openai.js.map +1 -1
  137. package/dist/esm/mcp/cli.js +267 -0
  138. package/dist/esm/mcp/cli.js.map +1 -0
  139. package/dist/esm/mcp/index.js +39 -0
  140. package/dist/esm/mcp/index.js.map +1 -0
  141. package/dist/esm/mcp/prompts.js +419 -0
  142. package/dist/esm/mcp/prompts.js.map +1 -0
  143. package/dist/esm/mcp/resources.js +359 -0
  144. package/dist/esm/mcp/resources.js.map +1 -0
  145. package/dist/esm/mcp/server.js +372 -0
  146. package/dist/esm/mcp/server.js.map +1 -0
  147. package/dist/esm/mcp/tools.js +598 -0
  148. package/dist/esm/mcp/tools.js.map +1 -0
  149. package/dist/esm/mcp/types.js +9 -0
  150. package/dist/esm/mcp/types.js.map +1 -0
  151. package/dist/esm/types/assessment.js +40 -0
  152. package/dist/esm/types/assessment.js.map +1 -0
  153. package/dist/esm/types/bloom.js +11 -0
  154. package/dist/esm/types/bloom.js.map +1 -1
  155. package/dist/esm/types/index.js +2 -1
  156. package/dist/esm/types/index.js.map +1 -1
  157. package/dist/types/api/routes/analytics.d.ts +14 -0
  158. package/dist/types/api/routes/analytics.d.ts.map +1 -0
  159. package/dist/types/api/routes/assessments.d.ts +14 -0
  160. package/dist/types/api/routes/assessments.d.ts.map +1 -0
  161. package/dist/types/api/routes/curriculum.d.ts +14 -0
  162. package/dist/types/api/routes/curriculum.d.ts.map +1 -0
  163. package/dist/types/api/routes/edges.d.ts +14 -0
  164. package/dist/types/api/routes/edges.d.ts.map +1 -0
  165. package/dist/types/api/routes/explore.d.ts +14 -0
  166. package/dist/types/api/routes/explore.d.ts.map +1 -0
  167. package/dist/types/api/routes/learners.d.ts +14 -0
  168. package/dist/types/api/routes/learners.d.ts.map +1 -0
  169. package/dist/types/api/routes/me.d.ts +14 -0
  170. package/dist/types/api/routes/me.d.ts.map +1 -0
  171. package/dist/types/api/routes/skills.d.ts +14 -0
  172. package/dist/types/api/routes/skills.d.ts.map +1 -0
  173. package/dist/types/api/server.d.ts +147 -0
  174. package/dist/types/api/server.d.ts.map +1 -0
  175. package/dist/types/api/types.d.ts +443 -0
  176. package/dist/types/api/types.d.ts.map +1 -0
  177. package/dist/types/assessment/adaptive.d.ts +155 -0
  178. package/dist/types/assessment/adaptive.d.ts.map +1 -0
  179. package/dist/types/assessment/bkt.d.ts +185 -0
  180. package/dist/types/assessment/bkt.d.ts.map +1 -0
  181. package/dist/types/assessment/index.d.ts +18 -0
  182. package/dist/types/assessment/index.d.ts.map +1 -0
  183. package/dist/types/assessment/irt.d.ts +159 -0
  184. package/dist/types/assessment/irt.d.ts.map +1 -0
  185. package/dist/types/assessment/mastery-engine.d.ts +178 -0
  186. package/dist/types/assessment/mastery-engine.d.ts.map +1 -0
  187. package/dist/types/components/LearningPathView.d.ts +40 -0
  188. package/dist/types/components/LearningPathView.d.ts.map +1 -0
  189. package/dist/types/components/ProgressDashboard.d.ts +49 -0
  190. package/dist/types/components/ProgressDashboard.d.ts.map +1 -0
  191. package/dist/types/components/SkillCard.d.ts +34 -0
  192. package/dist/types/components/SkillCard.d.ts.map +1 -0
  193. package/dist/types/components/SkillExplorer.d.ts +39 -0
  194. package/dist/types/components/SkillExplorer.d.ts.map +1 -0
  195. package/dist/types/components/SkillGraph.d.ts +38 -0
  196. package/dist/types/components/SkillGraph.d.ts.map +1 -0
  197. package/dist/types/components/hooks.d.ts +187 -0
  198. package/dist/types/components/hooks.d.ts.map +1 -0
  199. package/dist/types/components/index.d.ts +59 -0
  200. package/dist/types/components/index.d.ts.map +1 -0
  201. package/dist/types/components/types.d.ts +410 -0
  202. package/dist/types/components/types.d.ts.map +1 -0
  203. package/dist/types/index.d.ts +1 -0
  204. package/dist/types/index.d.ts.map +1 -1
  205. package/dist/types/llm/adapters/anthropic.d.ts +84 -1
  206. package/dist/types/llm/adapters/anthropic.d.ts.map +1 -1
  207. package/dist/types/llm/adapters/gemini.d.ts +93 -6
  208. package/dist/types/llm/adapters/gemini.d.ts.map +1 -1
  209. package/dist/types/llm/adapters/index.d.ts +13 -4
  210. package/dist/types/llm/adapters/index.d.ts.map +1 -1
  211. package/dist/types/llm/adapters/ollama.d.ts +126 -1
  212. package/dist/types/llm/adapters/ollama.d.ts.map +1 -1
  213. package/dist/types/llm/adapters/openai.d.ts +104 -1
  214. package/dist/types/llm/adapters/openai.d.ts.map +1 -1
  215. package/dist/types/mcp/cli.d.ts +15 -0
  216. package/dist/types/mcp/cli.d.ts.map +1 -0
  217. package/dist/types/mcp/index.d.ts +32 -0
  218. package/dist/types/mcp/index.d.ts.map +1 -0
  219. package/dist/types/mcp/prompts.d.ts +27 -0
  220. package/dist/types/mcp/prompts.d.ts.map +1 -0
  221. package/dist/types/mcp/resources.d.ts +59 -0
  222. package/dist/types/mcp/resources.d.ts.map +1 -0
  223. package/dist/types/mcp/server.d.ts +136 -0
  224. package/dist/types/mcp/server.d.ts.map +1 -0
  225. package/dist/types/mcp/tools.d.ts +344 -0
  226. package/dist/types/mcp/tools.d.ts.map +1 -0
  227. package/dist/types/mcp/types.d.ts +137 -0
  228. package/dist/types/mcp/types.d.ts.map +1 -0
  229. package/dist/types/types/assessment.d.ts +512 -0
  230. package/dist/types/types/assessment.d.ts.map +1 -0
  231. package/dist/types/types/bloom.d.ts +4 -0
  232. package/dist/types/types/bloom.d.ts.map +1 -1
  233. package/dist/types/types/index.d.ts +3 -1
  234. package/dist/types/types/index.d.ts.map +1 -1
  235. package/package.json +48 -3
@@ -0,0 +1,406 @@
1
+ /**
2
+ * Mastery Estimation Engine
3
+ *
4
+ * Unified engine for estimating and tracking learner mastery.
5
+ * Combines multiple evidence sources:
6
+ * - Bayesian Knowledge Tracing (BKT) for skill-level mastery
7
+ * - Item Response Theory (IRT) for ability estimation
8
+ * - Response patterns for confidence calibration
9
+ * - Time-based decay for forgetting
10
+ *
11
+ * @packageDocumentation
12
+ */
13
+ import { createBKTEngine } from './bkt.js';
14
+ import { createIRTEstimator } from './irt.js';
15
+ /**
16
+ * Default engine configuration
17
+ */
18
+ export const MASTERY_ENGINE_DEFAULTS = {
19
+ useBKT: true,
20
+ useIRT: true,
21
+ applyForgetting: true,
22
+ forgettingRate: 0.05, // 5% decay per day
23
+ masteryThreshold: 0.8,
24
+ bktParams: {
25
+ pInit: 0.3,
26
+ pLearn: 0.1,
27
+ pSlip: 0.1,
28
+ pGuess: 0.2,
29
+ },
30
+ evidenceWeights: {
31
+ assessment: 1.0,
32
+ practice: 0.8,
33
+ observation: 0.7,
34
+ 'self-report': 0.3,
35
+ project: 0.9,
36
+ portfolio: 0.8,
37
+ 'peer-review': 0.5,
38
+ automated: 0.6,
39
+ },
40
+ };
41
+ /**
42
+ * Mastery Estimation Engine
43
+ *
44
+ * Provides a unified interface for tracking learner mastery across skills.
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const engine = new MasteryEngine();
49
+ *
50
+ * // Initialize a learner profile
51
+ * const profile = engine.createProfile('learner-1');
52
+ *
53
+ * // Record a response
54
+ * const updated = engine.recordResponse(profile, 'skill-1', true);
55
+ * console.log(`Mastery: ${engine.getMastery(updated, 'skill-1')}`);
56
+ *
57
+ * // Check if skill is mastered
58
+ * console.log(`Mastered: ${engine.isMastered(updated, 'skill-1')}`);
59
+ * ```
60
+ */
61
+ export class MasteryEngine {
62
+ config;
63
+ bktEngine;
64
+ irtEstimator;
65
+ constructor(config = {}) {
66
+ this.config = { ...MASTERY_ENGINE_DEFAULTS, ...config };
67
+ this.bktEngine = createBKTEngine({ masteryThreshold: this.config.masteryThreshold }, this.config.bktParams);
68
+ this.irtEstimator = createIRTEstimator();
69
+ }
70
+ /**
71
+ * Create a new learner profile
72
+ */
73
+ createProfile(learnerId) {
74
+ return {
75
+ learnerId,
76
+ bktStates: new Map(),
77
+ masteryLevels: new Map(),
78
+ evidence: new Map(),
79
+ responseHistory: [],
80
+ lastActivity: new Date(),
81
+ updateHistory: [],
82
+ };
83
+ }
84
+ /**
85
+ * Get or initialize BKT state for a skill
86
+ */
87
+ getOrCreateBKTState(profile, skillId) {
88
+ let state = profile.bktStates.get(skillId);
89
+ if (!state) {
90
+ state = this.bktEngine.initializeState(skillId);
91
+ profile.bktStates.set(skillId, state);
92
+ }
93
+ return state;
94
+ }
95
+ /**
96
+ * Record a learner response and update mastery
97
+ */
98
+ recordResponse(profile, skillId, correct, responseTime, itemParams) {
99
+ const now = new Date();
100
+ const previousMastery = this.getMastery(profile, skillId);
101
+ // Update BKT
102
+ if (this.config.useBKT) {
103
+ const currentState = this.getOrCreateBKTState(profile, skillId);
104
+ const { state: newState } = this.bktEngine.update(currentState, correct);
105
+ profile.bktStates.set(skillId, newState);
106
+ }
107
+ // Record response
108
+ const response = {
109
+ skillId,
110
+ correct,
111
+ timestamp: now,
112
+ ...(responseTime !== undefined && { responseTimeMs: responseTime }),
113
+ };
114
+ profile.responseHistory.push(response);
115
+ // Calculate new mastery
116
+ const newMastery = this.calculateMastery(profile, skillId);
117
+ profile.masteryLevels.set(skillId, newMastery);
118
+ // Update IRT ability if item params provided
119
+ if (this.config.useIRT && itemParams) {
120
+ this.updateAbility(profile);
121
+ }
122
+ // Record update
123
+ const update = {
124
+ skillId,
125
+ previousMastery,
126
+ newMastery,
127
+ delta: newMastery - previousMastery,
128
+ reason: 'response',
129
+ timestamp: now,
130
+ };
131
+ profile.updateHistory.push(update);
132
+ profile.lastActivity = now;
133
+ return profile;
134
+ }
135
+ /**
136
+ * Record multiple responses at once
137
+ */
138
+ recordResponses(profile, responses) {
139
+ let currentProfile = profile;
140
+ for (const response of responses) {
141
+ currentProfile = this.recordResponse(currentProfile, response.skillId, response.correct, response.responseTime);
142
+ }
143
+ return currentProfile;
144
+ }
145
+ /**
146
+ * Add learning evidence
147
+ */
148
+ addEvidence(profile, evidence) {
149
+ const existing = profile.evidence.get(evidence.skillId) ?? [];
150
+ existing.push(evidence);
151
+ profile.evidence.set(evidence.skillId, existing);
152
+ // Recalculate mastery with new evidence
153
+ const previousMastery = this.getMastery(profile, evidence.skillId);
154
+ const newMastery = this.calculateMastery(profile, evidence.skillId);
155
+ profile.masteryLevels.set(evidence.skillId, newMastery);
156
+ // Record update
157
+ const update = {
158
+ skillId: evidence.skillId,
159
+ previousMastery,
160
+ newMastery,
161
+ delta: newMastery - previousMastery,
162
+ reason: 'evidence',
163
+ timestamp: new Date(),
164
+ };
165
+ profile.updateHistory.push(update);
166
+ profile.lastActivity = new Date();
167
+ return profile;
168
+ }
169
+ /**
170
+ * Get current mastery level for a skill
171
+ */
172
+ getMastery(profile, skillId) {
173
+ // Check cached level
174
+ const cached = profile.masteryLevels.get(skillId);
175
+ if (cached !== undefined) {
176
+ // Apply forgetting if needed
177
+ if (this.config.applyForgetting) {
178
+ return this.applyForgetting(cached, profile.lastActivity);
179
+ }
180
+ return cached;
181
+ }
182
+ // Calculate fresh
183
+ return this.calculateMastery(profile, skillId);
184
+ }
185
+ /**
186
+ * Get mastery for multiple skills
187
+ */
188
+ getMasteryMap(profile, skillIds) {
189
+ const result = new Map();
190
+ for (const skillId of skillIds) {
191
+ result.set(skillId, this.getMastery(profile, skillId));
192
+ }
193
+ return result;
194
+ }
195
+ /**
196
+ * Check if a skill is mastered
197
+ */
198
+ isMastered(profile, skillId) {
199
+ return this.getMastery(profile, skillId) >= this.config.masteryThreshold;
200
+ }
201
+ /**
202
+ * Get skills that are mastered
203
+ */
204
+ getMasteredSkills(profile) {
205
+ const mastered = [];
206
+ for (const [skillId] of profile.masteryLevels) {
207
+ if (this.isMastered(profile, skillId)) {
208
+ mastered.push(skillId);
209
+ }
210
+ }
211
+ return mastered;
212
+ }
213
+ /**
214
+ * Calculate mastery combining all evidence sources
215
+ */
216
+ calculateMastery(profile, skillId) {
217
+ let mastery = 0;
218
+ let totalWeight = 0;
219
+ // BKT mastery
220
+ if (this.config.useBKT) {
221
+ const bktState = profile.bktStates.get(skillId);
222
+ if (bktState && bktState.observations > 0) {
223
+ mastery += bktState.pMastery * 1.0;
224
+ totalWeight += 1.0;
225
+ }
226
+ }
227
+ // Evidence-based mastery
228
+ const skillEvidence = profile.evidence.get(skillId) ?? [];
229
+ for (const evidence of skillEvidence) {
230
+ const weight = this.config.evidenceWeights[evidence.source] ?? 0.5;
231
+ mastery += evidence.masteryLevel * weight * evidence.confidence;
232
+ totalWeight += weight * evidence.confidence;
233
+ }
234
+ if (totalWeight === 0) {
235
+ return 0; // No data
236
+ }
237
+ let finalMastery = mastery / totalWeight;
238
+ // Apply forgetting
239
+ if (this.config.applyForgetting) {
240
+ finalMastery = this.applyForgetting(finalMastery, profile.lastActivity);
241
+ }
242
+ return Math.max(0, Math.min(1, finalMastery));
243
+ }
244
+ /**
245
+ * Apply time-based forgetting
246
+ */
247
+ applyForgetting(mastery, lastActivity) {
248
+ const now = new Date();
249
+ const daysSinceActivity = (now.getTime() - lastActivity.getTime()) / (1000 * 60 * 60 * 24);
250
+ if (daysSinceActivity <= 0) {
251
+ return mastery;
252
+ }
253
+ // Exponential decay
254
+ const decayFactor = Math.exp(-this.config.forgettingRate * daysSinceActivity);
255
+ return mastery * decayFactor;
256
+ }
257
+ /**
258
+ * Update IRT ability estimate
259
+ */
260
+ updateAbility(profile) {
261
+ // Collect all responses with IRT params
262
+ const irtResponses = [];
263
+ // We'd need to track IRT params per response
264
+ // For now, skip if not available
265
+ if (irtResponses.length > 0) {
266
+ const estimate = this.irtEstimator.estimate(irtResponses);
267
+ profile.abilityEstimate = estimate.theta;
268
+ }
269
+ }
270
+ /**
271
+ * Reset mastery for a skill
272
+ */
273
+ resetMastery(profile, skillId) {
274
+ const previousMastery = this.getMastery(profile, skillId);
275
+ profile.bktStates.delete(skillId);
276
+ profile.masteryLevels.set(skillId, 0);
277
+ const update = {
278
+ skillId,
279
+ previousMastery,
280
+ newMastery: 0,
281
+ delta: -previousMastery,
282
+ reason: 'reset',
283
+ timestamp: new Date(),
284
+ };
285
+ profile.updateHistory.push(update);
286
+ return profile;
287
+ }
288
+ /**
289
+ * Get evidence summary for a skill
290
+ */
291
+ getEvidenceSummary(profile, skillId) {
292
+ const evidence = profile.evidence.get(skillId);
293
+ if (!evidence || evidence.length === 0) {
294
+ return null;
295
+ }
296
+ const bySource = {};
297
+ let totalMastery = 0;
298
+ let totalWeight = 0;
299
+ for (const e of evidence) {
300
+ bySource[e.source] = (bySource[e.source] ?? 0) + 1;
301
+ const weight = this.config.evidenceWeights[e.source] ?? 0.5;
302
+ totalMastery += e.masteryLevel * weight;
303
+ totalWeight += weight;
304
+ }
305
+ // Sort by timestamp to find latest
306
+ const sorted = [...evidence].sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
307
+ const latest = sorted[0];
308
+ // Determine trend
309
+ let trend = 'stable';
310
+ if (sorted.length >= 3) {
311
+ const recent = sorted.slice(0, 3);
312
+ const older = sorted.slice(3, 6);
313
+ if (older.length > 0) {
314
+ const recentAvg = recent.reduce((s, e) => s + e.masteryLevel, 0) / recent.length;
315
+ const olderAvg = older.reduce((s, e) => s + e.masteryLevel, 0) / older.length;
316
+ if (recentAvg > olderAvg + 0.1) {
317
+ trend = 'improving';
318
+ }
319
+ else if (recentAvg < olderAvg - 0.1) {
320
+ trend = 'declining';
321
+ }
322
+ }
323
+ }
324
+ // latest is always defined since we check evidence.length > 0 above
325
+ return {
326
+ skillId,
327
+ evidenceCount: evidence.length,
328
+ averageMastery: totalWeight > 0 ? totalMastery / totalWeight : 0,
329
+ latestEvidence: latest,
330
+ bySource,
331
+ trend,
332
+ confidence: Math.min(1, evidence.length / 10), // More evidence = higher confidence
333
+ };
334
+ }
335
+ /**
336
+ * Predict probability of correct response
337
+ */
338
+ predictCorrect(profile, skillId) {
339
+ const bktState = profile.bktStates.get(skillId);
340
+ if (bktState) {
341
+ return this.bktEngine.predict(bktState).pCorrect;
342
+ }
343
+ // Fallback to mastery level
344
+ return this.getMastery(profile, skillId);
345
+ }
346
+ /**
347
+ * Estimate opportunities until mastery
348
+ */
349
+ estimateOpportunitiesToMastery(profile, skillId) {
350
+ const bktState = profile.bktStates.get(skillId);
351
+ if (bktState) {
352
+ return this.bktEngine.estimateOpportunitiesToMastery(bktState);
353
+ }
354
+ // Rough estimate based on current mastery
355
+ const mastery = this.getMastery(profile, skillId);
356
+ const gap = this.config.masteryThreshold - mastery;
357
+ if (gap <= 0)
358
+ return 0;
359
+ // Assume ~10% increase per opportunity
360
+ return Math.ceil(gap / 0.1);
361
+ }
362
+ /**
363
+ * Convert profile to MasteryState map for integration
364
+ */
365
+ toMasteryStates(profile, skillIds) {
366
+ const result = new Map();
367
+ const ids = skillIds ?? Array.from(profile.masteryLevels.keys());
368
+ for (const skillId of ids) {
369
+ const mastery = this.getMastery(profile, skillId);
370
+ const bktState = profile.bktStates.get(skillId);
371
+ // Find last attempt for this skill
372
+ const lastResponse = [...profile.responseHistory]
373
+ .reverse()
374
+ .find((r) => r.skillId === skillId);
375
+ // Calculate streak
376
+ let streak = 0;
377
+ for (let i = profile.responseHistory.length - 1; i >= 0; i--) {
378
+ const r = profile.responseHistory[i];
379
+ if (r.skillId === skillId) {
380
+ if (r.correct) {
381
+ streak++;
382
+ }
383
+ else {
384
+ break;
385
+ }
386
+ }
387
+ }
388
+ result.set(skillId, {
389
+ skillId,
390
+ mastery,
391
+ lastAttempt: lastResponse?.timestamp ?? null,
392
+ attempts: bktState?.observations ?? 0,
393
+ streak,
394
+ easinessFactor: 2.5, // Default SM-2 factor
395
+ });
396
+ }
397
+ return result;
398
+ }
399
+ }
400
+ /**
401
+ * Create a mastery engine with default configuration
402
+ */
403
+ export function createMasteryEngine(config) {
404
+ return new MasteryEngine(config);
405
+ }
406
+ //# sourceMappingURL=mastery-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mastery-engine.js","sourceRoot":"","sources":["../../../src/assessment/mastery-engine.ts"],"names":[],"mappings":"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"}