@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
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { x as AiSupportedActivityType, g as AiActivityInput, l as AiFeature, a4 as LearnerResponse, a3 as ItemOutcome, k as AiExplanationRequest, p as AiGrade, q as AiHintRequest, ak as ScoringDetail, r as AiItemFacts, y as AiTextResult, v as AiRefusal, F as AiWritingFeedbackRequest, E as AiWritingFeedback, a as ActivityData, ap as ValidationError, f as ActivityType, b as ActivityDataMap, I as CriterionScore, X as GradeRecord, ac as NativeControlHint, d as ActivityMedia, am as ScoringResult, K as DeferredScoringPartial, L as DictationData, N as DictationLearnerResponse, Q as FillInTheBlanksData, R as FillInTheBlanksLearnerResponse, U as GapSelectData, W as GapSelectLearnerResponse, a8 as MultipleChoiceData, a9 as MultipleChoiceLearnerResponse, ad as ReadAloudData, ag as ReadAloudLearnerResponse, ar as WrittenResponseData, as as WrittenResponseLearnerResponse } from './activity-DgpBJeBc.js';
2
- export { A as ActivityAiPermissions, c as ActivityFeedback, e as ActivityResult, h as AiBlankFact, i as AiCriterionJudgement, j as AiDictationFacts, m as AiFillInTheBlanksFacts, n as AiGapFact, o as AiGapSelectFacts, s as AiMultipleChoiceFacts, t as AiOptionFact, u as AiProvenance, w as AiRubricCriterionFact, z as AiVerdict, B as AiWordFact, C as AiWritingCorrection, D as AiWritingFacts, G as AiWritingFeedbackResult, H as BlankConfig, J as DeferredReason, M as DictationEquivalence, O as DictationSlowMedia, P as DictationTolerance, S as GapSelectBank, T as GapSelectChoice, V as GapSelectGap, Y as Grader, Z as GraderKind, _ as GraderUsage, $ as GradingState, a0 as InlineCorrection, a1 as InteractionEvent, a2 as InteractionKind, a5 as LearnerResponseMap, a6 as MediaPlaybackPolicy, a7 as MediaTrack, aa as MultipleChoiceOption, ab as MultipleChoiceOptionMedia, ae as ReadAloudDimension, af as ReadAloudDimensionWeight, ah as ReadAloudSlowMedia, ai as RecordingBounds, aj as RecordingRef, al as ScoringOutcome, an as TextMatchPolicy, ao as TextMatchResult, aq as ValidationResult, at as WrittenResponseRubric, au as WrittenResponseRubricCriterion, av as XAPIActor, aw as XAPIConfig, ax as XAPIContext, ay as XAPIContextActivities, az as XAPIError, aA as XAPIObject, aB as XAPIResult, aC as XAPIScore, aD as XAPIStatement, aE as XAPIVerbObject, aF as levenshteinDistance, aG as matchText } from './activity-DgpBJeBc.js';
3
- import { ResolvedItemScoringPolicy, ItemScoringPolicy, ScoredItem, RoundingPolicy, CompositionPolicy, AssessmentScore } from './scoring.js';
4
- export { AssessmentSectionInput, Band, DEFAULT_ITEM_SCORING_POLICY, DEFAULT_PASS_THRESHOLD, DICTATION_MAX_ACCEPTED_TRANSCRIPTS, DICTATION_MAX_EQUIVALENCES, DICTATION_MAX_EQUIVALENCE_LENGTH, DICTATION_MAX_TEXT_LENGTH, DICTATION_MAX_TRANSCRIPT_LENGTH, DictationAlignment, DictationCharOp, DictationReference, DictationWordAlignment, EvaluateOptions, GradeReadAloudOptions, ITEM_SCORING_MAX_RETRIES, ItemScoringCount, ItemScoringPolicyIssue, ItemTriesOutcome, ItemTriesScore, ItemTry, ItemTryScore, PassFailureReason, READ_ALOUD_MAX_DIMENSION_WEIGHT, READ_ALOUD_MAX_REFERENCE_LENGTH, READ_ALOUD_MAX_SECONDS, READ_ALOUD_MAX_TAKES, ReadAloudWordAlignment, ReadAloudWordState, RoundingMode, SPEECH_ASSESSMENT_MAX_WORDS, ScoringOptions, SectionScore, SpeechAssessment, SpeechMeasurement, SpeechPhoneme, SpeechPhonemeCandidate, SpeechPlausibilityPolicy, SpeechSyllable, SpeechUnscorable, SpeechUnscorableCode, SpeechWord, SpeechWordError, WavInspection, WavInspectionPolicy, alignDictation, alignReadAloud, classifyBand, composeAssessmentScore, computePassThreshold, dictationReferenceWords, diffDictationChars, evaluate, evaluateTries, gradeReadAloud, gte, inspectWav, outcomeFromUnscorable, resolveItemScoringPolicy, roundGrade, score, scoreTries, validateItemScoringPolicy, validateSpeechAssessment } from './scoring.js';
5
- import { p as SequenceSlot, S as SequenceEntry, I as ItemGroup, M as MediaProgress } from './index-BVNeSCWC.js';
6
- export { a as MediaTimeline, R as RedactedActivity, b as RedactedBlankConfig, c as RedactedDictationData, d as RedactedDictationSlowMedia, e as RedactedFillInTheBlanksData, f as RedactedGapSelectBank, g as RedactedGapSelectChoice, h as RedactedGapSelectData, i as RedactedGapSelectGap, j as RedactedMultipleChoiceData, k as RedactedMultipleChoiceOption, l as RedactedMultipleChoiceOptionMedia, m as RedactedReadAloudData, n as RedactedStimulus, o as RedactedWrittenResponseData, q as SequenceSlotGroup, r as Stimulus, s as StimulusKind, T as TimelineChapter, t as TimelineCue, u as dictationJsonSchema, v as fillInTheBlanksJsonSchema, w as gapSelectJsonSchema, x as itemGroupJsonSchema, y as jsonSchemaFor, z as multipleChoiceJsonSchema, A as readAloudJsonSchema, B as stimulusJsonSchema, C as validateActivity, D as validateItemGroup, E as validateMedia, F as validateOptionMedia, G as writtenResponseJsonSchema } from './index-BVNeSCWC.js';
1
+ import { W as AiSupportedActivityType, g as AiActivityInput, G as AiFeature, aB as LearnerResponse, aA as ItemOutcome, F as AiExplanationRequest, L as AiGrade, M as AiHintRequest, aR as ScoringDetail, N as AiItemFacts, X as AiTextResult, T as AiRefusal, aq as GradeRecord, j as AiCoachingRequest, i as AiCoaching, f as ActivityType, s as AiCritiqueRequest, n as AiCritique, D as AiDraftsRequest, B as AiDrafts, K as AiGeneratedDraft, z as AiDraftType, y as AiDraftSource, x as AiDraftSettings, E as AiDraftsRun, d as ActivityMedia, Z as AiVideoDraft, a2 as AiWritingFeedbackRequest, a1 as AiWritingFeedback, a as ActivityData, ae as DraftContext, ay as ItemFinding, ai as DraftValidationResult, b as ActivityDataMap, aW as ValidationError, a5 as CriterionScore, aJ as NativeControlHint, af as DraftIssue, aT as ScoringResult, a7 as DeferredScoringPartial, a8 as DictationData, aa as DictationLearnerResponse, aj as FillInTheBlanksData, ak as FillInTheBlanksLearnerResponse, an as GapSelectData, ap as GapSelectLearnerResponse, aF as MultipleChoiceData, aG as MultipleChoiceLearnerResponse, aK as ReadAloudData, aN as ReadAloudLearnerResponse, aY as WrittenResponseData, aZ as WrittenResponseLearnerResponse } from './activity-D705CXng.js';
2
+ export { A as ActivityAiPermissions, c as ActivityFeedback, e as ActivityResult, h as AiBlankFact, k as AiCoachingResult, l as AiCoachingWord, m as AiCriterionJudgement, o as AiCritiqueField, p as AiCritiqueFinding, q as AiCritiqueFindingResult, r as AiCritiqueKind, t as AiCritiqueResult, u as AiDictationFacts, v as AiDraftCaption, w as AiDraftProblem, C as AiDraftsCall, H as AiFillInTheBlanksFacts, I as AiGapFact, J as AiGapSelectFacts, O as AiMultipleChoiceFacts, P as AiOptionFact, Q as AiProvenance, R as AiReadingFacts, S as AiReadingWordFact, U as AiRubricCriterionFact, V as AiSoundFact, Y as AiVerdict, _ as AiWordFact, $ as AiWritingCorrection, a0 as AiWritingFacts, a3 as AiWritingFeedbackResult, a4 as BlankConfig, a6 as DeferredReason, a9 as DictationEquivalence, ab as DictationSlowMedia, ac as DictationTolerance, ad as DraftComplete, ag as DraftNotComplete, ah as DraftSeverity, al as GapSelectBank, am as GapSelectChoice, ao as GapSelectGap, ar as Grader, as as GraderKind, at as GraderUsage, au as GradingState, av as InlineCorrection, aw as InteractionEvent, ax as InteractionKind, az as ItemFindingSeverity, aC as LearnerResponseMap, aD as MediaPlaybackPolicy, aE as MediaTrack, aH as MultipleChoiceOption, aI as MultipleChoiceOptionMedia, aL as ReadAloudDimension, aM as ReadAloudDimensionWeight, aO as ReadAloudSlowMedia, aP as RecordingBounds, aQ as RecordingRef, aS as ScoringOutcome, aU as TextMatchPolicy, aV as TextMatchResult, aX as ValidationResult, a_ as WrittenResponseRubric, a$ as WrittenResponseRubricCriterion, b0 as XAPIActor, b1 as XAPIConfig, b2 as XAPIContext, b3 as XAPIContextActivities, b4 as XAPIError, b5 as XAPIObject, b6 as XAPIResult, b7 as XAPIScore, b8 as XAPIStatement, b9 as XAPIVerbObject, ba as levenshteinDistance, bb as matchText } from './activity-D705CXng.js';
3
+ import { SpeechAssessment, ResolvedItemScoringPolicy, ItemScoringPolicy, ScoredItem, RoundingPolicy, CompositionPolicy, AssessmentScore } from './scoring.js';
4
+ export { AssessmentSectionInput, Band, DEFAULT_ITEM_SCORING_POLICY, DEFAULT_PASS_THRESHOLD, DICTATION_MAX_ACCEPTED_TRANSCRIPTS, DICTATION_MAX_EQUIVALENCES, DICTATION_MAX_EQUIVALENCE_LENGTH, DICTATION_MAX_TEXT_LENGTH, DICTATION_MAX_TRANSCRIPT_LENGTH, DictationAlignment, DictationCharOp, DictationReference, DictationWordAlignment, EvaluateOptions, GradeReadAloudOptions, ITEM_SCORING_MAX_RETRIES, ItemScoringCount, ItemScoringPolicyIssue, ItemTriesOutcome, ItemTriesScore, ItemTry, ItemTryScore, PassFailureReason, READ_ALOUD_MAX_DIMENSION_WEIGHT, READ_ALOUD_MAX_REFERENCE_LENGTH, READ_ALOUD_MAX_SECONDS, READ_ALOUD_MAX_TAKES, ReadAloudWordAlignment, ReadAloudWordState, RoundingMode, SPEECH_ASSESSMENT_MAX_WORDS, ScoringOptions, SectionScore, SpeechMeasurement, SpeechPhoneme, SpeechPhonemeCandidate, SpeechPlausibilityPolicy, SpeechSyllable, SpeechUnscorable, SpeechUnscorableCode, SpeechWord, SpeechWordError, WavInspection, WavInspectionPolicy, alignDictation, alignReadAloud, classifyBand, composeAssessmentScore, computePassThreshold, dictationReferenceWords, diffDictationChars, evaluate, evaluateTries, gradeReadAloud, gte, inspectWav, outcomeFromUnscorable, resolveItemScoringPolicy, roundGrade, score, scoreTries, validateItemScoringPolicy, validateSpeechAssessment } from './scoring.js';
5
+ import { p as SequenceSlot, S as SequenceEntry, I as ItemGroup, M as MediaProgress } from './index-BChYtrEe.js';
6
+ export { a as MediaTimeline, R as RedactedActivity, b as RedactedBlankConfig, c as RedactedDictationData, d as RedactedDictationSlowMedia, e as RedactedFillInTheBlanksData, f as RedactedGapSelectBank, g as RedactedGapSelectChoice, h as RedactedGapSelectData, i as RedactedGapSelectGap, j as RedactedMultipleChoiceData, k as RedactedMultipleChoiceOption, l as RedactedMultipleChoiceOptionMedia, m as RedactedReadAloudData, n as RedactedStimulus, o as RedactedWrittenResponseData, q as SequenceSlotGroup, r as Stimulus, s as StimulusKind, T as TimelineChapter, t as TimelineCue, u as dictationJsonSchema, v as fillInTheBlanksJsonSchema, w as gapSelectJsonSchema, x as itemGroupJsonSchema, y as jsonSchemaFor, z as multipleChoiceJsonSchema, A as readAloudJsonSchema, B as stimulusJsonSchema, C as validateActivity, D as validateItemGroup, E as validateMedia, F as validateOptionMedia, G as writtenResponseJsonSchema } from './index-BChYtrEe.js';
7
7
  export { AnsweredStatementParams, CompletedStatementParams, SubmittedStatementParams, XAPIObjectParams, XAPIStatementParams, XAPIVerb, XAPIVerbKey, XAPI_VERB_DISPLAY, validateXAPIStatement, xAPIBuilder, xapiDefinitionFor } from './xapi.js';
