@vue-skuilder/db 0.1.22 → 0.1.24
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/{contentSource-BP9hznNV.d.ts → contentSource-BotbOOfX.d.ts} +227 -3
- package/dist/{contentSource-DsJadoBU.d.cts → contentSource-C90LH-OH.d.cts} +227 -3
- package/dist/core/index.d.cts +220 -6
- package/dist/core/index.d.ts +220 -6
- package/dist/core/index.js +2052 -559
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +2035 -555
- package/dist/core/index.mjs.map +1 -1
- package/dist/{dataLayerProvider-CHYrQ5pB.d.cts → dataLayerProvider-DGKp4zFB.d.cts} +1 -1
- package/dist/{dataLayerProvider-MDTxXq2l.d.ts → dataLayerProvider-SBpz9jQf.d.ts} +1 -1
- package/dist/impl/couch/index.d.cts +11 -3
- package/dist/impl/couch/index.d.ts +11 -3
- package/dist/impl/couch/index.js +1811 -574
- package/dist/impl/couch/index.js.map +1 -1
- package/dist/impl/couch/index.mjs +1792 -550
- package/dist/impl/couch/index.mjs.map +1 -1
- package/dist/impl/static/index.d.cts +4 -4
- package/dist/impl/static/index.d.ts +4 -4
- package/dist/impl/static/index.js +1797 -560
- package/dist/impl/static/index.js.map +1 -1
- package/dist/impl/static/index.mjs +1789 -547
- package/dist/impl/static/index.mjs.map +1 -1
- package/dist/{index-Dj0SEgk3.d.ts → index-BWvO-_rJ.d.ts} +1 -1
- package/dist/{index-B_j6u5E4.d.cts → index-Ba7hYbHj.d.cts} +1 -1
- package/dist/index.d.cts +150 -12
- package/dist/index.d.ts +150 -12
- package/dist/index.js +2658 -791
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2584 -747
- package/dist/index.mjs.map +1 -1
- package/dist/{types-DQaXnuoc.d.ts → types-CJrLM1Ew.d.ts} +1 -1
- package/dist/{types-Bn0itutr.d.cts → types-W8n-B6HG.d.cts} +1 -1
- package/dist/{types-legacy-DDY4N-Uq.d.cts → types-legacy-JXDxinpU.d.cts} +5 -1
- package/dist/{types-legacy-DDY4N-Uq.d.ts → types-legacy-JXDxinpU.d.ts} +5 -1
- package/dist/util/packer/index.d.cts +3 -3
- package/dist/util/packer/index.d.ts +3 -3
- package/docs/brainstorm-navigation-paradigm.md +40 -34
- package/docs/future-orchestration-vision.md +216 -0
- package/docs/navigators-architecture.md +188 -5
- package/docs/todo-strategy-authoring.md +8 -6
- package/package.json +3 -3
- package/src/core/index.ts +2 -0
- package/src/core/interfaces/contentSource.ts +7 -0
- package/src/core/interfaces/userDB.ts +6 -0
- package/src/core/navigators/Pipeline.ts +46 -0
- package/src/core/navigators/PipelineAssembler.ts +14 -1
- package/src/core/navigators/filters/WeightedFilter.ts +141 -0
- package/src/core/navigators/filters/types.ts +4 -0
- package/src/core/navigators/generators/CompositeGenerator.ts +61 -19
- package/src/core/navigators/generators/types.ts +4 -0
- package/src/core/navigators/index.ts +194 -13
- package/src/core/orchestration/gradient.ts +133 -0
- package/src/core/orchestration/index.ts +210 -0
- package/src/core/orchestration/learning.ts +250 -0
- package/src/core/orchestration/recording.ts +92 -0
- package/src/core/orchestration/signal.ts +67 -0
- package/src/core/types/contentNavigationStrategy.ts +38 -0
- package/src/core/types/learningState.ts +77 -0
- package/src/core/types/types-legacy.ts +4 -0
- package/src/core/types/userOutcome.ts +51 -0
- package/src/courseConfigRegistration.ts +546 -0
- package/src/factory.ts +6 -0
- package/src/impl/common/BaseUserDB.ts +16 -0
- package/src/index.ts +2 -0
- package/src/study/SessionController.ts +64 -1
- package/tests/core/navigators/Pipeline.test.ts +2 -0
- package/docs/todo-evolutionary-orchestration.md +0 -310
package/dist/core/index.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { W as WeightedCard, U as UserDBInterface, C as CourseDBInterface } from '../contentSource-
|
|
2
|
-
export { J as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, G as ClassroomRegistrationDoc, f as ContentNavigator, q as ContentSourceID, d as CourseInfo, K as CourseRegistration, s as CourseRegistrationDoc, b as CoursesDBInterface,
|
|
3
|
-
export { D as DataLayerProvider } from '../dataLayerProvider-
|
|
4
|
-
import {
|
|
5
|
-
export { d as CardData, e as CourseListData, g as DataShapeData, f as DisplayableData, F as Field, G as GuestUsername, Q as QualifiedCardID, h as QuestionData, S as SkuilderCourseData, a as Tag, T as TagStub, l as log } from '../types-legacy-
|
|
1
|
+
import { a1 as LearnableWeight, L as UserOutcomeRecord, a2 as OrchestrationContext, W as WeightedCard, U as UserDBInterface, C as CourseDBInterface } from '../contentSource-C90LH-OH.cjs';
|
|
2
|
+
export { J as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, G as ClassroomRegistrationDoc, e as ContentNavigationStrategyData, f as ContentNavigator, q as ContentSourceID, d as CourseInfo, K as CourseRegistration, s as CourseRegistrationDoc, b as CoursesDBInterface, N as NavigatorConstructor, Z as NavigatorRole, _ as NavigatorRoles, Y as Navigators, j as ScheduledCard, H as SessionTrackingData, V as StrategyContribution, i as StudentClassroomDBInterface, h as StudyContentSource, k as StudySessionFailedItem, l as StudySessionFailedNewItem, m as StudySessionFailedReviewItem, S as StudySessionItem, n as StudySessionNewItem, o as StudySessionReviewItem, T as TeacherClassroomDBInterface, I as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, B as UsrCrsDataInterface, a3 as computeDeviation, a5 as computeEffectiveWeight, a4 as computeSpread, a6 as createOrchestrationContext, X as getCardOrigin, O as getRegisteredNavigator, Q as getRegisteredNavigatorNames, r as getStudySource, P as hasRegisteredNavigator, R as initializeNavigatorRegistry, a0 as isFilter, $ as isGenerator, p as isReview, M as registerNavigator } from '../contentSource-C90LH-OH.cjs';
|
|
3
|
+
export { D as DataLayerProvider } from '../dataLayerProvider-DGKp4zFB.cjs';
|
|
4
|
+
import { D as DocType, i as QuestionRecord, b as DocTypePrefixes, C as CardHistory, c as CardRecord } from '../types-legacy-JXDxinpU.cjs';
|
|
5
|
+
export { d as CardData, e as CourseListData, g as DataShapeData, f as DisplayableData, F as Field, G as GuestUsername, Q as QualifiedCardID, h as QuestionData, S as SkuilderCourseData, a as Tag, T as TagStub, l as log } from '../types-legacy-JXDxinpU.cjs';
|
|
6
6
|
import { DataShape, ParsedCard } from '@vue-skuilder/common';
|
|
7
7
|
import 'moment';
|
|
8
8
|
|
|
@@ -12,6 +12,216 @@ declare abstract class Loggable {
|
|
|
12
12
|
protected error(...args: unknown[]): void;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Snapshot of the learning state for a strategy.
|
|
17
|
+
*
|
|
18
|
+
* Stored in the CourseDB for observability and debugging.
|
|
19
|
+
* Updated periodically by the gradient learning system.
|
|
20
|
+
*/
|
|
21
|
+
interface StrategyLearningState {
|
|
22
|
+
/**
|
|
23
|
+
* Unique ID: "STRATEGY_LEARNING_STATE::{courseId}::{strategyId}"
|
|
24
|
+
*/
|
|
25
|
+
_id: string;
|
|
26
|
+
/** Allow CouchDB to manage revisions */
|
|
27
|
+
_rev?: string;
|
|
28
|
+
docType: DocType.STRATEGY_LEARNING_STATE;
|
|
29
|
+
courseId: string;
|
|
30
|
+
strategyId: string;
|
|
31
|
+
/** Current learned weight (mirrors the strategy doc, for convenience) */
|
|
32
|
+
currentWeight: LearnableWeight;
|
|
33
|
+
/** Most recent regression statistics */
|
|
34
|
+
regression: {
|
|
35
|
+
/** Slope of the linear regression (deviation vs outcome) */
|
|
36
|
+
gradient: number;
|
|
37
|
+
/** Y-intercept of the regression line */
|
|
38
|
+
intercept: number;
|
|
39
|
+
/** R-squared value (0-1), measure of fit quality */
|
|
40
|
+
rSquared: number;
|
|
41
|
+
/** Number of observations used in this regression */
|
|
42
|
+
sampleSize: number;
|
|
43
|
+
/** ISO timestamp of when this regression was computed */
|
|
44
|
+
computedAt: string;
|
|
45
|
+
};
|
|
46
|
+
/** Historical weight snapshots for visualization */
|
|
47
|
+
history: Array<{
|
|
48
|
+
timestamp: string;
|
|
49
|
+
weight: number;
|
|
50
|
+
confidence: number;
|
|
51
|
+
gradient: number;
|
|
52
|
+
}>;
|
|
53
|
+
/** ISO timestamp of last update */
|
|
54
|
+
updatedAt: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Data point for gradient computation: (deviation, outcome) pair.
|
|
58
|
+
*/
|
|
59
|
+
interface GradientObservation {
|
|
60
|
+
/** User's deviation for this strategy [-1, 1] */
|
|
61
|
+
deviation: number;
|
|
62
|
+
/** User's outcome value [0, 1] */
|
|
63
|
+
outcomeValue: number;
|
|
64
|
+
/** Optional: weight for this observation (default 1.0) */
|
|
65
|
+
weight?: number;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Result of linear regression on (deviation, outcome) pairs.
|
|
69
|
+
*/
|
|
70
|
+
interface GradientResult {
|
|
71
|
+
/** Slope: positive = higher deviation correlates with better outcomes */
|
|
72
|
+
gradient: number;
|
|
73
|
+
/** Y-intercept */
|
|
74
|
+
intercept: number;
|
|
75
|
+
/** R-squared: 0-1, how well the line fits */
|
|
76
|
+
rSquared: number;
|
|
77
|
+
/** Number of observations */
|
|
78
|
+
sampleSize: number;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Extract (deviation, outcome) observations for a specific strategy
|
|
83
|
+
* from a collection of UserOutcomeRecords.
|
|
84
|
+
*
|
|
85
|
+
* @param outcomes - Collection of outcome records (from multiple users)
|
|
86
|
+
* @param strategyId - The strategy to extract observations for
|
|
87
|
+
* @returns Array of gradient observations
|
|
88
|
+
*/
|
|
89
|
+
declare function aggregateOutcomesForGradient(outcomes: UserOutcomeRecord[], strategyId: string): GradientObservation[];
|
|
90
|
+
/**
|
|
91
|
+
* Compute linear regression on (deviation, outcome) pairs.
|
|
92
|
+
*
|
|
93
|
+
* Uses ordinary least squares to find the best fit line:
|
|
94
|
+
* outcome = gradient * deviation + intercept
|
|
95
|
+
*
|
|
96
|
+
* The gradient tells us:
|
|
97
|
+
* - Positive: users with higher deviation (higher weight) had better outcomes
|
|
98
|
+
* → we should increase the peak weight
|
|
99
|
+
* - Negative: users with higher deviation (higher weight) had worse outcomes
|
|
100
|
+
* → we should decrease the peak weight
|
|
101
|
+
* - Near zero: weight doesn't affect outcomes much
|
|
102
|
+
* → we're near optimal, increase confidence
|
|
103
|
+
*
|
|
104
|
+
* @param observations - Array of (deviation, outcome) pairs
|
|
105
|
+
* @returns Regression result, or null if insufficient data
|
|
106
|
+
*/
|
|
107
|
+
declare function computeStrategyGradient(observations: GradientObservation[]): GradientResult | null;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Compute updated weight based on gradient result.
|
|
111
|
+
*
|
|
112
|
+
* The update logic:
|
|
113
|
+
* - Positive gradient: users with higher weight did better → increase weight
|
|
114
|
+
* - Negative gradient: users with higher weight did worse → decrease weight
|
|
115
|
+
* - Flat gradient: weight doesn't affect outcome → increase confidence
|
|
116
|
+
*
|
|
117
|
+
* @param current - Current learnable weight
|
|
118
|
+
* @param gradient - Computed gradient result
|
|
119
|
+
* @returns Updated learnable weight
|
|
120
|
+
*/
|
|
121
|
+
declare function updateStrategyWeight(current: LearnableWeight, gradient: GradientResult): LearnableWeight;
|
|
122
|
+
/**
|
|
123
|
+
* Create or update a StrategyLearningState document.
|
|
124
|
+
*
|
|
125
|
+
* @param courseId - Course ID
|
|
126
|
+
* @param strategyId - Strategy ID
|
|
127
|
+
* @param currentWeight - Current learned weight
|
|
128
|
+
* @param gradient - Gradient result from recent computation
|
|
129
|
+
* @param existing - Existing learning state (if any)
|
|
130
|
+
* @returns Updated learning state document
|
|
131
|
+
*/
|
|
132
|
+
declare function updateLearningState(courseId: string, strategyId: string, currentWeight: LearnableWeight, gradient: GradientResult, existing?: StrategyLearningState): StrategyLearningState;
|
|
133
|
+
/**
|
|
134
|
+
* Input data for running a period update on a single strategy.
|
|
135
|
+
*/
|
|
136
|
+
interface PeriodUpdateInput {
|
|
137
|
+
courseId: string;
|
|
138
|
+
strategyId: string;
|
|
139
|
+
currentWeight: LearnableWeight;
|
|
140
|
+
gradient: GradientResult;
|
|
141
|
+
existingState?: StrategyLearningState;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Result of a period update for a single strategy.
|
|
145
|
+
*/
|
|
146
|
+
interface PeriodUpdateResult {
|
|
147
|
+
strategyId: string;
|
|
148
|
+
previousWeight: LearnableWeight;
|
|
149
|
+
newWeight: LearnableWeight;
|
|
150
|
+
gradient: GradientResult;
|
|
151
|
+
learningState: StrategyLearningState;
|
|
152
|
+
updated: boolean;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Run a period update for a single strategy.
|
|
156
|
+
*
|
|
157
|
+
* This function:
|
|
158
|
+
* 1. Takes the computed gradient
|
|
159
|
+
* 2. Computes the new weight
|
|
160
|
+
* 3. Generates the updated learning state
|
|
161
|
+
*
|
|
162
|
+
* Note: Actual persistence (updating strategy doc, saving learning state)
|
|
163
|
+
* must be done by the caller with appropriate DB access.
|
|
164
|
+
*
|
|
165
|
+
* @param input - Update input data
|
|
166
|
+
* @returns Update result with new weight and learning state
|
|
167
|
+
*/
|
|
168
|
+
declare function runPeriodUpdate(input: PeriodUpdateInput): PeriodUpdateResult;
|
|
169
|
+
/**
|
|
170
|
+
* Create a default LearnableWeight for strategies that don't have one.
|
|
171
|
+
*/
|
|
172
|
+
declare function getDefaultLearnableWeight(): LearnableWeight;
|
|
173
|
+
|
|
174
|
+
interface SignalConfig {
|
|
175
|
+
/** Target accuracy for "in the zone" learning (default: 0.85) */
|
|
176
|
+
targetAccuracy?: number;
|
|
177
|
+
/** Width of the peak plateau (default: 0.05) */
|
|
178
|
+
tolerance?: number;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Computes a scalar signal (0-1) representing the quality of the learning outcome.
|
|
182
|
+
*
|
|
183
|
+
* Current implementation focuses on "accuracy within Zone of Proximal Development".
|
|
184
|
+
* Future versions should include ELO gain rate.
|
|
185
|
+
*
|
|
186
|
+
* @param records - List of question attempts in the period
|
|
187
|
+
* @param config - Configuration for the signal function
|
|
188
|
+
* @returns Score 0.0-1.0, or null if insufficient data
|
|
189
|
+
*/
|
|
190
|
+
declare function computeOutcomeSignal(records: QuestionRecord[], config?: SignalConfig): number | null;
|
|
191
|
+
/**
|
|
192
|
+
* Scores an accuracy value based on how close it is to the target "sweet spot".
|
|
193
|
+
*
|
|
194
|
+
* The function defines a plateau of width (2 * tolerance) around the target
|
|
195
|
+
* where score is 1.0. Outside this plateau, it falls off linearly.
|
|
196
|
+
*
|
|
197
|
+
* @param accuracy - Observed accuracy (0-1)
|
|
198
|
+
* @param target - Target accuracy (e.g. 0.85)
|
|
199
|
+
* @param tolerance - +/- range allowed for max score
|
|
200
|
+
*/
|
|
201
|
+
declare function scoreAccuracyInZone(accuracy: number, target: number, tolerance: number): number;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Records a learning outcome for a specific period of time.
|
|
205
|
+
*
|
|
206
|
+
* This function:
|
|
207
|
+
* 1. Computes a scalar "success" signal from the provided question records
|
|
208
|
+
* 2. Re-computes the deviations that were active for this user/course
|
|
209
|
+
* 3. Persists a UserOutcomeRecord to the user's database
|
|
210
|
+
*
|
|
211
|
+
* This record is later used by the optimization job to correlate
|
|
212
|
+
* deviations with outcomes (Evolutionary Orchestration).
|
|
213
|
+
*
|
|
214
|
+
* @param context - Orchestration context (user, course, etc.)
|
|
215
|
+
* @param periodStart - ISO timestamp of period start
|
|
216
|
+
* @param periodEnd - ISO timestamp of period end (now)
|
|
217
|
+
* @param records - Question records generated during this period
|
|
218
|
+
* @param activeStrategyIds - IDs of strategies active in this course
|
|
219
|
+
* @param eloStart - User's ELO at start of period (optional)
|
|
220
|
+
* @param eloEnd - User's ELO at end of period (optional)
|
|
221
|
+
* @param config - Optional configuration for signal computation
|
|
222
|
+
*/
|
|
223
|
+
declare function recordUserOutcome(context: OrchestrationContext, periodStart: string, periodEnd: string, records: QuestionRecord[], activeStrategyIds: string[], eloStart?: number, eloEnd?: number, config?: SignalConfig): Promise<void>;
|
|
224
|
+
|
|
15
225
|
/**
|
|
16
226
|
* Shared context available to all filters in a pipeline.
|
|
17
227
|
*
|
|
@@ -25,6 +235,8 @@ interface FilterContext {
|
|
|
25
235
|
course: CourseDBInterface;
|
|
26
236
|
/** User's global ELO score for this course */
|
|
27
237
|
userElo: number;
|
|
238
|
+
/** Orchestration context for evolutionary weighting */
|
|
239
|
+
orchestration?: OrchestrationContext;
|
|
28
240
|
}
|
|
29
241
|
/**
|
|
30
242
|
* A filter that transforms a list of weighted cards.
|
|
@@ -104,6 +316,8 @@ interface GeneratorContext {
|
|
|
104
316
|
course: CourseDBInterface;
|
|
105
317
|
/** User's global ELO score for this course */
|
|
106
318
|
userElo: number;
|
|
319
|
+
/** Orchestration context for evolutionary weighting */
|
|
320
|
+
orchestration?: OrchestrationContext;
|
|
107
321
|
}
|
|
108
322
|
/**
|
|
109
323
|
* A generator that produces candidate cards with initial scores.
|
|
@@ -301,4 +515,4 @@ declare function validateProcessorConfig(config: Partial<BulkCardProcessorConfig
|
|
|
301
515
|
errorMessage?: string;
|
|
302
516
|
};
|
|
303
517
|
|
|
304
|
-
export { type BulkCardProcessorConfig, type CardFilter, type CardFilterFactory, type CardGenerator, type CardGeneratorFactory, CardHistory, CardRecord, CourseDBInterface, DocType, DocTypePrefixes, type FilterContext, type GeneratorContext, type ImportResult, Loggable, QuestionRecord, type StrategyStateDoc, type StrategyStateId, UserDBInterface, WeightedCard, areQuestionRecords, buildStrategyStateId, docIsDeleted, getCardHistoryID, importParsedCards, isQuestionRecord, parseCardHistoryID, validateProcessorConfig };
|
|
518
|
+
export { type BulkCardProcessorConfig, type CardFilter, type CardFilterFactory, type CardGenerator, type CardGeneratorFactory, CardHistory, CardRecord, CourseDBInterface, DocType, DocTypePrefixes, type FilterContext, type GeneratorContext, type GradientObservation, type GradientResult, type ImportResult, LearnableWeight, Loggable, OrchestrationContext, type PeriodUpdateInput, type PeriodUpdateResult, QuestionRecord, type SignalConfig, type StrategyLearningState, type StrategyStateDoc, type StrategyStateId, UserDBInterface, UserOutcomeRecord, WeightedCard, aggregateOutcomesForGradient, areQuestionRecords, buildStrategyStateId, computeOutcomeSignal, computeStrategyGradient, docIsDeleted, getCardHistoryID, getDefaultLearnableWeight, importParsedCards, isQuestionRecord, parseCardHistoryID, recordUserOutcome, runPeriodUpdate, scoreAccuracyInZone, updateLearningState, updateStrategyWeight, validateProcessorConfig };
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { W as WeightedCard, U as UserDBInterface, C as CourseDBInterface } from '../contentSource-
|
|
2
|
-
export { J as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, G as ClassroomRegistrationDoc, f as ContentNavigator, q as ContentSourceID, d as CourseInfo, K as CourseRegistration, s as CourseRegistrationDoc, b as CoursesDBInterface,
|
|
3
|
-
export { D as DataLayerProvider } from '../dataLayerProvider-
|
|
4
|
-
import {
|
|
5
|
-
export { d as CardData, e as CourseListData, g as DataShapeData, f as DisplayableData, F as Field, G as GuestUsername, Q as QualifiedCardID, h as QuestionData, S as SkuilderCourseData, a as Tag, T as TagStub, l as log } from '../types-legacy-
|
|
1
|
+
import { a1 as LearnableWeight, L as UserOutcomeRecord, a2 as OrchestrationContext, W as WeightedCard, U as UserDBInterface, C as CourseDBInterface } from '../contentSource-BotbOOfX.js';
|
|
2
|
+
export { J as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, G as ClassroomRegistrationDoc, e as ContentNavigationStrategyData, f as ContentNavigator, q as ContentSourceID, d as CourseInfo, K as CourseRegistration, s as CourseRegistrationDoc, b as CoursesDBInterface, N as NavigatorConstructor, Z as NavigatorRole, _ as NavigatorRoles, Y as Navigators, j as ScheduledCard, H as SessionTrackingData, V as StrategyContribution, i as StudentClassroomDBInterface, h as StudyContentSource, k as StudySessionFailedItem, l as StudySessionFailedNewItem, m as StudySessionFailedReviewItem, S as StudySessionItem, n as StudySessionNewItem, o as StudySessionReviewItem, T as TeacherClassroomDBInterface, I as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, B as UsrCrsDataInterface, a3 as computeDeviation, a5 as computeEffectiveWeight, a4 as computeSpread, a6 as createOrchestrationContext, X as getCardOrigin, O as getRegisteredNavigator, Q as getRegisteredNavigatorNames, r as getStudySource, P as hasRegisteredNavigator, R as initializeNavigatorRegistry, a0 as isFilter, $ as isGenerator, p as isReview, M as registerNavigator } from '../contentSource-BotbOOfX.js';
|
|
3
|
+
export { D as DataLayerProvider } from '../dataLayerProvider-SBpz9jQf.js';
|
|
4
|
+
import { D as DocType, i as QuestionRecord, b as DocTypePrefixes, C as CardHistory, c as CardRecord } from '../types-legacy-JXDxinpU.js';
|
|
5
|
+
export { d as CardData, e as CourseListData, g as DataShapeData, f as DisplayableData, F as Field, G as GuestUsername, Q as QualifiedCardID, h as QuestionData, S as SkuilderCourseData, a as Tag, T as TagStub, l as log } from '../types-legacy-JXDxinpU.js';
|
|
6
6
|
import { DataShape, ParsedCard } from '@vue-skuilder/common';
|
|
7
7
|
import 'moment';
|
|
8
8
|
|
|
@@ -12,6 +12,216 @@ declare abstract class Loggable {
|
|
|
12
12
|
protected error(...args: unknown[]): void;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Snapshot of the learning state for a strategy.
|
|
17
|
+
*
|
|
18
|
+
* Stored in the CourseDB for observability and debugging.
|
|
19
|
+
* Updated periodically by the gradient learning system.
|
|
20
|
+
*/
|
|
21
|
+
interface StrategyLearningState {
|
|
22
|
+
/**
|
|
23
|
+
* Unique ID: "STRATEGY_LEARNING_STATE::{courseId}::{strategyId}"
|
|
24
|
+
*/
|
|
25
|
+
_id: string;
|
|
26
|
+
/** Allow CouchDB to manage revisions */
|
|
27
|
+
_rev?: string;
|
|
28
|
+
docType: DocType.STRATEGY_LEARNING_STATE;
|
|
29
|
+
courseId: string;
|
|
30
|
+
strategyId: string;
|
|
31
|
+
/** Current learned weight (mirrors the strategy doc, for convenience) */
|
|
32
|
+
currentWeight: LearnableWeight;
|
|
33
|
+
/** Most recent regression statistics */
|
|
34
|
+
regression: {
|
|
35
|
+
/** Slope of the linear regression (deviation vs outcome) */
|
|
36
|
+
gradient: number;
|
|
37
|
+
/** Y-intercept of the regression line */
|
|
38
|
+
intercept: number;
|
|
39
|
+
/** R-squared value (0-1), measure of fit quality */
|
|
40
|
+
rSquared: number;
|
|
41
|
+
/** Number of observations used in this regression */
|
|
42
|
+
sampleSize: number;
|
|
43
|
+
/** ISO timestamp of when this regression was computed */
|
|
44
|
+
computedAt: string;
|
|
45
|
+
};
|
|
46
|
+
/** Historical weight snapshots for visualization */
|
|
47
|
+
history: Array<{
|
|
48
|
+
timestamp: string;
|
|
49
|
+
weight: number;
|
|
50
|
+
confidence: number;
|
|
51
|
+
gradient: number;
|
|
52
|
+
}>;
|
|
53
|
+
/** ISO timestamp of last update */
|
|
54
|
+
updatedAt: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Data point for gradient computation: (deviation, outcome) pair.
|
|
58
|
+
*/
|
|
59
|
+
interface GradientObservation {
|
|
60
|
+
/** User's deviation for this strategy [-1, 1] */
|
|
61
|
+
deviation: number;
|
|
62
|
+
/** User's outcome value [0, 1] */
|
|
63
|
+
outcomeValue: number;
|
|
64
|
+
/** Optional: weight for this observation (default 1.0) */
|
|
65
|
+
weight?: number;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Result of linear regression on (deviation, outcome) pairs.
|
|
69
|
+
*/
|
|
70
|
+
interface GradientResult {
|
|
71
|
+
/** Slope: positive = higher deviation correlates with better outcomes */
|
|
72
|
+
gradient: number;
|
|
73
|
+
/** Y-intercept */
|
|
74
|
+
intercept: number;
|
|
75
|
+
/** R-squared: 0-1, how well the line fits */
|
|
76
|
+
rSquared: number;
|
|
77
|
+
/** Number of observations */
|
|
78
|
+
sampleSize: number;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Extract (deviation, outcome) observations for a specific strategy
|
|
83
|
+
* from a collection of UserOutcomeRecords.
|
|
84
|
+
*
|
|
85
|
+
* @param outcomes - Collection of outcome records (from multiple users)
|
|
86
|
+
* @param strategyId - The strategy to extract observations for
|
|
87
|
+
* @returns Array of gradient observations
|
|
88
|
+
*/
|
|
89
|
+
declare function aggregateOutcomesForGradient(outcomes: UserOutcomeRecord[], strategyId: string): GradientObservation[];
|
|
90
|
+
/**
|
|
91
|
+
* Compute linear regression on (deviation, outcome) pairs.
|
|
92
|
+
*
|
|
93
|
+
* Uses ordinary least squares to find the best fit line:
|
|
94
|
+
* outcome = gradient * deviation + intercept
|
|
95
|
+
*
|
|
96
|
+
* The gradient tells us:
|
|
97
|
+
* - Positive: users with higher deviation (higher weight) had better outcomes
|
|
98
|
+
* → we should increase the peak weight
|
|
99
|
+
* - Negative: users with higher deviation (higher weight) had worse outcomes
|
|
100
|
+
* → we should decrease the peak weight
|
|
101
|
+
* - Near zero: weight doesn't affect outcomes much
|
|
102
|
+
* → we're near optimal, increase confidence
|
|
103
|
+
*
|
|
104
|
+
* @param observations - Array of (deviation, outcome) pairs
|
|
105
|
+
* @returns Regression result, or null if insufficient data
|
|
106
|
+
*/
|
|
107
|
+
declare function computeStrategyGradient(observations: GradientObservation[]): GradientResult | null;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Compute updated weight based on gradient result.
|
|
111
|
+
*
|
|
112
|
+
* The update logic:
|
|
113
|
+
* - Positive gradient: users with higher weight did better → increase weight
|
|
114
|
+
* - Negative gradient: users with higher weight did worse → decrease weight
|
|
115
|
+
* - Flat gradient: weight doesn't affect outcome → increase confidence
|
|
116
|
+
*
|
|
117
|
+
* @param current - Current learnable weight
|
|
118
|
+
* @param gradient - Computed gradient result
|
|
119
|
+
* @returns Updated learnable weight
|
|
120
|
+
*/
|
|
121
|
+
declare function updateStrategyWeight(current: LearnableWeight, gradient: GradientResult): LearnableWeight;
|
|
122
|
+
/**
|
|
123
|
+
* Create or update a StrategyLearningState document.
|
|
124
|
+
*
|
|
125
|
+
* @param courseId - Course ID
|
|
126
|
+
* @param strategyId - Strategy ID
|
|
127
|
+
* @param currentWeight - Current learned weight
|
|
128
|
+
* @param gradient - Gradient result from recent computation
|
|
129
|
+
* @param existing - Existing learning state (if any)
|
|
130
|
+
* @returns Updated learning state document
|
|
131
|
+
*/
|
|
132
|
+
declare function updateLearningState(courseId: string, strategyId: string, currentWeight: LearnableWeight, gradient: GradientResult, existing?: StrategyLearningState): StrategyLearningState;
|
|
133
|
+
/**
|
|
134
|
+
* Input data for running a period update on a single strategy.
|
|
135
|
+
*/
|
|
136
|
+
interface PeriodUpdateInput {
|
|
137
|
+
courseId: string;
|
|
138
|
+
strategyId: string;
|
|
139
|
+
currentWeight: LearnableWeight;
|
|
140
|
+
gradient: GradientResult;
|
|
141
|
+
existingState?: StrategyLearningState;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Result of a period update for a single strategy.
|
|
145
|
+
*/
|
|
146
|
+
interface PeriodUpdateResult {
|
|
147
|
+
strategyId: string;
|
|
148
|
+
previousWeight: LearnableWeight;
|
|
149
|
+
newWeight: LearnableWeight;
|
|
150
|
+
gradient: GradientResult;
|
|
151
|
+
learningState: StrategyLearningState;
|
|
152
|
+
updated: boolean;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Run a period update for a single strategy.
|
|
156
|
+
*
|
|
157
|
+
* This function:
|
|
158
|
+
* 1. Takes the computed gradient
|
|
159
|
+
* 2. Computes the new weight
|
|
160
|
+
* 3. Generates the updated learning state
|
|
161
|
+
*
|
|
162
|
+
* Note: Actual persistence (updating strategy doc, saving learning state)
|
|
163
|
+
* must be done by the caller with appropriate DB access.
|
|
164
|
+
*
|
|
165
|
+
* @param input - Update input data
|
|
166
|
+
* @returns Update result with new weight and learning state
|
|
167
|
+
*/
|
|
168
|
+
declare function runPeriodUpdate(input: PeriodUpdateInput): PeriodUpdateResult;
|
|
169
|
+
/**
|
|
170
|
+
* Create a default LearnableWeight for strategies that don't have one.
|
|
171
|
+
*/
|
|
172
|
+
declare function getDefaultLearnableWeight(): LearnableWeight;
|
|
173
|
+
|
|
174
|
+
interface SignalConfig {
|
|
175
|
+
/** Target accuracy for "in the zone" learning (default: 0.85) */
|
|
176
|
+
targetAccuracy?: number;
|
|
177
|
+
/** Width of the peak plateau (default: 0.05) */
|
|
178
|
+
tolerance?: number;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Computes a scalar signal (0-1) representing the quality of the learning outcome.
|
|
182
|
+
*
|
|
183
|
+
* Current implementation focuses on "accuracy within Zone of Proximal Development".
|
|
184
|
+
* Future versions should include ELO gain rate.
|
|
185
|
+
*
|
|
186
|
+
* @param records - List of question attempts in the period
|
|
187
|
+
* @param config - Configuration for the signal function
|
|
188
|
+
* @returns Score 0.0-1.0, or null if insufficient data
|
|
189
|
+
*/
|
|
190
|
+
declare function computeOutcomeSignal(records: QuestionRecord[], config?: SignalConfig): number | null;
|
|
191
|
+
/**
|
|
192
|
+
* Scores an accuracy value based on how close it is to the target "sweet spot".
|
|
193
|
+
*
|
|
194
|
+
* The function defines a plateau of width (2 * tolerance) around the target
|
|
195
|
+
* where score is 1.0. Outside this plateau, it falls off linearly.
|
|
196
|
+
*
|
|
197
|
+
* @param accuracy - Observed accuracy (0-1)
|
|
198
|
+
* @param target - Target accuracy (e.g. 0.85)
|
|
199
|
+
* @param tolerance - +/- range allowed for max score
|
|
200
|
+
*/
|
|
201
|
+
declare function scoreAccuracyInZone(accuracy: number, target: number, tolerance: number): number;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Records a learning outcome for a specific period of time.
|
|
205
|
+
*
|
|
206
|
+
* This function:
|
|
207
|
+
* 1. Computes a scalar "success" signal from the provided question records
|
|
208
|
+
* 2. Re-computes the deviations that were active for this user/course
|
|
209
|
+
* 3. Persists a UserOutcomeRecord to the user's database
|
|
210
|
+
*
|
|
211
|
+
* This record is later used by the optimization job to correlate
|
|
212
|
+
* deviations with outcomes (Evolutionary Orchestration).
|
|
213
|
+
*
|
|
214
|
+
* @param context - Orchestration context (user, course, etc.)
|
|
215
|
+
* @param periodStart - ISO timestamp of period start
|
|
216
|
+
* @param periodEnd - ISO timestamp of period end (now)
|
|
217
|
+
* @param records - Question records generated during this period
|
|
218
|
+
* @param activeStrategyIds - IDs of strategies active in this course
|
|
219
|
+
* @param eloStart - User's ELO at start of period (optional)
|
|
220
|
+
* @param eloEnd - User's ELO at end of period (optional)
|
|
221
|
+
* @param config - Optional configuration for signal computation
|
|
222
|
+
*/
|
|
223
|
+
declare function recordUserOutcome(context: OrchestrationContext, periodStart: string, periodEnd: string, records: QuestionRecord[], activeStrategyIds: string[], eloStart?: number, eloEnd?: number, config?: SignalConfig): Promise<void>;
|
|
224
|
+
|
|
15
225
|
/**
|
|
16
226
|
* Shared context available to all filters in a pipeline.
|
|
17
227
|
*
|
|
@@ -25,6 +235,8 @@ interface FilterContext {
|
|
|
25
235
|
course: CourseDBInterface;
|
|
26
236
|
/** User's global ELO score for this course */
|
|
27
237
|
userElo: number;
|
|
238
|
+
/** Orchestration context for evolutionary weighting */
|
|
239
|
+
orchestration?: OrchestrationContext;
|
|
28
240
|
}
|
|
29
241
|
/**
|
|
30
242
|
* A filter that transforms a list of weighted cards.
|
|
@@ -104,6 +316,8 @@ interface GeneratorContext {
|
|
|
104
316
|
course: CourseDBInterface;
|
|
105
317
|
/** User's global ELO score for this course */
|
|
106
318
|
userElo: number;
|
|
319
|
+
/** Orchestration context for evolutionary weighting */
|
|
320
|
+
orchestration?: OrchestrationContext;
|
|
107
321
|
}
|
|
108
322
|
/**
|
|
109
323
|
* A generator that produces candidate cards with initial scores.
|
|
@@ -301,4 +515,4 @@ declare function validateProcessorConfig(config: Partial<BulkCardProcessorConfig
|
|
|
301
515
|
errorMessage?: string;
|
|
302
516
|
};
|
|
303
517
|
|
|
304
|
-
export { type BulkCardProcessorConfig, type CardFilter, type CardFilterFactory, type CardGenerator, type CardGeneratorFactory, CardHistory, CardRecord, CourseDBInterface, DocType, DocTypePrefixes, type FilterContext, type GeneratorContext, type ImportResult, Loggable, QuestionRecord, type StrategyStateDoc, type StrategyStateId, UserDBInterface, WeightedCard, areQuestionRecords, buildStrategyStateId, docIsDeleted, getCardHistoryID, importParsedCards, isQuestionRecord, parseCardHistoryID, validateProcessorConfig };
|
|
518
|
+
export { type BulkCardProcessorConfig, type CardFilter, type CardFilterFactory, type CardGenerator, type CardGeneratorFactory, CardHistory, CardRecord, CourseDBInterface, DocType, DocTypePrefixes, type FilterContext, type GeneratorContext, type GradientObservation, type GradientResult, type ImportResult, LearnableWeight, Loggable, OrchestrationContext, type PeriodUpdateInput, type PeriodUpdateResult, QuestionRecord, type SignalConfig, type StrategyLearningState, type StrategyStateDoc, type StrategyStateId, UserDBInterface, UserOutcomeRecord, WeightedCard, aggregateOutcomesForGradient, areQuestionRecords, buildStrategyStateId, computeOutcomeSignal, computeStrategyGradient, docIsDeleted, getCardHistoryID, getDefaultLearnableWeight, importParsedCards, isQuestionRecord, parseCardHistoryID, recordUserOutcome, runPeriodUpdate, scoreAccuracyInZone, updateLearningState, updateStrategyWeight, validateProcessorConfig };
|