@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.
Files changed (64) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +2 -1
  3. package/dist/{activity-MBOYLBjR.d.cts → activity-D705CXng.d.cts} +324 -2
  4. package/dist/{activity-MBOYLBjR.d.ts → activity-D705CXng.d.ts} +324 -2
  5. package/dist/ai-check.cjs +174 -12
  6. package/dist/ai-check.cjs.map +1 -1
  7. package/dist/ai-check.d.cts +15 -3
  8. package/dist/ai-check.d.ts +15 -3
  9. package/dist/ai-check.js +166 -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-DlcqkM_L.d.ts → index-BChYtrEe.d.ts} +1 -1
  34. package/dist/{index-DlCW0XaQ.d.cts → index-VXt_v3YI.d.cts} +1 -1
  35. package/dist/index.cjs +68 -593
  36. package/dist/index.cjs.map +1 -1
  37. package/dist/index.d.cts +245 -60
  38. package/dist/index.d.ts +245 -60
  39. package/dist/index.js +68 -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 +2 -2
  48. package/dist/scoring.d.ts +2 -2
  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-LDFQUZII.cjs +0 -950
  59. package/dist/chunk-LDFQUZII.cjs.map +0 -1
  60. package/dist/chunk-NQHETFDA.js +0 -950
  61. package/dist/chunk-NQHETFDA.js.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.cts CHANGED
@@ -1,9 +1,9 @@
1
- import { F as AiSupportedActivityType, g as AiActivityInput, p as AiFeature, ab as LearnerResponse, aa as ItemOutcome, o as AiExplanationRequest, t as AiGrade, u as AiHintRequest, ar as ScoringDetail, v as AiItemFacts, G as AiTextResult, C as AiRefusal, a2 as GradeRecord, j as AiCoachingRequest, i as AiCoaching, M as AiWritingFeedbackRequest, L as AiWritingFeedback, a as ActivityData, aw as ValidationError, f as ActivityType, b as ActivityDataMap, P as CriterionScore, aj as NativeControlHint, d as ActivityMedia, at as ScoringResult, R as DeferredScoringPartial, S as DictationData, U as DictationLearnerResponse, X as FillInTheBlanksData, Y as FillInTheBlanksLearnerResponse, $ as GapSelectData, a1 as GapSelectLearnerResponse, af as MultipleChoiceData, ag as MultipleChoiceLearnerResponse, ak as ReadAloudData, an as ReadAloudLearnerResponse, ay as WrittenResponseData, az as WrittenResponseLearnerResponse } from './activity-MBOYLBjR.cjs';
2
- export { A as ActivityAiPermissions, c as ActivityFeedback, e as ActivityResult, h as AiBlankFact, k as AiCoachingResult, l as AiCoachingWord, m as AiCriterionJudgement, n as AiDictationFacts, q as AiFillInTheBlanksFacts, r as AiGapFact, s as AiGapSelectFacts, w as AiMultipleChoiceFacts, x as AiOptionFact, y as AiProvenance, z as AiReadingFacts, B as AiReadingWordFact, D as AiRubricCriterionFact, E as AiSoundFact, H as AiVerdict, I as AiWordFact, J as AiWritingCorrection, K as AiWritingFacts, N as AiWritingFeedbackResult, O as BlankConfig, Q as DeferredReason, T as DictationEquivalence, V as DictationSlowMedia, W as DictationTolerance, Z as GapSelectBank, _ as GapSelectChoice, a0 as GapSelectGap, a3 as Grader, a4 as GraderKind, a5 as GraderUsage, a6 as GradingState, a7 as InlineCorrection, a8 as InteractionEvent, a9 as InteractionKind, 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, aA as WrittenResponseRubric, aB as WrittenResponseRubricCriterion, aC as XAPIActor, aD as XAPIConfig, aE as XAPIContext, aF as XAPIContextActivities, aG as XAPIError, aH as XAPIObject, aI as XAPIResult, aJ as XAPIScore, aK as XAPIStatement, aL as XAPIVerbObject, aM as levenshteinDistance, aN as matchText } from './activity-MBOYLBjR.cjs';
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.cjs';
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.cjs';
3
3
  import { SpeechAssessment, ResolvedItemScoringPolicy, ItemScoringPolicy, ScoredItem, RoundingPolicy, CompositionPolicy, AssessmentScore } from './scoring.cjs';
4
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.cjs';
5
- import { p as SequenceSlot, S as SequenceEntry, I as ItemGroup, M as MediaProgress } from './index-DlCW0XaQ.cjs';
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-DlCW0XaQ.cjs';
5
+ import { p as SequenceSlot, S as SequenceEntry, I as ItemGroup, M as MediaProgress } from './index-VXt_v3YI.cjs';
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-VXt_v3YI.cjs';
7
7
  export { AnsweredStatementParams, CompletedStatementParams, SubmittedStatementParams, XAPIObjectParams, XAPIStatementParams, XAPIVerb, XAPIVerbKey, XAPI_VERB_DISPLAY, validateXAPIStatement, xAPIBuilder, xapiDefinitionFor } from './xapi.cjs';