8
8
 
9
9
  /**
@@ -18,16 +18,16 @@ declare const AI_TEXT_MAX_LENGTH = 2000;
18
18
  /**
19
19
  * Whether the SDK supports `feature` for this activity type: explanations and
20
20
  * hints for the types it builds facts for, and writing feedback for a written
21
- * response. A read-aloud, or a consumer's own type, has none.
21
+ * response, and coaching for a read-aloud. A consumer's own type has none.
22
22
  */
23
23
  declare function aiSupports(activityType: string, feature: AiFeature): boolean;
24
24
  /**
25
25
  * Whether the item's author allows `feature`. Only an explicit `false`
26
26
  * switches it off: an author can refuse a feature, never force one on.
27
27
  *
28
- * Writing feedback reads `explanations`: both are a model's words about the
29
- * learner's own answer, and an author who switched one off has switched off
30
- * the other.
28
+ * Writing feedback and pronunciation coaching read `explanations`: each is a
29
+ * model's words about the learner's own answer, and an author who switched one
30
+ * off has switched off the others.
31
31
  */
32
32
  declare function aiAllowedByContent(data: AiActivityInput, feature: AiFeature): boolean;
33
33
  /** A grade as an explanation must speak to it: all marks, some, or none. */
@@ -131,6 +131,249 @@ declare function checkAiHint(raw: unknown, request: AiHintRequest): {
131
131
  */
132
132
  declare function hintRevealsAnswer(facts: AiItemFacts, hint: string): boolean;
133
133
 
134
+ /** The most words one coaching may work on. More is refused, not cut. */
135
+ declare const AI_COACHING_MAX_WORDS = 20;
136
+ /** The longest tip for one word, in code points. */
137
+ declare const AI_COACHING_MAX_TIP_LENGTH = 500;
138
+ /**
139
+ * The request for coaching on a graded reading, or `null` when there is none
140
+ * to give: not a read-aloud, an author who switched explanations off (coaching
141
+ * reads `ai.explanations`), or no marks.
142
+ *
143
+ * The marks come from the `assessment` when one is given — with each word's
144
+ * sounds and what each was heard as — and then only from it: an assessment
145
+ * `gradeReadAloud` would not read (no speech heard, unscripted, or made against
146
+ * another text or locale) gives none, rather than a stored grade's marks the
147
+ * learner is not looking at. With no assessment, they come from
148
+ * `grade.details`, without sounds.
149
+ *
150
+ * The facts are the text as the learner saw it, those marks word by word, and
151
+ * the engine's dimension scores. The marks are the engine's; the model
152
+ * explains them.
153
+ */
154
+ declare function aiCoachingRequest(input: {
155
+ data: AiActivityInput;
156
+ assessment?: SpeechAssessment | null;
157
+ grade?: GradeRecord | null;
158
+ learnerLocale?: string;
159
+ }): AiCoachingRequest | null;
160
+ /**
161
+ * Checks coaching a port returned for `request`, and turns it into what a
162
+ * learner is shown. As every AI text, it is shown whole or not at all.
163
+ *
164
+ * - **The text** is read as every AI text is (`readAiTextResult`).
165
+ * - **Every word coached is one the engine marked.** Each `itemId` names a word
166
+ * of the text marked `mispronounced` or `omitted`, once; coaching on a word
167
+ * read correctly, or one the text does not have, refuses the whole reply as
168
+ * `contradicts-marks`. Praise belongs in `text`.
169
+ * - **Every sound named is one the engine reported** for that word, and a sound
170
+ * it was heard as is one the engine heard it as. Where the facts carry no
171
+ * sounds — marks from a stored grade, or an assessor that reports none — any
172
+ * sound is `contradicts-marks`: nothing stands behind it.
173
+ * - **Nothing numeric is read.** A score in the reply is ignored: the marks and
174
+ * the grade are the engine's.
175
+ * - **Limits:** {@link AI_COACHING_MAX_WORDS} words, a tip of
176
+ * {@link AI_COACHING_MAX_TIP_LENGTH} code points; over them `too-long`. A
177
+ * shape that is not the one documented is `malformed`.
178
+ *
179
+ * The words come back in reading order, each with the word as the marks show it
180
+ * (the SDK's reading of the text, never the model's), and each sound spelt as
181
+ * the engine spelt it.
182
+ */
183
+ declare function checkAiCoaching(raw: unknown, request: AiCoachingRequest): {
184
+ ok: true;
185
+ coaching: AiCoaching;
186
+ } | {
187
+ ok: false;
188
+ refusal: AiRefusal;
189
+ };
190
+
191
+ /** The most findings one critique may carry. More is refused, not cut. */
192
+ declare const AI_CRITIQUE_MAX_FINDINGS = 20;
193
+ /** The longest message or quote in a finding, in code points. */
194
+ declare const AI_CRITIQUE_MAX_FIELD_LENGTH = 500;
195
+ /**
196
+ * What a model is given to review an item, or `null` when there is nothing to
197
+ * review: a draft that is not an object, or one with no words in it yet.
198
+ *
199
+ * The facts are the item as the author wrote it — the answer key included; this
200
+ * is for an author, never a learner — every text field a finding may point at,
201
+ * and what the SDK's own critic already found there, so a model spends its
202
+ * words on what a rule cannot see: a stem that reads two ways, a distractor
203
+ * that is defensibly right, a key that is wrong, language above the level.
204
+ *
205
+ * Works for every registered type, the SDK's own and yours: the fields are read
206
+ * from the draft itself.
207
+ *
208
+ * @throws UnknownActivityTypeError when `type` has no registered descriptor.
209
+ */
210
+ declare function aiCritiqueRequest(input: {
211
+ type: ActivityType;
212
+ draft: unknown;
213
+ level?: string;
214
+ authorLocale?: string;
215
+ }): AiCritiqueRequest | null;
216
+ /**
217
+ * Checks a critique a port returned for `request`, and turns it into findings
218
+ * an editor lists beside the SDK's own. As every AI answer, it is shown whole
219
+ * or not at all.
220
+ *
221
+ * - **Every finding points at a field the item has.** Its `path` is one of
222
+ * `facts.fields`, exactly; a path to a field the item does not have refuses
223
+ * the whole reply as `contradicts-item`.
224
+ * - **A quote is words that field contains**, typographic quotes and runs of
225
+ * spacing aside, case kept; one it does not refuses the reply the same way.
226
+ * - **Every finding is `advice`.** It is a model's opinion about the item, and
227
+ * nothing in the SDK acts on it; its code is `ai_` and the kind
228
+ * (`ai_second_answer`).
229
+ * - **Limits:** {@link AI_CRITIQUE_MAX_FINDINGS} findings; a message or quote of
230
+ * {@link AI_CRITIQUE_MAX_FIELD_LENGTH} code points; over them `too-long`. A
231
+ * kind the SDK does not name, or any other shape, is `malformed`.
232
+ */
233
+ declare function checkAiCritique(raw: unknown, request: AiCritiqueRequest): {
234
+ ok: true;
235
+ critique: AiCritique;
236
+ } | {
237
+ ok: false;
238
+ refusal: AiRefusal;
239
+ };
240
+
241
+ /** The most drafts one request may ask for, and the most a reply may hold when it names no count. */
242
+ declare const AI_DRAFTS_MAX_COUNT = 50;
243
+ /** The most repair passes `generateDrafts` makes. */
244
+ declare const AI_DRAFTS_MAX_REPAIRS = 3;
245
+ /**
246
+ * What a model is given to draft items from a source, or `null` when there is
247
+ * no source to draft from: an empty text, or no caption with words in it.
248
+ *
249
+ * `types` are the ones the author chose, in the author's order: the model
250
+ * leans on the first, and where several drafts share a moment of a video — or
251
+ * the end of one — they are shown in this order. `count` is how many to write
252
+ * at most; left out, the model writes as many as the source is worth, up to
253
+ * {@link AI_DRAFTS_MAX_COUNT}.
254
+ *
255
+ * The facts are the source — a caption list numbered, with its times in
256
+ * seconds — the types, the count, and the language, level and instructions
257
+ * the author gave. `shape` is the JSON Schema of the reply: each draft names
258
+ * its type and writes that type's own fields, with no ids, no HTML, no media
259
+ * and no settings. Those are not a model's to write. `settings` are yours, put
260
+ * on every draft of a type: a read-aloud's `recording` and `scoring`, say, which
261
+ * the SDK has no default for.
262
+ *
263
+ * @throws RangeError when `types` is empty, repeats a type or names one a model
264
+ * does not draft, or `count` is not a whole number from 1 to
265
+ * {@link AI_DRAFTS_MAX_COUNT}.
266
+ */
267
+ declare function aiDraftsRequest(input: {
268
+ types: readonly AiDraftType[];
269
+ source: AiDraftSource;
270
+ count?: number;
271
+ locale?: string;
272
+ level?: string;
273
+ instructions?: string;
274
+ settings?: AiDraftSettings;
275
+ }): AiDraftsRequest | null;
276
+ /**
277
+ * Reads a model's reply to {@link aiDraftsRequest} into drafts an editor can
278
+ * show for approval: each with ids from `newId`, your settings for its type,
279
+ * what `validateDraft` says of it, what the item critic finds in it, and — from
280
+ * captions — where it goes, and for a dictation the stretch of the video that
281
+ * says its words. They come back in the author's order of types.
282
+ *
283
+ * Drafts are independent: one that is unfinished or wrong is returned as such,
284
+ * for an author or {@link aiDraftsRepairRequest} to fix, beside the ones that
285
+ * are complete. `complete` means valid, never approved: a model wrote it, and a
286
+ * person decides whether learners see it. The whole reply is refused only when
287
+ * it is not `{ drafts: [...] }` of objects of the chosen types (`malformed`), or
288
+ * holds more drafts than asked for (`too-long`) — on a repair, not exactly one
289
+ * per draft to fix (`malformed`).
290
+ *
291
+ * Only the fields a type's shape names are read: a model cannot set an id,
292
+ * HTML, media, a switch or a scoring setting through this. A question is scored
293
+ * `all-or-nothing` unless your settings say otherwise, a written response's
294
+ * criteria are weighted equally, and a dictation carries no recording — attach
295
+ * one, or cut it from the video at `clip`.
296
+ *
297
+ * @throws Error when `newId` returns an empty or repeated id.
298
+ */
299
+ declare function checkAiDrafts(raw: unknown, request: AiDraftsRequest, options: {
300
+ newId: () => string;
301
+ }): {
302
+ ok: true;
303
+ drafts: AiDrafts;
304
+ } | {
305
+ ok: false;
306
+ refusal: AiRefusal;
307
+ };
308
+ /**
309
+ * A second request, for the drafts with something wrong the model can fix —
310
+ * unfinished, wrong, or a flaw the critic warns about, at a field the model
311
+ * writes — each as the model wrote it, with those problems at the paths the
312
+ * model wrote. `null` when there is none.
313
+ *
314
+ * The reply holds one draft for each, in order; {@link checkAiDrafts} reads it
315
+ * and gives each the `index` of the draft it replaces.
316
+ */
317
+ declare function aiDraftsRepairRequest(request: AiDraftsRequest, drafts: AiDrafts | readonly AiGeneratedDraft[]): AiDraftsRequest | null;
318
+ /**
319
+ * Drafts items from a source, with a bounded repair loop: asks the port with
320
+ * `request`, reads the reply with {@link checkAiDrafts}, then — up to `repairs`
321
+ * times — sends back the drafts with something wrong the model can fix
322
+ * ({@link aiDraftsRepairRequest}), and keeps a repaired draft only when it is
323
+ * no worse than the one it replaces. A repaired draft keeps its id.
324
+ *
325
+ * Never throws for a model's failure: a port that throws or a reply the SDK
326
+ * refuses ends the loop, and is recorded in `calls` beside the provenance and
327
+ * usage of every call — which the SDK never adds up. A first call that fails
328
+ * leaves no drafts.
329
+ *
330
+ * ```ts
331
+ * const run = await generateDrafts({
332
+ * request: aiDraftsRequest({ types: ['multiple-choice', 'dictation'], source: { kind: 'transcript', text } }),
333
+ * port: (request) => callMyModel(DRAFTS_PROMPT, request),
334
+ * newId: () => crypto.randomUUID(),
335
+ * });
336
+ * // run.drafts: store each as proposed, for a person to approve.
337
+ * ```
338
+ *
339
+ * @throws RangeError when `repairs` is not a whole number from 0 to
340
+ * {@link AI_DRAFTS_MAX_REPAIRS} (default 1), and Error when `newId` returns an
341
+ * empty or repeated id.
342
+ */
343
+ declare function generateDrafts(input: {
344
+ request: AiDraftsRequest;
345
+ port: (request: AiDraftsRequest) => Promise<unknown> | unknown;
346
+ newId: () => string;
347
+ repairs?: number;
348
+ }): Promise<AiDraftsRun>;
349
+ /**
350
+ * An interactive video made of drafts: an item group whose stimulus is
351
+ * `video`, whose items are the drafts, and whose timeline opens a quiz at each
352
+ * moment a draft was placed — drafts placed at one moment share its quiz, in
353
+ * the author's order of types — and one more at `durationSeconds` for every
354
+ * draft placed nowhere: all of them when the source had no times.
355
+ *
356
+ * The SDK never reads the video, so it cannot know where the end is: without
357
+ * `durationSeconds` that last quiz has no time yet, which
358
+ * `validateItemGroupDraft` reports for the author to set. The source is kept on
359
+ * the stimulus as its author-only `transcript`.
360
+ *
361
+ * Like every draft it is checked (`validateItemGroupDraft`) and critiqued
362
+ * (`critiqueItemGroupDraft`), never approved. A dictation still needs its own
363
+ * recording; a type a video does not take — a written response — is reported,
364
+ * not dropped.
365
+ *
366
+ * @throws Error when `newId` returns an empty or repeated id.
367
+ */
368
+ declare function interactiveVideoFromDrafts(input: {
369
+ request: AiDraftsRequest;
370
+ drafts: AiDrafts | AiDraftsRun | readonly AiGeneratedDraft[];
371
+ video: ActivityMedia;
372
+ durationSeconds?: number;
373
+ title?: string;
374
+ newId: () => string;
375
+ }): AiVideoDraft;
376
+
134
377
  /** The most corrections one piece of writing feedback may carry. More is refused, not cut. */
135
378
  declare const AI_WRITING_MAX_CORRECTIONS = 20;
136
379
  /** The longest quote, correction, explanation or criterion comment, in code points. */
@@ -652,61 +895,6 @@ declare function restoreAttemptState(plan: AttemptPlan, state: AttemptState): At
652
895
  */
653
896
  declare function diffResponses(before: Pick<AttemptState, 'responses'>, after: Pick<AttemptState, 'responses'>): ResponseDiffEntry[];
654
897
 
655
- /**
656
- * Why a draft is not an activity yet.
657
- *
658
- * - `incomplete` — something the author has not written yet: an empty title, an
659
- * option with no text, no option marked correct. The fix is to add it.
660
- * - `invalid` — something is wrong in a way that writing more cannot fix: two
661
- * correct options on a single-selection question, a maximum word count below
662
- * the minimum, a media address with a scheme the SDK refuses, a `null` in an
663
- * optional field that accepts none. The fix is to change it.
664
- */
665
- type DraftSeverity = 'incomplete' | 'invalid';
666
- /**
667
- * One problem with a draft. A {@link ValidationError} with a severity, so code
668
- * that already lists `validateActivity` errors can list these unchanged.
669
- */
670
- interface DraftIssue extends ValidationError {
671
- severity: DraftSeverity;
672
- }
673
- /** A draft that is a valid activity and has nothing left to write. */
674
- interface DraftComplete<T> {
675
- status: 'complete';
676
- /** The validated activity, exactly as `validateActivity` returns it. */
677
- data: T;
678
- /** Always empty. Present so that every result can be read the same way. */
679
- issues: DraftIssue[];
680
- }
681
- /**
682
- * A draft that is not an activity yet: `invalid` when any issue is invalid,
683
- * otherwise `incomplete`. It carries no `data`, because nothing here may be
684
- * stored or rendered as an activity.
685
- */
686
- interface DraftNotComplete {
687
- status: 'incomplete' | 'invalid';
688
- issues: DraftIssue[];
689
- }
690
- /**
691
- * The result of `validateDraft`.
692
- *
693
- * There is deliberately no `success` boolean. A boolean has to call an
694
- * incomplete draft either a success, which lets a half-written answer key
695
- * through anything that checks it, or a failure, which is the conflation this
696
- * result exists to remove. Branch on `status`.
697
- */
698
- type DraftValidationResult<T> = DraftComplete<T> | DraftNotComplete;
699
- /** What `createDraft` hands an activity type's `authoring.createDraft`. */
700
- interface DraftContext {
701
- /**
702
- * Returns a new id on every call. The SDK invents none: an id made here would
703
- * need `crypto`, which plain-http origins do not have, or would be positional —
704
- * and option ids reach the learner, so ids like `"a"` and `"b"` would tell them
705
- * which option was written first.
706
- */
707
- newId: () => string;
708
- }
709
-
710
898
  /**
711
899
  * A new, empty reading or listening testlet for an editor to start from.
712
900
  *
@@ -757,6 +945,24 @@ declare function createInteractiveVideoDraft(context: DraftContext): ItemGroup;
757
945
  * turned into an issue: a fault in a type's own code is not a problem with the
758
946
  * draft, and reporting it as an unknown type would hide it.
759
947
  */
948
+ /**
949
+ * The item critic over a testlet: each item's findings, under `items.N.…`, and
950
+ * what only the set shows — every single-answer question keeping its right
951
+ * option in one place. The stimulus is not searched for answers: a reading
952
+ * group's answers are meant to be in its passage.
953
+ *
954
+ * An item of a type that is not registered, or without a `type`, is skipped:
955
+ * {@link validateItemGroupDraft} already reports it.
956
+ */
957
+ declare function critiqueItemGroupDraft(draft: unknown): ItemFinding[];
958
+ /**
959
+ * The item critic over a question set, as `<ActivitySequence>` takes one: each
960
+ * entry's findings under its index — an item group's under `N.items.M.…` — and,
961
+ * over the entries that are items, what only the set shows (see
962
+ * {@link critiqueItemGroupDraft}). An entry of a type that is not registered is
963
+ * skipped.
964
+ */
965
+ declare function critiqueDrafts(entries: readonly unknown[]): ItemFinding[];
760
966
  declare function validateItemGroupDraft(draft: unknown): DraftValidationResult<ItemGroup>;
761
967
 
762
968
  /**
@@ -815,6 +1021,29 @@ declare function validateDraft<T extends ActivityType>(type: T, draft: unknown):
815
1021
  * `newId` returns an empty or repeated id.
816
1022
  */
817
1023
  declare function createDraft<T extends ActivityType>(type: T, context: DraftContext): ActivityDataMap[T];
1024
+ /**
1025
+ * What an experienced item writer would point out on review: flaws a learner
1026
+ * can exploit or trip over (`warning`) and item-writing guidelines the item
1027
+ * departs from (`advice`) — the right option much longer than the rest, an
1028
+ * answer printed in the passage, a hint that gives the answer away, two
1029
+ * options that read the same, "all of the above" under shuffle.
1030
+ *
1031
+ * A finding is never a reason to refuse an item. It does not change what
1032
+ * {@link validateDraft} says: a valid item with findings is still valid. The
1033
+ * shape is a `DraftIssue`'s, so an editor shows both in one list.
1034
+ *
1035
+ * It reads a draft, finished or not, and skips any rule whose fields are not
1036
+ * written yet. The codes are documented in `docs/authoring.md`, each with its
1037
+ * severity; the rule behind a code is advice and may be refined in a minor.
1038
+ *
1039
+ * ```ts
1040
+ * const list = [...validateDraft(type, draft).issues, ...critiqueDraft(type, draft)];
1041
+ * ```
1042
+ *
1043
+ * @throws UnknownActivityTypeError when `type` has no registered descriptor —
1044
+ * including `'item-group'`: use {@link critiqueItemGroupDraft}.
1045
+ */
1046
+ declare function critiqueDraft(type: ActivityType, draft: unknown): ItemFinding[];
818
1047
 
819
1048
  /**
820
1049
  * Content fingerprinting — "is this the same content the learner was served?"
@@ -1376,6 +1605,19 @@ interface ActivityTypeAuthoring<TData> {
1376
1605
  * reported as `invalid`.
1377
1606
  */
1378
1607
  readonly checkDraft?: (draft: Readonly<Record<string, unknown>>) => DraftIssue[];
1608
+ /**
1609
+ * The item critic for the type: what `critiqueDraft` reports about a draft
1610
+ * that may be perfectly valid — a flaw a learner can exploit (`warning`), or
1611
+ * an item-writing guideline it departs from (`advice`). Receives any plain
1612
+ * object, finished or not, and must not throw on one: skip a rule whose
1613
+ * fields are not there yet. Never a reason to refuse the item; that is
1614
+ * `checkDraft`'s.
1615
+ *
1616
+ * A code documented in `docs/authoring.md` is reported with its documented
1617
+ * severity. For a code of your own, a severity other than `'advice'` is
1618
+ * reported as `warning`.
1619
+ */
1620
+ readonly critique?: (draft: Readonly<Record<string, unknown>>) => ItemFinding[];
1379
1621
  }
