Skip to content

fix: 流式转写服务的连通性测试改走流式客户端 - #7

Open
Syfer-Omestics wants to merge 1 commit into
Lynn-x:mainfrom
Syfer-Omestics:fix/streaming-asr-connectivity-test
Open

Syfer-Omestics wants to merge 1 commit into
Lynn-x:mainfrom
Syfer-Omestics:fix/streaming-asr-connectivity-test

Conversation

@Syfer-Omestics

Copy link
Copy Markdown

Fixes #6

问题

runAsrConnectivityTest() 无条件调 transcribeAudio(),而后者第一件事就是 assertSafeServiceEndpoint(p.endpoint, "http", "转写服务地址")。流式服务(OpenAI Realtime 转写 / 翻译、百炼 Paraformer)的端点全是 wss://,既不匹配 https: 也不匹配 http:,于是掉进 getServiceEndpointSecurityIssue() 最后那个 return

测试失败:转写服务地址协议不受支持;请使用 HTTPS,本地、私网或 Tailscale 等私有网络服务可使用 HTTP

WebSocket 客户端一次都没被碰到。录音路径是好的——main.ts 里那条兜底分支的注释早就写了「端点是 wss://,HTTP 必失败」——只是连通性测试没跟上。

改动

流式服务改用录音时同一套客户端自检。 testStreamingTranscribeConnectivity() 建连、灌 1 秒静音、收网,把服务端说的话原样报出来。几个取舍:

  • 静音探针,空文本算通过。 静音不触发 VAD,不会出字。这个按钮回答的是「连不连得上」,不是「认不认得出」——握手、鉴权、会话协商过了就够了,为了让它出字而去合成一段真语音,既拖慢按钮又把断言绑死在识别质量上。
  • 送完音频留 1.2 秒宽限窗口。 模型名写错、账号没权限这类拒绝,服务端通常要等收到首帧音频之后才回 error 事件。送完就判会漏掉它们,白报一个「连通成功」。
  • 握手失败不 await finish() connect() 挂掉时底层 socket 已经被 ws 关了,再等只是白白耗掉客户端那 5 秒收网超时,按钮干转。改走 _safeClose()

createStreamingTranscriptionClientmain.ts 搬到 asr/clients.ts,和它 new 出来的那三个客户端类放一起,设置页才够得着(否则要 import main)。纯搬迁,逻辑没动。

端点说明补一句 ?model= OpenAIRealtimeTranslationClient 会自己拼 ?model=OpenAIRealtimeTranscriptionClient 是地址原样使用。官方端点没问题,但自建 / 中转的 OpenAI 兼容服务很多要求 URL 带 ?model=,不带直接 403,而设置项只写了「保持默认即可」。这里只改了说明文案和关闭时的报错提示,没有动拼 URL 的行为——给官方端点自动加 ?model= 会把它从 transcription session 变成 conversation session,风险不该塞在这个 PR 里。要不要对齐两个客户端,留给你定。

验证

  • npm run verify(lint + build + test)通过,434 + 5 个测试
  • 新增 tests/streaming-connectivity-test.test.ts 5 例:钉住原 bug 的那条 http 校验分支、静音探针的帧数与收网、首帧之后才到的服务端拒绝、握手失败不空等 finish()、三个协议各自路由且端点原样透传
  • 拿一个自建的 OpenAI 兼容实时 ASR 服务实测过完整链路:wss://<host>/v1/realtime?model=<model> 握手 101 → transcription_session.created.delta / .completed 正常出中文;不带 ?model= 的地址 403

main.js 按仓库惯例一并重新构建提交了。

🤖 Generated with Claude Code

The 连通性测试 button called transcribeAudio() unconditionally, which
asserts an HTTP endpoint. Streaming providers (OpenAI Realtime
transcription/translation, DashScope Paraformer) all use wss://
endpoints, so the assert fell through to its last branch and the button
reported "转写服务地址协议不受支持" for every one of them — the WebSocket
client was never reached. Recording itself worked; only the self-test
was broken.

Streaming profiles now probe through the same client recording uses:
connect, stream one second of silence, and report whatever the server
says. Silence does not trip VAD, so an empty transcript is a pass — the
test answers "can it connect", not "can it hear". A server-side
rejection (bad model name, no permission) usually arrives only after the
first audio frame, hence the grace window before the verdict.

createStreamingTranscriptionClient moves from main.ts to asr/clients.ts,
next to the three client classes it constructs, so the settings tab can
reach it without importing main.

Also spell out in the endpoint help and the close-error hint that
self-hosted and relayed OpenAI-compatible services often need the full
path plus ?model=<name>: unlike the translation client, the
transcription client uses the configured address verbatim.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] v2.1.2:流式转写服务的「连通性测试」必然失败,报「转写服务地址协议不受支持」

1 participant