Skip to content

Commit 16c80db

Browse files
author
DavidQ
committed
Source Text to Speech V2 payloads from JSON and align workspace manifest array data - PR_26130_020-text-to-speech-v2-sample-json-source
1 parent 21dbcfb commit 16c80db

13 files changed

Lines changed: 395 additions & 82 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# PR_26130_020-text-to-speech-v2-sample-json-source
2+
3+
## Summary
4+
5+
- Updated Text to Speech V2 so it no longer fabricates built-in named speech items on empty launch.
6+
- Added explicit load paths for URL JSON, workspace/session payload, and Import JSON only.
7+
- Updated Workspace Manager V2 default/current manifest data so `root.tools.text2speach-V2` is a root array of named speech items.
8+
- Added a phase 19 Text to Speech V2 sample JSON source using the root-array schema contract.
9+
- Kept Text to Speech V2 schema shape unchanged from the prior root-array contract and avoided root queue wrappers or duplicated root fields.
10+
11+
## Implementation Notes
12+
13+
- `tools/text2speach-V2/js/TextToSpeechToolApp.js` now shows a safe empty/actionable state when no JSON source is provided instead of creating default speech items.
14+
- URL-provided sample JSON is loaded through `samplePresetPath`, validated before render, and logged as the active preset source.
15+
- Workspace/session payload loading remains schema-validated and rejects invalid payloads before partial render.
16+
- `tools/workspace-manager-v2/js/services/WorkspaceManagerV2ContextService.js` only provides Text to Speech V2 session data when a real array payload exists.
17+
- `games/Asteroids/game.manifest.json`, `games/GravityWell/game.manifest.json`, and `games/pong/game.manifest.json` now store `tools.text2speach-V2` as a root array.
18+
- `samples/phase-19/1903/sample.1903.text2speach-V2.json` contains the prepopulated named speech items as the selected sample source.
19+
- `tests/runtime/SampleStandaloneToolDataFlow.test.mjs` now recognizes the Text to Speech V2 sample as a tool-specific root-array contract instead of requiring the older wrapper JSON contract.
20+
21+
## Validation
22+
23+
- Passed: `npm run test:workspace-v2`
24+
- Result: 32 passed.
25+
- Passed: `node --check tests/runtime/SampleStandaloneToolDataFlow.test.mjs`
26+
- Passed: `git diff --check`
27+
- Note: Git printed line-ending normalization warnings for existing CRLF/LF handling, but no whitespace errors were reported.
28+
29+
## Skipped
30+
31+
- Full samples smoke test was not run. The BUILD request explicitly said not to run the full samples smoke test; this PR is scoped to Workspace Manager V2/Text to Speech V2 manifest loading, one sample JSON source, and focused Playwright coverage.
32+
33+
## Scope Guard
34+
35+
- No `start_of_day` files changed.
36+
- No unrelated tool schemas were changed.
37+
- No root queue wrapper or duplicated Text to Speech V2 root fields were reintroduced.

samples/metadata/samples.index.metadata.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3441,6 +3441,25 @@
34413441
"presetPath": "/samples/phase-19/1902/sample.1902.workspace-all-tools.json"
34423442
}
34433443
]
3444+
},
3445+
{
3446+
"id": "1903",
3447+
"phase": "19",
3448+
"title": "Text to Speech V2 JSON Source",
3449+
"description": "Text to Speech V2 sample that opens the tool with an explicit root-array JSON source for named speech items.",
3450+
"href": "./phase-19/1903/index.html",
3451+
"tags": ["text-to-speech", "audio", "json-source", "schema", "tool"],
3452+
"thumbnail": "/samples/phase-19/1903/assets/images/preview.svg",
3453+
"preview": "/samples/phase-19/1903/assets/images/preview.svg",
3454+
"classValues": [],
3455+
"engineClassesUsed": [],
3456+
"toolHints": ["text2speach-V2"],
3457+
"roundtripToolPresets": [
3458+
{
3459+
"toolId": "text2speach-V2",
3460+
"presetPath": "/samples/phase-19/1903/sample.1903.text2speach-V2.json"
3461+
}
3462+
]
34443463
}
34453464
]
34463465
}

