@@ -1019,24 +1019,34 @@ def _agent_resource_to_agent_info(
10191019 ["completed" , "failed" , "cancelled" , "incomplete" , "budget_exceeded" ]
10201020)
10211021
1022+ _INITIAL_POLL_INTERVAL_SECONDS = 2.0
1023+ _MAX_POLL_INTERVAL_SECONDS = 30.0
1024+ _POLL_BACKOFF_MULTIPLIER = 2.0
1025+
10221026
10231027def _await_interaction (
10241028 interactions_client : "_InteractionsRestClient" ,
10251029 interaction : dict [str , Any ],
1026- poll_interval_seconds : float = 2.0 ,
1030+ initial_poll_interval_seconds : float = _INITIAL_POLL_INTERVAL_SECONDS ,
1031+ max_poll_interval_seconds : float = _MAX_POLL_INTERVAL_SECONDS ,
1032+ poll_backoff_multiplier : float = _POLL_BACKOFF_MULTIPLIER ,
10271033 timeout_seconds : float = 600.0 ,
10281034) -> dict [str , Any ]:
10291035 """Polls a background interaction until it reaches a terminal state.
10301036
10311037 Gemini agent interactions must run in the background (`background=True`), so
10321038 `create` returns before the model output is ready. This polls
10331039 `interactions.get` until the interaction reaches a terminal state and then
1034- returns the resolved interaction.
1040+ returns the resolved interaction. The delay between polls grows
1041+ exponentially (capped at `max_poll_interval_seconds`) to avoid hitting rate
1042+ limits when evaluating large datasets.
10351043
10361044 Args:
10371045 interactions_client: The interactions client used to poll.
10381046 interaction: The interaction returned by `create`.
1039- poll_interval_seconds: Delay between poll attempts.
1047+ initial_poll_interval_seconds: Delay before the first poll.
1048+ max_poll_interval_seconds: Upper bound for the poll interval.
1049+ poll_backoff_multiplier: Factor the interval grows by after each poll.
10401050 timeout_seconds: Maximum time to wait before raising.
10411051
10421052 Returns:
@@ -1049,11 +1059,18 @@ def _await_interaction(
10491059 return interaction
10501060 interaction_id = interaction .get ("id" )
10511061 deadline = time .monotonic () + timeout_seconds
1052- while time .monotonic () < deadline :
1053- time .sleep (poll_interval_seconds )
1062+ poll_interval = initial_poll_interval_seconds
1063+ while True :
1064+ remaining = deadline - time .monotonic ()
1065+ if remaining <= 0 :
1066+ break
1067+ time .sleep (min (poll_interval , remaining ))
10541068 interaction = interactions_client .get (interaction_id )
10551069 if interaction .get ("status" ) in _INTERACTION_TERMINAL_STATES :
10561070 return interaction
1071+ poll_interval = min (
1072+ poll_interval * poll_backoff_multiplier , max_poll_interval_seconds
1073+ )
10571074 raise TimeoutError (
10581075 f"Interaction { interaction_id } did not complete within"
10591076 f" { timeout_seconds } seconds."
0 commit comments