@intellectif/lk-core 0.16.0 → 0.17.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 +45 -0
- package/dist/{activity-DcxtpX7Z.d.cts → activity-BmjBjXVJ.d.cts} +213 -2
- package/dist/{activity-DcxtpX7Z.d.ts → activity-BmjBjXVJ.d.ts} +213 -2
- package/dist/{chunk-FJJ2GVBA.cjs → chunk-2CV6NU32.cjs} +19 -19
- package/dist/{chunk-FJJ2GVBA.cjs.map → chunk-2CV6NU32.cjs.map} +1 -1
- package/dist/{chunk-IRUD73IQ.js → chunk-D3GP5MET.js} +683 -638
- package/dist/chunk-D3GP5MET.js.map +1 -0
- package/dist/{chunk-F7UOLKWV.cjs → chunk-D4TOPSHV.cjs} +518 -473
- package/dist/chunk-D4TOPSHV.cjs.map +1 -0
- package/dist/{chunk-VFTVZJO5.cjs → chunk-EOFWSGLU.cjs} +4 -4
- package/dist/{chunk-VFTVZJO5.cjs.map → chunk-EOFWSGLU.cjs.map} +1 -1
- package/dist/{chunk-S63IOKFP.js → chunk-WXS5EB65.js} +2 -2
- package/dist/{chunk-OXF7VT7S.js → chunk-X5DAXBJI.js} +2 -2
- package/dist/{chunk-6P6XK2LI.cjs → chunk-XNMKDFPW.cjs} +31 -31
- package/dist/{chunk-6P6XK2LI.cjs.map → chunk-XNMKDFPW.cjs.map} +1 -1
- package/dist/{chunk-GOZGBVJP.js → chunk-Z7QQZ53L.js} +2 -2
- package/dist/{chunk-GOZGBVJP.js.map → chunk-Z7QQZ53L.js.map} +1 -1
- package/dist/{index-BWpwZRQw.d.cts → index-CvfeD_cU.d.cts} +144 -86
- package/dist/{index-DRJqwO2y.d.ts → index-G_KusUcK.d.ts} +144 -86
- package/dist/index.cjs +542 -127
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +122 -5
- package/dist/index.d.ts +122 -5
- package/dist/index.js +422 -7
- package/dist/index.js.map +1 -1
- package/dist/schemas.cjs +5 -3
- package/dist/schemas.cjs.map +1 -1
- package/dist/schemas.d.cts +2 -2
- package/dist/schemas.d.ts +2 -2
- package/dist/schemas.js +4 -2
- package/dist/scoring.cjs +3 -3
- package/dist/scoring.d.cts +2 -2
- package/dist/scoring.d.ts +2 -2
- package/dist/scoring.js +2 -2
- package/dist/xapi.cjs +3 -3
- package/dist/xapi.d.cts +1 -1
- package/dist/xapi.d.ts +1 -1
- package/dist/xapi.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-F7UOLKWV.cjs.map +0 -1
- package/dist/chunk-IRUD73IQ.js.map +0 -1
- /package/dist/{chunk-S63IOKFP.js.map → chunk-WXS5EB65.js.map} +0 -0
- /package/dist/{chunk-OXF7VT7S.js.map → chunk-X5DAXBJI.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
# @intellectif/lk-core
|
|
2
2
|
|
|
3
|
+
## 0.17.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 15a3435: The contract for AI help a learner reads — an explanation of a graded answer, and hints before one —
|
|
8
|
+
between an activity and a model the host runs. The SDK never calls a model and holds no key or prompt;
|
|
9
|
+
it builds what the model is given and checks what comes back.
|
|
10
|
+
|
|
11
|
+
- **Facts:** `buildAiFacts(data, response, details)` describes an item as the learner saw it, their
|
|
12
|
+
answer, and the SDK's own verdict part by part. It covers multiple choice (every option), fill in the
|
|
13
|
+
blanks and gap select (each blank or gap in passage order, the passage written with `[1]`, `[2]`…),
|
|
14
|
+
and dictation (the word-by-word alignment). On a redacted item the key is absent, except where a
|
|
15
|
+
server's outcome supplies it.
|
|
16
|
+
- **Requests:**
|
|
17
|
+
- `aiExplanationRequest({ data, response, outcome?, learnerLocale? })` carries the facts and the
|
|
18
|
+
`grade`, with its `category` (`correct`, `partly-correct` or `incorrect`). A scored `outcome` wins
|
|
19
|
+
over grading locally, so an explanation speaks to the grade of record.
|
|
20
|
+
- `aiHintRequest({ data, response, previousHints, learnerLocale? })` carries the key and the answer
|
|
21
|
+
so far, marked part by part. It gives none for a dictation, which has hints of its own, or for a
|
|
22
|
+
redacted item.
|
|
23
|
+
- **Checks:**
|
|
24
|
+
- `readAiTextResult` refuses anything but plain text of up to 2,000 characters (`malformed`,
|
|
25
|
+
`empty`, `too-long`), with control characters removed.
|
|
26
|
+
- `checkAiExplanation` also refuses an explanation stating a verdict other than the SDK's
|
|
27
|
+
(`contradicts-grade`).
|
|
28
|
+
- `checkAiHint` also refuses a hint that contains an answer (`reveals-answer`).
|
|
29
|
+
- **The guard:** `hintRevealsAnswer(facts, text)` finds an answer written out, ignoring case,
|
|
30
|
+
accents and punctuation. An answer of one short word counts only where the hint writes it beside a
|
|
31
|
+
neighbour it has in the passage, so a hint can still say "the verb is…".
|
|
32
|
+
- **Permissions:** `aiSupports(type, feature)`, `aiAllowedByContent(data, feature)`, `aiGradeOf`, and
|
|
33
|
+
the types `AiItemFacts`, `AiExplanationRequest`, `AiHintRequest`, `AiTextResult`, `AiProvenance`,
|
|
34
|
+
`ActivityAiPermissions` and more. Two new interaction kinds: `ai-hint-shown` and
|
|
35
|
+
`ai-explanation-shown`.
|
|
36
|
+
|
|
37
|
+
**The author's switch, and one tightened rule.** Every built-in type now defines an optional
|
|
38
|
+
`ai: { hints?: boolean, explanations?: boolean }`: `false` switches that help off for the item,
|
|
39
|
+
wherever it is delivered, and an author can only switch help off. `redact()` keeps both flags, as
|
|
40
|
+
public, and drops any other key inside `ai`; the strict redacted schemas accept them.
|
|
41
|
+
|
|
42
|
+
A field named `ai` was until now an unknown key the loose schemas kept, whatever it held. A sidecar
|
|
43
|
+
such as `ai: 'generated'`, or a flag that is not a boolean, now fails `validateActivity`: check stored
|
|
44
|
+
content before upgrading.
|
|
45
|
+
|
|
46
|
+
See `docs/ai.md`.
|
|
47
|
+
|
|
3
48
|
## 0.16.0
|
|
4
49
|
|
|
5
50
|
### Minor Changes
|
|
@@ -63,6 +63,197 @@ declare function levenshteinDistance(a: string, b: string, max: number): number;
|
|
|
63
63
|
*/
|
|
64
64
|
declare function matchText(input: string, accepted: string | readonly string[], policy?: TextMatchPolicy): TextMatchResult;
|
|
65
65
|
|
|
66
|
+
/**
|
|
67
|
+
* The contract between an activity and a model the HOST runs, for help a
|
|
68
|
+
* learner reads: an explanation of a graded answer, and hints before one.
|
|
69
|
+
*
|
|
70
|
+
* The SDK never calls a model and holds no key, prompt or provider. It builds
|
|
71
|
+
* the facts a model is given — from the item, the learner's answer and the
|
|
72
|
+
* SDK's own scorer — and checks what comes back. The model explains a verdict
|
|
73
|
+
* the SDK reached; it never reaches one.
|
|
74
|
+
*/
|
|
75
|
+
/**
|
|
76
|
+
* What an author allows AI to do for one item. Absent, or a feature left out,
|
|
77
|
+
* leaves the choice to the deployment. `false` switches a feature off for this
|
|
78
|
+
* item wherever it is delivered; an author can only switch a feature off,
|
|
79
|
+
* never force one on.
|
|
80
|
+
*
|
|
81
|
+
* Switch hints off where any hint would give the answer away — a
|
|
82
|
+
* one-word vocabulary item, say.
|
|
83
|
+
*/
|
|
84
|
+
interface ActivityAiPermissions {
|
|
85
|
+
/** An explanation of the learner's graded answer. */
|
|
86
|
+
explanations?: boolean;
|
|
87
|
+
/** Hints before the learner submits. */
|
|
88
|
+
hints?: boolean;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* An activity as a renderer holds it: full data or a `redact()` projection.
|
|
92
|
+
* Structural rather than the data union, so a renderer's own view of an item —
|
|
93
|
+
* whose answer-key fields may be absent — is accepted as it is. The AI
|
|
94
|
+
* functions read every field defensively.
|
|
95
|
+
*/
|
|
96
|
+
interface AiActivityInput {
|
|
97
|
+
readonly type: string;
|
|
98
|
+
readonly id: string;
|
|
99
|
+
readonly title: string;
|
|
100
|
+
readonly locale?: unknown;
|
|
101
|
+
readonly redacted?: unknown;
|
|
102
|
+
readonly ai?: unknown;
|
|
103
|
+
}
|
|
104
|
+
/** The two kinds of help a learner can be given. */
|
|
105
|
+
type AiFeature = 'explanation' | 'hint';
|
|
106
|
+
/** The activity types the SDK builds facts for. */
|
|
107
|
+
type AiSupportedActivityType = 'multiple-choice' | 'fill-in-the-blanks' | 'gap-select' | 'dictation';
|
|
108
|
+
/**
|
|
109
|
+
* A whole answer's grade, from the SDK's scorer. `category` is the verdict an
|
|
110
|
+
* explanation must agree with: all marks, some, or none.
|
|
111
|
+
*/
|
|
112
|
+
interface AiGrade {
|
|
113
|
+
score: number;
|
|
114
|
+
maxScore: number;
|
|
115
|
+
passed: boolean;
|
|
116
|
+
category: AiVerdict;
|
|
117
|
+
}
|
|
118
|
+
/** The three verdicts an explanation can speak to. */
|
|
119
|
+
type AiVerdict = 'correct' | 'partly-correct' | 'incorrect';
|
|
120
|
+
interface AiFactsBase {
|
|
121
|
+
activityId: string;
|
|
122
|
+
title: string;
|
|
123
|
+
/** The language the item is written in, when the author gave one. */
|
|
124
|
+
locale?: string;
|
|
125
|
+
}
|
|
126
|
+
/** One option of a multiple-choice question, and what the learner did with it. */
|
|
127
|
+
interface AiOptionFact {
|
|
128
|
+
id: string;
|
|
129
|
+
text: string;
|
|
130
|
+
chosen: boolean;
|
|
131
|
+
/** Whether this option is part of the answer; `null` when the key is not available. */
|
|
132
|
+
correct: boolean | null;
|
|
133
|
+
/** The author's feedback on this option. */
|
|
134
|
+
feedback?: string;
|
|
135
|
+
}
|
|
136
|
+
interface AiMultipleChoiceFacts extends AiFactsBase {
|
|
137
|
+
activityType: 'multiple-choice';
|
|
138
|
+
question: string;
|
|
139
|
+
mode: 'single' | 'multi';
|
|
140
|
+
options: AiOptionFact[];
|
|
141
|
+
}
|
|
142
|
+
/** One blank, in the order it appears in the passage. */
|
|
143
|
+
interface AiBlankFact {
|
|
144
|
+
id: string;
|
|
145
|
+
/** 1-based, in passage order. */
|
|
146
|
+
position: number;
|
|
147
|
+
/** What the learner typed, or `''`. */
|
|
148
|
+
typed: string;
|
|
149
|
+
/** The answers that count; `null` when the key is not available. */
|
|
150
|
+
accepted: string[] | null;
|
|
151
|
+
/** The SDK's verdict on this blank; `null` before it is graded or without a key. */
|
|
152
|
+
correct: boolean | null;
|
|
153
|
+
/** The author's hint for this blank. */
|
|
154
|
+
hint?: string;
|
|
155
|
+
/** The author's feedback for this blank. */
|
|
156
|
+
feedback?: string;
|
|
157
|
+
}
|
|
158
|
+
interface AiFillInTheBlanksFacts extends AiFactsBase {
|
|
159
|
+
activityType: 'fill-in-the-blanks';
|
|
160
|
+
/** The passage, each blank written as `[1]`, `[2]`… in passage order. */
|
|
161
|
+
passage: string;
|
|
162
|
+
blanks: AiBlankFact[];
|
|
163
|
+
}
|
|
164
|
+
/** One gap, in the order it appears in the passage. */
|
|
165
|
+
interface AiGapFact {
|
|
166
|
+
id: string;
|
|
167
|
+
/** 1-based, in passage order. */
|
|
168
|
+
position: number;
|
|
169
|
+
/** The words offered at this gap. */
|
|
170
|
+
choices: string[];
|
|
171
|
+
/** The word the learner chose, or `null`. */
|
|
172
|
+
chosen: string | null;
|
|
173
|
+
/** The right word; `null` when the key is not available. */
|
|
174
|
+
answer: string | null;
|
|
175
|
+
/** The SDK's verdict on this gap; `null` before it is graded or without a key. */
|
|
176
|
+
correct: boolean | null;
|
|
177
|
+
/** The author's feedback for this gap. */
|
|
178
|
+
feedback?: string;
|
|
179
|
+
}
|
|
180
|
+
interface AiGapSelectFacts extends AiFactsBase {
|
|
181
|
+
activityType: 'gap-select';
|
|
182
|
+
/** The passage, each gap written as `[1]`, `[2]`… in passage order. */
|
|
183
|
+
passage: string;
|
|
184
|
+
gaps: AiGapFact[];
|
|
185
|
+
}
|
|
186
|
+
/** One word of a dictation, as the SDK's alignment paired it. */
|
|
187
|
+
interface AiWordFact {
|
|
188
|
+
/** The word the recording says; `''` for an extra word the learner added. */
|
|
189
|
+
expected: string;
|
|
190
|
+
/** The word the learner typed; `''` for a word they left out. */
|
|
191
|
+
typed: string;
|
|
192
|
+
status: 'correct' | 'incorrect' | 'missing' | 'extra';
|
|
193
|
+
}
|
|
194
|
+
interface AiDictationFacts extends AiFactsBase {
|
|
195
|
+
activityType: 'dictation';
|
|
196
|
+
/** What the recording says; `null` when the key is not available. */
|
|
197
|
+
transcript: string | null;
|
|
198
|
+
/** What the learner typed. */
|
|
199
|
+
typed: string;
|
|
200
|
+
/** The alignment word by word; `null` when the key is not available. */
|
|
201
|
+
words: AiWordFact[] | null;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* What a model is told about one item and one answer: the question as the
|
|
205
|
+
* learner saw it, what they answered, and — part by part — the SDK's verdict.
|
|
206
|
+
*/
|
|
207
|
+
type AiItemFacts = AiMultipleChoiceFacts | AiFillInTheBlanksFacts | AiGapSelectFacts | AiDictationFacts;
|
|
208
|
+
/**
|
|
209
|
+
* Asks for an explanation of a graded answer. Sent after the SDK has graded
|
|
210
|
+
* it, so `grade` is always present, and an explanation that contradicts
|
|
211
|
+
* `grade.category` is refused.
|
|
212
|
+
*/
|
|
213
|
+
interface AiExplanationRequest {
|
|
214
|
+
feature: 'explanation';
|
|
215
|
+
facts: AiItemFacts;
|
|
216
|
+
grade: AiGrade;
|
|
217
|
+
/** The language to answer in: the learner's interface language, when known. */
|
|
218
|
+
learnerLocale?: string;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Asks for the next hint before the learner submits. `facts` carries the key
|
|
222
|
+
* so a model can hint toward the answer; the SDK refuses any hint that
|
|
223
|
+
* contains it.
|
|
224
|
+
*/
|
|
225
|
+
interface AiHintRequest {
|
|
226
|
+
feature: 'hint';
|
|
227
|
+
facts: AiItemFacts;
|
|
228
|
+
/** 1-based: the hint being asked for. */
|
|
229
|
+
hintNumber: number;
|
|
230
|
+
/** The hints already shown for this item, oldest first. */
|
|
231
|
+
previousHints: string[];
|
|
232
|
+
learnerLocale?: string;
|
|
233
|
+
}
|
|
234
|
+
/** What produced an AI text, for the record a host keeps. */
|
|
235
|
+
interface AiProvenance {
|
|
236
|
+
/** The model's identifier, e.g. a name and version. */
|
|
237
|
+
model?: string;
|
|
238
|
+
/** A hash or id of the prompt revision. */
|
|
239
|
+
promptHash?: string;
|
|
240
|
+
/** ISO 8601. */
|
|
241
|
+
generatedAt?: string;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* What a host's port returns. Plain text: the SDK renders it as text, never
|
|
245
|
+
* as HTML. An explanation may state the verdict it assumed; one that
|
|
246
|
+
* disagrees with the SDK's is refused.
|
|
247
|
+
*/
|
|
248
|
+
interface AiTextResult {
|
|
249
|
+
text: string;
|
|
250
|
+
/** For an explanation: the verdict the model explained. */
|
|
251
|
+
verdict?: AiVerdict;
|
|
252
|
+
provenance?: AiProvenance;
|
|
253
|
+
}
|
|
254
|
+
/** Why a result was not shown. */
|
|
255
|
+
type AiRefusal = 'malformed' | 'empty' | 'too-long' | 'contradicts-grade' | 'reveals-answer';
|
|
256
|
+
|
|
66
257
|
/**
|
|
67
258
|
* The return trip for deferred grading.
|
|
68
259
|
*
|
|
@@ -590,6 +781,8 @@ interface MultipleChoiceData {
|
|
|
590
781
|
learningObjectives?: string[];
|
|
591
782
|
/** Subjective difficulty on a 1–5 scale. */
|
|
592
783
|
difficultyLevel?: 1 | 2 | 3 | 4 | 5;
|
|
784
|
+
/** What an author allows AI to do for this item: see {@link ActivityAiPermissions}. */
|
|
785
|
+
ai?: ActivityAiPermissions;
|
|
593
786
|
}
|
|
594
787
|
/** Configuration for a single fill-in-the-blank slot. */
|
|
595
788
|
interface BlankConfig {
|
|
@@ -724,6 +917,8 @@ interface GapSelectData {
|
|
|
724
917
|
learningObjectives?: string[];
|
|
725
918
|
/** Subjective difficulty on a 1–5 scale. */
|
|
726
919
|
difficultyLevel?: 1 | 2 | 3 | 4 | 5;
|
|
920
|
+
/** What an author allows AI to do for this item: see {@link ActivityAiPermissions}. */
|
|
921
|
+
ai?: ActivityAiPermissions;
|
|
727
922
|
}
|
|
728
923
|
interface FillInTheBlanksData {
|
|
729
924
|
schemaVersion: '1.0';
|
|
@@ -756,6 +951,8 @@ interface FillInTheBlanksData {
|
|
|
756
951
|
learningObjectives?: string[];
|
|
757
952
|
/** Subjective difficulty on a 1–5 scale. */
|
|
758
953
|
difficultyLevel?: 1 | 2 | 3 | 4 | 5;
|
|
954
|
+
/** What an author allows AI to do for this item: see {@link ActivityAiPermissions}. */
|
|
955
|
+
ai?: ActivityAiPermissions;
|
|
759
956
|
}
|
|
760
957
|
/** A single criterion within a written-response grading rubric. */
|
|
761
958
|
interface WrittenResponseRubricCriterion {
|
|
@@ -818,6 +1015,8 @@ interface WrittenResponseData {
|
|
|
818
1015
|
learningObjectives?: string[];
|
|
819
1016
|
/** Subjective difficulty on a 1–5 scale. */
|
|
820
1017
|
difficultyLevel?: 1 | 2 | 3 | 4 | 5;
|
|
1018
|
+
/** What an author allows AI to do for this item: see {@link ActivityAiPermissions}. */
|
|
1019
|
+
ai?: ActivityAiPermissions;
|
|
821
1020
|
}
|
|
822
1021
|
/**
|
|
823
1022
|
* A second, slower recording of a dictation — a separate file (a text-to-speech
|
|
@@ -920,6 +1119,8 @@ interface DictationData {
|
|
|
920
1119
|
learningObjectives?: string[];
|
|
921
1120
|
/** Subjective difficulty on a 1–5 scale. */
|
|
922
1121
|
difficultyLevel?: 1 | 2 | 3 | 4 | 5;
|
|
1122
|
+
/** What an author allows AI to do for this item: see {@link ActivityAiPermissions}. */
|
|
1123
|
+
ai?: ActivityAiPermissions;
|
|
923
1124
|
}
|
|
924
1125
|
/** A dimension of speech a pronunciation assessor scores, on a 0–100 scale. */
|
|
925
1126
|
type ReadAloudDimension = 'accuracy' | 'fluency' | 'completeness' | 'prosody';
|
|
@@ -1010,6 +1211,8 @@ interface ReadAloudData {
|
|
|
1010
1211
|
learningObjectives?: string[];
|
|
1011
1212
|
/** Subjective difficulty on a 1–5 scale. */
|
|
1012
1213
|
difficultyLevel?: 1 | 2 | 3 | 4 | 5;
|
|
1214
|
+
/** What an author allows AI to do for this item: see {@link ActivityAiPermissions}. */
|
|
1215
|
+
ai?: ActivityAiPermissions;
|
|
1013
1216
|
}
|
|
1014
1217
|
/**
|
|
1015
1218
|
* Maps each ActivityType string to its learner-response shape. Open for
|
|
@@ -1320,7 +1523,15 @@ type InteractionKind = 'option-selected' | 'option-deselected' | 'blank-filled'
|
|
|
1320
1523
|
* primary line's language, or `null` with captions off; `payload.secondary` is
|
|
1321
1524
|
* the second line's, or `null` with none showing. Fires when either changes.
|
|
1322
1525
|
*/
|
|
1323
|
-
| 'video-captions-changed' | 'video-fullscreen-changed' | 'video-pip-changed'
|
|
1526
|
+
| 'video-captions-changed' | 'video-fullscreen-changed' | 'video-pip-changed'
|
|
1527
|
+
/**
|
|
1528
|
+
* An AI hint was shown to the learner (`hintNumber`, and the port's
|
|
1529
|
+
* `provenance` when it sent one). Only a hint the SDK accepted: a refused one
|
|
1530
|
+
* is never shown and never reported here.
|
|
1531
|
+
*/
|
|
1532
|
+
| 'ai-hint-shown'
|
|
1533
|
+
/** An AI explanation of the graded answer was shown (`provenance` when sent). */
|
|
1534
|
+
| 'ai-explanation-shown' | (string & {});
|
|
1324
1535
|
/** Fired by activity components on every discrete learner interaction. */
|
|
1325
1536
|
interface InteractionEvent {
|
|
1326
1537
|
/** The kind of interaction that occurred. */
|
|
@@ -1333,4 +1544,4 @@ interface InteractionEvent {
|
|
|
1333
1544
|
payload: Record<string, unknown>;
|
|
1334
1545
|
}
|
|
1335
1546
|
|
|
1336
|
-
export { type
|
|
1547
|
+
export { type MediaPlaybackPolicy as $, type ActivityAiPermissions as A, type BlankConfig as B, type CriterionScore as C, type DeferredReason as D, type DictationData as E, type DictationEquivalence as F, type DictationLearnerResponse as G, type DictationSlowMedia as H, type DictationTolerance as I, type FillInTheBlanksData as J, type FillInTheBlanksLearnerResponse as K, type GapSelectBank as L, type GapSelectChoice as M, type GapSelectData as N, type GapSelectGap as O, type GapSelectLearnerResponse as P, type GradeRecord as Q, type Grader as R, type GraderKind as S, type GraderUsage as T, type GradingState as U, type InlineCorrection as V, type InteractionEvent as W, type InteractionKind as X, type ItemOutcome as Y, type LearnerResponse as Z, type LearnerResponseMap as _, type ActivityData as a, type MediaTrack as a0, type MultipleChoiceData as a1, type MultipleChoiceLearnerResponse as a2, type MultipleChoiceOption as a3, type MultipleChoiceOptionMedia as a4, type NativeControlHint as a5, type ReadAloudData as a6, type ReadAloudDimension as a7, type ReadAloudDimensionWeight as a8, type ReadAloudLearnerResponse as a9, type ReadAloudSlowMedia as aa, type RecordingBounds as ab, type RecordingRef as ac, type ScoringDetail as ad, type ScoringOutcome as ae, type ScoringResult as af, type TextMatchPolicy as ag, type TextMatchResult as ah, type ValidationError as ai, type ValidationResult as aj, type WrittenResponseData as ak, type WrittenResponseLearnerResponse as al, type WrittenResponseRubric as am, type WrittenResponseRubricCriterion as an, type XAPIActor as ao, type XAPIConfig as ap, type XAPIContext as aq, type XAPIContextActivities as ar, type XAPIError as as, type XAPIObject as at, type XAPIResult as au, type XAPIScore as av, type XAPIStatement as aw, type XAPIVerbObject as ax, levenshteinDistance as ay, matchText as az, type ActivityDataMap as b, type ActivityFeedback as c, type ActivityMedia as d, type ActivityResult as e, type ActivityType as f, type AiActivityInput as g, type AiBlankFact as h, type AiDictationFacts as i, type AiExplanationRequest as j, type AiFeature as k, type AiFillInTheBlanksFacts as l, type AiGapFact as m, type AiGapSelectFacts as n, type AiGrade as o, type AiHintRequest as p, type AiItemFacts as q, type AiMultipleChoiceFacts as r, type AiOptionFact as s, type AiProvenance as t, type AiRefusal as u, type AiSupportedActivityType as v, type AiTextResult as w, type AiVerdict as x, type AiWordFact as y, type DeferredScoringPartial as z };
|
|
@@ -63,6 +63,197 @@ declare function levenshteinDistance(a: string, b: string, max: number): number;
|
|
|
63
63
|
*/
|
|
64
64
|
declare function matchText(input: string, accepted: string | readonly string[], policy?: TextMatchPolicy): TextMatchResult;
|
|
65
65
|
|
|
66
|
+
/**
|
|
67
|
+
* The contract between an activity and a model the HOST runs, for help a
|
|
68
|
+
* learner reads: an explanation of a graded answer, and hints before one.
|
|
69
|
+
*
|
|
70
|
+
* The SDK never calls a model and holds no key, prompt or provider. It builds
|
|
71
|
+
* the facts a model is given — from the item, the learner's answer and the
|
|
72
|
+
* SDK's own scorer — and checks what comes back. The model explains a verdict
|
|
73
|
+
* the SDK reached; it never reaches one.
|
|
74
|
+
*/
|
|
75
|
+
/**
|
|
76
|
+
* What an author allows AI to do for one item. Absent, or a feature left out,
|
|
77
|
+
* leaves the choice to the deployment. `false` switches a feature off for this
|
|
78
|
+
* item wherever it is delivered; an author can only switch a feature off,
|
|
79
|
+
* never force one on.
|
|
80
|
+
*
|
|
81
|
+
* Switch hints off where any hint would give the answer away — a
|
|
82
|
+
* one-word vocabulary item, say.
|
|
83
|
+
*/
|
|
84
|
+
interface ActivityAiPermissions {
|
|
85
|
+
/** An explanation of the learner's graded answer. */
|
|
86
|
+
explanations?: boolean;
|
|
87
|
+
/** Hints before the learner submits. */
|
|
88
|
+
hints?: boolean;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* An activity as a renderer holds it: full data or a `redact()` projection.
|
|
92
|
+
* Structural rather than the data union, so a renderer's own view of an item —
|
|
93
|
+
* whose answer-key fields may be absent — is accepted as it is. The AI
|
|
94
|
+
* functions read every field defensively.
|
|
95
|
+
*/
|
|
96
|
+
interface AiActivityInput {
|
|
97
|
+
readonly type: string;
|
|
98
|
+
readonly id: string;
|
|
99
|
+
readonly title: string;
|
|
100
|
+
readonly locale?: unknown;
|
|
101
|
+
readonly redacted?: unknown;
|
|
102
|
+
readonly ai?: unknown;
|
|
103
|
+
}
|
|
104
|
+
/** The two kinds of help a learner can be given. */
|
|
105
|
+
type AiFeature = 'explanation' | 'hint';
|
|
106
|
+
/** The activity types the SDK builds facts for. */
|
|
107
|
+
type AiSupportedActivityType = 'multiple-choice' | 'fill-in-the-blanks' | 'gap-select' | 'dictation';
|
|
108
|
+
/**
|
|
109
|
+
* A whole answer's grade, from the SDK's scorer. `category` is the verdict an
|
|
110
|
+
* explanation must agree with: all marks, some, or none.
|
|
111
|
+
*/
|
|
112
|
+
interface AiGrade {
|
|
113
|
+
score: number;
|
|
114
|
+
maxScore: number;
|
|
115
|
+
passed: boolean;
|
|
116
|
+
category: AiVerdict;
|
|
117
|
+
}
|
|
118
|
+
/** The three verdicts an explanation can speak to. */
|
|
119
|
+
type AiVerdict = 'correct' | 'partly-correct' | 'incorrect';
|
|
120
|
+
interface AiFactsBase {
|
|
121
|
+
activityId: string;
|
|
122
|
+
title: string;
|
|
123
|
+
/** The language the item is written in, when the author gave one. */
|
|
124
|
+
locale?: string;
|
|
125
|
+
}
|
|
126
|
+
/** One option of a multiple-choice question, and what the learner did with it. */
|
|
127
|
+
interface AiOptionFact {
|
|
128
|
+
id: string;
|
|
129
|
+
text: string;
|
|
130
|
+
chosen: boolean;
|
|
131
|
+
/** Whether this option is part of the answer; `null` when the key is not available. */
|
|
132
|
+
correct: boolean | null;
|
|
133
|
+
/** The author's feedback on this option. */
|
|
134
|
+
feedback?: string;
|
|
135
|
+
}
|
|
136
|
+
interface AiMultipleChoiceFacts extends AiFactsBase {
|
|
137
|
+
activityType: 'multiple-choice';
|
|
138
|
+
question: string;
|
|
139
|
+
mode: 'single' | 'multi';
|
|
140
|
+
options: AiOptionFact[];
|
|
141
|
+
}
|
|
142
|
+
/** One blank, in the order it appears in the passage. */
|
|
143
|
+
interface AiBlankFact {
|
|
144
|
+
id: string;
|
|
145
|
+
/** 1-based, in passage order. */
|
|
146
|
+
position: number;
|
|
147
|
+
/** What the learner typed, or `''`. */
|
|
148
|
+
typed: string;
|
|
149
|
+
/** The answers that count; `null` when the key is not available. */
|
|
150
|
+
accepted: string[] | null;
|
|
151
|
+
/** The SDK's verdict on this blank; `null` before it is graded or without a key. */
|
|
152
|
+
correct: boolean | null;
|
|
153
|
+
/** The author's hint for this blank. */
|
|
154
|
+
hint?: string;
|
|
155
|
+
/** The author's feedback for this blank. */
|
|
156
|
+
feedback?: string;
|
|
157
|
+
}
|
|
158
|
+
interface AiFillInTheBlanksFacts extends AiFactsBase {
|
|
159
|
+
activityType: 'fill-in-the-blanks';
|
|
160
|
+
/** The passage, each blank written as `[1]`, `[2]`… in passage order. */
|
|
161
|
+
passage: string;
|
|
162
|
+
blanks: AiBlankFact[];
|
|
163
|
+
}
|
|
164
|
+
/** One gap, in the order it appears in the passage. */
|
|
165
|
+
interface AiGapFact {
|
|
166
|
+
id: string;
|
|
167
|
+
/** 1-based, in passage order. */
|
|
168
|
+
position: number;
|
|
169
|
+
/** The words offered at this gap. */
|
|
170
|
+
choices: string[];
|
|
171
|
+
/** The word the learner chose, or `null`. */
|
|
172
|
+
chosen: string | null;
|
|
173
|
+
/** The right word; `null` when the key is not available. */
|
|
174
|
+
answer: string | null;
|
|
175
|
+
/** The SDK's verdict on this gap; `null` before it is graded or without a key. */
|
|
176
|
+
correct: boolean | null;
|
|
177
|
+
/** The author's feedback for this gap. */
|
|
178
|
+
feedback?: string;
|
|
179
|
+
}
|
|
180
|
+
interface AiGapSelectFacts extends AiFactsBase {
|
|
181
|
+
activityType: 'gap-select';
|
|
182
|
+
/** The passage, each gap written as `[1]`, `[2]`… in passage order. */
|
|
183
|
+
passage: string;
|
|
184
|
+
gaps: AiGapFact[];
|
|
185
|
+
}
|
|
186
|
+
/** One word of a dictation, as the SDK's alignment paired it. */
|
|
187
|
+
interface AiWordFact {
|
|
188
|
+
/** The word the recording says; `''` for an extra word the learner added. */
|
|
189
|
+
expected: string;
|
|
190
|
+
/** The word the learner typed; `''` for a word they left out. */
|
|
191
|
+
typed: string;
|
|
192
|
+
status: 'correct' | 'incorrect' | 'missing' | 'extra';
|
|
193
|
+
}
|
|
194
|
+
interface AiDictationFacts extends AiFactsBase {
|
|
195
|
+
activityType: 'dictation';
|
|
196
|
+
/** What the recording says; `null` when the key is not available. */
|
|
197
|
+
transcript: string | null;
|
|
198
|
+
/** What the learner typed. */
|
|
199
|
+
typed: string;
|
|
200
|
+
/** The alignment word by word; `null` when the key is not available. */
|
|
201
|
+
words: AiWordFact[] | null;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* What a model is told about one item and one answer: the question as the
|
|
205
|
+
* learner saw it, what they answered, and — part by part — the SDK's verdict.
|
|
206
|
+
*/
|
|
207
|
+
type AiItemFacts = AiMultipleChoiceFacts | AiFillInTheBlanksFacts | AiGapSelectFacts | AiDictationFacts;
|
|
208
|
+
/**
|
|
209
|
+
* Asks for an explanation of a graded answer. Sent after the SDK has graded
|
|
210
|
+
* it, so `grade` is always present, and an explanation that contradicts
|
|
211
|
+
* `grade.category` is refused.
|
|
212
|
+
*/
|
|
213
|
+
interface AiExplanationRequest {
|
|
214
|
+
feature: 'explanation';
|
|
215
|
+
facts: AiItemFacts;
|
|
216
|
+
grade: AiGrade;
|
|
217
|
+
/** The language to answer in: the learner's interface language, when known. */
|
|
218
|
+
learnerLocale?: string;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Asks for the next hint before the learner submits. `facts` carries the key
|
|
222
|
+
* so a model can hint toward the answer; the SDK refuses any hint that
|
|
223
|
+
* contains it.
|
|
224
|
+
*/
|
|
225
|
+
interface AiHintRequest {
|
|
226
|
+
feature: 'hint';
|
|
227
|
+
facts: AiItemFacts;
|
|
228
|
+
/** 1-based: the hint being asked for. */
|
|
229
|
+
hintNumber: number;
|
|
230
|
+
/** The hints already shown for this item, oldest first. */
|
|
231
|
+
previousHints: string[];
|
|
232
|
+
learnerLocale?: string;
|
|
233
|
+
}
|
|
234
|
+
/** What produced an AI text, for the record a host keeps. */
|
|
235
|
+
interface AiProvenance {
|
|
236
|
+
/** The model's identifier, e.g. a name and version. */
|
|
237
|
+
model?: string;
|
|
238
|
+
/** A hash or id of the prompt revision. */
|
|
239
|
+
promptHash?: string;
|
|
240
|
+
/** ISO 8601. */
|
|
241
|
+
generatedAt?: string;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* What a host's port returns. Plain text: the SDK renders it as text, never
|
|
245
|
+
* as HTML. An explanation may state the verdict it assumed; one that
|
|
246
|
+
* disagrees with the SDK's is refused.
|
|
247
|
+
*/
|
|
248
|
+
interface AiTextResult {
|
|
249
|
+
text: string;
|
|
250
|
+
/** For an explanation: the verdict the model explained. */
|
|
251
|
+
verdict?: AiVerdict;
|
|
252
|
+
provenance?: AiProvenance;
|
|
253
|
+
}
|
|
254
|
+
/** Why a result was not shown. */
|
|
255
|
+
type AiRefusal = 'malformed' | 'empty' | 'too-long' | 'contradicts-grade' | 'reveals-answer';
|
|
256
|
+
|
|
66
257
|
/**
|
|
67
258
|
* The return trip for deferred grading.
|
|
68
259
|
*
|
|
@@ -590,6 +781,8 @@ interface MultipleChoiceData {
|
|
|
590
781
|
learningObjectives?: string[];
|
|
591
782
|
/** Subjective difficulty on a 1–5 scale. */
|
|
592
783
|
difficultyLevel?: 1 | 2 | 3 | 4 | 5;
|
|
784
|
+
/** What an author allows AI to do for this item: see {@link ActivityAiPermissions}. */
|
|
785
|
+
ai?: ActivityAiPermissions;
|
|
593
786
|
}
|
|
594
787
|
/** Configuration for a single fill-in-the-blank slot. */
|
|
595
788
|
interface BlankConfig {
|
|
@@ -724,6 +917,8 @@ interface GapSelectData {
|
|
|
724
917
|
learningObjectives?: string[];
|
|
725
918
|
/** Subjective difficulty on a 1–5 scale. */
|
|
726
919
|
difficultyLevel?: 1 | 2 | 3 | 4 | 5;
|
|
920
|
+
/** What an author allows AI to do for this item: see {@link ActivityAiPermissions}. */
|
|
921
|
+
ai?: ActivityAiPermissions;
|
|
727
922
|
}
|
|
728
923
|
interface FillInTheBlanksData {
|
|
729
924
|
schemaVersion: '1.0';
|
|
@@ -756,6 +951,8 @@ interface FillInTheBlanksData {
|
|
|
756
951
|
learningObjectives?: string[];
|
|
757
952
|
/** Subjective difficulty on a 1–5 scale. */
|
|
758
953
|
difficultyLevel?: 1 | 2 | 3 | 4 | 5;
|
|
954
|
+
/** What an author allows AI to do for this item: see {@link ActivityAiPermissions}. */
|
|
955
|
+
ai?: ActivityAiPermissions;
|
|
759
956
|
}
|
|
760
957
|
/** A single criterion within a written-response grading rubric. */
|
|
761
958
|
interface WrittenResponseRubricCriterion {
|
|
@@ -818,6 +1015,8 @@ interface WrittenResponseData {
|
|
|
818
1015
|
learningObjectives?: string[];
|
|
819
1016
|
/** Subjective difficulty on a 1–5 scale. */
|
|
820
1017
|
difficultyLevel?: 1 | 2 | 3 | 4 | 5;
|
|
1018
|
+
/** What an author allows AI to do for this item: see {@link ActivityAiPermissions}. */
|
|
1019
|
+
ai?: ActivityAiPermissions;
|
|
821
1020
|
}
|
|
822
1021
|
/**
|
|
823
1022
|
* A second, slower recording of a dictation — a separate file (a text-to-speech
|
|
@@ -920,6 +1119,8 @@ interface DictationData {
|
|
|
920
1119
|
learningObjectives?: string[];
|
|
921
1120
|
/** Subjective difficulty on a 1–5 scale. */
|
|
922
1121
|
difficultyLevel?: 1 | 2 | 3 | 4 | 5;
|
|
1122
|
+
/** What an author allows AI to do for this item: see {@link ActivityAiPermissions}. */
|
|
1123
|
+
ai?: ActivityAiPermissions;
|
|
923
1124
|
}
|
|
924
1125
|
/** A dimension of speech a pronunciation assessor scores, on a 0–100 scale. */
|
|
925
1126
|
type ReadAloudDimension = 'accuracy' | 'fluency' | 'completeness' | 'prosody';
|
|
@@ -1010,6 +1211,8 @@ interface ReadAloudData {
|
|
|
1010
1211
|
learningObjectives?: string[];
|
|
1011
1212
|
/** Subjective difficulty on a 1–5 scale. */
|
|
1012
1213
|
difficultyLevel?: 1 | 2 | 3 | 4 | 5;
|
|
1214
|
+
/** What an author allows AI to do for this item: see {@link ActivityAiPermissions}. */
|
|
1215
|
+
ai?: ActivityAiPermissions;
|
|
1013
1216
|
}
|
|
1014
1217
|
/**
|
|
1015
1218
|
* Maps each ActivityType string to its learner-response shape. Open for
|
|
@@ -1320,7 +1523,15 @@ type InteractionKind = 'option-selected' | 'option-deselected' | 'blank-filled'
|
|
|
1320
1523
|
* primary line's language, or `null` with captions off; `payload.secondary` is
|
|
1321
1524
|
* the second line's, or `null` with none showing. Fires when either changes.
|
|
1322
1525
|
*/
|
|
1323
|
-
| 'video-captions-changed' | 'video-fullscreen-changed' | 'video-pip-changed'
|
|
1526
|
+
| 'video-captions-changed' | 'video-fullscreen-changed' | 'video-pip-changed'
|
|
1527
|
+
/**
|
|
1528
|
+
* An AI hint was shown to the learner (`hintNumber`, and the port's
|
|
1529
|
+
* `provenance` when it sent one). Only a hint the SDK accepted: a refused one
|
|
1530
|
+
* is never shown and never reported here.
|
|
1531
|
+
*/
|
|
1532
|
+
| 'ai-hint-shown'
|
|
1533
|
+
/** An AI explanation of the graded answer was shown (`provenance` when sent). */
|
|
1534
|
+
| 'ai-explanation-shown' | (string & {});
|
|
1324
1535
|
/** Fired by activity components on every discrete learner interaction. */
|
|
1325
1536
|
interface InteractionEvent {
|
|
1326
1537
|
/** The kind of interaction that occurred. */
|
|
@@ -1333,4 +1544,4 @@ interface InteractionEvent {
|
|
|
1333
1544
|
payload: Record<string, unknown>;
|
|
1334
1545
|
}
|
|
1335
1546
|
|
|
1336
|
-
export { type
|
|
1547
|
+
export { type MediaPlaybackPolicy as $, type ActivityAiPermissions as A, type BlankConfig as B, type CriterionScore as C, type DeferredReason as D, type DictationData as E, type DictationEquivalence as F, type DictationLearnerResponse as G, type DictationSlowMedia as H, type DictationTolerance as I, type FillInTheBlanksData as J, type FillInTheBlanksLearnerResponse as K, type GapSelectBank as L, type GapSelectChoice as M, type GapSelectData as N, type GapSelectGap as O, type GapSelectLearnerResponse as P, type GradeRecord as Q, type Grader as R, type GraderKind as S, type GraderUsage as T, type GradingState as U, type InlineCorrection as V, type InteractionEvent as W, type InteractionKind as X, type ItemOutcome as Y, type LearnerResponse as Z, type LearnerResponseMap as _, type ActivityData as a, type MediaTrack as a0, type MultipleChoiceData as a1, type MultipleChoiceLearnerResponse as a2, type MultipleChoiceOption as a3, type MultipleChoiceOptionMedia as a4, type NativeControlHint as a5, type ReadAloudData as a6, type ReadAloudDimension as a7, type ReadAloudDimensionWeight as a8, type ReadAloudLearnerResponse as a9, type ReadAloudSlowMedia as aa, type RecordingBounds as ab, type RecordingRef as ac, type ScoringDetail as ad, type ScoringOutcome as ae, type ScoringResult as af, type TextMatchPolicy as ag, type TextMatchResult as ah, type ValidationError as ai, type ValidationResult as aj, type WrittenResponseData as ak, type WrittenResponseLearnerResponse as al, type WrittenResponseRubric as am, type WrittenResponseRubricCriterion as an, type XAPIActor as ao, type XAPIConfig as ap, type XAPIContext as aq, type XAPIContextActivities as ar, type XAPIError as as, type XAPIObject as at, type XAPIResult as au, type XAPIScore as av, type XAPIStatement as aw, type XAPIVerbObject as ax, levenshteinDistance as ay, matchText as az, type ActivityDataMap as b, type ActivityFeedback as c, type ActivityMedia as d, type ActivityResult as e, type ActivityType as f, type AiActivityInput as g, type AiBlankFact as h, type AiDictationFacts as i, type AiExplanationRequest as j, type AiFeature as k, type AiFillInTheBlanksFacts as l, type AiGapFact as m, type AiGapSelectFacts as n, type AiGrade as o, type AiHintRequest as p, type AiItemFacts as q, type AiMultipleChoiceFacts as r, type AiOptionFact as s, type AiProvenance as t, type AiRefusal as u, type AiSupportedActivityType as v, type AiTextResult as w, type AiVerdict as x, type AiWordFact as y, type DeferredScoringPartial as z };
|