1380
1622
  /**
1381
1623
  * A value-level description of an activity type: its contract (schema), its
@@ -1795,4 +2037,4 @@ interface ThemeTokens {
1795
2037
  '--lk-transition-base': string;
1796
2038
  }
1797
2039
 
1798
- export { AI_EXPLANATION_TYPES, AI_HINT_TYPES, AI_TEXT_MAX_LENGTH, AI_WRITING_MAX_CORRECTIONS, AI_WRITING_MAX_FIELD_LENGTH, ActivityData, ActivityDataMap, ActivityMedia, ActivitySchemaError, ActivityType, type ActivityTypeAuthoring, type ActivityTypeDescriptor, type ActivityTypeInterop, type ActivityTypeScoring, AiActivityInput, AiExplanationRequest, AiFeature, AiGrade, AiHintRequest, AiItemFacts, AiRefusal, AiSupportedActivityType, AiTextResult, AiWritingFeedback, AiWritingFeedbackRequest, AssessmentScore, type AttemptPlan, type AttemptPlanDrift, type AttemptPlanSlot, type AttemptProgress, type AttemptState, CompositionPolicy, CriterionScore, DeferredScoringError, DeferredScoringPartial, type DeliveryPolicy, type DeliveryPolicyIssue, DictationData, DictationLearnerResponse, type DraftComplete, type DraftContext, type DraftIssue, type DraftNotComplete, type DraftSeverity, type DraftValidationResult, type FieldPolicy, FillInTheBlanksData, FillInTheBlanksLearnerResponse, type FlattenSequenceOptions, GapSelectData, GapSelectLearnerResponse, type GradeFromRubricOptions, GradeRecord, INTERACTIVE_VIDEO_ITEM_TYPES, type InteractiveVideoItemType, ItemGroup, ItemOutcome, ItemScoringPolicy, LearnerResponse, type MediaBudgetRef, type MediaPlayClaim, type MediaPlayGrant, type MediaPlayLedger, type MediaPlayLedgerEntry, MediaProgress, type MissingOutcomePolicy, MultipleChoiceData, MultipleChoiceLearnerResponse, NativeControlHint, OPEN_DELIVERY_POLICY, type PartialScoringResult, type PlanAttemptOptions, type PlannableEntry, ReadAloudData, ReadAloudLearnerResponse, type RedactOptions, type RedactedActivityData, type RedactedItemGroup, RedactedScoringError, type RegisteredActivityTypeDescriptor, type ResolvedDeliveryPolicy, ResolvedItemScoringPolicy, type ResolvedPlaybackPolicy, type ResponseDiffEntry, RoundingPolicy, ScoredItem, ScoringDetail, ScoringResult, type SeededShuffleOptions, type Sensitivity, SequenceEntry, SequenceSlot, type ShuffleVersion, StandardSchemaV1, TIMELINE_MAX_CHAPTERS, TIMELINE_MAX_ITEMS, TIMELINE_MAX_QUIZZES, TIMELINE_MAX_TITLE_LENGTH, type ThemeTokens, UnknownActivityTypeError, ValidationError, WrittenResponseData, WrittenResponseLearnerResponse, type XAPIInteractionType, aiAllowedByContent, aiExplanationRequest, aiGradeOf, aiHintRequest, aiSupports, aiWritingFeedbackRequest, assertRedacted, assertRedactedItemGroup, buildAiFacts, canonicalJson, checkAiExplanation, checkAiHint, checkAiWritingFeedback, combineDeliveryPolicies, composeTimelineScore, contentHash, countWords, createDraft, createInteractiveVideoDraft, createItemGroupDraft, defineActivityType, dictationType, diffResponses, entryKeyOf, fillInTheBlanksType, fingerprint, flattenSequence, gapSelectType, getActivityTypeDescriptor, gradeFromRubric, hasGrade, hashSeed, hintRevealsAnswer, isInteractiveVideoItemType, isItemGroup, multipleChoiceType, outcomeFromGrade, planAttempt, planMediaBudgets, readAiTextResult, readAloudType, readMediaProgress, redact, redactItemGroup, registerActivityType, registeredActivityTypes, resolveDeliveryPolicy, resolvePlaybackPolicy, restoreAttemptState, restoreMediaPlayLedger, scoredItemsFromPlan, seededShuffle, serializeAttemptState, serializeMediaPlayLedger, slotMediaKey, stimulusMediaKey, validateDeliveryPolicy, validateDraft, validateItemGroupDraft, verifyAttemptPlan, writtenResponseType };
2040
+ export { AI_COACHING_MAX_TIP_LENGTH, AI_COACHING_MAX_WORDS, AI_CRITIQUE_MAX_FIELD_LENGTH, AI_CRITIQUE_MAX_FINDINGS, AI_DRAFTS_MAX_COUNT, AI_DRAFTS_MAX_REPAIRS, AI_EXPLANATION_TYPES, AI_HINT_TYPES, AI_TEXT_MAX_LENGTH, AI_WRITING_MAX_CORRECTIONS, AI_WRITING_MAX_FIELD_LENGTH, ActivityData, ActivityDataMap, ActivityMedia, ActivitySchemaError, ActivityType, type ActivityTypeAuthoring, type ActivityTypeDescriptor, type ActivityTypeInterop, type ActivityTypeScoring, AiActivityInput, AiCoaching, AiCoachingRequest, AiCritique, AiCritiqueRequest, AiDraftSettings, AiDraftSource, AiDraftType, AiDrafts, AiDraftsRequest, AiDraftsRun, AiExplanationRequest, AiFeature, AiGeneratedDraft, AiGrade, AiHintRequest, AiItemFacts, AiRefusal, AiSupportedActivityType, AiTextResult, AiVideoDraft, AiWritingFeedback, AiWritingFeedbackRequest, AssessmentScore, type AttemptPlan, type AttemptPlanDrift, type AttemptPlanSlot, type AttemptProgress, type AttemptState, CompositionPolicy, CriterionScore, DeferredScoringError, DeferredScoringPartial, type DeliveryPolicy, type DeliveryPolicyIssue, DictationData, DictationLearnerResponse, DraftContext, DraftIssue, DraftValidationResult, type FieldPolicy, FillInTheBlanksData, FillInTheBlanksLearnerResponse, type FlattenSequenceOptions, GapSelectData, GapSelectLearnerResponse, type GradeFromRubricOptions, GradeRecord, INTERACTIVE_VIDEO_ITEM_TYPES, type InteractiveVideoItemType, ItemFinding, ItemGroup, ItemOutcome, ItemScoringPolicy, LearnerResponse, type MediaBudgetRef, type MediaPlayClaim, type MediaPlayGrant, type MediaPlayLedger, type MediaPlayLedgerEntry, MediaProgress, type MissingOutcomePolicy, MultipleChoiceData, MultipleChoiceLearnerResponse, NativeControlHint, OPEN_DELIVERY_POLICY, type PartialScoringResult, type PlanAttemptOptions, type PlannableEntry, ReadAloudData, ReadAloudLearnerResponse, type RedactOptions, type RedactedActivityData, type RedactedItemGroup, RedactedScoringError, type RegisteredActivityTypeDescriptor, type ResolvedDeliveryPolicy, ResolvedItemScoringPolicy, type ResolvedPlaybackPolicy, type ResponseDiffEntry, RoundingPolicy, ScoredItem, ScoringDetail, ScoringResult, type SeededShuffleOptions, type Sensitivity, SequenceEntry, SequenceSlot, type ShuffleVersion, SpeechAssessment, StandardSchemaV1, TIMELINE_MAX_CHAPTERS, TIMELINE_MAX_ITEMS, TIMELINE_MAX_QUIZZES, TIMELINE_MAX_TITLE_LENGTH, type ThemeTokens, UnknownActivityTypeError, ValidationError, WrittenResponseData, WrittenResponseLearnerResponse, type XAPIInteractionType, aiAllowedByContent, aiCoachingRequest, aiCritiqueRequest, aiDraftsRepairRequest, aiDraftsRequest, aiExplanationRequest, aiGradeOf, aiHintRequest, aiSupports, aiWritingFeedbackRequest, assertRedacted, assertRedactedItemGroup, buildAiFacts, canonicalJson, checkAiCoaching, checkAiCritique, checkAiDrafts, checkAiExplanation, checkAiHint, checkAiWritingFeedback, combineDeliveryPolicies, composeTimelineScore, contentHash, countWords, createDraft, createInteractiveVideoDraft, createItemGroupDraft, critiqueDraft, critiqueDrafts, critiqueItemGroupDraft, defineActivityType, dictationType, diffResponses, entryKeyOf, fillInTheBlanksType, fingerprint, flattenSequence, gapSelectType, generateDrafts, getActivityTypeDescriptor, gradeFromRubric, hasGrade, hashSeed, hintRevealsAnswer, interactiveVideoFromDrafts, isInteractiveVideoItemType, isItemGroup, multipleChoiceType, outcomeFromGrade, planAttempt, planMediaBudgets, readAiTextResult, readAloudType, readMediaProgress, redact, redactItemGroup, registerActivityType, registeredActivityTypes, resolveDeliveryPolicy, resolvePlaybackPolicy, restoreAttemptState, restoreMediaPlayLedger, scoredItemsFromPlan, seededShuffle, serializeAttemptState, serializeMediaPlayLedger, slotMediaKey, stimulusMediaKey, validateDeliveryPolicy, validateDraft, validateItemGroupDraft, verifyAttemptPlan, writtenResponseType };