connect method

Future<LiveSession> connect({
  1. required String model,
  2. LiveConfig? liveConfig,
  3. String? accessToken,
})

Connects to the Live API and starts a new session.

model is the model to use (e.g., 'gemini-2.0-flash-live-001'). liveConfig contains session configuration (generation, VAD, tools, etc.). accessToken is an optional ephemeral token for client-side authentication. When provided, this token is used instead of the configured auth provider.

Returns a LiveSession for bidirectional streaming.

Throws LiveConnectionException if the connection fails. Throws LiveSessionSetupException if session setup fails.

Using Ephemeral Tokens

Ephemeral tokens allow secure client-side authentication without exposing the main API key. Create tokens server-side using AuthTokensResource.create:

// Server-side
final token = await client.authTokens.create(
  authToken: AuthToken(
    expireTime: DateTime.now().add(Duration(minutes: 30)),
    uses: 1,
  ),
);

// Client-side
final session = await liveClient.connect(
  model: 'gemini-2.0-flash-live-001',
  accessToken: tokenFromServer,
);

Implementation

Future<LiveSession> connect({
  required String model,
  LiveConfig? liveConfig,
  String? accessToken,
}) async {
  final uri = await _buildWebSocketUri(model, accessToken: accessToken);
  _log.fine('Connecting to Live API');

  // Get headers for Vertex AI OAuth (native platforms only)
  // Web platforms don't support WebSocket headers - the connector will throw
  // a clear error if headers are needed but not supported.
  Map<String, String>? headers;
  if (_config.apiMode == ApiMode.vertexAI && accessToken == null) {
    final credentials = await _config.authProvider?.getCredentials();
    if (credentials is BearerTokenCredentials) {
      headers = {'Authorization': 'Bearer ${credentials.token}'};
    }
  }

  // Phase 1: Establish WebSocket connection
  LiveSession session;
  try {
    // Connect WebSocket with optional auth headers
    // On native platforms (dart:io), headers are passed to the WebSocket.
    // On web platforms, if headers are provided, a clear error is thrown.
    final socket = await ws.connectWebSocket(uri, headers: headers);

    // Create session
    session = LiveSession.fromWebSocket(socket);
    _sessions.add(session);
  } on Exception catch (e) {
    throw LiveConnectionException(
      message: 'Failed to connect to Live API: $e',
      uri: uri,
      cause: e,
    );
  }

  // Phase 2: Setup session (separate try block to surface setup errors)
  try {
    await _setupSession(session, model, liveConfig);
    _log.fine('Live session established: ${session.sessionId}');
    return session;
  } on LiveSessionSetupException {
    // Clean up failed session and rethrow setup errors directly
    await session.close();
    _sessions.remove(session);
    rethrow;
  } on Exception catch (e) {
    // Clean up failed session and wrap other errors
    await session.close();
    _sessions.remove(session);
    throw LiveSessionSetupException(
      message: 'Session setup failed: $e',
      cause: e,
    );
  }
}