@pie-players/pie-assessment-toolkit 0.3.74 → 1.0.0-beta.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 (257) hide show
  1. package/README.md +658 -714
  2. package/custom-elements.json +1315 -0
  3. package/dist/attempt/TestSession.d.ts +1 -21
  4. package/dist/attempt/TestSession.js +16 -102
  5. package/dist/components/ItemScope.custom-element.d.ts +1 -0
  6. package/dist/components/ItemScope.custom-element.js +1 -0
  7. package/dist/components/ItemToolBar.custom-element.js +1 -1
  8. package/dist/components/PieAssessmentToolkit.custom-element.js +14 -14
  9. package/dist/components/SectionToolBar.custom-element.js +1 -1
  10. package/dist/components/chunks/ItemToolBar-3zrc4p3d.js +4 -0
  11. package/dist/components/chunks/ItemToolBar-66hcwmfw.js +2 -0
  12. package/dist/components/chunks/ItemToolBar-9gqhfxtn.js +40 -0
  13. package/dist/components/chunks/ItemToolBar-hzc5wyjp.js +2 -0
  14. package/dist/components/chunks/{ItemToolBar-gmrryv2v.js → ItemToolBar-kkj69ptr.js} +1 -1
  15. package/dist/components/chunks/ItemToolBar-vdkyn9f3.js +2 -0
  16. package/dist/components/chunks/sre-engine-bj997w4b.js +1 -0
  17. package/dist/components/item-scope-element.d.ts +2 -0
  18. package/dist/components/item-scope-element.js +2 -0
  19. package/dist/context/assessment-toolkit-context.d.ts +33 -6
  20. package/dist/index.d.ts +25 -50
  21. package/dist/index.js +15 -45
  22. package/dist/policy/core/PolicySource.d.ts +2 -2
  23. package/dist/policy/core/ToolPolicyEngine.d.ts +118 -34
  24. package/dist/policy/core/ToolPolicyEngine.js +203 -56
  25. package/dist/policy/core/compose-decision.d.ts +28 -7
  26. package/dist/policy/core/compose-decision.js +95 -74
  27. package/dist/policy/core/decision-types.d.ts +98 -55
  28. package/dist/policy/core/feature-decision.d.ts +28 -19
  29. package/dist/policy/core/feature-decision.js +15 -11
  30. package/dist/policy/core/pnp-policy-inputs.d.ts +29 -35
  31. package/dist/policy/core/pnp-policy-inputs.js +40 -88
  32. package/dist/policy/core/provenance.d.ts +10 -5
  33. package/dist/policy/core/provenance.js +1 -1
  34. package/dist/policy/core/tool-parameters.d.ts +11 -0
  35. package/dist/policy/core/tool-parameters.js +15 -0
  36. package/dist/policy/engine.d.ts +7 -23
  37. package/dist/policy/engine.js +5 -20
  38. package/dist/policy/sources/PnpPolicySource.d.ts +43 -68
  39. package/dist/policy/sources/PnpPolicySource.js +133 -132
  40. package/dist/runtime/SectionControllerBinding.d.ts +283 -0
  41. package/dist/runtime/SectionControllerBinding.js +456 -0
  42. package/dist/runtime/SectionRuntimeEngine.d.ts +26 -289
  43. package/dist/runtime/SectionRuntimeEngine.js +30 -372
  44. package/dist/runtime/adapter/SectionEngineAdapter.d.ts +19 -80
  45. package/dist/runtime/adapter/SectionEngineAdapter.js +19 -92
  46. package/dist/runtime/adapter/dom-event-bridge.d.ts +15 -30
  47. package/dist/runtime/adapter/dom-event-bridge.js +17 -44
  48. package/dist/runtime/adapter/subscriber-fanout.d.ts +1 -3
  49. package/dist/runtime/adapter/subscriber-fanout.js +2 -6
  50. package/dist/runtime/catalog-context.d.ts +19 -0
  51. package/dist/runtime/catalog-context.js +28 -0
  52. package/dist/runtime/composition-emit-scheduler.d.ts +12 -18
  53. package/dist/runtime/composition-emit-scheduler.js +10 -16
  54. package/dist/runtime/content-language.d.ts +32 -0
  55. package/dist/runtime/content-language.js +46 -0
  56. package/dist/runtime/content-region.d.ts +13 -0
  57. package/dist/runtime/content-region.js +29 -0
  58. package/dist/runtime/content-registration.d.ts +13 -0
  59. package/dist/runtime/content-registration.js +25 -0
  60. package/dist/runtime/core/SectionEngineCore.d.ts +2 -4
  61. package/dist/runtime/core/SectionEngineCore.js +2 -6
  62. package/dist/runtime/core/cohort.d.ts +1 -6
  63. package/dist/runtime/core/cohort.js +1 -10
  64. package/dist/runtime/core/engine-input.d.ts +18 -30
  65. package/dist/runtime/core/engine-input.js +11 -12
  66. package/dist/runtime/core/engine-output.d.ts +17 -40
  67. package/dist/runtime/core/engine-output.js +9 -21
  68. package/dist/runtime/core/engine-readiness.d.ts +5 -37
  69. package/dist/runtime/core/engine-readiness.js +8 -41
  70. package/dist/runtime/core/engine-resolver.d.ts +46 -74
  71. package/dist/runtime/core/engine-resolver.js +18 -43
  72. package/dist/runtime/core/engine-state.d.ts +28 -36
  73. package/dist/runtime/core/engine-state.js +18 -21
  74. package/dist/runtime/core/engine-transition.d.ts +14 -19
  75. package/dist/runtime/core/engine-transition.js +74 -53
  76. package/dist/runtime/engine.d.ts +16 -19
  77. package/dist/runtime/engine.js +12 -19
  78. package/dist/runtime/page-warnings.d.ts +13 -0
  79. package/dist/runtime/page-warnings.js +22 -0
  80. package/dist/runtime/policy-input-forwarding.d.ts +25 -0
  81. package/dist/runtime/policy-input-forwarding.js +25 -0
  82. package/dist/runtime/registration-events.d.ts +22 -14
  83. package/dist/runtime/runtime-event-claim.d.ts +8 -0
  84. package/dist/runtime/runtime-event-claim.js +15 -0
  85. package/dist/runtime/runtime-id.d.ts +1 -1
  86. package/dist/runtime/runtime-id.js +1 -1
  87. package/dist/runtime/shell-event-bridge.d.ts +45 -0
  88. package/dist/runtime/shell-event-bridge.js +127 -0
  89. package/dist/runtime/shell-registration.d.ts +73 -0
  90. package/dist/runtime/shell-registration.js +95 -0
  91. package/dist/runtime/shell-scope.d.ts +68 -0
  92. package/dist/runtime/shell-scope.js +194 -0
  93. package/dist/runtime/tool-host-contract.d.ts +8 -14
  94. package/dist/runtime/tool-host-contract.js +12 -12
  95. package/dist/runtime/unclaimed-registration-watch.d.ts +7 -0
  96. package/dist/runtime/unclaimed-registration-watch.js +23 -0
  97. package/dist/services/AccessibilityCatalogResolver.d.ts +21 -31
  98. package/dist/services/AccessibilityCatalogResolver.js +29 -42
  99. package/dist/services/ElementToolStateStore.d.ts +42 -67
  100. package/dist/services/ElementToolStateStore.js +65 -71
  101. package/dist/services/HighlightCoordinator.d.ts +28 -40
  102. package/dist/services/HighlightCoordinator.js +459 -381
  103. package/dist/services/RangeSerializer.d.ts +11 -33
  104. package/dist/services/RangeSerializer.js +88 -59
  105. package/dist/services/SSMLExtractor.d.ts +8 -31
  106. package/dist/services/SSMLExtractor.js +18 -40
  107. package/dist/services/TTSService.d.ts +159 -119
  108. package/dist/services/TTSService.js +937 -822
  109. package/dist/services/ToolCoordinator.d.ts +42 -102
  110. package/dist/services/ToolCoordinator.js +178 -256
  111. package/dist/services/ToolRegistry.d.ts +152 -133
  112. package/dist/services/ToolRegistry.js +192 -178
  113. package/dist/services/ToolkitCoordinator.d.ts +233 -237
  114. package/dist/services/ToolkitCoordinator.js +615 -557
  115. package/dist/services/audio-handoff.d.ts +6 -7
  116. package/dist/services/audio-handoff.js +20 -14
  117. package/dist/services/catalog-owner.d.ts +0 -1
  118. package/dist/services/framework-error-bus.d.ts +3 -6
  119. package/dist/services/framework-error-bus.js +3 -6
  120. package/dist/services/framework-error.d.ts +51 -13
  121. package/dist/services/framework-error.js +19 -20
  122. package/dist/services/interfaces.d.ts +189 -184
  123. package/dist/services/section-controller-types.d.ts +7 -7
  124. package/dist/services/section-session-assignment.d.ts +21 -0
  125. package/dist/services/section-session-assignment.js +80 -0
  126. package/dist/services/spoken-audio-cards.d.ts +2 -6
  127. package/dist/services/spoken-audio-cards.js +2 -6
  128. package/dist/services/tool-config-defaults.d.ts +3 -3
  129. package/dist/services/tool-config-defaults.js +3 -3
  130. package/dist/services/tool-config-validation.d.ts +9 -12
  131. package/dist/services/tool-config-validation.js +47 -87
  132. package/dist/services/tool-context.d.ts +7 -31
  133. package/dist/services/tool-context.js +99 -65
  134. package/dist/services/tool-failure.d.ts +30 -0
  135. package/dist/services/tool-failure.js +11 -0
  136. package/dist/services/tool-icons.d.ts +5 -5
  137. package/dist/services/tool-icons.js +6 -5
  138. package/dist/services/tool-instance-id.d.ts +8 -7
  139. package/dist/services/tool-instance-id.js +12 -24
  140. package/dist/services/tool-providers/TTSToolProvider.d.ts +20 -58
  141. package/dist/services/tool-providers/TTSToolProvider.js +32 -85
  142. package/dist/services/tool-providers/ToolProviderApi.d.ts +10 -11
  143. package/dist/services/tool-providers/ToolProviderRegistry.d.ts +29 -60
  144. package/dist/services/tool-providers/ToolProviderRegistry.js +128 -144
  145. package/dist/services/tool-request.d.ts +31 -12
  146. package/dist/services/tool-request.js +31 -16
  147. package/dist/services/toolbar-decided-tools.d.ts +16 -0
  148. package/dist/services/toolbar-decided-tools.js +29 -0
  149. package/dist/services/toolbar-items.js +2 -5
  150. package/dist/services/tools-config-normalizer.d.ts +33 -29
  151. package/dist/services/tools-config-normalizer.js +26 -28
  152. package/dist/services/tts/browser-provider.d.ts +39 -6
  153. package/dist/services/tts/browser-provider.js +280 -160
  154. package/dist/services/tts/catalog-span-alignment.js +14 -7
  155. package/dist/services/tts/flat-tree.d.ts +64 -0
  156. package/dist/services/tts/flat-tree.js +269 -0
  157. package/dist/services/tts/generated-speech/assemble-plan.d.ts +3 -1
  158. package/dist/services/tts/generated-speech/assemble-plan.js +3 -1
  159. package/dist/services/tts/generated-speech/dom/build-dom-plan.d.ts +2 -0
  160. package/dist/services/tts/generated-speech/dom/build-dom-plan.js +1 -1
  161. package/dist/services/tts/generated-speech/dom/to-chunk-inputs.d.ts +2 -2
  162. package/dist/services/tts/generated-speech/index.d.ts +1 -1
  163. package/dist/services/tts/generated-speech/index.js +1 -1
  164. package/dist/services/tts/generated-speech/math-speech-cache.d.ts +3 -1
  165. package/dist/services/tts/generated-speech/math-speech-cache.js +5 -1
  166. package/dist/services/tts/generated-speech/types.d.ts +1 -1
  167. package/dist/services/tts/generated-speech/types.js +1 -1
  168. package/dist/services/tts/highlight-pipeline/create-highlight-plan.js +22 -16
  169. package/dist/services/tts/highlight-pipeline/prose-boundary-resolver.js +6 -4
  170. package/dist/services/tts/highlight-pipeline/readable-region.js +3 -2
  171. package/dist/services/tts/highlight-pipeline/types.d.ts +5 -0
  172. package/dist/services/tts/highlight-pipeline/visible-map-range.d.ts +12 -0
  173. package/dist/services/tts/highlight-pipeline/visible-map-range.js +73 -7
  174. package/dist/services/tts/highlight-target-resolver.d.ts +12 -0
  175. package/dist/services/tts/math-aware-text-processing.d.ts +5 -1
  176. package/dist/services/tts/math-aware-text-processing.js +42 -47
  177. package/dist/services/tts/math-control-names.d.ts +21 -0
  178. package/dist/services/tts/math-control-names.js +142 -0
  179. package/dist/services/tts/math-speech.d.ts +12 -1
  180. package/dist/services/tts/math-speech.js +54 -18
  181. package/dist/services/tts/mathml-sanitization.d.ts +7 -0
  182. package/dist/services/tts/mathml-sanitization.js +9 -1
  183. package/dist/services/tts/provider-options.d.ts +52 -0
  184. package/dist/services/tts/provider-options.js +1 -0
  185. package/dist/services/tts/ssml/spoken-text.d.ts +2 -26
  186. package/dist/services/tts/ssml/spoken-text.js +29 -0
  187. package/dist/services/tts/start-failure.d.ts +4 -0
  188. package/dist/services/tts/start-failure.js +19 -0
  189. package/dist/services/tts/text-processing.d.ts +9 -0
  190. package/dist/services/tts/text-processing.js +46 -33
  191. package/dist/services/tts/text-segmentation.d.ts +12 -0
  192. package/dist/services/tts/text-segmentation.js +60 -10
  193. package/dist/services/tts-runtime-config.d.ts +54 -26
  194. package/dist/services/tts-runtime-config.js +27 -112
  195. package/dist/tools/content-capability-resolution.d.ts +9 -11
  196. package/dist/tools/content-capability-resolution.js +8 -45
  197. package/dist/tools/registration.d.ts +59 -0
  198. package/dist/tools/registration.js +55 -0
  199. package/dist/tools/registrations/toolbar-registration-helpers.d.ts +6 -0
  200. package/dist/tools/registrations/toolbar-registration-helpers.js +8 -2
  201. package/dist/tools/tool-surface-host.d.ts +6 -10
  202. package/dist/tools/tool-surface-host.js +45 -50
  203. package/dist/tools/tool-tag-map.d.ts +5 -15
  204. package/dist/tools/tool-tag-map.js +6 -20
  205. package/dist/utils/structural-equality.d.ts +11 -0
  206. package/dist/utils/structural-equality.js +47 -0
  207. package/package.json +15 -29
  208. package/dist/attempt/adapters/activity-to-test-attempt-session.d.ts +0 -49
  209. package/dist/attempt/adapters/activity-to-test-attempt-session.js +0 -138
  210. package/dist/components/chunks/ItemToolBar-b9dz5jvd.js +0 -40
  211. package/dist/components/chunks/ItemToolBar-h4xap0t0.js +0 -4
  212. package/dist/components/chunks/ItemToolBar-wr2myaah.js +0 -2
  213. package/dist/components/chunks/sre-engine-wf9s43gg.js +0 -1
  214. package/dist/context/runtime-context-consumer.d.ts +0 -13
  215. package/dist/context/runtime-context-consumer.js +0 -18
  216. package/dist/item-loader.d.ts +0 -44
  217. package/dist/item-loader.js +0 -61
  218. package/dist/policy/core/engine-context.d.ts +0 -29
  219. package/dist/policy/core/engine-context.js +0 -27
  220. package/dist/policy/core/policy-source-tag.d.ts +0 -31
  221. package/dist/policy/core/policy-source-tag.js +0 -28
  222. package/dist/policy/internal.d.ts +0 -25
  223. package/dist/policy/internal.js +0 -25
  224. package/dist/runtime/adapter/coordinator-bridge.d.ts +0 -92
  225. package/dist/runtime/adapter/coordinator-bridge.js +0 -126
  226. package/dist/runtime/adapter/framework-error-bridge.d.ts +0 -36
  227. package/dist/runtime/adapter/framework-error-bridge.js +0 -46
  228. package/dist/runtime/adapter/instrumentation-bridge.d.ts +0 -31
  229. package/dist/runtime/adapter/instrumentation-bridge.js +0 -38
  230. package/dist/runtime/core/engine-stage-derivation.d.ts +0 -18
  231. package/dist/runtime/core/engine-stage-derivation.js +0 -29
  232. package/dist/runtime/engine-context.d.ts +0 -39
  233. package/dist/runtime/engine-context.js +0 -31
  234. package/dist/runtime/internal.d.ts +0 -43
  235. package/dist/runtime/internal.js +0 -45
  236. package/dist/runtime/section-runtime-engine-host-context.d.ts +0 -74
  237. package/dist/runtime/section-runtime-engine-host-context.js +0 -57
  238. package/dist/runtime/stage-emit-gate.d.ts +0 -92
  239. package/dist/runtime/stage-emit-gate.js +0 -82
  240. package/dist/services/ContextVariableStore.d.ts +0 -113
  241. package/dist/services/ContextVariableStore.js +0 -206
  242. package/dist/services/I18nService.d.ts +0 -47
  243. package/dist/services/I18nService.js +0 -84
  244. package/dist/services/ThemeProvider.d.ts +0 -95
  245. package/dist/services/ThemeProvider.js +0 -334
  246. package/dist/services/defaultPersonalNeedsProfile.d.ts +0 -21
  247. package/dist/services/defaultPersonalNeedsProfile.js +0 -26
  248. package/dist/services/pnp-standard-features.d.ts +0 -238
  249. package/dist/services/pnp-standard-features.js +0 -338
  250. package/dist/services/tts-control-events.d.ts +0 -13
  251. package/dist/services/tts-control-events.js +0 -7
  252. package/dist/tools/client.d.ts +0 -10
  253. package/dist/tools/client.js +0 -10
  254. package/dist/tools/internal.d.ts +0 -44
  255. package/dist/tools/internal.js +0 -39
  256. package/dist/utils/logger.d.ts +0 -6
  257. package/dist/utils/logger.js +0 -10
