feat: 重做阅读找答案题与 AI 情境对话,并归拢本地识别、查词等既有改动
阅读"在对话里找到答案": - 16 道题全部重写,干扰项真实出现在对话里,靠说话人归属或否定句才能作答 - 选项按题目内容确定性打乱,答案不再固定排第一;听力环节同样处理 - 去掉超纲干扰项、重复题干,收紧自由作答匹配(过去单个字母也能判对) AI 情境对话: - 提示词区分"AI 这一句要做什么"与"学习者随后要完成什么",并下发已教词句清单 - JSON 只强制 reply,translation/feedback 可选;不再索要用不上的 slots/evidence - AI 不可用时页面明确提示当前回复来自内置示范脚本 - 删掉按 stage 下标猜中文翻译的兜底,避免译文与英文对不上 - 整课对话改用逐轮必需表达校验,替换"关键词沾边就算过";修正自由场景正则误伤 - 总结的"完成任务"按实际通过的轮次生成;模型点评只在结束页呈现一次 - 自由场景支持草稿续练(独立存储槽);修正回答轮数文案与永不解锁的场景标注 同时提交此前工作区中累积的改动:SenseVoice 本地识别、查词/句型解析卡、 复习与测评页调整等,并补充对话校验、选项分布和句子解析的测试。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,20 +1,32 @@
|
||||
// ignore_for_file: avoid_print
|
||||
import 'dart:io';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:kouyu_english/core/sherpa_stt_service.dart';
|
||||
import 'package:sherpa_onnx/sherpa_onnx.dart' as sherpa_onnx;
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
final home = Platform.environment['HOME'] ?? '';
|
||||
final pubCache = Platform.environment['PUB_CACHE'] ?? '$home/.pub-cache';
|
||||
final candidateDirs = [
|
||||
'$pubCache/hosted/pub.dev/sherpa_onnx_macos-1.13.8/macos',
|
||||
'$home/.pub-cache/hosted/pub.dev/sherpa_onnx_macos-1.13.8/macos',
|
||||
'/Users/shenlei/.pub-cache/hosted/pub.dev/sherpa_onnx_macos-1.13.8/macos',
|
||||
];
|
||||
final macosDir = candidateDirs.firstWhere(
|
||||
(d) => Directory(d).existsSync(),
|
||||
orElse: () => candidateDirs.first,
|
||||
);
|
||||
|
||||
test('SenseVoice-Small ONNX transcribes WAV audio file accurately', () async {
|
||||
const macosDir = '/Users/shen/.pub-cache/hosted/pub.dev/sherpa_onnx_macos-1.13.8/macos';
|
||||
|
||||
// Test direct Sherpa ASR initialization and decoding with SenseVoice
|
||||
sherpa_onnx.initBindings(macosDir);
|
||||
|
||||
final modelConfig = sherpa_onnx.OfflineModelConfig(
|
||||
senseVoice: const sherpa_onnx.OfflineSenseVoiceModelConfig(
|
||||
model: 'assets/models/sense_voice/model.int8.onnx',
|
||||
language: 'auto',
|
||||
language: 'en',
|
||||
useInverseTextNormalization: true,
|
||||
),
|
||||
tokens: 'assets/models/sense_voice/tokens.txt',
|
||||
@@ -38,10 +50,26 @@ void main() {
|
||||
stream.acceptWaveform(samples: wave.samples, sampleRate: wave.sampleRate);
|
||||
recognizer.decode(stream);
|
||||
final result = recognizer.getResult(stream);
|
||||
print("SenseVoice transcribed result: ${result.text}");
|
||||
expect(result.text.toLowerCase().contains("nightfall"), isTrue);
|
||||
print('SenseVoice transcribed result: ${result.text}');
|
||||
expect(result.text.toLowerCase().contains('nightfall'), isTrue);
|
||||
stream.free();
|
||||
}
|
||||
recognizer.free();
|
||||
});
|
||||
|
||||
test('SherpaSttService singleton initializes and transcribes cleanly', () async {
|
||||
final ready = await SherpaSttService.instance.initialize(nativeLibDir: macosDir);
|
||||
expect(ready, isTrue);
|
||||
expect(SherpaSttService.instance.isReady, isTrue);
|
||||
|
||||
const testWave = '/tmp/sherpa_test/sherpa-onnx-zipformer-small-en-2023-06-26/test_wavs/0.wav';
|
||||
if (File(testWave).existsSync()) {
|
||||
final transcribed = await SherpaSttService.instance.transcribeWav(testWave);
|
||||
expect(transcribed, isNotNull);
|
||||
print('SherpaSttService transcribed: $transcribed');
|
||||
expect(transcribed!.toLowerCase().contains('nightfall'), isTrue);
|
||||
// SenseVoice tags should be stripped
|
||||
expect(transcribed.contains('<|'), isFalse);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user