dsh-diagnostic-tutor 0.1.0 → 0.2.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/README.md +316 -79
- package/lib/api.js +364 -78
- package/lib/api.js.map +1 -1
- package/lib/block-types.js +25 -0
- package/lib/block-types.js.map +1 -0
- package/lib/client.js +9952 -821
- package/lib/client.js.map +1 -1
- package/lib/diagnostics.js +170 -0
- package/lib/diagnostics.js.map +1 -0
- package/lib/execution-key.js +91 -0
- package/lib/execution-key.js.map +1 -0
- package/lib/handoff.js +44 -1
- package/lib/handoff.js.map +1 -1
- package/lib/index.js +87 -51
- package/lib/index.js.map +1 -1
- package/lib/insights.js +82 -0
- package/lib/insights.js.map +1 -0
- package/lib/interactions.js +70 -0
- package/lib/interactions.js.map +1 -0
- package/lib/journal.js +122 -0
- package/lib/journal.js.map +1 -0
- package/lib/lesson-markdown.js +72 -0
- package/lib/lesson-markdown.js.map +1 -0
- package/lib/lesson.js +152 -3
- package/lib/lesson.js.map +1 -1
- package/lib/math.js +126 -0
- package/lib/math.js.map +1 -0
- package/lib/path-api.js +140 -0
- package/lib/path-api.js.map +1 -0
- package/lib/path-runtime.js +361 -0
- package/lib/path-runtime.js.map +1 -0
- package/lib/path-tools.js +107 -0
- package/lib/path-tools.js.map +1 -0
- package/lib/path.js +179 -0
- package/lib/path.js.map +1 -0
- package/lib/plan-tools.js +89 -0
- package/lib/plan-tools.js.map +1 -0
- package/lib/plan.js +82 -0
- package/lib/plan.js.map +1 -0
- package/lib/project-session.js +48 -0
- package/lib/project-session.js.map +1 -0
- package/lib/prompt.js +4 -19
- package/lib/prompt.js.map +1 -1
- package/lib/review-sync.js +51 -0
- package/lib/review-sync.js.map +1 -0
- package/lib/review-tools.js +115 -0
- package/lib/review-tools.js.map +1 -0
- package/lib/review.js +103 -0
- package/lib/review.js.map +1 -0
- package/lib/source-schema.js +24 -0
- package/lib/source-schema.js.map +1 -0
- package/lib/source-tools.js +61 -0
- package/lib/source-tools.js.map +1 -0
- package/lib/sources.js +78 -0
- package/lib/sources.js.map +1 -0
- package/lib/state.js +353 -47
- package/lib/state.js.map +1 -1
- package/lib/tools.js +620 -123
- package/lib/tools.js.map +1 -1
- package/lib/types/api.d.ts +10 -3
- package/lib/types/api.d.ts.map +1 -1
- package/lib/types/block-types.d.ts +12 -0
- package/lib/types/block-types.d.ts.map +1 -0
- package/lib/types/contract.d.ts +81 -7
- package/lib/types/contract.d.ts.map +1 -1
- package/lib/types/diagnostics.d.ts +95 -0
- package/lib/types/diagnostics.d.ts.map +1 -0
- package/lib/types/execution-key.d.ts +59 -0
- package/lib/types/execution-key.d.ts.map +1 -0
- package/lib/types/handoff.d.ts +2 -2
- package/lib/types/handoff.d.ts.map +1 -1
- package/lib/types/index.d.ts +19 -14
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/insights.d.ts +57 -0
- package/lib/types/insights.d.ts.map +1 -0
- package/lib/types/interactions.d.ts +23 -0
- package/lib/types/interactions.d.ts.map +1 -0
- package/lib/types/journal.d.ts +57 -0
- package/lib/types/journal.d.ts.map +1 -0
- package/lib/types/lesson-markdown.d.ts +11 -0
- package/lib/types/lesson-markdown.d.ts.map +1 -0
- package/lib/types/lesson.d.ts +697 -5
- package/lib/types/lesson.d.ts.map +1 -1
- package/lib/types/math.d.ts +50 -0
- package/lib/types/math.d.ts.map +1 -0
- package/lib/types/path-api.d.ts +5 -0
- package/lib/types/path-api.d.ts.map +1 -0
- package/lib/types/path-runtime.d.ts +1558 -0
- package/lib/types/path-runtime.d.ts.map +1 -0
- package/lib/types/path-tools.d.ts +4 -0
- package/lib/types/path-tools.d.ts.map +1 -0
- package/lib/types/path.d.ts +744 -0
- package/lib/types/path.d.ts.map +1 -0
- package/lib/types/plan-tools.d.ts +4 -0
- package/lib/types/plan-tools.d.ts.map +1 -0
- package/lib/types/plan.d.ts +53 -0
- package/lib/types/plan.d.ts.map +1 -0
- package/lib/types/project-session.d.ts +33 -0
- package/lib/types/project-session.d.ts.map +1 -0
- package/lib/types/prompt.d.ts.map +1 -1
- package/lib/types/review-sync.d.ts +17 -0
- package/lib/types/review-sync.d.ts.map +1 -0
- package/lib/types/review-tools.d.ts +4 -0
- package/lib/types/review-tools.d.ts.map +1 -0
- package/lib/types/review.d.ts +65 -0
- package/lib/types/review.d.ts.map +1 -0
- package/lib/types/source-schema.d.ts +31 -0
- package/lib/types/source-schema.d.ts.map +1 -0
- package/lib/types/source-tools.d.ts +4 -0
- package/lib/types/source-tools.d.ts.map +1 -0
- package/lib/types/sources.d.ts +33 -0
- package/lib/types/sources.d.ts.map +1 -0
- package/lib/types/state.d.ts +607 -23
- package/lib/types/state.d.ts.map +1 -1
- package/lib/types/tools.d.ts +3 -1
- package/lib/types/tools.d.ts.map +1 -1
- package/lib/types/udt.d.ts +20 -24
- package/lib/types/udt.d.ts.map +1 -1
- package/lib/types/version.d.ts +11 -0
- package/lib/types/version.d.ts.map +1 -0
- package/lib/types/vocabulary.d.ts +2 -2
- package/lib/udt.js +72 -19
- package/lib/udt.js.map +1 -1
- package/lib/version.js +26 -0
- package/lib/version.js.map +1 -0
- package/package.json +27 -22
package/lib/math.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host-side math pre-rendering.
|
|
3
|
+
*
|
|
4
|
+
* The browser half is a single JavaScript file with nowhere to serve KaTeX
|
|
5
|
+
* fonts or CSS from, so TeX cannot be typeset there. Instead the host renders
|
|
6
|
+
* every formula to a MathML subtree at write time and stores that subtree next
|
|
7
|
+
* to the original TeX. The browser renders native MathML; no font, stylesheet or
|
|
8
|
+
* network request is added. TeX remains the source of truth for re-rendering and
|
|
9
|
+
* export.
|
|
10
|
+
*
|
|
11
|
+
* Only the `<math>` element is stored. KaTeX's wrapper `<span class="katex">`
|
|
12
|
+
* is deliberately dropped: the client whitelist should never have to decide
|
|
13
|
+
* what to do with arbitrary KaTeX chrome.
|
|
14
|
+
*/
|
|
15
|
+
import katex from 'katex';
|
|
16
|
+
import { MAX_MATHML_CHARS, MAX_MATH_TEX_CHARS } from './lesson.js';
|
|
17
|
+
/** The skill's convention: inline `\(...\)`, display `\[...\]`. */
|
|
18
|
+
const MATH_PATTERN = /\\\[([\s\S]*?)\\\]|\\\(([\s\S]*?)\\\)/g;
|
|
19
|
+
/**
|
|
20
|
+
* Mark byte ranges that are fenced code so math-looking text inside a code
|
|
21
|
+
* sample is not rendered. Offsets are JavaScript string indices.
|
|
22
|
+
*/
|
|
23
|
+
function fenceMask(markdown) {
|
|
24
|
+
const ranges = [];
|
|
25
|
+
const lines = markdown.split('\n');
|
|
26
|
+
let offset = 0;
|
|
27
|
+
let open = null;
|
|
28
|
+
for (const line of lines) {
|
|
29
|
+
const next = offset + line.length + 1;
|
|
30
|
+
if (line.trimStart().startsWith('```')) {
|
|
31
|
+
if (open === null)
|
|
32
|
+
open = offset;
|
|
33
|
+
else {
|
|
34
|
+
ranges.push([open, next]);
|
|
35
|
+
open = null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
offset = next;
|
|
39
|
+
}
|
|
40
|
+
if (open !== null)
|
|
41
|
+
ranges.push([open, markdown.length]);
|
|
42
|
+
return ranges;
|
|
43
|
+
}
|
|
44
|
+
function masked(index, ranges) {
|
|
45
|
+
return ranges.some(([start, end]) => index >= start && index < end);
|
|
46
|
+
}
|
|
47
|
+
/** Extract every formula in the skill's delimiters, skipping fenced code. */
|
|
48
|
+
export function extractMath(markdown) {
|
|
49
|
+
const ranges = fenceMask(markdown);
|
|
50
|
+
const found = [];
|
|
51
|
+
for (const match of markdown.matchAll(MATH_PATTERN)) {
|
|
52
|
+
const index = match.index ?? 0;
|
|
53
|
+
if (masked(index, ranges))
|
|
54
|
+
continue;
|
|
55
|
+
const display = match[1] !== undefined;
|
|
56
|
+
const tex = ((display ? match[1] : match[2]) ?? '').trim();
|
|
57
|
+
if (tex.length === 0)
|
|
58
|
+
continue;
|
|
59
|
+
found.push({ tex, display, start: index, end: index + (match[0] ?? '').length });
|
|
60
|
+
}
|
|
61
|
+
return found;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Render one TeX expression to a stored MathML subtree.
|
|
65
|
+
*
|
|
66
|
+
* Invalid TeX is a caller-visible error: a formula block that cannot be
|
|
67
|
+
* rendered should be rejected at the boundary, not stored as an unexplained
|
|
68
|
+
* blank. Text blocks use the non-throwing `renderMathFragments` instead so one
|
|
69
|
+
* bad inline expression cannot destroy an otherwise useful unit.
|
|
70
|
+
*/
|
|
71
|
+
export function renderTexToMathML(tex, display = false) {
|
|
72
|
+
if (tex.trim().length === 0)
|
|
73
|
+
throw new Error('empty-formula');
|
|
74
|
+
if (tex.length > MAX_MATH_TEX_CHARS)
|
|
75
|
+
throw new Error('formula-too-long');
|
|
76
|
+
let rendered;
|
|
77
|
+
try {
|
|
78
|
+
rendered = katex.renderToString(tex, {
|
|
79
|
+
output: 'mathml',
|
|
80
|
+
displayMode: display,
|
|
81
|
+
throwOnError: true,
|
|
82
|
+
strict: 'ignore',
|
|
83
|
+
trust: false,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
catch (cause) {
|
|
87
|
+
throw new Error(`invalid-formula: ${cause.message}`);
|
|
88
|
+
}
|
|
89
|
+
const match = /<math[\s\S]*?<\/math>/.exec(rendered);
|
|
90
|
+
if (match === null)
|
|
91
|
+
throw new Error('invalid-formula: no MathML produced');
|
|
92
|
+
if (match[0].length > MAX_MATHML_CHARS)
|
|
93
|
+
throw new Error('formula-mathml-too-long');
|
|
94
|
+
return match[0];
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Pre-render every valid formula in a markdown string.
|
|
98
|
+
*
|
|
99
|
+
* A bad inline expression is skipped, leaving the raw delimiters for the
|
|
100
|
+
* existing styled fallback; the rest of the unit still renders. Fragments are
|
|
101
|
+
* unique by (tex, display) to keep the stored record small.
|
|
102
|
+
*/
|
|
103
|
+
export function renderMathFragments(markdown) {
|
|
104
|
+
const unique = new Map();
|
|
105
|
+
for (const formula of extractMath(markdown)) {
|
|
106
|
+
const key = `${formula.display ? 'd' : 'i'}:${formula.tex}`;
|
|
107
|
+
if (unique.has(key))
|
|
108
|
+
continue;
|
|
109
|
+
try {
|
|
110
|
+
unique.set(key, {
|
|
111
|
+
tex: formula.tex,
|
|
112
|
+
display: formula.display,
|
|
113
|
+
mathml: renderTexToMathML(formula.tex, formula.display),
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// Preserve the raw text; the client falls back to the old styled math.
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return [...unique.values()];
|
|
121
|
+
}
|
|
122
|
+
/** True when a Markdown body contains at least one formula. */
|
|
123
|
+
export function hasMath(markdown) {
|
|
124
|
+
return extractMath(markdown).length > 0;
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=math.js.map
|
package/lib/math.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"math.js","sourceRoot":"","sources":["../src/math.ts"],"names":[],"mappings":"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"}
|
package/lib/path-api.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { activeAttempt } from './path.js';
|
|
3
|
+
import { AnswerSubmissionSchema, recordBlockResponse } from './interactions.js';
|
|
4
|
+
import { acceptCurriculum, beginCourseItem, pathView, pauseCourseItem, reservePathRequest, saveAssessment, saveBrief, selectedProject, stampCoursePrompt, stampPathRequest, } from './path-runtime.js';
|
|
5
|
+
const identity = z.object({ courseId: z.string().min(1), sessionId: z.string().min(1), expectedRevision: z.number().int().min(0) });
|
|
6
|
+
function send(res, status, value) {
|
|
7
|
+
res.statusCode = status;
|
|
8
|
+
res.setHeader('content-type', 'application/json; charset=utf-8');
|
|
9
|
+
res.setHeader('cache-control', 'no-store');
|
|
10
|
+
res.setHeader('x-content-type-options', 'nosniff');
|
|
11
|
+
res.end(JSON.stringify(value));
|
|
12
|
+
}
|
|
13
|
+
async function body(req) {
|
|
14
|
+
let size = 0;
|
|
15
|
+
const chunks = [];
|
|
16
|
+
for await (const chunk of req) {
|
|
17
|
+
const part = Buffer.from(chunk);
|
|
18
|
+
if ((size += part.length) > 65536)
|
|
19
|
+
throw new Error('body-too-large');
|
|
20
|
+
chunks.push(part);
|
|
21
|
+
}
|
|
22
|
+
return JSON.parse(Buffer.concat(chunks).toString('utf8'));
|
|
23
|
+
}
|
|
24
|
+
export async function handlePathApi(route, req, res, deps, url) {
|
|
25
|
+
if (route !== '/path' && !route.startsWith('/path/'))
|
|
26
|
+
return false;
|
|
27
|
+
try {
|
|
28
|
+
if (req.method === 'GET' && route === '/path') {
|
|
29
|
+
const sessionId = url.searchParams.get('sessionId') || undefined;
|
|
30
|
+
const courseId = url.searchParams.get('courseId') || deps.state.resolveProject(sessionId).course?.id;
|
|
31
|
+
if (!courseId)
|
|
32
|
+
throw new Error('no-selected-project');
|
|
33
|
+
send(res, 200, pathView(deps.state, courseId, sessionId));
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
if (req.method !== 'POST') {
|
|
37
|
+
send(res, 405, { ok: false, error: { code: 'method-not-allowed' } });
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
const raw = await body(req);
|
|
41
|
+
const base = identity.parse(raw);
|
|
42
|
+
const state = deps.state;
|
|
43
|
+
selectedProject(state, base.courseId, base.sessionId);
|
|
44
|
+
if (route === '/path/brief') {
|
|
45
|
+
const input = identity.extend({ brief: z.unknown() }).parse(raw);
|
|
46
|
+
const saved = await saveBrief(state, base.courseId, base.sessionId, base.expectedRevision, input.brief);
|
|
47
|
+
deps.onEvent?.('path.brief', { courseId: base.courseId, sessionId: base.sessionId, revision: saved.revision });
|
|
48
|
+
}
|
|
49
|
+
else if (route === '/path/skip-assessment') {
|
|
50
|
+
const path = pathView(state, base.courseId, base.sessionId).path;
|
|
51
|
+
const saved = await saveAssessment(state, base.courseId, base.sessionId, base.expectedRevision, {
|
|
52
|
+
status: 'skipped', summary: 'The learner chose to start with unverified foundations.', strengths: [], gaps: [],
|
|
53
|
+
uncertainties: ['Foundations have not been checked; early lessons need diagnostic checks.'], evidence: [],
|
|
54
|
+
briefRevision: path.briefRevision, sessionId: base.sessionId, updatedAt: new Date().toISOString(),
|
|
55
|
+
}, true);
|
|
56
|
+
deps.onEvent?.('path.skip-diagnosis', { courseId: base.courseId, sessionId: base.sessionId, revision: saved.revision });
|
|
57
|
+
}
|
|
58
|
+
else if (route === '/path/accept') {
|
|
59
|
+
const input = identity.extend({ version: z.number().int().positive() }).parse(raw);
|
|
60
|
+
const accepted = await acceptCurriculum(state, base.courseId, base.sessionId, base.expectedRevision, input.version);
|
|
61
|
+
deps.onEvent?.('path.accept-route', { courseId: base.courseId, sessionId: base.sessionId, version: input.version, revision: accepted.revision });
|
|
62
|
+
}
|
|
63
|
+
else if (route === '/path/request') {
|
|
64
|
+
const input = identity.extend({ kind: z.enum(['diagnosis', 'plan']), operationId: z.string().min(1).max(200) }).parse(raw);
|
|
65
|
+
const request = await reservePathRequest(state, input);
|
|
66
|
+
let prompted = request.request.prompted;
|
|
67
|
+
let reason = request.request.reason ?? undefined;
|
|
68
|
+
if (request.shouldPrompt && state.resolveProject(base.sessionId).course?.id === base.courseId) {
|
|
69
|
+
try {
|
|
70
|
+
const result = deps.prompt(base.sessionId, request.prompt);
|
|
71
|
+
prompted = result.prompted;
|
|
72
|
+
reason = result.reason;
|
|
73
|
+
}
|
|
74
|
+
catch (cause) {
|
|
75
|
+
prompted = false;
|
|
76
|
+
reason = cause.message;
|
|
77
|
+
}
|
|
78
|
+
await stampPathRequest(state, base.courseId, base.sessionId, input.operationId, prompted, reason);
|
|
79
|
+
}
|
|
80
|
+
deps.onEvent?.('path.request', {
|
|
81
|
+
courseId: base.courseId, sessionId: base.sessionId, kind: input.kind, requestId: input.operationId,
|
|
82
|
+
prompted, ...(reason === undefined ? {} : { reason: reason.slice(0, 240) }),
|
|
83
|
+
});
|
|
84
|
+
send(res, 200, { ...pathView(state, base.courseId, base.sessionId), prompted, ...(reason ? { promptReason: reason } : {}) });
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
else if (route === '/path/answer') {
|
|
88
|
+
const input = identity.extend(AnswerSubmissionSchema.shape).parse(raw);
|
|
89
|
+
const view = await recordBlockResponse(state, { ...base, ...input });
|
|
90
|
+
deps.onEvent?.('path.answer', { courseId: base.courseId, sessionId: base.sessionId, attemptId: input.attemptId, blockId: input.blockId });
|
|
91
|
+
send(res, 200, view);
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
else if (route === '/path/pause') {
|
|
95
|
+
const paused = await pauseCourseItem(state, base);
|
|
96
|
+
deps.onEvent?.('path.pause', { courseId: base.courseId, sessionId: base.sessionId });
|
|
97
|
+
send(res, 200, paused);
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
else if (route === '/path/start') {
|
|
101
|
+
const input = identity.extend({ version: z.number().int().positive(), itemId: z.string().min(1).max(200), operationId: z.string().min(1).max(200), review: z.boolean().optional(), resume: z.boolean().optional(), checkin: z.boolean().optional(), teachBack: z.boolean().optional() }).parse(raw);
|
|
102
|
+
const result = await beginCourseItem(state, input);
|
|
103
|
+
let prompted = result.attempt.prompted;
|
|
104
|
+
let reason = result.attempt.promptReason ?? undefined;
|
|
105
|
+
if (result.shouldPrompt && activeAttempt(state.readCourseRun(base.courseId, base.sessionId))?.id === result.attempt.id && state.resolveProject(base.sessionId).course?.id === base.courseId) {
|
|
106
|
+
try {
|
|
107
|
+
const outcome = deps.prompt(base.sessionId, result.prompt);
|
|
108
|
+
prompted = outcome.prompted;
|
|
109
|
+
reason = outcome.reason;
|
|
110
|
+
}
|
|
111
|
+
catch (cause) {
|
|
112
|
+
prompted = false;
|
|
113
|
+
reason = cause.message;
|
|
114
|
+
}
|
|
115
|
+
await stampCoursePrompt(state, input, result.attempt.id, prompted, reason);
|
|
116
|
+
}
|
|
117
|
+
deps.onEvent?.('path.start-lesson', {
|
|
118
|
+
courseId: base.courseId, sessionId: base.sessionId, version: input.version, itemId: input.itemId,
|
|
119
|
+
attemptId: result.attempt.id, resume: input.resume === true, checkin: input.checkin === true, teachBack: input.teachBack === true,
|
|
120
|
+
prompted, ...(reason === undefined ? {} : { reason: reason.slice(0, 240) }),
|
|
121
|
+
});
|
|
122
|
+
send(res, 200, { ...pathView(state, base.courseId, base.sessionId), prompted, ...(reason ? { promptReason: reason } : {}) });
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
send(res, 404, { ok: false, error: { code: 'no-such-path-route' } });
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
send(res, 200, pathView(state, base.courseId, base.sessionId));
|
|
130
|
+
}
|
|
131
|
+
catch (cause) {
|
|
132
|
+
const message = cause instanceof z.ZodError ? cause.issues.map((entry) => `${entry.path.join('.')}: ${entry.message}`).join('; ') : cause.message;
|
|
133
|
+
const code = message.split(':')[0] ?? 'invalid-planning-request';
|
|
134
|
+
deps.onEvent?.('path.error', { route, code: code.slice(0, 80) });
|
|
135
|
+
const status = code === 'revision-conflict' || code === 'project-selection-changed' || code === 'stale-curriculum' || code === 'stale-attempt' ? 409 : code === 'no-such-course' ? 404 : 400;
|
|
136
|
+
send(res, status, { ok: false, error: { code, message } });
|
|
137
|
+
}
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=path-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-api.js","sourceRoot":"","sources":["../src/path-api.ts"],"names":[],"mappings":"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"}
|