or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

batch-operations.mdcaching.mdchat-sessions.mdclient-configuration.mdcontent-generation.mdembeddings-tokens.mderror-handling.mdfile-search-stores.mdfiles-management.mdimage-operations.mdindex.mdlive-sessions.mdmodel-tuning.mdoperations.mdtools-functions.mdtypes-reference.mdvideo-generation.md

live-sessions.mddocs/

0

# Live Sessions (Experimental)

1

2

**WARNING: This API is experimental and subject to change.**

3

4

Real-time bidirectional communication with AI models using WebSocket connections. Live sessions enable low-latency, streaming interactions for applications requiring immediate responses, such as voice assistants, real-time translation, or interactive chatbots.

5

6

## Core Imports

7

8

```java

9

import com.google.genai.AsyncLive;

10

import com.google.genai.AsyncSession;

11

import com.google.genai.types.LiveConnectConfig;

12

import com.google.genai.types.LiveSendClientContentParameters;

13

import com.google.genai.types.LiveSendRealtimeInputParameters;

14

import com.google.genai.types.LiveSendToolResponseParameters;

15

import com.google.genai.types.LiveServerMessage;

16

import java.util.concurrent.CompletableFuture;

17

import java.util.function.Consumer;

18

```

19

20

## AsyncLive Service

21

22

```java { .api }

23

package com.google.genai;

24

25

public class AsyncLive {

26

public CompletableFuture<AsyncSession> connect(

27

String model,

28

LiveConnectConfig config);

29

}

30

```

31

32

## AsyncSession Class

33

34

```java { .api }

35

package com.google.genai;

36

37

public final class AsyncSession {

38

// Send client content

39

public CompletableFuture<Void> sendClientContent(

40

LiveSendClientContentParameters clientContent);

41

42

// Send realtime audio input

43

public CompletableFuture<Void> sendRealtimeInput(

44

LiveSendRealtimeInputParameters realtimeInput);

45

46

// Send tool/function response

47

public CompletableFuture<Void> sendToolResponse(

48

LiveSendToolResponseParameters toolResponse);

49

50

// Register callback for server messages

51

public CompletableFuture<Void> receive(

52

Consumer<LiveServerMessage> onMessage);

53

54

// Close WebSocket connection

55

public CompletableFuture<Void> close();

56

57

// Get session ID

58

public String sessionId();

59

}

60

```

61

62

## Live Connect Config

63

64

```java { .api }

65

package com.google.genai.types;

66

67

public final class LiveConnectConfig {

68

public static Builder builder();

69

70

public Optional<GenerateContentConfig> config();

71

public Optional<HttpOptions> httpOptions();

72

}

73

```

74

75

## Live Server Message

76

77

```java { .api }

78

package com.google.genai.types;

79

80

public final class LiveServerMessage {

81

public static LiveServerMessage fromJson(String json);

82

83

public Optional<SetupComplete> setupComplete();

84

public Optional<ServerContent> serverContent();

85

public Optional<ToolCall> toolCall();

86

public Optional<ToolCallCancellation> toolCallCancellation();

87

}

88

```

89

90

## Basic Usage

91

92

### Connect to Live Session

93

94

```java

95

import com.google.genai.Client;

96

import com.google.genai.AsyncLive;

97

import com.google.genai.AsyncSession;

98

99

Client client = new Client();

100

101

// Connect to live session

102

CompletableFuture<AsyncSession> sessionFuture =

103

client.async.live.connect("gemini-2.0-flash", null);

104

105

sessionFuture.thenAccept(session -> {

106

System.out.println("Connected! Session ID: " + session.sessionId());

107

108

// Register message receiver

109

session.receive(message -> {

110

message.serverContent().ifPresent(content -> {

111

System.out.println("Server: " + content);

112

});

113

});

114

115

// Send a message

116

LiveSendClientContentParameters params =

117

LiveSendClientContentParameters.builder()

118

.turns(List.of(

119

Content.fromParts(Part.fromText("Hello from live session!"))

120

))

121

.build();

122

123

session.sendClientContent(params).thenRun(() -> {

124

System.out.println("Message sent successfully");

125

});

126

});

127

```

