openspeechapi 0.2.0__tar.gz → 0.2.3__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.
Files changed (247) hide show
  1. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/PKG-INFO +1 -1
  2. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/__init__.py +1 -1
  3. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/stt/iflytek.py +100 -16
  4. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/tts/iflytek.py +67 -16
  5. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/pyproject.toml +1 -1
  6. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.dockerignore +0 -0
  7. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.env.example +0 -0
  8. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.github/workflows/ci.yml +0 -0
  9. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.gitignore +0 -0
  10. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.tmp/audio/en.aiff +0 -0
  11. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.tmp/audio/en_16k.wav +0 -0
  12. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.tmp/audio/en_16k_pad6.wav +0 -0
  13. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.tmp/audio/en_long.aiff +0 -0
  14. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.tmp/audio/en_long_16k.wav +0 -0
  15. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.tmp/audio/en_mid.aiff +0 -0
  16. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.tmp/audio/en_mid_16k.wav +0 -0
  17. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.tmp/audio/zh.aiff +0 -0
  18. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.tmp/audio/zh_16k.wav +0 -0
  19. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.tmp/openspeech-8600.log +0 -0
  20. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.tmp/openspeech-serve.log +0 -0
  21. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.tmp/webui-server.log +0 -0
  22. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.tmp/webui-server.pid +0 -0
  23. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.tmp/wlk12101.log +0 -0
  24. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.tmp/wlk12101.pid +0 -0
  25. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.tmp/wlk12102.log +0 -0
  26. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/.tmp/wlk12102.pid +0 -0
  27. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/AGENTS.md +0 -0
  28. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/CLAUDE.md +0 -0
  29. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/Dockerfile +0 -0
  30. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/README.md +0 -0
  31. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/aibox-script/aibox-1.0.0-SNAPSHOT-stdout.log +0 -0
  32. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/aibox-script/aibox.2026-04-02.log +0 -0
  33. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/aibox-script/com.user.restart-jar.plist +0 -0
  34. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/aibox-script/restart-jar.sh +0 -0
  35. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/aibox-script.tar.gz +0 -0
  36. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/docker-compose.yml +0 -0
  37. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/docs/architecture/local-engine-manager.md +0 -0
  38. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/docs/architecture/logging-spec.md +0 -0
  39. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/docs/architecture/stt-engineering-optimization-guide.md +0 -0
  40. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/docs/architecture/stt-streaming-spec.md +0 -0
  41. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/docs/architecture/webui-phase-a.md +0 -0
  42. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/docs/engines/fish-speech-docker.md +0 -0
  43. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/docs/engines/fish-speech-native.md +0 -0
  44. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/docs/engines/stt-native-models.md +0 -0
  45. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/docs/superpowers/plans/2026-04-01-phase1-implementation.md +0 -0
  46. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/docs/superpowers/plans/2026-04-11-macos-native-tts-stt.md +0 -0
  47. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/docs/superpowers/specs/2026-04-01-openspeech-api-design.md +0 -0
  48. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/docs/superpowers/specs/2026-04-03-hot-lazy-loading.md +0 -0
  49. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/docs/superpowers/specs/2026-04-03-phase2-protocol-layer.md +0 -0
  50. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/docs/superpowers/specs/2026-04-03-phase3-production.md +0 -0
  51. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/docs/superpowers/specs/2026-04-11-macos-native-tts-stt-design.md +0 -0
  52. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/docs/superpowers/specs/2026-04-12-cloud-providers-webui-design.md +0 -0
  53. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/docs/superpowers/specs/2026-04-15-streaming-tts-stt-fixes-display-names.md +0 -0
  54. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/docs/superpowers/specs/2026-04-16-provider-management-engines-rename.md +0 -0
  55. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/examples/client_stt.py +0 -0
  56. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/examples/client_tts.py +0 -0
  57. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/examples/stt_simple.py +0 -0
  58. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/examples/tts_simple.py +0 -0
  59. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/__main__.py +0 -0
  60. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/cli.py +0 -0
  61. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/client/__init__.py +0 -0
  62. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/client/client.py +0 -0
  63. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/config.py +0 -0
  64. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/core/__init__.py +0 -0
  65. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/core/base.py +0 -0
  66. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/core/enums.py +0 -0
  67. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/core/models.py +0 -0
  68. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/core/registry.py +0 -0
  69. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/core/settings.py +0 -0
  70. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/demo.py +0 -0
  71. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/dispatch/__init__.py +0 -0
  72. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/dispatch/context.py +0 -0
  73. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/dispatch/dispatcher.py +0 -0
  74. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/dispatch/executors/__init__.py +0 -0
  75. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/dispatch/executors/base.py +0 -0
  76. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/dispatch/executors/in_process.py +0 -0
  77. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/dispatch/executors/remote.py +0 -0
  78. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/dispatch/executors/subprocess_exec.py +0 -0
  79. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/dispatch/fanout.py +0 -0
  80. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/dispatch/filters.py +0 -0
  81. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/dispatch/lifecycle.py +0 -0
  82. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/dispatch/watcher.py +0 -0
  83. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/engine_catalog.py +0 -0
  84. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/engine_registry.yaml +0 -0
  85. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/exceptions.py +0 -0
  86. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/factory.py +0 -0
  87. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/local_engines/__init__.py +0 -0
  88. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/local_engines/aim_resolver.py +0 -0
  89. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/local_engines/backends/__init__.py +0 -0
  90. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/local_engines/backends/docker_backend.py +0 -0
  91. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/local_engines/backends/native_backend.py +0 -0
  92. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/local_engines/base.py +0 -0
  93. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/local_engines/engines/__init__.py +0 -0
  94. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/local_engines/engines/faster_whisper.py +0 -0
  95. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/local_engines/engines/fish_speech.py +0 -0
  96. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/local_engines/engines/sherpa_onnx.py +0 -0
  97. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/local_engines/engines/whisper.py +0 -0
  98. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/local_engines/engines/whisperlivekit.py +0 -0
  99. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/local_engines/manager.py +0 -0
  100. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/local_engines/models.py +0 -0
  101. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/local_engines/progress.py +0 -0
  102. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/local_engines/registry.py +0 -0
  103. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/local_engines/task_store.py +0 -0
  104. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/local_engines/tasks.py +0 -0
  105. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/logging_config.py +0 -0
  106. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/observe/__init__.py +0 -0
  107. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/observe/base.py +0 -0
  108. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/observe/debug.py +0 -0
  109. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/observe/latency.py +0 -0
  110. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/observe/metrics.py +0 -0
  111. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/observe/tracing.py +0 -0
  112. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/observe/usage.py +0 -0
  113. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/__init__.py +0 -0
  114. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/_template.py +0 -0
  115. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/stt/__init__.py +0 -0
  116. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/stt/alibaba.py +0 -0
  117. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/stt/assemblyai.py +0 -0
  118. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/stt/azure_speech.py +0 -0
  119. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/stt/baidu.py +0 -0
  120. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/stt/deepgram.py +0 -0
  121. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/stt/elevenlabs.py +0 -0
  122. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/stt/faster_whisper.py +0 -0
  123. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/stt/google_cloud.py +0 -0
  124. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/stt/macos_speech.py +0 -0
  125. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/stt/openai.py +0 -0
  126. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/stt/sherpa_onnx.py +0 -0
  127. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/stt/tencent.py +0 -0
  128. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/stt/volcengine.py +0 -0
  129. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/stt/whisper.py +0 -0
  130. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/stt/whisperlivekit.py +0 -0
  131. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/stt/windows_speech.py +0 -0
  132. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/tts/__init__.py +0 -0
  133. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/tts/alibaba.py +0 -0
  134. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/tts/azure_speech.py +0 -0
  135. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/tts/baidu.py +0 -0
  136. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/tts/coqui.py +0 -0
  137. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/tts/cosyvoice.py +0 -0
  138. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/tts/deepgram.py +0 -0
  139. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/tts/elevenlabs.py +0 -0
  140. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/tts/fish_speech.py +0 -0
  141. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/tts/google_cloud.py +0 -0
  142. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/tts/macos_say.py +0 -0
  143. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/tts/minimax.py +0 -0
  144. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/tts/openai.py +0 -0
  145. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/tts/piper.py +0 -0
  146. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/tts/tencent.py +0 -0
  147. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/tts/volcengine.py +0 -0
  148. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/providers/tts/windows_sapi.py +0 -0
  149. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/server/__init__.py +0 -0
  150. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/server/app.py +0 -0
  151. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/server/auth.py +0 -0
  152. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/server/middleware.py +0 -0
  153. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/server/routes/__init__.py +0 -0
  154. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/server/routes/management.py +0 -0
  155. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/server/routes/stt.py +0 -0
  156. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/server/routes/tts.py +0 -0
  157. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/server/routes/webui.py +0 -0
  158. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/server/webui/app.js +0 -0
  159. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/server/webui/index.html +0 -0
  160. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/server/webui/styles.css +0 -0
  161. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/server/ws/__init__.py +0 -0
  162. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/server/ws/stt_stream.py +0 -0
  163. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/server/ws/tts_stream.py +0 -0
  164. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/telemetry/__init__.py +0 -0
  165. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/telemetry/perf.py +0 -0
  166. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/utils/__init__.py +0 -0
  167. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/utils/audio_converter.py +0 -0
  168. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/utils/audio_playback.py +0 -0
  169. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/openspeechapi/vendor_registry.yaml +0 -0
  170. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/output/output.wav +0 -0
  171. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/output.wav +0 -0
  172. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/providers.example.yaml +0 -0
  173. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/scripts/engines/cloud/install.sh +0 -0
  174. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/scripts/engines/faster-whisper/native/install.sh +0 -0
  175. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/scripts/engines/fish-speech/native/install.sh +0 -0
  176. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/scripts/engines/macos-stt/install.sh +0 -0
  177. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/scripts/engines/macos-stt/macos_stt.swift +0 -0
  178. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/scripts/engines/macos-stt/request_auth.swift +0 -0
  179. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/scripts/engines/sherpa-onnx/native/install.sh +0 -0
  180. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/scripts/engines/sherpa-onnx/native/run_streaming_server.py +0 -0
  181. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/scripts/engines/whisper/native/install.sh +0 -0
  182. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/scripts/engines/whisperlivekit/native/install.sh +0 -0
  183. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/__init__.py +0 -0
  184. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/conftest.py +0 -0
  185. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/e2e/__init__.py +0 -0
  186. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/e2e/conftest.py +0 -0
  187. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/e2e/test_fanout_e2e.py +0 -0
  188. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/e2e/test_faster_whisper_e2e.py +0 -0
  189. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/e2e/test_openai_e2e.py +0 -0
  190. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/e2e/test_webui_e2e.py +0 -0
  191. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/fixtures/hello.wav +0 -0
  192. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/integration/__init__.py +0 -0
  193. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/integration/test_fanout_integration.py +0 -0
  194. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/integration/test_in_process_integration.py +0 -0
  195. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/integration/test_server_client.py +0 -0
  196. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/__init__.py +0 -0
  197. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_aim_resolver.py +0 -0
  198. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_audio_converter.py +0 -0
  199. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_audio_playback.py +0 -0
  200. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_base.py +0 -0
  201. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_cli.py +0 -0
  202. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_cli_engine.py +0 -0
  203. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_client.py +0 -0
  204. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_config.py +0 -0
  205. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_context.py +0 -0
  206. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_debug_observer.py +0 -0
  207. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_dispatcher.py +0 -0
  208. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_docker_backend_progress.py +0 -0
  209. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_engine_registry.py +0 -0
  210. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_enums.py +0 -0
  211. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_executor_base.py +0 -0
  212. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_fanout.py +0 -0
  213. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_filters.py +0 -0
  214. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_hot_reload.py +0 -0
  215. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_in_process.py +0 -0
  216. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_latency_observer.py +0 -0
  217. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_lifecycle.py +0 -0
  218. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_local_engine_task_store.py +0 -0
  219. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_local_engines_manager.py +0 -0
  220. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_logging.py +0 -0
  221. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_metrics_observer.py +0 -0
  222. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_models.py +0 -0
  223. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_native_backend.py +0 -0
  224. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_observer_base.py +0 -0
  225. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_plugin_mechanism.py +0 -0
  226. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_providers/__init__.py +0 -0
  227. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_providers/test_cloud_providers.py +0 -0
  228. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_providers/test_elevenlabs_stt.py +0 -0
  229. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_providers/test_macos_say.py +0 -0
  230. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_providers/test_macos_speech.py +0 -0
  231. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_providers/test_openai_base_url.py +0 -0
  232. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_providers/test_openai_stt.py +0 -0
  233. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_providers/test_openai_tts.py +0 -0
  234. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_providers/test_sherpa_onnx_stt.py +0 -0
  235. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_providers/test_stt_stubs.py +0 -0
  236. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_providers/test_tts_stubs.py +0 -0
  237. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_providers/test_whisperlivekit_stt.py +0 -0
  238. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_registry.py +0 -0
  239. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_remote.py +0 -0
  240. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_server/__init__.py +0 -0
  241. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_server/test_auth.py +0 -0
  242. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_server/test_config_api.py +0 -0
  243. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_server/test_routes.py +0 -0
  244. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_server/test_websocket.py +0 -0
  245. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_subprocess.py +0 -0
  246. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_usage_observer.py +0 -0
  247. {openspeechapi-0.2.0 → openspeechapi-0.2.3}/tests/unit/test_watcher.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openspeechapi
