@intellectif/lk-react 18.1.0 → 19.0.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 (59) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +1 -1
  3. package/dist/ai/useAiHelp.cjs +3 -3
  4. package/dist/ai/useAiHelp.js +1 -1
  5. package/dist/{chunk-TXMP5AOW.cjs → chunk-2X2NZF46.cjs} +10 -10
  6. package/dist/{chunk-TXMP5AOW.cjs.map → chunk-2X2NZF46.cjs.map} +1 -1
  7. package/dist/{chunk-3SDCALS3.cjs → chunk-55W2472T.cjs} +10 -10
  8. package/dist/{chunk-3SDCALS3.cjs.map → chunk-55W2472T.cjs.map} +1 -1
  9. package/dist/{chunk-GM4PXDZ2.js → chunk-5QCZZBOX.js} +3 -3
  10. package/dist/{chunk-GM4PXDZ2.js.map → chunk-5QCZZBOX.js.map} +1 -1
  11. package/dist/{chunk-WSPVQR4O.js → chunk-7NNMDZUU.js} +6 -6
  12. package/dist/{chunk-WSPVQR4O.js.map → chunk-7NNMDZUU.js.map} +1 -1
  13. package/dist/{chunk-NWGQ7JML.cjs → chunk-KGDGYRBL.cjs} +5 -5
  14. package/dist/{chunk-NWGQ7JML.cjs.map → chunk-KGDGYRBL.cjs.map} +1 -1
  15. package/dist/{chunk-6NY7OTOO.js → chunk-KOFA54C7.js} +6 -6
  16. package/dist/{chunk-6NY7OTOO.js.map → chunk-KOFA54C7.js.map} +1 -1
  17. package/dist/{chunk-7GYAUA56.cjs → chunk-NGFTSRKO.cjs} +4 -4
  18. package/dist/{chunk-7GYAUA56.cjs.map → chunk-NGFTSRKO.cjs.map} +1 -1
  19. package/dist/{chunk-THHFIP4N.js → chunk-NLTU5JFD.js} +3 -3
  20. package/dist/{chunk-THHFIP4N.js.map → chunk-NLTU5JFD.js.map} +1 -1
  21. package/dist/{chunk-MKWBLNTD.js → chunk-OWV7VRMQ.js} +6 -6
  22. package/dist/{chunk-MKWBLNTD.js.map → chunk-OWV7VRMQ.js.map} +1 -1
  23. package/dist/{chunk-BURYHHBM.js → chunk-QRT2W5N5.js} +3 -3
  24. package/dist/{chunk-BURYHHBM.js.map → chunk-QRT2W5N5.js.map} +1 -1
  25. package/dist/{chunk-IKV2I7KT.js → chunk-SEQTGOOU.js} +3 -3
  26. package/dist/{chunk-IKV2I7KT.js.map → chunk-SEQTGOOU.js.map} +1 -1
  27. package/dist/{chunk-TL3GVPBO.cjs → chunk-SXU26SFO.cjs} +26 -7
  28. package/dist/chunk-SXU26SFO.cjs.map +1 -0
  29. package/dist/{chunk-PROKRNL2.cjs → chunk-WKA6FUR4.cjs} +10 -10
  30. package/dist/{chunk-PROKRNL2.cjs.map → chunk-WKA6FUR4.cjs.map} +1 -1
  31. package/dist/{chunk-3SJ7TVL6.cjs → chunk-XAIJNGTU.cjs} +5 -5
  32. package/dist/{chunk-3SJ7TVL6.cjs.map → chunk-XAIJNGTU.cjs.map} +1 -1
  33. package/dist/{chunk-JSRKES2Z.js → chunk-XHF376ES.js} +3 -3
  34. package/dist/{chunk-JSRKES2Z.js.map → chunk-XHF376ES.js.map} +1 -1
  35. package/dist/{chunk-JH77MAON.cjs → chunk-XUQ4KRTT.cjs} +5 -5
  36. package/dist/{chunk-JH77MAON.cjs.map → chunk-XUQ4KRTT.cjs.map} +1 -1
  37. package/dist/{chunk-YGJE7RSW.js → chunk-YIYMBCPV.js} +26 -7
  38. package/dist/chunk-YIYMBCPV.js.map +1 -0
  39. package/dist/{chunk-X4YU6BX7.cjs → chunk-ZME5FMED.cjs} +5 -5
  40. package/dist/{chunk-X4YU6BX7.cjs.map → chunk-ZME5FMED.cjs.map} +1 -1
  41. package/dist/components/ActivityPreview.cjs +8 -8
  42. package/dist/components/ActivityPreview.js +7 -7
  43. package/dist/components/ActivitySequence.cjs +8 -8
  44. package/dist/components/ActivitySequence.js +7 -7
  45. package/dist/components/Dictation.cjs +4 -4
  46. package/dist/components/Dictation.js +3 -3
  47. package/dist/components/FillInTheBlanks.cjs +4 -4
  48. package/dist/components/FillInTheBlanks.js +3 -3
  49. package/dist/components/GapSelect.cjs +4 -4
  50. package/dist/components/GapSelect.js +3 -3
  51. package/dist/components/InteractiveVideo.cjs +9 -9
  52. package/dist/components/InteractiveVideo.js +7 -7
  53. package/dist/components/MultipleChoice.cjs +4 -4
  54. package/dist/components/MultipleChoice.js +3 -3
  55. package/dist/index.cjs +19 -19
  56. package/dist/index.js +9 -9
  57. package/package.json +3 -3
  58. package/dist/chunk-TL3GVPBO.cjs.map +0 -1
  59. package/dist/chunk-YGJE7RSW.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @intellectif/lk-react
