@@ -326,4 +326,120 @@ class Snippets {
326
326
// [END set_safety_settings]
327
327
}
328
328
329
+ func functionCalling( ) async throws {
330
+ // [START create_function]
331
+ func makeAPIRequest( currencyDate: String , currencyFrom: String ,
332
+ currencyTo: String ) -> JSONObject {
333
+ // This hypothetical API returns a JSON such as:
334
+ // {"base":"USD","date":"2024-04-17","rates":{"SEK": 0.091}}
335
+ return [
336
+ " date " : . string( currencyDate) ,
337
+ " base " : . string( currencyFrom) ,
338
+ " rates " : . object( [ currencyTo: . number( 0.091 ) ] ) ,
339
+ ]
340
+ }
341
+ // [END create_function]
342
+
343
+ // [START create_function_metadata]
344
+ let getExchangeRate = FunctionDeclaration (
345
+ name: " getExchangeRate " ,
346
+ description: " Get the exchange rate for currencies between countries " ,
347
+ parameters: [
348
+ " currencyDate " : Schema (
349
+ type: . string,
350
+ description: " A date that must always be in YYYY-MM-DD format or the value 'latest' if a time period is not specified "
351
+ ) ,
352
+ " currencyFrom " : Schema (
353
+ type: . string,
354
+ description: " The currency to convert from. "
355
+ ) ,
356
+ " currencyTo " : Schema (
357
+ type: . string,
358
+ description: " The currency to convert to. "
359
+ ) ,
360
+ ] ,
361
+ requiredParameters: nil
362
+ )
363
+
364
+ // [END create_function_metadata]
365
+
366
+ // [START initialize_model_function]
367
+ // Specify the function declaration.
368
+ let function = Tool ( functionDeclarations: [ getExchangeRate] )
369
+
370
+ // Use a model that supports function calling, like Gemini 1.0 Pro.
371
+ // See "Supported models" in the "Introduction to function calling" page.
372
+ let generativeModel = VertexAI . vertexAI ( ) . generativeModel ( modelName: " gemini-1.0-pro " ,
373
+ tools: [ function] )
374
+ // [END initialize_model_function]
375
+
376
+ // [START generate_function_call]
377
+ let chat = generativeModel. startChat ( )
378
+
379
+ let prompt = " How much is 50 US dollars worth in Swedish krona? "
380
+
381
+ // Send the message to the generative model
382
+ let response1 = try await chat. sendMessage ( prompt)
383
+
384
+ // Check if the model responded with a function call
385
+ guard let functionCall = response1. functionCalls. first else {
386
+ fatalError ( " Model did not respond with a function call. " )
387
+ }
388
+ // Print an error if the returned function was not declared
389
+ guard functionCall. name == " getExchangeRate " else {
390
+ fatalError ( " Unexpected function called: \( functionCall. name) " )
391
+ }
392
+ // Verify that the names and types of the parameters match the declaration
393
+ guard case let . string( currencyDate) = functionCall. args [ " currencyDate " ] else {
394
+ fatalError ( " Missing argument: currencyDate " )
395
+ }
396
+ guard case let . string( currencyFrom) = functionCall. args [ " currencyFrom " ] else {
397
+ fatalError ( " Missing argument: currencyFrom " )
398
+ }
399
+ guard case let . string( currencyTo) = functionCall. args [ " currencyTo " ] else {
400
+ fatalError ( " Missing argument: currencyTo " )
401
+ }
402
+
403
+ // Call the hypothetical API
404
+ let apiResponse = makeAPIRequest (
405
+ currencyDate: currencyDate,
406
+ currencyFrom: currencyFrom,
407
+ currencyTo: currencyTo
408
+ )
409
+
410
+ // Send the API response back to the model so it can generate a text response that can be
411
+ // displayed to the user.
412
+ let response2 = try await chat. sendMessage ( [ ModelContent (
413
+ role: " function " ,
414
+ parts: [ . functionResponse( FunctionResponse (
415
+ name: functionCall. name,
416
+ response: apiResponse
417
+ ) ) ]
418
+ ) ] )
419
+
420
+ // Log the text response.
421
+ guard let modelResponse = response2. text else {
422
+ fatalError ( " Model did not respond with text. " )
423
+ }
424
+ print ( modelResponse)
425
+ // [END generate_function_call]
426
+
427
+ // [START function_modes]
428
+ let model = VertexAI . vertexAI ( ) . generativeModel (
429
+ // Setting a function calling mode is only available in Gemini 1.5 Pro
430
+ modelName: " gemini-1.5-pro-latest " ,
431
+ // Pass the function declaration
432
+ tools: [ Tool ( functionDeclarations: [ getExchangeRate] ) ] ,
433
+ toolConfig: ToolConfig (
434
+ functionCallingConfig: FunctionCallingConfig (
435
+ // Only call functions (model won't generate text)
436
+ mode: FunctionCallingConfig . Mode. any,
437
+ // This should only be set when the Mode is .any.
438
+ allowedFunctionNames: [ " getExchangeRate " ]
439
+ )
440
+ )
441
+ )
442
+ // [END function_modes]
443
+ }
444
+
329
445
}
0 commit comments