128

129

### Connect with Configuration

130

131

```java

132

import com.google.genai.types.LiveConnectConfig;

133

import com.google.genai.types.GenerateContentConfig;

134

135

GenerateContentConfig contentConfig = GenerateContentConfig.builder()

136

.temperature(0.7)

137

.maxOutputTokens(1024)

138

.build();

139

140

LiveConnectConfig connectConfig = LiveConnectConfig.builder()

141

.config(contentConfig)

142

.build();

143

144

CompletableFuture<AsyncSession> sessionFuture =

145

client.async.live.connect("gemini-2.0-flash", connectConfig);

146

147

sessionFuture.thenAccept(session -> {

148

System.out.println("Connected with config");

149

});

150

```

151

152

## Sending Messages

153

154

### Send Text Content

155

156

```java

157

import com.google.genai.types.LiveSendClientContentParameters;

158

import com.google.genai.types.Content;

159

import com.google.genai.types.Part;

160

import java.util.List;

161

162

AsyncSession session = /* ... */;

163

164

Content userMessage = Content.fromParts(

165

Part.fromText("What is the weather like today?")

166

);

167

168

LiveSendClientContentParameters params =

169

LiveSendClientContentParameters.builder()

170

.turns(List.of(userMessage))

171

.turnComplete(true)

172

.build();

173

174

session.sendClientContent(params).thenRun(() -> {

175

System.out.println("Content sent");

176

}).exceptionally(error -> {

177

System.err.println("Failed to send: " + error.getMessage());

178

return null;

179

});

180

```

181

182

### Send Multiple Turns

183

184

```java

185

Content turn1 = Content.fromParts(Part.fromText("Tell me about AI"));

186

Content turn2 = Content.fromParts(Part.fromText("Specifically machine learning"));

187

188

LiveSendClientContentParameters params =

189

LiveSendClientContentParameters.builder()

190

.turns(List.of(turn1, turn2))

191

.turnComplete(true)

192

.build();

193

194

session.sendClientContent(params);

195

```

196

197

### Send Realtime Audio Input

198

199

```java

200

import com.google.genai.types.LiveSendRealtimeInputParameters;

201

202

// Send audio chunks for real-time processing

203

byte[] audioData = /* audio bytes */;

204

205

LiveSendRealtimeInputParameters audioParams =

206

LiveSendRealtimeInputParameters.builder()

207

.mediaChunks(List.of(audioData))

208

.build();

209

210

session.sendRealtimeInput(audioParams).thenRun(() -> {

211

System.out.println("Audio sent");

212

});

213

```

214

215

### Send Tool Response

216

217

```java

218

import com.google.genai.types.LiveSendToolResponseParameters;

219

import com.google.genai.types.FunctionResponse;

220

221

// Respond to a tool call from the model

222

FunctionResponse functionResponse = FunctionResponse.builder()

223

.name("get_weather")

224

.response(Map.of("temperature", 72, "condition", "sunny"))

225

.build();

226

227

LiveSendToolResponseParameters toolParams =

228

LiveSendToolResponseParameters.builder()

229

.functionResponses(List.of(functionResponse))

230

.build();

231

232

session.sendToolResponse(toolParams);

233

```

234

235

## Receiving Messages

236

237

### Register Message Callback

238

239

