@pie-players/pie-assessment-toolkit 0.3.73 → 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 (274) hide show
  1. package/README.md +469 -318
  2. package/dist/attempt/AssessmentSession.d.ts +1 -5
  3. package/dist/attempt/AssessmentSession.js +0 -29
  4. package/dist/attempt/TestSession.d.ts +1 -20
  5. package/dist/attempt/TestSession.js +8 -99
  6. package/dist/components/ItemScope.custom-element.d.ts +1 -0
  7. package/dist/components/ItemScope.custom-element.js +1 -0
  8. package/dist/components/ItemToolBar.custom-element.d.ts +1 -0
  9. package/dist/components/ItemToolBar.custom-element.js +1 -1
  10. package/dist/components/PieAssessmentToolkit.custom-element.d.ts +1 -0
  11. package/dist/components/PieAssessmentToolkit.custom-element.js +13 -13
  12. package/dist/components/SectionToolBar.custom-element.d.ts +1 -0
  13. package/dist/components/SectionToolBar.custom-element.js +1 -1
  14. package/dist/components/chunks/ItemToolBar-7tt7v2xp.js +4 -0
  15. package/dist/components/chunks/ItemToolBar-97hx60z4.js +2 -0
  16. package/dist/components/chunks/ItemToolBar-bxwyhr5p.js +2 -0
  17. package/dist/components/chunks/ItemToolBar-jx38w99s.js +2 -0
  18. package/dist/components/chunks/ItemToolBar-rd2bb4p6.js +40 -0
  19. package/dist/components/chunks/ItemToolBar-vdkyn9f3.js +2 -0
  20. package/dist/components/chunks/sre-engine-jd8cc08x.js +1 -0
  21. package/dist/components/item-scope-element.d.ts +2 -0
  22. package/dist/components/item-scope-element.js +2 -0
  23. package/dist/context/assessment-toolkit-context.d.ts +32 -6
  24. package/dist/index.d.ts +23 -48
  25. package/dist/index.js +12 -37
  26. package/dist/policy/core/PolicySource.d.ts +1 -1
  27. package/dist/policy/core/ToolPolicyEngine.d.ts +85 -34
  28. package/dist/policy/core/ToolPolicyEngine.js +148 -46
  29. package/dist/policy/core/compose-decision.d.ts +28 -7
  30. package/dist/policy/core/compose-decision.js +75 -54
  31. package/dist/policy/core/decision-types.d.ts +65 -34
  32. package/dist/policy/core/feature-decision.d.ts +16 -9
  33. package/dist/policy/core/feature-decision.js +14 -8
  34. package/dist/policy/core/pnp-policy-inputs.d.ts +24 -33
  35. package/dist/policy/core/pnp-policy-inputs.js +28 -56
  36. package/dist/policy/core/provenance.d.ts +9 -4
  37. package/dist/policy/core/provenance.js +1 -1
  38. package/dist/policy/engine.d.ts +7 -23
  39. package/dist/policy/engine.js +5 -20
  40. package/dist/policy/sources/PnpPolicySource.d.ts +44 -61
  41. package/dist/policy/sources/PnpPolicySource.js +117 -118
  42. package/dist/runtime/SectionControllerBinding.d.ts +279 -0
  43. package/dist/runtime/SectionControllerBinding.js +450 -0
  44. package/dist/runtime/SectionRuntimeEngine.d.ts +26 -289
  45. package/dist/runtime/SectionRuntimeEngine.js +30 -372
  46. package/dist/runtime/adapter/SectionEngineAdapter.d.ts +19 -80
  47. package/dist/runtime/adapter/SectionEngineAdapter.js +19 -92
  48. package/dist/runtime/adapter/dom-event-bridge.d.ts +15 -30
  49. package/dist/runtime/adapter/dom-event-bridge.js +17 -44
  50. package/dist/runtime/adapter/subscriber-fanout.d.ts +1 -2
  51. package/dist/runtime/adapter/subscriber-fanout.js +1 -2
  52. package/dist/runtime/catalog-context.d.ts +19 -0
  53. package/dist/runtime/catalog-context.js +28 -0
  54. package/dist/runtime/composition-emit-scheduler.d.ts +9 -15
  55. package/dist/runtime/composition-emit-scheduler.js +9 -15
  56. package/dist/runtime/content-language.d.ts +32 -0
  57. package/dist/runtime/content-language.js +46 -0
  58. package/dist/runtime/content-region.d.ts +17 -0
  59. package/dist/runtime/content-region.js +29 -0
  60. package/dist/runtime/content-registration.d.ts +13 -0
  61. package/dist/runtime/content-registration.js +25 -0
  62. package/dist/runtime/core/SectionEngineCore.d.ts +2 -2
  63. package/dist/runtime/core/SectionEngineCore.js +2 -2
  64. package/dist/runtime/core/cohort.d.ts +1 -1
  65. package/dist/runtime/core/cohort.js +1 -1
  66. package/dist/runtime/core/engine-input.d.ts +18 -30
  67. package/dist/runtime/core/engine-input.js +11 -12
  68. package/dist/runtime/core/engine-output.d.ts +16 -40
  69. package/dist/runtime/core/engine-output.js +9 -21
  70. package/dist/runtime/core/engine-readiness.d.ts +5 -37
  71. package/dist/runtime/core/engine-readiness.js +8 -41
  72. package/dist/runtime/core/engine-resolver.d.ts +46 -74
  73. package/dist/runtime/core/engine-resolver.js +18 -43
  74. package/dist/runtime/core/engine-state.d.ts +28 -36
  75. package/dist/runtime/core/engine-state.js +18 -21
  76. package/dist/runtime/core/engine-transition.d.ts +14 -19
  77. package/dist/runtime/core/engine-transition.js +71 -51
  78. package/dist/runtime/engine.d.ts +16 -19
  79. package/dist/runtime/engine.js +12 -19
  80. package/dist/runtime/page-warnings.d.ts +13 -0
  81. package/dist/runtime/page-warnings.js +22 -0
  82. package/dist/runtime/policy-input-forwarding.d.ts +25 -0
  83. package/dist/runtime/policy-input-forwarding.js +25 -0
  84. package/dist/runtime/registration-events.d.ts +14 -0
  85. package/dist/runtime/runtime-event-claim.d.ts +8 -0
  86. package/dist/runtime/runtime-event-claim.js +15 -0
  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 +188 -0
  93. package/dist/runtime/tool-host-contract.d.ts +28 -10
  94. package/dist/runtime/tool-host-contract.js +31 -10
  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/ElementToolStateStore.d.ts +14 -10
  98. package/dist/services/ElementToolStateStore.js +37 -13
  99. package/dist/services/HighlightCoordinator.d.ts +22 -28
  100. package/dist/services/HighlightCoordinator.js +431 -327
  101. package/dist/services/RangeSerializer.d.ts +10 -1
  102. package/dist/services/RangeSerializer.js +87 -14
  103. package/dist/services/TTSService.d.ts +130 -69
  104. package/dist/services/TTSService.js +713 -570
  105. package/dist/services/ToolCoordinator.d.ts +43 -66
  106. package/dist/services/ToolCoordinator.js +164 -208
  107. package/dist/services/ToolRegistry.d.ts +78 -54
  108. package/dist/services/ToolRegistry.js +107 -105
  109. package/dist/services/ToolkitCoordinator.d.ts +261 -175
  110. package/dist/services/ToolkitCoordinator.js +667 -433
  111. package/dist/services/audio-handoff.d.ts +6 -7
  112. package/dist/services/audio-handoff.js +20 -14
  113. package/dist/services/catalog-owner.d.ts +11 -1
  114. package/dist/services/catalog-owner.js +25 -0
  115. package/dist/services/create-tools-config.d.ts +2 -2
  116. package/dist/services/framework-error-bus.d.ts +3 -6
  117. package/dist/services/framework-error-bus.js +3 -6
  118. package/dist/services/framework-error.d.ts +30 -8
  119. package/dist/services/framework-error.js +9 -7
  120. package/dist/services/interfaces.d.ts +158 -129
  121. package/dist/services/section-controller-types.d.ts +15 -0
  122. package/dist/services/section-session-assignment.d.ts +21 -0
  123. package/dist/services/section-session-assignment.js +82 -0
  124. package/dist/services/spoken-audio-cards.d.ts +0 -2
  125. package/dist/services/spoken-audio-cards.js +1 -3
  126. package/dist/services/tool-config-defaults.d.ts +3 -3
  127. package/dist/services/tool-config-defaults.js +3 -3
  128. package/dist/services/tool-config-validation.d.ts +14 -4
  129. package/dist/services/tool-config-validation.js +63 -71
  130. package/dist/services/tool-context.d.ts +0 -8
  131. package/dist/services/tool-context.js +29 -25
  132. package/dist/services/tool-icons.d.ts +4 -3
  133. package/dist/services/tool-icons.js +4 -3
  134. package/dist/services/tool-instance-id.d.ts +0 -1
  135. package/dist/services/tool-instance-id.js +0 -6
  136. package/dist/services/tool-providers/TTSToolProvider.d.ts +41 -80
  137. package/dist/services/tool-providers/TTSToolProvider.js +81 -40
  138. package/dist/services/tool-providers/ToolProviderApi.d.ts +10 -4
  139. package/dist/services/tool-providers/ToolProviderRegistry.d.ts +32 -28
  140. package/dist/services/tool-providers/ToolProviderRegistry.js +121 -107
  141. package/dist/services/tool-providers/index.d.ts +0 -9
  142. package/dist/services/tool-providers/index.js +2 -4
  143. package/dist/services/tool-request.d.ts +27 -12
  144. package/dist/services/tool-request.js +24 -14
  145. package/dist/services/toolbar-decided-tools.d.ts +15 -0
  146. package/dist/services/toolbar-decided-tools.js +28 -0
  147. package/dist/services/tools-config-normalizer.d.ts +37 -23
  148. package/dist/services/tools-config-normalizer.js +2 -10
  149. package/dist/services/tts/browser-provider.d.ts +38 -2
  150. package/dist/services/tts/browser-provider.js +276 -140
  151. package/dist/services/tts/catalog-span-alignment.d.ts +2 -17
  152. package/dist/services/tts/catalog-span-alignment.js +17 -142
  153. package/dist/services/tts/flat-tree.d.ts +71 -0
  154. package/dist/services/tts/flat-tree.js +269 -0
  155. package/dist/services/tts/generated-speech/assemble-plan.d.ts +3 -1
  156. package/dist/services/tts/generated-speech/assemble-plan.js +3 -1
  157. package/dist/services/tts/generated-speech/dom/build-dom-plan.d.ts +2 -0
  158. package/dist/services/tts/generated-speech/dom/build-dom-plan.js +1 -1
  159. package/dist/services/tts/generated-speech/math-speech-cache.d.ts +3 -1
  160. package/dist/services/tts/generated-speech/math-speech-cache.js +5 -1
  161. package/dist/services/tts/generated-speech/types.d.ts +0 -12
  162. package/dist/services/tts/highlight-pipeline/boundary-normalizer.js +12 -62
  163. package/dist/services/tts/highlight-pipeline/create-highlight-plan.js +38 -5
  164. package/dist/services/tts/highlight-pipeline/normalize-speech-chunks.js +3 -6
  165. package/dist/services/tts/highlight-pipeline/prose-boundary-resolver.js +6 -4
  166. package/dist/services/tts/highlight-pipeline/readable-region.js +3 -2
  167. package/dist/services/tts/highlight-pipeline/types.d.ts +5 -0
  168. package/dist/services/tts/highlight-pipeline/visible-map-range.d.ts +12 -0
  169. package/dist/services/tts/highlight-pipeline/visible-map-range.js +73 -7
  170. package/dist/services/tts/math-alignment/index.d.ts +0 -5
  171. package/dist/services/tts/math-alignment/index.js +5 -25
  172. package/dist/services/tts/math-alignment/speech-tokenizer.d.ts +9 -1
  173. package/dist/services/tts/math-alignment/speech-tokenizer.js +38 -36
  174. package/dist/services/tts/math-alignment/types.d.ts +4 -2
  175. package/dist/services/tts/math-aware-text-processing.d.ts +5 -1
  176. package/dist/services/tts/math-aware-text-processing.js +74 -18
  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 +16 -1
  180. package/dist/services/tts/math-speech.js +55 -19
  181. package/dist/services/tts/provider-options.d.ts +41 -0
  182. package/dist/services/tts/provider-options.js +1 -0
  183. package/dist/services/tts/sre-engine.d.ts +7 -0
  184. package/dist/services/tts/sre-engine.js +11 -0
  185. package/dist/services/tts/sre-locales.d.ts +14 -0
  186. package/dist/services/tts/sre-locales.js +57 -0
  187. package/dist/services/tts/ssml/spoken-text.d.ts +2 -26
  188. package/dist/services/tts/ssml/spoken-text.js +29 -0
  189. package/dist/services/tts/start-failure.d.ts +11 -0
  190. package/dist/services/tts/start-failure.js +19 -0
  191. package/dist/services/tts/text-processing.d.ts +9 -1
  192. package/dist/services/tts/text-processing.js +46 -34
  193. package/dist/services/tts/text-segmentation.d.ts +7 -0
  194. package/dist/services/tts/text-segmentation.js +47 -0
  195. package/dist/services/tts-runtime-config.d.ts +44 -18
  196. package/dist/services/tts-runtime-config.js +22 -93
  197. package/dist/tools/content-capability-resolution.d.ts +7 -9
  198. package/dist/tools/content-capability-resolution.js +8 -45
  199. package/dist/tools/registration.d.ts +58 -0
  200. package/dist/tools/registration.js +54 -0
  201. package/dist/tools/registrations/toolbar-registration-helpers.js +2 -2
  202. package/dist/tools/tool-surface-host.d.ts +6 -10
  203. package/dist/tools/tool-surface-host.js +44 -42
  204. package/dist/tools/tool-tag-map.d.ts +5 -15
  205. package/dist/tools/tool-tag-map.js +6 -20
  206. package/dist/utils/structural-equality.d.ts +11 -0
  207. package/dist/utils/structural-equality.js +47 -0
  208. package/package.json +24 -59
  209. package/dist/attempt/adapters/activity-to-test-attempt-session.d.ts +0 -49
  210. package/dist/attempt/adapters/activity-to-test-attempt-session.js +0 -138
  211. package/dist/components/chunks/ItemToolBar-byq80z42.js +0 -40
  212. package/dist/components/chunks/ItemToolBar-d36g3aw4.js +0 -49
  213. package/dist/context/runtime-context-consumer.d.ts +0 -13
  214. package/dist/context/runtime-context-consumer.js +0 -51
  215. package/dist/item-loader.d.ts +0 -44
  216. package/dist/item-loader.js +0 -61
  217. package/dist/policy/core/engine-context.d.ts +0 -29
  218. package/dist/policy/core/engine-context.js +0 -27
  219. package/dist/policy/core/policy-source-tag.d.ts +0 -31
  220. package/dist/policy/core/policy-source-tag.js +0 -28
  221. package/dist/policy/internal.d.ts +0 -25
  222. package/dist/policy/internal.js +0 -25
  223. package/dist/runtime/adapter/coordinator-bridge.d.ts +0 -92
  224. package/dist/runtime/adapter/coordinator-bridge.js +0 -126
  225. package/dist/runtime/adapter/framework-error-bridge.d.ts +0 -36
  226. package/dist/runtime/adapter/framework-error-bridge.js +0 -46
  227. package/dist/runtime/adapter/instrumentation-bridge.d.ts +0 -31
  228. package/dist/runtime/adapter/instrumentation-bridge.js +0 -38
  229. package/dist/runtime/core/engine-stage-derivation.d.ts +0 -18
  230. package/dist/runtime/core/engine-stage-derivation.js +0 -29
  231. package/dist/runtime/engine-context.d.ts +0 -39
  232. package/dist/runtime/engine-context.js +0 -31
  233. package/dist/runtime/internal.d.ts +0 -43
  234. package/dist/runtime/internal.js +0 -45
  235. package/dist/runtime/section-runtime-engine-host-context.d.ts +0 -80
  236. package/dist/runtime/section-runtime-engine-host-context.js +0 -95
  237. package/dist/runtime/stage-emit-gate.d.ts +0 -92
  238. package/dist/runtime/stage-emit-gate.js +0 -82
  239. package/dist/services/I18nService.d.ts +0 -47
  240. package/dist/services/I18nService.js +0 -84
  241. package/dist/services/ThemeProvider.d.ts +0 -95
  242. package/dist/services/ThemeProvider.js +0 -334
  243. package/dist/services/ToolConfigResolver.d.ts +0 -161
  244. package/dist/services/ToolConfigResolver.js +0 -229
  245. package/dist/services/catalog-media.d.ts +0 -56
  246. package/dist/services/catalog-media.js +0 -190
  247. package/dist/services/createDefaultToolRegistry.d.ts +0 -53
  248. package/dist/services/createDefaultToolRegistry.js +0 -45
  249. package/dist/services/defaultPersonalNeedsProfile.d.ts +0 -21
  250. package/dist/services/defaultPersonalNeedsProfile.js +0 -26
  251. package/dist/services/pnp-standard-features.d.ts +0 -238
  252. package/dist/services/pnp-standard-features.js +0 -338
  253. package/dist/services/tool-providers/CortexToolProvider.d.ts +0 -13
  254. package/dist/services/tool-providers/CortexToolProvider.js +0 -32
  255. package/dist/services/tool-providers/DesmosToolProvider.d.ts +0 -14
  256. package/dist/services/tool-providers/DesmosToolProvider.js +0 -32
  257. package/dist/services/tool-providers/GeoGebraToolProvider.d.ts +0 -16
  258. package/dist/services/tool-providers/GeoGebraToolProvider.js +0 -32
  259. package/dist/services/tool-providers/LazyCalculatorToolProvider.d.ts +0 -35
  260. package/dist/services/tool-providers/LazyCalculatorToolProvider.js +0 -95
  261. package/dist/services/tts/visual-line-ranges.d.ts +0 -18
  262. package/dist/services/tts/visual-line-ranges.js +0 -226
  263. package/dist/tools/client.d.ts +0 -12
  264. package/dist/tools/client.js +0 -14
  265. package/dist/tools/index.d.ts +0 -8
  266. package/dist/tools/index.js +0 -10
  267. package/dist/tools/internal.d.ts +0 -43
  268. package/dist/tools/internal.js +0 -41
  269. package/dist/tools/response-discovery.d.ts +0 -61
  270. package/dist/tools/response-discovery.js +0 -113
  271. package/dist/tools/types.d.ts +0 -337
  272. package/dist/tools/types.js +0 -12
  273. package/dist/tools/variant-resolver.d.ts +0 -41
  274. package/dist/tools/variant-resolver.js +0 -207
