@pie-players/pie-assessment-toolkit 0.2.7 → 0.2.9
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.
- package/README.md +200 -67
- package/dist/attempt/TestSession.d.ts +23 -21
- package/dist/attempt/TestSession.d.ts.map +1 -1
- package/dist/attempt/TestSession.js +17 -15
- package/dist/attempt/TestSession.js.map +1 -1
- package/dist/attempt/adapters/activity-to-test-attempt-session.d.ts +50 -0
- package/dist/attempt/adapters/activity-to-test-attempt-session.d.ts.map +1 -0
- package/dist/attempt/adapters/activity-to-test-attempt-session.js +135 -0
- package/dist/attempt/adapters/activity-to-test-attempt-session.js.map +1 -0
- package/dist/components/ItemToolBar.custom-element.js +628 -0
- package/dist/components/PieAssessmentToolkit.custom-element.js +670 -0
- package/dist/components/item-toolbar-element.d.ts +3 -0
- package/dist/components/item-toolbar-element.d.ts.map +1 -0
- package/dist/components/item-toolbar-element.js +2 -0
- package/dist/components/item-toolbar-element.js.map +1 -0
- package/dist/components/pie-assessment-toolkit-element.d.ts +3 -0
- package/dist/components/pie-assessment-toolkit-element.d.ts.map +1 -0
- package/dist/components/pie-assessment-toolkit-element.js +2 -0
- package/dist/components/pie-assessment-toolkit-element.js.map +1 -0
- package/dist/context/assessment-toolkit-context.d.ts +52 -0
- package/dist/context/assessment-toolkit-context.d.ts.map +1 -0
- package/dist/context/assessment-toolkit-context.js +6 -0
- package/dist/context/assessment-toolkit-context.js.map +1 -0
- package/dist/context/runtime-context-consumer.d.ts +14 -0
- package/dist/context/runtime-context-consumer.d.ts.map +1 -0
- package/dist/context/runtime-context-consumer.js +52 -0
- package/dist/context/runtime-context-consumer.js.map +1 -0
- package/dist/index.d.ts +16 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -11
- package/dist/index.js.map +1 -1
- package/dist/runtime/RuntimeRegistry.d.ts +13 -0
- package/dist/runtime/RuntimeRegistry.d.ts.map +1 -0
- package/dist/runtime/RuntimeRegistry.js +50 -0
- package/dist/runtime/RuntimeRegistry.js.map +1 -0
- package/dist/runtime/SectionRuntimeEngine.d.ts +45 -0
- package/dist/runtime/SectionRuntimeEngine.d.ts.map +1 -0
- package/dist/runtime/SectionRuntimeEngine.js +81 -0
- package/dist/runtime/SectionRuntimeEngine.js.map +1 -0
- package/dist/runtime/registration-events.d.ts +19 -0
- package/dist/runtime/registration-events.d.ts.map +1 -0
- package/dist/runtime/registration-events.js +4 -0
- package/dist/runtime/registration-events.js.map +1 -0
- package/dist/runtime/runtime-event-guards.d.ts +3 -0
- package/dist/runtime/runtime-event-guards.d.ts.map +1 -0
- package/dist/runtime/runtime-event-guards.js +9 -0
- package/dist/runtime/runtime-event-guards.js.map +1 -0
- package/dist/runtime/tool-host-contract.d.ts +30 -0
- package/dist/runtime/tool-host-contract.d.ts.map +1 -0
- package/dist/runtime/tool-host-contract.js +48 -0
- package/dist/runtime/tool-host-contract.js.map +1 -0
- package/dist/services/TTSService.d.ts +3 -1
- package/dist/services/TTSService.d.ts.map +1 -1
- package/dist/services/TTSService.js +13 -12
- package/dist/services/TTSService.js.map +1 -1
- package/dist/services/ThemeProvider.d.ts +1 -0
- package/dist/services/ThemeProvider.d.ts.map +1 -1
- package/dist/services/ThemeProvider.js +82 -46
- package/dist/services/ThemeProvider.js.map +1 -1
- package/dist/services/ToolConfigResolver.d.ts +1 -1
- package/dist/services/ToolConfigResolver.js +1 -1
- package/dist/services/ToolCoordinator.d.ts +1 -1
- package/dist/services/ToolCoordinator.d.ts.map +1 -1
- package/dist/services/ToolRegistry.d.ts +64 -67
- package/dist/services/ToolRegistry.d.ts.map +1 -1
- package/dist/services/ToolRegistry.js +72 -22
- package/dist/services/ToolRegistry.js.map +1 -1
- package/dist/services/ToolkitCoordinator.d.ts +106 -8
- package/dist/services/ToolkitCoordinator.d.ts.map +1 -1
- package/dist/services/ToolkitCoordinator.js +502 -71
- package/dist/services/ToolkitCoordinator.js.map +1 -1
- package/dist/services/createDefaultToolRegistry.d.ts +12 -7
- package/dist/services/createDefaultToolRegistry.d.ts.map +1 -1
- package/dist/services/createDefaultToolRegistry.js +6 -10
- package/dist/services/createDefaultToolRegistry.js.map +1 -1
- package/dist/services/defaultPersonalNeedsProfile.d.ts +4 -0
- package/dist/services/defaultPersonalNeedsProfile.d.ts.map +1 -0
- package/dist/services/defaultPersonalNeedsProfile.js +25 -0
- package/dist/services/defaultPersonalNeedsProfile.js.map +1 -0
- package/dist/services/interfaces.d.ts +61 -1
- package/dist/services/interfaces.d.ts.map +1 -1
- package/dist/services/interfaces.js.map +1 -1
- package/dist/services/pnp-standard-features.d.ts +3 -4
- package/dist/services/pnp-standard-features.d.ts.map +1 -1
- package/dist/services/pnp-standard-features.js +0 -3
- package/dist/services/pnp-standard-features.js.map +1 -1
- package/dist/services/section-controller-types.d.ts +32 -0
- package/dist/services/section-controller-types.d.ts.map +1 -0
- package/dist/services/section-controller-types.js +2 -0
- package/dist/services/section-controller-types.js.map +1 -0
- package/dist/services/tool-context.d.ts +4 -4
- package/dist/services/tool-context.d.ts.map +1 -1
- package/dist/services/tool-context.js +106 -17
- package/dist/services/tool-context.js.map +1 -1
- package/dist/services/tool-instance-id.d.ts +17 -0
- package/dist/services/tool-instance-id.d.ts.map +1 -0
- package/dist/services/tool-instance-id.js +61 -0
- package/dist/services/tool-instance-id.js.map +1 -0
- package/dist/services/tool-providers/IToolProvider.d.ts +2 -3
- package/dist/services/tool-providers/IToolProvider.d.ts.map +1 -1
- package/dist/services/tool-providers/IToolProvider.js +1 -2
- package/dist/services/tool-providers/IToolProvider.js.map +1 -1
- package/dist/services/tool-providers/MathJsToolProvider.d.ts +25 -0
- package/dist/services/tool-providers/MathJsToolProvider.d.ts.map +1 -0
- package/dist/services/tool-providers/MathJsToolProvider.js +53 -0
- package/dist/services/tool-providers/MathJsToolProvider.js.map +1 -0
- package/dist/services/tool-providers/index.d.ts +2 -0
- package/dist/services/tool-providers/index.d.ts.map +1 -1
- package/dist/services/tool-providers/index.js +1 -0
- package/dist/services/tool-providers/index.js.map +1 -1
- package/dist/services/tools-config-normalizer.d.ts +26 -0
- package/dist/services/tools-config-normalizer.d.ts.map +1 -0
- package/dist/services/tools-config-normalizer.js +63 -0
- package/dist/services/tools-config-normalizer.js.map +1 -0
- package/dist/tools/calculators/ti-provider.d.ts.map +1 -1
- package/dist/tools/calculators/ti-provider.js +127 -4
- package/dist/tools/calculators/ti-provider.js.map +1 -1
- package/dist/tools/client.d.ts +2 -1
- package/dist/tools/client.d.ts.map +1 -1
- package/dist/tools/client.js +2 -1
- package/dist/tools/client.js.map +1 -1
- package/dist/tools/default-tool-module-loaders.d.ts +9 -0
- package/dist/tools/default-tool-module-loaders.d.ts.map +1 -0
- package/dist/tools/default-tool-module-loaders.js +17 -0
- package/dist/tools/default-tool-module-loaders.js.map +1 -0
- package/dist/tools/index.d.ts +2 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/library-loader.d.ts +1 -1
- package/dist/tools/library-loader.d.ts.map +1 -1
- package/dist/tools/library-loader.js +7 -2
- package/dist/tools/library-loader.js.map +1 -1
- package/dist/tools/registrations/accessibility-tools.d.ts +1 -9
- package/dist/tools/registrations/accessibility-tools.d.ts.map +1 -1
- package/dist/tools/registrations/accessibility-tools.js +95 -113
- package/dist/tools/registrations/accessibility-tools.js.map +1 -1
- package/dist/tools/registrations/calculator.d.ts +2 -2
- package/dist/tools/registrations/calculator.d.ts.map +1 -1
- package/dist/tools/registrations/calculator.js +34 -55
- package/dist/tools/registrations/calculator.js.map +1 -1
- package/dist/tools/registrations/interaction-tools.d.ts.map +1 -1
- package/dist/tools/registrations/interaction-tools.js +77 -52
- package/dist/tools/registrations/interaction-tools.js.map +1 -1
- package/dist/tools/registrations/measurement-tools.d.ts.map +1 -1
- package/dist/tools/registrations/measurement-tools.js +63 -38
- package/dist/tools/registrations/measurement-tools.js.map +1 -1
- package/dist/tools/registrations/subject-specific-tools.d.ts.map +1 -1
- package/dist/tools/registrations/subject-specific-tools.js +63 -38
- package/dist/tools/registrations/subject-specific-tools.js.map +1 -1
- package/dist/tools/registrations/tts.d.ts +1 -1
- package/dist/tools/registrations/tts.d.ts.map +1 -1
- package/dist/tools/registrations/tts.js +27 -41
- package/dist/tools/registrations/tts.js.map +1 -1
- package/dist/tools/response-discovery.d.ts +12 -14
- package/dist/tools/response-discovery.d.ts.map +1 -1
- package/dist/tools/response-discovery.js +23 -80
- package/dist/tools/response-discovery.js.map +1 -1
- package/dist/tools/tool-tag-map.d.ts +3 -3
- package/dist/tools/tool-tag-map.d.ts.map +1 -1
- package/dist/tools/tool-tag-map.js +2 -3
- package/dist/tools/tool-tag-map.js.map +1 -1
- package/dist/tools/types.d.ts +3 -1
- package/dist/tools/types.d.ts.map +1 -1
- package/package.json +25 -28
- package/src/README.md +16 -32
- package/src/components/ItemToolBar.svelte +489 -0
- package/src/components/PNPProvenanceViewer.svelte +14 -4
- package/src/components/PieAssessmentToolkit.svelte +517 -0
- package/src/components/ToolButton.svelte +11 -11
- package/src/components/ToolButtonGroup.svelte +27 -11
- package/src/tools/README.md +6 -5
- package/src/tools/calculators/README.md +4 -4
- package/dist/player/AssessmentPlayer.d.ts +0 -397
- package/dist/player/AssessmentPlayer.d.ts.map +0 -1
- package/dist/player/AssessmentPlayer.js +0 -974
- package/dist/player/AssessmentPlayer.js.map +0 -1
- package/dist/player/index.d.ts +0 -17
- package/dist/player/index.d.ts.map +0 -1
- package/dist/player/index.js +0 -15
- package/dist/player/index.js.map +0 -1
- package/dist/player/navigation-types.d.ts +0 -63
- package/dist/player/navigation-types.d.ts.map +0 -1
- package/dist/player/navigation-types.js +0 -7
- package/dist/player/navigation-types.js.map +0 -1
- package/dist/player/qti-navigation.d.ts +0 -29
- package/dist/player/qti-navigation.d.ts.map +0 -1
- package/dist/player/qti-navigation.js +0 -160
- package/dist/player/qti-navigation.js.map +0 -1
- package/dist/reference-layout/index.d.ts +0 -19
- package/dist/reference-layout/index.d.ts.map +0 -1
- package/dist/reference-layout/index.js +0 -20
- package/dist/reference-layout/index.js.map +0 -1
- package/dist/services/AnnotationToolbarConfig.d.ts +0 -134
- package/dist/services/AnnotationToolbarConfig.d.ts.map +0 -1
- package/dist/services/AnnotationToolbarConfig.js +0 -100
- package/dist/services/AnnotationToolbarConfig.js.map +0 -1
- package/dist/services/AssessmentAuthoringService.d.ts +0 -60
- package/dist/services/AssessmentAuthoringService.d.ts.map +0 -1
- package/dist/services/AssessmentAuthoringService.js +0 -183
- package/dist/services/AssessmentAuthoringService.js.map +0 -1
- package/dist/services/PNPMapper.d.ts +0 -81
- package/dist/services/PNPMapper.d.ts.map +0 -1
- package/dist/services/PNPMapper.js +0 -108
- package/dist/services/PNPMapper.js.map +0 -1
- package/src/components/PNPProfileTester.example.svelte +0 -188
- package/src/components/PNPProfileTester.svelte +0 -397
- package/src/components/QuestionToolBar.svelte +0 -483
- package/src/player/AssessmentLayout.svelte +0 -68
- package/src/player/README.md +0 -154
- package/src/reference-layout/README.md +0 -135
- package/src/reference-layout/ReferenceLayout.svelte +0 -201
- package/src/reference-layout/components/AssessmentContent.svelte +0 -259
- package/src/reference-layout/components/AssessmentFooter.svelte +0 -89
- package/src/reference-layout/components/AssessmentHeader.svelte +0 -250
- package/src/reference-layout/components/AssessmentNavigation.svelte +0 -134
- package/src/reference-layout/components/AssessmentToolsBar.svelte +0 -176
- package/src/reference-layout/components/ItemPanel.svelte +0 -200
- package/src/reference-layout/components/NotesPanel.svelte +0 -179
- package/src/reference-layout/components/PassagePanel.svelte +0 -76
|
@@ -13,13 +13,14 @@
|
|
|
13
13
|
*
|
|
14
14
|
* Part of PIE Assessment Toolkit.
|
|
15
15
|
*/
|
|
16
|
+
import { normalizeToolsConfig, resolveToolsForLevel, } from "./tools-config-normalizer.js";
|
|
16
17
|
import { AccessibilityCatalogResolver } from "./AccessibilityCatalogResolver.js";
|
|
17
18
|
import { ElementToolStateStore } from "./ElementToolStateStore.js";
|
|
18
19
|
import { HighlightCoordinator } from "./HighlightCoordinator.js";
|
|
19
20
|
import { ToolCoordinator } from "./ToolCoordinator.js";
|
|
20
21
|
import { TTSService } from "./TTSService.js";
|
|
21
22
|
import { BrowserTTSProvider } from "./tts/browser-provider.js";
|
|
22
|
-
import { ToolProviderRegistry, DesmosToolProvider, TIToolProvider, TTSToolProvider, } from "./tool-providers/index.js";
|
|
23
|
+
import { ToolProviderRegistry, DesmosToolProvider, MathJsToolProvider, TIToolProvider, TTSToolProvider, } from "./tool-providers/index.js";
|
|
23
24
|
/**
|
|
24
25
|
* ToolkitCoordinator - Orchestrates all assessment toolkit services
|
|
25
26
|
*
|
|
@@ -54,106 +55,447 @@ export class ToolkitCoordinator {
|
|
|
54
55
|
elementToolStateStore;
|
|
55
56
|
catalogResolver;
|
|
56
57
|
toolProviderRegistry;
|
|
58
|
+
hooks;
|
|
59
|
+
lazyInit;
|
|
57
60
|
/** Track TTS initialization state */
|
|
58
61
|
ttsInitialized = false;
|
|
62
|
+
ttsInitPromise;
|
|
63
|
+
stateLoaded = false;
|
|
64
|
+
stateLoadPromise;
|
|
65
|
+
coordinatorReadyPromise;
|
|
66
|
+
coordinatorReadyNotified = false;
|
|
67
|
+
providerInitPromises = new Map();
|
|
68
|
+
sectionControllers = new Map();
|
|
69
|
+
sectionControllerInitPromises = new Map();
|
|
70
|
+
sectionPersistenceStrategies = new Map();
|
|
59
71
|
/** Callback for floating tools changes */
|
|
60
72
|
floatingToolsChangeCallback = null;
|
|
73
|
+
static resolveConfig(config) {
|
|
74
|
+
const normalized = normalizeToolsConfig(config.tools);
|
|
75
|
+
const defaultProviders = {
|
|
76
|
+
tts: {
|
|
77
|
+
enabled: true,
|
|
78
|
+
backend: "browser",
|
|
79
|
+
},
|
|
80
|
+
calculator: {
|
|
81
|
+
enabled: true,
|
|
82
|
+
provider: "desmos",
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
return {
|
|
86
|
+
...config,
|
|
87
|
+
tools: {
|
|
88
|
+
...normalized,
|
|
89
|
+
providers: {
|
|
90
|
+
...defaultProviders,
|
|
91
|
+
...normalized.providers,
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
accessibility: {
|
|
95
|
+
language: "en-US",
|
|
96
|
+
...(config.accessibility ?? {}),
|
|
97
|
+
catalogs: config.accessibility?.catalogs ?? [],
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
61
101
|
constructor(config) {
|
|
62
102
|
if (!config.assessmentId) {
|
|
63
103
|
throw new Error("ToolkitCoordinator requires assessmentId in config");
|
|
64
104
|
}
|
|
65
|
-
|
|
66
|
-
this.
|
|
105
|
+
const resolvedConfig = ToolkitCoordinator.resolveConfig(config);
|
|
106
|
+
this.assessmentId = resolvedConfig.assessmentId;
|
|
107
|
+
this.config = resolvedConfig;
|
|
108
|
+
this.hooks = resolvedConfig.hooks ?? {};
|
|
109
|
+
this.lazyInit = config.lazyInit === true;
|
|
67
110
|
// Initialize all services
|
|
68
111
|
this.toolCoordinator = new ToolCoordinator();
|
|
69
112
|
this.highlightCoordinator = new HighlightCoordinator();
|
|
70
113
|
this.elementToolStateStore = new ElementToolStateStore();
|
|
71
|
-
this.catalogResolver = new AccessibilityCatalogResolver(
|
|
114
|
+
this.catalogResolver = new AccessibilityCatalogResolver(resolvedConfig.accessibility?.catalogs || [], resolvedConfig.accessibility?.language || "en-US");
|
|
72
115
|
// Initialize tool provider registry
|
|
73
116
|
this.toolProviderRegistry = new ToolProviderRegistry();
|
|
74
117
|
this._registerToolProviders();
|
|
75
118
|
// Initialize TTS service based on config
|
|
76
119
|
this.ttsService = new TTSService();
|
|
77
|
-
|
|
78
|
-
if (
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
120
|
+
this.setupStatePersistenceHooks();
|
|
121
|
+
if (!this.lazyInit) {
|
|
122
|
+
void this.waitUntilReady().catch((err) => {
|
|
123
|
+
console.error("[ToolkitCoordinator] Failed eager initialization:", err);
|
|
124
|
+
this.handleError(err, { phase: "coordinator-ready" });
|
|
82
125
|
});
|
|
83
126
|
}
|
|
84
127
|
}
|
|
128
|
+
async emitTelemetry(eventName, payload) {
|
|
129
|
+
try {
|
|
130
|
+
await this.hooks.onTelemetry?.(eventName, payload);
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
console.warn("[ToolkitCoordinator] telemetry hook failed:", err);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
handleError(error, context) {
|
|
137
|
+
const normalized = error instanceof Error ? error : new Error(String(error));
|
|
138
|
+
try {
|
|
139
|
+
this.hooks.onError?.(normalized, context);
|
|
140
|
+
}
|
|
141
|
+
catch (hookError) {
|
|
142
|
+
console.warn("[ToolkitCoordinator] onError hook failed:", hookError);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
getSectionControllerMapKey(key) {
|
|
146
|
+
return `${key.assessmentId}::${key.sectionId}::${key.attemptId || ""}`;
|
|
147
|
+
}
|
|
148
|
+
createDefaultSectionPersistence() {
|
|
149
|
+
const storage = (() => {
|
|
150
|
+
try {
|
|
151
|
+
if (typeof window === "undefined")
|
|
152
|
+
return null;
|
|
153
|
+
return window.localStorage;
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
})();
|
|
159
|
+
const getStorageKey = (context) => {
|
|
160
|
+
const { assessmentId, sectionId, attemptId } = context.key;
|
|
161
|
+
return `pie:section-controller:v1:${assessmentId}:${sectionId}:${attemptId || "default"}`;
|
|
162
|
+
};
|
|
163
|
+
return {
|
|
164
|
+
async load(context) {
|
|
165
|
+
if (!storage)
|
|
166
|
+
return null;
|
|
167
|
+
const value = storage.getItem(getStorageKey(context));
|
|
168
|
+
if (!value)
|
|
169
|
+
return null;
|
|
170
|
+
try {
|
|
171
|
+
return JSON.parse(value);
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
async save(context, snapshot) {
|
|
178
|
+
if (!storage)
|
|
179
|
+
return;
|
|
180
|
+
storage.setItem(getStorageKey(context), JSON.stringify(snapshot));
|
|
181
|
+
},
|
|
182
|
+
async clear(context) {
|
|
183
|
+
if (!storage)
|
|
184
|
+
return;
|
|
185
|
+
storage.removeItem(getStorageKey(context));
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
async resolveSectionPersistence(context) {
|
|
190
|
+
const cacheKey = this.getSectionControllerMapKey(context.key);
|
|
191
|
+
const existing = this.sectionPersistenceStrategies.get(cacheKey);
|
|
192
|
+
if (existing)
|
|
193
|
+
return existing;
|
|
194
|
+
const defaults = {
|
|
195
|
+
createDefaultPersistence: () => this.createDefaultSectionPersistence(),
|
|
196
|
+
};
|
|
197
|
+
const strategy = (await this.hooks.createSectionPersistence?.(context, defaults)) ??
|
|
198
|
+
(await defaults.createDefaultPersistence());
|
|
199
|
+
this.sectionPersistenceStrategies.set(cacheKey, strategy);
|
|
200
|
+
return strategy;
|
|
201
|
+
}
|
|
202
|
+
setupStatePersistenceHooks() {
|
|
203
|
+
this.elementToolStateStore.setOnStateChange((state) => {
|
|
204
|
+
if (!this.hooks.saveToolState)
|
|
205
|
+
return;
|
|
206
|
+
void Promise.resolve(this.hooks.saveToolState(state)).catch((err) => {
|
|
207
|
+
this.handleError(err, { phase: "state-save" });
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
async ensureStateLoaded() {
|
|
212
|
+
if (this.stateLoaded)
|
|
213
|
+
return;
|
|
214
|
+
if (this.stateLoadPromise)
|
|
215
|
+
return this.stateLoadPromise;
|
|
216
|
+
this.stateLoadPromise = (async () => {
|
|
217
|
+
const loader = this.hooks.loadToolState;
|
|
218
|
+
if (!loader) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
try {
|
|
222
|
+
const state = await loader();
|
|
223
|
+
if (state && typeof state === "object") {
|
|
224
|
+
this.elementToolStateStore.loadState(state);
|
|
225
|
+
}
|
|
226
|
+
this.stateLoaded = true;
|
|
227
|
+
await this.emitTelemetry("tool-state-loaded", {
|
|
228
|
+
hasState: Boolean(state),
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
this.handleError(err, { phase: "state-load" });
|
|
233
|
+
}
|
|
234
|
+
})().finally(() => {
|
|
235
|
+
this.stateLoadPromise = undefined;
|
|
236
|
+
});
|
|
237
|
+
return this.stateLoadPromise;
|
|
238
|
+
}
|
|
85
239
|
/**
|
|
86
240
|
* Register tool providers in the registry
|
|
87
241
|
*/
|
|
88
242
|
_registerToolProviders() {
|
|
89
243
|
// Register TTS provider
|
|
90
|
-
const ttsConfig = this.config.tools?.tts;
|
|
244
|
+
const ttsConfig = this.config.tools?.providers?.tts;
|
|
91
245
|
if (ttsConfig?.enabled !== false) {
|
|
92
246
|
const backend = ttsConfig?.backend || "browser";
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
catch (error) {
|
|
108
|
-
console.warn("[ToolkitCoordinator] Failed to register TTS provider:", error);
|
|
109
|
-
}
|
|
247
|
+
void this.registerProvider("tts", {
|
|
248
|
+
provider: new TTSToolProvider(backend),
|
|
249
|
+
config: {
|
|
250
|
+
backend,
|
|
251
|
+
apiEndpoint: ttsConfig?.apiEndpoint,
|
|
252
|
+
voice: ttsConfig?.defaultVoice,
|
|
253
|
+
rate: ttsConfig?.rate,
|
|
254
|
+
pitch: ttsConfig?.pitch,
|
|
255
|
+
},
|
|
256
|
+
lazy: true,
|
|
257
|
+
authFetcher: ttsConfig?.authFetcher,
|
|
258
|
+
});
|
|
110
259
|
}
|
|
111
260
|
// Register calculator providers
|
|
112
|
-
const
|
|
113
|
-
const calculatorConfig = floatingTools?.calculator;
|
|
261
|
+
const calculatorConfig = this.config.tools?.providers?.calculator;
|
|
114
262
|
if (calculatorConfig?.enabled !== false) {
|
|
115
263
|
const provider = calculatorConfig?.provider || "desmos";
|
|
116
264
|
if (provider === "desmos") {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
catch (error) {
|
|
126
|
-
console.warn("[ToolkitCoordinator] Failed to register Desmos calculator provider:", error);
|
|
127
|
-
}
|
|
265
|
+
void this.registerProvider("calculator-desmos", {
|
|
266
|
+
provider: new DesmosToolProvider(),
|
|
267
|
+
config: {},
|
|
268
|
+
lazy: true,
|
|
269
|
+
authFetcher: calculatorConfig?.authFetcher,
|
|
270
|
+
});
|
|
128
271
|
}
|
|
129
272
|
else if (provider === "ti") {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
273
|
+
void this.registerProvider("calculator-ti", {
|
|
274
|
+
provider: new TIToolProvider(),
|
|
275
|
+
config: {},
|
|
276
|
+
lazy: true,
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
else if (provider === "mathjs") {
|
|
280
|
+
void this.registerProvider("calculator-mathjs", {
|
|
281
|
+
provider: new MathJsToolProvider(),
|
|
282
|
+
config: {},
|
|
283
|
+
lazy: true,
|
|
284
|
+
});
|
|
140
285
|
}
|
|
141
286
|
}
|
|
142
287
|
}
|
|
288
|
+
async registerProvider(providerId, config) {
|
|
289
|
+
try {
|
|
290
|
+
this.toolProviderRegistry.register(providerId, config);
|
|
291
|
+
const meta = {
|
|
292
|
+
providerId,
|
|
293
|
+
providerName: config.provider.providerName,
|
|
294
|
+
};
|
|
295
|
+
await this.hooks.onProviderRegistered?.(providerId, meta);
|
|
296
|
+
await this.emitTelemetry("provider-registered", {
|
|
297
|
+
providerId,
|
|
298
|
+
providerName: config.provider.providerName,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
catch (err) {
|
|
302
|
+
console.warn(`[ToolkitCoordinator] Failed to register provider "${providerId}":`, err);
|
|
303
|
+
this.handleError(err, { phase: "provider-register", providerId });
|
|
304
|
+
this.hooks.onProviderError?.(providerId, err, {
|
|
305
|
+
phase: "provider-register",
|
|
306
|
+
providerId,
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
async ensureProviderReady(providerId) {
|
|
311
|
+
const existing = this.providerInitPromises.get(providerId);
|
|
312
|
+
if (existing)
|
|
313
|
+
return existing;
|
|
314
|
+
const promise = (async () => {
|
|
315
|
+
const provider = await this.toolProviderRegistry.getProvider(providerId, false);
|
|
316
|
+
const meta = {
|
|
317
|
+
providerId,
|
|
318
|
+
providerName: provider.providerName,
|
|
319
|
+
};
|
|
320
|
+
try {
|
|
321
|
+
await this.hooks.onProviderInitStart?.(providerId, meta);
|
|
322
|
+
await this.toolProviderRegistry.initialize(providerId);
|
|
323
|
+
await this.hooks.onProviderReady?.(providerId, meta);
|
|
324
|
+
await this.emitTelemetry("provider-ready", { providerId });
|
|
325
|
+
return provider;
|
|
326
|
+
}
|
|
327
|
+
catch (err) {
|
|
328
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
329
|
+
this.hooks.onProviderError?.(providerId, error, {
|
|
330
|
+
phase: "provider-init",
|
|
331
|
+
providerId,
|
|
332
|
+
});
|
|
333
|
+
this.handleError(error, { phase: "provider-init", providerId });
|
|
334
|
+
throw error;
|
|
335
|
+
}
|
|
336
|
+
})().finally(() => {
|
|
337
|
+
this.providerInitPromises.delete(providerId);
|
|
338
|
+
});
|
|
339
|
+
this.providerInitPromises.set(providerId, promise);
|
|
340
|
+
return promise;
|
|
341
|
+
}
|
|
342
|
+
setHooks(hooks) {
|
|
343
|
+
Object.assign(this.hooks, hooks);
|
|
344
|
+
this.setupStatePersistenceHooks();
|
|
345
|
+
if (hooks.onCoordinatorReady && this.isReady()) {
|
|
346
|
+
void Promise.resolve(hooks.onCoordinatorReady(this)).catch((err) => {
|
|
347
|
+
this.handleError(err, { phase: "coordinator-ready" });
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
getSectionController(args) {
|
|
352
|
+
const key = {
|
|
353
|
+
assessmentId: this.assessmentId,
|
|
354
|
+
sectionId: args.sectionId,
|
|
355
|
+
attemptId: args.attemptId,
|
|
356
|
+
};
|
|
357
|
+
return this.sectionControllers.get(this.getSectionControllerMapKey(key));
|
|
358
|
+
}
|
|
359
|
+
async getOrCreateSectionController(args) {
|
|
360
|
+
const key = {
|
|
361
|
+
assessmentId: this.assessmentId,
|
|
362
|
+
sectionId: args.sectionId,
|
|
363
|
+
attemptId: args.attemptId,
|
|
364
|
+
};
|
|
365
|
+
const mapKey = this.getSectionControllerMapKey(key);
|
|
366
|
+
const existingController = this.sectionControllers.get(mapKey);
|
|
367
|
+
if (existingController) {
|
|
368
|
+
if (args.updateExisting !== false) {
|
|
369
|
+
await existingController.updateInput?.(args.input);
|
|
370
|
+
}
|
|
371
|
+
return existingController;
|
|
372
|
+
}
|
|
373
|
+
const existingPromise = this.sectionControllerInitPromises.get(mapKey);
|
|
374
|
+
if (existingPromise)
|
|
375
|
+
return existingPromise;
|
|
376
|
+
const initPromise = (async () => {
|
|
377
|
+
const context = {
|
|
378
|
+
key,
|
|
379
|
+
coordinator: this,
|
|
380
|
+
input: args.input,
|
|
381
|
+
};
|
|
382
|
+
const persistence = await this.resolveSectionPersistence(context);
|
|
383
|
+
const defaults = {
|
|
384
|
+
createDefaultController: args.createDefaultController,
|
|
385
|
+
};
|
|
386
|
+
const controller = (await this.hooks.createSectionController?.(context, defaults)) ??
|
|
387
|
+
(await defaults.createDefaultController());
|
|
388
|
+
await controller.setPersistenceStrategy?.(persistence);
|
|
389
|
+
await controller.setPersistenceContext?.(context);
|
|
390
|
+
await controller.initialize?.(args.input);
|
|
391
|
+
await controller.hydrate?.();
|
|
392
|
+
this.sectionControllers.set(mapKey, controller);
|
|
393
|
+
await this.hooks.onSectionControllerReady?.(context, controller);
|
|
394
|
+
await this.emitTelemetry("section-controller-ready", {
|
|
395
|
+
assessmentId: key.assessmentId,
|
|
396
|
+
sectionId: key.sectionId,
|
|
397
|
+
attemptId: key.attemptId,
|
|
398
|
+
});
|
|
399
|
+
return controller;
|
|
400
|
+
})().catch((err) => {
|
|
401
|
+
this.handleError(err, {
|
|
402
|
+
phase: "section-controller-init",
|
|
403
|
+
details: {
|
|
404
|
+
sectionId: args.sectionId,
|
|
405
|
+
attemptId: args.attemptId,
|
|
406
|
+
},
|
|
407
|
+
});
|
|
408
|
+
throw err;
|
|
409
|
+
}).finally(() => {
|
|
410
|
+
this.sectionControllerInitPromises.delete(mapKey);
|
|
411
|
+
});
|
|
412
|
+
this.sectionControllerInitPromises.set(mapKey, initPromise);
|
|
413
|
+
return initPromise;
|
|
414
|
+
}
|
|
415
|
+
async disposeSectionController(args) {
|
|
416
|
+
const key = {
|
|
417
|
+
assessmentId: this.assessmentId,
|
|
418
|
+
sectionId: args.sectionId,
|
|
419
|
+
attemptId: args.attemptId,
|
|
420
|
+
};
|
|
421
|
+
const mapKey = this.getSectionControllerMapKey(key);
|
|
422
|
+
const controller = this.sectionControllers.get(mapKey);
|
|
423
|
+
if (!controller)
|
|
424
|
+
return;
|
|
425
|
+
const context = {
|
|
426
|
+
key,
|
|
427
|
+
coordinator: this,
|
|
428
|
+
};
|
|
429
|
+
try {
|
|
430
|
+
if (args.persistBeforeDispose !== false) {
|
|
431
|
+
await controller.persist?.();
|
|
432
|
+
}
|
|
433
|
+
await controller.dispose?.();
|
|
434
|
+
await this.hooks.onSectionControllerDispose?.(context, controller);
|
|
435
|
+
await this.emitTelemetry("section-controller-disposed", {
|
|
436
|
+
assessmentId: key.assessmentId,
|
|
437
|
+
sectionId: key.sectionId,
|
|
438
|
+
attemptId: key.attemptId,
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
catch (err) {
|
|
442
|
+
this.handleError(err, {
|
|
443
|
+
phase: "section-controller-dispose",
|
|
444
|
+
details: {
|
|
445
|
+
sectionId: args.sectionId,
|
|
446
|
+
attemptId: args.attemptId,
|
|
447
|
+
},
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
finally {
|
|
451
|
+
this.sectionControllers.delete(mapKey);
|
|
452
|
+
if (args.clearPersistence) {
|
|
453
|
+
const strategy = this.sectionPersistenceStrategies.get(mapKey);
|
|
454
|
+
await strategy?.clear?.(context);
|
|
455
|
+
}
|
|
456
|
+
this.sectionPersistenceStrategies.delete(mapKey);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
143
459
|
/**
|
|
144
460
|
* Initialize TTS service with provider
|
|
145
461
|
*/
|
|
462
|
+
async ensureTTSReady(config) {
|
|
463
|
+
if (this.ttsInitialized)
|
|
464
|
+
return;
|
|
465
|
+
if (this.ttsInitPromise)
|
|
466
|
+
return this.ttsInitPromise;
|
|
467
|
+
this.ttsInitPromise = this._initializeTTS(config).finally(() => {
|
|
468
|
+
this.ttsInitPromise = undefined;
|
|
469
|
+
});
|
|
470
|
+
return this.ttsInitPromise;
|
|
471
|
+
}
|
|
146
472
|
async _initializeTTS(config) {
|
|
147
473
|
if (this.ttsInitialized)
|
|
148
474
|
return;
|
|
475
|
+
await this.hooks.onBeforeTTSInit?.({
|
|
476
|
+
phase: "tts-init",
|
|
477
|
+
details: {
|
|
478
|
+
backend: config?.backend,
|
|
479
|
+
},
|
|
480
|
+
});
|
|
481
|
+
await this.emitTelemetry("tts-init-start", {
|
|
482
|
+
backend: config?.backend ??
|
|
483
|
+
this.config.tools?.providers?.tts
|
|
484
|
+
?.backend ??
|
|
485
|
+
"browser",
|
|
486
|
+
});
|
|
149
487
|
// Try to use TTS provider from registry if available
|
|
150
488
|
if (this.toolProviderRegistry.has("tts")) {
|
|
151
489
|
try {
|
|
152
|
-
const ttsProvider = await this.
|
|
490
|
+
const ttsProvider = await this.ensureProviderReady("tts");
|
|
153
491
|
const providerInstance = await ttsProvider.createInstance();
|
|
154
492
|
await this.ttsService.initialize(providerInstance);
|
|
155
493
|
this.ttsService.setCatalogResolver(this.catalogResolver);
|
|
156
494
|
this.ttsInitialized = true;
|
|
495
|
+
await this.hooks.onTTSReady?.();
|
|
496
|
+
await this.emitTelemetry("tts-init-success", {
|
|
497
|
+
provider: "registry",
|
|
498
|
+
});
|
|
157
499
|
console.log("[ToolkitCoordinator] TTS initialized via ToolProviderRegistry");
|
|
158
500
|
return;
|
|
159
501
|
}
|
|
@@ -163,14 +505,24 @@ export class ToolkitCoordinator {
|
|
|
163
505
|
}
|
|
164
506
|
// Fallback to browser provider
|
|
165
507
|
const provider = new BrowserTTSProvider();
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
508
|
+
try {
|
|
509
|
+
await this.ttsService.initialize(provider, config);
|
|
510
|
+
this.ttsService.setCatalogResolver(this.catalogResolver);
|
|
511
|
+
this.ttsInitialized = true;
|
|
512
|
+
await this.hooks.onTTSReady?.();
|
|
513
|
+
await this.emitTelemetry("tts-init-success", {
|
|
514
|
+
provider: "browser-fallback",
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
catch (error) {
|
|
518
|
+
const normalized = error instanceof Error ? error : new Error(String(error));
|
|
519
|
+
this.hooks.onTTSError?.(normalized, { phase: "tts-init" });
|
|
520
|
+
this.handleError(normalized, { phase: "tts-init" });
|
|
521
|
+
await this.emitTelemetry("tts-init-error", {
|
|
522
|
+
message: normalized.message,
|
|
523
|
+
});
|
|
524
|
+
throw normalized;
|
|
172
525
|
}
|
|
173
|
-
this.ttsInitialized = true;
|
|
174
526
|
}
|
|
175
527
|
/**
|
|
176
528
|
* Get all services as a bundle for section player convenience.
|
|
@@ -193,7 +545,48 @@ export class ToolkitCoordinator {
|
|
|
193
545
|
* @returns Tool provider instance
|
|
194
546
|
*/
|
|
195
547
|
async getToolProvider(providerId) {
|
|
196
|
-
return this.
|
|
548
|
+
return this.ensureProviderReady(providerId);
|
|
549
|
+
}
|
|
550
|
+
async waitUntilReady() {
|
|
551
|
+
if (this.isReady())
|
|
552
|
+
return;
|
|
553
|
+
if (this.coordinatorReadyPromise)
|
|
554
|
+
return this.coordinatorReadyPromise;
|
|
555
|
+
this.coordinatorReadyPromise = (async () => {
|
|
556
|
+
await this.ensureStateLoaded();
|
|
557
|
+
const ttsConfig = this.config.tools?.providers?.tts;
|
|
558
|
+
if (ttsConfig?.enabled !== false) {
|
|
559
|
+
await this.ensureTTSReady(ttsConfig);
|
|
560
|
+
}
|
|
561
|
+
if (!this.coordinatorReadyNotified) {
|
|
562
|
+
this.coordinatorReadyNotified = true;
|
|
563
|
+
await this.hooks.onCoordinatorReady?.(this);
|
|
564
|
+
await this.emitTelemetry("coordinator-ready", {
|
|
565
|
+
assessmentId: this.assessmentId,
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
})().finally(() => {
|
|
569
|
+
this.coordinatorReadyPromise = undefined;
|
|
570
|
+
});
|
|
571
|
+
return this.coordinatorReadyPromise;
|
|
572
|
+
}
|
|
573
|
+
isReady() {
|
|
574
|
+
return this.getInitStatus().coordinator;
|
|
575
|
+
}
|
|
576
|
+
getInitStatus() {
|
|
577
|
+
const providers = {};
|
|
578
|
+
for (const providerId of this.toolProviderRegistry.getProviderIds()) {
|
|
579
|
+
providers[providerId] = this.toolProviderRegistry.isInitialized(providerId);
|
|
580
|
+
}
|
|
581
|
+
return {
|
|
582
|
+
tts: this.ttsInitialized,
|
|
583
|
+
stateLoaded: this.stateLoaded || !this.hooks.loadToolState,
|
|
584
|
+
coordinator: (this.stateLoaded || !this.hooks.loadToolState) &&
|
|
585
|
+
(this.ttsInitialized ||
|
|
586
|
+
this.config.tools?.providers?.tts
|
|
587
|
+
?.enabled === false),
|
|
588
|
+
providers,
|
|
589
|
+
};
|
|
197
590
|
}
|
|
198
591
|
/**
|
|
199
592
|
* Check if a tool is enabled.
|
|
@@ -203,7 +596,7 @@ export class ToolkitCoordinator {
|
|
|
203
596
|
* @returns True if tool is enabled
|
|
204
597
|
*/
|
|
205
598
|
isToolEnabled(toolId) {
|
|
206
|
-
const toolConfig = this.config.tools?.[toolId];
|
|
599
|
+
const toolConfig = this.config.tools?.providers?.[toolId];
|
|
207
600
|
// Enabled by default unless explicitly set to false
|
|
208
601
|
return toolConfig?.enabled !== false;
|
|
209
602
|
}
|
|
@@ -214,7 +607,7 @@ export class ToolkitCoordinator {
|
|
|
214
607
|
* @returns Tool configuration or null if not configured
|
|
215
608
|
*/
|
|
216
609
|
getToolConfig(toolId) {
|
|
217
|
-
return this.config.tools?.[toolId] || null;
|
|
610
|
+
return this.config.tools?.providers?.[toolId] || null;
|
|
218
611
|
}
|
|
219
612
|
/**
|
|
220
613
|
* Update tool configuration.
|
|
@@ -227,9 +620,12 @@ export class ToolkitCoordinator {
|
|
|
227
620
|
// Update config
|
|
228
621
|
const current = this.getToolConfig(toolId) || {};
|
|
229
622
|
if (!this.config.tools) {
|
|
230
|
-
this.config.tools =
|
|
623
|
+
this.config.tools = normalizeToolsConfig();
|
|
624
|
+
}
|
|
625
|
+
if (!this.config.tools.providers) {
|
|
626
|
+
this.config.tools.providers = {};
|
|
231
627
|
}
|
|
232
|
-
this.config.tools[toolId] = { ...current, ...updates };
|
|
628
|
+
this.config.tools.providers[toolId] = { ...current, ...updates };
|
|
233
629
|
// Apply configuration changes to services
|
|
234
630
|
this._applyToolConfigChange(toolId, updates);
|
|
235
631
|
}
|
|
@@ -241,12 +637,12 @@ export class ToolkitCoordinator {
|
|
|
241
637
|
*/
|
|
242
638
|
updateFloatingTools(toolIds) {
|
|
243
639
|
if (!this.config.tools) {
|
|
244
|
-
this.config.tools =
|
|
640
|
+
this.config.tools = normalizeToolsConfig();
|
|
245
641
|
}
|
|
246
|
-
if (!this.config.tools.
|
|
247
|
-
this.config.tools.
|
|
642
|
+
if (!this.config.tools.placement) {
|
|
643
|
+
this.config.tools.placement = normalizeToolsConfig().placement;
|
|
248
644
|
}
|
|
249
|
-
this.config.tools.
|
|
645
|
+
this.config.tools.placement.section = [...toolIds];
|
|
250
646
|
// Notify listener of change
|
|
251
647
|
if (this.floatingToolsChangeCallback) {
|
|
252
648
|
this.floatingToolsChangeCallback(toolIds);
|
|
@@ -258,7 +654,9 @@ export class ToolkitCoordinator {
|
|
|
258
654
|
* @returns Array of enabled tool IDs
|
|
259
655
|
*/
|
|
260
656
|
getFloatingTools() {
|
|
261
|
-
|
|
657
|
+
if (!this.config.tools)
|
|
658
|
+
return [];
|
|
659
|
+
return resolveToolsForLevel(this.config.tools, "section");
|
|
262
660
|
}
|
|
263
661
|
/**
|
|
264
662
|
* Set a callback to be notified when floating tools change.
|
|
@@ -279,12 +677,16 @@ export class ToolkitCoordinator {
|
|
|
279
677
|
* Apply tool configuration changes to underlying services.
|
|
280
678
|
* Called after updateToolConfig().
|
|
281
679
|
*/
|
|
282
|
-
_applyToolConfigChange(toolId,
|
|
680
|
+
_applyToolConfigChange(toolId, _updates) {
|
|
283
681
|
// Apply configuration changes based on tool
|
|
284
682
|
switch (toolId) {
|
|
285
683
|
case "tts":
|
|
286
|
-
|
|
287
|
-
|
|
684
|
+
void this._reconfigureTTSProvider().then(async () => {
|
|
685
|
+
const ttsConfig = this.config.tools?.providers?.tts;
|
|
686
|
+
if (!this.lazyInit && ttsConfig?.enabled !== false) {
|
|
687
|
+
await this.ensureTTSReady(ttsConfig);
|
|
688
|
+
}
|
|
689
|
+
});
|
|
288
690
|
break;
|
|
289
691
|
case "answerEliminator":
|
|
290
692
|
// Future: Could notify answer eliminator tools of strategy change
|
|
@@ -292,5 +694,34 @@ export class ToolkitCoordinator {
|
|
|
292
694
|
// Add cases for other tools as needed
|
|
293
695
|
}
|
|
294
696
|
}
|
|
697
|
+
async _reconfigureTTSProvider() {
|
|
698
|
+
this.ttsInitialized = false;
|
|
699
|
+
this.ttsInitPromise = undefined;
|
|
700
|
+
try {
|
|
701
|
+
this.ttsService.stop();
|
|
702
|
+
}
|
|
703
|
+
catch {
|
|
704
|
+
// noop: stop best effort
|
|
705
|
+
}
|
|
706
|
+
if (this.toolProviderRegistry.has("tts")) {
|
|
707
|
+
await this.toolProviderRegistry.unregister("tts");
|
|
708
|
+
}
|
|
709
|
+
const ttsConfig = this.config.tools?.providers?.tts;
|
|
710
|
+
if (ttsConfig?.enabled === false)
|
|
711
|
+
return;
|
|
712
|
+
const backend = ttsConfig?.backend || "browser";
|
|
713
|
+
await this.registerProvider("tts", {
|
|
714
|
+
provider: new TTSToolProvider(backend),
|
|
715
|
+
config: {
|
|
716
|
+
backend,
|
|
717
|
+
apiEndpoint: ttsConfig?.apiEndpoint,
|
|
718
|
+
voice: ttsConfig?.defaultVoice,
|
|
719
|
+
rate: ttsConfig?.rate,
|
|
720
|
+
pitch: ttsConfig?.pitch,
|
|
721
|
+
},
|
|
722
|
+
lazy: true,
|
|
723
|
+
authFetcher: ttsConfig?.authFetcher,
|
|
724
|
+
});
|
|
725
|
+
}
|
|
295
726
|
}
|
|
296
727
|
//# sourceMappingURL=ToolkitCoordinator.js.map
|