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.
- package/dist/cjs/api/routes/analytics.js +288 -0
- package/dist/cjs/api/routes/analytics.js.map +1 -0
- package/dist/cjs/api/routes/assessments.js +269 -0
- package/dist/cjs/api/routes/assessments.js.map +1 -0
- package/dist/cjs/api/routes/curriculum.js +345 -0
- package/dist/cjs/api/routes/curriculum.js.map +1 -0
- package/dist/cjs/api/routes/edges.js +162 -0
- package/dist/cjs/api/routes/edges.js.map +1 -0
- package/dist/cjs/api/routes/explore.js +224 -0
- package/dist/cjs/api/routes/explore.js.map +1 -0
- package/dist/cjs/api/routes/learners.js +324 -0
- package/dist/cjs/api/routes/learners.js.map +1 -0
- package/dist/cjs/api/routes/me.js +404 -0
- package/dist/cjs/api/routes/me.js.map +1 -0
- package/dist/cjs/api/routes/skills.js +319 -0
- package/dist/cjs/api/routes/skills.js.map +1 -0
- package/dist/cjs/api/server.js +185 -0
- package/dist/cjs/api/server.js.map +1 -0
- package/dist/cjs/api/types.js +10 -0
- package/dist/cjs/api/types.js.map +1 -0
- package/dist/cjs/assessment/adaptive.js +390 -0
- package/dist/cjs/assessment/adaptive.js.map +1 -0
- package/dist/cjs/assessment/bkt.js +362 -0
- package/dist/cjs/assessment/bkt.js.map +1 -0
- package/dist/cjs/assessment/index.js +54 -0
- package/dist/cjs/assessment/index.js.map +1 -0
- package/dist/cjs/assessment/irt.js +420 -0
- package/dist/cjs/assessment/irt.js.map +1 -0
- package/dist/cjs/assessment/mastery-engine.js +411 -0
- package/dist/cjs/assessment/mastery-engine.js.map +1 -0
- package/dist/cjs/components/LearningPathView.js +320 -0
- package/dist/cjs/components/LearningPathView.js.map +1 -0
- package/dist/cjs/components/ProgressDashboard.js +308 -0
- package/dist/cjs/components/ProgressDashboard.js.map +1 -0
- package/dist/cjs/components/SkillCard.js +264 -0
- package/dist/cjs/components/SkillCard.js.map +1 -0
- package/dist/cjs/components/SkillExplorer.js +401 -0
- package/dist/cjs/components/SkillExplorer.js.map +1 -0
- package/dist/cjs/components/SkillGraph.js +435 -0
- package/dist/cjs/components/SkillGraph.js.map +1 -0
- package/dist/cjs/components/hooks.js +510 -0
- package/dist/cjs/components/hooks.js.map +1 -0
- package/dist/cjs/components/index.js +77 -0
- package/dist/cjs/components/index.js.map +1 -0
- package/dist/cjs/components/types.js +34 -0
- package/dist/cjs/components/types.js.map +1 -0
- package/dist/cjs/index.js +35 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/llm/adapters/anthropic.js +91 -3
- package/dist/cjs/llm/adapters/anthropic.js.map +1 -1
- package/dist/cjs/llm/adapters/gemini.js +101 -8
- package/dist/cjs/llm/adapters/gemini.js.map +1 -1
- package/dist/cjs/llm/adapters/index.js +42 -1
- package/dist/cjs/llm/adapters/index.js.map +1 -1
- package/dist/cjs/llm/adapters/ollama.js +120 -3
- package/dist/cjs/llm/adapters/ollama.js.map +1 -1
- package/dist/cjs/llm/adapters/openai.js +108 -2
- package/dist/cjs/llm/adapters/openai.js.map +1 -1
- package/dist/cjs/mcp/cli.js +302 -0
- package/dist/cjs/mcp/cli.js.map +1 -0
- package/dist/cjs/mcp/index.js +79 -0
- package/dist/cjs/mcp/index.js.map +1 -0
- package/dist/cjs/mcp/prompts.js +425 -0
- package/dist/cjs/mcp/prompts.js.map +1 -0
- package/dist/cjs/mcp/resources.js +371 -0
- package/dist/cjs/mcp/resources.js.map +1 -0
- package/dist/cjs/mcp/server.js +410 -0
- package/dist/cjs/mcp/server.js.map +1 -0
- package/dist/cjs/mcp/tools.js +612 -0
- package/dist/cjs/mcp/tools.js.map +1 -0
- package/dist/cjs/mcp/types.js +10 -0
- package/dist/cjs/mcp/types.js.map +1 -0
- package/dist/cjs/types/assessment.js +46 -0
- package/dist/cjs/types/assessment.js.map +1 -0
- package/dist/cjs/types/bloom.js +12 -1
- package/dist/cjs/types/bloom.js.map +1 -1
- package/dist/cjs/types/index.js +7 -1
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/esm/api/routes/analytics.js +285 -0
- package/dist/esm/api/routes/analytics.js.map +1 -0
- package/dist/esm/api/routes/assessments.js +266 -0
- package/dist/esm/api/routes/assessments.js.map +1 -0
- package/dist/esm/api/routes/curriculum.js +342 -0
- package/dist/esm/api/routes/curriculum.js.map +1 -0
- package/dist/esm/api/routes/edges.js +159 -0
- package/dist/esm/api/routes/edges.js.map +1 -0
- package/dist/esm/api/routes/explore.js +221 -0
- package/dist/esm/api/routes/explore.js.map +1 -0
- package/dist/esm/api/routes/learners.js +321 -0
- package/dist/esm/api/routes/learners.js.map +1 -0
- package/dist/esm/api/routes/me.js +401 -0
- package/dist/esm/api/routes/me.js.map +1 -0
- package/dist/esm/api/routes/skills.js +316 -0
- package/dist/esm/api/routes/skills.js.map +1 -0
- package/dist/esm/api/server.js +179 -0
- package/dist/esm/api/server.js.map +1 -0
- package/dist/esm/api/types.js +9 -0
- package/dist/esm/api/types.js.map +1 -0
- package/dist/esm/assessment/adaptive.js +384 -0
- package/dist/esm/assessment/adaptive.js.map +1 -0
- package/dist/esm/assessment/bkt.js +354 -0
- package/dist/esm/assessment/bkt.js.map +1 -0
- package/dist/esm/assessment/index.js +21 -0
- package/dist/esm/assessment/index.js.map +1 -0
- package/dist/esm/assessment/irt.js +406 -0
- package/dist/esm/assessment/irt.js.map +1 -0
- package/dist/esm/assessment/mastery-engine.js +406 -0
- package/dist/esm/assessment/mastery-engine.js.map +1 -0
- package/dist/esm/components/LearningPathView.js +316 -0
- package/dist/esm/components/LearningPathView.js.map +1 -0
- package/dist/esm/components/ProgressDashboard.js +304 -0
- package/dist/esm/components/ProgressDashboard.js.map +1 -0
- package/dist/esm/components/SkillCard.js +260 -0
- package/dist/esm/components/SkillCard.js.map +1 -0
- package/dist/esm/components/SkillExplorer.js +397 -0
- package/dist/esm/components/SkillExplorer.js.map +1 -0
- package/dist/esm/components/SkillGraph.js +398 -0
- package/dist/esm/components/SkillGraph.js.map +1 -0
- package/dist/esm/components/hooks.js +502 -0
- package/dist/esm/components/hooks.js.map +1 -0
- package/dist/esm/components/index.js +61 -0
- package/dist/esm/components/index.js.map +1 -0
- package/dist/esm/components/types.js +31 -0
- package/dist/esm/components/types.js.map +1 -0
- package/dist/esm/index.js +12 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/llm/adapters/anthropic.js +88 -2
- package/dist/esm/llm/adapters/anthropic.js.map +1 -1
- package/dist/esm/llm/adapters/gemini.js +98 -7
- package/dist/esm/llm/adapters/gemini.js.map +1 -1
- package/dist/esm/llm/adapters/index.js +15 -4
- package/dist/esm/llm/adapters/index.js.map +1 -1
- package/dist/esm/llm/adapters/ollama.js +117 -2
- package/dist/esm/llm/adapters/ollama.js.map +1 -1
- package/dist/esm/llm/adapters/openai.js +105 -1
- package/dist/esm/llm/adapters/openai.js.map +1 -1
- package/dist/esm/mcp/cli.js +267 -0
- package/dist/esm/mcp/cli.js.map +1 -0
- package/dist/esm/mcp/index.js +39 -0
- package/dist/esm/mcp/index.js.map +1 -0
- package/dist/esm/mcp/prompts.js +419 -0
- package/dist/esm/mcp/prompts.js.map +1 -0
- package/dist/esm/mcp/resources.js +359 -0
- package/dist/esm/mcp/resources.js.map +1 -0
- package/dist/esm/mcp/server.js +372 -0
- package/dist/esm/mcp/server.js.map +1 -0
- package/dist/esm/mcp/tools.js +598 -0
- package/dist/esm/mcp/tools.js.map +1 -0
- package/dist/esm/mcp/types.js +9 -0
- package/dist/esm/mcp/types.js.map +1 -0
- package/dist/esm/types/assessment.js +40 -0
- package/dist/esm/types/assessment.js.map +1 -0
- package/dist/esm/types/bloom.js +11 -0
- package/dist/esm/types/bloom.js.map +1 -1
- package/dist/esm/types/index.js +2 -1
- package/dist/esm/types/index.js.map +1 -1
- package/dist/types/api/routes/analytics.d.ts +14 -0
- package/dist/types/api/routes/analytics.d.ts.map +1 -0
- package/dist/types/api/routes/assessments.d.ts +14 -0
- package/dist/types/api/routes/assessments.d.ts.map +1 -0
- package/dist/types/api/routes/curriculum.d.ts +14 -0
- package/dist/types/api/routes/curriculum.d.ts.map +1 -0
- package/dist/types/api/routes/edges.d.ts +14 -0
- package/dist/types/api/routes/edges.d.ts.map +1 -0
- package/dist/types/api/routes/explore.d.ts +14 -0
- package/dist/types/api/routes/explore.d.ts.map +1 -0
- package/dist/types/api/routes/learners.d.ts +14 -0
- package/dist/types/api/routes/learners.d.ts.map +1 -0
- package/dist/types/api/routes/me.d.ts +14 -0
- package/dist/types/api/routes/me.d.ts.map +1 -0
- package/dist/types/api/routes/skills.d.ts +14 -0
- package/dist/types/api/routes/skills.d.ts.map +1 -0
- package/dist/types/api/server.d.ts +147 -0
- package/dist/types/api/server.d.ts.map +1 -0
- package/dist/types/api/types.d.ts +443 -0
- package/dist/types/api/types.d.ts.map +1 -0
- package/dist/types/assessment/adaptive.d.ts +155 -0
- package/dist/types/assessment/adaptive.d.ts.map +1 -0
- package/dist/types/assessment/bkt.d.ts +185 -0
- package/dist/types/assessment/bkt.d.ts.map +1 -0
- package/dist/types/assessment/index.d.ts +18 -0
- package/dist/types/assessment/index.d.ts.map +1 -0
- package/dist/types/assessment/irt.d.ts +159 -0
- package/dist/types/assessment/irt.d.ts.map +1 -0
- package/dist/types/assessment/mastery-engine.d.ts +178 -0
- package/dist/types/assessment/mastery-engine.d.ts.map +1 -0
- package/dist/types/components/LearningPathView.d.ts +40 -0
- package/dist/types/components/LearningPathView.d.ts.map +1 -0
- package/dist/types/components/ProgressDashboard.d.ts +49 -0
- package/dist/types/components/ProgressDashboard.d.ts.map +1 -0
- package/dist/types/components/SkillCard.d.ts +34 -0
- package/dist/types/components/SkillCard.d.ts.map +1 -0
- package/dist/types/components/SkillExplorer.d.ts +39 -0
- package/dist/types/components/SkillExplorer.d.ts.map +1 -0
- package/dist/types/components/SkillGraph.d.ts +38 -0
- package/dist/types/components/SkillGraph.d.ts.map +1 -0
- package/dist/types/components/hooks.d.ts +187 -0
- package/dist/types/components/hooks.d.ts.map +1 -0
- package/dist/types/components/index.d.ts +59 -0
- package/dist/types/components/index.d.ts.map +1 -0
- package/dist/types/components/types.d.ts +410 -0
- package/dist/types/components/types.d.ts.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/llm/adapters/anthropic.d.ts +84 -1
- package/dist/types/llm/adapters/anthropic.d.ts.map +1 -1
- package/dist/types/llm/adapters/gemini.d.ts +93 -6
- package/dist/types/llm/adapters/gemini.d.ts.map +1 -1
- package/dist/types/llm/adapters/index.d.ts +13 -4
- package/dist/types/llm/adapters/index.d.ts.map +1 -1
- package/dist/types/llm/adapters/ollama.d.ts +126 -1
- package/dist/types/llm/adapters/ollama.d.ts.map +1 -1
- package/dist/types/llm/adapters/openai.d.ts +104 -1
- package/dist/types/llm/adapters/openai.d.ts.map +1 -1
- package/dist/types/mcp/cli.d.ts +15 -0
- package/dist/types/mcp/cli.d.ts.map +1 -0
- package/dist/types/mcp/index.d.ts +32 -0
- package/dist/types/mcp/index.d.ts.map +1 -0
- package/dist/types/mcp/prompts.d.ts +27 -0
- package/dist/types/mcp/prompts.d.ts.map +1 -0
- package/dist/types/mcp/resources.d.ts +59 -0
- package/dist/types/mcp/resources.d.ts.map +1 -0
- package/dist/types/mcp/server.d.ts +136 -0
- package/dist/types/mcp/server.d.ts.map +1 -0
- package/dist/types/mcp/tools.d.ts +344 -0
- package/dist/types/mcp/tools.d.ts.map +1 -0
- package/dist/types/mcp/types.d.ts +137 -0
- package/dist/types/mcp/types.d.ts.map +1 -0
- package/dist/types/types/assessment.d.ts +512 -0
- package/dist/types/types/assessment.d.ts.map +1 -0
- package/dist/types/types/bloom.d.ts +4 -0
- package/dist/types/types/bloom.d.ts.map +1 -1
- package/dist/types/types/index.d.ts +3 -1
- package/dist/types/types/index.d.ts.map +1 -1
- 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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"}
|