@@ -13,8 +13,8 @@
13
13
  *
14
14
  * Part of PIE Assessment Toolkit.
15
15
  */
16
- import type { AccessibilityCatalog, AssessmentEntity, AssessmentItemRef } from "@pie-players/pie-players-shared/types";
17
- import { type CanonicalToolsConfig, type ToolPlacementConfig, type ToolPlacementLevel, type ToolPolicyConfig, type ToolProviderConfig, type ToolProvidersConfig } from "./tools-config-normalizer.js";
16
+ import type { AccessibilityCatalog, AssessmentEntity, ItemSettings } from "@pie-players/pie-players-shared/types";
17
+ import { type CanonicalToolsConfig, type ToolPlacementConfig, type ToolPolicyConfig, type TextToSpeechToolProviderConfig, type ToolProviderConfig, type ToolProvidersConfig, type ToolsConfigInput } from "./tools-config-normalizer.js";
18
18
  import { type ToolConfigStrictness } from "./tool-config-validation.js";
19
19
  import { AccessibilityCatalogResolver } from "./AccessibilityCatalogResolver.js";
20
20
  import type { CatalogChangeListener } from "./AccessibilityCatalogResolver.js";
@@ -24,53 +24,15 @@ import { FrameworkErrorBus, type FrameworkErrorListener } from "./framework-erro
24
24
  import { HighlightCoordinator } from "./HighlightCoordinator.js";
