@intellectif/lk-core 0.20.0 → 0.22.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 +32 -0
- package/README.md +30 -1
- package/dist/{activity-f0bgZSTP.d.cts → activity-CYc7SD3d.d.cts} +157 -11
- package/dist/{activity-f0bgZSTP.d.ts → activity-CYc7SD3d.d.ts} +157 -11
- package/dist/ai-check.cjs +103 -15
- package/dist/ai-check.cjs.map +1 -1
- package/dist/ai-check.d.cts +9 -5
- package/dist/ai-check.d.ts +9 -5
- package/dist/ai-check.js +102 -14
- package/dist/ai-check.js.map +1 -1
- package/dist/{chunk-BIJCO2HM.js → chunk-5UCR4UNR.js} +301 -20
- package/dist/chunk-5UCR4UNR.js.map +1 -0
- package/dist/{chunk-FVZJ4X3Y.cjs → chunk-OPMY2MNS.cjs} +302 -21
- package/dist/chunk-OPMY2MNS.cjs.map +1 -0
- package/dist/{chunk-MMEQKFFQ.js → chunk-Q7MV3IXJ.js} +196 -8
- package/dist/chunk-Q7MV3IXJ.js.map +1 -0
- package/dist/{chunk-COBK2RUX.cjs → chunk-WQVZPIN7.cjs} +197 -9
- package/dist/chunk-WQVZPIN7.cjs.map +1 -0
- package/dist/{index-BA9f2ydg.d.ts → index-0Z3-nnAP.d.ts} +1 -1
- package/dist/{index-7S3-TLjT.d.cts → index-CxxiNSSH.d.cts} +1 -1
- package/dist/index.cjs +56 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +93 -10
- package/dist/index.d.ts +93 -10
- package/dist/index.js +52 -5
- package/dist/index.js.map +1 -1
- package/dist/schemas.d.cts +2 -2
- package/dist/schemas.d.ts +2 -2
- package/dist/scoring.cjs +14 -2
- package/dist/scoring.cjs.map +1 -1
- package/dist/scoring.d.cts +240 -4
- package/dist/scoring.d.ts +240 -4
- package/dist/scoring.js +13 -1
- package/dist/xapi.d.cts +1 -1
- package/dist/xapi.d.ts +1 -1
- package/package.json +1 -1
- package/vectors/README.md +10 -0
- package/vectors/scoring.json +2127 -1
- package/dist/chunk-BIJCO2HM.js.map +0 -1
- package/dist/chunk-COBK2RUX.cjs.map +0 -1
- package/dist/chunk-FVZJ4X3Y.cjs.map +0 -1
- package/dist/chunk-MMEQKFFQ.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# @intellectif/lk-core
|
|
2
2
|
|
|
3
|
+
## 0.22.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#80](https://github.com/intellectif/learning-kit/pull/80) [`782b01b`](https://github.com/intellectif/learning-kit/commit/782b01ba697a90583b472ab1a7a2be102fd888c4) Thanks [@diego28e](https://github.com/diego28e)! - **Feedback on writing**: "Get feedback on my draft" on a written response in practice. The learner revises and asks again, and every correction must quote what they wrote.
|
|
8
|
+
|
|
9
|
+
**Action required:** none unless your code switches exhaustively over `AiFeature` or `AiRefusal` (new members `'writing-feedback'` and `'misquotes-answer'`), reads `AiCheckCase.request` without narrowing on `feature`, or implements a complete `LkStrings` (eight new keys). Nothing changes until you pass a `writingFeedback` port. Otherwise this is a major only because the peer range moves to `@intellectif/lk-core@^0.22.0`.
|
|
10
|
+
|
|
11
|
+
- **lk-core:** `aiWritingFeedbackRequest` builds what a model is given: the task, the draft verbatim, its word count as the grader counts it, the rubric, and the feedback on earlier drafts. `checkAiWritingFeedback` checks the reply before a learner sees it. It finds each correction's quote in the draft itself (typographic quotes and runs of whitespace folded, case kept) and anchors it there. A correction of words the draft does not contain refuses the whole reply as `misquotes-answer`. Criteria must be the rubric's; the author's weights are attached, and a model's weight is ignored. The indicative score is `gradeFromRubric`'s total, computed only when every criterion was judged. It is never a grade. Limits: 20 corrections, 500 characters a field.
|
|
12
|
+
- **lk-react:** a `writingFeedback` port and `maxWritingFeedback` (3 by default, at most 10) on `LearnerAi`. `<WrittenResponse>` shows the feedback with its corrections, rubric comments, the indicative score marked "Not a grade." and the AI notice, and says so once the draft has changed. It is never in `exam` or `review`, and it follows the author's and the paper's `ai.explanations`, `feedback` and `solutions`. `useAiWritingFeedback` gives a written response you draw yourself the same rules.
|
|
13
|
+
- **Records:** `ai-writing-feedback-shown` (the draft number, how many corrections, the indicative score, provenance and usage; never the text), and `ai-help-refused` with `feature: 'writing-feedback'`.
|
|
14
|
+
- **ai-check:** a `writingFeedback` port runs four writing cases: a draft with mistakes, one without, a revision, and feedback asked for in Spanish.
|
|
15
|
+
- Eight new strings: `aiWritingFeedback`, `aiWritingFeedbackLoading`, `aiWritingFeedbackHeading`, `aiWritingFeedbackUnavailable`, `aiNoMoreWritingFeedback`, `aiWritingFeedbackOutdated`, `aiCorrections`, `aiIndicativeScore`.
|
|
16
|
+
|
|
17
|
+
Guide: https://github.com/intellectif/learning-kit/blob/main/docs/ai.md#feedback-on-writing
|
|
18
|
+
|
|
19
|
+
## 0.21.0
|
|
20
|
+
|
|
21
|
+
### Minor Changes
|
|
22
|
+
|
|
23
|
+
- [#78](https://github.com/intellectif/learning-kit/pull/78) [`30a9b3d`](https://github.com/intellectif/learning-kit/commit/30a9b3da9be60589d63516752a02cc2f44bdf73b) Thanks [@diego28e](https://github.com/diego28e)! - **Scoring policies**: "Try again" in practice, which try counts, and what tries and hints cost — set per paper, recorded in the plan, and no grade moves without one.
|
|
24
|
+
|
|
25
|
+
**Action required:** only if you build an `InteractiveVideoQuestion` by hand (add `scoring`, e.g. `DEFAULT_ITEM_SCORING_POLICY`) or implement a complete `LkStrings` of your own (nine new keys). Everyone else upgrades with no change.
|
|
26
|
+
|
|
27
|
+
- **lk-core:** `ItemScoringPolicy` — `retries` (0–10), `counts` (`'first'` by default, `'best'`, `'last'`), `retryPenalty` and `hintPenalty` (fractions of the marks). `scoreTries` does the arithmetic: a cost is subtracted, never below zero, with floating-point residue under a pass line removed. `evaluate(item, response, { scoring })` charges the response's hints; `evaluateTries(item, responses, { scoring })` picks the try that counts. `validateItemScoringPolicy` and `resolveItemScoringPolicy` refuse a policy that cannot be applied — a `RangeError`, never a guess. `planAttempt(…, { scoring })` records it in the plan and `planHash`, and `verifyAttemptPlan` reports `scoringChanged`. With no policy every number is what it was; 43 new grade vectors pin the arithmetic.
|
|
28
|
+
- **Responses:** multiple-choice, fill-in-the-blanks and gap-select responses gain an optional `hintsRevealed`, as dictation's already had: in `practice`, the hints a learner was shown, counted from the start of the question.
|
|
29
|
+
- **lk-react:** `scoring` on every activity, `<ActivitySequence>` and `<InteractiveVideo>`; the paper's policy wins over a question's. "Try again" after an answer short of full marks keeps the answer and clears the marks; "Show answer" (or "Keep this answer") ends the tries. While a try is on offer the right answer and "Explain my answer" wait. `onComplete` fires after every try with the question's score so far. A set waits for any question being tried again, and for the question on screen while it offers a try, and closes every question's tries once it reports; the video closes them at Finish.
|
|
30
|
+
- **Fixed:** a dictation under `delivery={{ solutions: false }}` hid "Show solution" but its marks still named every word they corrected. They now say a word is wrong or missing without naming it, and draw no letter diff.
|
|
31
|
+
- Nine new strings: `tryAgain`, `showAnswer`, `keepAnswer`, `triesLeft`, `countedTry`, `scoreBeforeCosts`, `hintCost`, `dictationWordWrongUnnamed`, `dictationWordMissingUnnamed`.
|
|
32
|
+
|
|
33
|
+
Guide: https://github.com/intellectif/learning-kit/blob/main/docs/scoring.md
|
|
34
|
+
|
|
3
35
|
## 0.20.0
|
|
4
36
|
|
|
5
37
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -27,6 +27,8 @@ npm install @intellectif/lk-core
|
|
|
27
27
|
- **Assessment composition** — `composeAssessmentScore()` for weighted, sectioned totals, with a `provisional` status so an unmarked essay never deflates a grade — and a grade out of contract (`NaN`, 85 "out of 1") never finalises one — and `RoundingPolicy` / `roundGrade` / `gte` / `classifyBand` keeping grade rounding and band classification as the two distinct operations they are.
|
|
28
28
|
- **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
29
|
- **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
|
+
- **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 `aiWritingFeedbackRequest` build the requests a component makes, so a server can rebuild them from its own copy of an item; `checkAiExplanation`, `checkAiHint` and `checkAiWritingFeedback` refuse an explanation that contradicts the grade, a hint that contains the answer, and writing feedback that corrects words the learner never wrote, and `checkAiWritingFeedback` computes the rubric's indicative score itself.
|
|
30
32
|
- **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.
|
|
31
33
|
- **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*.
|
|
32
34
|
- **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.
|
|
@@ -125,12 +127,39 @@ and content hashing — those have no subpath of their own.
|
|
|
125
127
|
All exports ship as ESM + CJS with `.d.ts` types. Tree-shakeable; `sideEffects: false`. Node >= 20. In browsers, the SDK's own code needs `Object.hasOwn` — Chrome and Edge 93, Firefox 92, Safari 15.4 — because output targets ES2022 and nothing is polyfilled.
|
|
126
128
|
Zod is the single runtime dependency: the package depends on `zod@^3.25` and imports the **Zod 4 API** from its `zod/v4` subpath, so it coexists with an app still on Zod 3.
|
|
127
129
|
|
|
130
|
+
## Releases & upgrading
|
|
131
|
+
|
|
132
|
+
- **What is supported, and since when** — [Features](https://github.com/intellectif/learning-kit/blob/main/docs/features.md): every activity and capability, the `lk-core` / `lk-react` versions it arrived in, and its guide.
|
|
133
|
+
- **What changed** — [GitHub Releases](https://github.com/intellectif/learning-kit/releases), one per package version, and the same notes in each package's `CHANGELOG.md` (it ships in the npm package, so it is in your `node_modules` too). Notes written since release notes gained a template — every release after lk-core 0.20.0 / lk-react 20.0.0 — start with a one-line summary and **Action required**: `none`, or what to do. Earlier notes lead with the detail; the version map in the upgrading guide says what each one asks of you.
|
|
134
|
+
- **How to upgrade** — [Upgrading](https://github.com/intellectif/learning-kit/blob/main/docs/upgrading.md): which `lk-core` goes with which `lk-react`, and a section per release saying what, if anything, you need to change. A `lk-react` major is often only the `lk-core` peer bump; the map says so.
|
|
135
|
+
- **Hearing about a release** — on GitHub, **Watch → Custom → Releases**, or subscribe to [the releases feed](https://github.com/intellectif/learning-kit/releases.atom). Better still, let your dependency bot bring each release to you as a pull request, with its notes — and keep the two packages together in one, since they move together:
|
|
136
|
+
|
|
137
|
+
```yaml
|
|
138
|
+
# .github/dependabot.yml — one entry per directory with a package.json
|
|
139
|
+
version: 2
|
|
140
|
+
updates:
|
|
141
|
+
- package-ecosystem: npm
|
|
142
|
+
directory: /
|
|
143
|
+
schedule: { interval: weekly }
|
|
144
|
+
groups:
|
|
145
|
+
learning-kit:
|
|
146
|
+
patterns: ["@intellectif/lk-*"]
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
With Renovate: `"packageRules": [{ "matchPackageNames": ["@intellectif/lk-core", "@intellectif/lk-react"], "groupName": "learning-kit" }]`.
|
|
150
|
+
|
|
151
|
+
`lk-core` is still `0.x`, and a caret range on a `0.x` version matches only that minor: `^0.18.0` never installs `0.19.0`. A bot is how you find out there is one.
|
|
152
|
+
|
|
128
153
|
## Documentation
|
|
129
154
|
|
|
130
|
-
- [
|
|
155
|
+
- [Features](https://github.com/intellectif/learning-kit/blob/main/docs/features.md) — everything supported, and the versions each arrived in.
|
|
156
|
+
- [Upgrading](https://github.com/intellectif/learning-kit/blob/main/docs/upgrading.md) — which `lk-core` goes with which `lk-react`, and what each release asks of you.
|
|
131
157
|
- [Changelog](https://github.com/intellectif/learning-kit/blob/main/packages/lk-core/CHANGELOG.md) — every release, with the reasoning.
|
|
132
158
|
- [Grade-stability vectors](https://github.com/intellectif/learning-kit/blob/main/packages/lk-core/vectors/README.md) — the package's grading frozen as data; replay it against the build you install.
|
|
133
159
|
- [Authoring & content storage](https://github.com/intellectif/learning-kit/blob/main/docs/authoring.md) — data model, validation, fetch → validate → render flow, and building an editor (the draft issue codes).
|
|
160
|
+
- [Delivery policies](https://github.com/intellectif/learning-kit/blob/main/docs/delivery.md) — `DeliveryPolicy`, and recording it with an attempt.
|
|
161
|
+
- [Scoring policies](https://github.com/intellectif/learning-kit/blob/main/docs/scoring.md) — `ItemScoringPolicy`: tries, which counts, what hints cost, and scoring them on a server.
|
|
162
|
+
- [AI help for learners](https://github.com/intellectif/learning-kit/blob/main/docs/ai.md) — the AI contract, the checks, and the `ai-check` kit for your prompts.
|
|
134
163
|
- [Project README](https://github.com/intellectif/learning-kit#readme) — the full picture, including the React renderers.
|
|
135
164
|
- [Contributing](https://github.com/intellectif/learning-kit/blob/main/CONTRIBUTING.md) — adding a new activity type.
|
|
136
165
|
|
|
@@ -224,7 +224,11 @@ interface GradeRecord {
|
|
|
224
224
|
* one-word vocabulary item, say.
|
|
225
225
|
*/
|
|
226
226
|
interface ActivityAiPermissions {
|
|
227
|
-
/**
|
|
227
|
+
/**
|
|
228
|
+
* An explanation of the learner's graded answer — and, on a written
|
|
229
|
+
* response, feedback on a draft: both are a model's words about the
|
|
230
|
+
* learner's own answer.
|
|
231
|
+
*/
|
|
228
232
|
explanations?: boolean;
|
|
229
233
|
/** Hints before the learner submits. */
|
|
230
234
|
hints?: boolean;
|
|
@@ -243,8 +247,8 @@ interface AiActivityInput {
|
|
|
243
247
|
readonly redacted?: unknown;
|
|
244
248
|
readonly ai?: unknown;
|
|
245
249
|
}
|
|
246
|
-
/** The
|
|
247
|
-
type AiFeature = 'explanation' | 'hint';
|
|
250
|
+
/** The kinds of help a learner can be given. */
|
|
251
|
+
type AiFeature = 'explanation' | 'hint' | 'writing-feedback';
|
|
248
252
|
/** The activity types the SDK builds facts for. */
|
|
249
253
|
type AiSupportedActivityType = 'multiple-choice' | 'fill-in-the-blanks' | 'gap-select' | 'dictation';
|
|
250
254
|
/**
|
|
@@ -404,8 +408,117 @@ interface AiTextResult {
|
|
|
404
408
|
*/
|
|
405
409
|
usage?: GraderUsage;
|
|
406
410
|
}
|
|
407
|
-
/**
|
|
408
|
-
|
|
411
|
+
/**
|
|
412
|
+
* Why a result was not shown. `misquotes-answer` is writing feedback that
|
|
413
|
+
* corrects words the learner did not write: a correction whose quote is not in
|
|
414
|
+
* the draft, or not where it claims to be.
|
|
415
|
+
*/
|
|
416
|
+
type AiRefusal = 'malformed' | 'empty' | 'too-long' | 'contradicts-grade' | 'reveals-answer' | 'misquotes-answer';
|
|
417
|
+
/** One criterion of a written response's rubric, as the author wrote it. */
|
|
418
|
+
interface AiRubricCriterionFact {
|
|
419
|
+
name: string;
|
|
420
|
+
description?: string;
|
|
421
|
+
weight: number;
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* What a model is told about a draft of a written response: the task as the
|
|
425
|
+
* learner saw it, the draft verbatim, and the rubric it will be graded on.
|
|
426
|
+
*/
|
|
427
|
+
interface AiWritingFacts {
|
|
428
|
+
activityType: 'written-response';
|
|
429
|
+
activityId: string;
|
|
430
|
+
title: string;
|
|
431
|
+
/** The language the item is written in, when the author gave one. */
|
|
432
|
+
locale?: string;
|
|
433
|
+
prompt: string;
|
|
434
|
+
/** The draft, exactly as the learner wrote it. Every correction quotes it. */
|
|
435
|
+
text: string;
|
|
436
|
+
/** Recomputed with `countWords`, as the grader will count it. */
|
|
437
|
+
wordCount: number;
|
|
438
|
+
minWords: number;
|
|
439
|
+
maxWords: number;
|
|
440
|
+
withinWordBounds: boolean;
|
|
441
|
+
/** The rubric the answer will be graded on; `null` when the item has none. */
|
|
442
|
+
rubric: AiRubricCriterionFact[] | null;
|
|
443
|
+
/** The target language and level, when the author gave one (e.g. `"en-A2"`). */
|
|
444
|
+
languageTarget?: string;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Asks for feedback on a draft of a written response, before the learner
|
|
448
|
+
* submits it. Practice only.
|
|
449
|
+
*/
|
|
450
|
+
interface AiWritingFeedbackRequest {
|
|
451
|
+
feature: 'writing-feedback';
|
|
452
|
+
facts: AiWritingFacts;
|
|
453
|
+
/** 1-based: which draft this is. */
|
|
454
|
+
draftNumber: number;
|
|
455
|
+
/** The text of the feedback already shown on earlier drafts, oldest first. */
|
|
456
|
+
previousFeedback: string[];
|
|
457
|
+
/** The language to write in: the learner's interface language, when known. */
|
|
458
|
+
learnerLocale?: string;
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* One correction a model proposes. `original` must be words the learner
|
|
462
|
+
* wrote; the SDK finds them in the draft itself, so a model need not count
|
|
463
|
+
* characters — leave `range` out unless you are sure of it, because a range
|
|
464
|
+
* that does not hold the quote is refused.
|
|
465
|
+
*/
|
|
466
|
+
interface AiWritingCorrection {
|
|
467
|
+
original: string;
|
|
468
|
+
corrected: string;
|
|
469
|
+
explanation?: string;
|
|
470
|
+
/** An error-type tag, e.g. `"tense"`, `"article"`. */
|
|
471
|
+
category?: string;
|
|
472
|
+
range?: {
|
|
473
|
+
start: number;
|
|
474
|
+
end: number;
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* A model's judgement of one rubric criterion. The SDK attaches the author's
|
|
479
|
+
* weight; a weight sent here is ignored.
|
|
480
|
+
*/
|
|
481
|
+
type AiCriterionJudgement = Omit<CriterionScore, 'weight'> & {
|
|
482
|
+
weight?: number;
|
|
483
|
+
};
|
|
484
|
+
/**
|
|
485
|
+
* What a host's `writingFeedback` port returns: the overall feedback as plain
|
|
486
|
+
* text, and optionally corrections and a judgement per rubric criterion.
|
|
487
|
+
*/
|
|
488
|
+
interface AiWritingFeedbackResult {
|
|
489
|
+
/** The overall feedback, addressed to the learner. Plain text, never HTML. */
|
|
490
|
+
text: string;
|
|
491
|
+
corrections?: AiWritingCorrection[];
|
|
492
|
+
criteria?: AiCriterionJudgement[];
|
|
493
|
+
provenance?: AiProvenance;
|
|
494
|
+
usage?: GraderUsage;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Feedback on a draft, as the SDK accepted it: what a learner is shown.
|
|
498
|
+
*/
|
|
499
|
+
interface AiWritingFeedback {
|
|
500
|
+
text: string;
|
|
501
|
+
/**
|
|
502
|
+
* Every correction, anchored in the draft: `range` is where the SDK found
|
|
503
|
+
* the quote, and `original` is the draft's own text at that range.
|
|
504
|
+
*/
|
|
505
|
+
corrections: InlineCorrection[];
|
|
506
|
+
/** The model's judgements, with the rubric's weights. */
|
|
507
|
+
criteria: CriterionScore[];
|
|
508
|
+
/**
|
|
509
|
+
* The rubric's weighted total of the judgements, from 0 to 1, computed by
|
|
510
|
+
* the SDK as `gradeFromRubric` computes a grade — when every criterion of
|
|
511
|
+
* the rubric was judged; `null` otherwise, and on an item with no rubric.
|
|
512
|
+
*
|
|
513
|
+
* **An indication, never a grade:** it is a model's reading of a draft the
|
|
514
|
+
* learner has not submitted, and nothing in the SDK scores an answer with
|
|
515
|
+
* it. `ai-writing-feedback-shown` reports it, so a record can say what the
|
|
516
|
+
* learner was shown.
|
|
517
|
+
*/
|
|
518
|
+
indicativeScore: number | null;
|
|
519
|
+
provenance?: AiProvenance;
|
|
520
|
+
usage?: GraderUsage;
|
|
521
|
+
}
|
|
409
522
|
|
|
410
523
|
/**
|
|
411
524
|
* An xAPI Activity object — the thing a statement is about.
|
|
@@ -1253,12 +1366,28 @@ interface MultipleChoiceLearnerResponse {
|
|
|
1253
1366
|
type: 'multiple-choice';
|
|
1254
1367
|
/** IDs of the options the learner selected. */
|
|
1255
1368
|
selectedOptionIds: string[];
|
|
1369
|
+
/**
|
|
1370
|
+
* Hints the learner was shown before submitting this answer, counted from
|
|
1371
|
+
* the start of the question — the author's and AI hints alike. Written by
|
|
1372
|
+
* the SDK's components in `practice`; absent or 0 means none. A scoring
|
|
1373
|
+
* policy's `hintPenalty` charges for them. Client-reported, like any count
|
|
1374
|
+
* a browser makes.
|
|
1375
|
+
*/
|
|
1376
|
+
hintsRevealed?: number;
|
|
1256
1377
|
}
|
|
1257
1378
|
/** Learner response for a Fill-in-the-Blanks activity. */
|
|
1258
1379
|
interface FillInTheBlanksLearnerResponse {
|
|
1259
1380
|
type: 'fill-in-the-blanks';
|
|
1260
1381
|
/** Map of blank ID to the learner's typed answer. */
|
|
1261
1382
|
answers: Record<string, string>;
|
|
1383
|
+
/**
|
|
1384
|
+
* Hints the learner was shown before submitting this answer, counted from
|
|
1385
|
+
* the start of the question — the author's and AI hints alike. Written by
|
|
1386
|
+
* the SDK's components in `practice`; absent or 0 means none. A scoring
|
|
1387
|
+
* policy's `hintPenalty` charges for them. Client-reported, like any count
|
|
1388
|
+
* a browser makes.
|
|
1389
|
+
*/
|
|
1390
|
+
hintsRevealed?: number;
|
|
1262
1391
|
}
|
|
1263
1392
|
/**
|
|
1264
1393
|
* Learner response for a Gap Select activity.
|
|
@@ -1273,6 +1402,14 @@ interface GapSelectLearnerResponse {
|
|
|
1273
1402
|
type: 'gap-select';
|
|
1274
1403
|
/** Map of gap ID to the ID of the choice the learner selected. */
|
|
1275
1404
|
selections: Record<string, string>;
|
|
1405
|
+
/**
|
|
1406
|
+
* Hints the learner was shown before submitting this answer, counted from
|
|
1407
|
+
* the start of the question — the author's and AI hints alike. Written by
|
|
1408
|
+
* the SDK's components in `practice`; absent or 0 means none. A scoring
|
|
1409
|
+
* policy's `hintPenalty` charges for them. Client-reported, like any count
|
|
1410
|
+
* a browser makes.
|
|
1411
|
+
*/
|
|
1412
|
+
hintsRevealed?: number;
|
|
1276
1413
|
}
|
|
1277
1414
|
/** Learner response for a Written Response activity. */
|
|
1278
1415
|
interface WrittenResponseLearnerResponse {
|
|
@@ -1286,15 +1423,18 @@ interface WrittenResponseLearnerResponse {
|
|
|
1286
1423
|
* Learner response for a Dictation activity.
|
|
1287
1424
|
*
|
|
1288
1425
|
* `text` is exactly what the learner typed; every normalisation happens in the
|
|
1289
|
-
* scorer. `hintsRevealed` is client-reported
|
|
1290
|
-
*
|
|
1291
|
-
*
|
|
1426
|
+
* scorer. `hintsRevealed` is client-reported — how many hint words were shown
|
|
1427
|
+
* before submitting. The scorer ignores it; a scoring policy's `hintPenalty`
|
|
1428
|
+
* charges for it, knowing it cannot be verified.
|
|
1292
1429
|
*/
|
|
1293
1430
|
interface DictationLearnerResponse {
|
|
1294
1431
|
type: 'dictation';
|
|
1295
1432
|
/** The learner's text, as typed. */
|
|
1296
1433
|
text: string;
|
|
1297
|
-
/**
|
|
1434
|
+
/**
|
|
1435
|
+
* Hint words shown before submitting (practice only), counted from the start
|
|
1436
|
+
* of the question. Absent or 0 means none.
|
|
1437
|
+
*/
|
|
1298
1438
|
hintsRevealed?: number;
|
|
1299
1439
|
}
|
|
1300
1440
|
/**
|
|
@@ -1572,7 +1712,13 @@ type InteractionKind = 'option-selected' | 'option-deselected' | 'blank-filled'
|
|
|
1572
1712
|
* watches its own model in production, where the development console warning
|
|
1573
1713
|
* it accompanies is silent.
|
|
1574
1714
|
*/
|
|
1575
|
-
| 'ai-help-refused'
|
|
1715
|
+
| 'ai-help-refused'
|
|
1716
|
+
/**
|
|
1717
|
+
* Feedback on a draft of a written response was shown (`draftNumber`, the
|
|
1718
|
+
* number of `corrections`, the `indicativeScore` when there was one, and the
|
|
1719
|
+
* port's `provenance` and `usage` when it sent them). Never the text.
|
|
1720
|
+
*/
|
|
1721
|
+
| 'ai-writing-feedback-shown' | (string & {});
|
|
1576
1722
|
/** Fired by activity components on every discrete learner interaction. */
|
|
1577
1723
|
interface InteractionEvent {
|
|
1578
1724
|
/** The kind of interaction that occurred. */
|
|
@@ -1585,4 +1731,4 @@ interface InteractionEvent {
|
|
|
1585
1731
|
payload: Record<string, unknown>;
|
|
1586
1732
|
}
|
|
1587
1733
|
|
|
1588
|
-
export { type
|
|
1734
|
+
export { type GradingState as $, type ActivityAiPermissions as A, type AiWordFact as B, type AiWritingCorrection as C, type AiWritingFacts as D, type AiWritingFeedback as E, type AiWritingFeedbackRequest as F, type AiWritingFeedbackResult as G, type BlankConfig as H, type CriterionScore as I, type DeferredReason as J, type DeferredScoringPartial as K, type DictationData as L, type DictationEquivalence as M, type DictationLearnerResponse as N, type DictationSlowMedia as O, type DictationTolerance as P, type FillInTheBlanksData as Q, type FillInTheBlanksLearnerResponse as R, type GapSelectBank as S, type GapSelectChoice as T, type GapSelectData as U, type GapSelectGap as V, type GapSelectLearnerResponse as W, type GradeRecord as X, type Grader as Y, type GraderKind as Z, type GraderUsage as _, type ActivityData as a, type InlineCorrection as a0, type InteractionEvent as a1, type InteractionKind as a2, type ItemOutcome as a3, type LearnerResponse as a4, type LearnerResponseMap as a5, type MediaPlaybackPolicy as a6, type MediaTrack as a7, type MultipleChoiceData as a8, type MultipleChoiceLearnerResponse as a9, type XAPIObject as aA, type XAPIResult as aB, type XAPIScore as aC, type XAPIStatement as aD, type XAPIVerbObject as aE, levenshteinDistance as aF, matchText as aG, type MultipleChoiceOption as aa, type MultipleChoiceOptionMedia as ab, type NativeControlHint as ac, type ReadAloudData as ad, type ReadAloudDimension as ae, type ReadAloudDimensionWeight as af, type ReadAloudLearnerResponse as ag, type ReadAloudSlowMedia as ah, type RecordingBounds as ai, type RecordingRef as aj, type ScoringDetail as ak, type ScoringOutcome as al, type ScoringResult as am, type TextMatchPolicy as an, type TextMatchResult as ao, type ValidationError as ap, type ValidationResult as aq, type WrittenResponseData as ar, type WrittenResponseLearnerResponse as as, type WrittenResponseRubric as at, type WrittenResponseRubricCriterion as au, type XAPIActor as av, type XAPIConfig as aw, type XAPIContext as ax, type XAPIContextActivities as ay, type XAPIError 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 AiCriterionJudgement as i, type AiDictationFacts as j, type AiExplanationRequest as k, type AiFeature as l, type AiFillInTheBlanksFacts as m, type AiGapFact as n, type AiGapSelectFacts as o, type AiGrade as p, type AiHintRequest as q, type AiItemFacts as r, type AiMultipleChoiceFacts as s, type AiOptionFact as t, type AiProvenance as u, type AiRefusal as v, type AiRubricCriterionFact as w, type AiSupportedActivityType as x, type AiTextResult as y, type AiVerdict as z };
|
|
@@ -224,7 +224,11 @@ interface GradeRecord {
|
|
|
224
224
|
* one-word vocabulary item, say.
|
|
225
225
|
*/
|
|
226
226
|
interface ActivityAiPermissions {
|
|
227
|
-
/**
|
|
227
|
+
/**
|
|
228
|
+
* An explanation of the learner's graded answer — and, on a written
|
|
229
|
+
* response, feedback on a draft: both are a model's words about the
|
|
230
|
+
* learner's own answer.
|
|
231
|
+
*/
|
|
228
232
|
explanations?: boolean;
|
|
229
233
|
/** Hints before the learner submits. */
|
|
230
234
|
hints?: boolean;
|
|
@@ -243,8 +247,8 @@ interface AiActivityInput {
|
|
|
243
247
|
readonly redacted?: unknown;
|
|
244
248
|
readonly ai?: unknown;
|
|
245
249
|
}
|
|
246
|
-
/** The
|
|
247
|
-
type AiFeature = 'explanation' | 'hint';
|
|
250
|
+
/** The kinds of help a learner can be given. */
|
|
251
|
+
type AiFeature = 'explanation' | 'hint' | 'writing-feedback';
|
|
248
252
|
/** The activity types the SDK builds facts for. */
|
|
249
253
|
type AiSupportedActivityType = 'multiple-choice' | 'fill-in-the-blanks' | 'gap-select' | 'dictation';
|
|
250
254
|
/**
|
|
@@ -404,8 +408,117 @@ interface AiTextResult {
|
|
|
404
408
|
*/
|
|
405
409
|
usage?: GraderUsage;
|
|
406
410
|
}
|
|
407
|
-
/**
|
|
408
|
-
|
|
411
|
+
/**
|
|
412
|
+
* Why a result was not shown. `misquotes-answer` is writing feedback that
|
|
413
|
+
* corrects words the learner did not write: a correction whose quote is not in
|
|
414
|
+
* the draft, or not where it claims to be.
|
|
415
|
+
*/
|
|
416
|
+
type AiRefusal = 'malformed' | 'empty' | 'too-long' | 'contradicts-grade' | 'reveals-answer' | 'misquotes-answer';
|
|
417
|
+
/** One criterion of a written response's rubric, as the author wrote it. */
|
|
418
|
+
interface AiRubricCriterionFact {
|
|
419
|
+
name: string;
|
|
420
|
+
description?: string;
|
|
421
|
+
weight: number;
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* What a model is told about a draft of a written response: the task as the
|
|
425
|
+
* learner saw it, the draft verbatim, and the rubric it will be graded on.
|
|
426
|
+
*/
|
|
427
|
+
interface AiWritingFacts {
|
|
428
|
+
activityType: 'written-response';
|
|
429
|
+
activityId: string;
|
|
430
|
+
title: string;
|
|
431
|
+
/** The language the item is written in, when the author gave one. */
|
|
432
|
+
locale?: string;
|
|
433
|
+
prompt: string;
|
|
434
|
+
/** The draft, exactly as the learner wrote it. Every correction quotes it. */
|
|
435
|
+
text: string;
|
|
436
|
+
/** Recomputed with `countWords`, as the grader will count it. */
|
|
437
|
+
wordCount: number;
|
|
438
|
+
minWords: number;
|
|
439
|
+
maxWords: number;
|
|
440
|
+
withinWordBounds: boolean;
|
|
441
|
+
/** The rubric the answer will be graded on; `null` when the item has none. */
|
|
442
|
+
rubric: AiRubricCriterionFact[] | null;
|
|
443
|
+
/** The target language and level, when the author gave one (e.g. `"en-A2"`). */
|
|
444
|
+
languageTarget?: string;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Asks for feedback on a draft of a written response, before the learner
|
|
448
|
+
* submits it. Practice only.
|
|
449
|
+
*/
|
|
450
|
+
interface AiWritingFeedbackRequest {
|
|
451
|
+
feature: 'writing-feedback';
|
|
452
|
+
facts: AiWritingFacts;
|
|
453
|
+
/** 1-based: which draft this is. */
|
|
454
|
+
draftNumber: number;
|
|
455
|
+
/** The text of the feedback already shown on earlier drafts, oldest first. */
|
|
456
|
+
previousFeedback: string[];
|
|
457
|
+
/** The language to write in: the learner's interface language, when known. */
|
|
458
|
+
learnerLocale?: string;
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* One correction a model proposes. `original` must be words the learner
|
|
462
|
+
* wrote; the SDK finds them in the draft itself, so a model need not count
|
|
463
|
+
* characters — leave `range` out unless you are sure of it, because a range
|
|
464
|
+
* that does not hold the quote is refused.
|
|
465
|
+
*/
|
|
466
|
+
interface AiWritingCorrection {
|
|
467
|
+
original: string;
|
|
468
|
+
corrected: string;
|
|
469
|
+
explanation?: string;
|
|
470
|
+
/** An error-type tag, e.g. `"tense"`, `"article"`. */
|
|
471
|
+
category?: string;
|
|
472
|
+
range?: {
|
|
473
|
+
start: number;
|
|
474
|
+
end: number;
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* A model's judgement of one rubric criterion. The SDK attaches the author's
|
|
479
|
+
* weight; a weight sent here is ignored.
|
|
480
|
+
*/
|
|
481
|
+
type AiCriterionJudgement = Omit<CriterionScore, 'weight'> & {
|
|
482
|
+
weight?: number;
|
|
483
|
+
};
|
|
484
|
+
/**
|
|
485
|
+
* What a host's `writingFeedback` port returns: the overall feedback as plain
|
|
486
|
+
* text, and optionally corrections and a judgement per rubric criterion.
|
|
487
|
+
*/
|
|
488
|
+
interface AiWritingFeedbackResult {
|
|
489
|
+
/** The overall feedback, addressed to the learner. Plain text, never HTML. */
|
|
490
|
+
text: string;
|
|
491
|
+
corrections?: AiWritingCorrection[];
|
|
492
|
+
criteria?: AiCriterionJudgement[];
|
|
493
|
+
provenance?: AiProvenance;
|
|
494
|
+
usage?: GraderUsage;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Feedback on a draft, as the SDK accepted it: what a learner is shown.
|
|
498
|
+
*/
|
|
499
|
+
interface AiWritingFeedback {
|
|
500
|
+
text: string;
|
|
501
|
+
/**
|
|
502
|
+
* Every correction, anchored in the draft: `range` is where the SDK found
|
|
503
|
+
* the quote, and `original` is the draft's own text at that range.
|
|
504
|
+
*/
|
|
505
|
+
corrections: InlineCorrection[];
|
|
506
|
+
/** The model's judgements, with the rubric's weights. */
|
|
507
|
+
criteria: CriterionScore[];
|
|
508
|
+
/**
|
|
509
|
+
* The rubric's weighted total of the judgements, from 0 to 1, computed by
|
|
510
|
+
* the SDK as `gradeFromRubric` computes a grade — when every criterion of
|
|
511
|
+
* the rubric was judged; `null` otherwise, and on an item with no rubric.
|
|
512
|
+
*
|
|
513
|
+
* **An indication, never a grade:** it is a model's reading of a draft the
|
|
514
|
+
* learner has not submitted, and nothing in the SDK scores an answer with
|
|
515
|
+
* it. `ai-writing-feedback-shown` reports it, so a record can say what the
|
|
516
|
+
* learner was shown.
|
|
517
|
+
*/
|
|
518
|
+
indicativeScore: number | null;
|
|
519
|
+
provenance?: AiProvenance;
|
|
520
|
+
usage?: GraderUsage;
|
|
521
|
+
}
|
|
409
522
|
|
|
410
523
|
/**
|
|
411
524
|
* An xAPI Activity object — the thing a statement is about.
|
|
@@ -1253,12 +1366,28 @@ interface MultipleChoiceLearnerResponse {
|
|
|
1253
1366
|
type: 'multiple-choice';
|
|
1254
1367
|
/** IDs of the options the learner selected. */
|
|
1255
1368
|
selectedOptionIds: string[];
|
|
1369
|
+
/**
|
|
1370
|
+
* Hints the learner was shown before submitting this answer, counted from
|
|
1371
|
+
* the start of the question — the author's and AI hints alike. Written by
|
|
1372
|
+
* the SDK's components in `practice`; absent or 0 means none. A scoring
|
|
1373
|
+
* policy's `hintPenalty` charges for them. Client-reported, like any count
|
|
1374
|
+
* a browser makes.
|
|
1375
|
+
*/
|
|
1376
|
+
hintsRevealed?: number;
|
|
1256
1377
|
}
|
|
1257
1378
|
/** Learner response for a Fill-in-the-Blanks activity. */
|
|
1258
1379
|
interface FillInTheBlanksLearnerResponse {
|
|
1259
1380
|
type: 'fill-in-the-blanks';
|
|
1260
1381
|
/** Map of blank ID to the learner's typed answer. */
|
|
1261
1382
|
answers: Record<string, string>;
|
|
1383
|
+
/**
|
|
1384
|
+
* Hints the learner was shown before submitting this answer, counted from
|
|
1385
|
+
* the start of the question — the author's and AI hints alike. Written by
|
|
1386
|
+
* the SDK's components in `practice`; absent or 0 means none. A scoring
|
|
1387
|
+
* policy's `hintPenalty` charges for them. Client-reported, like any count
|
|
1388
|
+
* a browser makes.
|
|
1389
|
+
*/
|
|
1390
|
+
hintsRevealed?: number;
|
|
1262
1391
|
}
|
|
1263
1392
|
/**
|
|
1264
1393
|
* Learner response for a Gap Select activity.
|
|
@@ -1273,6 +1402,14 @@ interface GapSelectLearnerResponse {
|
|
|
1273
1402
|
type: 'gap-select';
|
|
1274
1403
|
/** Map of gap ID to the ID of the choice the learner selected. */
|
|
1275
1404
|
selections: Record<string, string>;
|
|
1405
|
+
/**
|
|
1406
|
+
* Hints the learner was shown before submitting this answer, counted from
|
|
1407
|
+
* the start of the question — the author's and AI hints alike. Written by
|
|
1408
|
+
* the SDK's components in `practice`; absent or 0 means none. A scoring
|
|
1409
|
+
* policy's `hintPenalty` charges for them. Client-reported, like any count
|
|
1410
|
+
* a browser makes.
|
|
1411
|
+
*/
|
|
1412
|
+
hintsRevealed?: number;
|
|
1276
1413
|
}
|
|
1277
1414
|
/** Learner response for a Written Response activity. */
|
|
1278
1415
|
interface WrittenResponseLearnerResponse {
|
|
@@ -1286,15 +1423,18 @@ interface WrittenResponseLearnerResponse {
|
|
|
1286
1423
|
* Learner response for a Dictation activity.
|
|
1287
1424
|
*
|
|
1288
1425
|
* `text` is exactly what the learner typed; every normalisation happens in the
|
|
1289
|
-
* scorer. `hintsRevealed` is client-reported
|
|
1290
|
-
*
|
|
1291
|
-
*
|
|
1426
|
+
* scorer. `hintsRevealed` is client-reported — how many hint words were shown
|
|
1427
|
+
* before submitting. The scorer ignores it; a scoring policy's `hintPenalty`
|
|
1428
|
+
* charges for it, knowing it cannot be verified.
|
|
1292
1429
|
*/
|
|
1293
1430
|
interface DictationLearnerResponse {
|
|
1294
1431
|
type: 'dictation';
|
|
1295
1432
|
/** The learner's text, as typed. */
|
|
1296
1433
|
text: string;
|
|
1297
|
-
/**
|
|
1434
|
+
/**
|
|
1435
|
+
* Hint words shown before submitting (practice only), counted from the start
|
|
1436
|
+
* of the question. Absent or 0 means none.
|
|
1437
|
+
*/
|
|
1298
1438
|
hintsRevealed?: number;
|
|
1299
1439
|
}
|
|
1300
1440
|
/**
|
|
@@ -1572,7 +1712,13 @@ type InteractionKind = 'option-selected' | 'option-deselected' | 'blank-filled'
|
|
|
1572
1712
|
* watches its own model in production, where the development console warning
|
|
1573
1713
|
* it accompanies is silent.
|
|
1574
1714
|
*/
|
|
1575
|
-
| 'ai-help-refused'
|
|
1715
|
+
| 'ai-help-refused'
|
|
1716
|
+
/**
|
|
1717
|
+
* Feedback on a draft of a written response was shown (`draftNumber`, the
|
|
1718
|
+
* number of `corrections`, the `indicativeScore` when there was one, and the
|
|
1719
|
+
* port's `provenance` and `usage` when it sent them). Never the text.
|
|
1720
|
+
*/
|
|
1721
|
+
| 'ai-writing-feedback-shown' | (string & {});
|
|
1576
1722
|
/** Fired by activity components on every discrete learner interaction. */
|
|
1577
1723
|
interface InteractionEvent {
|
|
1578
1724
|
/** The kind of interaction that occurred. */
|
|
@@ -1585,4 +1731,4 @@ interface InteractionEvent {
|
|
|
1585
1731
|
payload: Record<string, unknown>;
|
|
1586
1732
|
}
|
|
1587
1733
|
|
|
1588
|
-
export { type
|
|
1734
|
+
export { type GradingState as $, type ActivityAiPermissions as A, type AiWordFact as B, type AiWritingCorrection as C, type AiWritingFacts as D, type AiWritingFeedback as E, type AiWritingFeedbackRequest as F, type AiWritingFeedbackResult as G, type BlankConfig as H, type CriterionScore as I, type DeferredReason as J, type DeferredScoringPartial as K, type DictationData as L, type DictationEquivalence as M, type DictationLearnerResponse as N, type DictationSlowMedia as O, type DictationTolerance as P, type FillInTheBlanksData as Q, type FillInTheBlanksLearnerResponse as R, type GapSelectBank as S, type GapSelectChoice as T, type GapSelectData as U, type GapSelectGap as V, type GapSelectLearnerResponse as W, type GradeRecord as X, type Grader as Y, type GraderKind as Z, type GraderUsage as _, type ActivityData as a, type InlineCorrection as a0, type InteractionEvent as a1, type InteractionKind as a2, type ItemOutcome as a3, type LearnerResponse as a4, type LearnerResponseMap as a5, type MediaPlaybackPolicy as a6, type MediaTrack as a7, type MultipleChoiceData as a8, type MultipleChoiceLearnerResponse as a9, type XAPIObject as aA, type XAPIResult as aB, type XAPIScore as aC, type XAPIStatement as aD, type XAPIVerbObject as aE, levenshteinDistance as aF, matchText as aG, type MultipleChoiceOption as aa, type MultipleChoiceOptionMedia as ab, type NativeControlHint as ac, type ReadAloudData as ad, type ReadAloudDimension as ae, type ReadAloudDimensionWeight as af, type ReadAloudLearnerResponse as ag, type ReadAloudSlowMedia as ah, type RecordingBounds as ai, type RecordingRef as aj, type ScoringDetail as ak, type ScoringOutcome as al, type ScoringResult as am, type TextMatchPolicy as an, type TextMatchResult as ao, type ValidationError as ap, type ValidationResult as aq, type WrittenResponseData as ar, type WrittenResponseLearnerResponse as as, type WrittenResponseRubric as at, type WrittenResponseRubricCriterion as au, type XAPIActor as av, type XAPIConfig as aw, type XAPIContext as ax, type XAPIContextActivities as ay, type XAPIError 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 AiCriterionJudgement as i, type AiDictationFacts as j, type AiExplanationRequest as k, type AiFeature as l, type AiFillInTheBlanksFacts as m, type AiGapFact as n, type AiGapSelectFacts as o, type AiGrade as p, type AiHintRequest as q, type AiItemFacts as r, type AiMultipleChoiceFacts as s, type AiOptionFact as t, type AiProvenance as u, type AiRefusal as v, type AiRubricCriterionFact as w, type AiSupportedActivityType as x, type AiTextResult as y, type AiVerdict as z };
|