@pie-players/pie-assessment-toolkit 0.3.75 → 1.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +449 -541
- package/custom-elements.json +1315 -0
- package/dist/attempt/TestSession.d.ts +0 -1
- package/dist/attempt/TestSession.js +10 -5
- package/dist/components/ItemScope.custom-element.js +1 -1
- package/dist/components/ItemToolBar.custom-element.js +1 -1
- package/dist/components/PieAssessmentToolkit.custom-element.js +8 -8
- package/dist/components/SectionToolBar.custom-element.js +1 -1
- package/dist/components/chunks/{ItemToolBar-7tt7v2xp.js → ItemToolBar-3zrc4p3d.js} +4 -4
- package/dist/components/chunks/{ItemToolBar-jx38w99s.js → ItemToolBar-66hcwmfw.js} +2 -2
- package/dist/components/chunks/ItemToolBar-9gqhfxtn.js +40 -0
- package/dist/components/chunks/ItemToolBar-hzc5wyjp.js +2 -0
- package/dist/components/chunks/{ItemToolBar-97hx60z4.js → ItemToolBar-kkj69ptr.js} +1 -1
- package/dist/components/chunks/sre-engine-bj997w4b.js +1 -0
- package/dist/context/assessment-toolkit-context.d.ts +6 -0
- package/dist/index.d.ts +7 -7
- package/dist/index.js +4 -10
- package/dist/policy/core/PolicySource.d.ts +1 -1
- package/dist/policy/core/ToolPolicyEngine.d.ts +46 -7
- package/dist/policy/core/ToolPolicyEngine.js +73 -16
- package/dist/policy/core/compose-decision.d.ts +3 -3
- package/dist/policy/core/compose-decision.js +30 -30
- package/dist/policy/core/decision-types.d.ts +44 -32
- package/dist/policy/core/feature-decision.d.ts +17 -15
- package/dist/policy/core/feature-decision.js +11 -13
- package/dist/policy/core/pnp-policy-inputs.d.ts +5 -2
- package/dist/policy/core/pnp-policy-inputs.js +12 -32
- package/dist/policy/core/provenance.d.ts +1 -1
- package/dist/policy/core/tool-parameters.d.ts +11 -0
- package/dist/policy/core/tool-parameters.js +15 -0
- package/dist/policy/engine.d.ts +1 -1
- package/dist/policy/sources/PnpPolicySource.d.ts +14 -22
- package/dist/policy/sources/PnpPolicySource.js +30 -28
- package/dist/runtime/SectionControllerBinding.d.ts +6 -2
- package/dist/runtime/SectionControllerBinding.js +21 -15
- package/dist/runtime/adapter/subscriber-fanout.d.ts +0 -1
- package/dist/runtime/adapter/subscriber-fanout.js +1 -4
- package/dist/runtime/composition-emit-scheduler.d.ts +3 -3
- package/dist/runtime/composition-emit-scheduler.js +1 -1
- package/dist/runtime/content-region.d.ts +0 -4
- package/dist/runtime/content-region.js +2 -2
- package/dist/runtime/core/SectionEngineCore.d.ts +0 -2
- package/dist/runtime/core/SectionEngineCore.js +0 -4
- package/dist/runtime/core/cohort.d.ts +0 -5
- package/dist/runtime/core/cohort.js +0 -9
- package/dist/runtime/core/engine-output.d.ts +3 -2
- package/dist/runtime/core/engine-transition.js +3 -2
- package/dist/runtime/registration-events.d.ts +11 -14
- package/dist/runtime/runtime-id.d.ts +1 -1
- package/dist/runtime/runtime-id.js +1 -1
- package/dist/runtime/shell-scope.d.ts +4 -4
- package/dist/runtime/shell-scope.js +15 -9
- package/dist/runtime/tool-host-contract.d.ts +0 -4
- package/dist/runtime/tool-host-contract.js +1 -1
- package/dist/services/AccessibilityCatalogResolver.d.ts +21 -31
- package/dist/services/AccessibilityCatalogResolver.js +29 -42
- package/dist/services/ElementToolStateStore.d.ts +32 -61
- package/dist/services/ElementToolStateStore.js +37 -67
- package/dist/services/HighlightCoordinator.d.ts +9 -21
- package/dist/services/HighlightCoordinator.js +52 -80
- package/dist/services/RangeSerializer.d.ts +4 -35
- package/dist/services/RangeSerializer.js +4 -48
- package/dist/services/SSMLExtractor.d.ts +8 -31
- package/dist/services/SSMLExtractor.js +18 -40
- package/dist/services/TTSService.d.ts +49 -56
- package/dist/services/TTSService.js +308 -283
- package/dist/services/ToolCoordinator.d.ts +6 -49
- package/dist/services/ToolCoordinator.js +25 -61
- package/dist/services/ToolRegistry.d.ts +82 -80
- package/dist/services/ToolRegistry.js +91 -67
- package/dist/services/ToolkitCoordinator.d.ts +83 -81
- package/dist/services/ToolkitCoordinator.js +186 -174
- package/dist/services/framework-error.d.ts +30 -7
- package/dist/services/framework-error.js +10 -13
- package/dist/services/interfaces.d.ts +47 -71
- package/dist/services/section-controller-types.d.ts +7 -7
- package/dist/services/section-session-assignment.js +6 -8
- package/dist/services/spoken-audio-cards.d.ts +2 -4
- package/dist/services/spoken-audio-cards.js +2 -4
- package/dist/services/tool-config-validation.d.ts +5 -7
- package/dist/services/tool-config-validation.js +11 -26
- package/dist/services/tool-context.d.ts +7 -23
- package/dist/services/tool-context.js +99 -53
- package/dist/services/tool-failure.d.ts +30 -0
- package/dist/services/tool-failure.js +11 -0
- package/dist/services/tool-icons.d.ts +1 -2
- package/dist/services/tool-icons.js +2 -2
- package/dist/services/tool-instance-id.d.ts +8 -6
- package/dist/services/tool-instance-id.js +12 -18
- package/dist/services/tool-providers/TTSToolProvider.d.ts +6 -43
- package/dist/services/tool-providers/TTSToolProvider.js +7 -63
- package/dist/services/tool-providers/ToolProviderApi.d.ts +0 -7
- package/dist/services/tool-providers/ToolProviderRegistry.d.ts +7 -42
- package/dist/services/tool-providers/ToolProviderRegistry.js +21 -63
- package/dist/services/tool-request.d.ts +4 -0
- package/dist/services/tool-request.js +7 -2
- package/dist/services/toolbar-decided-tools.d.ts +1 -0
- package/dist/services/toolbar-decided-tools.js +1 -0
- package/dist/services/toolbar-items.js +2 -5
- package/dist/services/tools-config-normalizer.d.ts +18 -9
- package/dist/services/tools-config-normalizer.js +25 -19
- package/dist/services/tts/browser-provider.d.ts +2 -5
- package/dist/services/tts/browser-provider.js +4 -20
- package/dist/services/tts/catalog-span-alignment.js +14 -7
- package/dist/services/tts/flat-tree.d.ts +0 -7
- package/dist/services/tts/flat-tree.js +2 -2
- package/dist/services/tts/generated-speech/dom/to-chunk-inputs.d.ts +2 -2
- package/dist/services/tts/generated-speech/index.d.ts +1 -1
- package/dist/services/tts/generated-speech/index.js +1 -1
- package/dist/services/tts/generated-speech/types.d.ts +1 -1
- package/dist/services/tts/generated-speech/types.js +1 -1
- package/dist/services/tts/highlight-pipeline/create-highlight-plan.js +10 -12
- package/dist/services/tts/highlight-target-resolver.d.ts +12 -0
- package/dist/services/tts/math-aware-text-processing.js +10 -29
- package/dist/services/tts/math-speech.d.ts +1 -1
- package/dist/services/tts/math-speech.js +3 -0
- package/dist/services/tts/mathml-sanitization.d.ts +7 -0
- package/dist/services/tts/mathml-sanitization.js +9 -1
- package/dist/services/tts/provider-options.d.ts +12 -1
- package/dist/services/tts/ssml/spoken-text.js +1 -1
- package/dist/services/tts/start-failure.d.ts +0 -7
- package/dist/services/tts/start-failure.js +1 -1
- package/dist/services/tts/text-segmentation.d.ts +5 -0
- package/dist/services/tts/text-segmentation.js +13 -10
- package/dist/services/tts-runtime-config.d.ts +32 -12
- package/dist/services/tts-runtime-config.js +14 -20
- package/dist/tools/content-capability-resolution.d.ts +2 -2
- package/dist/tools/registration.d.ts +6 -5
- package/dist/tools/registration.js +10 -9
- package/dist/tools/registrations/toolbar-registration-helpers.d.ts +6 -0
- package/dist/tools/registrations/toolbar-registration-helpers.js +6 -0
- package/dist/tools/tool-surface-host.js +1 -8
- package/package.json +8 -6
- package/dist/components/chunks/ItemToolBar-bxwyhr5p.js +0 -2
- package/dist/components/chunks/ItemToolBar-rd2bb4p6.js +0 -40
- package/dist/components/chunks/sre-engine-jd8cc08x.js +0 -1
- package/dist/services/ContextVariableStore.d.ts +0 -113
- package/dist/services/ContextVariableStore.js +0 -206
- package/dist/services/tts-control-events.d.ts +0 -13
- package/dist/services/tts-control-events.js +0 -7
- package/dist/utils/logger.d.ts +0 -6
- package/dist/utils/logger.js +0 -10
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Centralized registry for managing tool providers.
|
|
5
5
|
* Handles initialization, authentication, and lazy loading.
|
|
6
|
-
*
|
|
7
|
-
* Part of PIE Assessment Toolkit.
|
|
8
6
|
*/
|
|
9
7
|
import type { ToolProviderApi, ToolCategory } from "./ToolProviderApi.js";
|
|
10
8
|
/**
|
|
@@ -36,7 +34,7 @@ export interface ToolProviderRegistration<TConfig = any> {
|
|
|
36
34
|
* @example
|
|
37
35
|
* ```typescript
|
|
38
36
|
* authFetcher: async () => {
|
|
39
|
-
* const response = await fetch('/api/desmos/
|
|
37
|
+
* const response = await fetch('/api/tools/desmos/auth');
|
|
40
38
|
* return response.json(); // { apiKey: '...' }
|
|
41
39
|
* }
|
|
42
40
|
* ```
|
|
@@ -90,9 +88,6 @@ export declare class ToolProviderRegistry {
|
|
|
90
88
|
* A registration under an id already registered replaces it: the replaced
|
|
91
89
|
* provider is destroyed once a start in progress settles, and a caller
|
|
92
90
|
* waiting on that start gets the replacement.
|
|
93
|
-
*
|
|
94
|
-
* @param toolId Id of the tool the provider serves
|
|
95
|
-
* @param config Provider configuration
|
|
96
91
|
*/
|
|
97
92
|
register(toolId: string, config: ToolProviderRegistration): void;
|
|
98
93
|
/**
|
|
@@ -100,10 +95,7 @@ export declare class ToolProviderRegistry {
|
|
|
100
95
|
*
|
|
101
96
|
* Fetches auth if needed and initializes the provider.
|
|
102
97
|
* Safe to call multiple times - subsequent calls wait for first initialization.
|
|
103
|
-
*
|
|
104
|
-
* @param toolId Tool whose provider to initialize
|
|
105
|
-
* @returns Promise that resolves when initialization complete
|
|
106
|
-
* @throws Error if provider not registered or initialization fails
|
|
98
|
+
* Throws when the provider is not registered or its initialization fails.
|
|
107
99
|
*/
|
|
108
100
|
initialize(toolId: string): Promise<void>;
|
|
109
101
|
/** Whether a registration replaced `provider` under `toolId`. */
|
|
@@ -117,51 +109,24 @@ export declare class ToolProviderRegistry {
|
|
|
117
109
|
* Get a provider instance
|
|
118
110
|
*
|
|
119
111
|
* Retrieves a registered provider. If autoInitialize is true and provider
|
|
120
|
-
* is not initialized, initializes it first.
|
|
121
|
-
*
|
|
122
|
-
* @param toolId Id of the tool the provider serves
|
|
123
|
-
* @param autoInitialize Auto-initialize if not ready (default: true)
|
|
124
|
-
* @returns Provider instance
|
|
125
|
-
* @throws Error if provider not registered
|
|
112
|
+
* is not initialized, initializes it first. Throws when the provider is not
|
|
113
|
+
* registered.
|
|
126
114
|
*/
|
|
127
115
|
getProvider<T extends ToolProviderApi = ToolProviderApi>(toolId: string, autoInitialize?: boolean): Promise<T>;
|
|
128
|
-
/**
|
|
129
|
-
* The ids of the tools whose provider is in `category`.
|
|
130
|
-
*
|
|
131
|
-
* @param category Tool category to filter by
|
|
132
|
-
*/
|
|
116
|
+
/** The ids of the tools whose provider is in `category`. */
|
|
133
117
|
getProvidersByCategory(category: ToolCategory): string[];
|
|
134
118
|
/**
|
|
135
119
|
* The ids of the tools with a registered provider.
|
|
136
120
|
*/
|
|
137
121
|
getProviderIds(): string[];
|
|
138
|
-
/**
|
|
139
|
-
* Check if provider is registered
|
|
140
|
-
*
|
|
141
|
-
* @param toolId Id of the tool the provider serves
|
|
142
|
-
* @returns true if provider is registered
|
|
143
|
-
*/
|
|
144
122
|
has(toolId: string): boolean;
|
|
145
|
-
/**
|
|
146
|
-
* Check if provider is initialized
|
|
147
|
-
*
|
|
148
|
-
* @param toolId Id of the tool the provider serves
|
|
149
|
-
* @returns true if provider is initialized
|
|
150
|
-
*/
|
|
151
123
|
isInitialized(toolId: string): boolean;
|
|
152
|
-
/**
|
|
153
|
-
* Check if provider is currently initializing
|
|
154
|
-
*
|
|
155
|
-
* @param toolId Id of the tool the provider serves
|
|
156
|
-
* @returns true if initialization in progress
|
|
157
|
-
*/
|
|
158
124
|
isInitializing(toolId: string): boolean;
|
|
159
125
|
/**
|
|
160
126
|
* Unregister and destroy a provider
|
|
161
127
|
*
|
|
162
|
-
* Removes the provider from the registry and calls its destroy method
|
|
163
|
-
*
|
|
164
|
-
* @param toolId Tool whose provider to unregister
|
|
128
|
+
* Removes the provider from the registry and calls its destroy method,
|
|
129
|
+
* after any start in progress settles.
|
|
165
130
|
*/
|
|
166
131
|
unregister(toolId: string): Promise<void>;
|
|
167
132
|
/**
|
|
@@ -3,12 +3,17 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Centralized registry for managing tool providers.
|
|
5
5
|
* Handles initialization, authentication, and lazy loading.
|
|
6
|
-
*
|
|
7
|
-
* Part of PIE Assessment Toolkit.
|
|
8
6
|
*/
|
|
9
7
|
import { createPieLogger, isGlobalDebugEnabled, } from "@pie-players/pie-players-shared/pie";
|
|
10
8
|
// Lifecycle lines need `window.PIE_DEBUG = true`, read on each line.
|
|
11
9
|
const logger = createPieLogger("ToolProviderRegistry", isGlobalDebugEnabled);
|
|
10
|
+
/** The `backend` a provider config names, for telemetry payloads. */
|
|
11
|
+
function telemetryBackend(value) {
|
|
12
|
+
const backend = value && typeof value === "object"
|
|
13
|
+
? value.backend
|
|
14
|
+
: undefined;
|
|
15
|
+
return typeof backend === "string" && backend ? backend : "unknown";
|
|
16
|
+
}
|
|
12
17
|
/**
|
|
13
18
|
* Tool Provider Registry
|
|
14
19
|
*
|
|
@@ -59,9 +64,6 @@ export class ToolProviderRegistry {
|
|
|
59
64
|
* A registration under an id already registered replaces it: the replaced
|
|
60
65
|
* provider is destroyed once a start in progress settles, and a caller
|
|
61
66
|
* waiting on that start gets the replacement.
|
|
62
|
-
*
|
|
63
|
-
* @param toolId Id of the tool the provider serves
|
|
64
|
-
* @param config Provider configuration
|
|
65
67
|
*/
|
|
66
68
|
register(toolId, config) {
|
|
67
69
|
const replaced = this.providers.get(toolId);
|
|
@@ -81,7 +83,6 @@ export class ToolProviderRegistry {
|
|
|
81
83
|
}
|
|
82
84
|
}
|
|
83
85
|
logger.debug(`${replaced ? "Replaced" : "Registered"} provider "${toolId}" (${config.provider.providerName})`);
|
|
84
|
-
// Initialize immediately if not lazy
|
|
85
86
|
if (config.lazy === false) {
|
|
86
87
|
this.initialize(toolId).catch((error) => {
|
|
87
88
|
console.error(`[ToolProviderRegistry] Failed to initialize provider "${toolId}":`, error);
|
|
@@ -93,22 +94,16 @@ export class ToolProviderRegistry {
|
|
|
93
94
|
*
|
|
94
95
|
* Fetches auth if needed and initializes the provider.
|
|
95
96
|
* Safe to call multiple times - subsequent calls wait for first initialization.
|
|
96
|
-
*
|
|
97
|
-
* @param toolId Tool whose provider to initialize
|
|
98
|
-
* @returns Promise that resolves when initialization complete
|
|
99
|
-
* @throws Error if provider not registered or initialization fails
|
|
97
|
+
* Throws when the provider is not registered or its initialization fails.
|
|
100
98
|
*/
|
|
101
99
|
async initialize(toolId) {
|
|
102
|
-
// Already initialized
|
|
103
100
|
if (this.initialized.get(toolId)) {
|
|
104
101
|
return;
|
|
105
102
|
}
|
|
106
|
-
// Initialization in progress - wait for it
|
|
107
103
|
const existingPromise = this.initializationPromises.get(toolId);
|
|
108
104
|
if (existingPromise) {
|
|
109
105
|
return existingPromise;
|
|
110
106
|
}
|
|
111
|
-
// Start new initialization
|
|
112
107
|
const provider = this.providers.get(toolId);
|
|
113
108
|
const initPromise = this._doInitialize(toolId);
|
|
114
109
|
this.initializationPromises.set(toolId, initPromise);
|
|
@@ -116,6 +111,8 @@ export class ToolProviderRegistry {
|
|
|
116
111
|
await initPromise;
|
|
117
112
|
}
|
|
118
113
|
catch (error) {
|
|
114
|
+
// When a registration replaced the provider mid-start, this caller
|
|
115
|
+
// gets the replacement, so the old start's failure is dropped.
|
|
119
116
|
if (!this.isReplaced(toolId, provider))
|
|
120
117
|
throw error;
|
|
121
118
|
}
|
|
@@ -150,26 +147,18 @@ export class ToolProviderRegistry {
|
|
|
150
147
|
if (!provider || !config) {
|
|
151
148
|
throw new Error(`[ToolProviderRegistry] Provider "${toolId}" not registered`);
|
|
152
149
|
}
|
|
153
|
-
// Start with base config
|
|
154
150
|
let providerConfig = { ...config.config };
|
|
155
|
-
const deriveBackend = (value) => {
|
|
156
|
-
const backend = value && typeof value === "object"
|
|
157
|
-
? value.backend
|
|
158
|
-
: undefined;
|
|
159
|
-
return typeof backend === "string" && backend ? backend : "unknown";
|
|
160
|
-
};
|
|
161
151
|
const providerInitStartedAt = Date.now();
|
|
162
152
|
await this.emitTelemetry(config, "pie-tool-init-start", {
|
|
163
153
|
toolId,
|
|
164
|
-
backend:
|
|
154
|
+
backend: telemetryBackend(providerConfig),
|
|
165
155
|
operation: "provider-initialize",
|
|
166
156
|
});
|
|
167
|
-
// Fetch auth if needed
|
|
168
157
|
if (provider.requiresAuth && config.authFetcher) {
|
|
169
158
|
const authFetchStartedAt = Date.now();
|
|
170
159
|
await this.emitTelemetry(config, "pie-tool-backend-call-start", {
|
|
171
160
|
toolId,
|
|
172
|
-
backend:
|
|
161
|
+
backend: telemetryBackend(providerConfig),
|
|
173
162
|
operation: "auth-fetch",
|
|
174
163
|
});
|
|
175
164
|
logger.debug(`Fetching auth for "${toolId}"...`);
|
|
@@ -178,7 +167,7 @@ export class ToolProviderRegistry {
|
|
|
178
167
|
providerConfig = { ...providerConfig, ...authData };
|
|
179
168
|
await this.emitTelemetry(config, "pie-tool-backend-call-success", {
|
|
180
169
|
toolId,
|
|
181
|
-
backend:
|
|
170
|
+
backend: telemetryBackend(providerConfig),
|
|
182
171
|
operation: "auth-fetch",
|
|
183
172
|
duration: Date.now() - authFetchStartedAt,
|
|
184
173
|
});
|
|
@@ -186,7 +175,7 @@ export class ToolProviderRegistry {
|
|
|
186
175
|
catch (error) {
|
|
187
176
|
await this.emitTelemetry(config, "pie-tool-backend-call-error", {
|
|
188
177
|
toolId,
|
|
189
|
-
backend:
|
|
178
|
+
backend: telemetryBackend(providerConfig),
|
|
190
179
|
operation: "auth-fetch",
|
|
191
180
|
duration: Date.now() - authFetchStartedAt,
|
|
192
181
|
errorType: "ProviderAuthFetchError",
|
|
@@ -196,7 +185,6 @@ export class ToolProviderRegistry {
|
|
|
196
185
|
throw new Error(`Failed to fetch auth credentials for provider "${toolId}"`);
|
|
197
186
|
}
|
|
198
187
|
}
|
|
199
|
-
// Initialize provider
|
|
200
188
|
try {
|
|
201
189
|
await provider.initialize(providerConfig);
|
|
202
190
|
if (this.providers.get(toolId) === provider) {
|
|
@@ -204,7 +192,7 @@ export class ToolProviderRegistry {
|
|
|
204
192
|
}
|
|
205
193
|
await this.emitTelemetry(config, "pie-tool-init-success", {
|
|
206
194
|
toolId,
|
|
207
|
-
backend:
|
|
195
|
+
backend: telemetryBackend(providerConfig),
|
|
208
196
|
operation: "provider-initialize",
|
|
209
197
|
duration: Date.now() - providerInitStartedAt,
|
|
210
198
|
});
|
|
@@ -213,7 +201,7 @@ export class ToolProviderRegistry {
|
|
|
213
201
|
catch (error) {
|
|
214
202
|
await this.emitTelemetry(config, "pie-tool-init-error", {
|
|
215
203
|
toolId,
|
|
216
|
-
backend:
|
|
204
|
+
backend: telemetryBackend(providerConfig),
|
|
217
205
|
operation: "provider-initialize",
|
|
218
206
|
duration: Date.now() - providerInitStartedAt,
|
|
219
207
|
errorType: "ProviderInitializationError",
|
|
@@ -227,12 +215,8 @@ export class ToolProviderRegistry {
|
|
|
227
215
|
* Get a provider instance
|
|
228
216
|
*
|
|
229
217
|
* Retrieves a registered provider. If autoInitialize is true and provider
|
|
230
|
-
* is not initialized, initializes it first.
|
|
231
|
-
*
|
|
232
|
-
* @param toolId Id of the tool the provider serves
|
|
233
|
-
* @param autoInitialize Auto-initialize if not ready (default: true)
|
|
234
|
-
* @returns Provider instance
|
|
235
|
-
* @throws Error if provider not registered
|
|
218
|
+
* is not initialized, initializes it first. Throws when the provider is not
|
|
219
|
+
* registered.
|
|
236
220
|
*/
|
|
237
221
|
async getProvider(toolId, autoInitialize = true) {
|
|
238
222
|
const provider = this.providers.get(toolId);
|
|
@@ -243,18 +227,13 @@ export class ToolProviderRegistry {
|
|
|
243
227
|
});
|
|
244
228
|
throw new Error(`[ToolProviderRegistry] Provider "${toolId}" not registered`);
|
|
245
229
|
}
|
|
246
|
-
// Auto-initialize if needed
|
|
247
230
|
if (autoInitialize && !this.initialized.get(toolId)) {
|
|
248
231
|
logger.debug("Auto-initializing provider:", toolId);
|
|
249
232
|
await this.initialize(toolId);
|
|
250
233
|
}
|
|
251
234
|
return provider;
|
|
252
235
|
}
|
|
253
|
-
/**
|
|
254
|
-
* The ids of the tools whose provider is in `category`.
|
|
255
|
-
*
|
|
256
|
-
* @param category Tool category to filter by
|
|
257
|
-
*/
|
|
236
|
+
/** The ids of the tools whose provider is in `category`. */
|
|
258
237
|
getProvidersByCategory(category) {
|
|
259
238
|
return Array.from(this.providers.entries())
|
|
260
239
|
.filter(([_, provider]) => provider.category === category)
|
|
@@ -266,44 +245,24 @@ export class ToolProviderRegistry {
|
|
|
266
245
|
getProviderIds() {
|
|
267
246
|
return Array.from(this.providers.keys());
|
|
268
247
|
}
|
|
269
|
-
/**
|
|
270
|
-
* Check if provider is registered
|
|
271
|
-
*
|
|
272
|
-
* @param toolId Id of the tool the provider serves
|
|
273
|
-
* @returns true if provider is registered
|
|
274
|
-
*/
|
|
275
248
|
has(toolId) {
|
|
276
249
|
return this.providers.has(toolId);
|
|
277
250
|
}
|
|
278
|
-
/**
|
|
279
|
-
* Check if provider is initialized
|
|
280
|
-
*
|
|
281
|
-
* @param toolId Id of the tool the provider serves
|
|
282
|
-
* @returns true if provider is initialized
|
|
283
|
-
*/
|
|
284
251
|
isInitialized(toolId) {
|
|
285
252
|
return this.initialized.get(toolId) === true;
|
|
286
253
|
}
|
|
287
|
-
/**
|
|
288
|
-
* Check if provider is currently initializing
|
|
289
|
-
*
|
|
290
|
-
* @param toolId Id of the tool the provider serves
|
|
291
|
-
* @returns true if initialization in progress
|
|
292
|
-
*/
|
|
293
254
|
isInitializing(toolId) {
|
|
294
255
|
return this.initializationPromises.has(toolId);
|
|
295
256
|
}
|
|
296
257
|
/**
|
|
297
258
|
* Unregister and destroy a provider
|
|
298
259
|
*
|
|
299
|
-
* Removes the provider from the registry and calls its destroy method
|
|
300
|
-
*
|
|
301
|
-
* @param toolId Tool whose provider to unregister
|
|
260
|
+
* Removes the provider from the registry and calls its destroy method,
|
|
261
|
+
* after any start in progress settles.
|
|
302
262
|
*/
|
|
303
263
|
async unregister(toolId) {
|
|
304
264
|
const provider = this.providers.get(toolId);
|
|
305
265
|
if (provider) {
|
|
306
|
-
// Wait for any pending initialization
|
|
307
266
|
const initPromise = this.initializationPromises.get(toolId);
|
|
308
267
|
if (initPromise) {
|
|
309
268
|
try {
|
|
@@ -318,7 +277,6 @@ export class ToolProviderRegistry {
|
|
|
318
277
|
return;
|
|
319
278
|
}
|
|
320
279
|
this.destroyProvider(toolId, provider);
|
|
321
|
-
// Remove from registry
|
|
322
280
|
this.providers.delete(toolId);
|
|
323
281
|
this.configs.delete(toolId);
|
|
324
282
|
this.initialized.delete(toolId);
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
* Core names no capability. The requester supplies the tool id, which is why the
|
|
20
20
|
* pairing of a selection action to a dictionary lives in the composition layer.
|
|
21
21
|
*/
|
|
22
|
+
import type { ToolFailurePhase } from "./tool-failure.js";
|
|
22
23
|
import type { ToolPlacementLevel } from "./tools-config-normalizer.js";
|
|
23
24
|
/** Level a request resolves against when the requester names none. */
|
|
24
25
|
export declare const DEFAULT_TOOL_REQUEST_LEVEL: ToolPlacementLevel;
|
|
@@ -79,8 +80,11 @@ export interface ToolRequestTarget {
|
|
|
79
80
|
* earlier one is still mounted does not displace it.
|
|
80
81
|
*/
|
|
81
82
|
export declare class ToolRequestRegistry {
|
|
83
|
+
private readonly onTargetFailure;
|
|
82
84
|
private readonly targets;
|
|
83
85
|
private readonly changeListeners;
|
|
86
|
+
/** `onTargetFailure` receives a target's throw, which the registry recovers from. */
|
|
87
|
+
constructor(onTargetFailure?: (toolId: string, phase: ToolFailurePhase, error: unknown) => void);
|
|
84
88
|
registerTarget(target: ToolRequestTarget): () => void;
|
|
85
89
|
/**
|
|
86
90
|
* Whether a request for this tool would reach a toolbar.
|
|
@@ -28,8 +28,13 @@ export const DEFAULT_TOOL_REQUEST_LEVEL = "section";
|
|
|
28
28
|
* earlier one is still mounted does not displace it.
|
|
29
29
|
*/
|
|
30
30
|
export class ToolRequestRegistry {
|
|
31
|
+
onTargetFailure;
|
|
31
32
|
targets = new Set();
|
|
32
33
|
changeListeners = new Set();
|
|
34
|
+
/** `onTargetFailure` receives a target's throw, which the registry recovers from. */
|
|
35
|
+
constructor(onTargetFailure = (toolId, phase, error) => console.error(`[ToolRequestRegistry] "${toolId}" ${phase} failed:`, error)) {
|
|
36
|
+
this.onTargetFailure = onTargetFailure;
|
|
37
|
+
}
|
|
33
38
|
registerTarget(target) {
|
|
34
39
|
this.targets.add(target);
|
|
35
40
|
this.notifyTargetsChange();
|
|
@@ -58,7 +63,7 @@ export class ToolRequestRegistry {
|
|
|
58
63
|
target.open(request.toolId, request.params);
|
|
59
64
|
}
|
|
60
65
|
catch (error) {
|
|
61
|
-
|
|
66
|
+
this.onTargetFailure(request.toolId, "tool-request-open", error);
|
|
62
67
|
return false;
|
|
63
68
|
}
|
|
64
69
|
return true;
|
|
@@ -115,7 +120,7 @@ export class ToolRequestRegistry {
|
|
|
115
120
|
return target.hostsTool(toolId) === true;
|
|
116
121
|
}
|
|
117
122
|
catch (error) {
|
|
118
|
-
|
|
123
|
+
this.onTargetFailure(toolId, "tool-request-host-check", error);
|
|
119
124
|
return false;
|
|
120
125
|
}
|
|
121
126
|
}
|
|
@@ -17,6 +17,7 @@ export function createDecidedToolsTracker() {
|
|
|
17
17
|
toolId: entry.toolId,
|
|
18
18
|
required: entry.required,
|
|
19
19
|
alwaysAvailable: entry.alwaysAvailable,
|
|
20
|
+
parameters: entry.parameters,
|
|
20
21
|
}));
|
|
21
22
|
if (last?.renderVersion === renderVersion &&
|
|
22
23
|
structurallyEqual(last.tools, tools)) {
|
|
@@ -19,13 +19,10 @@ export function isValidToolbarItemShape(value) {
|
|
|
19
19
|
return false;
|
|
20
20
|
if (item.disabled !== undefined && typeof item.disabled !== "boolean")
|
|
21
21
|
return false;
|
|
22
|
+
// A link or a button: exactly one of `href` and `onClick`.
|
|
22
23
|
const hasHref = typeof item.href === "string";
|
|
23
24
|
const hasOnClick = typeof item.onClick === "function";
|
|
24
|
-
|
|
25
|
-
return false;
|
|
26
|
-
if (hasHref)
|
|
27
|
-
return true;
|
|
28
|
-
return hasOnClick;
|
|
25
|
+
return hasHref !== hasOnClick;
|
|
29
26
|
}
|
|
30
27
|
export function isInlineSvgIcon(icon) {
|
|
31
28
|
return typeof icon === "string" && icon.trimStart().startsWith("<svg");
|
|
@@ -76,16 +76,16 @@ export interface ToolProvidersConfig {
|
|
|
76
76
|
}
|
|
77
77
|
/**
|
|
78
78
|
* PNP/profile enforcement mode, set as `tools.pnpEnforcement` (on a section
|
|
79
|
-
* player, `runtime.tools.pnpEnforcement`)
|
|
79
|
+
* player, `runtime.tools.pnpEnforcement`) or through `setPnpEnforcement`.
|
|
80
80
|
*
|
|
81
|
-
* - `"on"` —
|
|
82
|
-
* - `"off"` —
|
|
83
|
-
* - omitted
|
|
84
|
-
*
|
|
85
|
-
*
|
|
81
|
+
* - `"on"` — toolbar decisions apply PNP/profile policy.
|
|
82
|
+
* - `"off"` — toolbar decisions skip it. Feature decisions read it either way.
|
|
83
|
+
* - omitted — auto-mode (the default): on when the bound assessment carries
|
|
84
|
+
* PNP/profile policy material, or, for a decision scoped to an item, when
|
|
85
|
+
* that item's settings require or restrict a tool. See
|
|
86
86
|
* `resolveDefaultPnpEnforcement` in `policy/core/pnp-policy-inputs.ts`.
|
|
87
87
|
*/
|
|
88
|
-
export type
|
|
88
|
+
export type PnpEnforcementMode = "on" | "off";
|
|
89
89
|
export interface CanonicalToolsConfig {
|
|
90
90
|
policy: ToolPolicyConfig;
|
|
91
91
|
placement: Required<ToolPlacementConfig>;
|
|
@@ -93,9 +93,9 @@ export interface CanonicalToolsConfig {
|
|
|
93
93
|
/**
|
|
94
94
|
* Optional PNP/profile enforcement override, read by
|
|
95
95
|
* `<pie-assessment-toolkit>` and `ToolkitCoordinator`. See
|
|
96
|
-
* {@link
|
|
96
|
+
* {@link PnpEnforcementMode} for semantics.
|
|
97
97
|
*/
|
|
98
|
-
pnpEnforcement?:
|
|
98
|
+
pnpEnforcement?: PnpEnforcementMode;
|
|
99
99
|
}
|
|
100
100
|
/**
|
|
101
101
|
* The tools config a host supplies. Every part is optional, placement levels
|
|
@@ -104,6 +104,15 @@ export interface CanonicalToolsConfig {
|
|
|
104
104
|
export type ToolsConfigInput = Omit<Partial<CanonicalToolsConfig>, "placement"> & {
|
|
105
105
|
placement?: ToolPlacementConfig;
|
|
106
106
|
};
|
|
107
|
+
/**
|
|
108
|
+
* Tool ids trimmed, with empty ones dropped and duplicates removed in
|
|
109
|
+
* first-seen order. Throws on a non-string entry.
|
|
110
|
+
*/
|
|
107
111
|
export declare function normalizeToolList(toolIds: string[] | undefined | null): string[];
|
|
108
112
|
export declare function parseToolList(input: string | undefined | null): string[];
|
|
113
|
+
/**
|
|
114
|
+
* Check a host's tools config shape, throwing at the first malformed field, and
|
|
115
|
+
* return it canonical: tool lists trimmed and deduplicated, and every placement
|
|
116
|
+
* level that names no tool filled with its default.
|
|
117
|
+
*/
|
|
109
118
|
export declare function normalizeToolsConfig(input?: ToolsConfigInput | null): CanonicalToolsConfig;
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { DEFAULT_TOOL_PLACEMENT } from "./tool-config-defaults.js";
|
|
2
|
+
import { isPlainRecord } from "@pie-players/pie-players-shared/object";
|
|
2
3
|
const DEFAULT_PLACEMENT = {
|
|
3
4
|
section: [...DEFAULT_TOOL_PLACEMENT.section],
|
|
4
5
|
item: [...DEFAULT_TOOL_PLACEMENT.item],
|
|
5
6
|
passage: [...DEFAULT_TOOL_PLACEMENT.passage],
|
|
6
7
|
};
|
|
7
|
-
function isPlainObject(value) {
|
|
8
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9
|
-
}
|
|
10
8
|
function assertStringArray(value, fieldPath) {
|
|
11
9
|
if (value == null)
|
|
12
10
|
return [];
|
|
@@ -22,7 +20,7 @@ function assertStringArray(value, fieldPath) {
|
|
|
22
20
|
function assertPlacementConfig(value) {
|
|
23
21
|
if (value == null)
|
|
24
22
|
return undefined;
|
|
25
|
-
if (!
|
|
23
|
+
if (!isPlainRecord(value)) {
|
|
26
24
|
throw new Error('Invalid tools config at "placement": expected an object with section/item/passage arrays.');
|
|
27
25
|
}
|
|
28
26
|
return value;
|
|
@@ -30,7 +28,7 @@ function assertPlacementConfig(value) {
|
|
|
30
28
|
function assertPolicyConfig(value) {
|
|
31
29
|
if (value == null)
|
|
32
30
|
return undefined;
|
|
33
|
-
if (!
|
|
31
|
+
if (!isPlainRecord(value)) {
|
|
34
32
|
throw new Error('Invalid tools config at "policy": expected an object with allowed/blocked arrays.');
|
|
35
33
|
}
|
|
36
34
|
return value;
|
|
@@ -38,7 +36,7 @@ function assertPolicyConfig(value) {
|
|
|
38
36
|
function assertProviderConfig(providerId, value) {
|
|
39
37
|
if (value == null)
|
|
40
38
|
return undefined;
|
|
41
|
-
if (!
|
|
39
|
+
if (!isPlainRecord(value)) {
|
|
42
40
|
throw new Error(`Invalid tools config at "providers.${providerId}": expected an object.`);
|
|
43
41
|
}
|
|
44
42
|
const config = value;
|
|
@@ -49,12 +47,12 @@ function assertProviderConfig(providerId, value) {
|
|
|
49
47
|
}
|
|
50
48
|
if ("settings" in config &&
|
|
51
49
|
config.settings !== undefined &&
|
|
52
|
-
!
|
|
50
|
+
!isPlainRecord(config.settings)) {
|
|
53
51
|
throw new Error(`Invalid tools config at "providers.${providerId}.settings": expected an object.`);
|
|
54
52
|
}
|
|
55
53
|
if ("provider" in config &&
|
|
56
54
|
config.provider !== undefined &&
|
|
57
|
-
!
|
|
55
|
+
!isPlainRecord(config.provider)) {
|
|
58
56
|
throw new Error(`Invalid tools config at "providers.${providerId}.provider": expected an object.`);
|
|
59
57
|
}
|
|
60
58
|
return config;
|
|
@@ -62,7 +60,7 @@ function assertProviderConfig(providerId, value) {
|
|
|
62
60
|
function assertProvidersConfig(value) {
|
|
63
61
|
if (value == null)
|
|
64
62
|
return {};
|
|
65
|
-
if (!
|
|
63
|
+
if (!isPlainRecord(value)) {
|
|
66
64
|
throw new Error('Invalid tools config at "providers": expected an object keyed by tool id.');
|
|
67
65
|
}
|
|
68
66
|
const normalized = {};
|
|
@@ -71,6 +69,10 @@ function assertProvidersConfig(value) {
|
|
|
71
69
|
}
|
|
72
70
|
return normalized;
|
|
73
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Tool ids trimmed, with empty ones dropped and duplicates removed in
|
|
74
|
+
* first-seen order. Throws on a non-string entry.
|
|
75
|
+
*/
|
|
74
76
|
export function normalizeToolList(toolIds) {
|
|
75
77
|
if (!toolIds || toolIds.length === 0)
|
|
76
78
|
return [];
|
|
@@ -101,8 +103,18 @@ function assertPnpEnforcement(value, fieldPath) {
|
|
|
101
103
|
return value;
|
|
102
104
|
throw new Error(`Invalid tools config at "${fieldPath}": expected "on" or "off", got ${JSON.stringify(value)}.`);
|
|
103
105
|
}
|
|
106
|
+
/** A placement level's tool ids, or the level's default when it names none. */
|
|
107
|
+
function normalizePlacementLevel(placement, level) {
|
|
108
|
+
const toolIds = normalizeToolList(assertStringArray(placement?.[level], `placement.${level}`));
|
|
109
|
+
return toolIds.length ? toolIds : [...DEFAULT_PLACEMENT[level]];
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Check a host's tools config shape, throwing at the first malformed field, and
|
|
113
|
+
* return it canonical: tool lists trimmed and deduplicated, and every placement
|
|
114
|
+
* level that names no tool filled with its default.
|
|
115
|
+
*/
|
|
104
116
|
export function normalizeToolsConfig(input) {
|
|
105
|
-
if (input != null && !
|
|
117
|
+
if (input != null && !isPlainRecord(input)) {
|
|
106
118
|
throw new Error('Invalid tools config: expected an object with "policy", "placement", and "providers".');
|
|
107
119
|
}
|
|
108
120
|
const policy = assertPolicyConfig(input?.policy);
|
|
@@ -115,15 +127,9 @@ export function normalizeToolsConfig(input) {
|
|
|
115
127
|
blocked: normalizeToolList(assertStringArray(policy?.blocked, "policy.blocked")),
|
|
116
128
|
},
|
|
117
129
|
placement: {
|
|
118
|
-
section:
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
item: normalizeToolList(assertStringArray(placement?.item, "placement.item")).length
|
|
122
|
-
? normalizeToolList(assertStringArray(placement?.item, "placement.item"))
|
|
123
|
-
: [...DEFAULT_PLACEMENT.item],
|
|
124
|
-
passage: normalizeToolList(assertStringArray(placement?.passage, "placement.passage")).length
|
|
125
|
-
? normalizeToolList(assertStringArray(placement?.passage, "placement.passage"))
|
|
126
|
-
: [...DEFAULT_PLACEMENT.passage],
|
|
130
|
+
section: normalizePlacementLevel(placement, "section"),
|
|
131
|
+
item: normalizePlacementLevel(placement, "item"),
|
|
132
|
+
passage: normalizePlacementLevel(placement, "passage"),
|
|
127
133
|
},
|
|
128
134
|
providers,
|
|
129
135
|
};
|
|
@@ -3,16 +3,15 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Text-to-speech provider using the browser's Web Speech API.
|
|
5
5
|
* Works in all modern browsers that support SpeechSynthesis.
|
|
6
|
-
*
|
|
7
|
-
* Part of PIE Assessment Toolkit.
|
|
8
6
|
*/
|
|
9
7
|
import type { ITTSProvider, ITTSProviderImplementation, TTSConfig, TTSProviderCapabilities } from "@pie-players/pie-tts";
|
|
8
|
+
import type { ToolkitTTSConfig } from "./provider-options.js";
|
|
10
9
|
/**
|
|
11
10
|
* The part of another provider's configuration that keeps its meaning on
|
|
12
11
|
* browser speech. Every path that replaces a provider with browser speech
|
|
13
12
|
* starts it with this.
|
|
14
13
|
*/
|
|
15
|
-
export declare const browserFallbackConfig: (config: Partial<
|
|
14
|
+
export declare const browserFallbackConfig: (config: Partial<ToolkitTTSConfig>) => Partial<ToolkitTTSConfig>;
|
|
16
15
|
/**
|
|
17
16
|
* The voice traits browser voice selection reads. A `SpeechSynthesisVoice` has
|
|
18
17
|
* them all; a host's own voice list may carry a subset.
|
|
@@ -51,8 +50,6 @@ export declare const waitForBrowserVoices: (synth: SpeechSynthesis, timeoutMs: n
|
|
|
51
50
|
*/
|
|
52
51
|
export declare class BrowserTTSProvider implements ITTSProvider {
|
|
53
52
|
readonly providerId = "browser";
|
|
54
|
-
readonly providerName = "Browser Speech Synthesis";
|
|
55
|
-
readonly version = "1.0.0";
|
|
56
53
|
initialize(config: TTSConfig): Promise<ITTSProviderImplementation>;
|
|
57
54
|
getCapabilities(): TTSProviderCapabilities;
|
|
58
55
|
destroy(): void;
|