@@ -5,7 +5,7 @@ import os.log
5
5
6
6
/// Main class for ElevenLabsSwift package
7
7
public class ElevenLabsSDK {
8
- public static let version = " 1.0.0 "
8
+ public static let version = " 1.0.1 "
9
9
10
10
private enum Constants {
11
11
static let defaultApiOrigin = " wss://api.elevenlabs.io "
@@ -18,6 +18,80 @@ public class ElevenLabsSDK {
18
18
static let bufferSize : AVAudioFrameCount = 1024
19
19
}
20
20
21
+ // MARK: - Session Config Utilities
22
+
23
+ public enum Language : String , Codable , Sendable {
24
+ case en, ja, zh, de, hi, fr, ko, pt, it, es, id, nl, tr, pl, sv, bg, ro, ar, cs, el, fi, ms, da, ta, uk, ru, hu, no, vi
25
+ }
26
+
27
+ public struct AgentPrompt : Codable , Sendable {
28
+ public var prompt : String ?
29
+
30
+ public init ( prompt: String ? = nil ) {
31
+ self . prompt = prompt
32
+ }
33
+ }
34
+
35
+ public struct TTSConfig : Codable , Sendable {
36
+ public var voiceId : String ?
37
+
38
+ private enum CodingKeys : String , CodingKey {
39
+ case voiceId = " voice_id "
40
+ }
41
+
42
+ public init ( voiceId: String ? = nil ) {
43
+ self . voiceId = voiceId
44
+ }
45
+ }
46
+
47
+ public struct ConversationConfigOverride : Codable , Sendable {
48
+ public var agent : AgentConfig ?
49
+ public var tts : TTSConfig ?
50
+
51
+ public init ( agent: AgentConfig ? = nil , tts: TTSConfig ? = nil ) {
52
+ self . agent = agent
53
+ self . tts = tts
54
+ }
55
+ }
56
+
57
+ public struct AgentConfig : Codable , Sendable {
58
+ public var prompt : AgentPrompt ?
59
+ public var firstMessage : String ?
60
+ public var language : Language ?
61
+
62
+ private enum CodingKeys : String , CodingKey {
63
+ case prompt
64
+ case firstMessage = " first_message "
65
+ case language
66
+ }
67
+
68
+ public init ( prompt: AgentPrompt ? = nil , firstMessage: String ? = nil , language: Language ? = nil ) {
69
+ self . prompt = prompt
70
+ self . firstMessage = firstMessage
71
+ self . language = language
72
+ }
73
+ }
74
+
75
+ public enum LlmExtraBodyValue : Codable , Sendable {
76
+ case string( String )
77
+ case number( Double )
78
+ case boolean( Bool )
79
+ case null
80
+ case array( [ LlmExtraBodyValue ] )
81
+ case dictionary( [ String : LlmExtraBodyValue ] )
82
+
83
+ var jsonValue : Any {
84
+ switch self {
85
+ case let . string( str) : return str
86
+ case let . number( num) : return num
87
+ case let . boolean( bool) : return bool
88
+ case . null: return NSNull ( )
89
+ case let . array( arr) : return arr. map { $0. jsonValue }
90
+ case let . dictionary( dict) : return dict. mapValues { $0. jsonValue }
91
+ }
92
+ }
93
+ }
94
+
21
95
// MARK: - Audio Utilities
22
96
23
97
public static func arrayBufferToBase64( _ data: Data ) -> String {
@@ -113,15 +187,21 @@ public class ElevenLabsSDK {
113
187
public struct SessionConfig : Sendable {
114
188
public let signedUrl : String ?
115
189
public let agentId : String ?
190
+ public let overrides : ConversationConfigOverride ?
191
+ public let customLlmExtraBody : [ String : LlmExtraBodyValue ] ?
116
192
117
- public init ( signedUrl: String ) {
193
+ public init ( signedUrl: String , overrides : ConversationConfigOverride ? = nil , customLlmExtraBody : [ String : LlmExtraBodyValue ] ? = nil ) {
118
194
self . signedUrl = signedUrl
119
195
agentId = nil
196
+ self . overrides = overrides
197
+ self . customLlmExtraBody = customLlmExtraBody
120
198
}
121
199
122
- public init ( agentId: String ) {
200
+ public init ( agentId: String , overrides : ConversationConfigOverride ? = nil , customLlmExtraBody : [ String : LlmExtraBodyValue ] ? = nil ) {
123
201
self . agentId = agentId
124
202
signedUrl = nil
203
+ self . overrides = overrides
204
+ self . customLlmExtraBody = customLlmExtraBody
125
205
}
126
206
}
127
207
@@ -157,6 +237,25 @@ public class ElevenLabsSDK {
157
237
let socket = session. webSocketTask ( with: url)
158
238
socket. resume ( )
159
239
240
+ // Always send initialization event
241
+ var initEvent : [ String : Any ] = [ " type " : " conversation_initiation_client_data " ]
242
+
243
+ // Add overrides if present
244
+ if let overrides = config. overrides,
245
+ let overridesDict = overrides. dictionary
246
+ {
247
+ initEvent [ " conversation_config_override " ] = overridesDict
248
+ }
249
+
250
+ // Add custom body if present
251
+ if let customBody = config. customLlmExtraBody {
252
+ initEvent [ " custom_llm_extra_body " ] = customBody. mapValues { $0. jsonValue }
253
+ }
254
+
255
+ let jsonData = try JSONSerialization . data ( withJSONObject: initEvent)
256
+ let jsonString = String ( data: jsonData, encoding: . utf8) !
257
+ try await socket. send ( . string( jsonString) )
258
+
160
259
let configData = try await receiveInitialMessage ( socket: socket)
161
260
return Connection ( socket: socket, conversationId: configData. conversationId, sampleRate: configData. sampleRate)
162
261
}
@@ -1012,3 +1111,10 @@ private extension Data {
1012
1111
self = buffer. withUnsafeBufferPointer { Data ( buffer: $0) }
1013
1112
}
1014
1113
}
1114
+
1115
+ extension Encodable {
1116
+ var dictionary : [ String : Any ] ? {
1117
+ guard let data = try ? JSONEncoder ( ) . encode ( self ) else { return nil }
1118
+ return ( try ? JSONSerialization . jsonObject ( with: data, options: . allowFragments) ) as? [ String : Any ]
1119
+ }
1120
+ }
0 commit comments