@intellectif/lk-core 1.1.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 +15 -0
- package/README.md +2 -1
- package/dist/{activity-MBOYLBjR.d.cts → activity-D705CXng.d.cts} +324 -2
- package/dist/{activity-MBOYLBjR.d.ts → activity-D705CXng.d.ts} +324 -2
- package/dist/ai-check.cjs +174 -12
- package/dist/ai-check.cjs.map +1 -1
- package/dist/ai-check.d.cts +15 -3
- package/dist/ai-check.d.ts +15 -3
- package/dist/ai-check.js +166 -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-DlcqkM_L.d.ts → index-BChYtrEe.d.ts} +1 -1
- package/dist/{index-DlCW0XaQ.d.cts → index-VXt_v3YI.d.cts} +1 -1
- package/dist/index.cjs +68 -593
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +245 -60
- package/dist/index.d.ts +245 -60
- package/dist/index.js +68 -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 +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-2JT2WUQ2.cjs.map +0 -1
- package/dist/chunk-DSDXL3JO.cjs.map +0 -1
- package/dist/chunk-FBKTION6.js.map +0 -1
- package/dist/chunk-LDFQUZII.cjs +0 -950
- package/dist/chunk-LDFQUZII.cjs.map +0 -1
- package/dist/chunk-NQHETFDA.js +0 -950
- package/dist/chunk-NQHETFDA.js.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,20 @@
|
|
|
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
|
+
|
|
3
18
|
## 1.1.0
|
|
4
19
|
|
|
5
20
|
### Minor 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`, `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.
|
|
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
|
*
|
|
@@ -413,8 +488,10 @@ interface AiTextResult {
|
|
|
413
488
|
* corrects words the learner did not write: a correction whose quote is not in
|
|
414
489
|
* the draft, or not where it claims to be. `contradicts-marks` is coaching on
|
|
415
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.
|
|
416
493
|
*/
|
|
417
|
-
type AiRefusal = 'malformed' | 'empty' | 'too-long' | 'contradicts-grade' | 'reveals-answer' | 'misquotes-answer' | 'contradicts-marks';
|
|
494
|
+
type AiRefusal = 'malformed' | 'empty' | 'too-long' | 'contradicts-grade' | 'reveals-answer' | 'misquotes-answer' | 'contradicts-marks' | 'contradicts-item';
|
|
418
495
|
/** One criterion of a written response's rubric, as the author wrote it. */
|
|
419
496
|
interface AiRubricCriterionFact {
|
|
420
497
|
name: string;
|
|
@@ -624,6 +701,251 @@ interface AiCoaching {
|
|
|
624
701
|
provenance?: AiProvenance;
|
|
625
702
|
usage?: GraderUsage;
|
|
626
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
|
+
}
|
|
627
949
|
|
|
628
950
|
/**
|
|
629
951
|
* An xAPI Activity object — the thing a statement is about.
|
|
@@ -1837,4 +2159,4 @@ interface InteractionEvent {
|
|
|
1837
2159
|
payload: Record<string, unknown>;
|
|
1838
2160
|
}
|
|
1839
2161
|
|
|
1840
|
-
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 };
|