25
25
  import { ToolCoordinator } from "./ToolCoordinator.js";
26
26
  import { TTSService } from "./TTSService.js";
27
- import { type TTSRuntimeSettings } from "./tts-runtime-config.js";
28
- import type { SREMathSpeechOptions } from "./tts/math-speech.js";
29
27
  import { ToolProviderRegistry } from "./tool-providers/index.js";
30
28
  import type { ToolProviderApi } from "./tool-providers/ToolProviderApi.js";
31
- import type { TTSToolProviderConfig } from "./tool-providers/index.js";
32
29
  import { ToolRegistry } from "./ToolRegistry.js";
33
- import type { ResolvedToolContext, ToolContextResolver, ToolContextResolverContext, ToolContextResolverMap } from "./ToolRegistry.js";
30
+ import type { ResolvedToolContext, ToolContextResolverContext, ToolContextResolverMap } from "./ToolRegistry.js";
34
31
  import type { ToolOpenRequest, ToolRequestTarget } from "./tool-request.js";
35
- import { type FeaturePolicyDecision, type PnpEnforcementMode, type PolicySource, type ResolvedEngineInputs, type ToolPolicyChangeListener, type ToolPolicyDecision, type ToolPolicyDecisionRequest } from "../policy/engine.js";
36
- import type { SectionControllerContext, SectionControllerEvent, SectionControllerEventType, SectionControllerFactoryDefaults, SectionControllerHandle, SectionControllerKey, SectionSessionPersistenceStrategy, SectionPersistenceFactoryDefaults } from "./section-controller-types.js";
32
+ import { type FeaturePolicyDecision, type PnpEnforcementMode, type PolicySource, type ResolvedEngineInputs, type ToolPolicyChangeListener, type ToolPolicyDecision, type ToolPolicyDecisionRequest, type ToolScope } from "../policy/engine.js";
33
+ import type { SectionControllerContext, SectionControllerEvent, SectionControllerEventType, SectionControllerFactoryDefaults, SectionControllerHandle, SectionControllerKey, SectionControllerSessionState, SectionSessionPersistenceStrategy, SectionPersistenceFactoryDefaults } from "./section-controller-types.js";
37
34
  export type { SectionControllerContext, SectionControllerEvent, SectionControllerEventType, SectionControllerFactoryDefaults, SectionControllerHandle, SectionControllerKey, SectionControllerLoadedRenderable, SectionSessionPersistenceConfig, SectionSessionPersistenceStrategy, SectionControllerRuntimeState, SectionControllerSessionState, SectionPersistenceFactoryDefaults, } from "./section-controller-types.js";
