Skip to content

Commit e9dc851

Browse files
renal128cursoragent
andcommitted
Pass environment on the public-agent text handshake and conversation init.
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent dfe34cd commit e9dc851

5 files changed

Lines changed: 37 additions & 4 deletions

File tree

Sources/ElevenLabs/Internal/Networking/WebSocketConnectionManager.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ final class WebSocketConnectionManager: WebSocketConnectionManaging {
5151
do {
5252
resolved = try await Self.websocketUrl(
5353
for: auth,
54-
endpoints: endpoints
54+
endpoints: endpoints,
55+
environment: config.environment
5556
)
5657
} catch {
5758
metrics.total = Date().timeIntervalSince(startTime)
@@ -178,7 +179,8 @@ final class WebSocketConnectionManager: WebSocketConnectionManaging {
178179

179180
static func websocketUrl(
180181
for auth: ConversationAuth.TextOnly,
181-
endpoints: Endpoints
182+
endpoints: Endpoints,
183+
environment: String? = nil
182184
) async throws -> (url: URL, agentId: String) {
183185
switch auth {
184186
case let .publicAgent(agentId):
@@ -187,6 +189,9 @@ final class WebSocketConnectionManager: WebSocketConnectionManaging {
187189
}
188190
var queryItems = components.queryItems ?? []
189191
queryItems.append(URLQueryItem(name: "agent_id", value: agentId))
192+
if let environment {
193+
queryItems.append(URLQueryItem(name: "environment", value: environment))
194+
}
190195
components.queryItems = queryItems
191196
guard let url = components.url else {
192197
throw ConversationError.authenticationFailed("Invalid conversation URL")

Sources/ElevenLabs/Internal/Utilities/EventSerializer.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ enum EventSerializer {
128128
json["user_id"] = userId
129129
}
130130

131+
if let environment = config.environment {
132+
json["environment"] = environment
133+
}
134+
131135
return json
132136
}
133137
}

Sources/ElevenLabs/Public/Conversation/ConversationConfig.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ public struct ConversationConfig: Sendable {
88
public var customLlmExtraBody: [String: String]? // Simplified to be Sendable
99
public var dynamicVariables: [String: String]? // Simplified to be Sendable
1010
public var userId: String?
11-
/// Optional environment for the agent (defaults to production when nil)
11+
/// Workspace environment (`production` if nil). Applied to the public-agent
12+
/// handshake and conversation init.
1213
public var environment: String?
1314

1415
/// How to handle microphone setup failures during connection.

Tests/ElevenLabsTests/Mocks/MockWebSocketConnectionManager.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ final class MockWebSocketConnectionManager: WebSocketConnectionManaging {
3737
do {
3838
resolved = try await WebSocketConnectionManager.websocketUrl(
3939
for: auth,
40-
endpoints: config.endpoints
40+
endpoints: config.endpoints,
41+
environment: config.environment
4142
)
4243
lastConnectedURL = resolved.url
4344
} catch {

Tests/ElevenLabsTests/Unit/ElevenLabsSDKTests.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,28 @@ final class ElevenLabsSDKTests: XCTestCase {
5656
XCTAssertEqual(resolved.agentId, "agent-123")
5757
}
5858

59+
@MainActor
60+
func testWebsocketUrlAppendsPublicAgentEnvironment() async throws {
61+
let resolved = try await WebSocketConnectionManager.websocketUrl(
62+
for: .publicAgent(id: "agent-123"),
63+
endpoints: .production,
64+
environment: "staging"
65+
)
66+
XCTAssertEqual(
67+
resolved.url.absoluteString,
68+
"wss://api.elevenlabs.io/v1/convai/conversation?agent_id=agent-123&environment=staging"
69+
)
70+
}
71+
72+
func testConversationInitIncludesEnvironment() throws {
73+
let config = ConversationConfig(environment: "staging")
74+
let data = try EventSerializer.serializeOutgoingEvent(
75+
.conversationInit(ConversationInitEvent(config: config))
76+
)
77+
let json = try XCTUnwrap(JSONSerialization.jsonObject(with: data) as? [String: Any])
78+
XCTAssertEqual(json["environment"] as? String, "staging")
79+
}
80+
5981
func testConversationConfigDefaults() {
6082
let config = ConversationConfig()
6183

0 commit comments

Comments
 (0)