[Wake/VAD/STT 与 Live runtime]:完成真实重复语音运行,包含云端ASR/TTS开关、run-live和临时上下文测试
This commit is contained in:
@@ -12,11 +12,12 @@ from .conversation import ConversationContext
|
||||
from .llm import MockLlmProvider, OpenAICompatibleLlmProvider
|
||||
from .models import AudioFrame, ProviderError
|
||||
from .pipeline import VoicePipeline
|
||||
from .runtime import build_live_runtime
|
||||
from .speech_models import check_speech_models, model_status_errors
|
||||
from .stt import MetadataSttProvider
|
||||
from .stt import MetadataSttProvider, SherpaOnnxSttProvider
|
||||
from .transport import MemoryAudioTransport, sounddevice_device_report
|
||||
from .tts import SineTtsProvider
|
||||
from .vad import EnergyVadProvider, VadRecorder
|
||||
from .vad import EnergyVadProvider, SherpaOnnxVadProvider, VadRecorder
|
||||
from .wakeword import KeywordWakeWordProvider
|
||||
|
||||
|
||||
@@ -31,6 +32,8 @@ def main(argv: list[str] | None = None) -> int:
|
||||
model_check = subparsers.add_parser("model-check", help="Validate local speech model files")
|
||||
model_check.add_argument("--models-dir", default=None, help="Speech models directory. Defaults to .env or models")
|
||||
subparsers.add_parser("device-check", help="Validate local microphone and speaker availability")
|
||||
live = subparsers.add_parser("run-live", help="Run real repeated live voice conversation")
|
||||
live.add_argument("--once", action="store_true", help="Run one completed live turn and exit")
|
||||
smoke = subparsers.add_parser("llm-smoke", help="Call configured OpenAI/NewAPI endpoint")
|
||||
smoke.add_argument("--message", default="用一句中文回复:小杰在线。")
|
||||
smoke.add_argument("--no-stream", action="store_true")
|
||||
@@ -50,6 +53,10 @@ def main(argv: list[str] | None = None) -> int:
|
||||
"llm_stream": config.llm_stream,
|
||||
"llm_api_key_present": bool(config.llm_api_key),
|
||||
"asset_dir": str(config.asset_dir),
|
||||
"speech_provider": config.speech_provider,
|
||||
"asr_model": config.asr_model,
|
||||
"tts_model": config.tts_model,
|
||||
"tts_voice": config.tts_voice,
|
||||
"speech_models_dir": str(config.speech_models_dir),
|
||||
},
|
||||
ensure_ascii=False,
|
||||
@@ -73,8 +80,17 @@ def main(argv: list[str] | None = None) -> int:
|
||||
models_dir = Path(args.models_dir) if args.models_dir else config.speech_models_dir
|
||||
status = check_speech_models(models_dir, require_sherpa=True)
|
||||
errors = model_status_errors(status)
|
||||
provider_load_checked = False
|
||||
if not errors:
|
||||
try:
|
||||
SherpaOnnxVadProvider(models_dir).load()
|
||||
SherpaOnnxSttProvider(str(models_dir)).load()
|
||||
provider_load_checked = True
|
||||
except ProviderError as exc:
|
||||
errors.append(exc)
|
||||
data = status.to_json()
|
||||
data["errors"] = [str(error) for error in errors]
|
||||
data["provider_load_checked"] = provider_load_checked
|
||||
print(json.dumps(data, ensure_ascii=False, sort_keys=True))
|
||||
return 1 if errors else 0
|
||||
|
||||
@@ -83,6 +99,15 @@ def main(argv: list[str] | None = None) -> int:
|
||||
print(json.dumps(report, ensure_ascii=False, sort_keys=True))
|
||||
return 0 if report["ok"] else 1
|
||||
|
||||
if args.command == "run-live":
|
||||
config = AppConfig.from_dotenv(args.env_file)
|
||||
try:
|
||||
summary = build_live_runtime(config).run(once=args.once)
|
||||
except ProviderError as exc:
|
||||
print(json.dumps({"ok": False, "code": exc.code.value, "message": exc.message}, ensure_ascii=False, sort_keys=True))
|
||||
return 1
|
||||
return 0 if summary.completed_turns > 0 or summary.interrupted else 1
|
||||
|
||||
if args.command == "acceptance":
|
||||
result = run_acceptance()
|
||||
print(json.dumps(result, ensure_ascii=False, sort_keys=True))
|
||||
@@ -104,6 +129,10 @@ def main(argv: list[str] | None = None) -> int:
|
||||
audio_output_device=config.audio_output_device,
|
||||
asset_dir=config.asset_dir,
|
||||
log_dir=config.log_dir,
|
||||
speech_provider=config.speech_provider,
|
||||
asr_model=config.asr_model,
|
||||
tts_model=config.tts_model,
|
||||
tts_voice=config.tts_voice,
|
||||
speech_models_dir=config.speech_models_dir,
|
||||
context_max_messages=config.context_max_messages,
|
||||
context_max_chars=config.context_max_chars,
|
||||
@@ -155,7 +184,7 @@ def run_acceptance() -> dict[str, object]:
|
||||
|
||||
def find_secret_leaks(root: Path) -> list[str]:
|
||||
completed = subprocess.run(["git", "ls-files"], cwd=root, check=True, stdout=subprocess.PIPE, text=True)
|
||||
pattern = re.compile(r"sk-[A-Za-z0-9_\\-]{16,}")
|
||||
pattern = re.compile(r"(?:sk|tp)-[A-Za-z0-9_\\-]{16,}")
|
||||
leaks: list[str] = []
|
||||
for rel in completed.stdout.splitlines():
|
||||
path = root / rel
|
||||
|
||||
Reference in New Issue
Block a user