Files
openclaw/apps/ios/Sources/Voice/TalkRealtimeClientSession.swift
Peter Steinberger 26bfa88bb2 fix: restore native Talk transcripts, fallback, and microphone access (#115577)
* fix(ios): decode frameless Talk events

* fix(android): keep browser-only Talk models native

* fix(macos): gate dashboard media capture

* docs(talk): clarify native platform fallbacks

* chore(i18n): refresh native source inventory

* fix(android): gate relay entry on provider-level browser-only models too
2026-07-29 01:55:47 -04:00

131 lines
2.9 KiB
Swift

import Foundation
struct TalkRealtimeClientCreateParams: Encodable {
var sessionKey: String?
var voiceSessionId: String?
var mode = "realtime"
var provider: String?
var transport = "webrtc"
var brain = "agent-consult"
var model: String?
var voice: String?
var capabilities: [String]
}
struct TalkRealtimeClientSession: Decodable {
let provider: String
let transport: String
let voiceSessionId: String?
let clientSecret: String
let offerUrl: String?
let offerHeaders: [String: String]?
let model: String?
let voice: String?
let expiresAt: Double?
var isWebRTC: Bool {
self.transport.caseInsensitiveCompare("webrtc") == .orderedSame
}
}
enum TalkRealtimeTranscriptRole: String, Encodable {
case user
case assistant
}
struct TalkRealtimeTranscriptParams: Encodable {
let sessionKey: String
let voiceSessionId: String
let entryId: String
let role: TalkRealtimeTranscriptRole
let text: String
let timestamp: Double?
}
struct TalkRealtimeClientCloseParams: Encodable {
let sessionKey: String
let voiceSessionId: String
}
struct TalkRealtimeToolCallResponse: Decodable {
let runId: String?
let idempotencyKey: String?
}
struct TalkRealtimeServerEvent: Decodable {
let type: String
let error: TalkRealtimeServerError?
let itemId: String?
let item: TalkRealtimeServerItem?
let turn: TalkRealtimeServerTurn?
let callId: String?
let name: String?
let delta: String?
let arguments: String?
let transcript: String?
let text: String?
enum CodingKeys: String, CodingKey {
case type
case error
case itemId = "item_id"
case item
case turn
case callId = "call_id"
case name
case delta
case arguments
case transcript
case text
}
var resolvedItemId: String? {
self.itemId ?? self.item?.id
}
var resolvedCallId: String? {
self.callId ?? self.item?.callId
}
var resolvedName: String? {
self.name ?? self.item?.name
}
var resolvedArguments: String? {
self.arguments ?? self.item?.arguments
}
var isMaximumDurationError: Bool {
guard self.type == "error", let message = self.error?.message?.lowercased() else { return false }
return message.contains("session") && message.contains("maximum duration")
}
}
struct TalkRealtimeServerError: Decodable {
let message: String?
}
struct TalkRealtimeServerTurn: Decodable {
let id: String?
let role: String?
let transcript: String?
}
struct TalkRealtimeServerItem: Decodable {
let id: String?
let type: String?
let text: String?
let callId: String?
let name: String?
let arguments: String?
enum CodingKeys: String, CodingKey {
case id
case type
case text
case callId = "call_id"
case name
case arguments
}
}