```java

240

import com.google.genai.types.LiveServerMessage;

241

242

AsyncSession session = /* ... */;

243

244

session.receive(message -> {

245

// Handle setup complete

246

message.setupComplete().ifPresent(setup -> {

247

System.out.println("Setup complete for session: " +

248

setup.sessionId().orElse("N/A"));

249

});

250

251

// Handle server content

252

message.serverContent().ifPresent(content -> {

253

content.modelTurn().ifPresent(turn -> {

254

turn.parts().ifPresent(parts -> {

255

for (Part part : parts) {

256

part.text().ifPresent(text -> {

257

System.out.print(text);

258

});

259

}

260

});

261

});

262

});

263

264

// Handle tool calls

265

message.toolCall().ifPresent(toolCall -> {

266

toolCall.functionCalls().ifPresent(calls -> {

267

for (FunctionCall call : calls) {

268

System.out.println("Tool call: " + call.name().orElse("N/A"));

269

// Execute function and send response

270

});

271

});

272

});

273

274

// Handle tool call cancellation

275

message.toolCallCancellation().ifPresent(cancellation -> {

276

System.out.println("Tool call cancelled");

277

});

278

});

279

```

280

281

### Stream Text Response

282

283

```java

284

session.receive(message -> {

285

message.serverContent().ifPresent(content -> {

286

content.modelTurn().ifPresent(turn -> {

287

turn.parts().ifPresent(parts -> {

288

// Stream each chunk of text as it arrives

289

parts.forEach(part -> {

290

part.text().ifPresent(text -> {

291

System.out.print(text);

292

System.out.flush();

293

});

294

});

295

});

296

});

297

298

// Check if turn is complete

299

if (content.turnComplete().orElse(false)) {

300

System.out.println("\n[Turn complete]");

301

}

302

});

303

});

304

```

305

306

## Complete Interactive Example

307

308

### Real-time Chat Session

309

310

```java

311

import java.util.Scanner;

312

import java.util.concurrent.CountDownLatch;

313

314

public class LiveChatExample {

315

public static void main(String[] args) throws Exception {

316

Client client = new Client();

317

318

CompletableFuture<AsyncSession> sessionFuture =

319

client.async.live.connect("gemini-2.0-flash", null);

320

321

AsyncSession session = sessionFuture.get();

322

System.out.println("Connected! Session: " + session.sessionId());

323

324

CountDownLatch responseLatch = new CountDownLatch(1);

325

326

// Register message handler

327

session.receive(message -> {

328

message.serverContent().ifPresent(content -> {

329

content.modelTurn().ifPresent(turn -> {

330

turn.parts().ifPresent(parts -> {

331

parts.forEach(part -> {

332

part.text().ifPresent(text -> {

333

System.out.print(text);

334

});

335

});

336

});

337

});

338

339

if (content.turnComplete().orElse(false)) {

340

System.out.println();

341

responseLatch.countDown();

342

}

343

});

344

});

345

346

Scanner scanner = new Scanner(System.in);

347

348

while (true) {

349

System.out.print("\nYou: ");

350

String input = scanner.nextLine();

351

352

if ("exit".equalsIgnoreCase(input)) {

353

break;

354

}

355

356

Content userContent = Content.fromParts(Part.fromText(input));

357

358

LiveSendClientContentParameters params =

359

LiveSendClientContentParameters.builder()

360

.turns(List.of(userContent))

361

.turnComplete(true)

362

.build();

363

364

System.out.print("Bot: ");

365

session.sendClientContent(params).get();

366

367

// Wait for response to complete

368

responseLatch.await();

369

responseLatch = new CountDownLatch(1);

370

}

371

372

session.close().get();

373

scanner.close();

374

client.close();

375

}

376

}

377

```

378

379

### Voice Assistant with Audio

380

381

