@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.
Files changed (64) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +2 -1
  3. package/dist/{activity-DgpBJeBc.d.cts → activity-D705CXng.d.cts} +439 -7
  4. package/dist/{activity-DgpBJeBc.d.ts → activity-D705CXng.d.ts} +439 -7
  5. package/dist/ai-check.cjs +300 -9
  6. package/dist/ai-check.cjs.map +1 -1
  7. package/dist/ai-check.d.cts +18 -3
  8. package/dist/ai-check.d.ts +18 -3
  9. package/dist/ai-check.js +295 -4
  10. package/dist/ai-check.js.map +1 -1
  11. package/dist/{chunk-TJJFKKH2.cjs → chunk-46BXIGLG.cjs} +4 -4
  12. package/dist/{chunk-TJJFKKH2.cjs.map → chunk-46BXIGLG.cjs.map} +1 -1
  13. package/dist/{chunk-VSH7ECQL.cjs → chunk-4YANYTFN.cjs} +43 -43
  14. package/dist/{chunk-VSH7ECQL.cjs.map → chunk-4YANYTFN.cjs.map} +1 -1
  15. package/dist/chunk-7KOWU4RO.js +2207 -0
  16. package/dist/chunk-7KOWU4RO.js.map +1 -0
  17. package/dist/{chunk-DSDXL3JO.cjs → chunk-7THXD7AN.cjs} +657 -197
  18. package/dist/chunk-7THXD7AN.cjs.map +1 -0
  19. package/dist/chunk-CYCTIXUN.cjs +118 -0
  20. package/dist/chunk-CYCTIXUN.cjs.map +1 -0
  21. package/dist/chunk-CYPA5BW5.js +118 -0
  22. package/dist/chunk-CYPA5BW5.js.map +1 -0
  23. package/dist/{chunk-SJVRUPJT.js → chunk-JTNDIBZO.js} +2 -2
  24. package/dist/{chunk-XS6U2ARZ.js → chunk-MV2N2WNS.js} +6 -112
  25. package/dist/chunk-MV2N2WNS.js.map +1 -0
  26. package/dist/chunk-MXI26H62.cjs +2207 -0
  27. package/dist/chunk-MXI26H62.cjs.map +1 -0
  28. package/dist/{chunk-FBKTION6.js → chunk-QS7B42ZR.js} +640 -180
  29. package/dist/chunk-QS7B42ZR.js.map +1 -0
  30. package/dist/{chunk-IARLJ5MW.js → chunk-QX2ERL72.js} +2 -2
  31. package/dist/{chunk-2JT2WUQ2.cjs → chunk-ZWXQSKCX.cjs} +14 -120
  32. package/dist/chunk-ZWXQSKCX.cjs.map +1 -0
  33. package/dist/{index-BVNeSCWC.d.ts → index-BChYtrEe.d.ts} +1 -1
  34. package/dist/{index-BlOLlwOi.d.cts → index-VXt_v3YI.d.cts} +1 -1
  35. package/dist/index.cjs +76 -593
  36. package/dist/index.cjs.map +1 -1
  37. package/dist/index.d.cts +308 -66
  38. package/dist/index.d.ts +308 -66
  39. package/dist/index.js +76 -593
  40. package/dist/index.js.map +1 -1
  41. package/dist/schemas.cjs +5 -3
  42. package/dist/schemas.cjs.map +1 -1
  43. package/dist/schemas.d.cts +2 -2
  44. package/dist/schemas.d.ts +2 -2
  45. package/dist/schemas.js +5 -3
  46. package/dist/scoring.cjs +3 -3
  47. package/dist/scoring.d.cts +242 -242
  48. package/dist/scoring.d.ts +242 -242
  49. package/dist/scoring.js +2 -2
  50. package/dist/xapi.cjs +3 -3
  51. package/dist/xapi.d.cts +1 -1
  52. package/dist/xapi.d.ts +1 -1
  53. package/dist/xapi.js +2 -2
  54. package/package.json +1 -1
  55. package/dist/chunk-2JT2WUQ2.cjs.map +0 -1
  56. package/dist/chunk-DSDXL3JO.cjs.map +0 -1
  57. package/dist/chunk-FBKTION6.js.map +0 -1
  58. package/dist/chunk-RCZCP5OE.js +0 -729
  59. package/dist/chunk-RCZCP5OE.js.map +0 -1
  60. package/dist/chunk-W5KB3DNT.cjs +0 -729
  61. package/dist/chunk-W5KB3DNT.cjs.map +0 -1
  62. package/dist/chunk-XS6U2ARZ.js.map +0 -1
  63. /package/dist/{chunk-SJVRUPJT.js.map → chunk-JTNDIBZO.js.map} +0 -0
  64. /package/dist/{chunk-IARLJ5MW.js.map → chunk-QX2ERL72.js.map} +0 -0
@@ -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: both are a model's words about the
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' | (string & {});
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 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 };
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 };