samples/phase-19/1903/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<!-- SAMPLE_LOCAL_CONTRACT_README -->
2+
# Sample 1903 - Text to Speech V2 JSON Source
3+
4+
Sample-local contract for `samples/phase-19/1903`.
5+
6+
## Implementation Location
7+
8+
- Entrypoint: `samples/phase-19/1903/index.html`
9+
- Sample payload: `samples/phase-19/1903/sample.1903.text2speach-V2.json`
10+
- The payload is a Text to Speech V2 root array of named speech items and validates against `tools/schemas/tools/text2speach-V2.schema.json`.
11+
- The sample launches `/tools/text2speach-V2/index.html` with `samplePresetPath` pointing at the sample JSON.
12+
13+
## Discovery Contract
14+
15+
- This sample is valid because the physical folder `samples/phase-19/1903` exists and contains `index.html`.
16+
- Preview Generator V2 discovers samples by enumerating directories under `samples/phase-19` and keeping only four-digit child folders that contain `index.html`.
17+
- Use `FAIL` only after an existing discovered sample cannot be launched, rendered, captured, or written.
18+
19+
## Assets
20+
21+
- Preview and image assets belong under `samples/phase-19/1903/assets/images`.
22+
- Asset folder status: present.
Lines changed: 11 additions & 0 deletions
Loading

samples/phase-19/1903/index.html

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!--
2+
Toolbox Aid
3+
David Quesenberry
4+
05/11/2026
5+
index.html
6+
-->
7+
<!DOCTYPE html>
8+
<html lang="en">
9+
<head>
10+
<meta charset="UTF-8" />
11+
<title>Sample 1903 - Text to Speech V2 JSON Source</title>
12+
<link rel="stylesheet" href="../../../src/engine/ui/baseLayout.css" />
13+
<link rel="stylesheet" href="../../../src/engine/theme/main.css" />
14+
</head>
15+
<body class="hub-page-samples">
16+
<div id="shared-theme-header"></div>
17+
<main>
18+
<h1>Sample 1903 - Text to Speech V2 JSON Source</h1>
19+
<p>Text to Speech V2 sample that opens the tool with an explicit root-array JSON source for named speech items.</p>
20+
21+
<section class="sample-tool-roundtrip">
22+
<h3>Tool Launch</h3>
23+
<p>If auto-launch is blocked, open the tool manually:</p>
24+
<ul>
25+
<li><a id="textToSpeechLaunchLink" href="#">Open Text to Speech V2</a></li>
26+
</ul>
27+
<p>Tip: add <code>?stay=1</code> to this URL to stay on the sample page without auto-launch.</p>
28+
</section>
29+
</main>
30+
31+
<script type="module" src="/samples/shared/sampleDetailPageEnhancement.js"></script>
32+
<script type="module" src="./main.js"></script>
33+
<script type="module" src="../../../src/engine/theme/mount-shared-header.js"></script>
34+
</body>
35+
</html>