```java

382

// Real-time audio streaming example

383

AsyncSession session = client.async.live.connect(

384

"gemini-2.0-flash",

385

null

386

).get();

387

388

session.receive(message -> {

389

message.serverContent().ifPresent(content -> {

390

// Handle audio response from model

391

content.modelTurn().ifPresent(turn -> {

392

turn.parts().ifPresent(parts -> {

393

parts.forEach(part -> {

394

part.text().ifPresent(text -> {

395

System.out.println("Model: " + text);

396

});

397

// Handle audio output if present

398

part.inlineData().ifPresent(blob -> {

399

// Play audio response

400

});

401

});

402

});

403

});

404

});

405

});

406

407

// Stream audio input in real-time

408

try (AudioInputStream audioStream = /* microphone input */) {

409

byte[] buffer = new byte[4096];

410

int bytesRead;

411

412

while ((bytesRead = audioStream.read(buffer)) != -1) {

413

byte[] audioChunk = Arrays.copyOf(buffer, bytesRead);

414

415

LiveSendRealtimeInputParameters params =

416

LiveSendRealtimeInputParameters.builder()

417

.mediaChunks(List.of(audioChunk))

418

.build();

419

420

session.sendRealtimeInput(params);

421

}

422

}

423

```

424

425

## Function Calling in Live Sessions

426

427

### Register Functions and Handle Calls

428

429

```java

430

import com.google.genai.types.Tool;

431

import com.google.genai.types.FunctionDeclaration;

432

import com.google.genai.types.Schema;

433

434

// Define functions

435

FunctionDeclaration weatherFunction = FunctionDeclaration.builder()

436

.name("get_weather")

437

.description("Get current weather for a location")

438

.parameters(Schema.builder()

439

.type("object")

440

.properties(Map.of(

441

"location", Schema.builder().type("string").build()

442

))

443

.required(List.of("location"))

444

.build())

445

.build();

446

447

Tool tool = Tool.builder()

448

.functionDeclarations(List.of(weatherFunction))

449

.build();

450

451

GenerateContentConfig config = GenerateContentConfig.builder()

452

.tools(List.of(tool))

453

.build();

454

455

LiveConnectConfig liveConfig = LiveConnectConfig.builder()

456

.config(config)

457

.build();

458

459

AsyncSession session = client.async.live.connect(

460

"gemini-2.0-flash",

461

liveConfig

462

).get();

463

464

// Handle tool calls

465

session.receive(message -> {

466

message.toolCall().ifPresent(toolCall -> {

467

toolCall.functionCalls().ifPresent(calls -> {

468

for (FunctionCall call : calls) {

469

String functionName = call.name().orElse("");

470

JsonNode args = call.args().orElse(null);

471

472

if ("get_weather".equals(functionName)) {

473

// Execute function

474

String location = args.get("location").asText();

475

Map<String, Object> result = getWeather(location);

476

477

// Send response back

478

FunctionResponse response = FunctionResponse.builder()

479

.name(functionName)

480

.id(call.id().orElse(""))

481

.response(result)

482

.build();

483

484

LiveSendToolResponseParameters params =

485

LiveSendToolResponseParameters.builder()

486

.functionResponses(List.of(response))

487

.build();

488

489

session.sendToolResponse(params);

490

}

491

}

492

});

493

});

494

});

495

```

496

497

## Closing Sessions

498

499

### Graceful Shutdown

500

501

```java

502

AsyncSession session = /* ... */;

503

504

// Close when done

505

session.close().thenRun(() -> {

506

System.out.println("Session closed successfully");

507

}).exceptionally(error -> {

508

System.err.println("Error closing session: " + error.getMessage());

509

return null;

510

});

511

```

512

513

### Close with try-with-resources Pattern

514

515

Live sessions don't implement AutoCloseable, so manual cleanup is required:

516

517

```java

518

AsyncSession session = null;

519

try {

520

session = client.async.live.connect("gemini-2.0-flash", null).get();

521

522

// Use session...

523

524

} finally {

525

if (session != null) {

526

session.close().get();

527

}

528

}

529

```

530

531

## Error Handling

532

533

### Handle Connection Errors

534

535

```java

536

CompletableFuture<AsyncSession> sessionFuture =

537

client.async.live.connect("gemini-2.0-flash", null);

538

539

sessionFuture

540

.thenAccept(session -> {

541

System.out.println("Connected successfully");

542

})

543

.exceptionally(error -> {

544

System.err.println("Connection failed: " + error.getMessage());

545

if (error instanceof GenAiIOException) {

546

System.err.println("I/O error during connection");

547

}

548

return null;

549

});

550

```