@@ -19,13 +19,10 @@ export function isValidToolbarItemShape(value) {
19
19
  return false;
20
20
  if (item.disabled !== undefined && typeof item.disabled !== "boolean")
21
21
  return false;
22
+ // A link or a button: exactly one of `href` and `onClick`.
22
23
  const hasHref = typeof item.href === "string";
23
24
  const hasOnClick = typeof item.onClick === "function";
24
- if (hasHref === hasOnClick)
25
- return false;
26
- if (hasHref)
27
- return true;
28
- return hasOnClick;
25
+ return hasHref !== hasOnClick;
29
26
  }
30
27
  export function isInlineSvgIcon(icon) {
31
28
  return typeof icon === "string" && icon.trimStart().startsWith("<svg");
@@ -1,5 +1,5 @@
1
1
  import type { CalculatorProviderConfig } from "@pie-players/pie-calculator";
2
- import type { SREMathSpeechOptions } from "./tts/math-speech.js";
2
+ import type { TTSRuntimeSettings } from "./tts-runtime-config.js";
3
3
  export type ToolPlacementLevel = "section" | "item" | "passage";
4
4
  export interface ToolPolicyConfig {
5
5
  allowed?: string[];
@@ -43,22 +43,22 @@ export interface ToolRuntimeProviderConfig {
43
43
  init?: Record<string, unknown>;
44
44
  runtime?: ToolRuntimeProviderBridge;
45
45
  }
46
- export type TextToSpeechRuntimeProviderId = "polly" | "google" | "custom";
47
46
  export interface ToolProviderConfig {
48
47
  enabled?: boolean;
49
48
  provider?: ToolRuntimeProviderConfig;
50
49
  settings?: Record<string, unknown>;
51
50
  [key: string]: unknown;
52
51
  }
53
- export interface TextToSpeechToolProviderSettings extends Record<string, unknown> {
54
- mathSpeech?: SREMathSpeechOptions;
55
- }
56
- export interface TextToSpeechToolProviderConfig extends Omit<ToolProviderConfig, "provider" | "settings"> {
57
- provider?: ToolRuntimeProviderConfig | TextToSpeechRuntimeProviderId;
58
- serverProvider?: TextToSpeechRuntimeProviderId;
59
- mathSpeech?: SREMathSpeechOptions;
60
- settings?: TextToSpeechToolProviderSettings;
61
- }
52
+ /**
53
+ * `tools.providers.textToSpeech`, closed to the runtime settings the TTS tool
54
+ * reads plus the registration's `enabled` and runtime `provider`. `Pick` keeps
55
+ * it assignable to the providers index signature, which an interface would not
56
+ * be.
57
+ */
58
+ export type TextToSpeechToolProviderConfig = Pick<TTSRuntimeSettings, keyof TTSRuntimeSettings> & {
59
+ enabled?: boolean;
60
+ provider?: ToolRuntimeProviderConfig;
61
+ };
62
62
  /**
63
63
  * `tools.providers.calculator`, closed to the keys the calculator reads, so a
64
64
  * misplaced key such as a top-level `authFetcher` fails to compile instead of
@@ -72,34 +72,30 @@ export type CalculatorToolProviderConfig = Pick<CalculatorProviderConfig, keyof
72
72
  export interface ToolProvidersConfig {
73
73
  textToSpeech?: TextToSpeechToolProviderConfig;
74
74
  calculator?: CalculatorToolProviderConfig;
75
- [key: string]: ToolProviderConfig | TextToSpeechToolProviderConfig | undefined;
75
+ [key: string]: ToolProviderConfig | undefined;
76
76
  }
77
77
  /**
78
- * PNP/profile enforcement mode mirrored on `runtime.tools.pnpEnforcement`
79
- * (M5 mirror rule). Carried alongside `policy` / `placement` /
80
- * `providers` so hosts can pin or opt out of PNP/profile precedence via
81
- * the runtime config without reaching for the toolkit prop directly.
78
+ * PNP/profile enforcement mode, set as `tools.pnpEnforcement` (on a section
79
+ * player, `runtime.tools.pnpEnforcement`) or through `setPnpEnforcement`.
82
80
  *
83
- * - `"on"` — force enforcement (engine applies PNP/profile gates).
84
- * - `"off"` — opt out (engine ignores PNP/profile inputs).
85
- * - omitted / `undefined` — auto-mode (the default). The toolkit
86
- * coordinator computes the effective mode from PNP/profile policy material on the
87
- * bound `AssessmentEntity` / `AssessmentItemRef`. See
81
+ * - `"on"` — toolbar decisions apply PNP/profile policy.
82
+ * - `"off"` — toolbar decisions skip it. Feature decisions read it either way.
83
+ * - omitted — auto-mode (the default): on when the bound assessment carries
84
+ * PNP/profile policy material, or, for a decision scoped to an item, when
85
+ * that item's settings require or restrict a tool. See
88
86
  * `resolveDefaultPnpEnforcement` in `policy/core/pnp-policy-inputs.ts`.
89
87
  */
90
- export type ToolsPnpEnforcement = "on" | "off";
88
+ export type PnpEnforcementMode = "on" | "off";
91
89
  export interface CanonicalToolsConfig {
92
90
  policy: ToolPolicyConfig;
93
91
  placement: Required<ToolPlacementConfig>;
94
92
  providers: ToolProvidersConfig;
95
93
  /**
96
- * Optional PNP/profile enforcement override. Mirrored on
97
- * `runtime.tools.pnpEnforcement`; consumed by
98
- * `<pie-assessment-toolkit>` and `ToolkitCoordinator` as the
99
- * embedded path's equivalent of the standalone `pnp-enforcement`
100
- * attribute. See {@link ToolsPnpEnforcement} for semantics.
94
+ * Optional PNP/profile enforcement override, read by
95
+ * `<pie-assessment-toolkit>` and `ToolkitCoordinator`. See
96
+ * {@link PnpEnforcementMode} for semantics.
101
97
  */
102
- pnpEnforcement?: ToolsPnpEnforcement;
98
+ pnpEnforcement?: PnpEnforcementMode;
103
99
  }
104
100
  /**
105
101
  * The tools config a host supplies. Every part is optional, placement levels
@@ -108,7 +104,15 @@ export interface CanonicalToolsConfig {
108
104
  export type ToolsConfigInput = Omit<Partial<CanonicalToolsConfig>, "placement"> & {
109
105
  placement?: ToolPlacementConfig;
110
106
  };
111
- export declare function normalizeToolAlias(toolId: string): string;
107
+ /**
108
+ * Tool ids trimmed, with empty ones dropped and duplicates removed in
109
+ * first-seen order. Throws on a non-string entry.
110
+ */
112
111
  export declare function normalizeToolList(toolIds: string[] | undefined | null): string[];
113
112
  export declare function parseToolList(input: string | undefined | null): string[];
113
+ /**
114
+ * Check a host's tools config shape, throwing at the first malformed field, and
115
+ * return it canonical: tool lists trimmed and deduplicated, and every placement
116
+ * level that names no tool filled with its default.
117
+ */
114
118
  export declare function normalizeToolsConfig(input?: ToolsConfigInput | null): CanonicalToolsConfig;
@@ -1,12 +1,10 @@
1
1
  import { DEFAULT_TOOL_PLACEMENT } from "./tool-config-defaults.js";
2
+ import { isPlainRecord } from "@pie-players/pie-players-shared/object";
2
3
  const DEFAULT_PLACEMENT = {
3
4
  section: [...DEFAULT_TOOL_PLACEMENT.section],
4
5
  item: [...DEFAULT_TOOL_PLACEMENT.item],
5
6
  passage: [...DEFAULT_TOOL_PLACEMENT.passage],
6
7
  };
7
- function isPlainObject(value) {
8
- return typeof value === "object" && value !== null && !Array.isArray(value);
9
- }
10
8
  function assertStringArray(value, fieldPath) {
11
9
  if (value == null)
12
10
  return [];
@@ -22,7 +20,7 @@ function assertStringArray(value, fieldPath) {
22
20
  function assertPlacementConfig(value) {
23
21
  if (value == null)
24
22
  return undefined;
25
- if (!isPlainObject(value)) {
23
+ if (!isPlainRecord(value)) {
26
24
  throw new Error('Invalid tools config at "placement": expected an object with section/item/passage arrays.');
27
25
  }
28
26
  return value;
@@ -30,7 +28,7 @@ function assertPlacementConfig(value) {
30
28
  function assertPolicyConfig(value) {
31
29
  if (value == null)
32
30
  return undefined;
33
- if (!isPlainObject(value)) {
31
+ if (!isPlainRecord(value)) {
34
32
  throw new Error('Invalid tools config at "policy": expected an object with allowed/blocked arrays.');
35
33
  }
36
34
  return value;
@@ -38,11 +36,10 @@ function assertPolicyConfig(value) {
38
36
  function assertProviderConfig(providerId, value) {
39
37
  if (value == null)
40
38
  return undefined;
41
- if (!isPlainObject(value)) {
39
+ if (!isPlainRecord(value)) {
42
40
  throw new Error(`Invalid tools config at "providers.${providerId}": expected an object.`);
43
41
  }
44
42
  const config = value;
45
- const isTTSRuntimeProviderId = (provider) => provider === "polly" || provider === "google" || provider === "custom";
46
43
  if ("enabled" in config &&
47
44
  config.enabled !== undefined &&
48
45
  typeof config.enabled !== "boolean") {
@@ -50,13 +47,12 @@ function assertProviderConfig(providerId, value) {
50
47
  }
51
48
  if ("settings" in config &&
52
49
  config.settings !== undefined &&
53
- !isPlainObject(config.settings)) {
50
+ !isPlainRecord(config.settings)) {
54
51
  throw new Error(`Invalid tools config at "providers.${providerId}.settings": expected an object.`);
55
52
  }
56
53
  if ("provider" in config &&
57
54
  config.provider !== undefined &&
58
- !isPlainObject(config.provider) &&
59
- !(providerId === "textToSpeech" && isTTSRuntimeProviderId(config.provider))) {
55
+ !isPlainRecord(config.provider)) {
60
56
  throw new Error(`Invalid tools config at "providers.${providerId}.provider": expected an object.`);
61
57
  }
62
58
  return config;
@@ -64,7 +60,7 @@ function assertProviderConfig(providerId, value) {
64
60
  function assertProvidersConfig(value) {
65
61
  if (value == null)
66
62
  return {};
67
- if (!isPlainObject(value)) {
63
+ if (!isPlainRecord(value)) {
68
64
  throw new Error('Invalid tools config at "providers": expected an object keyed by tool id.');
69
65
  }
70
66
  const normalized = {};
@@ -73,12 +69,10 @@ function assertProvidersConfig(value) {
73
69
  }
74
70
  return normalized;
75
71
  }
76
- export function normalizeToolAlias(toolId) {
77
- const trimmed = toolId.trim();
78
- if (!trimmed)
79
- return "";
80
- return trimmed;
81
- }
72
+ /**
73
+ * Tool ids trimmed, with empty ones dropped and duplicates removed in
74
+ * first-seen order. Throws on a non-string entry.
75
+ */
82
76
  export function normalizeToolList(toolIds) {
83
77
  if (!toolIds || toolIds.length === 0)
84
78
  return [];
@@ -87,7 +81,7 @@ export function normalizeToolList(toolIds) {
87
81
  if (typeof rawToolId !== "string") {
88
82
  throw new Error("Invalid tools config: tool list entries must be strings.");
89
83
  }
90
- const normalized = normalizeToolAlias(rawToolId);
84
+ const normalized = rawToolId.trim();
91
85
  if (!normalized)
92
86
  continue;
93
87
  deduped.add(normalized);
@@ -109,8 +103,18 @@ function assertPnpEnforcement(value, fieldPath) {
109
103
  return value;
110
104
  throw new Error(`Invalid tools config at "${fieldPath}": expected "on" or "off", got ${JSON.stringify(value)}.`);
111
105
  }
106
+ /** A placement level's tool ids, or the level's default when it names none. */
107
+ function normalizePlacementLevel(placement, level) {
108
+ const toolIds = normalizeToolList(assertStringArray(placement?.[level], `placement.${level}`));
109
+ return toolIds.length ? toolIds : [...DEFAULT_PLACEMENT[level]];
110
+ }
111
+ /**
112
+ * Check a host's tools config shape, throwing at the first malformed field, and
113
+ * return it canonical: tool lists trimmed and deduplicated, and every placement
114
+ * level that names no tool filled with its default.
115
+ */
112
116
  export function normalizeToolsConfig(input) {
113
- if (input != null && !isPlainObject(input)) {
117
+ if (input != null && !isPlainRecord(input)) {
114
118
  throw new Error('Invalid tools config: expected an object with "policy", "placement", and "providers".');
115
119
  }
116
120
  const policy = assertPolicyConfig(input?.policy);
@@ -123,15 +127,9 @@ export function normalizeToolsConfig(input) {
123
127
  blocked: normalizeToolList(assertStringArray(policy?.blocked, "policy.blocked")),
124
128
  },
125
129
  placement: {
126
- section: normalizeToolList(assertStringArray(placement?.section, "placement.section")).length
127
- ? normalizeToolList(assertStringArray(placement?.section, "placement.section"))
128
- : [...DEFAULT_PLACEMENT.section],
129
- item: normalizeToolList(assertStringArray(placement?.item, "placement.item")).length
130
- ? normalizeToolList(assertStringArray(placement?.item, "placement.item"))
131
- : [...DEFAULT_PLACEMENT.item],
132
- passage: normalizeToolList(assertStringArray(placement?.passage, "placement.passage")).length
133
- ? normalizeToolList(assertStringArray(placement?.passage, "placement.passage"))
134
- : [...DEFAULT_PLACEMENT.passage],
130
+ section: normalizePlacementLevel(placement, "section"),
131
+ item: normalizePlacementLevel(placement, "item"),
132
+ passage: normalizePlacementLevel(placement, "passage"),
135
133
  },
136
134
  providers,
137
135
  };
@@ -3,10 +3,46 @@
3
3
  *
4
4
  * Text-to-speech provider using the browser's Web Speech API.
5
5
  * Works in all modern browsers that support SpeechSynthesis.
6
- *
7
- * Part of PIE Assessment Toolkit.
8
6
  */
9
- import type { ITTSProvider, ITTSProviderImplementation, TTSConfig, TTSFeature, TTSProviderCapabilities } from "@pie-players/pie-tts";
7
+ import type { ITTSProvider, ITTSProviderImplementation, TTSConfig, TTSProviderCapabilities } from "@pie-players/pie-tts";
8
+ import type { ToolkitTTSConfig } from "./provider-options.js";
9
+ /**
10
+ * The part of another provider's configuration that keeps its meaning on
11
+ * browser speech. Every path that replaces a provider with browser speech
12
+ * starts it with this.
13
+ */
14
+ export declare const browserFallbackConfig: (config: Partial<ToolkitTTSConfig>) => Partial<ToolkitTTSConfig>;
15
+ /**
16
+ * The voice traits browser voice selection reads. A `SpeechSynthesisVoice` has
17
+ * them all; a host's own voice list may carry a subset.
18
+ */
19
+ export interface BrowserVoiceTraits {
20
+ voiceURI?: string;
21
+ name?: string;
22
+ lang?: string;
23
+ localService?: boolean;
24
+ default?: boolean;
25
+ }
26
+ /**
27
+ * Whether a voice speaks `contentLanguage`, or the browser's own language when
28
+ * the content names none: the same language, or the same primary subtag.
29
+ */
30
+ export declare const browserVoiceMatchesLanguage: (voice: Pick<BrowserVoiceTraits, "lang">, contentLanguage?: string) => boolean;
31
+ /**
32
+ * The voice to read with: the configured one, else one for `contentLanguage`
33
+ * (the language of the content being read), else one for the browser's own
34
+ * language.
35
+ */
36
+ export declare const findBrowserVoice: <Voice extends BrowserVoiceTraits>(voices: readonly Voice[], preferredVoice?: string, contentLanguage?: string) => Voice | null;
37
+ /**
38
+ * Waits for `synth` to publish its voice inventory, which browsers fill
39
+ * asynchronously after page load. Resolves `true` once `getVoices()` is
40
+ * non-empty, at once when it already is; `false` after `timeoutMs`, once
41
+ * `isCurrent` reports the wait superseded, or when `synth` offers no
42
+ * `voiceschanged` channel to wait on. A previous `onvoiceschanged` handler
43
+ * keeps running and is restored afterwards.
44
+ */
45
+ export declare const waitForBrowserVoices: (synth: SpeechSynthesis, timeoutMs: number, isCurrent?: () => boolean) => Promise<boolean>;
10
46
  /**
11
47
  * Browser TTS Provider
12
48
  *
@@ -14,10 +50,7 @@ import type { ITTSProvider, ITTSProviderImplementation, TTSConfig, TTSFeature, T
14
50
  */
15
51
  export declare class BrowserTTSProvider implements ITTSProvider {
16
52
  readonly providerId = "browser";
17
- readonly providerName = "Browser Speech Synthesis";
18
- readonly version = "1.0.0";
19
53
  initialize(config: TTSConfig): Promise<ITTSProviderImplementation>;
20
- supportsFeature(feature: TTSFeature): boolean;
21
54
  getCapabilities(): TTSProviderCapabilities;
22
55
  destroy(): void;
23
56
  }