samples/phase-19/1903/main.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
Toolbox Aid
3+
David Quesenberry
4+
05/11/2026
5+
main.js
6+
*/
7+
8+
const TEXT_TO_SPEECH_PATH = "/tools/text2speach-V2/index.html";
9+
const TEXT_TO_SPEECH_SAMPLE_PRESET_PATH = "/samples/phase-19/1903/sample.1903.text2speach-V2.json";
10+
11+
function buildTextToSpeechHref() {
12+
const params = new URLSearchParams({
13+
sampleId: "1903",
14+
sampleTitle: "Text to Speech V2 JSON Source",
15+
samplePresetPath: TEXT_TO_SPEECH_SAMPLE_PRESET_PATH
16+
});
17+
return TEXT_TO_SPEECH_PATH + "?" + params.toString();
18+
}
19+
20+
function applyLaunchLink() {
21+
const link = document.getElementById("textToSpeechLaunchLink");
22+
if (link instanceof HTMLAnchorElement) {
23+
link.href = buildTextToSpeechHref();
24+
}
25+
}
26+
27+
function shouldAutoLaunch() {
28+
const params = new URLSearchParams(window.location.search);
29+
return params.get("stay") !== "1";
30+
}
31+
32+
function launchTextToSpeech() {
33+
if (shouldAutoLaunch()) {
34+
window.location.assign(buildTextToSpeechHref());
35+
}
36+
}
37+
38+
applyLaunchLink();
39+
launchTextToSpeech();
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
[
2+
{
3+
"id": "narrator-welcome",
4+
"name": "Narrator welcome",
5+
"text": "Welcome to Toolbox Aid. This is the default Text to Speech V2 sample line for previewing narration, prompts, and menu feedback.",
6+
"gender": "any",
7+
"language": "en-US",
8+
"voice": "mock-google-us-english",
9+
"voiceAge": "any",
10+
"volume": 1,
11+
"rate": 1,
12+
"pitch": 1,
13+
"queueMode": "replace",
14+
"characterPreset": "narrator",
15+
"ssmlLikePreset": "normal"
16+
},
17+
{
18+
"id": "hero-ready",
19+
"name": "Hero ready",
20+
"text": "Systems ready. The hero prompt is queued for an upbeat menu confirmation.",
21+
"gender": "male-preferred",
22+
"language": "en-GB",
23+
"voice": "mock-google-uk-english-male",
24+
"voiceAge": "teen",
25+
"volume": 1,
26+
"rate": 1.2,
27+
"pitch": 1.4,
28+
"queueMode": "append",
29+
"characterPreset": "dramatic",
30+
"ssmlLikePreset": "normal"
31+
},
32+
{
33+
"id": "alert-warning",
34+
"name": "Alert warning",
35+
"text": "Warning. Incoming hazard detected. Please confirm the next action.",
36+
"gender": "female-preferred",
37+
"language": "en-US",
38+
"voice": "mock-microsoft-zira",
39+
"voiceAge": "adult",
40+
"volume": 0.9,
41+
"rate": 1.3,
42+
"pitch": 0.9,
43+
"queueMode": "replace",
44+
"characterPreset": "alert",
45+
"ssmlLikePreset": "normal"
46+
}
47+
]

src/engine/audio/TextToSpeechDefaults.js

Lines changed: 1 addition & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -104,76 +104,22 @@ const TEXT_TO_SPEECH_DEFAULT_OPTIONS = Object.freeze({
104104
volume: TEXT_TO_SPEECH_CHARACTER_PRESET_DEFAULTS.manual.volume
105105
});
106106

107-
const TEXT_TO_SPEECH_DEFAULT_QUEUE = Object.freeze([
108-
Object.freeze({
109-
...TEXT_TO_SPEECH_DEFAULT_OPTIONS,
110-
...TEXT_TO_SPEECH_CHARACTER_PRESET_DEFAULTS.narrator,
111-
characterPreset: "narrator",
112-
gender: "any",
113-
id: "narrator-welcome",
114-
language: "en-US",
115-
name: "Narrator welcome",
116-
text: "Welcome to Toolbox Aid. This is the default Text to Speech V2 sample line for previewing narration, prompts, and menu feedback.",
117-
voice: "mock-google-us-english",
118-
voiceAge: "any"
119-
}),
120-
Object.freeze({
121-
...TEXT_TO_SPEECH_DEFAULT_OPTIONS,
122-
...TEXT_TO_SPEECH_CHARACTER_PRESET_DEFAULTS.dramatic,
123-
characterPreset: "dramatic",
124-
gender: "male-preferred",
125-
id: "hero-ready",
126-
language: "en-GB",
127-
name: "Hero ready",
128-
pitch: 1.4,
129-
queueMode: "append",
130-
rate: 1.2,
131-
text: "Systems ready. The hero prompt is queued for an upbeat menu confirmation.",
132-
voice: "mock-google-uk-english-male",
133-
voiceAge: "teen"
134-
}),
135-
Object.freeze({
136-
...TEXT_TO_SPEECH_DEFAULT_OPTIONS,
137-
...TEXT_TO_SPEECH_CHARACTER_PRESET_DEFAULTS.alert,
138-
characterPreset: "alert",
139-
gender: "female-preferred",
140-
id: "alert-warning",
141-
language: "en-US",
142-
name: "Alert warning",
143-
pitch: 0.9,
144-
queueMode: "replace",
145-
rate: 1.3,
146-
text: "Warning. Incoming hazard detected. Please confirm the next action.",
147-
voice: "mock-microsoft-zira",
148-
voiceAge: "adult",
149-
volume: 0.9
150-
})
151-
]);
152-
153-
const TEXT_TO_SPEECH_DEFAULT_QUEUE_DATA = TEXT_TO_SPEECH_DEFAULT_QUEUE;
154-
155107
const TEXT_TO_SPEECH_DEFAULTS = Object.freeze({
156-
...TEXT_TO_SPEECH_DEFAULT_OPTIONS,
157-
sampleText: TEXT_TO_SPEECH_DEFAULT_QUEUE[0].text
108+
...TEXT_TO_SPEECH_DEFAULT_OPTIONS
158109
});
159110

