|
9 | 9 | import com.azure.ai.voicelive.models.AudioNoiseReduction; |
10 | 10 | import com.azure.ai.voicelive.models.AudioNoiseReductionType; |
11 | 11 | import com.azure.ai.voicelive.models.AzureCustomVoice; |
| 12 | +import com.azure.ai.voicelive.models.ClientEventConversationItemCreate; |
| 13 | +import com.azure.ai.voicelive.models.ClientEventResponseCreate; |
| 14 | +import com.azure.ai.voicelive.models.FunctionCallOutputItem; |
| 15 | +import com.azure.ai.voicelive.models.ItemType; |
| 16 | +import com.azure.ai.voicelive.models.ResponseFunctionCallItem; |
| 17 | +import com.azure.ai.voicelive.models.SessionUpdateConversationItemCreated; |
| 18 | +import com.azure.ai.voicelive.models.VoiceLiveFunctionDefinition; |
12 | 19 | import com.azure.ai.voicelive.models.AzurePersonalVoice; |
13 | 20 | import com.azure.ai.voicelive.models.AzureStandardVoice; |
14 | 21 | import com.azure.ai.voicelive.models.ClientEventSessionUpdate; |
|
30 | 37 | import com.azure.core.util.BinaryData; |
31 | 38 | import com.azure.identity.AzureCliCredentialBuilder; |
32 | 39 | import com.azure.identity.DefaultAzureCredentialBuilder; |
| 40 | +import com.fasterxml.jackson.databind.ObjectMapper; |
33 | 41 | import reactor.core.publisher.Mono; |
34 | 42 |
|
35 | 43 | import java.io.IOException; |
| 44 | +import java.util.HashMap; |
| 45 | +import java.util.Map; |
36 | 46 | import java.nio.file.Files; |
37 | 47 | import java.nio.file.Path; |
38 | 48 | import java.nio.file.Paths; |
@@ -332,7 +342,77 @@ public void voiceConfigurationAzure() { |
332 | 342 | // END: com.azure.ai.voicelive.voice.azure |
333 | 343 | } |
334 | 344 |
|
| 345 | + /** |
| 346 | + * Sample for function calling |
| 347 | + */ |
| 348 | + public void functionCalling() { |
| 349 | + VoiceLiveAsyncClient client = new VoiceLiveClientBuilder() |
| 350 | + .endpoint(endpoint) |
| 351 | + .credential(new AzureKeyCredential(apiKey)) |
| 352 | + .buildAsyncClient(); |
| 353 | + |
| 354 | + // BEGIN: com.azure.ai.voicelive.functioncalling |
| 355 | + // 1. Define function tool with parameters |
| 356 | + VoiceLiveFunctionDefinition getWeatherFunction = new VoiceLiveFunctionDefinition("get_current_weather") |
| 357 | + .setDescription("Get the current weather in a given location") |
| 358 | + .setParameters(BinaryData.fromObject(parametersSchema)); // JSON schema |
| 359 | + |
| 360 | + // 2. Configure session with tools |
| 361 | + VoiceLiveSessionOptions options = new VoiceLiveSessionOptions() |
| 362 | + .setTools(Arrays.asList(getWeatherFunction)) |
| 363 | + .setInstructions("You have access to weather information. Use get_current_weather when asked about weather."); |
| 364 | + |
| 365 | + // 3. Handle function call events |
| 366 | + client.startSession("gpt-4o-realtime-preview") |
| 367 | + .flatMap(session -> { |
| 368 | + session.receiveEvents() |
| 369 | + .subscribe(event -> { |
| 370 | + if (event instanceof SessionUpdateConversationItemCreated) { |
| 371 | + SessionUpdateConversationItemCreated itemCreated = (SessionUpdateConversationItemCreated) event; |
| 372 | + if (itemCreated.getItem().getType() == ItemType.FUNCTION_CALL) { |
| 373 | + ResponseFunctionCallItem functionCall = (ResponseFunctionCallItem) itemCreated.getItem(); |
| 374 | + |
| 375 | + // Wait for arguments |
| 376 | + String callId = functionCall.getCallId(); |
| 377 | + String arguments = waitForArguments(session, callId); // Helper method |
| 378 | + |
| 379 | + // Execute function |
| 380 | + try { |
| 381 | + Map<String, Object> result = getCurrentWeather(arguments); |
| 382 | + String resultJson = new ObjectMapper().writeValueAsString(result); |
| 383 | + |
| 384 | + // Return result |
| 385 | + FunctionCallOutputItem output = new FunctionCallOutputItem(callId, resultJson); |
| 386 | + ClientEventConversationItemCreate createItem = new ClientEventConversationItemCreate() |
| 387 | + .setItem(output) |
| 388 | + .setPreviousItemId(functionCall.getId()); |
| 389 | + |
| 390 | + session.sendEvent(createItem).subscribe(); |
| 391 | + session.sendEvent(new ClientEventResponseCreate()).subscribe(); |
| 392 | + } catch (Exception e) { |
| 393 | + System.err.println("Error executing function: " + e.getMessage()); |
| 394 | + } |
| 395 | + } |
| 396 | + } |
| 397 | + }); |
| 398 | + |
| 399 | + return Mono.just(session); |
| 400 | + }) |
| 401 | + .block(); |
| 402 | + // END: com.azure.ai.voicelive.functioncalling |
| 403 | + } |
| 404 | + |
335 | 405 | // Helper methods |
| 406 | + private Object parametersSchema = new Object(); |
| 407 | + |
| 408 | + private String waitForArguments(VoiceLiveSessionAsyncClient session, String callId) { |
| 409 | + return "{}"; |
| 410 | + } |
| 411 | + |
| 412 | + private Map<String, Object> getCurrentWeather(String arguments) { |
| 413 | + return new HashMap<>(); |
| 414 | + } |
| 415 | + |
336 | 416 | private byte[] readAudioChunk() { |
337 | 417 | return new byte[0]; |
338 | 418 | } |
|
0 commit comments