@intellectif/lk-core 1.0.0 → 1.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/CHANGELOG.md +30 -0
- package/README.md +2 -1
- package/dist/{activity-DgpBJeBc.d.cts → activity-D705CXng.d.cts} +439 -7
- package/dist/{activity-DgpBJeBc.d.ts → activity-D705CXng.d.ts} +439 -7
- package/dist/ai-check.cjs +300 -9
- package/dist/ai-check.cjs.map +1 -1
- package/dist/ai-check.d.cts +18 -3
- package/dist/ai-check.d.ts +18 -3
- package/dist/ai-check.js +295 -4
- package/dist/ai-check.js.map +1 -1
- package/dist/{chunk-TJJFKKH2.cjs → chunk-46BXIGLG.cjs} +4 -4
- package/dist/{chunk-TJJFKKH2.cjs.map → chunk-46BXIGLG.cjs.map} +1 -1
- package/dist/{chunk-VSH7ECQL.cjs → chunk-4YANYTFN.cjs} +43 -43
- package/dist/{chunk-VSH7ECQL.cjs.map → chunk-4YANYTFN.cjs.map} +1 -1
- package/dist/chunk-7KOWU4RO.js +2207 -0
- package/dist/chunk-7KOWU4RO.js.map +1 -0
- package/dist/{chunk-DSDXL3JO.cjs → chunk-7THXD7AN.cjs} +657 -197
- package/dist/chunk-7THXD7AN.cjs.map +1 -0
- package/dist/chunk-CYCTIXUN.cjs +118 -0
- package/dist/chunk-CYCTIXUN.cjs.map +1 -0
- package/dist/chunk-CYPA5BW5.js +118 -0
- package/dist/chunk-CYPA5BW5.js.map +1 -0
- package/dist/{chunk-SJVRUPJT.js → chunk-JTNDIBZO.js} +2 -2
- package/dist/{chunk-XS6U2ARZ.js → chunk-MV2N2WNS.js} +6 -112
- package/dist/chunk-MV2N2WNS.js.map +1 -0
- package/dist/chunk-MXI26H62.cjs +2207 -0
- package/dist/chunk-MXI26H62.cjs.map +1 -0
- package/dist/{chunk-FBKTION6.js → chunk-QS7B42ZR.js} +640 -180
- package/dist/chunk-QS7B42ZR.js.map +1 -0
- package/dist/{chunk-IARLJ5MW.js → chunk-QX2ERL72.js} +2 -2
- package/dist/{chunk-2JT2WUQ2.cjs → chunk-ZWXQSKCX.cjs} +14 -120
- package/dist/chunk-ZWXQSKCX.cjs.map +1 -0
- package/dist/{index-BVNeSCWC.d.ts → index-BChYtrEe.d.ts} +1 -1
- package/dist/{index-BlOLlwOi.d.cts → index-VXt_v3YI.d.cts} +1 -1
- package/dist/index.cjs +76 -593
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +308 -66
- package/dist/index.d.ts +308 -66
- package/dist/index.js +76 -593
- 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 +5 -3
- package/dist/scoring.cjs +3 -3
- package/dist/scoring.d.cts +242 -242
- package/dist/scoring.d.ts +242 -242
- 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-2JT2WUQ2.cjs.map +0 -1
- package/dist/chunk-DSDXL3JO.cjs.map +0 -1
- package/dist/chunk-FBKTION6.js.map +0 -1
- package/dist/chunk-RCZCP5OE.js +0 -729
- package/dist/chunk-RCZCP5OE.js.map +0 -1
- package/dist/chunk-W5KB3DNT.cjs +0 -729
- package/dist/chunk-W5KB3DNT.cjs.map +0 -1
- package/dist/chunk-XS6U2ARZ.js.map +0 -1
- /package/dist/{chunk-SJVRUPJT.js.map → chunk-JTNDIBZO.js.map} +0 -0
- /package/dist/{chunk-IARLJ5MW.js.map → chunk-QX2ERL72.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# @intellectif/lk-core
|
|
2
2
|
|
|
3
|
+
## 1.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#88](https://github.com/intellectif/learning-kit/pull/88) [`493dd06`](https://github.com/intellectif/learning-kit/commit/493dd0648a73c7f47d889683bc9f7f08d8a0acc9) Thanks [@diego28e](https://github.com/diego28e)! - **Assistants for authors**: an item critic, a model's review of an item, and drafts from a passage, a transcript or a video's captions.
|
|
8
|
+
|
|
9
|
+
**Action required:** none unless your code switches over `AiRefusal` without a `default` branch (new member `'contradicts-item'`) or reads `AiCheckCase.request` without narrowing on `feature` (new `'item-critique'` and `'draft-generation'` cases). Nothing runs until you call it, no grade changes, and there is no lk-react release: lk-react 23.1 works with it as it is. See https://github.com/intellectif/learning-kit/blob/main/docs/upgrading.md
|
|
10
|
+
|
|
11
|
+
- **The item critic:** `critiqueDraft(type, draft)`, `critiqueDrafts(entries)` for a question set and `critiqueItemGroupDraft(group)` for a testlet point out what a reviewer would on an item that may be perfectly valid — a title, hint or passage that prints the answer, two options that read the same, the right option much longer than the rest, "all of the above" under shuffle, a word bank with no distractor, a text too long for its recording time, every right option in one position. Findings are `warning` or `advice`, in `DraftIssue`'s shape so an editor lists both, and never change what `validateDraft` says. Seventeen codes, documented with their rules: https://github.com/intellectif/learning-kit/blob/main/docs/authoring.md
|
|
12
|
+
- **A registered type** joins the critic through a new optional `authoring.critique`.
|
|
13
|
+
- **A model's review:** `aiCritiqueRequest` gives a model the item, every text field it may point at, and the critic's own findings; `checkAiCritique` lists its findings as `advice`, and refuses the whole reply as `contradicts-item` when a finding points at a field the item does not have or quotes words that field does not hold.
|
|
14
|
+
- **Drafts from a source:** `aiDraftsRequest` takes the types an author ticks — multiple choice, fill in the blanks, gap select, dictation, read-aloud, written response — in the author's order, an optional count (left out, as many as the source is worth, up to 50), the author's own instructions and your settings per type, and gives the model the JSON Schema of a reply: each type's own fields, no ids, HTML, media, switches or scoring settings; `checkAiDrafts` makes drafts with your ids and settings, in the author's order, each checked by `validateDraft` and the critic — from captions placed where its caption ends, a dictation with the stretch of video that says it; `aiDraftsRepairRequest` sends back what is unfinished, wrong or warned about; `generateDrafts` runs that loop, once by default and three times at most, and never throws for a model's failure. A draft is never approved by the SDK. https://github.com/intellectif/learning-kit/blob/main/docs/ai.md
|
|
15
|
+
- **A video's quizzes:** `interactiveVideoFromDrafts` makes the drafts an interactive video — each question where its caption ends, questions at one moment in the author's order, and every question without a moment in one quiz at the end of the video (`durationSeconds`).
|
|
16
|
+
- **ai-check:** a `critique` port runs four review cases and a `drafts` port six drafting cases, two of them video quizzes.
|
|
17
|
+
|
|
18
|
+
## 1.1.0
|
|
19
|
+
|
|
20
|
+
### Minor Changes
|
|
21
|
+
|
|
22
|
+
- [#86](https://github.com/intellectif/learning-kit/pull/86) [`2215060`](https://github.com/intellectif/learning-kit/commit/22150600b0d8f5f058214a0551566b58e154276d) Thanks [@diego28e](https://github.com/diego28e)! - **Coaching on a reading aloud**: "Coach me on this reading" under a read-aloud's marks, where a model may coach only the words the speech engine marked.
|
|
23
|
+
|
|
24
|
+
**Action required:** none unless your code switches over `AiFeature`, `AiRefusal` or `InteractionKind` without a `default` branch (new members `'pronunciation-coaching'`, `'contradicts-marks'` and `'ai-coaching-shown'`), reads `AiCheckCase.request` without narrowing on `feature`, or implements a complete `LkStrings` (six new keys). Nothing changes until you pass a `pronunciationCoaching` port. Install lk-core 1.1.0 with lk-react 23.1.0: lk-react calls the new lk-core functions, and its peer range moves to `^1.1.0`. See https://github.com/intellectif/learning-kit/blob/main/docs/upgrading.md
|
|
25
|
+
|
|
26
|
+
- **lk-core:** `aiCoachingRequest` builds what a model is given: the text, the engine's marks word by word — with each word's sounds and what each was heard as, when the marks come from the assessment — its dimension scores, and the grade. `checkAiCoaching` checks the reply before a learner sees it. Every word it coaches must be one the engine marked mispronounced or omitted, and every sound one the engine reported for that word; anything else refuses the whole reply as `contradicts-marks`. The words come back in reading order, each as the marks show it, and no number in the reply is read. An assessment the grader would not read (no speech, unscripted, another text or locale) gives no coaching.
|
|
27
|
+
- **lk-react:** a `pronunciationCoaching` port on `LearnerAi`. `<ReadAloud>` offers coaching under its marks in `practice` once a take is graded and in `review` wherever marks are shown, from a kept assessment or a stored grade; never in `exam`. `<PronunciationFeedback>` offers it too, given the item's `id` and `title` in `data`, and takes `ai`, `renderMode`, `delivery` and `onInteraction` for it. It follows the author's and the paper's `ai.explanations` and needs `feedback`, not `solutions`. One coaching per take. `useAiCoaching` gives marks you draw yourself the same rules.
|
|
28
|
+
- **Records:** `ai-coaching-shown` (how many words were coached, provenance and usage; never the text), and `ai-help-refused` with `feature: 'pronunciation-coaching'`.
|
|
29
|
+
- **ai-check:** a `pronunciationCoaching` port runs four reading cases: a mispronounced "th" and a word left out, a clean reading, the same slips from a stored grade without sounds, and coaching asked for in Spanish.
|
|
30
|
+
- Six new strings: `aiCoaching`, `aiCoachingLoading`, `aiCoachingHeading`, `aiCoachingUnavailable`, `aiCoachingWords`, `aiCoachingSound`.
|
|
31
|
+
- **Stability:** the promise now says what a minor may add to a type the SDK hands you — a union member, a `LkStrings` key, an optional property — and that a `default` branch keeps a switch correct across minors.
|
|
32
|
+
|
|
3
33
|
## 1.0.0
|
|
4
34
|
|
|
5
35
|
### Major Changes
|
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@ npm install @intellectif/lk-core
|
|
|
19
19
|
- **`validateActivity(type, data)`** — the authoritative runtime validator. Returns a typed `{ success, data }` or a structured `{ success: false, errors[] }`, and **throws `UnknownActivityTypeError` if `type` is not registered** — so guard it when validating a content bank that may carry types this build does not know. `validateItemGroup(data)` is the equivalent for a `Stimulus` + `ItemGroup` container, which `validateActivity` cannot take.
|
|
20
20
|
- **`validateDraft(type, draft)`** — for editors. Reports `complete`, `incomplete` (something not written yet) or `invalid` (something wrong), each issue with a `severity` and a `code` — documented for every problem the checks recognise — and deliberately no `success` boolean to misread. Stricter than `validateActivity`, never looser. **`createDraft(type, { newId })`** returns an empty draft to start from; a multiple-choice draft marks no option correct.
|
|
21
21
|
- **An open type system** — `defineActivityType` / `registerActivityType` make an activity type a *value*, not a hard-coded union member: register one and `validateActivity`, `validateDraft`, `score`, `evaluate`, `redact` and `jsonSchemaFor` all work for it, with no SDK release. An `authoring` block on the descriptor gives it draft support.
|
|
22
|
+
- **An item critic** — `critiqueDraft(type, draft)` (and `critiqueDrafts` for a question set, `critiqueItemGroupDraft` for a testlet) points out what a reviewer would on an item that may be perfectly valid: the right option much longer than the rest, an answer printed in the passage, a hint that gives it away, "all of the above" under shuffle. A finding is `warning` or `advice`, in `DraftIssue`'s shape, and never refuses an item.
|
|
22
23
|
- **JSON Schema (Draft-7) export** — `jsonSchemaFor(type)` for any registered type (plus the static per-type exports), suitable for form generators or AI prompting.
|
|
23
24
|
- **Scoring engine** — `score(activityType, data, response)` returning `{ score ∈ [0,1], maxScore: 1, passed, feedback, details }`. Pure, deterministic, 100 % test coverage enforced. It **throws** rather than inventing a number: `DeferredScoringError` for a deferred-graded type (`written-response`), and `RedactedScoringError` when handed a `redact()` projection, which has no answer key. Both are on the documented exam path — use `evaluate()` there, which returns `deferred` / `unscorable` instead of throwing.
|
|
24
25
|
- **Dictation marking as data** — a dictation is graded by the character-level similarity of the typed text to the transcript, with one `ScoringDetail` per word carrying its own `score`. `alignDictation(data, text)` returns the same comparison the grade was made of (normalised strings, word pairings, which accepted transcript won), `diffDictationChars(reference, attempt)` the character-level edits for a marked display, and `dictationReferenceWords(data)` the ids and words a stored result can be checked against — so a review screen or an analytics job never re-implements the arithmetic. `score()` and `evaluate()` take an optional `{ rounding }` to compare the pass line as displayed.
|
|
@@ -28,7 +29,7 @@ npm install @intellectif/lk-core
|
|
|
28
29
|
- **Item groups** — `Stimulus` + `ItemGroup` (one passage or recording serving several questions), `flattenSequence()` for seeded, shuffle-atomic presentation order with stable slot identity. Slot ids are positional by default (`"3"`, `"1.0"`); author a `slotKey` on an entry and its id survives an insert, so a stored response cannot slide onto a different question.
|
|
29
30
|
- **Delivery policies** — `DeliveryPolicy` says what a school lets a learner see around a question: feedback, solutions, hints and AI help. `resolveDeliveryPolicy` spells one out (an unreadable setting restricts, never allows), `validateDeliveryPolicy` checks one before it is stored, and `combineDeliveryPolicies` keeps a setting on only where every policy leaves it on.
|
|
30
31
|
- **Scoring policies** — `ItemScoringPolicy` says how a paper's questions are scored when a learner can try again or ask for hints: `retries`, which try `counts`, and what a try and a hint cost. `scoreTries` does the arithmetic, `evaluate(…, { scoring })` and `evaluateTries` reach a question's outcome from its answers, and `validateItemScoringPolicy` / `resolveItemScoringPolicy` refuse a policy that cannot be applied rather than guess — every setting moves a grade. No policy changes nothing, and the arithmetic is pinned by the grade vectors.
|
|
31
|
-
- **AI help contracts** — the SDK calls no model; it builds what yours is given and checks what comes back. `aiExplanationRequest`, `aiHintRequest` and `
|
|
32
|
+
- **AI help contracts** — the SDK calls no model; it builds what yours is given and checks what comes back. `aiExplanationRequest`, `aiHintRequest`, `aiWritingFeedbackRequest` and `aiCoachingRequest` build the requests a component makes, so a server can rebuild them from its own copy of an item; `checkAiExplanation`, `checkAiHint`, `checkAiWritingFeedback` and `checkAiCoaching` refuse an explanation that contradicts the grade, a hint that contains the answer, writing feedback that corrects words the learner never wrote, and coaching on a reading that names a word the speech engine did not mark or a sound it did not report; `checkAiWritingFeedback` computes the rubric's indicative score itself. For authors, `aiCritiqueRequest` / `checkAiCritique` give a model's review of an item, whose every finding must point at the item's own fields, and `aiDraftsRequest` / `checkAiDrafts` / `generateDrafts` draft the types an author ticks, in the author's order, from a passage, a script or captions — each checked by `validateDraft`, critiqued, repaired in a bounded loop, and never approved by the SDK — and `interactiveVideoFromDrafts` makes them a video's quizzes, each question where its caption ends or at the end.
|
|
32
33
|
- **Attempt plans** — `planAttempt(entries, { seed, shuffleEntries, points, delivery })` freezes the exact paper a learner sat, and the delivery policy it was sat under: slot order, per-slot points, a content hash of each item, and a `planHash` over the lot. `verifyAttemptPlan(plan, current)` reports the drift when that content is later edited (`changedSlotIds`, `changedStimulusSlotIds`, `changedPointsSlotIds`, `missingSlotIds`, …) — the thing you need during a remark or an appeal. `scoredItemsFromPlan(plan, outcomes)` turns collected outcomes into the `ScoredItem[]` composition wants, and defaults a slot with **no** outcome to `deferred` rather than silently shrinking the denominator.
|
|
33
34
|
- **Attempt state** — `serializeAttemptState(plan, progress)` / `restoreAttemptState(plan, snapshot)` round-trip an interrupted attempt (responses, submitted slots, position) and are **bound to the plan**: restoring answers onto a paper the learner never sat throws instead of succeeding quietly. `diffResponses(before, after)` reports what moved between two snapshots, including an answer the learner *cleared*.
|
|
34
35
|
- **Media playback policy** — `media.playback` on an audio recording: `maxPlays`, `seek`, `rate`, and advisory `nativeControlHints`. `resolvePlaybackPolicy()` derives the defaults once so the schema, the plan and the renderer cannot drift. Budgets are frozen into the plan by `planAttempt`, so editing `maxPlays` mid-window cannot change what a past learner was held to, and `planAttempt` refuses a paper where one recording is budgeted under two keys.
|
|
@@ -63,6 +63,81 @@ 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
|
+
* Why a draft is not an activity yet.
|
|
68
|
+
*
|
|
69
|
+
* - `incomplete` — something the author has not written yet: an empty title, an
|
|
70
|
+
* option with no text, no option marked correct. The fix is to add it.
|
|
71
|
+
* - `invalid` — something is wrong in a way that writing more cannot fix: two
|
|
72
|
+
* correct options on a single-selection question, a maximum word count below
|
|
73
|
+
* the minimum, a media address with a scheme the SDK refuses, a `null` in an
|
|
74
|
+
* optional field that accepts none. The fix is to change it.
|
|
75
|
+
*/
|
|
76
|
+
type DraftSeverity = 'incomplete' | 'invalid';
|
|
77
|
+
/**
|
|
78
|
+
* One problem with a draft. A {@link ValidationError} with a severity, so code
|
|
79
|
+
* that already lists `validateActivity` errors can list these unchanged.
|
|
80
|
+
*/
|
|
81
|
+
interface DraftIssue extends ValidationError {
|
|
82
|
+
severity: DraftSeverity;
|
|
83
|
+
}
|
|
84
|
+
/** A draft that is a valid activity and has nothing left to write. */
|
|
85
|
+
interface DraftComplete<T> {
|
|
86
|
+
status: 'complete';
|
|
87
|
+
/** The validated activity, exactly as `validateActivity` returns it. */
|
|
88
|
+
data: T;
|
|
89
|
+
/** Always empty. Present so that every result can be read the same way. */
|
|
90
|
+
issues: DraftIssue[];
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* A draft that is not an activity yet: `invalid` when any issue is invalid,
|
|
94
|
+
* otherwise `incomplete`. It carries no `data`, because nothing here may be
|
|
95
|
+
* stored or rendered as an activity.
|
|
96
|
+
*/
|
|
97
|
+
interface DraftNotComplete {
|
|
98
|
+
status: 'incomplete' | 'invalid';
|
|
99
|
+
issues: DraftIssue[];
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* The result of `validateDraft`.
|
|
103
|
+
*
|
|
104
|
+
* There is deliberately no `success` boolean. A boolean has to call an
|
|
105
|
+
* incomplete draft either a success, which lets a half-written answer key
|
|
106
|
+
* through anything that checks it, or a failure, which is the conflation this
|
|
107
|
+
* result exists to remove. Branch on `status`.
|
|
108
|
+
*/
|
|
109
|
+
type DraftValidationResult<T> = DraftComplete<T> | DraftNotComplete;
|
|
110
|
+
/**
|
|
111
|
+
* How much a finding of the item critic matters. Neither makes a draft
|
|
112
|
+
* incomplete or invalid: an item with findings is a valid item, stored and
|
|
113
|
+
* served like any other, and whether to change it is the author's call.
|
|
114
|
+
*
|
|
115
|
+
* - `warning` — a known flaw a learner can exploit or trip over: the right
|
|
116
|
+
* option is the longest, an answer printed in the passage, a hint that gives
|
|
117
|
+
* the answer away, two options that read the same.
|
|
118
|
+
* - `advice` — an item-writing guideline the item departs from: "all of the
|
|
119
|
+
* above", two accepted answers the matcher already treats as one.
|
|
120
|
+
*/
|
|
121
|
+
type ItemFindingSeverity = 'warning' | 'advice';
|
|
122
|
+
/**
|
|
123
|
+
* One thing the item critic found. A {@link ValidationError} with a severity,
|
|
124
|
+
* as a {@link DraftIssue} is, so an editor lists both in one list — sorted by
|
|
125
|
+
* severity: `invalid`, `incomplete`, `warning`, `advice`.
|
|
126
|
+
*/
|
|
127
|
+
interface ItemFinding extends ValidationError {
|
|
128
|
+
severity: ItemFindingSeverity;
|
|
129
|
+
}
|
|
130
|
+
/** What `createDraft` hands an activity type's `authoring.createDraft`. */
|
|
131
|
+
interface DraftContext {
|
|
132
|
+
/**
|
|
133
|
+
* Returns a new id on every call. The SDK invents none: an id made here would
|
|
134
|
+
* need `crypto`, which plain-http origins do not have, or would be positional —
|
|
135
|
+
* and option ids reach the learner, so ids like `"a"` and `"b"` would tell them
|
|
136
|
+
* which option was written first.
|
|
137
|
+
*/
|
|
138
|
+
newId: () => string;
|
|
139
|
+
}
|
|
140
|
+
|
|
66
141
|
/**
|
|
67
142
|
* The return trip for deferred grading.
|
|
68
143
|
*
|
|
@@ -226,8 +301,8 @@ interface GradeRecord {
|
|
|
226
301
|
interface ActivityAiPermissions {
|
|
227
302
|
/**
|
|
228
303
|
* An explanation of the learner's graded answer — and, on a written
|
|
229
|
-
* response, feedback on a draft
|
|
230
|
-
* learner's own answer.
|
|
304
|
+
* response, feedback on a draft, and on a read-aloud, coaching on the
|
|
305
|
+
* marks: each is a model's words about the learner's own answer.
|
|
231
306
|
*/
|
|
232
307
|
explanations?: boolean;
|
|
233
308
|
/** Hints before the learner submits. */
|
|
@@ -248,7 +323,7 @@ interface AiActivityInput {
|
|
|
248
323
|
readonly ai?: unknown;
|
|
249
324
|
}
|
|
250
325
|
/** The kinds of help a learner can be given. */
|
|
251
|
-
type AiFeature = 'explanation' | 'hint' | 'writing-feedback';
|
|
326
|
+
type AiFeature = 'explanation' | 'hint' | 'writing-feedback' | 'pronunciation-coaching';
|
|
252
327
|
/** The activity types the SDK builds facts for. */
|
|
253
328
|
type AiSupportedActivityType = 'multiple-choice' | 'fill-in-the-blanks' | 'gap-select' | 'dictation';
|
|
254
329
|
/**
|
|
@@ -411,9 +486,12 @@ interface AiTextResult {
|
|
|
411
486
|
/**
|
|
412
487
|
* Why a result was not shown. `misquotes-answer` is writing feedback that
|
|
413
488
|
* corrects words the learner did not write: a correction whose quote is not in
|
|
414
|
-
* the draft, or not where it claims to be.
|
|
489
|
+
* the draft, or not where it claims to be. `contradicts-marks` is coaching on
|
|
490
|
+
* a word the engine did not mark, or on a sound it did not report.
|
|
491
|
+
* `contradicts-item` is a critique of an item that points at a field the item
|
|
492
|
+
* does not have, or quotes words that field does not contain.
|
|
415
493
|
*/
|
|
416
|
-
type AiRefusal = 'malformed' | 'empty' | 'too-long' | 'contradicts-grade' | 'reveals-answer' | 'misquotes-answer';
|
|
494
|
+
type AiRefusal = 'malformed' | 'empty' | 'too-long' | 'contradicts-grade' | 'reveals-answer' | 'misquotes-answer' | 'contradicts-marks' | 'contradicts-item';
|
|
417
495
|
/** One criterion of a written response's rubric, as the author wrote it. */
|
|
418
496
|
interface AiRubricCriterionFact {
|
|
419
497
|
name: string;
|
|
@@ -519,6 +597,355 @@ interface AiWritingFeedback {
|
|
|
519
597
|
provenance?: AiProvenance;
|
|
520
598
|
usage?: GraderUsage;
|
|
521
599
|
}
|
|
600
|
+
/** One sound of a word, as the engine reported it. */
|
|
601
|
+
interface AiSoundFact {
|
|
602
|
+
/** The sound expected, in the assessment's phoneme alphabet. */
|
|
603
|
+
symbol: string;
|
|
604
|
+
/** How close it came, 0..100, when the engine scored it. */
|
|
605
|
+
accuracy?: number;
|
|
606
|
+
/** What the engine heard instead, best first, each with its score 0..100. */
|
|
607
|
+
heardAs?: {
|
|
608
|
+
symbol: string;
|
|
609
|
+
score: number;
|
|
610
|
+
}[];
|
|
611
|
+
}
|
|
612
|
+
/** One word of a reading, as the engine marked it. */
|
|
613
|
+
interface AiReadingWordFact {
|
|
614
|
+
/** `w<n>` for a word of the text; absent for a word the learner added. */
|
|
615
|
+
itemId?: string;
|
|
616
|
+
/** The word of the text, normalised; `''` for a word the learner added. */
|
|
617
|
+
word: string;
|
|
618
|
+
/** What was heard, normalised; `''` for an omitted word. */
|
|
619
|
+
heard: string;
|
|
620
|
+
state: 'correct' | 'mispronounced' | 'omitted' | 'inserted';
|
|
621
|
+
/** The engine's accuracy for the word, 0..100, when it has one. */
|
|
622
|
+
accuracy?: number;
|
|
623
|
+
/** The word's sounds, from the full assessment only. */
|
|
624
|
+
sounds?: AiSoundFact[];
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* What a model is told about a read-aloud: the text, the engine's marks word
|
|
628
|
+
* by word, and its scores. The marks are the engine's; a model explains them
|
|
629
|
+
* and never makes its own.
|
|
630
|
+
*/
|
|
631
|
+
interface AiReadingFacts {
|
|
632
|
+
activityType: 'read-aloud';
|
|
633
|
+
activityId: string;
|
|
634
|
+
title: string;
|
|
635
|
+
/** The language the text is in. */
|
|
636
|
+
locale: string;
|
|
637
|
+
referenceText: string;
|
|
638
|
+
instructions?: string;
|
|
639
|
+
/** Who made the marks: a measurement engine, a model, or a person. */
|
|
640
|
+
assessor: 'auto' | 'ai' | 'human' | 'unknown';
|
|
641
|
+
/** The alphabet `sounds` are written in, when any are. */
|
|
642
|
+
phonemeAlphabet?: 'ipa' | 'sapi';
|
|
643
|
+
/** The engine's dimension scores, each 0..100, where it measured them. */
|
|
644
|
+
scores: {
|
|
645
|
+
accuracy?: number;
|
|
646
|
+
fluency?: number;
|
|
647
|
+
completeness?: number;
|
|
648
|
+
prosody?: number;
|
|
649
|
+
};
|
|
650
|
+
words: AiReadingWordFact[];
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Asks for coaching on a graded reading: what to work on, word by word, and
|
|
654
|
+
* how. Never in an exam.
|
|
655
|
+
*/
|
|
656
|
+
interface AiCoachingRequest {
|
|
657
|
+
feature: 'pronunciation-coaching';
|
|
658
|
+
facts: AiReadingFacts;
|
|
659
|
+
/** The grade of the reading, when there is one. */
|
|
660
|
+
grade?: {
|
|
661
|
+
score: number;
|
|
662
|
+
maxScore: number;
|
|
663
|
+
passed: boolean;
|
|
664
|
+
};
|
|
665
|
+
/** The language to write in: the learner's interface language, when known. */
|
|
666
|
+
learnerLocale?: string;
|
|
667
|
+
}
|
|
668
|
+
/** One word a model coaches, as it returns it. */
|
|
669
|
+
interface AiCoachingWord {
|
|
670
|
+
/** The `itemId` of a word the engine marked mispronounced or omitted. */
|
|
671
|
+
itemId: string;
|
|
672
|
+
/** What to do about it, addressed to the learner. */
|
|
673
|
+
tip: string;
|
|
674
|
+
/**
|
|
675
|
+
* A sound the engine reported for this word — `expected` — and, if the
|
|
676
|
+
* model names one, what the engine heard instead.
|
|
677
|
+
*/
|
|
678
|
+
sound?: {
|
|
679
|
+
expected: string;
|
|
680
|
+
heard?: string;
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
/** What a host's `pronunciationCoaching` port returns. */
|
|
684
|
+
interface AiCoachingResult {
|
|
685
|
+
/** The coaching as a whole, addressed to the learner. Plain text, never HTML. */
|
|
686
|
+
text: string;
|
|
687
|
+
words?: AiCoachingWord[];
|
|
688
|
+
provenance?: AiProvenance;
|
|
689
|
+
usage?: GraderUsage;
|
|
690
|
+
}
|
|
691
|
+
/** Coaching, as the SDK accepted it: what a learner is shown. */
|
|
692
|
+
interface AiCoaching {
|
|
693
|
+
text: string;
|
|
694
|
+
/**
|
|
695
|
+
* The words to work on, in reading order, each with the word of the text as
|
|
696
|
+
* the SDK has it — never the model's spelling of it.
|
|
697
|
+
*/
|
|
698
|
+
words: (AiCoachingWord & {
|
|
699
|
+
word: string;
|
|
700
|
+
})[];
|
|
701
|
+
provenance?: AiProvenance;
|
|
702
|
+
usage?: GraderUsage;
|
|
703
|
+
}
|
|
704
|
+
/**
|
|
705
|
+
* What a model may find wrong with an item, in the SDK's words:
|
|
706
|
+
*
|
|
707
|
+
* - `ambiguous` — a stem, passage or blank that reads two ways;
|
|
708
|
+
* - `second-answer` — a distractor that is defensibly right, or an answer the
|
|
709
|
+
* key does not accept;
|
|
710
|
+
* - `wrong-key` — the answer marked right is not;
|
|
711
|
+
* - `implausible-distractor` — an option nobody who read the question would pick;
|
|
712
|
+
* - `cue` — grammar or wording that points at the answer;
|
|
713
|
+
* - `level` — language above or below the level the item is for;
|
|
714
|
+
* - `language` — a mistake in the item's own language;
|
|
715
|
+
* - `sensitivity` — content a learner may find loaded or unfamiliar for
|
|
716
|
+
* reasons that have nothing to do with what is assessed;
|
|
717
|
+
* - `other`.
|
|
718
|
+
*/
|
|
719
|
+
type AiCritiqueKind = 'ambiguous' | 'second-answer' | 'wrong-key' | 'implausible-distractor' | 'cue' | 'level' | 'language' | 'sensitivity' | 'other';
|
|
720
|
+
/** One field of an item a critique may point at, and what it says. */
|
|
721
|
+
interface AiCritiqueField {
|
|
722
|
+
path: string[];
|
|
723
|
+
text: string;
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* What a host's model is given to review an item. Built by
|
|
727
|
+
* `aiCritiqueRequest`; for an author, never a learner, so it carries the
|
|
728
|
+
* answer key.
|
|
729
|
+
*/
|
|
730
|
+
interface AiCritiqueRequest {
|
|
731
|
+
feature: 'item-critique';
|
|
732
|
+
facts: {
|
|
733
|
+
activityType: string;
|
|
734
|
+
/** The item as the author wrote it, answer key included. */
|
|
735
|
+
item: Readonly<Record<string, unknown>>;
|
|
736
|
+
/** Every text field a finding may point at, with its text: the only paths a finding may name. */
|
|
737
|
+
fields: AiCritiqueField[];
|
|
738
|
+
/**
|
|
739
|
+
* What the SDK's own critic already found, so a model does not say it
|
|
740
|
+
* again: code, path and message.
|
|
741
|
+
*/
|
|
742
|
+
findings: {
|
|
743
|
+
path: string[];
|
|
744
|
+
code: string;
|
|
745
|
+
message: string;
|
|
746
|
+
}[];
|
|
747
|
+
/** The level the item is for, as the host names it (`A2`, `B1`), when it gave one. */
|
|
748
|
+
level?: string;
|
|
749
|
+
};
|
|
750
|
+
/** The language to write findings in: the author's. */
|
|
751
|
+
authorLocale?: string;
|
|
752
|
+
}
|
|
753
|
+
/** One finding as a host's port returns it. */
|
|
754
|
+
interface AiCritiqueFindingResult {
|
|
755
|
+
/** A path from `facts.fields`, exactly. */
|
|
756
|
+
path: (string | number)[];
|
|
757
|
+
kind: AiCritiqueKind;
|
|
758
|
+
/** What is wrong, and what to do, addressed to the author. */
|
|
759
|
+
message: string;
|
|
760
|
+
/** Words copied from that field, when the finding is about some of them. */
|
|
761
|
+
quote?: string;
|
|
762
|
+
}
|
|
763
|
+
/** What a host's critique port returns. */
|
|
764
|
+
interface AiCritiqueResult {
|
|
765
|
+
findings: AiCritiqueFindingResult[];
|
|
766
|
+
provenance?: AiProvenance;
|
|
767
|
+
usage?: GraderUsage;
|
|
768
|
+
}
|
|
769
|
+
/**
|
|
770
|
+
* A model's finding, as the SDK accepted it: an `ItemFinding` — always
|
|
771
|
+
* `advice`, since it is a model's opinion — whose code is `ai_` and the kind
|
|
772
|
+
* (`ai_second_answer`), with the quote it pointed at.
|
|
773
|
+
*/
|
|
774
|
+
interface AiCritiqueFinding extends ItemFinding {
|
|
775
|
+
severity: 'advice';
|
|
776
|
+
quote?: string;
|
|
777
|
+
}
|
|
778
|
+
/** A critique, as the SDK accepted it. */
|
|
779
|
+
interface AiCritique {
|
|
780
|
+
findings: AiCritiqueFinding[];
|
|
781
|
+
provenance?: AiProvenance;
|
|
782
|
+
usage?: GraderUsage;
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* The types a model can draft from a source. An interactive video takes the
|
|
786
|
+
* first five; a written response is for a quiz of its own.
|
|
787
|
+
*/
|
|
788
|
+
type AiDraftType = 'multiple-choice' | 'fill-in-the-blanks' | 'gap-select' | 'dictation' | 'read-aloud' | 'written-response';
|
|
789
|
+
/**
|
|
790
|
+
* What drafts are written from: a passage or a script as text — an item
|
|
791
|
+
* group's `stimulus.transcript` is one — or a video's captions, each with its
|
|
792
|
+
* start and end in seconds, so a question can be placed where its caption ends.
|
|
793
|
+
*/
|
|
794
|
+
type AiDraftSource = {
|
|
795
|
+
kind: 'passage' | 'transcript';
|
|
796
|
+
text: string;
|
|
797
|
+
} | {
|
|
798
|
+
kind: 'captions';
|
|
799
|
+
cues: {
|
|
800
|
+
start: number;
|
|
801
|
+
end: number;
|
|
802
|
+
text: string;
|
|
803
|
+
}[];
|
|
804
|
+
};
|
|
805
|
+
/** A caption as a model is given it: numbered, so a draft can name the one it is about. */
|
|
806
|
+
interface AiDraftCaption {
|
|
807
|
+
index: number;
|
|
808
|
+
start: number;
|
|
809
|
+
end: number;
|
|
810
|
+
text: string;
|
|
811
|
+
}
|
|
812
|
+
/** One problem with a draft, as a model is told it on a repair. */
|
|
813
|
+
interface AiDraftProblem {
|
|
814
|
+
path: string[];
|
|
815
|
+
code: string;
|
|
816
|
+
message: string;
|
|
817
|
+
severity: 'incomplete' | 'invalid' | 'warning';
|
|
818
|
+
}
|
|
819
|
+
/**
|
|
820
|
+
* Fields of the host's for every draft of a type — settings a model never
|
|
821
|
+
* writes: a read-aloud's `recording`, `scoring` and region-tagged `locale`, a
|
|
822
|
+
* question's `shuffle` or `scoringStrategy`. They are put on each draft of
|
|
823
|
+
* that type before it is checked, and never override what the model wrote, nor
|
|
824
|
+
* the draft's `id`, `type` or `schemaVersion`.
|
|
825
|
+
*/
|
|
826
|
+
type AiDraftSettings = Partial<Record<AiDraftType, Readonly<Record<string, unknown>>>>;
|
|
827
|
+
/**
|
|
828
|
+
* What a host's model is given to draft items. Built by `aiDraftsRequest`, and
|
|
829
|
+
* by `aiDraftsRepairRequest` for a second pass over the drafts that came back
|
|
830
|
+
* unfinished or flawed in ways the model can fix.
|
|
831
|
+
*/
|
|
832
|
+
interface AiDraftsRequest {
|
|
833
|
+
feature: 'draft-generation';
|
|
834
|
+
facts: {
|
|
835
|
+
/**
|
|
836
|
+
* The types the author chose, in the author's order: the ones to lean on
|
|
837
|
+
* first, and the order questions are shown in where several share a moment
|
|
838
|
+
* of a video — or share the end of one.
|
|
839
|
+
*/
|
|
840
|
+
activityTypes: AiDraftType[];
|
|
841
|
+
source: {
|
|
842
|
+
kind: 'passage' | 'transcript';
|
|
843
|
+
text: string;
|
|
844
|
+
} | {
|
|
845
|
+
kind: 'captions';
|
|
846
|
+
captions: AiDraftCaption[];
|
|
847
|
+
};
|
|
848
|
+
/** How many drafts to write, at most. Absent: as many as the source is worth, up to `AI_DRAFTS_MAX_COUNT`. */
|
|
849
|
+
count?: number;
|
|
850
|
+
/** The language the items are written in. */
|
|
851
|
+
locale?: string;
|
|
852
|
+
/** The level they are for, as the host names it (`A2`, `B1`). */
|
|
853
|
+
level?: string;
|
|
854
|
+
/** What the author asked for, in their words. */
|
|
855
|
+
instructions?: string;
|
|
856
|
+
};
|
|
857
|
+
/**
|
|
858
|
+
* The JSON Schema of a reply — `{ drafts: [...] }` — for a model's structured
|
|
859
|
+
* output, or its prompt. Plain JSON Schema a model can follow: types, required
|
|
860
|
+
* fields, enums and descriptions, nothing a provider's structured output
|
|
861
|
+
* commonly refuses. Each draft names its `type`, and fills the fields that
|
|
862
|
+
* type uses.
|
|
863
|
+
*/
|
|
864
|
+
shape: Readonly<Record<string, unknown>>;
|
|
865
|
+
/** The host's settings for every draft of a type. Not for the model; `checkAiDrafts` applies them. */
|
|
866
|
+
settings?: AiDraftSettings;
|
|
867
|
+
/**
|
|
868
|
+
* On a repair: the drafts to fix, each as the model wrote it, with what is
|
|
869
|
+
* wrong with it that the model can fix. The reply holds one draft for each,
|
|
870
|
+
* in this order.
|
|
871
|
+
*/
|
|
872
|
+
repair?: {
|
|
873
|
+
index: number;
|
|
874
|
+
draft: Readonly<Record<string, unknown>>;
|
|
875
|
+
problems: AiDraftProblem[];
|
|
876
|
+
}[];
|
|
877
|
+
}
|
|
878
|
+
/** A draft as the SDK made it from a reply: ids minted, settings applied, checked, and critiqued. */
|
|
879
|
+
interface AiGeneratedDraft {
|
|
880
|
+
/** Its position in the first reply; a repaired draft keeps the position it replaces. */
|
|
881
|
+
index: number;
|
|
882
|
+
type: AiDraftType;
|
|
883
|
+
/** The draft, an activity of its type once `validation` says `complete`. */
|
|
884
|
+
draft: Record<string, unknown>;
|
|
885
|
+
/** What `validateDraft` says of it. `complete` means valid — never approved. */
|
|
886
|
+
validation: DraftValidationResult<unknown>;
|
|
887
|
+
/** What the item critic says of it. */
|
|
888
|
+
findings: ItemFinding[];
|
|
889
|
+
/**
|
|
890
|
+
* From captions: where the question goes, in seconds — the end of the
|
|
891
|
+
* caption it named. Absent when it named no caption the source has: it
|
|
892
|
+
* belongs at the end of the video.
|
|
893
|
+
*/
|
|
894
|
+
at?: number;
|
|
895
|
+
/**
|
|
896
|
+
* A dictation from captions whose transcript is words of the caption it
|
|
897
|
+
* named: that caption's start and end, in seconds — the stretch of the
|
|
898
|
+
* video that says it, for a host that cuts the recording from the video.
|
|
899
|
+
*/
|
|
900
|
+
clip?: {
|
|
901
|
+
start: number;
|
|
902
|
+
end: number;
|
|
903
|
+
};
|
|
904
|
+
/** The draft as the model wrote it, for a repair. */
|
|
905
|
+
generated: Readonly<Record<string, unknown>>;
|
|
906
|
+
}
|
|
907
|
+
/** What `checkAiDrafts` makes of a reply. */
|
|
908
|
+
interface AiDrafts {
|
|
909
|
+
/** The drafts in the author's order of types, and in the order the model wrote them within a type. */
|
|
910
|
+
drafts: AiGeneratedDraft[];
|
|
911
|
+
/** What only the set shows: every right option in one place (`set_key_position_same`). */
|
|
912
|
+
findings: ItemFinding[];
|
|
913
|
+
provenance?: AiProvenance;
|
|
914
|
+
usage?: GraderUsage;
|
|
915
|
+
}
|
|
916
|
+
/** One call `generateDrafts` made: what it cost, or why it went no further. */
|
|
917
|
+
type AiDraftsCall = {
|
|
918
|
+
ok: true;
|
|
919
|
+
provenance?: AiProvenance;
|
|
920
|
+
usage?: GraderUsage;
|
|
921
|
+
} | {
|
|
922
|
+
ok: false;
|
|
923
|
+
refusal?: AiRefusal;
|
|
924
|
+
error?: string;
|
|
925
|
+
};
|
|
926
|
+
/** What `generateDrafts` came to. */
|
|
927
|
+
interface AiDraftsRun {
|
|
928
|
+
/** The drafts, in the author's order of types, each the best pass of it. */
|
|
929
|
+
drafts: AiGeneratedDraft[];
|
|
930
|
+
/** What only the set shows, over the drafts as they ended. */
|
|
931
|
+
findings: ItemFinding[];
|
|
932
|
+
/** Every call, in order: the first, then each repair. */
|
|
933
|
+
calls: AiDraftsCall[];
|
|
934
|
+
}
|
|
935
|
+
/**
|
|
936
|
+
* An interactive video made of drafts: an item group whose stimulus is the
|
|
937
|
+
* video and whose timeline opens a quiz at each moment a draft was placed —
|
|
938
|
+
* and one at the end for every draft placed nowhere. A draft, like every
|
|
939
|
+
* draft: checked, critiqued, and approved by a person, never by the SDK.
|
|
940
|
+
*/
|
|
941
|
+
interface AiVideoDraft {
|
|
942
|
+
/** The item group, an interactive video once `validation` says `complete`. */
|
|
943
|
+
group: Record<string, unknown>;
|
|
944
|
+
/** What `validateItemGroupDraft` says of it. */
|
|
945
|
+
validation: DraftValidationResult<unknown>;
|
|
946
|
+
/** What `critiqueItemGroupDraft` says of it. */
|
|
947
|
+
findings: ItemFinding[];
|
|
948
|
+
}
|
|
522
949
|
|
|
523
950
|
/**
|
|
524
951
|
* An xAPI Activity object — the thing a statement is about.
|
|
@@ -1714,7 +2141,12 @@ type InteractionKind = 'option-selected' | 'option-deselected' | 'blank-filled'
|
|
|
1714
2141
|
* number of `corrections`, the `indicativeScore` when there was one, and the
|
|
1715
2142
|
* port's `provenance` and `usage` when it sent them). Never the text.
|
|
1716
2143
|
*/
|
|
1717
|
-
| 'ai-writing-feedback-shown'
|
|
2144
|
+
| 'ai-writing-feedback-shown'
|
|
2145
|
+
/**
|
|
2146
|
+
* Coaching on a read-aloud was shown (the number of `words` it coached, and
|
|
2147
|
+
* the port's `provenance` and `usage` when it sent them). Never the text.
|
|
2148
|
+
*/
|
|
2149
|
+
| 'ai-coaching-shown' | (string & {});
|
|
1718
2150
|
/** Fired by activity components on every discrete learner interaction. */
|
|
1719
2151
|
interface InteractionEvent {
|
|
1720
2152
|
/** The kind of interaction that occurred. */
|
|
@@ -1727,4 +2159,4 @@ interface InteractionEvent {
|
|
|
1727
2159
|
payload: Record<string, unknown>;
|
|
1728
2160
|
}
|
|
1729
2161
|
|
|
1730
|
-
export { type
|
|
2162
|
+
export { type AiWritingCorrection as $, type ActivityAiPermissions as A, type AiDrafts as B, type AiDraftsCall as C, type AiDraftsRequest as D, type AiDraftsRun as E, type AiExplanationRequest as F, type AiFeature as G, type AiFillInTheBlanksFacts as H, type AiGapFact as I, type AiGapSelectFacts as J, type AiGeneratedDraft as K, type AiGrade as L, type AiHintRequest as M, type AiItemFacts as N, type AiMultipleChoiceFacts as O, type AiOptionFact as P, type AiProvenance as Q, type AiReadingFacts as R, type AiReadingWordFact as S, type AiRefusal as T, type AiRubricCriterionFact as U, type AiSoundFact as V, type AiSupportedActivityType as W, type AiTextResult as X, type AiVerdict as Y, type AiVideoDraft as Z, type AiWordFact as _, type ActivityData as a, type WrittenResponseRubricCriterion as a$, type AiWritingFacts as a0, type AiWritingFeedback as a1, type AiWritingFeedbackRequest as a2, type AiWritingFeedbackResult as a3, type BlankConfig as a4, type CriterionScore as a5, type DeferredReason as a6, type DeferredScoringPartial as a7, type DictationData as a8, type DictationEquivalence as a9, type ItemOutcome as aA, type LearnerResponse as aB, type LearnerResponseMap as aC, type MediaPlaybackPolicy as aD, type MediaTrack as aE, type MultipleChoiceData as aF, type MultipleChoiceLearnerResponse as aG, type MultipleChoiceOption as aH, type MultipleChoiceOptionMedia as aI, type NativeControlHint as aJ, type ReadAloudData as aK, type ReadAloudDimension as aL, type ReadAloudDimensionWeight as aM, type ReadAloudLearnerResponse as aN, type ReadAloudSlowMedia as aO, type RecordingBounds as aP, type RecordingRef as aQ, type ScoringDetail as aR, type ScoringOutcome as aS, type ScoringResult as aT, type TextMatchPolicy as aU, type TextMatchResult as aV, type ValidationError as aW, type ValidationResult as aX, type WrittenResponseData as aY, type WrittenResponseLearnerResponse as aZ, type WrittenResponseRubric as a_, type DictationLearnerResponse as aa, type DictationSlowMedia as ab, type DictationTolerance as ac, type DraftComplete as ad, type DraftContext as ae, type DraftIssue as af, type DraftNotComplete as ag, type DraftSeverity as ah, type DraftValidationResult as ai, type FillInTheBlanksData as aj, type FillInTheBlanksLearnerResponse as ak, type GapSelectBank as al, type GapSelectChoice as am, type GapSelectData as an, type GapSelectGap as ao, type GapSelectLearnerResponse as ap, type GradeRecord as aq, type Grader as ar, type GraderKind as as, type GraderUsage as at, type GradingState as au, type InlineCorrection as av, type InteractionEvent as aw, type InteractionKind as ax, type ItemFinding as ay, type ItemFindingSeverity as az, type ActivityDataMap as b, type XAPIActor as b0, type XAPIConfig as b1, type XAPIContext as b2, type XAPIContextActivities as b3, type XAPIError as b4, type XAPIObject as b5, type XAPIResult as b6, type XAPIScore as b7, type XAPIStatement as b8, type XAPIVerbObject as b9, levenshteinDistance as ba, matchText as bb, 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 AiCoaching as i, type AiCoachingRequest as j, type AiCoachingResult as k, type AiCoachingWord as l, type AiCriterionJudgement as m, type AiCritique as n, type AiCritiqueField as o, type AiCritiqueFinding as p, type AiCritiqueFindingResult as q, type AiCritiqueKind as r, type AiCritiqueRequest as s, type AiCritiqueResult as t, type AiDictationFacts as u, type AiDraftCaption as v, type AiDraftProblem as w, type AiDraftSettings as x, type AiDraftSource as y, type AiDraftType as z };
|