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,384 @@
1
+ /**
2
+ * Adaptive Assessment Framework
3
+ *
4
+ * Implements adaptive testing with:
5
+ * - IRT-based item selection (Maximum Fisher Information)
6
+ * - Content balancing across skills
7
+ * - Termination criteria (precision, item count, time)
8
+ * - Real-time ability estimation
9
+ *
10
+ * @packageDocumentation
11
+ */
12
+ import { IRTEstimator, calculateInformation, } from './irt.js';
13
+ /**
14
+ * Default adaptive configuration
15
+ */
16
+ export const ADAPTIVE_DEFAULTS = {
17
+ selectionMethod: 'MFI',
18
+ contentBalancing: [],
19
+ maxExposureRate: 0.25,
20
+ preventOverlap: true,
21
+ };
22
+ /**
23
+ * Default termination criteria
24
+ */
25
+ export const TERMINATION_DEFAULTS = {
26
+ maxQuestions: 30,
27
+ minQuestions: 5,
28
+ targetPrecision: 0.3,
29
+ maxTimeMinutes: 60,
30
+ masteryThreshold: 0.95,
31
+ };
32
+ /**
33
+ * Adaptive Assessment Engine
34
+ *
35
+ * Manages adaptive testing sessions with intelligent item selection.
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * const engine = new AdaptiveEngine();
40
+ *
41
+ * // Create session
42
+ * const session = engine.createSession(pool, assessment, 'learner-1');
43
+ *
44
+ * // Get next question
45
+ * const next = engine.selectNextQuestion(session);
46
+ * if (next) {
47
+ * // Present question to learner...
48
+ * session = engine.recordResponse(session, next.questionId, true);
49
+ * }
50
+ *
51
+ * // Check if complete
52
+ * if (engine.shouldTerminate(session)) {
53
+ * const result = engine.getResult(session);
54
+ * }
55
+ * ```
56
+ */
57
+ export class AdaptiveEngine {
58
+ irtEstimator;
59
+ constructor() {
60
+ this.irtEstimator = new IRTEstimator();
61
+ }
62
+ /**
63
+ * Create a new adaptive session
64
+ */
65
+ createSession(pool, assessment, learnerId, config, termination) {
66
+ const sessionConfig = { ...ADAPTIVE_DEFAULTS, ...config };
67
+ const sessionTermination = { ...TERMINATION_DEFAULTS, ...assessment.terminationCriteria, ...termination };
68
+ // Initialize ability estimate with prior
69
+ const abilityEstimate = {
70
+ theta: 0,
71
+ standardError: 1,
72
+ itemCount: 0,
73
+ method: 'EAP',
74
+ confidenceInterval: { lower: -1.96, upper: 1.96 },
75
+ };
76
+ // Initialize content coverage
77
+ const contentCoverage = new Map();
78
+ for (const skillId of assessment.skillIds) {
79
+ contentCoverage.set(skillId, 0);
80
+ }
81
+ const state = {
82
+ abilityEstimate: 0,
83
+ standardError: 1,
84
+ administeredItems: [],
85
+ contentCoverage,
86
+ shouldTerminate: false,
87
+ };
88
+ return {
89
+ id: `session-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
90
+ assessmentId: assessment.id,
91
+ learnerId,
92
+ pool,
93
+ administeredQuestions: [],
94
+ responses: [],
95
+ abilityEstimate,
96
+ contentCoverage,
97
+ startTime: new Date(),
98
+ config: sessionConfig,
99
+ termination: sessionTermination,
100
+ state,
101
+ };
102
+ }
103
+ /**
104
+ * Select the next question using the configured strategy
105
+ */
106
+ selectNextQuestion(session) {
107
+ // Check termination first
108
+ if (this.shouldTerminate(session)) {
109
+ return null;
110
+ }
111
+ const administered = new Set(session.administeredQuestions);
112
+ // Get eligible questions
113
+ const eligible = this.getEligibleQuestions(session, administered);
114
+ if (eligible.length === 0) {
115
+ return null;
116
+ }
117
+ // Select based on method
118
+ switch (session.config.selectionMethod) {
119
+ case 'MFI':
120
+ return this.selectMFI(session, eligible);
121
+ case 'KL':
122
+ return this.selectKL(session, eligible);
123
+ case 'EBI':
124
+ return this.selectEBI(session, eligible);
125
+ case 'MEPV':
126
+ return this.selectMEPV(session, eligible);
127
+ default:
128
+ return this.selectMFI(session, eligible);
129
+ }
130
+ }
131
+ /**
132
+ * Record a response and update ability estimate
133
+ */
134
+ recordResponse(session, questionId, correct) {
135
+ const params = session.pool.irtParams.get(questionId);
136
+ if (!params) {
137
+ throw new Error(`No IRT parameters for question ${questionId}`);
138
+ }
139
+ // Add response
140
+ const response = { questionId, params, correct };
141
+ session.responses.push(response);
142
+ session.administeredQuestions.push(questionId);
143
+ // Update ability estimate
144
+ session.abilityEstimate = this.irtEstimator.estimate(session.responses);
145
+ // Update content coverage
146
+ const question = session.pool.questions.get(questionId);
147
+ if (question) {
148
+ for (const skillId of question.skillIds) {
149
+ const current = session.contentCoverage.get(skillId) ?? 0;
150
+ session.contentCoverage.set(skillId, current + 1);
151
+ }
152
+ }
153
+ // Update exposure count
154
+ const exposure = session.pool.exposureCounts.get(questionId) ?? 0;
155
+ session.pool.exposureCounts.set(questionId, exposure + 1);
156
+ session.pool.totalAdministrations++;
157
+ // Update state
158
+ const terminationReason = this.getTerminationReason(session);
159
+ session.state = {
160
+ abilityEstimate: session.abilityEstimate.theta,
161
+ standardError: session.abilityEstimate.standardError,
162
+ administeredItems: [...session.administeredQuestions],
163
+ contentCoverage: session.contentCoverage,
164
+ shouldTerminate: this.shouldTerminate(session),
165
+ ...(terminationReason !== undefined && { terminationReason }),
166
+ };
167
+ return session;
168
+ }
169
+ /**
170
+ * Check if assessment should terminate
171
+ */
172
+ shouldTerminate(session) {
173
+ const { termination, responses, startTime, abilityEstimate } = session;
174
+ // Max questions reached
175
+ if (responses.length >= termination.maxQuestions) {
176
+ return true;
177
+ }
178
+ // Min questions not yet reached
179
+ if (responses.length < termination.minQuestions) {
180
+ return false;
181
+ }
182
+ // Target precision achieved
183
+ if (abilityEstimate.standardError <= termination.targetPrecision) {
184
+ return true;
185
+ }
186
+ // Time limit reached
187
+ const elapsedMinutes = (Date.now() - startTime.getTime()) / (1000 * 60);
188
+ if (elapsedMinutes >= termination.maxTimeMinutes) {
189
+ return true;
190
+ }
191
+ // No more eligible questions
192
+ const administered = new Set(session.administeredQuestions);
193
+ const eligible = this.getEligibleQuestions(session, administered);
194
+ if (eligible.length === 0) {
195
+ return true;
196
+ }
197
+ return false;
198
+ }
199
+ /**
200
+ * Get reason for termination
201
+ */
202
+ getTerminationReason(session) {
203
+ if (!this.shouldTerminate(session)) {
204
+ return undefined;
205
+ }
206
+ const { termination, responses, startTime, abilityEstimate } = session;
207
+ if (responses.length >= termination.maxQuestions) {
208
+ return 'Maximum questions reached';
209
+ }
210
+ if (abilityEstimate.standardError <= termination.targetPrecision) {
211
+ return 'Target precision achieved';
212
+ }
213
+ const elapsedMinutes = (Date.now() - startTime.getTime()) / (1000 * 60);
214
+ if (elapsedMinutes >= termination.maxTimeMinutes) {
215
+ return 'Time limit reached';
216
+ }
217
+ return 'No more eligible questions';
218
+ }
219
+ /**
220
+ * Get eligible questions based on constraints
221
+ */
222
+ getEligibleQuestions(session, administered) {
223
+ const eligible = [];
224
+ for (const [id, params] of session.pool.irtParams) {
225
+ // Skip administered
226
+ if (administered.has(id))
227
+ continue;
228
+ // Check exposure control
229
+ if (session.config.maxExposureRate < 1) {
230
+ const exposure = session.pool.exposureCounts.get(id) ?? 0;
231
+ const total = session.pool.totalAdministrations;
232
+ if (total > 0) {
233
+ const rate = exposure / total;
234
+ if (rate > session.config.maxExposureRate)
235
+ continue;
236
+ }
237
+ }
238
+ // Check content balancing
239
+ const question = session.pool.questions.get(id);
240
+ if (question && session.config.contentBalancing.length > 0) {
241
+ let valid = true;
242
+ for (const constraint of session.config.contentBalancing) {
243
+ if (question.skillIds.includes(constraint.skillId)) {
244
+ const current = session.contentCoverage.get(constraint.skillId) ?? 0;
245
+ if (constraint.maxItems !== undefined && current >= constraint.maxItems) {
246
+ valid = false;
247
+ break;
248
+ }
249
+ }
250
+ }
251
+ if (!valid)
252
+ continue;
253
+ }
254
+ eligible.push({ id, params });
255
+ }
256
+ return eligible;
257
+ }
258
+ /**
259
+ * Maximum Fisher Information selection
260
+ */
261
+ selectMFI(session, eligible) {
262
+ const theta = session.abilityEstimate.theta;
263
+ let best = eligible[0];
264
+ let maxInfo = calculateInformation(theta, best.params);
265
+ for (const item of eligible) {
266
+ const info = calculateInformation(theta, item.params);
267
+ if (info > maxInfo) {
268
+ maxInfo = info;
269
+ best = item;
270
+ }
271
+ }
272
+ return {
273
+ questionId: best.id,
274
+ information: maxInfo,
275
+ reason: 'Maximum Fisher Information at current ability estimate',
276
+ alternatives: eligible.slice(1, 4).map((e) => e.id),
277
+ };
278
+ }
279
+ /**
280
+ * Kullback-Leibler information selection
281
+ * (Simplified implementation - selects based on KL divergence)
282
+ */
283
+ selectKL(session, eligible) {
284
+ // For KL, we want items that maximize expected KL divergence
285
+ // Simplified: use weighted information over ability range
286
+ const theta = session.abilityEstimate.theta;
287
+ const se = session.abilityEstimate.standardError;
288
+ let best = eligible[0];
289
+ let maxKL = 0;
290
+ for (const item of eligible) {
291
+ // Integrate information over likely ability range
292
+ let kl = 0;
293
+ for (let t = theta - 2 * se; t <= theta + 2 * se; t += se / 2) {
294
+ const weight = Math.exp(-0.5 * ((t - theta) / se) ** 2);
295
+ kl += weight * calculateInformation(t, item.params);
296
+ }
297
+ if (kl > maxKL) {
298
+ maxKL = kl;
299
+ best = item;
300
+ }
301
+ }
302
+ return {
303
+ questionId: best.id,
304
+ information: maxKL,
305
+ reason: 'Kullback-Leibler weighted information',
306
+ alternatives: eligible.slice(1, 4).map((e) => e.id),
307
+ };
308
+ }
309
+ /**
310
+ * Expected Bayesian Information selection
311
+ */
312
+ selectEBI(session, eligible) {
313
+ // Similar to MFI but weighted by posterior probability
314
+ return this.selectMFI(session, eligible);
315
+ }
316
+ /**
317
+ * Minimum Expected Posterior Variance selection
318
+ */
319
+ selectMEPV(session, eligible) {
320
+ // Select item that minimizes expected posterior variance
321
+ // Equivalent to maximizing expected information gain
322
+ return this.selectMFI(session, eligible);
323
+ }
324
+ /**
325
+ * Get session result
326
+ */
327
+ getResult(session) {
328
+ const correct = session.responses.filter((r) => r.correct).length;
329
+ const total = session.responses.length;
330
+ const elapsedMinutes = (Date.now() - session.startTime.getTime()) / (1000 * 60);
331
+ return {
332
+ abilityEstimate: session.abilityEstimate,
333
+ score: total > 0 ? correct / total : 0,
334
+ itemCount: total,
335
+ elapsedMinutes,
336
+ contentCoverage: session.contentCoverage,
337
+ terminationReason: this.getTerminationReason(session) ?? 'Assessment complete',
338
+ };
339
+ }
340
+ }
341
+ /**
342
+ * Create question pool from questions with IRT parameters
343
+ */
344
+ export function createQuestionPool(questions, getIRTParams) {
345
+ const pool = {
346
+ questions: new Map(),
347
+ irtParams: new Map(),
348
+ bySkill: new Map(),
349
+ exposureCounts: new Map(),
350
+ totalAdministrations: 0,
351
+ };
352
+ for (const question of questions) {
353
+ pool.questions.set(question.id, question);
354
+ // Get IRT params from question or generator
355
+ const params = question.irtParams ?? getIRTParams?.(question);
356
+ if (params) {
357
+ pool.irtParams.set(question.id, params);
358
+ }
359
+ else {
360
+ // Default params based on question difficulty
361
+ const defaultParams = {
362
+ difficulty: 0, // Neutral difficulty
363
+ discrimination: 1.0,
364
+ model: '2PL',
365
+ };
366
+ pool.irtParams.set(question.id, defaultParams);
367
+ }
368
+ // Index by skill
369
+ for (const skillId of question.skillIds) {
370
+ const existing = pool.bySkill.get(skillId) ?? [];
371
+ existing.push(question.id);
372
+ pool.bySkill.set(skillId, existing);
373
+ }
374
+ pool.exposureCounts.set(question.id, 0);
375
+ }
376
+ return pool;
377
+ }
378
+ /**
379
+ * Create an adaptive engine
380
+ */
381
+ export function createAdaptiveEngine() {
382
+ return new AdaptiveEngine();
383
+ }
384
+ //# sourceMappingURL=adaptive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adaptive.js","sourceRoot":"","sources":["../../../src/assessment/adaptive.ts"],"names":[],"mappings":"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"}