@intellectif/lk-core 1.3.0 → 1.4.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/CHANGELOG.md +14 -0
- package/dist/{ai-B222dtHH.d.ts → ai-CnmLPMzd.d.cts} +265 -2
- package/dist/ai-CnmLPMzd.d.cts.map +1 -0
- package/dist/{ai-B222dtHH.d.cts → ai-CnmLPMzd.d.ts} +265 -2
- package/dist/ai-CnmLPMzd.d.ts.map +1 -0
- package/dist/ai-check.cjs +101 -8
- package/dist/ai-check.cjs.map +1 -1
- package/dist/ai-check.d.cts +1 -1
- package/dist/ai-check.d.cts.map +1 -1
- package/dist/ai-check.d.ts +1 -1
- package/dist/ai-check.d.ts.map +1 -1
- package/dist/ai-check.js +101 -8
- package/dist/ai-check.js.map +1 -1
- package/dist/{ai-writing-CCBjTOM3.js → ai-writing-CPpH9Qxq.js} +126 -21
- package/dist/ai-writing-CPpH9Qxq.js.map +1 -0
- package/dist/{ai-writing-DCVkv4Zj.cjs → ai-writing-G6tnCGzw.cjs} +114 -3
- package/dist/ai-writing-G6tnCGzw.cjs.map +1 -0
- package/dist/{index-BWPRPIXL.d.ts → index-2nigSf4N.d.cts} +3 -217
- package/dist/index-2nigSf4N.d.cts.map +1 -0
- package/dist/{index-O4_ExlAD.d.cts → index-B54baFUA.d.ts} +3 -217
- package/dist/index-B54baFUA.d.ts.map +1 -0
- package/dist/{index-Dyu66R4-.d.cts → index-BAfEHCnD.d.cts} +2 -2
- package/dist/{index-Dyu66R4-.d.cts.map → index-BAfEHCnD.d.cts.map} +1 -1
- package/dist/{index-CXyOV8sm.d.cts → index-BqMXWuNC.d.cts} +2 -2
- package/dist/{index-CXyOV8sm.d.cts.map → index-BqMXWuNC.d.cts.map} +1 -1
- package/dist/{index-UGxRSopE.d.ts → index-CVWvymVb.d.ts} +2 -2
- package/dist/{index-UGxRSopE.d.ts.map → index-CVWvymVb.d.ts.map} +1 -1
- package/dist/{index-CegM8o15.d.ts → index-CcHDTxIZ.d.ts} +2 -2
- package/dist/{index-CegM8o15.d.ts.map → index-CcHDTxIZ.d.ts.map} +1 -1
- package/dist/index.cjs +2 -1
- package/dist/index.d.cts +35 -7
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +35 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/schemas.d.cts +1 -1
- package/dist/schemas.d.ts +1 -1
- package/dist/scoring.d.cts +2 -2
- package/dist/scoring.d.ts +2 -2
- package/dist/xapi.d.cts +1 -1
- package/dist/xapi.d.ts +1 -1
- package/package.json +1 -1
- package/dist/ai-B222dtHH.d.cts.map +0 -1
- package/dist/ai-B222dtHH.d.ts.map +0 -1
- package/dist/ai-writing-CCBjTOM3.js.map +0 -1
- package/dist/ai-writing-DCVkv4Zj.cjs.map +0 -1
- package/dist/index-BWPRPIXL.d.ts.map +0 -1
- package/dist/index-O4_ExlAD.d.cts.map +0 -1
|
@@ -1,6 +1,95 @@
|
|
|
1
1
|
const require_registry = require("./registry-DVi0LR_i.cjs");
|
|
2
2
|
const require_scoring = require("./scoring-B2_HEhMT.cjs");
|
|
3
3
|
const require_item_group = require("./item-group-DroFXgLb.cjs");
|
|
4
|
+
//#region src/ai-material.ts
|
|
5
|
+
/**
|
|
6
|
+
* What a model is told about the group a question sits in: the material the
|
|
7
|
+
* learner reads and sees beside it.
|
|
8
|
+
*
|
|
9
|
+
* Internal: the request builders in `ai.ts` and `ai-writing.ts` are its public
|
|
10
|
+
* face, through their `group` input.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* The longest material text a model is given, in code points. A longer one is
|
|
14
|
+
* cut and marked `truncated`: a long reading passage on an exam paper runs to
|
|
15
|
+
* 4,000–7,000.
|
|
16
|
+
*/
|
|
17
|
+
const AI_MATERIAL_MAX_LENGTH = 12e3;
|
|
18
|
+
const KINDS$2 = {
|
|
19
|
+
text: true,
|
|
20
|
+
audio: true,
|
|
21
|
+
video: true,
|
|
22
|
+
image: true,
|
|
23
|
+
mixed: true
|
|
24
|
+
};
|
|
25
|
+
const MEDIA_TYPES = {
|
|
26
|
+
image: true,
|
|
27
|
+
audio: true,
|
|
28
|
+
video: true,
|
|
29
|
+
embed: true
|
|
30
|
+
};
|
|
31
|
+
const isRecord$4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
32
|
+
/** A string with something in it, as written; otherwise nothing. */
|
|
33
|
+
const filled = (value) => typeof value === "string" && value.trim() !== "" ? value : void 0;
|
|
34
|
+
/**
|
|
35
|
+
* `text` cut to {@link AI_MATERIAL_MAX_LENGTH} code points. The cut falls at
|
|
36
|
+
* the last space in its second half, so no word is broken; in a script written
|
|
37
|
+
* without spaces, at the limit itself.
|
|
38
|
+
*/
|
|
39
|
+
function cut(text) {
|
|
40
|
+
const points = [...text];
|
|
41
|
+
if (points.length <= 12e3) return {
|
|
42
|
+
text,
|
|
43
|
+
truncated: false
|
|
44
|
+
};
|
|
45
|
+
let end = AI_MATERIAL_MAX_LENGTH;
|
|
46
|
+
for (let at = AI_MATERIAL_MAX_LENGTH; at >= AI_MATERIAL_MAX_LENGTH / 2; at -= 1) if (/\s/u.test(points[at])) {
|
|
47
|
+
end = at;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
text: points.slice(0, end).join("").trimEnd(),
|
|
52
|
+
truncated: true
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The facts of `group`'s material, or `null` without a group or a stimulus it
|
|
57
|
+
* can read: not an object, or of a kind the SDK does not know.
|
|
58
|
+
*
|
|
59
|
+
* Only what the learner sees reaches a model. The `transcript` is author-only
|
|
60
|
+
* and never read, so the facts are the same for a whole group and a redacted
|
|
61
|
+
* one; a media address is never read either, since a model cannot open one
|
|
62
|
+
* and a signed address must not end up in a prompt. Each field is read once.
|
|
63
|
+
*/
|
|
64
|
+
function materialFacts(group) {
|
|
65
|
+
if (!isRecord$4(group)) return null;
|
|
66
|
+
const stimulus = group.stimulus;
|
|
67
|
+
if (!isRecord$4(stimulus)) return null;
|
|
68
|
+
const kind = stimulus.kind;
|
|
69
|
+
if (typeof kind !== "string" || !Object.hasOwn(KINDS$2, kind)) return null;
|
|
70
|
+
const title = filled(stimulus.title) ?? filled(group.title);
|
|
71
|
+
const body = filled(stimulus.body);
|
|
72
|
+
const text = body === void 0 ? void 0 : cut(body);
|
|
73
|
+
const rawMedia = stimulus.media;
|
|
74
|
+
const mediaType = isRecord$4(rawMedia) ? rawMedia.type : void 0;
|
|
75
|
+
const alt = isRecord$4(rawMedia) ? filled(rawMedia.alt) : void 0;
|
|
76
|
+
const media = typeof mediaType === "string" && Object.hasOwn(MEDIA_TYPES, mediaType) ? {
|
|
77
|
+
type: mediaType,
|
|
78
|
+
...alt !== void 0 ? { alt } : {}
|
|
79
|
+
} : void 0;
|
|
80
|
+
const attribution = filled(stimulus.attribution);
|
|
81
|
+
const locale = filled(stimulus.locale);
|
|
82
|
+
return {
|
|
83
|
+
kind,
|
|
84
|
+
...title !== void 0 ? { title } : {},
|
|
85
|
+
...text !== void 0 ? { text: text.text } : {},
|
|
86
|
+
...text?.truncated === true ? { truncated: true } : {},
|
|
87
|
+
...media !== void 0 ? { media } : {},
|
|
88
|
+
...attribution !== void 0 ? { attribution } : {},
|
|
89
|
+
...locale !== void 0 ? { locale } : {}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
4
93
|
//#region src/ai-text.ts
|
|
5
94
|
/**
|
|
6
95
|
* How the SDK reads text a model wrote, before a learner does. Internal: shared
|
|
@@ -341,6 +430,10 @@ function gradeLocally(data, response) {
|
|
|
341
430
|
* positive and finite, `score` finite from 0 to it) gets no explanation at all:
|
|
342
431
|
* explaining 85 "out of 1" would tell the model a wrong answer was correct, and
|
|
343
432
|
* grading locally instead would speak to a grade the screen does not show.
|
|
433
|
+
*
|
|
434
|
+
* `group` is the item group the question sits in: its material — the passage,
|
|
435
|
+
* or the instructions the group's questions share — goes with the request as
|
|
436
|
+
* `material`, as the learner sees it.
|
|
344
437
|
*/
|
|
345
438
|
function aiExplanationRequest(input) {
|
|
346
439
|
const { data, response, outcome, learnerLocale } = input;
|
|
@@ -366,10 +459,12 @@ function aiExplanationRequest(input) {
|
|
|
366
459
|
if (grade === null) return null;
|
|
367
460
|
const facts = buildAiFacts(data, response, details);
|
|
368
461
|
if (facts === null) return null;
|
|
462
|
+
const material = materialFacts(input.group);
|
|
369
463
|
return {
|
|
370
464
|
feature: "explanation",
|
|
371
465
|
facts,
|
|
372
466
|
grade,
|
|
467
|
+
...material !== null ? { material } : {},
|
|
373
468
|
...learnerLocale !== void 0 ? { learnerLocale } : {}
|
|
374
469
|
};
|
|
375
470
|
}
|
|
@@ -380,7 +475,11 @@ function aiExplanationRequest(input) {
|
|
|
380
475
|
*
|
|
381
476
|
* The facts carry the key, and which parts the learner has right so far, so a
|
|
382
477
|
* model can hint where it helps. The learner never sees them; a hint that
|
|
383
|
-
* contains an answer is refused by {@link checkAiHint}
|
|
478
|
+
* contains an answer is refused by {@link checkAiHint}, whatever it quotes —
|
|
479
|
+
* the group's material included.
|
|
480
|
+
*
|
|
481
|
+
* `group` is the item group the question sits in, as for
|
|
482
|
+
* {@link aiExplanationRequest}.
|
|
384
483
|
*/
|
|
385
484
|
function aiHintRequest(input) {
|
|
386
485
|
const { data, previousHints, learnerLocale } = input;
|
|
@@ -388,11 +487,13 @@ function aiHintRequest(input) {
|
|
|
388
487
|
const response = input.response ?? emptyResponse(data.type);
|
|
389
488
|
const facts = buildAiFacts(data, response, (response === null ? null : gradeLocally(data, response))?.details ?? null);
|
|
390
489
|
if (facts === null) return null;
|
|
490
|
+
const material = materialFacts(input.group);
|
|
391
491
|
return {
|
|
392
492
|
feature: "hint",
|
|
393
493
|
facts,
|
|
394
494
|
hintNumber: previousHints.length + 1,
|
|
395
495
|
previousHints: [...previousHints],
|
|
496
|
+
...material !== null ? { material } : {},
|
|
396
497
|
...learnerLocale !== void 0 ? { learnerLocale } : {}
|
|
397
498
|
};
|
|
398
499
|
}
|
|
@@ -2204,7 +2305,9 @@ const MAX_TAG_LENGTH = 40;
|
|
|
2204
2305
|
* The facts are the task as the learner saw it, the draft verbatim with its
|
|
2205
2306
|
* word count recomputed as the grader will count it, and the rubric the answer
|
|
2206
2307
|
* will be graded on. `previousFeedback` is the text of the feedback already
|
|
2207
|
-
* shown on earlier drafts, so a model can speak to what changed.
|
|
2308
|
+
* shown on earlier drafts, so a model can speak to what changed. `group` is the
|
|
2309
|
+
* item group the task sits in: its material, the text a summary is of, goes
|
|
2310
|
+
* with the request as `material`.
|
|
2208
2311
|
*/
|
|
2209
2312
|
function aiWritingFeedbackRequest(input) {
|
|
2210
2313
|
const { data, response, learnerLocale } = input;
|
|
@@ -2222,6 +2325,7 @@ function aiWritingFeedbackRequest(input) {
|
|
|
2222
2325
|
weight: criterion.weight
|
|
2223
2326
|
}));
|
|
2224
2327
|
const previousFeedback = [...input.previousFeedback ?? []];
|
|
2328
|
+
const material = materialFacts(input.group);
|
|
2225
2329
|
return {
|
|
2226
2330
|
feature: "writing-feedback",
|
|
2227
2331
|
facts: {
|
|
@@ -2240,6 +2344,7 @@ function aiWritingFeedbackRequest(input) {
|
|
|
2240
2344
|
},
|
|
2241
2345
|
draftNumber: previousFeedback.length + 1,
|
|
2242
2346
|
previousFeedback,
|
|
2347
|
+
...material !== null ? { material } : {},
|
|
2243
2348
|
...learnerLocale !== void 0 ? { learnerLocale } : {}
|
|
2244
2349
|
};
|
|
2245
2350
|
}
|
|
@@ -2539,6 +2644,12 @@ Object.defineProperty(exports, "AI_HINT_TYPES", {
|
|
|
2539
2644
|
return AI_HINT_TYPES;
|
|
2540
2645
|
}
|
|
2541
2646
|
});
|
|
2647
|
+
Object.defineProperty(exports, "AI_MATERIAL_MAX_LENGTH", {
|
|
2648
|
+
enumerable: true,
|
|
2649
|
+
get: function() {
|
|
2650
|
+
return AI_MATERIAL_MAX_LENGTH;
|
|
2651
|
+
}
|
|
2652
|
+
});
|
|
2542
2653
|
Object.defineProperty(exports, "AI_TEXT_MAX_LENGTH", {
|
|
2543
2654
|
enumerable: true,
|
|
2544
2655
|
get: function() {
|
|
@@ -2732,4 +2843,4 @@ Object.defineProperty(exports, "validateItemGroupDraft", {
|
|
|
2732
2843
|
}
|
|
2733
2844
|
});
|
|
2734
2845
|
|
|
2735
|
-
//# sourceMappingURL=ai-writing-
|
|
2846
|
+
//# sourceMappingURL=ai-writing-G6tnCGzw.cjs.map
|