@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/scoring.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { a3 as ItemOutcome, Y as Grader, L as DictationData, a as ActivityData, ad as ReadAloudData, aq as ValidationResult, ag as ReadAloudLearnerResponse, X as GradeRecord, a4 as LearnerResponse, f as ActivityType, am as ScoringResult } from './activity-DgpBJeBc.js';
2
- export { aj as RecordingRef, an as TextMatchPolicy, ao as TextMatchResult, aF as levenshteinDistance, aG as matchText } from './activity-DgpBJeBc.js';
1
+ import { ar as Grader, aA as ItemOutcome, a8 as DictationData, a as ActivityData, aK as ReadAloudData, aX as ValidationResult, aN as ReadAloudLearnerResponse, aq as GradeRecord, aB as LearnerResponse, f as ActivityType, aT as ScoringResult } from './activity-D705CXng.js';
2
+ export { aQ as RecordingRef, aU as TextMatchPolicy, aV as TextMatchResult, ba as levenshteinDistance, bb as matchText } from './activity-D705CXng.js';
3
3
 
4
4
  /**
5
5
  * Rounding for assessment scores.
@@ -60,6 +60,246 @@ interface Band {
60
60
  */
61
61
  declare function classifyBand(value: number, bands: readonly Band[]): Band | null;
62
62
 
