feat: voice and model pickers with sync-on-join (Phase 4)

- Voices.swift: 13 Azure voices, default en-US-Ava
- SettingsStore: persist voiceID/modelID, fallback to default voice
- VoiceSession: sync set_voice/set_model on agent_ready, selectVoice/selectModel, track models + model_changed
- SettingsView: voice and model picker sheets
- ControlChannel: publish via publish(data:) reliable data channel instead of sendText DataStream (agent listens on legacy data_received; DataStream text was dropped)
This commit is contained in:
snowspeeder committed 2026-08-30 07:50:45 -04:00
1 parent 5483e6ed48
commit ca2d26f171
8 files changed
+256 -14

No files matched your search

+2 -2
View File
@@ -84,8 +84,8 @@ final class ControlChannel: NSObject, RoomDelegate {
// MARK: Outbound (topic'd JSON over reliable data streams)
private func publish(_ object: [String: Any], topic: String, room: Room) async throws {
let text = String(data: try JSONSerialization.data(withJSONObject: object), encoding: .utf8) ?? "{}"
_ = try await room.localParticipant.sendText(text, for: topic)
let data = try JSONSerialization.data(withJSONObject: object)
try await room.localParticipant.publish(data: data, options: DataPublishOptions(topic: topic, reliable: true))
}
func setVoice(_ voiceID: String, room: Room) async throws {