@pie-players/pie-assessment-toolkit 0.3.74 → 0.3.75

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 (228) hide show
  1. package/README.md +349 -313
  2. package/dist/attempt/TestSession.d.ts +1 -20
  3. package/dist/attempt/TestSession.js +8 -99
  4. package/dist/components/ItemScope.custom-element.d.ts +1 -0
  5. package/dist/components/ItemScope.custom-element.js +1 -0
  6. package/dist/components/ItemToolBar.custom-element.js +1 -1
  7. package/dist/components/PieAssessmentToolkit.custom-element.js +14 -14
  8. package/dist/components/SectionToolBar.custom-element.js +1 -1
  9. package/dist/components/chunks/ItemToolBar-7tt7v2xp.js +4 -0
  10. package/dist/components/chunks/{ItemToolBar-gmrryv2v.js → ItemToolBar-97hx60z4.js} +1 -1
  11. package/dist/components/chunks/ItemToolBar-bxwyhr5p.js +2 -0
  12. package/dist/components/chunks/ItemToolBar-jx38w99s.js +2 -0
  13. package/dist/components/chunks/ItemToolBar-rd2bb4p6.js +40 -0
  14. package/dist/components/chunks/ItemToolBar-vdkyn9f3.js +2 -0
  15. package/dist/components/chunks/sre-engine-jd8cc08x.js +1 -0
  16. package/dist/components/item-scope-element.d.ts +2 -0
  17. package/dist/components/item-scope-element.js +2 -0
  18. package/dist/context/assessment-toolkit-context.d.ts +27 -6
  19. package/dist/index.d.ts +22 -47
  20. package/dist/index.js +12 -36
  21. package/dist/policy/core/PolicySource.d.ts +1 -1
  22. package/dist/policy/core/ToolPolicyEngine.d.ts +77 -32
  23. package/dist/policy/core/ToolPolicyEngine.js +136 -46
  24. package/dist/policy/core/compose-decision.d.ts +28 -7
  25. package/dist/policy/core/compose-decision.js +75 -54
  26. package/dist/policy/core/decision-types.d.ts +65 -34
  27. package/dist/policy/core/feature-decision.d.ts +16 -9
  28. package/dist/policy/core/feature-decision.js +14 -8
  29. package/dist/policy/core/pnp-policy-inputs.d.ts +24 -33
  30. package/dist/policy/core/pnp-policy-inputs.js +28 -56
  31. package/dist/policy/core/provenance.d.ts +9 -4
  32. package/dist/policy/core/provenance.js +1 -1
  33. package/dist/policy/engine.d.ts +7 -23
  34. package/dist/policy/engine.js +5 -20
  35. package/dist/policy/sources/PnpPolicySource.d.ts +44 -61
  36. package/dist/policy/sources/PnpPolicySource.js +117 -118
  37. package/dist/runtime/SectionControllerBinding.d.ts +279 -0
  38. package/dist/runtime/SectionControllerBinding.js +450 -0
  39. package/dist/runtime/SectionRuntimeEngine.d.ts +26 -289
  40. package/dist/runtime/SectionRuntimeEngine.js +30 -372
  41. package/dist/runtime/adapter/SectionEngineAdapter.d.ts +19 -80
  42. package/dist/runtime/adapter/SectionEngineAdapter.js +19 -92
  43. package/dist/runtime/adapter/dom-event-bridge.d.ts +15 -30
  44. package/dist/runtime/adapter/dom-event-bridge.js +17 -44
  45. package/dist/runtime/adapter/subscriber-fanout.d.ts +1 -2
  46. package/dist/runtime/adapter/subscriber-fanout.js +1 -2
  47. package/dist/runtime/catalog-context.d.ts +19 -0
  48. package/dist/runtime/catalog-context.js +28 -0
  49. package/dist/runtime/composition-emit-scheduler.d.ts +9 -15
  50. package/dist/runtime/composition-emit-scheduler.js +9 -15
  51. package/dist/runtime/content-language.d.ts +32 -0
  52. package/dist/runtime/content-language.js +46 -0
  53. package/dist/runtime/content-region.d.ts +17 -0
  54. package/dist/runtime/content-region.js +29 -0
  55. package/dist/runtime/content-registration.d.ts +13 -0
  56. package/dist/runtime/content-registration.js +25 -0
  57. package/dist/runtime/core/SectionEngineCore.d.ts +2 -2
  58. package/dist/runtime/core/SectionEngineCore.js +2 -2
  59. package/dist/runtime/core/cohort.d.ts +1 -1
  60. package/dist/runtime/core/cohort.js +1 -1
  61. package/dist/runtime/core/engine-input.d.ts +18 -30
  62. package/dist/runtime/core/engine-input.js +11 -12
  63. package/dist/runtime/core/engine-output.d.ts +16 -40
  64. package/dist/runtime/core/engine-output.js +9 -21
  65. package/dist/runtime/core/engine-readiness.d.ts +5 -37
  66. package/dist/runtime/core/engine-readiness.js +8 -41
  67. package/dist/runtime/core/engine-resolver.d.ts +46 -74
  68. package/dist/runtime/core/engine-resolver.js +18 -43
  69. package/dist/runtime/core/engine-state.d.ts +28 -36
  70. package/dist/runtime/core/engine-state.js +18 -21
  71. package/dist/runtime/core/engine-transition.d.ts +14 -19
  72. package/dist/runtime/core/engine-transition.js +71 -51
  73. package/dist/runtime/engine.d.ts +16 -19
  74. package/dist/runtime/engine.js +12 -19
  75. package/dist/runtime/page-warnings.d.ts +13 -0
  76. package/dist/runtime/page-warnings.js +22 -0
  77. package/dist/runtime/policy-input-forwarding.d.ts +25 -0
  78. package/dist/runtime/policy-input-forwarding.js +25 -0
  79. package/dist/runtime/registration-events.d.ts +11 -0
  80. package/dist/runtime/runtime-event-claim.d.ts +8 -0
  81. package/dist/runtime/runtime-event-claim.js +15 -0
  82. package/dist/runtime/shell-event-bridge.d.ts +45 -0
  83. package/dist/runtime/shell-event-bridge.js +127 -0
  84. package/dist/runtime/shell-registration.d.ts +73 -0
  85. package/dist/runtime/shell-registration.js +95 -0
  86. package/dist/runtime/shell-scope.d.ts +68 -0
  87. package/dist/runtime/shell-scope.js +188 -0
  88. package/dist/runtime/tool-host-contract.d.ts +8 -10
  89. package/dist/runtime/tool-host-contract.js +11 -11
  90. package/dist/runtime/unclaimed-registration-watch.d.ts +7 -0
  91. package/dist/runtime/unclaimed-registration-watch.js +23 -0
  92. package/dist/services/ElementToolStateStore.d.ts +14 -10
  93. package/dist/services/ElementToolStateStore.js +37 -13
  94. package/dist/services/HighlightCoordinator.d.ts +21 -21
  95. package/dist/services/HighlightCoordinator.js +431 -325
  96. package/dist/services/RangeSerializer.d.ts +10 -1
  97. package/dist/services/RangeSerializer.js +87 -14
  98. package/dist/services/TTSService.d.ts +117 -70
  99. package/dist/services/TTSService.js +668 -578
  100. package/dist/services/ToolCoordinator.d.ts +43 -60
  101. package/dist/services/ToolCoordinator.js +164 -206
  102. package/dist/services/ToolRegistry.d.ts +74 -57
  103. package/dist/services/ToolRegistry.js +104 -114
  104. package/dist/services/ToolkitCoordinator.d.ts +183 -189
  105. package/dist/services/ToolkitCoordinator.js +477 -431
  106. package/dist/services/audio-handoff.d.ts +6 -7
  107. package/dist/services/audio-handoff.js +20 -14
  108. package/dist/services/catalog-owner.d.ts +0 -1
  109. package/dist/services/framework-error-bus.d.ts +3 -6
  110. package/dist/services/framework-error-bus.js +3 -6
  111. package/dist/services/framework-error.d.ts +22 -7
  112. package/dist/services/framework-error.js +9 -7
  113. package/dist/services/interfaces.d.ts +158 -129
  114. package/dist/services/section-session-assignment.d.ts +21 -0
  115. package/dist/services/section-session-assignment.js +82 -0
  116. package/dist/services/spoken-audio-cards.d.ts +0 -2
  117. package/dist/services/spoken-audio-cards.js +0 -2
  118. package/dist/services/tool-config-defaults.d.ts +3 -3
  119. package/dist/services/tool-config-defaults.js +3 -3
  120. package/dist/services/tool-config-validation.d.ts +4 -5
  121. package/dist/services/tool-config-validation.js +36 -61
  122. package/dist/services/tool-context.d.ts +0 -8
  123. package/dist/services/tool-context.js +0 -12
  124. package/dist/services/tool-icons.d.ts +4 -3
  125. package/dist/services/tool-icons.js +4 -3
  126. package/dist/services/tool-instance-id.d.ts +0 -1
  127. package/dist/services/tool-instance-id.js +0 -6
  128. package/dist/services/tool-providers/TTSToolProvider.d.ts +18 -19
  129. package/dist/services/tool-providers/TTSToolProvider.js +37 -34
  130. package/dist/services/tool-providers/ToolProviderApi.d.ts +10 -4
  131. package/dist/services/tool-providers/ToolProviderRegistry.d.ts +30 -26
  132. package/dist/services/tool-providers/ToolProviderRegistry.js +119 -93
  133. package/dist/services/tool-request.d.ts +27 -12
  134. package/dist/services/tool-request.js +24 -14
  135. package/dist/services/toolbar-decided-tools.d.ts +15 -0
  136. package/dist/services/toolbar-decided-tools.js +28 -0
  137. package/dist/services/tools-config-normalizer.d.ts +17 -22
  138. package/dist/services/tools-config-normalizer.js +2 -10
  139. package/dist/services/tts/browser-provider.d.ts +38 -2
  140. package/dist/services/tts/browser-provider.js +276 -140
  141. package/dist/services/tts/flat-tree.d.ts +71 -0
  142. package/dist/services/tts/flat-tree.js +269 -0
  143. package/dist/services/tts/generated-speech/assemble-plan.d.ts +3 -1
  144. package/dist/services/tts/generated-speech/assemble-plan.js +3 -1
  145. package/dist/services/tts/generated-speech/dom/build-dom-plan.d.ts +2 -0
  146. package/dist/services/tts/generated-speech/dom/build-dom-plan.js +1 -1
  147. package/dist/services/tts/generated-speech/math-speech-cache.d.ts +3 -1
  148. package/dist/services/tts/generated-speech/math-speech-cache.js +5 -1
  149. package/dist/services/tts/highlight-pipeline/create-highlight-plan.js +12 -4
  150. package/dist/services/tts/highlight-pipeline/prose-boundary-resolver.js +6 -4
  151. package/dist/services/tts/highlight-pipeline/readable-region.js +3 -2
  152. package/dist/services/tts/highlight-pipeline/types.d.ts +5 -0
  153. package/dist/services/tts/highlight-pipeline/visible-map-range.d.ts +12 -0
  154. package/dist/services/tts/highlight-pipeline/visible-map-range.js +73 -7
  155. package/dist/services/tts/math-aware-text-processing.d.ts +5 -1
  156. package/dist/services/tts/math-aware-text-processing.js +32 -18
  157. package/dist/services/tts/math-control-names.d.ts +21 -0
  158. package/dist/services/tts/math-control-names.js +142 -0
  159. package/dist/services/tts/math-speech.d.ts +11 -0
  160. package/dist/services/tts/math-speech.js +51 -18
  161. package/dist/services/tts/provider-options.d.ts +41 -0
  162. package/dist/services/tts/provider-options.js +1 -0
  163. package/dist/services/tts/ssml/spoken-text.d.ts +2 -26
  164. package/dist/services/tts/ssml/spoken-text.js +29 -0
  165. package/dist/services/tts/start-failure.d.ts +11 -0
  166. package/dist/services/tts/start-failure.js +19 -0
  167. package/dist/services/tts/text-processing.d.ts +9 -0
  168. package/dist/services/tts/text-processing.js +46 -33
  169. package/dist/services/tts/text-segmentation.d.ts +7 -0
  170. package/dist/services/tts/text-segmentation.js +47 -0
  171. package/dist/services/tts-runtime-config.d.ts +25 -17
  172. package/dist/services/tts-runtime-config.js +16 -95
  173. package/dist/tools/content-capability-resolution.d.ts +7 -9
  174. package/dist/tools/content-capability-resolution.js +8 -45
  175. package/dist/tools/registration.d.ts +58 -0
  176. package/dist/tools/registration.js +54 -0
  177. package/dist/tools/registrations/toolbar-registration-helpers.js +2 -2
  178. package/dist/tools/tool-surface-host.d.ts +6 -10
  179. package/dist/tools/tool-surface-host.js +44 -42
  180. package/dist/tools/tool-tag-map.d.ts +5 -15
  181. package/dist/tools/tool-tag-map.js +6 -20
  182. package/dist/utils/structural-equality.d.ts +11 -0
  183. package/dist/utils/structural-equality.js +47 -0
  184. package/package.json +13 -29
  185. package/dist/attempt/adapters/activity-to-test-attempt-session.d.ts +0 -49
  186. package/dist/attempt/adapters/activity-to-test-attempt-session.js +0 -138
  187. package/dist/components/chunks/ItemToolBar-b9dz5jvd.js +0 -40
  188. package/dist/components/chunks/ItemToolBar-h4xap0t0.js +0 -4
  189. package/dist/components/chunks/ItemToolBar-wr2myaah.js +0 -2
  190. package/dist/components/chunks/sre-engine-wf9s43gg.js +0 -1
  191. package/dist/context/runtime-context-consumer.d.ts +0 -13
  192. package/dist/context/runtime-context-consumer.js +0 -18
  193. package/dist/item-loader.d.ts +0 -44
  194. package/dist/item-loader.js +0 -61
  195. package/dist/policy/core/engine-context.d.ts +0 -29
  196. package/dist/policy/core/engine-context.js +0 -27
  197. package/dist/policy/core/policy-source-tag.d.ts +0 -31
  198. package/dist/policy/core/policy-source-tag.js +0 -28
  199. package/dist/policy/internal.d.ts +0 -25
  200. package/dist/policy/internal.js +0 -25
  201. package/dist/runtime/adapter/coordinator-bridge.d.ts +0 -92
  202. package/dist/runtime/adapter/coordinator-bridge.js +0 -126
  203. package/dist/runtime/adapter/framework-error-bridge.d.ts +0 -36
  204. package/dist/runtime/adapter/framework-error-bridge.js +0 -46
  205. package/dist/runtime/adapter/instrumentation-bridge.d.ts +0 -31
  206. package/dist/runtime/adapter/instrumentation-bridge.js +0 -38
  207. package/dist/runtime/core/engine-stage-derivation.d.ts +0 -18
  208. package/dist/runtime/core/engine-stage-derivation.js +0 -29
  209. package/dist/runtime/engine-context.d.ts +0 -39
  210. package/dist/runtime/engine-context.js +0 -31
  211. package/dist/runtime/internal.d.ts +0 -43
  212. package/dist/runtime/internal.js +0 -45
  213. package/dist/runtime/section-runtime-engine-host-context.d.ts +0 -74
  214. package/dist/runtime/section-runtime-engine-host-context.js +0 -57
  215. package/dist/runtime/stage-emit-gate.d.ts +0 -92
  216. package/dist/runtime/stage-emit-gate.js +0 -82
  217. package/dist/services/I18nService.d.ts +0 -47
  218. package/dist/services/I18nService.js +0 -84
  219. package/dist/services/ThemeProvider.d.ts +0 -95
  220. package/dist/services/ThemeProvider.js +0 -334
  221. package/dist/services/defaultPersonalNeedsProfile.d.ts +0 -21
  222. package/dist/services/defaultPersonalNeedsProfile.js +0 -26
  223. package/dist/services/pnp-standard-features.d.ts +0 -238
  224. package/dist/services/pnp-standard-features.js +0 -338
  225. package/dist/tools/client.d.ts +0 -10
  226. package/dist/tools/client.js +0 -10
  227. package/dist/tools/internal.d.ts +0 -44
  228. package/dist/tools/internal.js +0 -39