63
+ /**
64
+ * Speech assessment: the neutral shape a pronunciation assessor's result is
65
+ * mapped into, and the types a read-aloud grade reads and writes.
66
+ *
67
+ * The SDK calls no assessor and holds no key. The application maps its
68
+ * provider's response into a {@link SpeechAssessment}; the SDK validates that
69
+ * evidence, checks that it belongs to the item and to the learner's recording,
70
+ * and does the arithmetic.
71
+ */
72
+
73
+ /**
74
+ * How the assessor classified a word against the reference text: `none`, read
75
+ * as written; `mispronunciation`, read but not well enough; `omission`, in the
76
+ * reference but not heard; `insertion`, heard but not in the reference.
77
+ */
78
+ type SpeechWordError = 'none' | 'mispronunciation' | 'omission' | 'insertion';
79
+ /** A phoneme the assessor heard instead of the expected one, and its score. */
80
+ interface SpeechPhonemeCandidate {
81
+ /** The phoneme, in the assessment's `phonemeAlphabet`. */
82
+ symbol: string;
83
+ /** 0..100. */
84
+ score: number;
85
+ }
86
+ /** One phoneme of a word, as the assessor measured it. Assessors report different subsets. */
87
+ interface SpeechPhoneme {
88
+ /** The phoneme, in the assessment's `phonemeAlphabet`. Absent when the assessor does not name it. */
89
+ symbol?: string;
90
+ /** 0..100. Absent means not assessed, never 0. */
91
+ accuracy?: number;
92
+ /** Milliseconds from the start of the recording. */
93
+ startMs?: number;
94
+ /** Milliseconds. */
95
+ durationMs?: number;
96
+ /** The phonemes the assessor heard instead, in the order it reported them. */
97
+ heardAs?: SpeechPhonemeCandidate[];
98
+ }
99
+ /** One syllable of a word, as the assessor measured it. */
100
+ interface SpeechSyllable {
101
+ /** The syllable as the assessor reports it. */
102
+ text: string;
103
+ /** The letters of the word the syllable is written with, when the assessor reports them. */
104
+ grapheme?: string;
105
+ /** 0..100. Absent means not assessed, never 0. */
106
+ accuracy?: number;
107
+ /** Milliseconds from the start of the recording. */
108
+ startMs?: number;
109
+ /** Milliseconds. */
110
+ durationMs?: number;
111
+ }
112
+ /** One word of a {@link SpeechAssessment}. */
113
+ interface SpeechWord {
114
+ /** The word as the assessor reports it. */
115
+ text: string;
116
+ /** 0..100. Absent means not assessed — never read as 0. */
117
+ accuracy?: number;
118
+ /** The assessor's classification of the word. */
119
+ error: SpeechWordError;
120
+ /** The provider's own error label, verbatim, for audit. No grade reads it. */
121
+ vendorError?: string;
122
+ /** Milliseconds from the start of the recording. */
123
+ startMs?: number;
124
+ /** Milliseconds. */
125
+ durationMs?: number;
126
+ syllables?: SpeechSyllable[];
127
+ phonemes?: SpeechPhoneme[];
128
+ /**
129
+ * Confidences (0..1) that an unexpected pause came before the word, or that
130
+ * an expected one is missing. Display only: no grade reads them.
131
+ */
132
+ breaks?: {
133
+ unexpected?: number;
134
+ missing?: number;
135
+ };
136
+ }
137
+ /**
138
+ * A pronunciation assessor's result, in the SDK's neutral shape. Every score in
139
+ * it is on a 0..100 scale. Check one with `validateSpeechAssessment`.
140
+ */
141
+ interface SpeechAssessment {
142
+ assessmentVersion: '1.0';
143
+ /** `no_speech`: the assessor heard nothing to assess — which is never a score of 0. */
144
+ status: 'assessed' | 'no_speech';
145
+ /** `scripted`: measured against a known text. Only a scripted assessment grades a read-aloud item. */
146
+ task: 'scripted' | 'unscripted';
147
+ /** The locale the assessment was made for: canonical, with a region — the rule `ReadAloudData.locale` follows. */
148
+ locale: string;
149
+ /**
150
+ * The text the assessment was made against: the authored reference text,
151
+ * verbatim. Required when scripted, so a grade can refuse evidence made
152
+ * against another text.
153
+ */
154
+ referenceText?: string;
155
+ /**
156
+ * The `RecordingRef.key` of the recording that was assessed. Required when
157
+ * scripted, so a grade can refuse evidence made for another recording.
158
+ */
159
+ recordingKey?: string;
160
+ /** Who measured. Evidence from `'ai'` grades only when the caller opts in. */
161
+ assessor: Grader;
162
+ /** What every score is out of. Stated, so an adapter never leaves it to be assumed. */
163
+ scale: 100;
164
+ /** Utterance-level scores, 0..100. An absent score was not assessed; it is never read as 0. */
165
+ scores: {
166
+ accuracy?: number;
167
+ fluency?: number;
168
+ completeness?: number;
169
+ prosody?: number;
170
+ overall?: number;
171
+ };
172
+ /** What the assessor recognised, as text. */
173
+ recognizedText?: string;
174
+ /**
175
+ * Who judged omissions, insertions and mispronunciations. `assessor`: the
176
+ * assessor did, and its word `error` labels are trusted. `none`: it did not,
177
+ * so a heard word that differs from its reference word is marked
178
+ * mispronounced.
179
+ */
180
+ miscue: 'assessor' | 'none';
181
+ /** The alphabet phoneme symbols are written in. Required whenever a phoneme names a `symbol` or `heardAs`. */
182
+ phonemeAlphabet?: 'ipa' | 'sapi';
183
+ /** The words, in the order the assessor reported them. */
184
+ words: SpeechWord[];
185
+ /** Utterance-level prosody: `monotoneConfidence` is 0..1, display only. */
186
+ prosody?: {
187
+ monotoneConfidence?: number;
188
+ };
189
+ /** Recording quality. Informational only: no grade reads it. */
190
+ signal?: {
191
+ snrDb?: number;
192
+ };
193
+ }
194
+ /**
195
+ * The server's own measurement of a recording, from `inspectWav`. It is what
196
+ * decides whether a take is plausible speech; a duration the client reported
197
+ * never is.
198
+ */
199
+ interface SpeechMeasurement {
200
+ /** Length of the recording, in milliseconds. */
201
+ durationMs: number;
202
+ /** Milliseconds of the recording at or above the silence floor. At most `durationMs`. */
203
+ voicedMs: number;
204
+ }
205
+ /**
206
+ * When a take is too little speech to grade. Both fields are required: the SDK
207
+ * holds no default for either, because each is a decision about an
208
+ * application's learners and its assessor.
209
+ */
210
+ interface SpeechPlausibilityPolicy {
211
+ /** The most words per second of voiced time a genuine reading can reach. Finite and above 0. */
212
+ maxWordsPerSecond: number;
213
+ /** The least voiced time, in milliseconds, a gradable take contains. Finite and at least 0. */
214
+ minVoicedMs: number;
215
+ }
216
+ /**
217
+ * Why a read-aloud take cannot be graded:
218
+ * - `invalid_assessment` — the assessment fails `validateSpeechAssessment`;
219
+ * - `task_mismatch` — it is not a scripted assessment;
220
+ * - `locale_mismatch` — it was made for another locale than the item's;
221
+ * - `reference_mismatch` — it was made against another text than the item's;
222
+ * - `recording_mismatch` — it was made for another recording than the response's;
223
+ * - `assessor_not_accepted` — its assessor is `'ai'`, and the caller did not opt in;
224
+ * - `no_speech` — the assessor heard no speech;
225
+ * - `insufficient_voiced_time` — the recording holds less voiced time than the policy requires;
226
+ * - `implausible_speech_rate` — more words were recognised than the voiced time can hold;
227
+ * - `missing_dimension` — a weighted dimension has no score in the assessment.
228
+ */
229
+ type SpeechUnscorableCode = 'invalid_assessment' | 'task_mismatch' | 'locale_mismatch' | 'reference_mismatch' | 'recording_mismatch' | 'assessor_not_accepted' | 'no_speech' | 'insufficient_voiced_time' | 'implausible_speech_rate' | 'missing_dimension';
230
+ /** A read-aloud take that cannot be graded. Never a zero: see `outcomeFromUnscorable`. */
231
+ interface SpeechUnscorable {
232
+ unscorable: true;
233
+ /** Machine-readable. See {@link SpeechUnscorableCode}. */
234
+ code: SpeechUnscorableCode;
235
+ /** A developer-facing English sentence. */
236
+ reason: string;
237
+ }
238
+ /**
239
+ * Options for `gradeReadAloud`. The plausibility policy is required: the SDK
240
+ * holds no default for a threshold that decides whether a take is graded.
241
+ */
242
+ interface GradeReadAloudOptions {
243
+ /** The server's measurement of the recording (inspectWav). `null` only for a blank response. */
244
+ measured: SpeechMeasurement | null;
245
+ /** When a take is too little speech to grade. */
246
+ plausibility: SpeechPlausibilityPolicy;
247
+ /** Accept `assessor.kind: 'ai'` evidence. Off unless set. */
248
+ allowAiAssessor?: boolean;
249
+ /** Compare the pass line with both sides rounded, as `gradeFromRubric` does. The score stays unrounded. */
250
+ rounding?: RoundingPolicy;
251
+ }
252
+ /** How a word of a read-aloud attempt is marked. */
253
+ type ReadAloudWordState = 'correct' | 'mispronounced' | 'omitted' | 'inserted';
254
+ /**
255
+ * One entry of `alignReadAloud`: a reference word and what was heard for it,
256
+ * or a heard word that is not in the reference.
257
+ */
258
+ interface ReadAloudWordAlignment {
259
+ /** `w<n>` for a reference word, as `dictationReferenceWords` numbers them; absent for an `inserted` word. */
260
+ itemId?: string;
261
+ /** The normalised reference word; `''` for an `inserted` word. */
262
+ reference: string;
263
+ /**
264
+ * The normalised heard word: `''` for an `omitted` word, and also for an
265
+ * `inserted` word whose text normalises to nothing — an assessor can tag a
266
+ * dash as an insertion, and every insertion gets an entry. Branch on `state`,
267
+ * never on the empty string.
268
+ */
269
+ heard: string;
270
+ state: ReadAloudWordState;
271
+ /** The assessor word's accuracy (0..100), when it has one. */
272
+ accuracy?: number;
273
+ /** Index into `assessment.words` of the word this entry came from. */
274
+ wordIndex?: number;
275
+ }
276
+ /**
277
+ * What `inspectWav` found in a recording's bytes: the duration, format, peak
278
+ * level and voiced time of a 16-bit PCM WAV, or why it could not read one.
279
+ */
280
+ type WavInspection = {
281
+ valid: true;
282
+ /** Length of the audio, in milliseconds. */
283
+ durationMs: number;
284
+ sampleRate: number;
285
+ channels: number;
286
+ bitsPerSample: 16;
287
+ /** The loudest sample across every channel, in dBFS; `-Infinity` for digital silence or no samples. */
288
+ peakDbfs: number;
289
+ /** Milliseconds of the windows at or above the policy's silence floor. */
290
+ voicedMs: number;
291
+ } | {
292
+ valid: false;
293
+ reason: 'not_wav' | 'unsupported_encoding' | 'truncated';
294
+ };
295
+ /** How `inspectWav` decides which parts of a recording are voiced. Both fields are required. */
296
+ interface WavInspectionPolicy {
297
+ /** A window whose RMS level is at or above this many dBFS is voiced. Finite, and at most 0. */
298
+ silenceDbfs: number;
299
+ /** The window length, in milliseconds. Finite, and above 0. */
300
+ frameMs: number;
301
+ }
302
+
63
303
  /**
64
304
  * Sectioned assessment scoring — weights, per-section thresholds, and an
65
305
  * explicit reason when an attempt fails.
@@ -332,246 +572,6 @@ interface ItemTriesScore {
332
572
  tries: ItemTryScore[];
333
573
  }
334
574
 
335
- /**
336
- * Speech assessment: the neutral shape a pronunciation assessor's result is
337
- * mapped into, and the types a read-aloud grade reads and writes.
338
- *
339
- * The SDK calls no assessor and holds no key. The application maps its
340
- * provider's response into a {@link SpeechAssessment}; the SDK validates that
341
- * evidence, checks that it belongs to the item and to the learner's recording,
342
- * and does the arithmetic.
343
- */
344
-
345
- /**
346
- * How the assessor classified a word against the reference text: `none`, read
347
- * as written; `mispronunciation`, read but not well enough; `omission`, in the
348
- * reference but not heard; `insertion`, heard but not in the reference.
349
- */
350
- type SpeechWordError = 'none' | 'mispronunciation' | 'omission' | 'insertion';
351
- /** A phoneme the assessor heard instead of the expected one, and its score. */
352
- interface SpeechPhonemeCandidate {
353
- /** The phoneme, in the assessment's `phonemeAlphabet`. */
354
- symbol: string;
355
- /** 0..100. */
356
- score: number;
357
- }
358
- /** One phoneme of a word, as the assessor measured it. Assessors report different subsets. */
359
- interface SpeechPhoneme {
360
- /** The phoneme, in the assessment's `phonemeAlphabet`. Absent when the assessor does not name it. */
361
- symbol?: string;
362
- /** 0..100. Absent means not assessed, never 0. */
363
- accuracy?: number;
364
- /** Milliseconds from the start of the recording. */
365
- startMs?: number;
366
- /** Milliseconds. */
367
- durationMs?: number;
368
- /** The phonemes the assessor heard instead, in the order it reported them. */
369
- heardAs?: SpeechPhonemeCandidate[];
370
- }
371
- /** One syllable of a word, as the assessor measured it. */
372
- interface SpeechSyllable {
373
- /** The syllable as the assessor reports it. */
374
- text: string;
375
- /** The letters of the word the syllable is written with, when the assessor reports them. */
376
- grapheme?: string;
377
- /** 0..100. Absent means not assessed, never 0. */
378
- accuracy?: number;
379
- /** Milliseconds from the start of the recording. */
380
- startMs?: number;
381
- /** Milliseconds. */
382
- durationMs?: number;
383
- }
384
- /** One word of a {@link SpeechAssessment}. */
385
- interface SpeechWord {
386
- /** The word as the assessor reports it. */
387
- text: string;
388
- /** 0..100. Absent means not assessed — never read as 0. */
389
- accuracy?: number;
390
- /** The assessor's classification of the word. */
391
- error: SpeechWordError;
392
- /** The provider's own error label, verbatim, for audit. No grade reads it. */
393
- vendorError?: string;
394
- /** Milliseconds from the start of the recording. */
395
- startMs?: number;
396
- /** Milliseconds. */
397
- durationMs?: number;
398
- syllables?: SpeechSyllable[];
399
- phonemes?: SpeechPhoneme[];
400
- /**
401
- * Confidences (0..1) that an unexpected pause came before the word, or that
402
- * an expected one is missing. Display only: no grade reads them.
403
- */
404
- breaks?: {
405
- unexpected?: number;
406
- missing?: number;
407
- };
408
- }
409
- /**
410
- * A pronunciation assessor's result, in the SDK's neutral shape. Every score in
411
- * it is on a 0..100 scale. Check one with `validateSpeechAssessment`.
412
- */
413
- interface SpeechAssessment {
414
- assessmentVersion: '1.0';
415
- /** `no_speech`: the assessor heard nothing to assess — which is never a score of 0. */
416
- status: 'assessed' | 'no_speech';
417
- /** `scripted`: measured against a known text. Only a scripted assessment grades a read-aloud item. */
418
- task: 'scripted' | 'unscripted';
419
- /** The locale the assessment was made for: canonical, with a region — the rule `ReadAloudData.locale` follows. */
420
- locale: string;
421
- /**
422
- * The text the assessment was made against: the authored reference text,
423
- * verbatim. Required when scripted, so a grade can refuse evidence made
424
- * against another text.
425
- */
426
- referenceText?: string;
427
- /**
428
- * The `RecordingRef.key` of the recording that was assessed. Required when
429
- * scripted, so a grade can refuse evidence made for another recording.
430
- */
431
- recordingKey?: string;
432
- /** Who measured. Evidence from `'ai'` grades only when the caller opts in. */
433
- assessor: Grader;
434
- /** What every score is out of. Stated, so an adapter never leaves it to be assumed. */
435
- scale: 100;
436
- /** Utterance-level scores, 0..100. An absent score was not assessed; it is never read as 0. */
437
- scores: {
438
- accuracy?: number;
439
- fluency?: number;
440
- completeness?: number;
441
- prosody?: number;
442
- overall?: number;
443
- };
444
- /** What the assessor recognised, as text. */
445
- recognizedText?: string;
446
- /**
447
- * Who judged omissions, insertions and mispronunciations. `assessor`: the
448
- * assessor did, and its word `error` labels are trusted. `none`: it did not,
449
- * so a heard word that differs from its reference word is marked
450
- * mispronounced.
451
- */
452
- miscue: 'assessor' | 'none';
453
- /** The alphabet phoneme symbols are written in. Required whenever a phoneme names a `symbol` or `heardAs`. */
454
- phonemeAlphabet?: 'ipa' | 'sapi';
455
- /** The words, in the order the assessor reported them. */
456
- words: SpeechWord[];
457
- /** Utterance-level prosody: `monotoneConfidence` is 0..1, display only. */
458
- prosody?: {
459
- monotoneConfidence?: number;
460
- };
461
- /** Recording quality. Informational only: no grade reads it. */
462
- signal?: {
463
- snrDb?: number;
464
- };
465
- }
466
- /**
467
- * The server's own measurement of a recording, from `inspectWav`. It is what
468
- * decides whether a take is plausible speech; a duration the client reported
469
- * never is.
470
- */
471
- interface SpeechMeasurement {
472
- /** Length of the recording, in milliseconds. */
473
- durationMs: number;
474
- /** Milliseconds of the recording at or above the silence floor. At most `durationMs`. */
475
- voicedMs: number;
476
- }
477
- /**
478
- * When a take is too little speech to grade. Both fields are required: the SDK
479
- * holds no default for either, because each is a decision about an
480
- * application's learners and its assessor.
481
- */
482
- interface SpeechPlausibilityPolicy {
483
- /** The most words per second of voiced time a genuine reading can reach. Finite and above 0. */
484
- maxWordsPerSecond: number;
485
- /** The least voiced time, in milliseconds, a gradable take contains. Finite and at least 0. */
486
- minVoicedMs: number;
487
- }
488
- /**
489
- * Why a read-aloud take cannot be graded:
490
- * - `invalid_assessment` — the assessment fails `validateSpeechAssessment`;
491
- * - `task_mismatch` — it is not a scripted assessment;
492
- * - `locale_mismatch` — it was made for another locale than the item's;
493
- * - `reference_mismatch` — it was made against another text than the item's;
494
- * - `recording_mismatch` — it was made for another recording than the response's;
495
- * - `assessor_not_accepted` — its assessor is `'ai'`, and the caller did not opt in;
496
- * - `no_speech` — the assessor heard no speech;
497
- * - `insufficient_voiced_time` — the recording holds less voiced time than the policy requires;
498
- * - `implausible_speech_rate` — more words were recognised than the voiced time can hold;
499
- * - `missing_dimension` — a weighted dimension has no score in the assessment.
500
- */
501
- type SpeechUnscorableCode = 'invalid_assessment' | 'task_mismatch' | 'locale_mismatch' | 'reference_mismatch' | 'recording_mismatch' | 'assessor_not_accepted' | 'no_speech' | 'insufficient_voiced_time' | 'implausible_speech_rate' | 'missing_dimension';
502
- /** A read-aloud take that cannot be graded. Never a zero: see `outcomeFromUnscorable`. */
503
- interface SpeechUnscorable {
504
- unscorable: true;
505
- /** Machine-readable. See {@link SpeechUnscorableCode}. */
506
- code: SpeechUnscorableCode;
507
- /** A developer-facing English sentence. */
508
- reason: string;
509
- }
510
- /**
511
- * Options for `gradeReadAloud`. The plausibility policy is required: the SDK
512
- * holds no default for a threshold that decides whether a take is graded.
513
- */
514
- interface GradeReadAloudOptions {
515
- /** The server's measurement of the recording (inspectWav). `null` only for a blank response. */
516
- measured: SpeechMeasurement | null;
517
- /** When a take is too little speech to grade. */
518
- plausibility: SpeechPlausibilityPolicy;
519
- /** Accept `assessor.kind: 'ai'` evidence. Off unless set. */
520
- allowAiAssessor?: boolean;
521
- /** Compare the pass line with both sides rounded, as `gradeFromRubric` does. The score stays unrounded. */
522
- rounding?: RoundingPolicy;
523
- }
524
- /** How a word of a read-aloud attempt is marked. */
525
- type ReadAloudWordState = 'correct' | 'mispronounced' | 'omitted' | 'inserted';
526
- /**
527
- * One entry of `alignReadAloud`: a reference word and what was heard for it,
528
- * or a heard word that is not in the reference.
529
- */
530
- interface ReadAloudWordAlignment {
531
- /** `w<n>` for a reference word, as `dictationReferenceWords` numbers them; absent for an `inserted` word. */
532
- itemId?: string;
533
- /** The normalised reference word; `''` for an `inserted` word. */
534
- reference: string;
535
- /**
536
- * The normalised heard word: `''` for an `omitted` word, and also for an
537
- * `inserted` word whose text normalises to nothing — an assessor can tag a
538
- * dash as an insertion, and every insertion gets an entry. Branch on `state`,
539
- * never on the empty string.
540
- */
541
- heard: string;
542
- state: ReadAloudWordState;
543
- /** The assessor word's accuracy (0..100), when it has one. */
544
- accuracy?: number;
545
- /** Index into `assessment.words` of the word this entry came from. */
546
- wordIndex?: number;
547
- }
548
- /**
549
- * What `inspectWav` found in a recording's bytes: the duration, format, peak
550
- * level and voiced time of a 16-bit PCM WAV, or why it could not read one.
551
- */
552
- type WavInspection = {
553
- valid: true;
554
- /** Length of the audio, in milliseconds. */
555
- durationMs: number;
556
- sampleRate: number;
557
- channels: number;
558
- bitsPerSample: 16;
559
- /** The loudest sample across every channel, in dBFS; `-Infinity` for digital silence or no samples. */
560
- peakDbfs: number;
561
- /** Milliseconds of the windows at or above the policy's silence floor. */
562
- voicedMs: number;
563
- } | {
564
- valid: false;
565
- reason: 'not_wav' | 'unsupported_encoding' | 'truncated';
566
- };
567
- /** How `inspectWav` decides which parts of a recording are voiced. Both fields are required. */
568
- interface WavInspectionPolicy {
569
- /** A window whose RMS level is at or above this many dBFS is voiced. Finite, and at most 0. */
570
- silenceDbfs: number;
571
- /** The window length, in milliseconds. Finite, and above 0. */
572
- frameMs: number;
573
- }
574
-
575
575
  /** One transcript word, or one extra word the learner typed, after alignment. */