2
2
 
3
+ ## 19.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - d576382: AI help now reports what it cost and what was refused.
8
+
9
+ - **`ai-hint-shown` and `ai-explanation-shown` carry `usage`** when your port sent it, beside the
10
+ `provenance` they already carried. What a learner was shown and what it cost are then one record,
11
+ keyed to the attempt — no second channel to reconcile.
12
+ - **`ai-help-refused` is new**, from the same one implementation the components and the hooks share
13
+ (`useAiHints`, `useAiExplanation`). It fires where a learner is told help is not available, with
14
+ `feature` (`hint` or `explanation`), `reason` (`reveals-answer`, `contradicts-grade`, `malformed`,
15
+ `empty`, `too-long`) and, for a hint, `hintNumber`. **The text is never carried:** a hint refused
16
+ for revealing the answer contains the answer, and interactions are logged.
17
+
18
+ A host that keeps every interaction will start seeing this kind. It is additive — nothing that
19
+ was emitted before has changed — but a `switch` over `InteractionKind` with no default will not
20
+ know it.
21
+
22
+ **Major** because the peer range moves to `@intellectif/lk-core@^0.19.0`, whose `ai-check` entry
23
+ point and `AiTextResult.usage` come with it. No React API was removed or renamed, and a host that
24
+ passes no AI port sees nothing new.
25
+
26
+ See `docs/ai.md`.
27
+
28
+ ### Patch Changes
29
+
30
+ - Updated dependencies [d576382]
31
+ - @intellectif/lk-core@0.19.0
32
+
3
33
  ## 18.1.0
4
34
 
5
35
  ### Minor Changes