38
35
  export type { FeaturePolicyDecision, PnpEnforcementMode, ResolvedEngineInputs, ToolPolicyChangeListener, ToolPolicyDecision, ToolPolicyDecisionRequest, } from "../policy/engine.js";
39
- /**
40
- * Generic tool configuration
41
- */
42
- export interface ToolConfig {
43
- enabled?: boolean;
44
- provider?: unknown;
45
- settings?: Record<string, unknown>;
46
- [key: string]: unknown;
47
- }
48
- /**
49
- * TTS configuration as a host writes it.
50
- *
51
- * The field set is `TTSRuntimeSettings`, which the runtime resolver owns: the two
52
- * were declared separately and had already drifted in both directions, so a field
53
- * the runtime honoured could not be named here. What this adds is the two things
54
- * only a host-facing config has — a place to stash unrecognised keys, and a
55
- * callback for fetching provider credentials, neither of which the resolved
56
- * runtime settings carry.
57
- *
58
- * An intersection rather than an interface: `ToolConfig.provider` is `unknown`
59
- * where the runtime settings narrow it to the three provider ids, and an interface
60
- * cannot inherit a member from two parents that type it differently.
61
- */
62
- export type TTSToolConfig = ToolConfig & TTSRuntimeSettings & {
63
- settings?: Record<string, unknown> & {
64
- mathSpeech?: SREMathSpeechOptions;
65
- };
66
- authFetcher?: () => Promise<Partial<TTSToolProviderConfig>>;
67
- };
68
- /**
69
- * Answer eliminator tool configuration
70
- */
71
- export interface AnswerEliminatorToolConfig extends ToolConfig {
72
- strategy?: "strikethrough" | "hide";
73
- }
74
36
  export interface ToolkitToolsConfig extends CanonicalToolsConfig {
75
37
  policy: ToolPolicyConfig;
76
38
  placement: Required<ToolPlacementConfig>;
@@ -86,10 +48,10 @@ export interface ToolkitCoordinatorConfig {
86
48
  */
87
49
  assessmentId: string;
88
50
  /**
89
- * Tool availability and configuration.
90
- * Defaults: all tools enabled with default settings.
51
+ * Tool availability and configuration. The default placement is empty: a tool
52
+ * shows only where placement puts it, and a grant does not place one.
91
53
  */
92
- tools?: Partial<CanonicalToolsConfig>;
54
+ tools?: ToolsConfigInput;
93
55
  /**
94
56
  * Validation strictness for tool config contracts.
95
57
  * - off: keep diagnostics internal (no warnings or throws)
@@ -100,8 +62,12 @@ export interface ToolkitCoordinatorConfig {
100
62
  */
101
63
  toolConfigStrictness?: ToolConfigStrictness;
102
64
  /**
103
- * Optional registry used for tool-config validation and provider descriptor resolution.
104
- * Defaults to packaged PIE tools when omitted.
65
+ * Registry used for tool-config validation and the only source of tool
66
+ * providers: the coordinator registers one per registration that carries a
67
+ * provider descriptor. Omitted, the coordinator takes the registry of the
68
+ * toolkit it is bound to — the section player's, under a section player — and
69
+ * until then validates nothing and registers no provider. A registry passed
70
+ * here is never replaced.
105
71
  */
106
72
  toolRegistry?: ToolRegistry | null;
107
73
  /**
@@ -125,12 +91,21 @@ export interface ToolkitCoordinatorConfig {
125
91
  */
126
92
  hooks?: ToolkitCoordinatorHooks;
127
93
  /**
128
- * Lazy initialization mode.
129
- * When true, async service/provider initialization is deferred until ensure methods are called.
94
+ * Start text-to-speech at its first use rather than as part of readiness.
95
+ * `waitUntilReady()` then settles without it, unless policy grants the tool,
96
+ * so a granted read-aloud still fails before the learner starts.
130
97
  *
131
98
  * @default false
132
99
  */
133
100
  lazyInit?: boolean;
101
+ /**
102
+ * Start initializing at construction. `<pie-assessment-toolkit>` passes false
103
+ * for the coordinator it builds, and starts initialization once its section
104
+ * composes.
105
+ *
106
+ * @default !lazyInit
107
+ */
108
+ eagerInit?: boolean;
134
109
  /**
135
110
  * Internal bootstrap escape hatch used by framework-owned hosts.
136
111
  * When true, constructor skips throwing validation and expects caller
@@ -139,6 +114,15 @@ export interface ToolkitCoordinatorConfig {
139
114
  * @internal
140
115
  */
141
116
  deferToolConfigValidation?: boolean;
117
+ /**
118
+ * Set by `<pie-assessment-toolkit>` on the coordinator it builds for itself.
119
+ * That toolkit binds only the `assessment` its host passes, and a section
120
+ * player passes none, so feature policy reports an unbound assessment only
121
+ * while PNP enforcement is explicitly `"on"`.
122
+ *
123
+ * @internal
124
+ */
125
+ assessmentOptional?: boolean;
142
126
  /**
143
127
  * Optional pre-constructed framework-error bus.
144
128
  *
@@ -153,20 +137,15 @@ export interface ToolkitCoordinatorConfig {
153
137
  frameworkErrorBus?: FrameworkErrorBus;
154
138
  }
155
139
  export interface ToolkitErrorContext {
156
- phase: "coordinator-ready" | "state-load" | "state-save" | "provider-register" | "provider-init" | "tts-init" | "section-controller-init" | "section-controller-dispose";
157
- providerId?: string;
140
+ phase: "coordinator-ready" | "state-load" | "state-save" | "provider-register" | "provider-init" | "tts-init" | "section-controller-init" | "section-controller-dispose" | "tool-module-load";
141
+ /** The tool whose provider failed. */
142
+ toolId?: string;
158
143
  details?: Record<string, unknown>;
144
+ recoverable?: boolean;
159
145
  }
160
146
  export interface ProviderLifecycleContext {
161
- providerId: string;
162
147
  providerName?: string;
163
148
  }
164
- export interface ToolkitInitStatus {
165
- tts: boolean;
166
- stateLoaded: boolean;
167
- coordinator: boolean;
168
- providers: Record<string, boolean>;
169
- }
170
149
  export interface SectionControllerLifecycleEvent {
171
150
  type: "ready" | "disposed";
172
151
  key: SectionControllerKey;
@@ -236,9 +215,9 @@ export interface ToolkitCoordinatorHooks {
236
215
  onBeforeTTSInit?: (context: ToolkitErrorContext) => void | Promise<void>;
237
216
  onTTSReady?: () => void | Promise<void>;
238
217
  onCoordinatorReady?: (coordinator: ToolkitCoordinator) => void | Promise<void>;
239
- onProviderRegistered?: (providerId: string, meta: ProviderLifecycleContext) => void | Promise<void>;
240
- onProviderInitStart?: (providerId: string, meta: ProviderLifecycleContext) => void | Promise<void>;
241
- onProviderReady?: (providerId: string, meta: ProviderLifecycleContext) => void | Promise<void>;
218
+ onProviderRegistered?: (toolId: string, meta: ProviderLifecycleContext) => void | Promise<void>;
219
+ onProviderInitStart?: (toolId: string, meta: ProviderLifecycleContext) => void | Promise<void>;
220
+ onProviderReady?: (toolId: string, meta: ProviderLifecycleContext) => void | Promise<void>;
242
221
  onTelemetry?: (eventName: string, payload?: Record<string, unknown>) => void | Promise<void>;
243
222
  loadToolState?: () => Record<string, Record<string, unknown>> | Promise<Record<string, Record<string, unknown>> | null | undefined> | null | undefined;
244
223
  saveToolState?: (state: Record<string, Record<string, unknown>>) => void | Promise<void>;
@@ -256,29 +235,24 @@ export type ToolkitTelemetryListener = (args: {
256
235
  eventName: string;
257
236
  payload?: Record<string, unknown>;
258
237
  }) => void;
259
- /**
260
- * Service bundle returned by getServiceBundle()
261
- */
262
- export interface ToolkitServiceBundle {
263
- ttsService: TTSService;
264
- toolCoordinator: ToolCoordinator;
265
- highlightCoordinator: HighlightCoordinator;
266
- elementToolStateStore: ElementToolStateStore;
267
- catalogResolver: AccessibilityCatalogResolver;
268
- toolProviderRegistry: ToolProviderRegistry;
269
- }
270
238
  /**
271
239
  * ToolkitCoordinator - Orchestrates all assessment toolkit services
272
240
  *
273
241
  * @example
274
242
  * ```typescript
243
+ * // Both are exported by @pie-players/pie-default-tool-loaders
244
+ * const toolRegistry = createPackagedToolRegistry({
245
+ * toolModuleLoaders: DEFAULT_TOOL_MODULE_LOADERS,
246
+ * });
247
+ *
275
248
  * // Create coordinator with configuration
276
249
  * const coordinator = new ToolkitCoordinator({
277
250
  * assessmentId: 'demo-three-questions',
251
+ * toolRegistry,
278
252
  * tools: {
279
253
  * providers: {
280
254
  * textToSpeech: { enabled: true, backend: 'browser' },
281
- * answerEliminator: { enabled: true, strategy: 'strikethrough' }
255
+ * answerEliminator: { enabled: true }
282
256
  * },
283
257
  * placement: {
284
258
  * item: ['textToSpeech', 'answerEliminator']
@@ -287,7 +261,7 @@ export interface ToolkitServiceBundle {
287
261
  * });
288
262
  *
289
263
  * // Pass to section player
290
- * player.toolkitCoordinator = coordinator;
264
+ * player.runtime = { ...(player.runtime ?? {}), coordinator };
291
265
  *
292
266
  * // Access services directly
293
267
  * const ttsService = coordinator.ttsService;
@@ -310,14 +284,43 @@ export declare class ToolkitCoordinator {
310
284
  readonly lazyInit: boolean;
311
285
  /** Track TTS initialization state */
312
286
  private ttsInitialized;
287
+ /** Text-to-speech failed to start and policy does not grant it. */
288
+ private ttsDegraded;
313
289
  private ttsInitPromise?;
314
290
  private ttsReconfigurePromise?;
315
291
  private stateLoaded;
292
+ /**
293
+ * The loader ran, whether or not it returned state. A failed load is
294
+ * reported once and the coordinator runs without saved tool state.
295
+ */
296
+ private stateLoadSettled;
316
297
  private stateLoadPromise?;
317
298
  private coordinatorReadyPromise?;
318
299
  private coordinatorReadyNotified;
319
300
  private readonly providerInitPromises;
320
- private readonly toolRegistry;
301
+ /**
302
+ * Recoverable failures, by tool. A policy change that grants one of these
303
+ * tools reports its failure again as fatal.
304
+ */
305
+ private readonly degradedTools;
306
+ /** Tools a toolbar reported a module failure for, each reported once. */
307
+ private readonly toolModuleFailures;
308
+ private readonly readyChangeListeners;
309
+ private readonly eagerInit;
310
+ private toolRegistry;
311
+ /** Whether the host passed `toolRegistry`, which then always stands. */
312
+ private readonly toolRegistrySupplied;
313
+ /**
314
+ * Whether the registry is final: supplied at construction, or adopted from
315
+ * the toolkit this coordinator is bound to.
316
+ */
317
+ private toolRegistrySettled;
318
+ /**
319
+ * Whether a bound toolkit reported having no registry. Until then, or until a
320
+ * registry settles, the empty placeholder reports no missing registry, since
321
+ * the toolkit may supply one.
322
+ */
323
+ private toolRegistryAbsent;
321
324
  private readonly toolContextResolvers;
322
325
  private readonly toolContextResolverChangeListeners;
323
326
  private readonly toolRequests;
@@ -344,14 +347,16 @@ export declare class ToolkitCoordinator {
344
347
  * Phase D: map key of the section controller currently treated as
345
348
  * the *active cohort*. Set by `getOrCreateSectionController` (both
346
349
  * the create-new and resolve-existing paths) and cleared when the
347
- * matching controller is disposed. `null` while no cohort exists,
348
- * which is the only state where `subscribeSectionEvents` throws.
350
+ * matching controller is disposed, and `null` while the next requested
351
+ * cohort is still starting.
349
352
  */
350
353
  private activeCohortMapKey;
351
354
  /**
352
355
  * Latest requested active cohort. Async controller initialization can
353
356
  * resolve out of order; only the most recent request may migrate active
354
357
  * subscriptions. Older completions still populate the controller cache.
358
+ * `null` until the first request, which is the only state where
359
+ * `subscribeSectionEvents` throws.
355
360
  */
356
361
  private latestRequestedActiveCohortMapKey;
357
362
  private readonly telemetryListeners;
@@ -367,32 +372,20 @@ export declare class ToolkitCoordinator {
367
372
  */
368
373
  private readonly policyEngine;
369
374
  /**
370
- * Host-set override for PNP/profile enforcement. `null` (the default) means
371
- * "auto" — the coordinator infers the effective mode from the
372
- * PNP/profile policy inputs the bound `AssessmentEntity` and `AssessmentItemRef`
373
- * actually carry (see {@link resolveEffectivePnpEnforcement}).
375
+ * Host-set override for PNP/profile enforcement, passed to the engine.
376
+ * `null` (the default) is auto-mode, which the engine resolves per decision
377
+ * from the policy material the bound assessment and the decision's item carry.
374
378
  * `"on"` / `"off"` are explicit host opt-in / opt-out and stick
375
- * across subsequent assessment / item swaps until the host clears
379
+ * across subsequent assessment swaps until the host clears
376
380
  * the override by calling `setPnpEnforcement(null)`.
377
381
  */
378
382
  private pnpEnforcementOverride;
379
383
  /**
380
- * Last assessment passed to {@link updateAssessment}. Read by
381
- * {@link resolveEffectivePnpEnforcement} to compute auto-mode.
382
- * The engine's own copy is the canonical record for decisions;
383
- * this mirror exists only so the auto-mode helper does not need
384
- * to round-trip through {@link policyEngine}'s frozen snapshot.
385
- */
386
- private boundAssessment;
387
- /**
388
- * Last item reference passed to {@link updateCurrentItemRef}.
389
- * Mirrored alongside {@link boundAssessment} so
390
- * {@link resolveEffectivePnpEnforcement} can detect item-level
391
- * profile policy inputs (`requiredTools` / `restrictedTools` /
392
- * `toolParameters`) without round-tripping through the engine's
393
- * frozen snapshot.
384
+ * Policy diagnostics already logged, keyed by code, tool id and, for
385
+ * `tool-policy.itemSettingNotApplied`, item id; see
386
+ * {@link warnPolicyDiagnostics}.
394
387
  */
395
- private boundCurrentItemRef;
388
+ private readonly warnedPolicyDiagnostics;
396
389
  /**
397
390
  * Whether {@link decideFeaturePolicy} has already reported serving a decision
398
391
  * with no assessment bound.
@@ -404,7 +397,31 @@ export declare class ToolkitCoordinator {
404
397
  * lifetime for no new information.
405
398
  */
406
399
  private reportedUnboundFeaturePolicy;
407
- private static resolveConfig;
400
+ /**
401
+ * Whether {@link _initializeTTS} has already reported a non-browser backend
402
+ * falling back to browser speech because no text-to-speech provider is registered.
403
+ * Once per coordinator: a text-to-speech config change re-runs
404
+ * initialization, and the missing provider is the same gap each time.
405
+ */
406
+ private reportedMissingTTSProvider;
407
+ /**
408
+ * The backend of a fallback {@link reportMissingTTSProvider} held back while
409
+ * the registry was unsettled, reported if the bound toolkit has no registry.
410
+ */
411
+ private heldMissingTTSProviderBackend;
412
+ /**
413
+ * Whether {@link validateToolsConfig} has already reported validating with
414
+ * no registry (`tools.registryUnavailable`). Once per coordinator: every
415
+ * {@link updateToolConfig} and {@link updateToolsPlacement} re-validates, and
416
+ * the missing registry is the same gap each time.
417
+ */
418
+ private reportedRegistryUnavailable;
419
+ private resolveConfig;
420
+ /**
421
+ * `normalizeAndValidateToolsConfig`, except that `tools.registryUnavailable`
422
+ * is reported once per coordinator, whichever call validates.
423
+ */
424
+ private validateToolsConfig;
408
425
  constructor(config: ToolkitCoordinatorConfig);
409
426
  private assertNotDisposed;
410
427
  /**
@@ -441,7 +458,39 @@ export declare class ToolkitCoordinator {
441
458
  */
442
459
  private emitTelemetry;
443
460
  private emitSectionControllerLifecycle;
461
+ /**
462
+ * Every report site states whether the coordinator carries on after the
463
+ * failure; one that takes down only its section passes `scope: "cohort"`.
464
+ */
444
465
  private handleError;
466
+ /**
467
+ * Whether policy grants `toolId` as an accommodation on some surface: a
468
+ * test-administration override, a mounted item's or a district requirement,
469
+ * or profile support. Read without the unbound-assessment warning.
470
+ */
471
+ private isToolGranted;
472
+ /**
473
+ * Reports a tool's start failure: recoverable, so the tool reports itself
474
+ * unavailable and the assessment goes on, unless policy grants the tool.
475
+ * `fallbackFollows` marks a failure another path absorbs, which is recoverable
476
+ * whatever the policy.
477
+ */
478
+ private reportToolFailure;
479
+ /**
480
+ * Report that a toolbar could not load a tool's module. The failure follows
481
+ * the start-failure policy: the tool degrades, so the toolbar withholds it,
482
+ * unless policy grants it. Reported once per tool however many toolbars fail
483
+ * to load it. Every report re-announces the request targets, since the
484
+ * reporting toolbar no longer hosts the tool.
485
+ */
486
+ reportToolModuleFailure(toolId: string, error: unknown): void;
487
+ private reportNewlyGrantedFailures;
488
+ /**
489
+ * Subscribe to changes of {@link isReady}: state loading, text-to-speech
490
+ * starting, failing or reconfiguring. The listener reads the status itself.
491
+ */
492
+ onReadyChange(listener: () => void): () => void;
493
+ private notifyReadyChange;
445
494
  /**
446
495
  * Subscribe to framework-error events emitted by this coordinator.
447
496
  *
@@ -472,16 +521,44 @@ export declare class ToolkitCoordinator {
472
521
  private resolveSectionPersistence;
473
522
  private setupStatePersistenceHooks;
474
523
  private ensureStateLoaded;
524
+ /** Whether the toolkit this coordinator binds to may still supply a registry. */
525
+ private toolRegistryPending;
526
+ private reportMissingTTSProvider;
527
+ /**
528
+ * Take the registry of the toolkit this coordinator is bound to, when the host
529
+ * constructed it without one: the config is validated against it, its
530
+ * providers register, and text-to-speech re-initializes through it if it
531
+ * already started. The toolkit elements call this on binding, and again when
532
+ * their registry changes. A registry passed at construction stands, and the
533
+ * first registry adopted wins; `null` records a toolkit without one, which
534
+ * reports the registry as missing and still adopts one that arrives later.
535
+ *
536
+ * @returns Whether `registry` was adopted.
537
+ */
538
+ adoptToolRegistry(registry: ToolRegistry | null): boolean;
475
539
  /**
476
540
  * Register tool providers in the registry
477
541
  */
478
542
  private _registerToolProviders;
479
543
  private getProviderDescriptorTools;
544
+ /**
545
+ * Register the provider `tool`'s descriptor creates for the tool's current
546
+ * config under the tool's id, unless the tool is disabled or, without
547
+ * `replace`, a provider is registered under that id. A descriptor that throws
548
+ * is reported the way a failed registration is.
549
+ */
480
550
  private registerProviderFromTool;
481
551
  private createToolTelemetryForwarder;
482
552
  private addToolTelemetryReporter;
483
553
  private registerProvider;
484
- ensureProviderReady(providerId: string): Promise<ToolProviderApi>;
554
+ /**
555
+ * A console warning and a `provider-register` framework error, under the
556
+ * start-failure policy every other tool failure follows.
557
+ */
558
+ private reportProviderRegisterFailure;
559
+ ensureProviderReady(toolId: string): Promise<ToolProviderApi>;
560
+ /** `fallbackFollows`: the caller recovers from a failure on its own. */
561
+ private initializeProvider;
485
562
  setHooks(hooks: ToolkitCoordinatorHooks): void;
486
563
  subscribeTelemetry(listener: ToolkitTelemetryListener): () => void;
487
564
  getSectionController(args: {
@@ -565,17 +642,31 @@ export declare class ToolkitCoordinator {
565
642
  attemptId?: string;
566
643
  input?: unknown;
567
644
  updateExisting?: boolean;
645
+ initialSession?: SectionControllerSessionState | null;
568
646
  createDefaultController: () => SectionControllerHandle | Promise<SectionControllerHandle>;
569
647
  }): Promise<SectionControllerHandle>;
570
648
  private resolveExistingSectionController;
571
649
  private createSectionControllerContext;
572
650
  private initializeNewSectionController;
651
+ /**
652
+ * Apply a host-supplied session to a controller that is already published,
653
+ * under the rules `resolveSectionSessionAssignment` sets: an equal session is a
654
+ * no-op and recorded responses are not replaced by response-free ones.
655
+ */
656
+ private assignSessionToPublishedController;
573
657
  private createSectionControllerRetirementError;
574
658
  private retireUnpublishedSectionControllerIfNeeded;
575
659
  private cleanupUnpublishedSectionController;
576
660
  private retirePublishedSectionControllerIfNeeded;
577
661
  private finalizeSectionControllerReady;
578
662
  private handleSectionControllerInitError;
663
+ /**
664
+ * A section that fails to start has no controller of its own to emit its
665
+ * `section-error`, and the host's subscriptions are already off the outgoing
666
+ * section, so the coordinator delivers the error to them while that section
667
+ * is still the one requested.
668
+ */
669
+ private deliverSectionStartError;
579
670
  disposeSectionController(args: {
580
671
  sectionId: string;
581
672
  attemptId?: string;
@@ -597,46 +688,41 @@ export declare class ToolkitCoordinator {
597
688
  /**
598
689
  * Initialize TTS service with provider
599
690
  */
600
- ensureTTSReady(config?: TTSToolConfig): Promise<void>;
691
+ ensureTTSReady(config?: TextToSpeechToolProviderConfig): Promise<void>;
601
692
  private waitForPendingTTSReconfigure;
602
693
  private _initializeTTS;
603
694
  private resolveTTSToolConfig;
604
695
  private initializeTTSService;
605
- private ensureBrowserVoicesReady;
696
+ waitUntilReady(): Promise<void>;
697
+ isReady(): boolean;
606
698
  /**
607
- * Get all services as a bundle for section player convenience.
608
- * Section player can extract and pass services to child components.
699
+ * Readiness waits for text-to-speech when it is enabled and either starts
700
+ * eagerly or is granted: a granted read-aloud fails before the learner starts.
609
701
  */
610
- getServiceBundle(): ToolkitServiceBundle;
702
+ private ttsRequiredForReadiness;
611
703
  /**
612
- * Get a tool provider from the registry
613
- *
614
- * @param providerId Provider identifier
615
- * @returns Tool provider instance
704
+ * Starts text-to-speech for readiness. A failure policy does not grant leaves
705
+ * the tool degraded, reporting itself unavailable, and readiness settles; a
706
+ * granted tool's failure rejects.
616
707
  */
617
- getToolProvider(providerId: string): Promise<ToolProviderApi<any, any>>;
618
- waitUntilReady(): Promise<void>;
619
- isReady(): boolean;
620
- getInitStatus(): ToolkitInitStatus;
708
+ private startTTSForReadiness;
621
709
  private getTTSConfigFromProviders;
622
710
  private assertCanonicalToolId;
623
711
  private installToolContextResolvers;
624
- setToolContextResolvers(resolvers: ToolContextResolverMap | null | undefined): void;
625
- private notifyToolContextResolverChange;
626
712
  /**
627
- * Check if a tool is enabled.
628
- * Tools are enabled by default unless explicitly disabled.
629
- *
630
- * @param toolId Tool identifier (e.g., 'textToSpeech', 'answerEliminator')
631
- * @returns True if tool is enabled
713
+ * Replace all host-owned render-context resolvers. The toolkit element
714
+ * calls this from `runtime.toolContextResolvers`; it is not on
715
+ * `ToolkitCoordinatorApi`.
632
716
  */
633
- isToolEnabled(toolId: string): boolean;
717
+ setToolContextResolvers(resolvers: ToolContextResolverMap | null | undefined): void;
718
+ private notifyToolContextResolverChange;
634
719
  /**
635
720
  * Get tool configuration.
636
721
  *
637
722
  * @param toolId Tool identifier
638
723
  * @returns Tool configuration or null if not configured
639
724
  */
725
+ getToolConfig(toolId: "textToSpeech"): TextToSpeechToolProviderConfig | null;
640
726
  getToolConfig(toolId: string): ToolProviderConfig | null;
641
727
  /**
642
728
  * Update tool configuration.
@@ -645,27 +731,38 @@ export declare class ToolkitCoordinator {
645
731
  * @param toolId Tool identifier
646
732
  * @param updates Partial configuration updates
647
733
  */
648
- updateToolConfig(toolId: "textToSpeech", updates: Partial<TTSToolConfig>): void;
734
+ updateToolConfig(toolId: "textToSpeech", updates: Partial<TextToSpeechToolProviderConfig>): void;
649
735
  updateToolConfig(toolId: string, updates: Partial<ToolProviderConfig>): void;
650
736
  /**
651
- * Update the enabled tool list for one placement level.
737
+ * Patch one or more placement levels in the canonical tools config.
652
738
  *
653
739
  * This is the generic placement companion to {@link updateToolConfig}:
654
740
  * it validates the next canonical tools config, keeps the policy
655
741
  * engine in lockstep, and emits the same policy-change event used by
656
742
  * live toolbars/debug panels.
657
743
  */
658
- updateToolPlacement(level: ToolPlacementLevel, toolIds: string[]): void;
659
- /**
660
- * Patch one or more placement levels in the canonical tools config.
661
- */
662
744
  updateToolsPlacement(partial: ToolPlacementConfig): void;
663
745
  /**
664
746
  * Resolve the visible tool set for a given placement level + scope.
665
747
  *
666
- * Thin shim over the owned tool-policy engine.
748
+ * Delegates to the owned tool-policy engine and logs the decision's
749
+ * diagnostics through {@link warnPolicyDiagnostics}.
667
750
  */
668
751
  decideToolPolicy(request: ToolPolicyDecisionRequest): ToolPolicyDecision;
752
+ /**
753
+ * Log each policy diagnostic as a console warning, once per code and tool
754
+ * id, and per item for `tool-policy.itemSettingNotApplied`. Decisions re-run
755
+ * on every input change, so a conflict would otherwise repeat on each.
756
+ */
757
+ private warnPolicyDiagnostics;
758
+ /**
759
+ * File a mounted item's policy settings (`requiredTools`, `restrictedTools`,
760
+ * `toolParameters`) under its canonical id. They govern the decisions scoped
761
+ * to that item: its own item-level toolbar, and the feature decisions its
762
+ * content asks with the item's scope. `pie-item-scope` registers them from
763
+ * its `settings` property; the returned function withdraws them.
764
+ */
765
+ registerItemSettings(itemId: string, settings: ItemSettings): () => void;
669
766
  /**
670
767
  * Resolve eligibility for one PNP/AfA feature id, independent of toolbar
671
768
  * placement.
@@ -679,14 +776,23 @@ export declare class ToolkitCoordinator {
679
776
  * capability it asks about, which is indistinguishable from a student who was
680
777
  * properly declined — so without this, forgetting {@link updateAssessment}
681
778
  * presents as an accommodation that silently never appears.
779
+ *
780
+ * A coordinator built with `assessmentOptional` reports only while PNP
781
+ * enforcement is explicitly `"on"`. Its toolkit binds whatever assessment the
782
+ * host gave, usually none, and a host that passes no profile and leaves
783
+ * enforcement unset or `"off"` has asked for no accommodation.
784
+ *
785
+ * `scope` is the surface asking; an item's scope brings in that item's
786
+ * registered settings ({@link registerItemSettings}).
682
787
  */
683
- decideFeaturePolicy(featureId: string): FeaturePolicyDecision;
788
+ decideFeaturePolicy(featureId: string, scope?: ToolScope): FeaturePolicyDecision;
684
789
  /**
685
790
  * Subscribe to policy-engine change events. Fires whenever the
686
791
  * coordinator's bound inputs change (`updateToolConfig`,
687
- * `updateToolPlacement`, `updateAssessment`, `updateCurrentItemRef`,
688
- * `setPnpEnforcement`) or a custom `PolicySource` is registered /
689
- * removed via {@link registerPolicySource}.
792
+ * `updateToolsPlacement`, `updateAssessment`, `setPnpEnforcement`), an
793
+ * item's settings are registered or withdrawn ({@link registerItemSettings}),
794
+ * or a custom `PolicySource` is registered / removed via
795
+ * {@link registerPolicySource}.
690
796
  *
691
797
  * The listener receives a `ToolPolicyChangeEvent` with the event
692
798
  * `reason` and a frozen snapshot of the engine inputs. Listeners
@@ -712,31 +818,20 @@ export declare class ToolkitCoordinator {
712
818
  /**
713
819
  * Bind (or clear) the active assessment for PNP/profile policy decisions.
714
820
  *
715
- * Under auto-mode (no host override via {@link setPnpEnforcement}),
716
- * the coordinator promotes the engine to `pnpEnforcement: "on"`
717
- * iff the assessment carries any profile precedence material
718
- * (`personalNeedsProfile`, `settings.districtPolicy`,
719
- * `settings.testAdministration`) or the currently-bound item ref
720
- * carries item-level profile policy inputs. A bare assessment record (just
821
+ * Under auto-mode (no host override via {@link setPnpEnforcement}), a
822
+ * decision enforces PNP/profile policy iff the assessment carries profile
823
+ * precedence material (`personalNeedsProfile`, `settings.districtPolicy`,
824
+ * `settings.testAdministration`), or the decision is scoped to an item whose
825
+ * settings carry item-level policy inputs. A bare assessment record (just
721
826
  * `id` / `name`, no PNP, no settings) keeps `"off"`.
722
827
  *
723
828
  * The host override set via {@link setPnpEnforcement} is sticky
724
- * across assessment swaps; calling with `null` clears the binding
725
- * and re-runs the auto-mode helper.
829
+ * across assessment swaps.
726
830
  */
727
831
  updateAssessment(assessment: AssessmentEntity | null): void;
728
832
  /**
729
- * Bind (or clear) the current item reference for policy decisions.
730
- *
731
- * Used by item-level profile gates (item `requiredTools` /
732
- * `restrictedTools` / `toolParameters`). Item-level profile material
733
- * also feeds {@link resolveEffectivePnpEnforcement} — navigating
734
- * to an item with profile settings can flip auto-mode to `"on"` even
735
- * when the parent assessment carries no profile block of its own.
736
- */
737
- updateCurrentItemRef(itemRef: AssessmentItemRef | null): void;
738
- /**
739
- * Override the auto-mode PNP/profile enforcement decision.
833
+ * Override the auto-mode PNP/profile enforcement decision; `null` returns
834
+ * to auto-mode.
740
835
  */
741
836
  setPnpEnforcement(mode: PnpEnforcementMode | null): void;
742
837
  /**
@@ -757,19 +852,10 @@ export declare class ToolkitCoordinator {
757
852
  * compose with the built-in PNP policy source).
758
853
  */
759
854
  registerPolicySource(source: PolicySource): () => void;
760
- /**
761
- * Register a host-owned resolver for one tool's render context.
762
- *
763
- * Resolvers are evaluated only for tools that already survived the
764
- * framework policy pipeline. They can hide the tool for the current
765
- * scope or attach render params consumed by the packaged registration;
766
- * they cannot re-enable tools blocked by placement, provider config,
767
- * host policy, or PNP/profile rules.
768
- */
769
- registerToolContextResolver(toolId: string, resolver: ToolContextResolver): () => void;
770
855
  hasToolContextResolver(toolId: string): boolean;
771
856
  resolveToolContext(context: ToolContextResolverContext): ResolvedToolContext | null;
772
857
  onToolContextResolverChange(listener: () => void): () => void;
858
+ getToolRegistry(): ToolRegistry;
773
859
  /**
774
860
  * Claim requests for one placement level. Called by a toolbar on mount.
775
861
  */
@@ -788,26 +874,26 @@ export declare class ToolkitCoordinator {
788
874
  * surface, and a host that swapped the registry for one without the tool would
789
875
  * otherwise lose the whole surface to an exception over an absent action.
790
876
  */
791
- canRequestTool(toolId: string, level?: ToolOpenRequest["level"]): boolean;
877
+ canRequestTool(toolId: string, level?: ToolOpenRequest["level"], scopeId?: string): boolean;
792
878
  onToolRequestTargetsChange(listener: () => void): () => void;
793
- /**
794
- * Compute the effective PNP/profile enforcement mode given the explicit
795
- * host override and the auto-mode helper.
796
- *
797
- * Auto-mode (no override) defers to
798
- * {@link resolveDefaultPnpEnforcement}, which returns `"on"`
799
- * exactly when the bound assessment or current item ref carries
800
- * profile precedence material (PNP, district policy, test
801
- * administration, item-level required/restricted/parameters), and
802
- * `"off"` otherwise. Profile gates engage the moment profile material
803
- * is present.
804
- */
805
- private resolveEffectivePnpEnforcement;
806
879
  private resolveConfiguredPnpEnforcement;
807
880
  /**
808
881
  * Apply tool configuration changes to underlying services.
809
882
  * Called after updateToolConfig().
810
883
  */
811
884
  private _applyToolConfigChange;
885
+ /**
886
+ * Register the provider a tool's updated config builds, replacing the one
887
+ * registered under the tool's id. Registration completes before this returns,
888
+ * so a check on the policy change the update dispatched finds the new provider.
889
+ */
890
+ private _registerChangedToolProvider;
891
+ /**
892
+ * Re-register the text-to-speech provider for the current config and registry, then
893
+ * re-initialize unless initialization is lazy. An initialization already
894
+ * running finishes first: it would otherwise mark its provider ready after
895
+ * the reset.
896
+ */
897
+ private scheduleTTSReconfigure;
812
898
  private _reconfigureTTSProvider;
813
899
  }