8
8
 
9
9
  /**
@@ -188,6 +188,192 @@ declare function checkAiCoaching(raw: unknown, request: AiCoachingRequest): {
188
188
  refusal: AiRefusal;
189
189
  };
190
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
+
191
377
  /** The most corrections one piece of writing feedback may carry. More is refused, not cut. */
192
378
  declare const AI_WRITING_MAX_CORRECTIONS = 20;
193
379
  /** The longest quote, correction, explanation or criterion comment, in code points. */
@@ -709,61 +895,6 @@ declare function restoreAttemptState(plan: AttemptPlan, state: AttemptState): At
709
895
  */
710
896
  declare function diffResponses(before: Pick<AttemptState, 'responses'>, after: Pick<AttemptState, 'responses'>): ResponseDiffEntry[];
711
897
 
712
- /**
713
- * Why a draft is not an activity yet.
714
- *
715
- * - `incomplete` — something the author has not written yet: an empty title, an
716
- * option with no text, no option marked correct. The fix is to add it.
717
- * - `invalid` — something is wrong in a way that writing more cannot fix: two
718
- * correct options on a single-selection question, a maximum word count below
719
- * the minimum, a media address with a scheme the SDK refuses, a `null` in an
720
- * optional field that accepts none. The fix is to change it.
721
- */
722
- type DraftSeverity = 'incomplete' | 'invalid';
723
- /**
724
- * One problem with a draft. A {@link ValidationError} with a severity, so code
725
- * that already lists `validateActivity` errors can list these unchanged.
726
- */
727
- interface DraftIssue extends ValidationError {
728
- severity: DraftSeverity;
729
- }
730
- /** A draft that is a valid activity and has nothing left to write. */
731
- interface DraftComplete<T> {
732
- status: 'complete';
733
- /** The validated activity, exactly as `validateActivity` returns it. */
734
- data: T;
735
- /** Always empty. Present so that every result can be read the same way. */
736
- issues: DraftIssue[];
737
- }
738
- /**
739
- * A draft that is not an activity yet: `invalid` when any issue is invalid,
740
- * otherwise `incomplete`. It carries no `data`, because nothing here may be
741
- * stored or rendered as an activity.
742
- */
743
- interface DraftNotComplete {
744
- status: 'incomplete' | 'invalid';
745
- issues: DraftIssue[];
746
- }
747
- /**
748
- * The result of `validateDraft`.
749
- *
750
- * There is deliberately no `success` boolean. A boolean has to call an
751
- * incomplete draft either a success, which lets a half-written answer key
752
- * through anything that checks it, or a failure, which is the conflation this
753
- * result exists to remove. Branch on `status`.
754
- */
755
- type DraftValidationResult<T> = DraftComplete<T> | DraftNotComplete;
756
- /** What `createDraft` hands an activity type's `authoring.createDraft`. */
757
- interface DraftContext {
758
- /**
759
- * Returns a new id on every call. The SDK invents none: an id made here would
760
- * need `crypto`, which plain-http origins do not have, or would be positional —
761
- * and option ids reach the learner, so ids like `"a"` and `"b"` would tell them
762
- * which option was written first.
763
- */
764
- newId: () => string;
765
- }
766
-
767
898
  /**
768
899
  * A new, empty reading or listening testlet for an editor to start from.
769
900
  *
@@ -814,6 +945,24 @@ declare function createInteractiveVideoDraft(context: DraftContext): ItemGroup;
814
945
  * turned into an issue: a fault in a type's own code is not a problem with the
815
946
  * draft, and reporting it as an unknown type would hide it.
816
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[];
817
966
  declare function validateItemGroupDraft(draft: unknown): DraftValidationResult<ItemGroup>;
818
967
 
819
968
  /**
@@ -872,6 +1021,29 @@ declare function validateDraft<T extends ActivityType>(type: T, draft: unknown):
872
1021
  * `newId` returns an empty or repeated id.
873
1022
  */
874
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[];
875
1047
 
876
1048
  /**
877
1049
  * Content fingerprinting — "is this the same content the learner was served?"
@@ -1433,6 +1605,19 @@ interface ActivityTypeAuthoring<TData> {
1433
1605
  * reported as `invalid`.
1434
1606
  */
1435
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[];
1436
1621
  }
1437
1622
  /**
1438
1623
  * A value-level description of an activity type: its contract (schema), its
@@ -1852,4 +2037,4 @@ interface ThemeTokens {
1852
2037
  '--lk-transition-base': string;
1853
2038
  }
1854
2039
 
1855
- export { AI_COACHING_MAX_TIP_LENGTH, AI_COACHING_MAX_WORDS, 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, 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, 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, aiExplanationRequest, aiGradeOf, aiHintRequest, aiSupports, aiWritingFeedbackRequest, assertRedacted, assertRedactedItemGroup, buildAiFacts, canonicalJson, checkAiCoaching, 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 };