576
576
  interface DictationWordAlignment {
577
577
  /** `w<n>`, the 1-based position of a transcript word; absent for an extra word. */
package/dist/scoring.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  scoreTries,
20
20
  validateItemScoringPolicy,
21
21
  validateSpeechAssessment
22
- } from "./chunk-IARLJ5MW.js";
22
+ } from "./chunk-QX2ERL72.js";
23
23
  import {
24
24
  DICTATION_MAX_ACCEPTED_TRANSCRIPTS,
25
25
  DICTATION_MAX_EQUIVALENCES,
@@ -35,7 +35,7 @@ import {
35
35
  dictationReferenceWords,
36
36
  levenshteinDistance,
37
37
  matchText
38
- } from "./chunk-FBKTION6.js";
38
+ } from "./chunk-QS7B42ZR.js";
39
39
  export {
40
40
  DEFAULT_ITEM_SCORING_POLICY,
41
41
  DEFAULT_PASS_THRESHOLD,
package/dist/xapi.cjs CHANGED
@@ -4,13 +4,13 @@
4
4
 
5
5
 
6
6
 
7
- var _chunkTJJFKKH2cjs = require('./chunk-TJJFKKH2.cjs');
8
- require('./chunk-DSDXL3JO.cjs');
7
+ var _chunk46BXIGLGcjs = require('./chunk-46BXIGLG.cjs');
8
+ require('./chunk-7THXD7AN.cjs');
9
9
 
10
10
 
11
11
 
12
12
 
13
13
 
14
14
 
15
- exports.XAPIVerb = _chunkTJJFKKH2cjs.XAPIVerb; exports.XAPI_VERB_DISPLAY = _chunkTJJFKKH2cjs.XAPI_VERB_DISPLAY; exports.validateXAPIStatement = _chunkTJJFKKH2cjs.validateXAPIStatement; exports.xAPIBuilder = _chunkTJJFKKH2cjs.xAPIBuilder; exports.xapiDefinitionFor = _chunkTJJFKKH2cjs.xapiDefinitionFor;
15
+ exports.XAPIVerb = _chunk46BXIGLGcjs.XAPIVerb; exports.XAPI_VERB_DISPLAY = _chunk46BXIGLGcjs.XAPI_VERB_DISPLAY; exports.validateXAPIStatement = _chunk46BXIGLGcjs.validateXAPIStatement; exports.xAPIBuilder = _chunk46BXIGLGcjs.xAPIBuilder; exports.xapiDefinitionFor = _chunk46BXIGLGcjs.xapiDefinitionFor;
16
16
  //# sourceMappingURL=xapi.cjs.map
package/dist/xapi.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { av as XAPIActor, am as ScoringResult, ax as XAPIContext, aB as XAPIResult, aD as XAPIStatement } from './activity-DgpBJeBc.cjs';
1
+ import { b0 as XAPIActor, aT as ScoringResult, b2 as XAPIContext, b6 as XAPIResult, b8 as XAPIStatement } from './activity-D705CXng.cjs';
2
2
 
3
3
  /**
4
4
  * The set of xAPI verbs emitted by SDK activities, keyed by a stable
package/dist/xapi.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { av as XAPIActor, am as ScoringResult, ax as XAPIContext, aB as XAPIResult, aD as XAPIStatement } from './activity-DgpBJeBc.js';
1
+ import { b0 as XAPIActor, aT as ScoringResult, b2 as XAPIContext, b6 as XAPIResult, b8 as XAPIStatement } from './activity-D705CXng.js';
2
2
 
3
3
  /**
4
4
  * The set of xAPI verbs emitted by SDK activities, keyed by a stable
package/dist/xapi.js CHANGED
@@ -4,8 +4,8 @@ import {
4
4
  validateXAPIStatement,
5
5
  xAPIBuilder,
6
6
  xapiDefinitionFor
7
- } from "./chunk-SJVRUPJT.js";
8
- import "./chunk-FBKTION6.js";
7
+ } from "./chunk-JTNDIBZO.js";
8
+ import "./chunk-QS7B42ZR.js";
9
9
  export {
10
10
  XAPIVerb,
11
11
  XAPI_VERB_DISPLAY,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intellectif/lk-core",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "Framework-free assessment core: activity validation, pure scoring, rubric & deferred grading, weighted assessment composition, exam attempt plans, and xAPI 1.0.3. Custom activity types take any Standard Schema.",
5
5
  "keywords": [
6
6
  "assessment",