@@ -4,12 +4,11 @@ import type { ToolRegistry } from "./ToolRegistry.js";
4
4
  export type ToolConfigStrictness = "off" | "warn" | "error";
5
5
  export type ToolConfigDiagnosticSeverity = "warning" | "error";
6
6
  export interface ToolConfigDiagnostic {
7
- code: "tools.unknownToolId" | "tools.unsupportedLevel" | "tools.unplaceableActivation" | "tools.registryUnavailable" | "tools.unknownProviderKey" | "tools.removedProviderKey" | "tools.providerSanitizeFailed" | "tools.providerValidateFailed" | "tools.invalidProviderValidation";
7
+ code: "tools.unknownToolId" | "tools.unsupportedLevel" | "tools.unplaceableActivation" | "tools.registryUnavailable" | "tools.unknownProviderKey" | "tools.providerSanitizeFailed" | "tools.providerValidateFailed" | "tools.invalidProviderValidation";
8
8
  severity: ToolConfigDiagnosticSeverity;
9
9
  path: string;
10
10
  message: string;
11
11
  toolId?: string;
12
- providerId?: string;
13
12
  }
14
13
  export interface ToolConfigValidationOptions {
15
14
  strictness?: ToolConfigStrictness;
@@ -34,8 +33,8 @@ export declare function normalizeAndValidateToolsConfig(input?: ToolsConfigInput
34
33
  */
35
34
  export declare function collectToolConfigDiagnostics(input: ToolsConfigInput | null | undefined, toolRegistry: ToolRegistry | null | undefined): ToolConfigValidationResult;
36
35
  /**
37
- * Report diagnostics as {@link normalizeAndValidateToolsConfig} does: a removed
38
- * provider key throws at every strictness, `"warn"` prints every diagnostic, and
39
- * `"error"` throws the blocking ones or, when there are none, prints the rest.
36
+ * Report diagnostics as {@link normalizeAndValidateToolsConfig} does: `"warn"`
37
+ * prints every diagnostic, and `"error"` throws the blocking ones or, when there
38
+ * are none, prints the rest.
40
39
  */
41
40
  export declare function reportToolConfigDiagnostics(diagnostics: ToolConfigDiagnostic[], options?: Pick<ToolConfigValidationOptions, "strictness" | "source">): void;
@@ -34,21 +34,20 @@ function getRegistryToolMap(toolRegistry) {
34
34
  .sort((left, right) => left.toolId.localeCompare(right.toolId))
35
35
  .map((tool) => [tool.toolId, tool]));
36
36
  }
37
- function sanitizeProviderConfig(providerId, providerConfig, tool, diagnostics) {
38
- if (!providerConfig || !tool?.provider?.sanitizeConfig)
37
+ function sanitizeToolConfig(toolId, providerConfig, tool, diagnostics) {
38
+ if (!providerConfig || !tool?.sanitizeConfig)
39
39
  return providerConfig;
40
40
  try {
41
- const sanitized = tool.provider.sanitizeConfig(providerConfig);
41
+ const sanitized = tool.sanitizeConfig(providerConfig);
42
42
  if (!sanitized ||
43
43
  typeof sanitized !== "object" ||
44
44
  Array.isArray(sanitized)) {
45
45
  diagnostics.push(createDiagnostic({
46
46
  code: "tools.providerSanitizeFailed",
47
47
  severity: "error",
48
- path: `providers.${providerId}`,
49
- message: `Provider sanitizer for "${providerId}" must return an object.`,
50
- providerId,
51
- toolId: providerId,
48
+ path: `providers.${toolId}`,
49
+ message: `Config sanitizer of tool "${toolId}" must return an object.`,
50
+ toolId,
52
51
  }));
53
52
  return providerConfig;
54
53
  }
@@ -58,36 +57,33 @@ function sanitizeProviderConfig(providerId, providerConfig, tool, diagnostics) {
58
57
  diagnostics.push(createDiagnostic({
59
58
  code: "tools.providerSanitizeFailed",
60
59
  severity: "error",
61
- path: `providers.${providerId}`,
62
- message: `Provider sanitizer failed for "${providerId}": ${error instanceof Error ? error.message : String(error)}`,
63
- providerId,
64
- toolId: providerId,
60
+ path: `providers.${toolId}`,
61
+ message: `Config sanitizer of tool "${toolId}" failed: ${error instanceof Error ? error.message : String(error)}`,
62
+ toolId,
65
63
  }));
66
64
  return providerConfig;
67
65
  }
68
66
  }
69
- function validateProviderConfig(providerId, providerConfig, tool, diagnostics) {
70
- if (!providerConfig || !tool?.provider?.validateConfig)
67
+ function validateToolConfig(toolId, providerConfig, tool, diagnostics) {
68
+ if (!providerConfig || !tool?.validateConfig)
71
69
  return;
72
70
  try {
73
- const providerDiagnostics = tool.provider.validateConfig(providerConfig);
74
- if (!Array.isArray(providerDiagnostics)) {
71
+ const toolDiagnostics = tool.validateConfig(providerConfig);
72
+ if (!Array.isArray(toolDiagnostics)) {
75
73
  diagnostics.push(createDiagnostic({
76
74
  code: "tools.invalidProviderValidation",
77
75
  severity: "error",
78
- path: `providers.${providerId}`,
79
- message: `Provider validator for "${providerId}" must return an array.`,
80
- providerId,
81
- toolId: providerId,
76
+ path: `providers.${toolId}`,
77
+ message: `Config validator of tool "${toolId}" must return an array.`,
78
+ toolId,
82
79
  }));
83
80
  return;
84
81
  }
85
- for (const diagnostic of providerDiagnostics) {
82
+ for (const diagnostic of toolDiagnostics) {
86
83
  diagnostics.push({
87
84
  ...diagnostic,
88
- path: diagnostic.path || `providers.${providerId}`,
89
- providerId: diagnostic.providerId || providerId,
90
- toolId: diagnostic.toolId || providerId,
85
+ path: diagnostic.path || `providers.${toolId}`,
86
+ toolId: diagnostic.toolId || toolId,
91
87
  });
92
88
  }
93
89
  }
@@ -95,10 +91,9 @@ function validateProviderConfig(providerId, providerConfig, tool, diagnostics) {
95
91
  diagnostics.push(createDiagnostic({
96
92
  code: "tools.providerValidateFailed",
97
93
  severity: "error",
98
- path: `providers.${providerId}`,
99
- message: `Provider validator failed for "${providerId}": ${error instanceof Error ? error.message : String(error)}`,
100
- providerId,
101
- toolId: providerId,
94
+ path: `providers.${toolId}`,
95
+ message: `Config validator of tool "${toolId}" failed: ${error instanceof Error ? error.message : String(error)}`,
96
+ toolId,
102
97
  }));
103
98
  }
104
99
  }
@@ -176,27 +171,16 @@ function collectPolicyDiagnostics(config, toolMap, diagnostics) {
176
171
  }));
177
172
  }
178
173
  }
179
- function collectProviderKeyDiagnostics(config, toolMap, hasRemovedTtsKey, diagnostics) {
180
- if (hasRemovedTtsKey) {
181
- diagnostics.push(createDiagnostic({
182
- code: "tools.removedProviderKey",
183
- severity: "error",
184
- path: "providers.tts",
185
- message: `Provider key "tts" is no longer supported. Use "providers.textToSpeech".`,
186
- providerId: "tts",
187
- toolId: "textToSpeech",
188
- }));
189
- }
190
- for (const providerId of Object.keys(config.providers).sort()) {
191
- if (toolMap.size === 0 || toolMap.has(providerId))
174
+ function collectProviderKeyDiagnostics(config, toolMap, diagnostics) {
175
+ for (const key of Object.keys(config.providers).sort()) {
176
+ if (toolMap.size === 0 || toolMap.has(key))
192
177
  continue;
193
178
  diagnostics.push(createDiagnostic({
194
179
  code: "tools.unknownProviderKey",
195
180
  severity: "error",
196
- path: `providers.${providerId}`,
197
- message: `Unknown provider key "${providerId}".`,
198
- providerId,
199
- toolId: providerId,
181
+ path: `providers.${key}`,
182
+ message: `Unknown provider key "${key}".`,
183
+ toolId: key,
200
184
  }));
201
185
  }
202
186
  }
@@ -245,18 +229,13 @@ export function collectToolConfigDiagnostics(input, toolRegistry) {
245
229
  message: 'No tool registry was supplied, so tool ids, placement levels and provider config were not validated, and a coordinator without one registers no tool providers. Pass `toolRegistry` to the coordinator or the toolkit it is bound to — for the packaged capability set, `createPackagedToolRegistry()` from "@pie-players/pie-default-tool-loaders".',
246
230
  }));
247
231
  }
248
- const hasRemovedTtsKey = Object.hasOwn(normalized.providers, "tts");
249
232
  const nextProviders = {
250
233
  ...(normalized.providers || {}),
251
234
  };
252
- for (const providerId of Object.keys(nextProviders).sort()) {
253
- if (providerId === "tts") {
254
- delete nextProviders.tts;
255
- continue;
256
- }
257
- const tool = registryTools.get(providerId);
258
- nextProviders[providerId] = sanitizeProviderConfig(providerId, nextProviders[providerId], tool, diagnostics);
259
- validateProviderConfig(providerId, nextProviders[providerId], tool, diagnostics);
235
+ for (const toolId of Object.keys(nextProviders).sort()) {
236
+ const tool = registryTools.get(toolId);
237
+ nextProviders[toolId] = sanitizeToolConfig(toolId, nextProviders[toolId], tool, diagnostics);
238
+ validateToolConfig(toolId, nextProviders[toolId], tool, diagnostics);
260
239
  }
261
240
  const nextConfig = {
262
241
  ...normalized,
@@ -264,24 +243,20 @@ export function collectToolConfigDiagnostics(input, toolRegistry) {
264
243
  };
265
244
  collectPlacementDiagnostics(nextConfig, registryTools, diagnostics);
266
245
  collectPolicyDiagnostics(nextConfig, registryTools, diagnostics);
267
- collectProviderKeyDiagnostics(nextConfig, registryTools, hasRemovedTtsKey, diagnostics);
246
+ collectProviderKeyDiagnostics(nextConfig, registryTools, diagnostics);
268
247
  return {
269
248
  config: nextConfig,
270
249
  diagnostics,
271
250
  };
272
251
  }
273
252
  /**
274
- * Report diagnostics as {@link normalizeAndValidateToolsConfig} does: a removed
275
- * provider key throws at every strictness, `"warn"` prints every diagnostic, and
276
- * `"error"` throws the blocking ones or, when there are none, prints the rest.
253
+ * Report diagnostics as {@link normalizeAndValidateToolsConfig} does: `"warn"`
254
+ * prints every diagnostic, and `"error"` throws the blocking ones or, when there
255
+ * are none, prints the rest.
277
256
  */
278
257
  export function reportToolConfigDiagnostics(diagnostics, options = {}) {
279
258
  const strictness = normalizeToolConfigStrictness(options.strictness);
280
259
  const source = options.source ?? "tools";
281
- const removedKeys = diagnostics.filter((entry) => entry.code === "tools.removedProviderKey");
282
- if (removedKeys.length > 0) {
283
- throwValidationError(removedKeys, source);
284
- }
285
260
  if (strictness === "warn") {
286
261
  emitWarnings(diagnostics, source);
287
262
  }
@@ -101,14 +101,6 @@ export interface ElementToolContext extends BaseToolContext {
101
101
  * Union type of all tool contexts
102
102
  */
103
103
  export type ToolContext = AssessmentToolContext | SectionToolContext | ItemToolContext | PassageToolContext | RubricToolContext | ElementToolContext;
104
- /**
105
- * Type guard to check if context is at assessment level
106
- */
107
- export declare function isAssessmentContext(context: ToolContext): context is AssessmentToolContext;
108
- /**
109
- * Type guard to check if context is at section level
110
- */
111
- export declare function isSectionContext(context: ToolContext): context is SectionToolContext;
112
104
  /**
113
105
  * Type guard to check if context is at item level
114
106
  */
@@ -4,18 +4,6 @@
4
4
  * Defines the context types passed to tools for making visibility and behavior decisions.
5
5
  * Each context level provides increasingly specific information about where the tool is being used.
6
6
  */
7
- /**
8
- * Type guard to check if context is at assessment level
9
- */
10
- export function isAssessmentContext(context) {
11
- return context.level === "assessment";
12
- }
13
- /**
14
- * Type guard to check if context is at section level
15
- */
16
- export function isSectionContext(context) {
17
- return context.level === "section";
18
- }
19
7
  /**
20
8
  * Type guard to check if context is at item level
21
9
  */
@@ -9,9 +9,10 @@
9
9
  * Names are generic shapes ("book-open", "beaker"), never capability names. Core
10
10
  * naming a capability is what the composition layer exists to prevent.
11
11
  *
12
- * Exported through `tools/internal` as well: a registration composing a selection
13
- * gateway renders its own buttons and has to draw the same icon the toolbar button
14
- * draws, or the learner sees two unrelated affordances for one tool.
12
+ * `resolveFallbackToolIcon` is exported through `tools/registration` as well: a
13
+ * registration composing a selection gateway renders its own buttons and has to
14
+ * draw the same icon the toolbar button draws, or the learner sees two unrelated
15
+ * affordances for one tool.
15
16
  */
16
17
  export declare const TOOL_FALLBACK_ICONS: Readonly<Record<string, string>>;
17
18
  /** Icon markup for `name`, or `null` when nothing built in matches. */
@@ -9,9 +9,10 @@
9
9
  * Names are generic shapes ("book-open", "beaker"), never capability names. Core
10
10
  * naming a capability is what the composition layer exists to prevent.
11
11
  *
12
- * Exported through `tools/internal` as well: a registration composing a selection
13
- * gateway renders its own buttons and has to draw the same icon the toolbar button
14
- * draws, or the learner sees two unrelated affordances for one tool.
12
+ * `resolveFallbackToolIcon` is exported through `tools/registration` as well: a
13
+ * registration composing a selection gateway renders its own buttons and has to
14
+ * draw the same icon the toolbar button draws, or the learner sees two unrelated
15
+ * affordances for one tool.
15
16
  */
16
17
  export const TOOL_FALLBACK_ICONS = {
17
18
  calculator: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 2h10a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2Zm0 2v4h10V4H7Zm0 6v2h2v-2H7Zm4 0v2h2v-2h-2Zm4 0v2h2v-2h-2Zm-8 4v2h2v-2H7Zm4 0v2h2v-2h-2Zm4 0v2h2v-2h-2Zm-8 4v2h2v-2H7Zm4 0v2h2v-2h-2Zm4 0v2h2v-2h-2Z" fill="currentColor"/></svg>',
@@ -11,4 +11,3 @@ export declare function registerToolScopeLevel(scopeLevel: string): void;
11
11
  export declare function isRegisteredToolScopeLevel(scopeLevel: string): scopeLevel is ToolScopeLevel;
12
12
  export declare function createScopedToolId(baseToolId: string, scopeLevel: ToolScopeLevel, scopeId: string): string;
13
13
  export declare function parseScopedToolId(id: string): ParsedToolInstanceId | null;
14
- export declare function toOverlayToolId(id: string): string;
@@ -46,9 +46,3 @@ export function parseScopedToolId(id) {
46
46
  scopeId,
47
47
  };
48
48
  }
49
- export function toOverlayToolId(id) {
50
- const parsed = parseScopedToolId(id);
51
- if (!parsed)
52
- return id;
53
- return createScopedToolId(parsed.baseToolId, parsed.scopeLevel, parsed.scopeId);
54
- }
@@ -1,10 +1,12 @@
1
1
  /**
2
2
  * TTS Tool Provider
3
3
  *
4
- * Unified provider for all TTS backends:
5
- * - Browser Web Speech API (no auth)
6
- * - AWS Polly (requires auth via server proxy)
7
- * - Google Cloud TTS (requires auth via server proxy)
4
+ * Unified provider for both TTS backends:
5
+ * - `browser`: the Web Speech API (no auth)
6
+ * - `server`: a TTS server, its service named by the config's `provider`.
7
+ * `polly` and `google` run on the `pie` transport; `custom` runs on the
8
+ * `custom` transport to a host's own service, which takes `lang_id`,
9
+ * `speedRate` and `cache`
8
10
  *
9
11
  * Part of PIE Assessment Toolkit.
10
12
  */
@@ -13,12 +15,10 @@ import type { RuntimeTTSConfig, TTSRuntimeSettings } from "../tts-runtime-config
13
15
  import type { ToolProviderApi, ToolProviderCapabilities } from "./ToolProviderApi.js";
14
16
  export type TTSBackend = NonNullable<TTSRuntimeSettings["backend"]>;
15
17
  /**
16
- * The runtime provider config plus the backend selection and instrumentation
17
- * this tool provider reads.
18
+ * The runtime provider config plus the credentials and instrumentation this
19
+ * tool provider reads. The backend is fixed at construction.
18
20
  */
19
21
  export type TTSToolProviderConfig = RuntimeTTSConfig & {
20
- backend: TTSBackend;
21
- serverProvider?: TTSRuntimeSettings["serverProvider"];
22
22
  /**
23
23
  * Bearer token for a server backend, sent as `Authorization`. A host supplies
24
24
  * it through `provider.runtime.authFetcher`.
@@ -38,34 +38,34 @@ export type TTSToolProviderOptions = {
38
38
  /**
39
39
  * TTS Tool Provider
40
40
  *
41
- * Wraps TTS providers (Browser, Polly, Google) with the ToolProviderApi interface
41
+ * Wraps the browser or a server TTS provider with the ToolProviderApi interface
42
42
  * for use in the ToolProviderRegistry.
43
43
  *
44
44
  * @example Browser TTS (no auth)
45
45
  * ```typescript
46
46
  * const provider = new TTSToolProvider();
47
- * await provider.initialize({ backend: 'browser' });
47
+ * await provider.initialize({});
48
48
  * const ttsProvider = await provider.createInstance();
49
49
  * ```
50
50
  *
51
51
  * @example Server TTS
52
52
  * ```typescript
53
- * const provider = new TTSToolProvider('polly', {
53
+ * const provider = new TTSToolProvider('server', {
54
54
  * loadServerProvider: async () => ServerTTSProvider,
55
55
  * });
56
56
  * await provider.initialize({
57
- * backend: 'polly',
57
+ * provider: 'polly',
58
58
  * apiEndpoint: '/api/tts',
59
59
  * });
60
60
  * const ttsProvider = await provider.createInstance();
61
61
  * ```
62
62
  */
63
- export declare class TTSToolProvider implements ToolProviderApi<TTSToolProviderConfig, ITTSProvider> {
64
- readonly providerId = "tts-service";
63
+ export declare class TTSToolProvider implements ToolProviderApi<ITTSProvider> {
65
64
  readonly providerName = "Text-to-Speech";
66
65
  readonly category: "tts";
67
66
  readonly version = "1.0";
68
67
  readonly requiresAuth: boolean;
68
+ private readonly backend;
69
69
  private ttsProvider;
70
70
  private config;
71
71
  private readonly loadServerProvider;
@@ -82,7 +82,7 @@ export declare class TTSToolProvider implements ToolProviderApi<TTSToolProviderC
82
82
  *
83
83
  * Sets up the appropriate TTS backend.
84
84
  *
85
- * @param config Configuration with backend type and credentials
85
+ * @param config Runtime configuration and credentials
86
86
  * @throws Error if initialization fails or required config missing
87
87
  */
88
88
  initialize(config: TTSToolProviderConfig): Promise<void>;
@@ -91,7 +91,7 @@ export declare class TTSToolProvider implements ToolProviderApi<TTSToolProviderC
91
91
  */
92
92
  private _initializeBrowserTTS;
93
93
  /**
94
- * Initialize server-based TTS (Polly, Google)
94
+ * Initialize server-based TTS
95
95
  */
96
96
  private _initializeServerTTS;
97
97
  /**
@@ -105,9 +105,8 @@ export declare class TTSToolProvider implements ToolProviderApi<TTSToolProviderC
105
105
  */
106
106
  createInstance(config?: Partial<TTSToolProviderConfig>): Promise<ITTSProvider>;
107
107
  /**
108
- * Get provider capabilities
109
- *
110
- * @returns TTS capabilities based on backend
108
+ * The backend's capabilities. Its features are the speech provider's own,
109
+ * and all false before {@link initialize} creates it.
111
110
  */
112
111
  getCapabilities(): ToolProviderCapabilities;
113
112
  /**
@@ -1,14 +1,18 @@
1
1
  /**
2
2
  * TTS Tool Provider
3
3
  *
4
- * Unified provider for all TTS backends:
5
- * - Browser Web Speech API (no auth)
6
- * - AWS Polly (requires auth via server proxy)
7
- * - Google Cloud TTS (requires auth via server proxy)
4
+ * Unified provider for both TTS backends:
5
+ * - `browser`: the Web Speech API (no auth)
6
+ * - `server`: a TTS server, its service named by the config's `provider`.
7
+ * `polly` and `google` run on the `pie` transport; `custom` runs on the
8
+ * `custom` transport to a host's own service, which takes `lang_id`,
9
+ * `speedRate` and `cache`
8
10
  *
9
11
  * Part of PIE Assessment Toolkit.
10
12
  */
13
+ import { createPieLogger, isTtsDebugEnabled, } from "@pie-players/pie-players-shared/pie";
11
14
  import { BrowserTTSProvider } from "../../services/tts/browser-provider.js";
15
+ const logger = createPieLogger("tts-tool-provider", isTtsDebugEnabled);
12
16
  /**
13
17
  * Binds a server backend's provider to the config the registry initialized this
14
18
  * tool provider with, including what `provider.runtime.authFetcher` returned.
@@ -34,7 +38,6 @@ function bindServerBackendConfig(provider, bound) {
34
38
  };
35
39
  return provider.initialize(merged);
36
40
  },
37
- supportsFeature: (feature) => provider.supportsFeature(feature),
38
41
  getCapabilities: () => provider.getCapabilities(),
39
42
  destroy: () => provider.destroy(),
40
43
  };
@@ -42,34 +45,34 @@ function bindServerBackendConfig(provider, bound) {
42
45
  /**
43
46
  * TTS Tool Provider
44
47
  *
45
- * Wraps TTS providers (Browser, Polly, Google) with the ToolProviderApi interface
48
+ * Wraps the browser or a server TTS provider with the ToolProviderApi interface
46
49
  * for use in the ToolProviderRegistry.
47
50
  *
48
51
  * @example Browser TTS (no auth)
49
52
  * ```typescript
50
53
  * const provider = new TTSToolProvider();
51
- * await provider.initialize({ backend: 'browser' });
54
+ * await provider.initialize({});
52
55
  * const ttsProvider = await provider.createInstance();
53
56
  * ```
54
57
  *
55
58
  * @example Server TTS
56
59
  * ```typescript
57
- * const provider = new TTSToolProvider('polly', {
60
+ * const provider = new TTSToolProvider('server', {
58
61
  * loadServerProvider: async () => ServerTTSProvider,
59
62
  * });
60
63
  * await provider.initialize({
61
- * backend: 'polly',
64
+ * provider: 'polly',
62
65
  * apiEndpoint: '/api/tts',
63
66
  * });
64
67
  * const ttsProvider = await provider.createInstance();
65
68
  * ```
66
69
  */
67
70
  export class TTSToolProvider {
68
- providerId = "tts-service";
69
71
  providerName = "Text-to-Speech";
70
72
  category = "tts";
71
73
  version = "1.0";
72
74
  requiresAuth;
75
+ backend;
73
76
  ttsProvider = null;
74
77
  config = null;
75
78
  loadServerProvider;
@@ -88,6 +91,7 @@ export class TTSToolProvider {
88
91
  * @param options Loader for the server adapter, required by server backends
89
92
  */
90
93
  constructor(backend = "browser", options = {}) {
94
+ this.backend = backend;
91
95
  this.requiresAuth = backend !== "browser";
92
96
  this.loadServerProvider = options.loadServerProvider;
93
97
  }
@@ -96,7 +100,7 @@ export class TTSToolProvider {
96
100
  *
97
101
  * Sets up the appropriate TTS backend.
98
102
  *
99
- * @param config Configuration with backend type and credentials
103
+ * @param config Runtime configuration and credentials
100
104
  * @throws Error if initialization fails or required config missing
101
105
  */
102
106
  async initialize(config) {
@@ -105,19 +109,17 @@ export class TTSToolProvider {
105
109
  return;
106
110
  }
107
111
  this.config = config;
108
- switch (config.backend) {
112
+ switch (this.backend) {
109
113
  case "browser":
110
114
  await this._initializeBrowserTTS(config);
111
115
  break;
112
- case "polly":
113
- case "google":
114
116
  case "server":
115
117
  await this._initializeServerTTS(config);
116
118
  break;
117
119
  default:
118
- throw new Error(`[TTSToolProvider] Unknown backend: ${config.backend}`);
120
+ throw new Error(`[TTSToolProvider] Unknown backend: ${this.backend}`);
119
121
  }
120
- console.log(`[TTSToolProvider] Initialized successfully (backend: ${config.backend})`);
122
+ logger.debug(`initialized (backend: ${this.backend})`);
121
123
  }
122
124
  /**
123
125
  * Initialize browser TTS (Web Speech API)
@@ -128,10 +130,10 @@ export class TTSToolProvider {
128
130
  throw new Error("[TTSToolProvider] Browser TTS not supported (Web Speech API not available)");
129
131
  }
130
132
  this.ttsProvider = new BrowserTTSProvider();
131
- console.log("[TTSToolProvider] Browser TTS initialized (Web Speech API)");
133
+ logger.debug("browser TTS initialized (Web Speech API)");
132
134
  }
133
135
  /**
134
- * Initialize server-based TTS (Polly, Google)
136
+ * Initialize server-based TTS
135
137
  */
136
138
  async _initializeServerTTS(config) {
137
139
  if (!config.apiEndpoint) {
@@ -141,11 +143,12 @@ export class TTSToolProvider {
141
143
  if (!loadServerProvider) {
142
144
  throw new Error("[TTSToolProvider] server-based TTS backends need the loadServerProvider option");
143
145
  }
146
+ const serverProvider = config.provider || this.backend;
144
147
  const moduleLoadStartedAt = Date.now();
145
148
  await this.emitTelemetry("pie-tool-library-load-start", {
146
149
  toolId: "textToSpeech",
147
150
  operation: "server-provider-module-import",
148
- backend: config.serverProvider || config.backend,
151
+ backend: serverProvider,
149
152
  });
150
153
  const ServerProvider = await (async () => {
151
154
  try {
@@ -153,7 +156,7 @@ export class TTSToolProvider {
153
156
  await this.emitTelemetry("pie-tool-library-load-success", {
154
157
  toolId: "textToSpeech",
155
158
  operation: "server-provider-module-import",
156
- backend: config.serverProvider || config.backend,
159
+ backend: serverProvider,
157
160
  duration: Date.now() - moduleLoadStartedAt,
158
161
  });
159
162
  return loaded;
@@ -162,7 +165,7 @@ export class TTSToolProvider {
162
165
  await this.emitTelemetry("pie-tool-library-load-error", {
163
166
  toolId: "textToSpeech",
164
167
  operation: "server-provider-module-import",
165
- backend: config.serverProvider || config.backend,
168
+ backend: serverProvider,
166
169
  duration: Date.now() - moduleLoadStartedAt,
167
170
  errorType: "ToolLibraryLoadError",
168
171
  message: error instanceof Error ? error.message : String(error),
@@ -170,9 +173,9 @@ export class TTSToolProvider {
170
173
  throw error;
171
174
  }
172
175
  })();
173
- const { backend, serverProvider, onTelemetry, ...backendConfig } = config;
176
+ const { onTelemetry: _onTelemetry, ...backendConfig } = config;
174
177
  this.ttsProvider = bindServerBackendConfig(new ServerProvider(), backendConfig);
175
- console.log(`[TTSToolProvider] Server TTS initialized (provider: ${config.serverProvider || config.backend})`);
178
+ logger.debug(`server TTS initialized (provider: ${serverProvider})`);
176
179
  }
177
180
  /**
178
181
  * Create a TTS provider instance
@@ -190,23 +193,23 @@ export class TTSToolProvider {
190
193
  return this.ttsProvider;
191
194
  }
192
195
  /**
193
- * Get provider capabilities
194
- *
195
- * @returns TTS capabilities based on backend
196
+ * The backend's capabilities. Its features are the speech provider's own,
197
+ * and all false before {@link initialize} creates it.
196
198
  */
197
199
  getCapabilities() {
198
- const isBrowser = this.config?.backend === "browser";
200
+ const isBrowser = this.backend === "browser";
201
+ const speech = this.ttsProvider?.getCapabilities();
199
202
  return {
200
203
  supportsOffline: isBrowser,
201
204
  requiresAuth: !isBrowser,
202
205
  maxInstances: 1, // Single TTS instance (playback is sequential)
203
206
  features: {
204
- wordBoundary: true, // All backends support word highlighting
205
- pause: true,
206
- resume: true,
207
- rateControl: true,
208
- pitchControl: isBrowser, // Only browser supports pitch
209
- voiceSelection: true,
207
+ wordBoundary: speech?.supportsWordBoundary ?? false,
208
+ pause: speech?.supportsPause ?? false,
209
+ resume: speech?.supportsResume ?? false,
210
+ rateControl: speech?.supportsRateControl ?? false,
211
+ pitchControl: speech?.supportsPitchControl ?? false,
212
+ voiceSelection: speech?.supportsVoiceSelection ?? false,
210
213
  },
211
214
  };
212
215
  }
@@ -229,6 +232,6 @@ export class TTSToolProvider {
229
232
  this.ttsProvider = null;
230
233
  }
231
234
  this.config = null;
232
- console.log("[TTSToolProvider] Destroyed");
235
+ logger.debug("destroyed");
233
236
  }
234
237
  }
@@ -11,14 +11,20 @@ export interface ToolProviderCapabilities {
11
11
  maxInstances?: number | null;
12
12
  features: Record<string, boolean>;
13
13
  }
14
- export interface ToolProviderApi<TConfig = any, TInstance = any> {
15
- readonly providerId: string;
14
+ /**
15
+ * A tool's provider. It registers under its tool's id, which is how the toolkit
16
+ * and the tool find it; it carries no id of its own.
17
+ *
18
+ * Config takes no type parameter (ADR 0002): an implementation narrows it in its
19
+ * own method signatures.
20
+ */
21
+ export interface ToolProviderApi<TInstance = any> {
16
22
  readonly providerName: string;
17
23
  readonly category: ToolCategory;
18
24
  readonly version: string;
19
25
  readonly requiresAuth: boolean;
20
- initialize(config: TConfig): Promise<void>;
21
- createInstance(config?: Partial<TConfig>): Promise<TInstance>;
26
+ initialize(config: unknown): Promise<void>;
27
+ createInstance(config?: unknown): Promise<TInstance>;
22
28
  getCapabilities(): ToolProviderCapabilities;
23
29
  isReady(): boolean;
24
30
  destroy(): void;