@@ -50,6 +50,33 @@ def square_integer(given_integer: int) -> int:
5050 return given_integer * given_integer
5151
5252
53+ def power_disco_ball (power : bool ) -> bool :
54+ """Powers the spinning disco ball."""
55+ print (f"Disco ball is { 'spinning!' if power else 'stopped.' } " )
56+ return True
57+
58+ def start_music (energetic : bool , loud : bool , bpm : int ) -> str :
59+ """Play some music matching the specified parameters.
60+
61+ Args:
62+ energetic: Whether the music is energetic or not.
63+ loud: Whether the music is loud or not.
64+ bpm: The beats per minute of the music.
65+
66+ Returns: The name of the song being played.
67+ """
68+ print (f"Starting music! { energetic = } { loud = } , { bpm = } " )
69+ return "Never gonna give you up."
70+
71+ def dim_lights (brightness : float ) -> bool :
72+ """Dim the lights.
73+
74+ Args:
75+ brightness: The brightness of the lights, 0.0 is off, 1.0 is full.
76+ """
77+ print (f"Lights are now set to { brightness :.0%} " )
78+ return True
79+
5380def test_text (client ):
5481 chat = client .chats .create (model = 'gemini-1.5-flash' )
5582 chat .send_message (
@@ -165,6 +192,100 @@ def test_with_afc_history(client):
165192 assert '51' in chat_history [3 ].parts [0 ].text
166193
167194
195+ def test_with_afc_multiple_remote_calls (client ):
196+
197+ house_fns = [power_disco_ball , start_music , dim_lights ]
198+ config = {
199+ 'tools' : house_fns ,
200+ # Force the model to act (call 'any' function), instead of chatting.
201+ 'tool_config' : {
202+ 'function_calling_config' : {
203+ 'mode' : 'ANY' ,
204+ }
205+ },
206+ 'automatic_function_calling' : {
207+ 'maximum_remote_calls' : 3 ,
208+ }
209+ }
210+ chat = client .chats .create (model = 'gemini-1.5-flash' , config = config )
211+ chat .send_message ('Turn this place into a party!' )
212+ curated_history = chat ._curated_history
213+
214+ assert len (curated_history ) == 8
215+ assert curated_history [0 ].role == 'user'
216+ assert curated_history [0 ].parts [0 ].text == 'Turn this place into a party!'
217+ assert curated_history [1 ].role == 'model'
218+ assert len (curated_history [1 ].parts ) == 3
219+ for part in curated_history [1 ].parts :
220+ assert part .function_call
221+ assert curated_history [2 ].role == 'user'
222+ assert len (curated_history [2 ].parts ) == 3
223+ for part in curated_history [2 ].parts :
224+ assert part .function_response
225+ assert curated_history [3 ].role == 'model'
226+ assert len (curated_history [3 ].parts ) == 1
227+ assert curated_history [3 ].parts [0 ].function_call
228+ assert curated_history [4 ].role == 'user'
229+ assert len (curated_history [4 ].parts ) == 1
230+ assert curated_history [4 ].parts [0 ].function_response
231+ assert curated_history [5 ].role == 'model'
232+ assert len (curated_history [5 ].parts ) == 1
233+ assert curated_history [5 ].parts [0 ].function_call
234+ assert curated_history [6 ].role == 'user'
235+ assert len (curated_history [6 ].parts ) == 1
236+ assert curated_history [6 ].parts [0 ].function_response
237+ assert curated_history [7 ].role == 'model'
238+ assert len (curated_history [7 ].parts ) == 1
239+ assert curated_history [7 ].parts [0 ].function_call
240+
241+
242+ def test_with_afc_multiple_remote_calls_async (client ):
243+
244+ house_fns = [power_disco_ball , start_music , dim_lights ]
245+ config = {
246+ 'tools' : house_fns ,
247+ # Force the model to act (call 'any' function), instead of chatting.
248+ 'tool_config' : {
249+ 'function_calling_config' : {
250+ 'mode' : 'ANY' ,
251+ }
252+ },
253+ 'automatic_function_calling' : {
254+ 'maximum_remote_calls' : 3 ,
255+ }
256+ }
257+ chat = client .chats .create (model = 'gemini-1.5-flash' , config = config )
258+ chat .send_message ('Turn this place into a party!' )
259+ curated_history = chat ._curated_history
260+
261+ assert len (curated_history ) == 8
262+ assert curated_history [0 ].role == 'user'
263+ assert curated_history [0 ].parts [0 ].text == 'Turn this place into a party!'
264+ assert curated_history [1 ].role == 'model'
265+ assert len (curated_history [1 ].parts ) == 3
266+ for part in curated_history [1 ].parts :
267+ assert part .function_call
268+ assert curated_history [2 ].role == 'user'
269+ assert len (curated_history [2 ].parts ) == 3
270+ for part in curated_history [2 ].parts :
271+ assert part .function_response
272+ assert curated_history [3 ].role == 'model'
273+ assert len (curated_history [3 ].parts ) == 1
274+ assert curated_history [3 ].parts [0 ].function_call
275+ assert curated_history [4 ].role == 'user'
276+ assert len (curated_history [4 ].parts ) == 1
277+ assert curated_history [4 ].parts [0 ].function_response
278+ assert curated_history [5 ].role == 'model'
279+ assert len (curated_history [5 ].parts ) == 1
280+ assert curated_history [5 ].parts [0 ].function_call
281+ assert curated_history [6 ].role == 'user'
282+ assert len (curated_history [6 ].parts ) == 1
283+ assert curated_history [6 ].parts [0 ].function_response
284+ assert curated_history [7 ].role == 'model'
285+ assert len (curated_history [7 ].parts ) == 1
286+ assert curated_history [7 ].parts [0 ].function_call
287+
288+
168289def test_with_afc_disabled (client ):
169290 chat = client .chats .create (
170291 model = 'gemini-1.5-flash' ,
0 commit comments