Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | 36x 36x 6400x 36x 36x 1273x 1273x 3258x 3258x | import { z } from "zod";
const SAFE_ID = /^[a-z][a-z0-9-]{0,63}$/;
const questionKindWeightsSchema = z.object({
recall: z.number().int().min(0).max(100),
concept: z.number().int().min(0).max(100),
application: z.number().int().min(0).max(100),
prediction: z.number().int().min(0).max(100),
transfer: z.number().int().min(0).max(100),
}).strict().refine(
(value) => Object.values(value).reduce((sum, weight) => sum + weight, 0) === 100,
"Question-kind weights must sum to 100",
);
export const effectiveTutorStrategySchema = z.object({
schemaVersion: z.literal(1),
id: z.string().regex(SAFE_ID),
questionKindWeights: questionKindWeightsSchema,
sketchSpecificity: z.enum(["prefer", "strict"]),
repetition: z.enum(["strict", "relaxed"]),
remediation: z.enum(["scaffold-first", "question-first"]),
clarification: z.enum(["same-indicator", "new-indicator"]),
progression: z.enum(["mastery-then-advance", "advance-immediately"]),
scaffolding: z.enum(["prefer-content", "prefer-generated"]),
feedbackVerbosity: z.enum(["short", "detailed"]),
hintFirst: z.boolean(),
adaptiveDifficulty: z.literal("current-contract"),
}).strict();
export type EffectiveTutorStrategy = z.infer<typeof effectiveTutorStrategySchema>;
export type TutorStrategyResolutionSource = "example" | "repository" | "built-in";
export const BUILT_IN_TUTOR_STRATEGY: EffectiveTutorStrategy = {
schemaVersion: 1,
id: "built-in-default",
questionKindWeights: {
recall: 10,
concept: 25,
application: 35,
prediction: 15,
transfer: 15,
},
sketchSpecificity: "prefer",
repetition: "strict",
remediation: "scaffold-first",
clarification: "same-indicator",
progression: "mastery-then-advance",
scaffolding: "prefer-content",
feedbackVerbosity: "short",
hintFirst: true,
adaptiveDifficulty: "current-contract",
};
export type StrategyResolution = {
readonly strategy: EffectiveTutorStrategy;
readonly source: TutorStrategyResolutionSource;
};
export function resolveEffectiveTutorStrategy(input: {
readonly perExample?: unknown;
readonly repositoryDefault?: unknown;
}): StrategyResolution {
const candidates: readonly { value: unknown; source: TutorStrategyResolutionSource }[] = [
{ value: input.perExample, source: "example" },
{ value: input.repositoryDefault, source: "repository" },
{ value: BUILT_IN_TUTOR_STRATEGY, source: "built-in" },
];
for (const candidate of candidates) {
const parsed = effectiveTutorStrategySchema.safeParse(candidate.value);
if (parsed.success) return { strategy: parsed.data, source: candidate.source };
}
throw new Error("Built-in Tutor strategy is invalid");
}
|