diff --git a/examples/voice-agent-local-sherpa/package.json b/examples/voice-agent-local-sherpa/package.json index b0bc046..54a6257 100644 --- a/examples/voice-agent-local-sherpa/package.json +++ b/examples/voice-agent-local-sherpa/package.json @@ -27,6 +27,8 @@ "download-tts:es": "node scripts/download-tts.mjs --lang=es", "download-tts:de": "node scripts/download-tts.mjs --lang=de", "download-tts:zh": "node scripts/download-tts.mjs --lang=zh", + "download-all": "node scripts/download-all-sherpa.mjs", + "download-all:minimal": "node scripts/download-all-sherpa.mjs --minimal", "start": "bash ../../scripts/export-sherpa-local-models.sh -- tsx src/index.ts", "start:roundtrip": "bash ../../scripts/export-sherpa-local-models.sh -- tsx src/roundtrip.ts", "start:roundtrip-counting": "bash ../../scripts/export-sherpa-local-models.sh -- tsx src/roundtrip-counting.ts", diff --git a/examples/voice-agent-local-sherpa/scripts/download-all-sherpa.mjs b/examples/voice-agent-local-sherpa/scripts/download-all-sherpa.mjs new file mode 100644 index 0000000..404a069 --- /dev/null +++ b/examples/voice-agent-local-sherpa/scripts/download-all-sherpa.mjs @@ -0,0 +1,83 @@ +#!/usr/bin/env node +/** + * Download every Sherpa STT/TTS bundle offered in the platform voice catalog + * (same ids as GET /api/v1/voice/models and deploy make bm-sherpa-models). + * + * npm run download-all --workspace=@node-webrtc-rust/example-voice-agent-local-sherpa + * npm run download-all:minimal --workspace=@node-webrtc-rust/example-voice-agent-local-sherpa + * + * Models land under examples/voice-agent-local-sherpa/.models// + */ + +import { SHERPA_MODEL_CATALOG } from './sherpa-model-catalog.mjs' +import { SHERPA_TTS_MODEL_CATALOG } from './sherpa-tts-model-catalog.mjs' +import { downloadSherpaSttModel } from './download-stt.mjs' +import { downloadSherpaTtsModel } from './download-tts.mjs' + +function parseArgs(argv) { + let minimal = false + for (const arg of argv) { + if (arg === '--minimal') minimal = true + if (arg === '--help' || arg === '-h') { + console.log(`Usage: node scripts/download-all-sherpa.mjs [--minimal] + + --minimal English STT + English TTS only (same as CI default) + default All downloadable catalog models (dedupes shared STT bundles) +`) + process.exit(0) + } + } + return { minimal } +} + +function uniqueByBundle(catalog, kind, ids) { + const want = ids ? new Set(ids) : null + const seen = new Set() + const out = [] + for (const m of catalog) { + if (m.kind !== kind || !m.bundle) continue + if (want && !want.has(m.id)) continue + if (seen.has(m.bundle)) continue + seen.add(m.bundle) + out.push(m.id) + } + return out +} + +const { minimal } = parseArgs(process.argv.slice(2)) + +const sttIds = minimal ? ['en'] : uniqueByBundle(SHERPA_MODEL_CATALOG, 'transducer') +const ttsIds = minimal ? ['en'] : uniqueByBundle(SHERPA_TTS_MODEL_CATALOG, 'vits') + +console.log(`download-all-sherpa: ${sttIds.length} STT bundle(s), ${ttsIds.length} TTS bundle(s)\n`) + +let failed = 0 +for (const id of sttIds) { + try { + console.log(`\n=== STT ${id} ===`) + downloadSherpaSttModel(id) + } catch (err) { + failed += 1 + console.error(`STT ${id} failed:`, err instanceof Error ? err.message : err) + } +} +for (const id of ttsIds) { + try { + console.log(`\n=== TTS ${id} ===`) + downloadSherpaTtsModel(id) + } catch (err) { + failed += 1 + console.error(`TTS ${id} failed:`, err instanceof Error ? err.message : err) + } +} + +console.log('\n--- Default env (English Kroko + Amy) ---') +console.log(' source scripts/export-sherpa-local-models.sh') +console.log(' # or: bash scripts/make-sherpa.sh --print-env') +console.log( + '\nOther voices: set SHERPA_STT_BUNDLE / SHERPA_TTS_BUNDLE to a bundle dir under .models/', +) + +if (failed > 0) { + process.exit(1) +} diff --git a/examples/voice-agent-local-sherpa/scripts/download-stt.mjs b/examples/voice-agent-local-sherpa/scripts/download-stt.mjs index 65bcd16..def191c 100644 --- a/examples/voice-agent-local-sherpa/scripts/download-stt.mjs +++ b/examples/voice-agent-local-sherpa/scripts/download-stt.mjs @@ -169,4 +169,7 @@ function main() { downloadSherpaSttModel(lang) } -main() +const isMain = process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1] +if (isMain) { + main() +} diff --git a/examples/voice-agent-local-sherpa/scripts/download-tts.mjs b/examples/voice-agent-local-sherpa/scripts/download-tts.mjs index d488123..2aa45e4 100644 --- a/examples/voice-agent-local-sherpa/scripts/download-tts.mjs +++ b/examples/voice-agent-local-sherpa/scripts/download-tts.mjs @@ -149,4 +149,7 @@ function main() { downloadSherpaTtsModel(lang) } -main() +const isMain = process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1] +if (isMain) { + main() +} diff --git a/package.json b/package.json index 15a5f90..72e0da2 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,9 @@ "ci:verify:release-ts:docker": "CI_VERIFY_RELEASE_TS_IN_DOCKER=1 bash scripts/ci/verify-release-publish-ts.sh", "ci:verify": "npm run ci:verify:checks", "release:local": "bash scripts/release-local.sh", - "release:publish": "bash scripts/release-publish.sh" + "release:publish": "bash scripts/release-publish.sh", + "make-sherpa": "bash scripts/make-sherpa.sh", + "make-sherpa:minimal": "bash scripts/make-sherpa.sh --minimal" }, "devDependencies": { "@eslint/js": "^9.17.0", diff --git a/scripts/make-sherpa.sh b/scripts/make-sherpa.sh new file mode 100755 index 0000000..d98690e --- /dev/null +++ b/scripts/make-sherpa.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# Download Sherpa ONNX models for local voice examples and print env exports. +# +# Full platform catalog (all STT/TTS options we offer): +# bash scripts/make-sherpa.sh +# npm run make-sherpa +# +# English-only (faster, matches CI): +# bash scripts/make-sherpa.sh --minimal +# +# After download, load defaults into your shell: +# source scripts/export-sherpa-local-models.sh +# +# Override active bundle (models must exist under .models/): +# SHERPA_STT_BUNDLE=sherpa-onnx-streaming-zipformer-de-kroko-2025-08-06 \ +# SHERPA_TTS_BUNDLE=vits-piper-de_DE-thorsten-medium \ +# SHERPA_STT_LANGUAGE=de source scripts/export-sherpa-local-models.sh +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +WS="@node-webrtc-rust/example-voice-agent-local-sherpa" + +if [[ "${1:-}" == "--print-env" ]]; then + exec bash "${ROOT}/scripts/export-sherpa-local-models.sh" +fi + +for cmd in curl tar node; do + command -v "${cmd}" >/dev/null 2>&1 || { + echo "make-sherpa: install ${cmd}" >&2 + exit 1 + } +done + +cd "${ROOT}" + +if [[ "${1:-}" == "--minimal" ]]; then + npm run download-all:minimal --workspace="${WS}" +else + npm run download-all --workspace="${WS}" +fi + +echo "" +echo "make-sherpa: default English env vars:" +bash "${ROOT}/scripts/export-sherpa-local-models.sh"