@pie-players/pie-assessment-toolkit 1.0.0-beta.7 → 1.0.0-beta.8
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/custom-elements.json +7 -0
- 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 +7 -7
- package/dist/components/SectionToolBar.custom-element.js +1 -1
- package/dist/components/chunks/ItemToolBar-bsww9e8f.js +4 -0
- package/dist/components/chunks/{ItemToolBar-pxan157g.js → ItemToolBar-gsb96731.js} +2 -2
- package/dist/components/chunks/ItemToolBar-na4e5vwt.js +2 -0
- package/dist/components/chunks/{ItemToolBar-xwjrpdmz.js → ItemToolBar-wcw4yxjy.js} +1 -1
- package/dist/components/chunks/ItemToolBar-x998kkvy.js +2 -0
- package/dist/components/chunks/ItemToolBar-zvy0hskj.js +40 -0
- package/dist/components/chunks/sre-engine-wazxma67.js +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/runtime/SectionControllerBinding.d.ts +11 -0
- package/dist/runtime/SectionControllerBinding.js +8 -0
- package/dist/runtime/registration-events.d.ts +28 -1
- package/dist/runtime/registration-events.js +19 -0
- package/dist/runtime/shell-event-bridge.d.ts +7 -1
- package/dist/runtime/shell-event-bridge.js +44 -1
- package/dist/runtime/shell-scope.d.ts +2 -2
- package/dist/runtime/shell-scope.js +14 -5
- package/dist/services/SSMLExtractor.js +8 -23
- package/dist/services/ToolRegistry.d.ts +11 -3
- package/dist/services/ToolRegistry.js +8 -4
- package/dist/services/ToolkitCoordinator.d.ts +12 -47
- package/dist/services/ToolkitCoordinator.js +45 -284
- package/dist/services/section-controller-types.d.ts +40 -0
- package/dist/services/tool-config-validation.d.ts +1 -1
- package/dist/services/tool-context.js +94 -11
- package/dist/services/tool-icons.js +2 -0
- package/dist/services/tool-provider-defaults.d.ts +13 -0
- package/dist/services/tool-provider-defaults.js +20 -0
- package/dist/services/tts/browser-provider.js +3 -1
- package/dist/services/tts/tts-lifecycle.d.ts +142 -0
- package/dist/services/tts/tts-lifecycle.js +341 -0
- package/dist/tools/content-surfaces.d.ts +35 -0
- package/dist/tools/content-surfaces.js +35 -0
- package/dist/tools/registration.d.ts +2 -0
- package/dist/tools/registration.js +5 -0
- package/package.json +8 -8
- package/dist/components/chunks/ItemToolBar-4vq9nbxz.js +0 -2
- package/dist/components/chunks/ItemToolBar-f971t0cw.js +0 -4
- package/dist/components/chunks/ItemToolBar-n05xjkp8.js +0 -2
- package/dist/components/chunks/ItemToolBar-rgmvw9sm.js +0 -40
- package/dist/components/chunks/sre-engine-dq0w45fv.js +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { commitPendingSessions, createPieLogger, normalizeItemSessionChange, } from "@pie-players/pie-players-shared";
|
|
2
|
-
import { PIE_INTERNAL_CONTENT_LOADED_EVENT, PIE_INTERNAL_ITEM_PLAYER_ERROR_EVENT, PIE_INTERNAL_ITEM_SESSION_CHANGED_EVENT, PIE_ITEM_SESSION_CHANGED_EVENT, } from "./registration-events.js";
|
|
2
|
+
import { PIE_INTERNAL_CONTENT_IDENTITY_EVENT, PIE_INTERNAL_CONTENT_LOADED_EVENT, PIE_INTERNAL_ITEM_PLAYER_ERROR_EVENT, PIE_INTERNAL_ITEM_SESSION_CHANGED_EVENT, PIE_ITEM_PLAYER_EVENT, PIE_ITEM_SESSION_CHANGED_EVENT, RELAYED_ITEM_PLAYER_EVENTS, } from "./registration-events.js";
|
|
3
3
|
import { dispatchCrossBoundaryEvent } from "./tool-host-contract.js";
|
|
4
4
|
/**
|
|
5
5
|
* Elements repeat themselves, a `complete` echo most often, so a session event
|
|
@@ -21,6 +21,9 @@ function sessionEventFingerprint(detail) {
|
|
|
21
21
|
return String(semanticDetail);
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
+
const isCorrectResponseSession = (detail) => Boolean(detail &&
|
|
25
|
+
typeof detail === "object" &&
|
|
26
|
+
detail.sessionSource === "correct-response");
|
|
24
27
|
const isCommit = (detail) => Boolean(detail &&
|
|
25
28
|
typeof detail === "object" &&
|
|
26
29
|
detail.sessionCommitReason);
|
|
@@ -70,6 +73,8 @@ export function createShellEventBridge(options) {
|
|
|
70
73
|
if (kind !== "item")
|
|
71
74
|
return;
|
|
72
75
|
const detail = event.detail;
|
|
76
|
+
if (isCorrectResponseSession(detail))
|
|
77
|
+
return;
|
|
73
78
|
const fingerprint = sessionEventFingerprint(detail);
|
|
74
79
|
// A commit is the response's last chance to reach the section.
|
|
75
80
|
if (!isCommit(detail) && fingerprint === lastForwardedFingerprint)
|
|
@@ -91,6 +96,22 @@ export function createShellEventBridge(options) {
|
|
|
91
96
|
};
|
|
92
97
|
send(PIE_INTERNAL_CONTENT_LOADED_EVENT, detail);
|
|
93
98
|
};
|
|
99
|
+
const onBackendLoadComplete = (event) => {
|
|
100
|
+
if (mode() !== "section" || kind !== "item")
|
|
101
|
+
return;
|
|
102
|
+
const loaded = event.detail;
|
|
103
|
+
if (loaded?.scope !== "delivery")
|
|
104
|
+
return;
|
|
105
|
+
const { itemId, canonicalItemId } = identity();
|
|
106
|
+
if (!itemId)
|
|
107
|
+
return;
|
|
108
|
+
const detail = {
|
|
109
|
+
itemId,
|
|
110
|
+
canonicalItemId: canonicalItemId || itemId,
|
|
111
|
+
...(loaded.identity ? { identity: loaded.identity } : {}),
|
|
112
|
+
};
|
|
113
|
+
send(PIE_INTERNAL_CONTENT_IDENTITY_EVENT, detail);
|
|
114
|
+
};
|
|
94
115
|
const onPlayerError = (event) => {
|
|
95
116
|
if (mode() === "section")
|
|
96
117
|
event.stopPropagation();
|
|
@@ -105,9 +126,27 @@ export function createShellEventBridge(options) {
|
|
|
105
126
|
};
|
|
106
127
|
send(PIE_INTERNAL_ITEM_PLAYER_ERROR_EVENT, detail);
|
|
107
128
|
};
|
|
129
|
+
const relayItemPlayerEvent = (event) => {
|
|
130
|
+
if (mode() !== "section" || kind !== "item")
|
|
131
|
+
return;
|
|
132
|
+
const { itemId, canonicalItemId } = identity();
|
|
133
|
+
if (!itemId)
|
|
134
|
+
return;
|
|
135
|
+
const payload = {
|
|
136
|
+
itemId,
|
|
137
|
+
canonicalItemId: canonicalItemId || itemId,
|
|
138
|
+
type: event.type,
|
|
139
|
+
detail: event.detail,
|
|
140
|
+
};
|
|
141
|
+
dispatchCrossBoundaryEvent(host, PIE_ITEM_PLAYER_EVENT, payload);
|
|
142
|
+
};
|
|
108
143
|
host.addEventListener("session-changed", onSessionChanged);
|
|
109
144
|
host.addEventListener("load-complete", onLoadComplete);
|
|
145
|
+
host.addEventListener("backend-load-complete", onBackendLoadComplete);
|
|
110
146
|
host.addEventListener("player-error", onPlayerError);
|
|
147
|
+
for (const type of RELAYED_ITEM_PLAYER_EVENTS) {
|
|
148
|
+
host.addEventListener(type, relayItemPlayerEvent);
|
|
149
|
+
}
|
|
111
150
|
return {
|
|
112
151
|
disconnect: () => {
|
|
113
152
|
// An escape from the commit must not strand the listeners it needed, so
|
|
@@ -120,7 +159,11 @@ export function createShellEventBridge(options) {
|
|
|
120
159
|
finally {
|
|
121
160
|
host.removeEventListener("session-changed", onSessionChanged);
|
|
122
161
|
host.removeEventListener("load-complete", onLoadComplete);
|
|
162
|
+
host.removeEventListener("backend-load-complete", onBackendLoadComplete);
|
|
123
163
|
host.removeEventListener("player-error", onPlayerError);
|
|
164
|
+
for (const type of RELAYED_ITEM_PLAYER_EVENTS) {
|
|
165
|
+
host.removeEventListener(type, relayItemPlayerEvent);
|
|
166
|
+
}
|
|
124
167
|
}
|
|
125
168
|
},
|
|
126
169
|
};
|
|
@@ -62,7 +62,7 @@ export interface ShellScope {
|
|
|
62
62
|
* replays the request instead, once the toolkit's provider connects. A
|
|
63
63
|
* different runtime answering later, a nearer toolkit taking over, moves the
|
|
64
64
|
* registration: the old runtime is told to unregister by its id, and the new
|
|
65
|
-
* one gets the registration and the content's last load
|
|
66
|
-
* one heard.
|
|
65
|
+
* one gets the registration and the content's last load and served identity,
|
|
66
|
+
* which only the old one heard.
|
|
67
67
|
*/
|
|
68
68
|
export declare function createShellScope(): ShellScope;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ContextProvider, } from "@pie-players/pie-context";
|
|
2
2
|
import { assessmentToolkitRegionScopeContext, assessmentToolkitShellContext, } from "../context/assessment-toolkit-context.js";
|
|
3
3
|
import { catalogSourceSignature, } from "../services/catalog-owner.js";
|
|
4
|
-
import { PIE_INTERNAL_CONTENT_LOADED_EVENT } from "./registration-events.js";
|
|
4
|
+
import { PIE_INTERNAL_CONTENT_IDENTITY_EVENT, PIE_INTERNAL_CONTENT_LOADED_EVENT, } from "./registration-events.js";
|
|
5
5
|
import { createShellRegistrationDispatcher, shellEventTarget, } from "./shell-registration.js";
|
|
6
6
|
import { connectHostRuntimeContext, dispatchCrossBoundaryEvent, } from "./tool-host-contract.js";
|
|
7
7
|
/**
|
|
@@ -65,8 +65,8 @@ const setAttributeIfChanged = (host, name, value) => {
|
|
|
65
65
|
* replays the request instead, once the toolkit's provider connects. A
|
|
66
66
|
* different runtime answering later, a nearer toolkit taking over, moves the
|
|
67
67
|
* registration: the old runtime is told to unregister by its id, and the new
|
|
68
|
-
* one gets the registration and the content's last load
|
|
69
|
-
* one heard.
|
|
68
|
+
* one gets the registration and the content's last load and served identity,
|
|
69
|
+
* which only the old one heard.
|
|
70
70
|
*/
|
|
71
71
|
export function createShellScope() {
|
|
72
72
|
const registration = createShellRegistrationDispatcher();
|
|
@@ -79,6 +79,7 @@ export function createShellScope() {
|
|
|
79
79
|
let identity = null;
|
|
80
80
|
let held = [];
|
|
81
81
|
let loaded = null;
|
|
82
|
+
let served = null;
|
|
82
83
|
const syncRegistration = () => {
|
|
83
84
|
if (runtime !== null)
|
|
84
85
|
registration.sync(identity, runtime);
|
|
@@ -90,6 +91,8 @@ export function createShellScope() {
|
|
|
90
91
|
function send(type, detail) {
|
|
91
92
|
if (type === PIE_INTERNAL_CONTENT_LOADED_EVENT)
|
|
92
93
|
loaded = detail;
|
|
94
|
+
if (type === PIE_INTERNAL_CONTENT_IDENTITY_EVENT)
|
|
95
|
+
served = detail;
|
|
93
96
|
if (host && runtime !== null && !runtimeDeparted(host, runtime)) {
|
|
94
97
|
dispatchCrossBoundaryEvent(shellEventTarget(host, runtime), type, {
|
|
95
98
|
...detail,
|
|
@@ -113,8 +116,13 @@ export function createShellScope() {
|
|
|
113
116
|
held = [];
|
|
114
117
|
for (const event of pending)
|
|
115
118
|
send(event.type, event.detail);
|
|
116
|
-
|
|
117
|
-
|
|
119
|
+
if (!moved)
|
|
120
|
+
return;
|
|
121
|
+
const replayed = (type) => pending.some((event) => event.type === type);
|
|
122
|
+
if (served && !replayed(PIE_INTERNAL_CONTENT_IDENTITY_EVENT)) {
|
|
123
|
+
send(PIE_INTERNAL_CONTENT_IDENTITY_EVENT, served);
|
|
124
|
+
}
|
|
125
|
+
if (loaded && !replayed(PIE_INTERNAL_CONTENT_LOADED_EVENT)) {
|
|
118
126
|
send(PIE_INTERNAL_CONTENT_LOADED_EVENT, loaded);
|
|
119
127
|
}
|
|
120
128
|
}
|
|
@@ -126,6 +134,7 @@ export function createShellScope() {
|
|
|
126
134
|
runtime = null;
|
|
127
135
|
held = [];
|
|
128
136
|
loaded = null;
|
|
137
|
+
served = null;
|
|
129
138
|
identity = null;
|
|
130
139
|
shell = null;
|
|
131
140
|
region = null;
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* This enables proper pronunciation, emphasis, and pacing for TTS without
|
|
15
15
|
* requiring authors to maintain separate catalog files.
|
|
16
16
|
*/
|
|
17
|
+
import { isCloudMetadataHostname, isPrivateHostname, } from "@pie-players/pie-players-shared/security/private-hosts";
|
|
17
18
|
/**
|
|
18
19
|
* Allow-listed SSML elements (from the SSML 1.1 spec subset we forward to
|
|
19
20
|
* TTS providers). Anything outside this list is unwrapped during
|
|
@@ -108,27 +109,11 @@ function expandSelfClosingVoidTags(input) {
|
|
|
108
109
|
return next;
|
|
109
110
|
}
|
|
110
111
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
112
|
+
* Whether an SSML `<audio src>` may stay. The server-side TTS provider fetches
|
|
113
|
+
* it on the request's behalf, so it must be http(s) and must not reach a cloud
|
|
114
|
+
* metadata or private host. The provider checks its own asset URLs against the
|
|
115
|
+
* same lists; this SSML-side block is cheap and belt-and-braces.
|
|
115
116
|
*/
|
|
116
|
-
const SSML_PRIVATE_AUDIO_HOSTS = [
|
|
117
|
-
/^localhost$/i,
|
|
118
|
-
/^127(?:\.\d{1,3}){3}$/,
|
|
119
|
-
/^0(?:\.\d{1,3}){3}$/,
|
|
120
|
-
/^10(?:\.\d{1,3}){3}$/,
|
|
121
|
-
/^192\.168(?:\.\d{1,3}){2}$/,
|
|
122
|
-
/^172\.(?:1[6-9]|2\d|3[01])(?:\.\d{1,3}){2}$/,
|
|
123
|
-
/^169\.254(?:\.\d{1,3}){2}$/,
|
|
124
|
-
/^::1$/,
|
|
125
|
-
/^fe80:/i,
|
|
126
|
-
/^fc00:/i,
|
|
127
|
-
/^fd[0-9a-f]{2}:/i,
|
|
128
|
-
/^metadata\.google\.internal$/i,
|
|
129
|
-
/^metadata\.azure\.internal$/i,
|
|
130
|
-
/^metadata\.packet\.net$/i,
|
|
131
|
-
];
|
|
132
117
|
function isSafeSsmlAudioSrc(raw) {
|
|
133
118
|
if (typeof raw !== "string" || raw.length === 0)
|
|
134
119
|
return false;
|
|
@@ -142,8 +127,8 @@ function isSafeSsmlAudioSrc(raw) {
|
|
|
142
127
|
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
143
128
|
return false;
|
|
144
129
|
}
|
|
145
|
-
|
|
146
|
-
|
|
130
|
+
return (!isCloudMetadataHostname(parsed.hostname) &&
|
|
131
|
+
!isPrivateHostname(parsed.hostname));
|
|
147
132
|
}
|
|
148
133
|
/**
|
|
149
134
|
* Sanitize an SSML subtree in place: remove disallowed attributes and
|
|
@@ -173,7 +158,7 @@ function sanitizeSsmlElement(element) {
|
|
|
173
158
|
}
|
|
174
159
|
}
|
|
175
160
|
// `src` survives the attribute allow-list, and a server-side provider
|
|
176
|
-
// fetches it: keep it only
|
|
161
|
+
// fetches it: keep it only when isSafeSsmlAudioSrc allows it.
|
|
177
162
|
if (element.tagName.toLowerCase() === "audio") {
|
|
178
163
|
const src = element.getAttribute("src");
|
|
179
164
|
if (src !== null && !isSafeSsmlAudioSrc(src)) {
|
|
@@ -545,8 +545,12 @@ export interface ToolRegistration {
|
|
|
545
545
|
* Declare this only where the tool's own controls provably do nothing:
|
|
546
546
|
* withdrawing a granted accommodation on a false negative is the more
|
|
547
547
|
* expensive failure. Omitting it means "applicable".
|
|
548
|
+
*
|
|
549
|
+
* `config` is this tool's `tools.providers.<toolId>` entry, when the surface
|
|
550
|
+
* asking has one: host configuration can narrow what a tool acts on, and a
|
|
551
|
+
* tool that acts on nothing here is not applicable.
|
|
548
552
|
*/
|
|
549
|
-
isApplicableToContent?(context: ToolContext): boolean;
|
|
553
|
+
isApplicableToContent?(context: ToolContext, config?: ToolProviderConfig): boolean;
|
|
550
554
|
/**
|
|
551
555
|
* Toolbar render contract. Required for `toolbar-toggle` and
|
|
552
556
|
* `selection-gateway`; a region capability renders through
|
|
@@ -666,8 +670,10 @@ export declare class ToolRegistry {
|
|
|
666
670
|
* @param contexts - Every context the tool could act on at this placement
|
|
667
671
|
* @param onFailure - Receives the gate's throw; the tool then counts as
|
|
668
672
|
* applicable. Logs when omitted.
|
|
673
|
+
* @param config - The tool's `tools.providers.<toolId>` entry, passed to the
|
|
674
|
+
* gate
|
|
669
675
|
*/
|
|
670
|
-
isApplicableToAnyContext(toolId: string, contexts: readonly ToolContext[], onFailure?: ToolCallbackFailureHandler): boolean;
|
|
676
|
+
isApplicableToAnyContext(toolId: string, contexts: readonly ToolContext[], onFailure?: ToolCallbackFailureHandler, config?: ToolProviderConfig): boolean;
|
|
671
677
|
/**
|
|
672
678
|
* Passes 2 and 3 over a policy decision's tools: the ids a surface at `level`
|
|
673
679
|
* shows against `contexts`, in decision order. This is the rule a toolbar
|
|
@@ -687,8 +693,10 @@ export declare class ToolRegistry {
|
|
|
687
693
|
* @param contexts - Every context the tools could act on at that surface
|
|
688
694
|
* @param onFailure - Receives a relevance or applicability check's throw.
|
|
689
695
|
* Logs when omitted.
|
|
696
|
+
* @param getToolConfig - A tool's `tools.providers.<toolId>` entry, which
|
|
697
|
+
* applicability receives; a toolkit coordinator's `getToolConfig`
|
|
690
698
|
*/
|
|
691
|
-
filterDecidedToolIds(entries: readonly Pick<ToolPolicyEntry, "toolId" | "required" | "alwaysAvailable">[], level: ToolLevel, contexts: readonly ToolContext[], onFailure?: ToolCallbackFailureHandler): string[];
|
|
699
|
+
filterDecidedToolIds(entries: readonly Pick<ToolPolicyEntry, "toolId" | "required" | "alwaysAvailable">[], level: ToolLevel, contexts: readonly ToolContext[], onFailure?: ToolCallbackFailureHandler, getToolConfig?: (toolId: string) => ToolProviderConfig | null): string[];
|
|
692
700
|
/**
|
|
693
701
|
* Plain metadata for every registration, in registration order, for UIs
|
|
694
702
|
* such as a PNP configuration screen.
|
|
@@ -382,8 +382,10 @@ export class ToolRegistry {
|
|
|
382
382
|
* @param contexts - Every context the tool could act on at this placement
|
|
383
383
|
* @param onFailure - Receives the gate's throw; the tool then counts as
|
|
384
384
|
* applicable. Logs when omitted.
|
|
385
|
+
* @param config - The tool's `tools.providers.<toolId>` entry, passed to the
|
|
386
|
+
* gate
|
|
385
387
|
*/
|
|
386
|
-
isApplicableToAnyContext(toolId, contexts, onFailure = logToolCallbackFailure) {
|
|
388
|
+
isApplicableToAnyContext(toolId, contexts, onFailure = logToolCallbackFailure, config) {
|
|
387
389
|
const tool = this.get(toolId);
|
|
388
390
|
if (!tool?.isApplicableToContent)
|
|
389
391
|
return true;
|
|
@@ -391,7 +393,7 @@ export class ToolRegistry {
|
|
|
391
393
|
return true;
|
|
392
394
|
return contexts.some((context) => {
|
|
393
395
|
try {
|
|
394
|
-
return tool.isApplicableToContent?.(context) ?? true;
|
|
396
|
+
return tool.isApplicableToContent?.(context, config) ?? true;
|
|
395
397
|
}
|
|
396
398
|
catch (error) {
|
|
397
399
|
onFailure(toolId, "tool-applicability", error);
|
|
@@ -419,8 +421,10 @@ export class ToolRegistry {
|
|
|
419
421
|
* @param contexts - Every context the tools could act on at that surface
|
|
420
422
|
* @param onFailure - Receives a relevance or applicability check's throw.
|
|
421
423
|
* Logs when omitted.
|
|
424
|
+
* @param getToolConfig - A tool's `tools.providers.<toolId>` entry, which
|
|
425
|
+
* applicability receives; a toolkit coordinator's `getToolConfig`
|
|
422
426
|
*/
|
|
423
|
-
filterDecidedToolIds(entries, level, contexts, onFailure = logToolCallbackFailure) {
|
|
427
|
+
filterDecidedToolIds(entries, level, contexts, onFailure = logToolCallbackFailure, getToolConfig) {
|
|
424
428
|
const granted = new Set();
|
|
425
429
|
const decided = [];
|
|
426
430
|
for (const entry of entries) {
|
|
@@ -447,7 +451,7 @@ export class ToolRegistry {
|
|
|
447
451
|
}
|
|
448
452
|
}
|
|
449
453
|
return decided.filter((toolId) => relevant.has(toolId) &&
|
|
450
|
-
this.isApplicableToAnyContext(toolId, contexts, onFailure));
|
|
454
|
+
this.isApplicableToAnyContext(toolId, contexts, onFailure, getToolConfig?.(toolId) ?? undefined));
|
|
451
455
|
}
|
|
452
456
|
/**
|
|
453
457
|
* Plain metadata for every registration, in registration order, for UIs
|
|
@@ -35,13 +35,14 @@ import type { ToolCoordinatorApi } from "./interfaces.js";
|
|
|
35
35
|
import { TTSService } from "./TTSService.js";
|
|
36
36
|
import { ToolProviderRegistry } from "./tool-providers/index.js";
|
|
37
37
|
import type { ToolProviderApi } from "./tool-providers/ToolProviderApi.js";
|
|
38
|
+
import { TTS_TOOL_ID } from "./tts/tts-lifecycle.js";
|
|
38
39
|
import { ToolRegistry } from "./ToolRegistry.js";
|
|
39
40
|
import type { ResolvedToolContext, ToolContextResolverContext, ToolContextResolverMap } from "./ToolRegistry.js";
|
|
40
41
|
import type { ToolFailurePhase } from "./tool-failure.js";
|
|
41
42
|
import type { ToolOpenRequest, ToolRequestTarget } from "./tool-request.js";
|
|
42
43
|
import { type FeaturePolicyDecision, type PnpEnforcementMode, type PolicySource, type ResolvedEngineInputs, type ToolPolicyChangeListener, type ToolPolicyDecision, type ToolPolicyDecisionRequest, type ToolPolicyDiagnostic, type ToolScope } from "../policy/engine.js";
|
|
43
44
|
import type { SectionControllerContext, SectionControllerEvent, SectionControllerEventType, SectionControllerFactoryDefaults, SectionControllerHandle, SectionControllerKey, SectionControllerSessionState, SectionSessionPersistenceStrategy, SectionPersistenceFactoryDefaults } from "./section-controller-types.js";
|
|
44
|
-
export type { SectionControllerContext, SectionControllerEvent, SectionControllerEventType, SectionControllerFactoryDefaults, SectionControllerHandle, SectionControllerKey, SectionControllerLoadedRenderable, SectionSessionPersistenceConfig, SectionSessionPersistenceStrategy, SectionControllerRuntimeState, SectionControllerSessionState, SectionPersistenceFactoryDefaults, } from "./section-controller-types.js";
|
|
45
|
+
export type { SectionControllerContext, SectionControllerEvent, SectionControllerEventType, SectionControllerFactoryDefaults, SectionControllerHandle, SectionControllerKey, SectionItemScore, SectionItemScorer, SectionScore, SectionControllerLoadedRenderable, SectionSessionPersistenceConfig, SectionSessionPersistenceStrategy, SectionControllerRuntimeState, SectionControllerSessionState, SectionPersistenceFactoryDefaults, } from "./section-controller-types.js";
|
|
45
46
|
export type { FeaturePolicyDecision, PnpEnforcementMode, ResolvedEngineInputs, ToolPolicyChangeListener, ToolPolicyDecision, ToolPolicyDecisionRequest, } from "../policy/engine.js";
|
|
46
47
|
export interface ToolkitToolsConfig extends CanonicalToolsConfig {
|
|
47
48
|
policy: ToolPolicyConfig;
|
|
@@ -291,11 +292,7 @@ export declare class ToolkitCoordinator {
|
|
|
291
292
|
readonly hooks: ToolkitCoordinatorHooks;
|
|
292
293
|
readonly lazyInit: boolean;
|
|
293
294
|
/** Track TTS initialization state */
|
|
294
|
-
private
|
|
295
|
-
/** Text-to-speech failed to start and policy does not grant it. */
|
|
296
|
-
private ttsDegraded;
|
|
297
|
-
private ttsInitPromise?;
|
|
298
|
-
private ttsReconfigurePromise?;
|
|
295
|
+
private tts;
|
|
299
296
|
/**
|
|
300
297
|
* The loader ran, whether or not it returned state. A failed load is
|
|
301
298
|
* reported once and the coordinator runs without saved tool state.
|
|
@@ -398,18 +395,6 @@ export declare class ToolkitCoordinator {
|
|
|
398
395
|
* lifetime for no new information.
|
|
399
396
|
*/
|
|
400
397
|
private reportedUnboundFeaturePolicy;
|
|
401
|
-
/**
|
|
402
|
-
* Whether {@link _initializeTTS} has already reported a non-browser backend
|
|
403
|
-
* falling back to browser speech because no text-to-speech provider is registered.
|
|
404
|
-
* Once per coordinator: a text-to-speech config change re-runs
|
|
405
|
-
* initialization, and the missing provider is the same gap each time.
|
|
406
|
-
*/
|
|
407
|
-
private reportedMissingTTSProvider;
|
|
408
|
-
/**
|
|
409
|
-
* The backend of a fallback {@link reportMissingTTSProvider} held back while
|
|
410
|
-
* the registry was unsettled, reported if the bound toolkit has no registry.
|
|
411
|
-
*/
|
|
412
|
-
private heldMissingTTSProviderBackend;
|
|
413
398
|
/**
|
|
414
399
|
* Whether {@link validateToolsConfig} has already reported validating with
|
|
415
400
|
* no registry (`tools.registryUnavailable`). Once per coordinator: every
|
|
@@ -528,7 +513,6 @@ export declare class ToolkitCoordinator {
|
|
|
528
513
|
private ensureStateLoaded;
|
|
529
514
|
/** Whether the toolkit this coordinator binds to may still supply a registry. */
|
|
530
515
|
private toolRegistryPending;
|
|
531
|
-
private reportMissingTTSProvider;
|
|
532
516
|
/**
|
|
533
517
|
* Take the registry of the toolkit this coordinator is bound to, when the host
|
|
534
518
|
* constructed it without one: the config is validated against it, its
|
|
@@ -694,27 +678,13 @@ export declare class ToolkitCoordinator {
|
|
|
694
678
|
private disposeOwnedResources;
|
|
695
679
|
private waitForAdmittedInitialization;
|
|
696
680
|
/**
|
|
697
|
-
* Initialize the TTS service from the `textToSpeech` tool config.
|
|
681
|
+
* Initialize the TTS service from the `textToSpeech` tool config. The
|
|
682
|
+
* lifecycle itself lives in `services/tts/tts-lifecycle.ts`; the coordinator
|
|
683
|
+
* keeps the public method hosts call.
|
|
698
684
|
*/
|
|
699
685
|
ensureTTSReady(): Promise<void>;
|
|
700
|
-
private waitForPendingTTSReconfigure;
|
|
701
|
-
private _initializeTTS;
|
|
702
|
-
private resolveTTSToolConfig;
|
|
703
|
-
private initializeTTSService;
|
|
704
686
|
waitUntilReady(): Promise<void>;
|
|
705
687
|
isReady(): boolean;
|
|
706
|
-
/**
|
|
707
|
-
* Readiness waits for text-to-speech when it is enabled and either starts
|
|
708
|
-
* eagerly or is granted: a granted read-aloud fails before the learner starts.
|
|
709
|
-
*/
|
|
710
|
-
private ttsRequiredForReadiness;
|
|
711
|
-
/**
|
|
712
|
-
* Starts text-to-speech for readiness. A failure policy does not grant leaves
|
|
713
|
-
* the tool degraded, reporting itself unavailable, and readiness settles; a
|
|
714
|
-
* granted tool's failure rejects.
|
|
715
|
-
*/
|
|
716
|
-
private startTTSForReadiness;
|
|
717
|
-
private getTTSConfigFromProviders;
|
|
718
688
|
private assertCanonicalToolId;
|
|
719
689
|
private installToolContextResolvers;
|
|
720
690
|
/**
|
|
@@ -725,14 +695,17 @@ export declare class ToolkitCoordinator {
|
|
|
725
695
|
setToolContextResolvers(resolvers: ToolContextResolverMap | null | undefined): void;
|
|
726
696
|
private notifyToolContextResolverChange;
|
|
727
697
|
/**
|
|
728
|
-
* Get tool configuration, or null if the tool is not configured.
|
|
698
|
+
* Get tool configuration, or null if the tool is not configured. The
|
|
699
|
+
* read-aloud overload takes its literal from `TTS_TOOL_ID` (the same type the
|
|
700
|
+
* runtime compares against), so the capability id is named once, where the
|
|
701
|
+
* capability lives.
|
|
729
702
|
*/
|
|
730
|
-
getToolConfig(toolId:
|
|
703
|
+
getToolConfig(toolId: typeof TTS_TOOL_ID): TextToSpeechToolProviderConfig | null;
|
|
731
704
|
getToolConfig(toolId: string): ToolProviderConfig | null;
|
|
732
705
|
/**
|
|
733
706
|
* Update tool configuration and apply the change to the underlying services.
|
|
734
707
|
*/
|
|
735
|
-
updateToolConfig(toolId:
|
|
708
|
+
updateToolConfig(toolId: typeof TTS_TOOL_ID, updates: Partial<TextToSpeechToolProviderConfig>): void;
|
|
736
709
|
updateToolConfig(toolId: string, updates: Partial<ToolProviderConfig>): void;
|
|
737
710
|
/**
|
|
738
711
|
* Patch one or more placement levels in the canonical tools config.
|
|
@@ -899,12 +872,4 @@ export declare class ToolkitCoordinator {
|
|
|
899
872
|
* so a check on the policy change the update dispatched finds the new provider.
|
|
900
873
|
*/
|
|
901
874
|
private _registerChangedToolProvider;
|
|
902
|
-
/**
|
|
903
|
-
* Re-register the text-to-speech provider for the current config and registry, then
|
|
904
|
-
* re-initialize unless initialization is lazy. An initialization already
|
|
905
|
-
* running finishes first: it would otherwise mark its provider ready after
|
|
906
|
-
* the reset.
|
|
907
|
-
*/
|
|
908
|
-
private scheduleTTSReconfigure;
|
|
909
|
-
private _reconfigureTTSProvider;
|
|
910
875
|
}
|