551

552

### Handle Send Failures

553

554

```java

555

session.sendClientContent(params)

556

.thenRun(() -> {

557

System.out.println("Message sent");

558

})

559

.exceptionally(error -> {

560

System.err.println("Failed to send message: " + error.getMessage());

561

// Optionally retry or reconnect

562

return null;

563

});

564

```

565

566

## Best Practices

567

568

### Connection Management

569

570

```java

571

// Keep session alive for multiple interactions

572

AsyncSession session = client.async.live.connect(

573

"gemini-2.0-flash",

574

null

575

).get();

576

577

try {

578

// Use session for multiple messages

579

for (String userInput : userInputs) {

580

LiveSendClientContentParameters params =

581

LiveSendClientContentParameters.builder()

582

.turns(List.of(Content.fromParts(Part.fromText(userInput))))

583

.turnComplete(true)

584

.build();

585

586

session.sendClientContent(params).get();

587

// Process response...

588

}

589

} finally {

590

// Always close when done

591

session.close().get();

592

}

593

```

594

595

### Handle Reconnection

596

597

```java

598

AsyncSession session = null;

599

int maxRetries = 3;

600

int retryCount = 0;

601

602

while (retryCount < maxRetries) {

603

try {

604

session = client.async.live.connect("gemini-2.0-flash", null).get();

605

break; // Success

606

} catch (Exception e) {

607

retryCount++;

608

System.err.println("Connection attempt " + retryCount + " failed");

609

if (retryCount < maxRetries) {

610

Thread.sleep(1000 * retryCount); // Exponential backoff

611

}

612

}

613

}

614

615

if (session == null) {

616

throw new RuntimeException("Failed to connect after " + maxRetries + " attempts");

617

}

618

```

619

620

### Message Synchronization

621

622

Since callbacks are async, use synchronization primitives when needed:

623

624

```java

625

import java.util.concurrent.CountDownLatch;

626

import java.util.concurrent.TimeUnit;

627

628

CountDownLatch responseLatch = new CountDownLatch(1);

629

AtomicReference<String> response = new AtomicReference<>();

630

631

session.receive(message -> {

632

message.serverContent().ifPresent(content -> {

633

if (content.turnComplete().orElse(false)) {

634

content.modelTurn().ifPresent(turn -> {

635

// Collect response

636

response.set(extractText(turn));

637

responseLatch.countDown();

638

});

639

}

640

});

641

});

642

643

// Send message

644

session.sendClientContent(params).get();

645

646

// Wait for response (with timeout)

647

if (responseLatch.await(30, TimeUnit.SECONDS)) {

648

System.out.println("Response: " + response.get());

649

} else {

650

System.err.println("Timeout waiting for response");

651

}

652

```

653

654

## Limitations

655

656

### Experimental Status

657

658

- API is subject to change without notice

659

- May have stability issues

660

- Not recommended for production use

661

662

### WebSocket Constraints

663

664

- Single callback per session (last registered wins)

665

- No automatic reconnection

666

- Manual error handling required

667

- Connection may drop unexpectedly

668

669

### Configuration Limits

670

671

- HttpOptions not supported at request level (use client-level config)

672

- Some GenerateContentConfig options may not be supported

673

- Check documentation for supported config parameters

674

675

## Use Cases

676

677

### Real-time Voice Assistant

678

679

Low-latency audio streaming for voice conversations with minimal delay.

680

681

### Interactive Chatbot

682

683

Streaming text responses for responsive user experiences.

684

685

### Live Translation

686

687

Real-time translation of speech or text with immediate feedback.

688

689

### Collaborative Coding Assistant

690

691

Interactive code completion and explanation with streaming responses.

692

693

### Real-time Content Moderation

694

695

Live analysis of user-generated content with immediate feedback.

696