openspeechapi 0.2.6__tar.gz → 0.2.7__tar.gz
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.
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/PKG-INFO +1 -1
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/__init__.py +1 -1
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/core/models.py +19 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/stt/iflytek.py +197 -77
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/pyproject.toml +1 -1
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.dockerignore +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.env.example +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.github/workflows/ci.yml +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.gitignore +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.tmp/audio/en.aiff +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.tmp/audio/en_16k.wav +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.tmp/audio/en_16k_pad6.wav +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.tmp/audio/en_long.aiff +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.tmp/audio/en_long_16k.wav +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.tmp/audio/en_mid.aiff +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.tmp/audio/en_mid_16k.wav +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.tmp/audio/zh.aiff +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.tmp/audio/zh_16k.wav +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.tmp/openspeech-8600.log +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.tmp/openspeech-serve.log +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.tmp/webui-server.log +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.tmp/webui-server.pid +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.tmp/wlk12101.log +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.tmp/wlk12101.pid +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.tmp/wlk12102.log +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/.tmp/wlk12102.pid +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/AGENTS.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/CLAUDE.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/Dockerfile +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/README.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/aibox-script/aibox-1.0.0-SNAPSHOT-stdout.log +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/aibox-script/aibox.2026-04-02.log +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/aibox-script/com.user.restart-jar.plist +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/aibox-script/restart-jar.sh +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/aibox-script.tar.gz +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/docker-compose.yml +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/architecture/local-engine-manager.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/architecture/logging-spec.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/architecture/stt-engineering-optimization-guide.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/architecture/stt-streaming-spec.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/architecture/webui-phase-a.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/engines/fish-speech-docker.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/engines/fish-speech-native.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/engines/stt-native-models.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/superpowers/plans/2026-04-01-phase1-implementation.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/superpowers/plans/2026-04-11-macos-native-tts-stt.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/superpowers/specs/2026-04-01-openspeech-api-design.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/superpowers/specs/2026-04-03-hot-lazy-loading.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/superpowers/specs/2026-04-03-phase2-protocol-layer.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/superpowers/specs/2026-04-03-phase3-production.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/superpowers/specs/2026-04-11-macos-native-tts-stt-design.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/superpowers/specs/2026-04-12-cloud-providers-webui-design.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/superpowers/specs/2026-04-15-streaming-tts-stt-fixes-display-names.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/superpowers/specs/2026-04-16-provider-management-engines-rename.md +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/examples/client_stt.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/examples/client_tts.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/examples/stt_simple.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/examples/tts_simple.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/__main__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/cli.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/client/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/client/client.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/config.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/core/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/core/base.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/core/enums.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/core/registry.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/core/settings.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/demo.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/dispatch/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/dispatch/context.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/dispatch/dispatcher.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/dispatch/executors/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/dispatch/executors/base.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/dispatch/executors/in_process.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/dispatch/executors/remote.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/dispatch/executors/subprocess_exec.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/dispatch/fanout.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/dispatch/filters.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/dispatch/lifecycle.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/dispatch/watcher.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/engine_catalog.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/engine_registry.yaml +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/exceptions.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/factory.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/aim_resolver.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/backends/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/backends/docker_backend.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/backends/native_backend.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/base.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/engines/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/engines/faster_whisper.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/engines/fish_speech.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/engines/sherpa_onnx.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/engines/whisper.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/engines/whisperlivekit.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/manager.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/models.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/progress.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/registry.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/task_store.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/tasks.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/logging_config.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/observe/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/observe/base.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/observe/debug.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/observe/latency.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/observe/metrics.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/observe/tracing.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/observe/usage.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/_template.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/stt/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/stt/alibaba.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/stt/assemblyai.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/stt/azure_speech.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/stt/baidu.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/stt/deepgram.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/stt/elevenlabs.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/stt/faster_whisper.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/stt/google_cloud.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/stt/macos_speech.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/stt/openai.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/stt/sherpa_onnx.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/stt/tencent.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/stt/volcengine.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/stt/whisper.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/stt/whisperlivekit.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/stt/windows_speech.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/tts/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/tts/alibaba.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/tts/azure_speech.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/tts/baidu.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/tts/coqui.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/tts/cosyvoice.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/tts/deepgram.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/tts/elevenlabs.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/tts/fish_speech.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/tts/google_cloud.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/tts/iflytek.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/tts/macos_say.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/tts/minimax.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/tts/openai.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/tts/piper.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/tts/tencent.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/tts/volcengine.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/providers/tts/windows_sapi.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/server/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/server/app.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/server/auth.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/server/middleware.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/server/routes/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/server/routes/management.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/server/routes/stt.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/server/routes/tts.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/server/routes/webui.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/server/webui/app.js +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/server/webui/index.html +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/server/webui/styles.css +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/server/ws/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/server/ws/stt_stream.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/server/ws/tts_stream.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/telemetry/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/telemetry/perf.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/utils/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/utils/audio_converter.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/utils/audio_playback.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/vendor_registry.yaml +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/output/output.wav +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/output.wav +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/providers.example.yaml +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/scripts/engines/cloud/install.sh +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/scripts/engines/faster-whisper/native/install.sh +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/scripts/engines/fish-speech/native/install.sh +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/scripts/engines/macos-stt/install.sh +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/scripts/engines/macos-stt/macos_stt.swift +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/scripts/engines/macos-stt/request_auth.swift +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/scripts/engines/sherpa-onnx/native/install.sh +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/scripts/engines/sherpa-onnx/native/run_streaming_server.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/scripts/engines/whisper/native/install.sh +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/scripts/engines/whisperlivekit/native/install.sh +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/conftest.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/e2e/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/e2e/conftest.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/e2e/test_fanout_e2e.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/e2e/test_faster_whisper_e2e.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/e2e/test_openai_e2e.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/e2e/test_webui_e2e.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/fixtures/hello.wav +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/integration/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/integration/test_fanout_integration.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/integration/test_in_process_integration.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/integration/test_server_client.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_aim_resolver.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_audio_converter.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_audio_playback.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_base.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_cli.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_cli_engine.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_client.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_config.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_context.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_debug_observer.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_dispatcher.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_docker_backend_progress.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_engine_registry.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_enums.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_executor_base.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_fanout.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_filters.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_hot_reload.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_in_process.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_latency_observer.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_lifecycle.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_local_engine_task_store.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_local_engines_manager.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_logging.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_metrics_observer.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_models.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_native_backend.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_observer_base.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_plugin_mechanism.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_providers/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_providers/test_cloud_providers.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_providers/test_elevenlabs_stt.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_providers/test_macos_say.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_providers/test_macos_speech.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_providers/test_openai_base_url.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_providers/test_openai_stt.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_providers/test_openai_tts.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_providers/test_sherpa_onnx_stt.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_providers/test_stt_stubs.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_providers/test_tts_stubs.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_providers/test_whisperlivekit_stt.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_registry.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_remote.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_server/__init__.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_server/test_auth.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_server/test_config_api.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_server/test_routes.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_server/test_websocket.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_subprocess.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_usage_observer.py +0 -0
- {openspeechapi-0.2.6 → openspeechapi-0.2.7}/tests/unit/test_watcher.py +0 -0
|
@@ -60,6 +60,25 @@ class STTOptions:
|
|
|
60
60
|
# voice assistant. Providers that don't support VAD finalization
|
|
61
61
|
# (Whisper, Faster-Whisper) silently ignore this field.
|
|
62
62
|
vad_eos: int | None = None
|
|
63
|
+
# ── iFlytek IAT pass-through (matches Java AsrServiceImpl) ───────
|
|
64
|
+
# Wallex's Java AsrService forwards the client-supplied
|
|
65
|
+
# ``audio.common`` / ``audio.business`` / extra ``audio.data``
|
|
66
|
+
# fields verbatim to iFlytek's WS, treating the panel as the
|
|
67
|
+
# source of truth for ASR parameters. The Python pipeline now
|
|
68
|
+
# mirrors that contract: when these fields are non-None, the
|
|
69
|
+
# iFlytek provider uses them as the basis for the WS first frame
|
|
70
|
+
# (with ``setdefault`` fallback to its own settings for any keys
|
|
71
|
+
# the client omitted) instead of building the blocks purely from
|
|
72
|
+
# ``speech_providers.yaml``. ``None`` preserves the existing
|
|
73
|
+
# yaml-driven behaviour. Other STT providers ignore these fields.
|
|
74
|
+
iflytek_common: dict | None = None
|
|
75
|
+
iflytek_business: dict | None = None
|
|
76
|
+
# Extra fields to merge into the iFlytek ``data`` block beyond the
|
|
77
|
+
# canonical ``status``/``format``/``encoding``/``audio`` quadruple
|
|
78
|
+
# (e.g. panel-supplied ``data_type``). Keys that collide with the
|
|
79
|
+
# canonical set are preserved (the provider's defaults still win,
|
|
80
|
+
# since the canonical set is required by the IAT spec).
|
|
81
|
+
iflytek_data_extras: dict | None = None
|
|
63
82
|
|
|
64
83
|
|
|
65
84
|
@dataclass
|
|
@@ -72,6 +72,34 @@ class IflytekSTTSettings(BaseSettings):
|
|
|
72
72
|
# that. Lower if the network has aggressive proxies, higher only
|
|
73
73
|
# if the iFlytek endpoint is consistently slow to handshake.
|
|
74
74
|
timeout_secs: int = 15
|
|
75
|
+
# ── Java AsrConfig parity (used as setdefault fallbacks) ────────
|
|
76
|
+
# When a wallex client (panel) supplies ``audio.business``/
|
|
77
|
+
# ``audio.common`` per-frame, those values flow through via
|
|
78
|
+
# ``STTOptions.iflytek_business``/``STTOptions.iflytek_common`` and
|
|
79
|
+
# become the WS first frame body. The settings below act as
|
|
80
|
+
# ``setdefault`` fallbacks for keys the client omits, mirroring
|
|
81
|
+
# Java ``AsrConfig``'s field set so the two implementations
|
|
82
|
+
# produce identical wire frames given the same panel payload.
|
|
83
|
+
#
|
|
84
|
+
# ``domain`` — iFlytek IAT domain. Java default ``iat``; a few
|
|
85
|
+
# vertical models (``medical`` / ``tv``) exist but most
|
|
86
|
+
# deployments stay on the general one.
|
|
87
|
+
domain: str = "iat"
|
|
88
|
+
# ``accent`` — only meaningful when ``language=="zh_cn"`` (selects
|
|
89
|
+
# mandarin vs. cantonese etc.). Java sends ``mandarin`` blindly;
|
|
90
|
+
# we keep the same default so the WS frame matches Java byte-for-
|
|
91
|
+
# byte when the panel omits ``business.accent``. iFlytek treats
|
|
92
|
+
# it as a no-op for non-Chinese language codes.
|
|
93
|
+
accent: str = "mandarin"
|
|
94
|
+
# ``dwa`` — dynamic word adjustment / wpgs (实时纠错). Java's
|
|
95
|
+
# default ``wpgs`` is the realtime-correction mode panels rely on
|
|
96
|
+
# for the partial-result protocol described in
|
|
97
|
+
# ``stt-streaming-spec.md``. Empty disables it.
|
|
98
|
+
dwa: str = "wpgs"
|
|
99
|
+
# ``sample_rate`` — required by the IAT directed-domain endpoint
|
|
100
|
+
# (``ws-api-dx.xfyun.cn``) which expects it in ``business``. Java
|
|
101
|
+
# AsrConfig.sampleRate=16000.
|
|
102
|
+
sample_rate: int = 16000
|
|
75
103
|
|
|
76
104
|
|
|
77
105
|
# iFlytek expects the full locale tag; common ISO short codes need to
|
|
@@ -188,6 +216,117 @@ class IflytekSTT(STTProvider):
|
|
|
188
216
|
)
|
|
189
217
|
return f"wss://{host}{path}?{params}"
|
|
190
218
|
|
|
219
|
+
def _build_first_frame_blocks(
|
|
220
|
+
self,
|
|
221
|
+
opts: STTOptions | None,
|
|
222
|
+
*,
|
|
223
|
+
include_dwa: bool,
|
|
224
|
+
) -> tuple[dict, dict]:
|
|
225
|
+
"""Build the ``common`` / ``business`` blocks for the WS first frame.
|
|
226
|
+
|
|
227
|
+
Mirrors Java ``AsrServiceImpl.sendToAsr`` semantics: when
|
|
228
|
+
``opts.iflytek_common``/``opts.iflytek_business`` is provided
|
|
229
|
+
(typically by wallex relaying the panel's per-frame
|
|
230
|
+
``audio.common`` / ``audio.business``), those dicts are the
|
|
231
|
+
source of truth. We only ``setdefault`` keys the client omitted,
|
|
232
|
+
falling back to ``self.settings`` so a panel that misses a
|
|
233
|
+
single field doesn't get a malformed frame.
|
|
234
|
+
|
|
235
|
+
``include_dwa`` differs between ``transcribe()`` (batch — no
|
|
236
|
+
wpgs because there's no streaming protocol) and
|
|
237
|
+
``transcribe_stream()`` (always wpgs).
|
|
238
|
+
"""
|
|
239
|
+
canon = _canonical_language(self.settings.language)
|
|
240
|
+
eos = (opts.vad_eos
|
|
241
|
+
if opts is not None and opts.vad_eos is not None
|
|
242
|
+
else self.settings.vad_eos)
|
|
243
|
+
|
|
244
|
+
# ── business block ─────────────────────────────────────────
|
|
245
|
+
if opts is not None and opts.iflytek_business:
|
|
246
|
+
# Panel-supplied is authoritative; copy then fill missing
|
|
247
|
+
# keys from yaml so we never send a partial frame.
|
|
248
|
+
business = dict(opts.iflytek_business)
|
|
249
|
+
else:
|
|
250
|
+
business = {}
|
|
251
|
+
|
|
252
|
+
business.setdefault("language", canon)
|
|
253
|
+
business.setdefault("domain", self.settings.domain)
|
|
254
|
+
business.setdefault("vad_eos", eos)
|
|
255
|
+
business.setdefault("ltc", self.settings.ltc)
|
|
256
|
+
if include_dwa:
|
|
257
|
+
business.setdefault("dwa", self.settings.dwa)
|
|
258
|
+
# ``accent`` is only meaningful for the Chinese model. Java
|
|
259
|
+
# sends ``mandarin`` blindly; we keep that for byte-for-byte
|
|
260
|
+
# parity when the panel omits it AND language is zh_cn. For
|
|
261
|
+
# other languages we leave it out entirely (sending it is a
|
|
262
|
+
# no-op on iFlytek's side but confuses log readers).
|
|
263
|
+
if "accent" not in business and canon == "zh_cn":
|
|
264
|
+
business["accent"] = self.settings.accent
|
|
265
|
+
|
|
266
|
+
# ── common block ──────────────────────────────────────────
|
|
267
|
+
if opts is not None and opts.iflytek_common:
|
|
268
|
+
common = dict(opts.iflytek_common)
|
|
269
|
+
else:
|
|
270
|
+
common = {}
|
|
271
|
+
common.setdefault("app_id", self.settings.app_id)
|
|
272
|
+
|
|
273
|
+
return common, business
|
|
274
|
+
|
|
275
|
+
@staticmethod
|
|
276
|
+
def _build_data_block(
|
|
277
|
+
*, status: int, audio_b64: str, opts: STTOptions | None,
|
|
278
|
+
) -> dict:
|
|
279
|
+
"""Assemble the ``data`` block, merging panel-supplied extras.
|
|
280
|
+
|
|
281
|
+
Canonical keys (``status``/``format``/``encoding``/``audio``)
|
|
282
|
+
always win over ``iflytek_data_extras`` because the IAT spec
|
|
283
|
+
requires them in a specific shape; extras like the panel's
|
|
284
|
+
``data_type`` flow through.
|
|
285
|
+
"""
|
|
286
|
+
if opts is not None and opts.iflytek_data_extras:
|
|
287
|
+
data = dict(opts.iflytek_data_extras)
|
|
288
|
+
else:
|
|
289
|
+
data = {}
|
|
290
|
+
data["status"] = status
|
|
291
|
+
data["format"] = "audio/L16;rate=16000"
|
|
292
|
+
data["encoding"] = "raw"
|
|
293
|
+
data["audio"] = audio_b64
|
|
294
|
+
return data
|
|
295
|
+
|
|
296
|
+
async def _connect_with_retry(self) -> "websockets.ClientConnection":
|
|
297
|
+
"""Connect to iFlytek IAT WS with backoff, mirroring Java parity.
|
|
298
|
+
|
|
299
|
+
Java ``AsrServiceImpl.connectWithRetry`` does 4 attempts with
|
|
300
|
+
300/600/1200ms backoff before giving up. The previous Python
|
|
301
|
+
path was one-shot: a single TCP/handshake hiccup surfaced as a
|
|
302
|
+
hard ASR failure. Aligning the retry budget keeps wallex's
|
|
303
|
+
Python and Java front-ends behaviourally interchangeable on
|
|
304
|
+
flaky links.
|
|
305
|
+
"""
|
|
306
|
+
backoffs = (0.3, 0.6, 1.2) # delays AFTER attempts 1, 2, 3
|
|
307
|
+
last_exc: Exception | None = None
|
|
308
|
+
for attempt in range(4):
|
|
309
|
+
try:
|
|
310
|
+
url = self._build_auth_url()
|
|
311
|
+
ws = await websockets.connect(url)
|
|
312
|
+
if attempt > 0:
|
|
313
|
+
logger.info(
|
|
314
|
+
"{}: WS connected on attempt {}/4",
|
|
315
|
+
self.name, attempt + 1,
|
|
316
|
+
)
|
|
317
|
+
return ws
|
|
318
|
+
except Exception as e: # noqa: BLE001 — retry boundary
|
|
319
|
+
last_exc = e
|
|
320
|
+
logger.warning(
|
|
321
|
+
"{}: WS connect failed (attempt {}/4): {}",
|
|
322
|
+
self.name, attempt + 1, e,
|
|
323
|
+
)
|
|
324
|
+
if attempt < len(backoffs):
|
|
325
|
+
await asyncio.sleep(backoffs[attempt])
|
|
326
|
+
raise RuntimeError(
|
|
327
|
+
f"iFlytek STT connect failed after 4 attempts: {last_exc}"
|
|
328
|
+
)
|
|
329
|
+
|
|
191
330
|
async def transcribe(
|
|
192
331
|
self, audio: AudioData, opts: STTOptions | None = None
|
|
193
332
|
) -> Transcription:
|
|
@@ -196,7 +335,6 @@ class IflytekSTT(STTProvider):
|
|
|
196
335
|
logger.info("{}: request received, audio={} bytes", self.name, len(audio.data))
|
|
197
336
|
_t0 = time.perf_counter()
|
|
198
337
|
|
|
199
|
-
url = self._build_auth_url()
|
|
200
338
|
audio_bytes = audio.data
|
|
201
339
|
# iFlytek recommends ~40ms per frame at 16kHz 16bit mono = 1280 bytes.
|
|
202
340
|
# Use larger frames (8000 bytes = ~250ms) with pacing to avoid server
|
|
@@ -209,7 +347,8 @@ class IflytekSTT(STTProvider):
|
|
|
209
347
|
|
|
210
348
|
result_texts: list[str] = []
|
|
211
349
|
|
|
212
|
-
|
|
350
|
+
ws = await self._connect_with_retry()
|
|
351
|
+
async with ws:
|
|
213
352
|
# Send audio in chunks with interleaved receive
|
|
214
353
|
total = len(audio_bytes)
|
|
215
354
|
offset = 0
|
|
@@ -228,47 +367,36 @@ class IflytekSTT(STTProvider):
|
|
|
228
367
|
frame_data = base64.b64encode(chunk).decode("utf-8")
|
|
229
368
|
|
|
230
369
|
if status == 0:
|
|
231
|
-
# First frame
|
|
232
|
-
#
|
|
233
|
-
#
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
# ``parameter.iat.eos`` through here so a kiosk
|
|
241
|
-
# can ship a tighter or looser silence threshold
|
|
242
|
-
# than the deployment yaml.
|
|
243
|
-
eos = (opts.vad_eos
|
|
244
|
-
if opts is not None and opts.vad_eos is not None
|
|
245
|
-
else self.settings.vad_eos)
|
|
246
|
-
business = {
|
|
247
|
-
"language": canon,
|
|
248
|
-
"domain": "iat",
|
|
249
|
-
"vad_eos": eos,
|
|
250
|
-
"ltc": self.settings.ltc,
|
|
251
|
-
}
|
|
252
|
-
if canon == "zh_cn":
|
|
253
|
-
business["accent"] = "mandarin"
|
|
370
|
+
# First frame: panel-supplied common/business win;
|
|
371
|
+
# batch path doesn't carry wpgs (no streaming
|
|
372
|
+
# protocol) so include_dwa=False.
|
|
373
|
+
common, business = self._build_first_frame_blocks(
|
|
374
|
+
opts, include_dwa=False,
|
|
375
|
+
)
|
|
376
|
+
data_block = self._build_data_block(
|
|
377
|
+
status=0, audio_b64=frame_data, opts=opts,
|
|
378
|
+
)
|
|
254
379
|
msg = {
|
|
255
|
-
"common":
|
|
380
|
+
"common": common,
|
|
256
381
|
"business": business,
|
|
257
|
-
"data":
|
|
258
|
-
"status": 0,
|
|
259
|
-
"format": "audio/L16;rate=16000",
|
|
260
|
-
"encoding": "raw",
|
|
261
|
-
"audio": frame_data,
|
|
262
|
-
},
|
|
382
|
+
"data": data_block,
|
|
263
383
|
}
|
|
384
|
+
# Java parity: log the exact blocks we're about to
|
|
385
|
+
# ship to iFlytek. Debugging "wrong language /
|
|
386
|
+
# wrong endpoint" reports needs to see this from
|
|
387
|
+
# the log alone — Java's AsrServiceImpl prints the
|
|
388
|
+
# equivalent line at INFO.
|
|
389
|
+
logger.info(
|
|
390
|
+
"{}: ASR first frame business={}, common={}",
|
|
391
|
+
self.name,
|
|
392
|
+
json.dumps(business, ensure_ascii=False),
|
|
393
|
+
json.dumps(common, ensure_ascii=False),
|
|
394
|
+
)
|
|
264
395
|
else:
|
|
265
396
|
msg = {
|
|
266
|
-
"data":
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
"encoding": "raw",
|
|
270
|
-
"audio": frame_data,
|
|
271
|
-
}
|
|
397
|
+
"data": self._build_data_block(
|
|
398
|
+
status=status, audio_b64=frame_data, opts=opts,
|
|
399
|
+
)
|
|
272
400
|
}
|
|
273
401
|
|
|
274
402
|
await ws.send(json.dumps(msg))
|
|
@@ -340,7 +468,6 @@ class IflytekSTT(STTProvider):
|
|
|
340
468
|
if self._client is None:
|
|
341
469
|
raise RuntimeError("Provider not started — call start() first")
|
|
342
470
|
|
|
343
|
-
url = self._build_auth_url()
|
|
344
471
|
results: asyncio.Queue[Transcription | None] = asyncio.Queue()
|
|
345
472
|
_t0 = time.perf_counter()
|
|
346
473
|
_frames_sent = 0
|
|
@@ -352,7 +479,8 @@ class IflytekSTT(STTProvider):
|
|
|
352
479
|
_sender_stop = asyncio.Event()
|
|
353
480
|
|
|
354
481
|
logger.debug("{}: connecting to iFlytek WebSocket...", self.name)
|
|
355
|
-
|
|
482
|
+
ws = await self._connect_with_retry()
|
|
483
|
+
async with ws:
|
|
356
484
|
_t_connected = time.perf_counter()
|
|
357
485
|
logger.info("{}: WS connected in {:.0f}ms", self.name,
|
|
358
486
|
(_t_connected - _t0) * 1000)
|
|
@@ -370,43 +498,38 @@ class IflytekSTT(STTProvider):
|
|
|
370
498
|
break
|
|
371
499
|
frame_data = base64.b64encode(chunk).decode("utf-8")
|
|
372
500
|
if is_first:
|
|
373
|
-
#
|
|
374
|
-
#
|
|
375
|
-
|
|
376
|
-
#
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
"language": canon,
|
|
384
|
-
"domain": "iat",
|
|
385
|
-
"dwa": "wpgs",
|
|
386
|
-
"vad_eos": eos,
|
|
387
|
-
"ltc": self.settings.ltc,
|
|
388
|
-
}
|
|
389
|
-
if canon == "zh_cn":
|
|
390
|
-
business["accent"] = "mandarin"
|
|
501
|
+
# First frame: panel-supplied common/business win;
|
|
502
|
+
# streaming path always carries wpgs (see
|
|
503
|
+
# stt-streaming-spec.md realtime-correction
|
|
504
|
+
# protocol) so include_dwa=True.
|
|
505
|
+
common, business = self._build_first_frame_blocks(
|
|
506
|
+
opts, include_dwa=True,
|
|
507
|
+
)
|
|
508
|
+
data_block = self._build_data_block(
|
|
509
|
+
status=0, audio_b64=frame_data, opts=opts,
|
|
510
|
+
)
|
|
391
511
|
msg = {
|
|
392
|
-
"common":
|
|
512
|
+
"common": common,
|
|
393
513
|
"business": business,
|
|
394
|
-
"data":
|
|
395
|
-
"status": 0,
|
|
396
|
-
"format": "audio/L16;rate=16000",
|
|
397
|
-
"encoding": "raw",
|
|
398
|
-
"audio": frame_data,
|
|
399
|
-
},
|
|
514
|
+
"data": data_block,
|
|
400
515
|
}
|
|
516
|
+
# Java parity (AsrServiceImpl line 221): log
|
|
517
|
+
# the first-frame business + common at INFO so
|
|
518
|
+
# operators can verify which language/eos/dwa
|
|
519
|
+
# the panel actually requested without
|
|
520
|
+
# rebuilding the call from yaml + STTOptions.
|
|
521
|
+
logger.info(
|
|
522
|
+
"{}: ASR first frame business={}, common={}",
|
|
523
|
+
self.name,
|
|
524
|
+
json.dumps(business, ensure_ascii=False),
|
|
525
|
+
json.dumps(common, ensure_ascii=False),
|
|
526
|
+
)
|
|
401
527
|
is_first = False
|
|
402
528
|
else:
|
|
403
529
|
msg = {
|
|
404
|
-
"data":
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
"encoding": "raw",
|
|
408
|
-
"audio": frame_data,
|
|
409
|
-
}
|
|
530
|
+
"data": self._build_data_block(
|
|
531
|
+
status=1, audio_b64=frame_data, opts=opts,
|
|
532
|
+
)
|
|
410
533
|
}
|
|
411
534
|
await ws.send(json.dumps(msg))
|
|
412
535
|
_frames_sent += 1
|
|
@@ -417,12 +540,9 @@ class IflytekSTT(STTProvider):
|
|
|
417
540
|
# Send empty last frame to signal end (only if WS still open)
|
|
418
541
|
if not _sender_stop.is_set():
|
|
419
542
|
last_msg = {
|
|
420
|
-
"data":
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
"encoding": "raw",
|
|
424
|
-
"audio": "",
|
|
425
|
-
}
|
|
543
|
+
"data": self._build_data_block(
|
|
544
|
+
status=2, audio_b64="", opts=opts,
|
|
545
|
+
)
|
|
426
546
|
}
|
|
427
547
|
await ws.send(json.dumps(last_msg))
|
|
428
548
|
except websockets.exceptions.ConnectionClosed:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/architecture/stt-engineering-optimization-guide.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/superpowers/specs/2026-04-03-hot-lazy-loading.md
RENAMED
|
File without changes
|
|
File without changes
|
{openspeechapi-0.2.6 → openspeechapi-0.2.7}/docs/superpowers/specs/2026-04-03-phase3-production.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/dispatch/executors/subprocess_exec.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/backends/__init__.py
RENAMED
|
File without changes
|
{openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/backends/docker_backend.py
RENAMED
|
File without changes
|
{openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/backends/native_backend.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openspeechapi-0.2.6 → openspeechapi-0.2.7}/openspeechapi/local_engines/engines/faster_whisper.py
RENAMED
|
File without changes
|