160-
const TEXT_TO_SPEECH_SAMPLE_TEXT = TEXT_TO_SPEECH_DEFAULTS.sampleText;
161-
162111
export {
163112
TEXT_TO_SPEECH_AGE_FILTER_OPTIONS,
164113
TEXT_TO_SPEECH_CHARACTER_PRESET_DEFAULTS,
165114
TEXT_TO_SPEECH_CHARACTER_PRESET_OPTIONS,
166115
TEXT_TO_SPEECH_DEFAULT_OPTIONS,
167-
TEXT_TO_SPEECH_DEFAULT_QUEUE,
168-
TEXT_TO_SPEECH_DEFAULT_QUEUE_DATA,
169116
TEXT_TO_SPEECH_DEFAULTS,
170117
TEXT_TO_SPEECH_DISPLAY_NAME,
171118
TEXT_TO_SPEECH_GENDER_FILTER_OPTIONS,
172119
TEXT_TO_SPEECH_LANGUAGE_OPTIONS,
173120
TEXT_TO_SPEECH_QUEUE_ITEM_REQUIRED_FIELDS,
174121
TEXT_TO_SPEECH_QUEUE_MODE_OPTIONS,
175122
TEXT_TO_SPEECH_RANGE_DEFAULTS,
176-
TEXT_TO_SPEECH_SAMPLE_TEXT,
177123
TEXT_TO_SPEECH_SCHEMA_ID,
178124
TEXT_TO_SPEECH_SSML_LIKE_PRESET_DEFAULTS,
179125
TEXT_TO_SPEECH_SSML_LIKE_PRESET_OPTIONS,

src/engine/audio/TextToSpeechEngine.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class TextToSpeechEngine {
104104
language = TEXT_TO_SPEECH_DEFAULTS.language,
105105
pitch = TEXT_TO_SPEECH_DEFAULTS.pitch,
106106
rate = TEXT_TO_SPEECH_DEFAULTS.rate,
107-
text = TEXT_TO_SPEECH_DEFAULTS.sampleText,
107+
text = "",
108108
voice = TEXT_TO_SPEECH_DEFAULTS.voice,
109109
volume = TEXT_TO_SPEECH_DEFAULTS.volume
110110
} = {}) {
@@ -156,7 +156,7 @@ class TextToSpeechEngine {
156156
speechItemId = "",
157157
speechItemName = "",
158158
ssmlLikePreset = TEXT_TO_SPEECH_DEFAULTS.ssmlLikePreset,
159-
text = TEXT_TO_SPEECH_DEFAULTS.sampleText,
159+
text = "",
160160
voice = TEXT_TO_SPEECH_DEFAULTS.voice,
161161
voiceAge = TEXT_TO_SPEECH_DEFAULTS.voiceAge,
162162
volume = TEXT_TO_SPEECH_DEFAULTS.volume

0 commit comments

Comments
 (0)