3
- Version: 0.2.0
3
+ Version: 0.2.3
4
4
  Summary: Unified speech interface for STT/TTS providers
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: httpx>=0.27
@@ -1,6 +1,6 @@
1
1
  """OpenSpeechAPI — Unified speech interface for STT/TTS providers."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "0.2.3"
4
4
 
5
5
  from openspeechapi.config import load_config
6
6
  from openspeechapi.core.base import SpeechProvider, STTProvider, TTSProvider
@@ -29,7 +29,58 @@ class IflytekSTTSettings(BaseSettings):
29
29
  app_id: str = ""
30
30
  api_key: str = ""
31
31
  api_secret: str = ""
32
+ # iFlytek-canonical language code. Acceptable values per iFlytek
33
+ # IAT docs: ``zh_cn``, ``en_us``, ``ja_jp``, ``ko_kr``, ``ru-ru``.
34
+ # Common ISO short codes (``en``, ``zh``, ``ja``, ``ko``, ``ru``)
35
+ # are accepted here and mapped on the request hop — see
36
+ # ``_canonical_language``. iFlytek silently falls back to ``zh_cn``
37
+ # when given an unrecognised value, so the alias mapping prevents
38
+ # English audio from being transcribed by the Chinese model
39
+ # (caught 04-28 by an "english only" deployment that had set
40
+ # ``language: en`` and got hanzi back).
32
41
  language: str = "zh_cn"
42
+ # ``vad_eos`` — milliseconds of trailing silence iFlytek treats as
43
+ # end-of-sentence before emitting the final result (``status == 2``).
44
+ # iFlytek's documented default is 2000; lower values give faster
45
+ # finalization at the cost of cutting off slow speakers mid-thought.
46
+ # The 04-28 17:00 audit found vad_eos=2000 contributed ~89% of the
47
+ # user-perceived latency budget — the speech itself only used ~3 s
48
+ # but iFlytek waited an additional 2 s of silence before declaring
49
+ # final. Common production values: 800-1000 (responsive),
50
+ # 1500 (conservative), 2000 (default, slow). Below ~500 risks
51
+ # premature finalization on natural pauses. Per-deployment override
52
+ # via ``speech_providers.yaml`` so different sites can pick their
53
+ # own latency-vs-tolerance trade-off.
54
+ vad_eos: int = 2000
55
+
56
+
57
+ # iFlytek expects the full locale tag; common ISO short codes need to
58
+ # be translated. Keys are casefolded for tolerant matching. Values are
59
+ # the iFlytek-canonical strings the WS request will carry.
60
+ _LANGUAGE_ALIASES: dict[str, str] = {
61
+ # Canonical pass-through (allow case variation)
62
+ "zh_cn": "zh_cn", "en_us": "en_us", "ja_jp": "ja_jp",
63
+ "ko_kr": "ko_kr", "ru-ru": "ru-ru", "ru_ru": "ru-ru",
64
+ # ISO 639-1 short codes — most config sources use these
65
+ "zh": "zh_cn", "zh-cn": "zh_cn", "zh-hans": "zh_cn",
66
+ "en": "en_us", "en-us": "en_us", "en-gb": "en_us",
67
+ "ja": "ja_jp", "ja-jp": "ja_jp",
68
+ "ko": "ko_kr", "ko-kr": "ko_kr",
69
+ "ru": "ru-ru",
70
+ }
71
+
72
+
73
+ def _canonical_language(raw: str | None) -> str:
74
+ """Translate a configured language string to iFlytek's canonical form.
75
+
76
+ Returns the iFlytek-canonical code (e.g. ``en_us``). Unknown inputs
77
+ pass through unchanged so iFlytek surfaces a real protocol error
78
+ instead of silently falling back to Chinese.
79
+ """
80
+ if not raw:
81
+ return "zh_cn"
82
+ return _LANGUAGE_ALIASES.get(raw.casefold().strip(), raw)
83
+
33
84
 
34
85
  class IflytekSTT(STTProvider):
35
86
  name = "iflytek-stt"
@@ -37,7 +88,9 @@ class IflytekSTT(STTProvider):
37
88
  execution_mode = ExecMode.IN_PROCESS
38
89
  settings_cls = IflytekSTTSettings
39
90
  capabilities = {Capability.BATCH, Capability.STREAMING, Capability.MULTILINGUAL}
40
- field_options = {"language": ["zh_cn", "en_us"]}
91
+ field_options = {
92
+ "language": ["zh_cn", "en_us", "ja_jp", "ko_kr", "ru-ru"],
93
+ }
41
94
 
42
95
  _WS_HOST = "iat-api.xfyun.cn"
43
96
  _WS_PATH = "/v2/iat"
@@ -55,7 +108,25 @@ class IflytekSTT(STTProvider):
55
108
  if self._client is None:
56
109
  self._client = httpx.AsyncClient(timeout=60.0)
57
110
  self._owns_client = True
58
- logger.info("{} provider started", self.name)
111
+ # Surface the effective language (after alias mapping) and
112
+ # vad_eos at startup so deployments can verify the iFlytek model
113
+ # and silence-finalization threshold that will actually run.
114
+ # The 04-28 audit caught a deployment shipping ``language: en``
115
+ # (invalid) which silently routed every request to the Chinese
116
+ # model; an analogous oversight on vad_eos would silently
117
+ # double the user-perceived latency. Logging both makes
118
+ # mis-config obvious from the first request.
119
+ effective = _canonical_language(self.settings.language)
120
+ if effective != self.settings.language:
121
+ logger.info(
122
+ "{} provider started, language={!r} (canonicalized from {!r}), vad_eos={}ms",
123
+ self.name, effective, self.settings.language, self.settings.vad_eos,
124
+ )
125
+ else:
126
+ logger.info(
127
+ "{} provider started, language={!r}, vad_eos={}ms",
128
+ self.name, effective, self.settings.vad_eos,
129
+ )
59
130
 
60
131
  async def stop(self) -> None:
61
132
  if self._client and self._owns_client:
@@ -138,15 +209,23 @@ class IflytekSTT(STTProvider):
138
209
  frame_data = base64.b64encode(chunk).decode("utf-8")
139
210
 
140
211
  if status == 0:
141
- # First frame includes common and business params
212
+ # First frame includes common and business params.
213
+ # ``accent="mandarin"`` is only meaningful for the
214
+ # Chinese model; sending it on en_us / ja_jp / etc.
215
+ # is a wire-level no-op on iFlytek's side but
216
+ # confuses anyone reading the request body, so
217
+ # gate it on the canonical language.
218
+ canon = _canonical_language(self.settings.language)
219
+ business = {
220
+ "language": canon,
221
+ "domain": "iat",
222
+ "vad_eos": self.settings.vad_eos,
223
+ }
224
+ if canon == "zh_cn":
225
+ business["accent"] = "mandarin"
142
226
  msg = {
143
227
  "common": {"app_id": self.settings.app_id},
144
- "business": {
145
- "language": self.settings.language,
146
- "domain": "iat",
147
- "accent": "mandarin",
148
- "vad_eos": 2000,
149
- },
228
+ "business": business,
150
229
  "data": {
151
230
  "status": 0,
152
231
  "format": "audio/L16;rate=16000",
@@ -263,15 +342,20 @@ class IflytekSTT(STTProvider):
263
342
  break
264
343
  frame_data = base64.b64encode(chunk).decode("utf-8")
265
344
  if is_first:
345
+ # See transcribe() for rationale on
346
+ # canonicalizing language and gating accent.
347
+ canon = _canonical_language(self.settings.language)
348
+ business = {
349
+ "language": canon,
350
+ "domain": "iat",
351
+ "dwa": "wpgs",
352
+ "vad_eos": self.settings.vad_eos,
353
+ }
354
+ if canon == "zh_cn":
355
+ business["accent"] = "mandarin"
266
356
  msg = {
267
357
  "common": {"app_id": self.settings.app_id},
268
- "business": {
269
- "language": self.settings.language,
270
- "domain": "iat",
271
- "accent": "mandarin",
272
- "dwa": "wpgs",
273
- "vad_eos": 2000,
274
- },
358
+ "business": business,
275
359
  "data": {
276
360
  "status": 0,
277
361
  "format": "audio/L16;rate=16000",
@@ -28,6 +28,28 @@ class IflytekTTSSettings(BaseSettings):
28
28
  api_secret: str = ""
29
29
  voice: str = "xiaoyan"
30
30
  speed: int = 50
31
+ # Audio output encoding requested from iFlytek.
32
+ # - "lame": MP3 frames (default; smaller, but caller must decode)
33
+ # - "raw": 16-bit PCM @ 16 kHz mono, big-endian L16 (drop-in
34
+ # playable as raw PCM; required by callers that wrap the
35
+ # bytes in a fixed-format wire envelope and assume PCM,
36
+ # e.g. wallex's RESP_VOICE which advertises
37
+ # encoding=raw/bitDepth=16/sampleRate=16000 to the
38
+ # panel — feeding MP3 bytes through that envelope plays
39
+ # back as pure noise on the speaker).
40
+ # Default stays "lame" for backward-compat; deployments that need
41
+ # PCM (wallex / direct hardware playback) override via yaml.
42
+ aue: str = "lame"
43
+ # Output sample rate for raw PCM mode (only meaningful when
44
+ # aue="raw"). 16000 matches what the panel and the iFlytek
45
+ # default both expect; left configurable so an 8 kHz device or
46
+ # a 24 kHz studio path doesn't have to fork the provider.
47
+ auf_rate: int = 16000
48
+ # Volume (0-100). iFlytek default is 50; making it explicit so
49
+ # the parameter parity with Java's TtsConfig is complete.
50
+ volume: int = 50
51
+ # Pitch (0-100). Same rationale as volume.
52
+ pitch: int = 50
31
53
 
32
54
  class IflytekTTS(TTSProvider):
33
55
  name = "iflytek-tts"
@@ -35,12 +57,17 @@ class IflytekTTS(TTSProvider):
35
57
  execution_mode = ExecMode.IN_PROCESS
36
58
  settings_cls = IflytekTTSSettings
37
59
  capabilities = {Capability.BATCH, Capability.STREAMING, Capability.MULTILINGUAL}
38
- field_options = {"voice": [
39
- "xiaoyan", "aisjiuxu", "aisxping", "aisjinger", "aisbabyxu",
40
- "x4_lingxiaolu_em", "x4_lingfeizhe_em", "xiaoyu", "xiaoqi",
41
- "xiaofeng", "xiaomei", "xiaolin", "xiaorong", "xiaoqian",
42
- "catherine", "john", "laura", "yuka", "xiaoqiukor",
43
- ]}
60
+ field_options = {
61
+ "voice": [
62
+ "xiaoyan", "aisjiuxu", "aisxping", "aisjinger", "aisbabyxu",
63
+ "x4_lingxiaolu_em", "x4_lingfeizhe_em", "xiaoyu", "xiaoqi",
64
+ "xiaofeng", "xiaomei", "xiaolin", "xiaorong", "xiaoqian",
65
+ "catherine", "john", "laura", "yuka", "xiaoqiukor",
66
+ # English assistant-style voices used by wallex deployments.
67
+ "x4_enuk_ashleigh_assist",
68
+ ],
69
+ "aue": ["lame", "raw"],
70
+ }
44
71
 
45
72
  _WS_HOST = "tts-api.xfyun.cn"
46
73
  _WS_PATH = "/v2/tts"
@@ -107,12 +134,21 @@ class IflytekTTS(TTSProvider):
107
134
  async for chunk in self.synthesize_stream(text, opts):
108
135
  parts.append(chunk.data)
109
136
  audio_bytes = b"".join(parts)
110
- logger.info("iFlytek TTS: {} chunks, {} MP3 bytes total", len(parts), len(audio_bytes))
137
+ # Format / sample_rate must reflect what iFlytek actually returned —
138
+ # callers downstream may set wire-protocol encoding metadata from
139
+ # this field, and a wrong tag on the bytes plays back as noise on
140
+ # raw-PCM consumers.
141
+ fmt = "pcm_s16le" if self.settings.aue == "raw" else "mp3"
142
+ sr = self.settings.auf_rate if self.settings.aue == "raw" else 16000
143
+ logger.info(
144
+ "iFlytek TTS: {} chunks, {} bytes total, format={}, sample_rate={}",
145
+ len(parts), len(audio_bytes), fmt, sr,
146
+ )
111
147
  return AudioData(
112
148
  data=audio_bytes,
113
- sample_rate=16000,
149
+ sample_rate=sr,
114
150
  channels=1,
115
- format="mp3",
151
+ format=fmt,
116
152
  )
117
153
 
118
154
  # iFlytek voice catalog — vcn → (display name, language, group)
@@ -147,15 +183,30 @@ class IflytekTTS(TTSProvider):
147
183
  vcn = voice or self.settings.voice
148
184
  spd = int(speed * 50) if speed and speed != 1.0 else self.settings.speed
149
185
  text_b64 = base64.b64encode(text.encode("utf-8")).decode("utf-8")
186
+ business: dict[str, Any] = {
187
+ "aue": self.settings.aue,
188
+ "vcn": vcn,
189
+ "speed": spd,
190
+ "volume": self.settings.volume,
191
+ "pitch": self.settings.pitch,
192
+ "tte": "UTF8",
193
+ }
194
+ if self.settings.aue == "lame":
195
+ # ``sfl=1`` (stream-frame-length) is an MP3-only knob that
196
+ # tells iFlytek to emit per-frame audio rather than waiting
197
+ # for the whole file. It has no meaning for raw PCM (raw is
198
+ # always streamed as 40 ms slices) and iFlytek rejects the
199
+ # combo with a code 10005 "invalid parameter" — so we only
200
+ # send it on the lame path.
201
+ business["sfl"] = 1
202
+ else:
203
+ # Raw / L16 mode requires ``auf`` to declare the PCM
204
+ # sample-rate iFlytek should produce. Java wallex sends
205
+ # ``audio/L16;rate=16000`` here; we mirror that exactly.
206
+ business["auf"] = f"audio/L16;rate={self.settings.auf_rate}"
150
207
  return {
151
208
  "common": {"app_id": self.settings.app_id},
152
- "business": {
153
- "aue": "lame",
154
- "sfl": 1,
155
- "vcn": vcn,
156
- "speed": spd,
157
- "tte": "UTF8",
158
- },
209
+ "business": business,
159
210
  "data": {
160
211
  "status": 2,
161
212
  "text": text_b64,
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "openspeechapi"
7
- version = "0.2.0"
7
+ version = "0.2.3"
8
8
  description = "Unified speech interface for STT/TTS providers"
9
9
  requires-python = ">=3.11"
10
10
  dependencies = [
File without changes
File without changes
File without changes
File without changes
File without changes