package/README.md CHANGED
@@ -73,7 +73,7 @@ export function Demo() {
73
73
  - **`<PronunciationFeedback>`** — the marks on their own, for a review screen that has evidence but no activity: the graded dimensions (accuracy, fluency, completeness, prosody — one the engine did not measure reads "not assessed", **never 0%**), and every word marked `correct` / `mispronounced` / `omitted` / `inserted` with a hidden sentence per word for screen readers and a glyph plus a text decoration for everyone else. A word opens onto its syllables, its sounds, what was heard instead, and a button that plays just that word. Evidence it cannot trust is checked before it is aligned, so in production a malformed assessment costs the word list — never the grade beside it.
74
74
  - **`<WrittenResponse>`** — free-text writing with a live word counter and bounds messaging, graded **asynchronously**: it emits an ungraded submission (never a fake zero) and a SUBMITTED-verb xAPI statement, and renders a returned `GradeRecord` in `review` mode with per-criterion scores and inline corrections.
75
75
  - **`<InteractiveVideo>`** — a video that stops at each quiz and asks its questions over itself, then plays on. **A formative tool**, for lessons and practice — deliver official summative exams with `<ActivitySequence>`. One player: a progress bar that marks every quiz and previews the caption under the pointer, speed, volume, captions drawn from WebVTT it parses itself (through a `captionsLoader` when the file needs the learner's credentials) — in one language or two at once, a second line under the first for a learner matching what they hear to what it means — a contents and transcript panel, picture-in-picture, fullscreen and a keyboard map with a shortcut sheet. A quiz covers the video and grows the player rather than scrolling inside it, every question of an opened quiz stays mounted so a rewind loses no answer, the controls are `inert` while it is open, and a **required** quiz holds both playback and seeking until it is answered. Answers report with the slot the question sits in and the quiz it belongs to, and `onProgress` gives a resume point that is never past an unanswered required quiz. A host with renderers of its own draws any question itself through `renderQuestion` — the video still counts it, tells it when it leaves the screen so it can stop its microphone, and holds Finish while its answer is still on its way. See the [interactive video guide](https://github.com/intellectif/learning-kit/blob/main/docs/interactive-video.md).
76
- - **AI help for learners** — "Explain my answer" after grading and "Get a hint" before submit, in `<MultipleChoice>`, `<FillInTheBlanks>`, `<GapSelect>` and `<Dictation>` (explanations only), through ports **you** supply with `<LkAiProvider>` or an `ai` prop (also on `<ActivitySequence>` and `<InteractiveVideo>`). The SDK never calls a model or holds a key: it builds the facts your model is given, refuses an explanation that contradicts the grade and a hint that contains the answer, marks everything a model wrote, and drops a late answer. Never in `exam`. See the [AI guide](https://github.com/intellectif/learning-kit/blob/main/docs/ai.md).
76
+ - **AI help for learners** — "Explain my answer" after grading and "Get a hint" before submit, in `<MultipleChoice>`, `<FillInTheBlanks>`, `<GapSelect>` and `<Dictation>` (explanations only), through ports **you** supply with `<LkAiProvider>` or an `ai` prop (also on `<ActivitySequence>` and `<InteractiveVideo>`). The SDK never calls a model or holds a key: it builds the facts your model is given, refuses an explanation that contradicts the grade and a hint that contains the answer, marks everything a model wrote, and drops a late answer. Never in `exam`. What was shown reaches `onInteraction` with the model that wrote it and what the call cost; what was refused reaches it with the reason, and never the text. See the [AI guide](https://github.com/intellectif/learning-kit/blob/main/docs/ai.md).
77
77
  - **`<ActivitySequence>`** — in-place "question set" pager (Previous/Next, "Question X of N", no scrolling, focus-managed). Accepts item groups and keeps their stimulus beside every question; `onSubmit` reports every raw answer with its `slotId`, which is the only response channel an `exam` sequence has. `onFinished` is the completion signal for a set that mixes scored and deferred-graded items, where `onComplete` can never fire. A read-aloud slot takes its storage from `recordingBinding`, whose methods are told which slot a take belongs to, and a `review` its per-word marks from `assessments`, keyed by `slotId` — there is a [worked example](https://github.com/intellectif/learning-kit/blob/main/docs/speech-assessment.md#in-a-question-set).
78
78
  - **Resume and review a whole attempt** — `<ActivitySequence>` takes `defaultIndex`, `responses` and `submittedSlotIds` (read at mount; remount with a `key` to show a different attempt), so an interrupted paper reopens on the right question with the right answers and already-committed questions still committed. `onIndexChange` reports every position the pager lands on, including a clamp it had to apply. Pass `renderMode="review"` plus server-computed `outcomes` to render a finished attempt read-only. Pairs with `serializeAttemptState` / `restoreAttemptState` in `lk-core`.
79
79
  - **`renderMode`** — `practice` (default: the component scores locally and reveals correctness), `exam` (never scores, never reveals; submit emits the raw response for the server to grade), `review` (read-only, marks correctness only from an `outcome` you supply). This is the single switch that takes grading off the client.
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  'use strict';
3
3
 
4
- var chunkTL3GVPBO_cjs = require('../chunk-TL3GVPBO.cjs');
4
+ var chunkSXU26SFO_cjs = require('../chunk-SXU26SFO.cjs');
5
5
  require('../chunk-ZDYNAWDZ.cjs');
6
6
  require('../chunk-JVWLXVYG.cjs');
7
7
  require('../chunk-EANGKAKG.cjs');
@@ -10,11 +10,11 @@ require('../chunk-EANGKAKG.cjs');
10
10
 
11
11
  Object.defineProperty(exports, "useAiExplanation", {
12
12
  enumerable: true,
13
- get: function () { return chunkTL3GVPBO_cjs.useAiExplanation; }
13
+ get: function () { return chunkSXU26SFO_cjs.useAiExplanation; }
14
14
  });
15
15
  Object.defineProperty(exports, "useAiHints", {
16
16
  enumerable: true,
17
- get: function () { return chunkTL3GVPBO_cjs.useAiHints; }
17
+ get: function () { return chunkSXU26SFO_cjs.useAiHints; }
18
18
  });
19
19
  //# sourceMappingURL=useAiHelp.cjs.map
20
20
  //# sourceMappingURL=useAiHelp.cjs.map
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- export { useAiExplanation, useAiHints } from '../chunk-YGJE7RSW.js';
2
+ export { useAiExplanation, useAiHints } from '../chunk-YIYMBCPV.js';
3
3
  import '../chunk-YNDKAYW3.js';
4
4
  import '../chunk-TEAVPUMX.js';
5
5
  import '../chunk-PPFVTXGJ.js';
@@ -3,10 +3,10 @@
3
3
 
4
4
  var chunk3FBBP5QR_cjs = require('./chunk-3FBBP5QR.cjs');
5
5
  var chunkCQNKZ435_cjs = require('./chunk-CQNKZ435.cjs');
6
- var chunkX4YU6BX7_cjs = require('./chunk-X4YU6BX7.cjs');
7
- var chunkJH77MAON_cjs = require('./chunk-JH77MAON.cjs');
8
- var chunk3SJ7TVL6_cjs = require('./chunk-3SJ7TVL6.cjs');
9
- var chunk7GYAUA56_cjs = require('./chunk-7GYAUA56.cjs');
6
+ var chunkZME5FMED_cjs = require('./chunk-ZME5FMED.cjs');
7
+ var chunkXUQ4KRTT_cjs = require('./chunk-XUQ4KRTT.cjs');
8
+ var chunkXAIJNGTU_cjs = require('./chunk-XAIJNGTU.cjs');
9
+ var chunkNGFTSRKO_cjs = require('./chunk-NGFTSRKO.cjs');
10
10
  var chunkNZM3M5IR_cjs = require('./chunk-NZM3M5IR.cjs');
11
11
  var chunkJVWLXVYG_cjs = require('./chunk-JVWLXVYG.cjs');
12
12
  var chunkEANGKAKG_cjs = require('./chunk-EANGKAKG.cjs');
@@ -614,7 +614,7 @@ function ActivitySequence({
614
614
  }
615
615
  if (activity.type === "multiple-choice") {
616
616
  return /* @__PURE__ */ jsxRuntime.jsx(
617
- chunkX4YU6BX7_cjs.MultipleChoice,
617
+ chunkZME5FMED_cjs.MultipleChoice,
618
618
  {
619
619
  data: activity,
620
620
  ...shuffleSeed !== void 0 ? { shuffleSeed } : {},
@@ -623,11 +623,11 @@ function ActivitySequence({
623
623
  );
624
624
  }
625
625
  if (activity.type === "fill-in-the-blanks") {
626
- return /* @__PURE__ */ jsxRuntime.jsx(chunkJH77MAON_cjs.FillInTheBlanks, { data: activity, ...childProps });
626
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkXUQ4KRTT_cjs.FillInTheBlanks, { data: activity, ...childProps });
627
627
  }
628
628
  if (activity.type === "gap-select") {
629
629
  return /* @__PURE__ */ jsxRuntime.jsx(
630
- chunk3SJ7TVL6_cjs.GapSelect,
630
+ chunkXAIJNGTU_cjs.GapSelect,
631
631
  {
632
632
  data: activity,
633
633
  ...shuffleSeed !== void 0 ? { shuffleSeed } : {},
@@ -636,7 +636,7 @@ function ActivitySequence({
636
636
  );
637
637
  }
638
638
  if (activity.type === "dictation") {
639
- return /* @__PURE__ */ jsxRuntime.jsx(chunk7GYAUA56_cjs.Dictation, { data: activity, ...childProps });
639
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkNGFTSRKO_cjs.Dictation, { data: activity, ...childProps });
640
640
  }
641
641
  if (activity.type === "read-aloud") {
642
642
  const slotRecordingBinding = recordingBindingFor(slot);
@@ -745,5 +745,5 @@ function ActivitySequence({
745
745
  }
746
746
 
747
747
  exports.ActivitySequence = ActivitySequence;
748
- //# sourceMappingURL=chunk-TXMP5AOW.cjs.map
749
- //# sourceMappingURL=chunk-TXMP5AOW.cjs.map
748
+ //# sourceMappingURL=chunk-2X2NZF46.cjs.map
749
+ //# sourceMappingURL=chunk-2X2NZF46.cjs.map