feat(aihr): complete M3 protected practice replay

This commit is contained in:
2026-07-23 22:21:43 +08:00
parent 83f775faec
commit 067cc30d80
11 changed files with 413 additions and 47 deletions
+21 -1
View File
@@ -68,6 +68,26 @@ test('语音 profile 透传方言枚举,并保持普通话默认值', async ()
assert.match(speechService, /dialect === 'sichuanese'[\s\S]*?当前设备语音不支持四川话/);
});
test('M3 将业主 TTS 绑定到当前训练会话与准确回合,供主管复盘回放', async () => {
const [practicePage, speechService, apiTypes] = await Promise.all([
pageSource('../src/pages/user/practice/index.vue'),
pageSource('../src/services/speech.ts'),
pageSource('../src/types/api.ts')
]);
assert.match(apiTypes, /export interface PracticeTtsContext/);
assert.match(speechService, /practiceContext\?: PracticeTtsContext/);
assert.match(speechService, /data: \{ text: text\.trim\(\)\.slice\(0, 300\), voiceProfile, practiceContext \}/);
assert.match(practicePage, /\{ sessionId: sessionId\.value, turnIndex: Number\(customerTurnIndex\), role: 'customer' \}/);
assert.match(practicePage, /speechPlayback\.preload\(spoken, profile, practiceContext\)/);
assert.match(practicePage, /turnVoice\(index\)\.profile, turnVoice\(index\)\.practiceContext/);
assert.match(practicePage, /let turnVoiceGeneration = 0/);
assert.match(practicePage, /turnVoiceGeneration === generation && turnVoices\.value\[index\]\?\.requestKey === requestKey/);
assert.match(practicePage, /turnVoiceGeneration \+= 1/);
assert.match(practicePage, /appendTurn\('customer', data\.customerText, data\.emotion, true, 0\)/);
assert.match(practicePage, /appendTurn\('customer', data\.customerText, data\.emotion, true, data\.roundIndex\)/);
});
test('训练结果回到顶部,SOP 答案生成后定位到回答区', async () => {
const [practiceSource, sopSource, navigationSource] = await Promise.all([
pageSource('../src/pages/user/practice/index.vue'),
@@ -560,7 +580,7 @@ test('播报复用已合成音频且总结图按内容高度生成并及时释
assert.match(speechService, /const sourceCache = new Map<string, string>\(\)/);
assert.match(speechService, /const maxCachedSources = 4/);
assert.match(speechService, /const sourceKey = cacheKey\(value, profile\)/);
assert.match(speechService, /const sourceKey = cacheKey\(value, profile, practiceContext\)/);
assert.match(speechService, /const cachedSource = sourceCache\.get\(sourceKey\)/);
assert.match(speechService, /sourceCache\.clear\(\)/);
assert.match(speechService, /registerAbort\?\.\(\(\) => task\.abort\(\)\)/);