oomi-ai 0.2.49 → 0.3.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 +227 -463
- package/agent_instructions.md +244 -234
- package/bin/oomi-ai.js +4028 -5797
- package/bin/sessionBridgeState.js +78 -78
- package/lib/openclawPaths.js +70 -71
- package/lib/openclawProfile.js +216 -216
- package/lib/personaApiClient.js +133 -303
- package/lib/spokenMetadata.js +137 -137
- package/openclaw.extension.js +341 -341
- package/openclaw.plugin.json +17 -17
- package/package.json +59 -59
- package/persona-app/README.md +27 -0
- package/persona-app/registry/v1.json +63 -0
- package/persona-app/schema/persona-app.v1.schema.json +90 -0
- package/skills/oomi/SKILL.md +165 -182
- package/skills/oomi/agent_instructions.md +99 -80
- package/lib/channelPluginClient.js +0 -119
- package/lib/openclawDevGateway.js +0 -384
- package/lib/personaJobExecutor.js +0 -139
- package/lib/personaJobPoller.js +0 -112
- package/lib/personaPortAllocator.js +0 -36
- package/lib/personaRuntimeManager.js +0 -496
- package/lib/personaRuntimeProcess.js +0 -924
- package/lib/personaRuntimeRegistry.js +0 -67
- package/lib/personaRuntimeSupervisor.js +0 -330
- package/lib/scaffold.js +0 -108
- package/lib/template.js +0 -45
- package/skills/oomi/config.json +0 -3
- package/skills/oomi/scripts/get_avatar_capabilities.py +0 -40
- package/skills/oomi/scripts/get_data.py +0 -49
- package/skills/oomi/scripts/install_agent_instructions.py +0 -78
- package/skills/oomi/scripts/send_goal.py +0 -53
- package/skills/oomi/scripts/sync.py +0 -46
- package/skills/oomi/setup.py +0 -41
- package/templates/persona-app/.env.example +0 -8
- package/templates/persona-app/README.md +0 -47
- package/templates/persona-app/eslint.config.js +0 -28
- package/templates/persona-app/index.html +0 -18
- package/templates/persona-app/oomi.runtime.json +0 -13
- package/templates/persona-app/package.json +0 -44
- package/templates/persona-app/persona/brief.md +0 -14
- package/templates/persona-app/persona.json +0 -14
- package/templates/persona-app/public/manifest.webmanifest +0 -8
- package/templates/persona-app/public/oomi.health.json +0 -6
- package/templates/persona-app/src/App.css +0 -379
- package/templates/persona-app/src/App.tsx +0 -17
- package/templates/persona-app/src/index.css +0 -53
- package/templates/persona-app/src/main.tsx +0 -23
- package/templates/persona-app/src/pages/HomePage.tsx +0 -127
- package/templates/persona-app/src/pages/ScenePage.tsx +0 -158
- package/templates/persona-app/src/persona/config.ts +0 -6
- package/templates/persona-app/src/persona/notes.ts +0 -9
- package/templates/persona-app/src/spatial.ts +0 -82
- package/templates/persona-app/src/vite-env.d.ts +0 -3
- package/templates/persona-app/template.json +0 -13
- package/templates/persona-app/tsconfig.app.json +0 -23
- package/templates/persona-app/tsconfig.json +0 -7
- package/templates/persona-app/tsconfig.node.json +0 -21
- package/templates/persona-app/vendor/webspatial/FORK.md +0 -6
- package/templates/persona-app/vendor/webspatial/core-sdk/LICENSE +0 -21
- package/templates/persona-app/vendor/webspatial/core-sdk/dist/iife/index.d.ts +0 -906
- package/templates/persona-app/vendor/webspatial/core-sdk/dist/iife/index.global.js +0 -75
- package/templates/persona-app/vendor/webspatial/core-sdk/dist/iife/index.global.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/core-sdk/dist/index.d.ts +0 -906
- package/templates/persona-app/vendor/webspatial/core-sdk/dist/index.js +0 -3131
- package/templates/persona-app/vendor/webspatial/core-sdk/dist/index.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/core-sdk/package.json +0 -45
- package/templates/persona-app/vendor/webspatial/react-sdk/LICENSE +0 -21
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/default/index.d.ts +0 -365
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/default/index.js +0 -4167
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/default/index.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.d.ts +0 -82
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.js +0 -66
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.web.d.ts +0 -2
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.web.js +0 -18
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.web.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.d.ts +0 -5
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.js +0 -66
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.web.d.ts +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.web.js +0 -18
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.web.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/web/index.d.ts +0 -365
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/web/index.js +0 -4207
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/web/index.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/package.json +0 -94
- package/templates/persona-app/vite.config.ts +0 -31
package/lib/spokenMetadata.js
CHANGED
|
@@ -7,66 +7,66 @@ const ELLIPSIS_PLACEHOLDER = '__OOMI_ELLIPSIS__';
|
|
|
7
7
|
function stripAvatarCommandTags(text) {
|
|
8
8
|
return text.replace(/\[(anim|animation|face|expression|emotion|gesture|look|gaze):[^\]]+\]/gi, ' ');
|
|
9
9
|
}
|
|
10
|
-
|
|
11
|
-
function clampInteger(value, fallback, { min = 1, max = Number.MAX_SAFE_INTEGER } = {}) {
|
|
12
|
-
if (typeof value !== 'number' || !Number.isFinite(value)) return fallback;
|
|
13
|
-
const normalized = Math.floor(value);
|
|
14
|
-
if (normalized < min) return fallback;
|
|
15
|
-
if (normalized > max) return max;
|
|
16
|
-
return normalized;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const BOUNDED_LANGUAGE_TYPES = new Set([
|
|
20
|
-
'Auto',
|
|
21
|
-
'Chinese',
|
|
22
|
-
'English',
|
|
23
|
-
'German',
|
|
24
|
-
'Italian',
|
|
25
|
-
'Portuguese',
|
|
26
|
-
'Spanish',
|
|
27
|
-
'Japanese',
|
|
28
|
-
'Korean',
|
|
29
|
-
'French',
|
|
30
|
-
'Russian',
|
|
31
|
-
]);
|
|
32
|
-
|
|
33
|
-
const BOUNDED_PACE_VALUES = new Set(['very_slow', 'slow', 'medium', 'medium_fast', 'fast']);
|
|
34
|
-
const BOUNDED_PITCH_VALUES = new Set(['low', 'slightly_low', 'neutral', 'slightly_high', 'high']);
|
|
35
|
-
const BOUNDED_ENERGY_VALUES = new Set(['soft', 'calm', 'warm', 'bright', 'intense']);
|
|
36
|
-
const BOUNDED_VOLUME_VALUES = new Set(['soft', 'normal', 'projected']);
|
|
37
|
-
|
|
38
|
-
function inferSpokenLanguage(text) {
|
|
39
|
-
const normalized = trimString(text);
|
|
40
|
-
if (!normalized) return 'English';
|
|
41
|
-
return 'English';
|
|
42
|
-
}
|
|
43
|
-
|
|
10
|
+
|
|
11
|
+
function clampInteger(value, fallback, { min = 1, max = Number.MAX_SAFE_INTEGER } = {}) {
|
|
12
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) return fallback;
|
|
13
|
+
const normalized = Math.floor(value);
|
|
14
|
+
if (normalized < min) return fallback;
|
|
15
|
+
if (normalized > max) return max;
|
|
16
|
+
return normalized;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const BOUNDED_LANGUAGE_TYPES = new Set([
|
|
20
|
+
'Auto',
|
|
21
|
+
'Chinese',
|
|
22
|
+
'English',
|
|
23
|
+
'German',
|
|
24
|
+
'Italian',
|
|
25
|
+
'Portuguese',
|
|
26
|
+
'Spanish',
|
|
27
|
+
'Japanese',
|
|
28
|
+
'Korean',
|
|
29
|
+
'French',
|
|
30
|
+
'Russian',
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
const BOUNDED_PACE_VALUES = new Set(['very_slow', 'slow', 'medium', 'medium_fast', 'fast']);
|
|
34
|
+
const BOUNDED_PITCH_VALUES = new Set(['low', 'slightly_low', 'neutral', 'slightly_high', 'high']);
|
|
35
|
+
const BOUNDED_ENERGY_VALUES = new Set(['soft', 'calm', 'warm', 'bright', 'intense']);
|
|
36
|
+
const BOUNDED_VOLUME_VALUES = new Set(['soft', 'normal', 'projected']);
|
|
37
|
+
|
|
38
|
+
function inferSpokenLanguage(text) {
|
|
39
|
+
const normalized = trimString(text);
|
|
40
|
+
if (!normalized) return 'English';
|
|
41
|
+
return 'English';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
44
|
function normalizeSpokenSegment(segment) {
|
|
45
45
|
if (!segment || typeof segment !== 'object' || Array.isArray(segment)) return null;
|
|
46
46
|
|
|
47
47
|
const text = normalizeSpeechText(trimString(segment.text));
|
|
48
48
|
if (!text) return null;
|
|
49
|
-
|
|
50
|
-
const normalized = { text };
|
|
51
|
-
const pace = trimString(segment.pace);
|
|
52
|
-
const pitch = trimString(segment.pitch);
|
|
53
|
-
const energy = trimString(segment.energy);
|
|
54
|
-
const volume = trimString(segment.volume);
|
|
55
|
-
const pauseAfterMs = clampInteger(segment.pause_after_ms, 0, { min: 0, max: 1200 });
|
|
56
|
-
|
|
57
|
-
if (BOUNDED_PACE_VALUES.has(pace)) normalized.pace = pace;
|
|
58
|
-
if (BOUNDED_PITCH_VALUES.has(pitch)) normalized.pitch = pitch;
|
|
59
|
-
if (BOUNDED_ENERGY_VALUES.has(energy)) normalized.energy = energy;
|
|
60
|
-
if (BOUNDED_VOLUME_VALUES.has(volume)) normalized.volume = volume;
|
|
61
|
-
normalized.pause_after_ms = pauseAfterMs;
|
|
62
|
-
|
|
63
|
-
return normalized;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function stripEmoji(text) {
|
|
67
|
-
return text.replace(/[\uFE0E\uFE0F]/g, '').replace(/\p{Extended_Pictographic}|\p{Emoji_Presentation}/gu, '');
|
|
68
|
-
}
|
|
69
|
-
|
|
49
|
+
|
|
50
|
+
const normalized = { text };
|
|
51
|
+
const pace = trimString(segment.pace);
|
|
52
|
+
const pitch = trimString(segment.pitch);
|
|
53
|
+
const energy = trimString(segment.energy);
|
|
54
|
+
const volume = trimString(segment.volume);
|
|
55
|
+
const pauseAfterMs = clampInteger(segment.pause_after_ms, 0, { min: 0, max: 1200 });
|
|
56
|
+
|
|
57
|
+
if (BOUNDED_PACE_VALUES.has(pace)) normalized.pace = pace;
|
|
58
|
+
if (BOUNDED_PITCH_VALUES.has(pitch)) normalized.pitch = pitch;
|
|
59
|
+
if (BOUNDED_ENERGY_VALUES.has(energy)) normalized.energy = energy;
|
|
60
|
+
if (BOUNDED_VOLUME_VALUES.has(volume)) normalized.volume = volume;
|
|
61
|
+
normalized.pause_after_ms = pauseAfterMs;
|
|
62
|
+
|
|
63
|
+
return normalized;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function stripEmoji(text) {
|
|
67
|
+
return text.replace(/[\uFE0E\uFE0F]/g, '').replace(/\p{Extended_Pictographic}|\p{Emoji_Presentation}/gu, '');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
70
|
function normalizeSpeechText(text) {
|
|
71
71
|
return stripEmoji(stripAvatarCommandTags(text))
|
|
72
72
|
.replace(/\*\*(.*?)\*\*/g, '$1')
|
|
@@ -85,7 +85,7 @@ function normalizeSpeechText(text) {
|
|
|
85
85
|
.replace(/\s+/g, ' ')
|
|
86
86
|
.trim();
|
|
87
87
|
}
|
|
88
|
-
|
|
88
|
+
|
|
89
89
|
function splitSpeechSegments(text) {
|
|
90
90
|
const normalized = normalizeSpeechText(text);
|
|
91
91
|
if (!normalized) return [];
|
|
@@ -94,14 +94,14 @@ function splitSpeechSegments(text) {
|
|
|
94
94
|
.split(/(?<=[.!?])\s+|\n+/)
|
|
95
95
|
.map((segment) => segment.trim())
|
|
96
96
|
.filter(Boolean);
|
|
97
|
-
|
|
98
|
-
const segments = [];
|
|
99
|
-
for (const segment of baseSegments) {
|
|
100
|
-
if (segment.length <= 96) {
|
|
101
|
-
segments.push(segment);
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
104
|
-
|
|
97
|
+
|
|
98
|
+
const segments = [];
|
|
99
|
+
for (const segment of baseSegments) {
|
|
100
|
+
if (segment.length <= 96) {
|
|
101
|
+
segments.push(segment);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
105
|
const clauseParts = segment
|
|
106
106
|
.split(/(?<=[,;:])\s+/)
|
|
107
107
|
.map((part) => part.trim())
|
|
@@ -113,15 +113,15 @@ function splitSpeechSegments(text) {
|
|
|
113
113
|
}
|
|
114
114
|
continue;
|
|
115
115
|
}
|
|
116
|
-
|
|
117
|
-
segments.push(segment);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if (segments.length <= 5) return segments;
|
|
121
|
-
|
|
122
|
-
return [...segments.slice(0, 4), segments.slice(4).join(' ').trim()];
|
|
123
|
-
}
|
|
124
|
-
|
|
116
|
+
|
|
117
|
+
segments.push(segment);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (segments.length <= 5) return segments;
|
|
121
|
+
|
|
122
|
+
return [...segments.slice(0, 4), segments.slice(4).join(' ').trim()];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
125
|
function inferSegmentStyle(segmentText, index, totalSegments) {
|
|
126
126
|
const normalized = segmentText.toLowerCase();
|
|
127
127
|
const greeting = /^(hey|hi|hello|yo)\b/.test(normalized);
|
|
@@ -151,9 +151,9 @@ function inferSegmentStyle(segmentText, index, totalSegments) {
|
|
|
151
151
|
pause_after_ms: 0,
|
|
152
152
|
};
|
|
153
153
|
}
|
|
154
|
-
|
|
155
|
-
if (exclamatory) {
|
|
156
|
-
return {
|
|
154
|
+
|
|
155
|
+
if (exclamatory) {
|
|
156
|
+
return {
|
|
157
157
|
pace: 'medium_fast',
|
|
158
158
|
pitch: 'slightly_high',
|
|
159
159
|
energy: 'bright',
|
|
@@ -178,75 +178,75 @@ function inferSegmentStyle(segmentText, index, totalSegments) {
|
|
|
178
178
|
energy: 'warm',
|
|
179
179
|
volume: 'normal',
|
|
180
180
|
pause_after_ms: index < totalSegments - 1 ? 180 : 0,
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
function synthesizeSpokenSegments(text) {
|
|
185
|
-
const language = inferSpokenLanguage(text);
|
|
186
|
-
const rawSegments = splitSpeechSegments(text);
|
|
187
|
-
if (rawSegments.length === 0) return null;
|
|
188
|
-
|
|
189
|
-
const segments = rawSegments.map((segmentText, index) => ({
|
|
190
|
-
text: segmentText,
|
|
191
|
-
...inferSegmentStyle(segmentText, index, rawSegments.length),
|
|
192
|
-
}));
|
|
193
|
-
|
|
194
|
-
return {
|
|
195
|
-
language,
|
|
196
|
-
segments,
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function synthesizeSpokenSegments(text) {
|
|
185
|
+
const language = inferSpokenLanguage(text);
|
|
186
|
+
const rawSegments = splitSpeechSegments(text);
|
|
187
|
+
if (rawSegments.length === 0) return null;
|
|
188
|
+
|
|
189
|
+
const segments = rawSegments.map((segmentText, index) => ({
|
|
190
|
+
text: segmentText,
|
|
191
|
+
...inferSegmentStyle(segmentText, index, rawSegments.length),
|
|
192
|
+
}));
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
language,
|
|
196
|
+
segments,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
200
|
function normalizeSpokenMetadata(spoken) {
|
|
201
201
|
if (!spoken || typeof spoken !== 'object' || Array.isArray(spoken)) return null;
|
|
202
202
|
|
|
203
203
|
const text = normalizeSpeechText(trimString(spoken.text));
|
|
204
204
|
if (!text) return null;
|
|
205
|
-
|
|
206
|
-
const normalized = { text };
|
|
207
|
-
const language = trimString(spoken.language);
|
|
208
|
-
if (BOUNDED_LANGUAGE_TYPES.has(language)) {
|
|
209
|
-
normalized.language = language;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
const explicitSegments =
|
|
213
|
-
Array.isArray(spoken.segments)
|
|
214
|
-
? spoken.segments.map((segment) => normalizeSpokenSegment(segment)).filter(Boolean)
|
|
215
|
-
: [];
|
|
216
|
-
if (explicitSegments.length > 0) {
|
|
217
|
-
normalized.segments = explicitSegments;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
const instructions = trimString(spoken.instructions);
|
|
221
|
-
if (instructions) normalized.instructions = instructions;
|
|
222
|
-
if (spoken.style && typeof spoken.style === 'object' && !Array.isArray(spoken.style)) {
|
|
223
|
-
normalized.style = spoken.style;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
const fallbackSegments = synthesizeSpokenSegments(text);
|
|
227
|
-
if (!normalized.language && fallbackSegments?.language) {
|
|
228
|
-
normalized.language = fallbackSegments.language;
|
|
229
|
-
}
|
|
230
|
-
if (!normalized.segments && fallbackSegments?.segments?.length) {
|
|
231
|
-
normalized.segments = fallbackSegments.segments;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
return normalized;
|
|
235
|
-
}
|
|
236
|
-
|
|
205
|
+
|
|
206
|
+
const normalized = { text };
|
|
207
|
+
const language = trimString(spoken.language);
|
|
208
|
+
if (BOUNDED_LANGUAGE_TYPES.has(language)) {
|
|
209
|
+
normalized.language = language;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const explicitSegments =
|
|
213
|
+
Array.isArray(spoken.segments)
|
|
214
|
+
? spoken.segments.map((segment) => normalizeSpokenSegment(segment)).filter(Boolean)
|
|
215
|
+
: [];
|
|
216
|
+
if (explicitSegments.length > 0) {
|
|
217
|
+
normalized.segments = explicitSegments;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const instructions = trimString(spoken.instructions);
|
|
221
|
+
if (instructions) normalized.instructions = instructions;
|
|
222
|
+
if (spoken.style && typeof spoken.style === 'object' && !Array.isArray(spoken.style)) {
|
|
223
|
+
normalized.style = spoken.style;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const fallbackSegments = synthesizeSpokenSegments(text);
|
|
227
|
+
if (!normalized.language && fallbackSegments?.language) {
|
|
228
|
+
normalized.language = fallbackSegments.language;
|
|
229
|
+
}
|
|
230
|
+
if (!normalized.segments && fallbackSegments?.segments?.length) {
|
|
231
|
+
normalized.segments = fallbackSegments.segments;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return normalized;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
237
|
function inferSpokenMetadataFromContent(content) {
|
|
238
238
|
const text = normalizeSpeechText(trimString(content));
|
|
239
239
|
if (!text) return null;
|
|
240
240
|
const synthesized = synthesizeSpokenSegments(text);
|
|
241
|
-
|
|
242
|
-
const normalized = text.toLowerCase();
|
|
243
|
-
const upbeat =
|
|
244
|
-
/!/.test(text) ||
|
|
245
|
-
/\b(hell yeah|awesome|amazing|great|stoked|love|glad|perfect|nice|cool)\b/.test(normalized);
|
|
246
|
-
const gentle =
|
|
247
|
-
/\b(sorry|gentle|softly|careful|reassuring|calm|okay|it'?s okay|i know)\b/.test(normalized);
|
|
248
|
-
const curious = /\?/.test(text);
|
|
249
|
-
|
|
241
|
+
|
|
242
|
+
const normalized = text.toLowerCase();
|
|
243
|
+
const upbeat =
|
|
244
|
+
/!/.test(text) ||
|
|
245
|
+
/\b(hell yeah|awesome|amazing|great|stoked|love|glad|perfect|nice|cool)\b/.test(normalized);
|
|
246
|
+
const gentle =
|
|
247
|
+
/\b(sorry|gentle|softly|careful|reassuring|calm|okay|it'?s okay|i know)\b/.test(normalized);
|
|
248
|
+
const curious = /\?/.test(text);
|
|
249
|
+
|
|
250
250
|
if (upbeat) {
|
|
251
251
|
return normalizeSpokenMetadata({
|
|
252
252
|
text,
|
|
@@ -285,7 +285,7 @@ function inferSpokenMetadataFromContent(content) {
|
|
|
285
285
|
style: { emotion: 'neutral', energy: 'medium' },
|
|
286
286
|
});
|
|
287
287
|
}
|
|
288
|
-
|
|
288
|
+
|
|
289
289
|
export {
|
|
290
290
|
inferSpokenMetadataFromContent,
|
|
291
291
|
normalizeSpokenMetadata,
|