Files
sundynix-agentix/sundynix-gateway/internal/voice/protocol.go
T
Blizzard b6927247da feat(voice): 下行打字机文本流 + 首块快出,即时反馈
- protocol.go: 新增 ServerReply("reply") 消息——Agent 回答增量文本
- voice_tts.go: token 一到即转发客户端(打字机),同时攒句喂 TTS(音频随后)
- sentence_buffer.go: 本轮首句用低阈值(5 rune)抢首字延迟,之后回常规 12
- 桌面端 voice.ts onReply + VoiceDock 对话气泡(我说的 + JARVIS 打字机回答,思考态光标)

管线已最优:文字在 LLM 首 token 即刻上屏、音频紧随。剩余时延=大模型 TTFT(deepseek-v4-pro
4-7s 且波动大,疑似推理模型),这是模型的账、非管线——真要"马上响应"需换快模型。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 11:25:20 +08:00

57 lines
2.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package voice
// 客户端 ↔ 网关的单条 WebSocket 消息协议(设计 VOICE_DESIGN.md D3):
// 一条连接同时承载上行音频、下行转写、下行 TTS 音频,用「帧类型 + JSON 消息类型」区分。
//
// - 二进制帧(BinaryMessage):纯音频 PCM
// · 上行 = 用户麦克风音频(喂 ASR)
// · 下行 = Agent 回答的 TTS 音频(客户端播放)
// - 文本帧(TextMessage, JSON):控制与事件(下方 ClientMsg / ServerMsg
// ClientMsg 是客户端发来的控制消息(文本帧)。音频走二进制帧,不在此。
type ClientMsg struct {
Type string `json:"type"`
// start:一轮语音开始(可带当前画布编排图,用它跑而非默认 DSL)
Graph string `json:"graph,omitempty"`
// 其它类型无额外字段:end(用户说完)、barge_in(打断,用户又开口)、bye(结束会话)
}
// 客户端消息类型。
const (
ClientStart = "start" // 一轮语音开始
ClientEnd = "end" // 用户说完(静音检测或手动结束)→ 触发任务
ClientBargeIn = "barge_in" // 打断:用户在 Agent 说话时又开口 → 停 TTS
ClientBye = "bye" // 结束整个语音会话
)
// ServerMsg 是网关下发的控制/事件消息(文本帧)。TTS 音频走二进制帧,不在此。
type ServerMsg struct {
Type string `json:"type"`
// transcriptASR 转写(Final=false 为实时部分结果,true 为最终)
// reply:Agent 回答的增量文本(打字机效果,逐 token 下发,早于音频)
Text string `json:"text,omitempty"`
Final bool `json:"final,omitempty"`
// task:转写完成、任务已提交,带 task_id 供客户端切运行视图
TaskID string `json:"task_id,omitempty"`
// error:出错文案
Msg string `json:"msg,omitempty"`
}
// 服务端消息类型。
const (
ServerReady = "ready" // 会话就绪,可以开始说话
ServerTranscript = "transcript" // ASR 转写结果(部分/最终)
ServerTask = "task" // 任务已提交(带 task_id
ServerReply = "reply" // Agent 回答增量文本(打字机;逐 token,早于音频)
ServerSpeaking = "speaking" // Agent 开始出声(首段 TTS 音频将至)
ServerTTSEnd = "tts_end" // 本轮 TTS 播放完毕
ServerError = "error" // 出错
)
// 音频格式(与火山 ASR/TTS 约定,客户端按此采集/播放)。
const (
AudioSampleRate = 16000 // 上行 ASR16kHz
AudioBits = 16 // 16bit
AudioChannels = 1 // 单声道
)