@@ -231,6 +231,128 @@ struct GenerateContentIntegrationTests {
231
231
) )
232
232
}
233
233
234
+ @Test (
235
+ arguments: [
236
+ ( . vertexAI_v1beta_global, ModelNames . gemini2_5_Flash, ThinkingConfig ( thinkingBudget: 0 ) ) ,
237
+ ( . vertexAI_v1beta_global, ModelNames . gemini2_5_Flash, ThinkingConfig ( thinkingBudget: 24576 ) ) ,
238
+ ( . vertexAI_v1beta_global, ModelNames . gemini2_5_Flash, ThinkingConfig (
239
+ thinkingBudget: 24576 , includeThoughts: true
240
+ ) ) ,
241
+ ( . vertexAI_v1beta_global, ModelNames . gemini2_5_Pro, ThinkingConfig ( thinkingBudget: 128 ) ) ,
242
+ ( . vertexAI_v1beta_global, ModelNames . gemini2_5_Pro, ThinkingConfig ( thinkingBudget: 32768 ) ) ,
243
+ ( . vertexAI_v1beta_global, ModelNames . gemini2_5_Pro, ThinkingConfig (
244
+ thinkingBudget: 32768 , includeThoughts: true
245
+ ) ) ,
246
+ ( . googleAI_v1beta, ModelNames . gemini2_5_Flash, ThinkingConfig ( thinkingBudget: 0 ) ) ,
247
+ ( . googleAI_v1beta, ModelNames . gemini2_5_Flash, ThinkingConfig ( thinkingBudget: 24576 ) ) ,
248
+ ( . googleAI_v1beta, ModelNames . gemini2_5_Flash, ThinkingConfig (
249
+ thinkingBudget: 24576 , includeThoughts: true
250
+ ) ) ,
251
+ ( . googleAI_v1beta, ModelNames . gemini2_5_Pro, ThinkingConfig ( thinkingBudget: 128 ) ) ,
252
+ ( . googleAI_v1beta, ModelNames . gemini2_5_Pro, ThinkingConfig ( thinkingBudget: 32768 ) ) ,
253
+ ( . googleAI_v1beta, ModelNames . gemini2_5_Pro, ThinkingConfig (
254
+ thinkingBudget: 32768 , includeThoughts: true
255
+ ) ) ,
256
+ ] as [ ( InstanceConfig , String , ThinkingConfig ) ]
257
+ )
258
+ func generateContentThinkingFunctionCalling( _ config: InstanceConfig , modelName: String ,
259
+ thinkingConfig: ThinkingConfig ) async throws {
260
+ let currentLocationDeclaration = FunctionDeclaration (
261
+ name: " currentLocation " ,
262
+ description: " Returns the user's current city, province or state, and country " ,
263
+ parameters: [ : ]
264
+ )
265
+ let getTemperatureDeclaration = FunctionDeclaration (
266
+ name: " getTemperature " ,
267
+ description: " Returns the current temperature in Celsius for the specified location " ,
268
+ parameters: [
269
+ " city " : . string( ) ,
270
+ " region " : . string( description: " The province or state " ) ,
271
+ " country " : . string( ) ,
272
+ ]
273
+ )
274
+ let model = FirebaseAI . componentInstance ( config) . generativeModel (
275
+ modelName: modelName,
276
+ generationConfig: GenerationConfig (
277
+ temperature: 0.0 ,
278
+ topP: 0.0 ,
279
+ topK: 1 ,
280
+ thinkingConfig: thinkingConfig
281
+ ) ,
282
+ safetySettings: safetySettings,
283
+ tools: [ . functionDeclarations( [ currentLocationDeclaration, getTemperatureDeclaration] ) ]
284
+ )
285
+ let chat = model. startChat ( )
286
+ let prompt = """
287
+ What is the temperature outside right now? Respond in the format:
288
+ - Location: City, Province/State, Country
289
+ - Temperature: #C
290
+
291
+ Example Output:
292
+ - Location: Vancouver, British Columbia, Canada
293
+ - Temperature: 15C
294
+ """
295
+
296
+ let response = try await chat. sendMessage ( prompt)
297
+
298
+ var thoughtSignatureCount = 0
299
+ #expect( response. functionCalls. count == 1 )
300
+ let locationFunctionCall = try #require( response. functionCalls. first)
301
+ try #require( locationFunctionCall. name == currentLocationDeclaration. name)
302
+ #expect( locationFunctionCall. args. isEmpty)
303
+ #expect( locationFunctionCall. isThought == false )
304
+ if locationFunctionCall. thoughtSignature != nil {
305
+ thoughtSignatureCount += 1
306
+ }
307
+
308
+ let locationFunctionResponse = FunctionResponsePart (
309
+ name: locationFunctionCall. name,
310
+ response: [
311
+ " city " : . string( " Waterloo " ) ,
312
+ " province " : . string( " Ontario " ) ,
313
+ " country " : . string( " Canada " ) ,
314
+ ]
315
+ )
316
+
317
+ let response2 = try await chat. sendMessage ( locationFunctionResponse)
318
+
319
+ #expect( response2. functionCalls. count == 1 )
320
+ let temperatureFunctionCall = try #require( response2. functionCalls. first)
321
+ try #require( temperatureFunctionCall. name == getTemperatureDeclaration. name)
322
+ #expect( temperatureFunctionCall. args == [
323
+ " city " : . string( " Waterloo " ) ,
324
+ " region " : . string( " Ontario " ) ,
325
+ " country " : . string( " Canada " ) ,
326
+ ] )
327
+ #expect( temperatureFunctionCall. isThought == false )
328
+ if temperatureFunctionCall. thoughtSignature != nil {
329
+ thoughtSignatureCount += 1
330
+ }
331
+
332
+ let temperatureFunctionResponse = FunctionResponsePart (
333
+ name: locationFunctionCall. name,
334
+ response: [
335
+ " temperature " : . number( 25 ) ,
336
+ " units " : . string( " Celsius " ) ,
337
+ ]
338
+ )
339
+
340
+ let response3 = try await chat. sendMessage ( temperatureFunctionResponse)
341
+
342
+ #expect( response3. functionCalls. isEmpty)
343
+ let finalText = try #require( response3. text) . trimmingCharacters ( in: . whitespacesAndNewlines)
344
+ #expect( finalText == """
345
+ - Location: Waterloo, Ontario, Canada
346
+ - Temperature: 25C
347
+ """ )
348
+
349
+ if let _ = thinkingConfig. includeThoughts, case . googleAI = config. apiConfig. service {
350
+ #expect( thoughtSignatureCount > 0 )
351
+ } else {
352
+ #expect( thoughtSignatureCount == 0 )
353
+ }
354
+ }
355
+
234
356
@Test ( arguments: [
235
357
InstanceConfig . vertexAI_v1beta,
236
358
InstanceConfig . vertexAI_v1beta_global,
0 commit comments