1212# See the License for the specific language governing permissions and
1313# limitations under the License.
1414
15- from typing import Any , Awaitable , Callable , Dict , Optional
15+ from typing import Any , Awaitable , Callable , Dict , Optional , cast
1616
1717import toolbox_core
1818from fastapi .openapi .models import (
@@ -127,21 +127,23 @@ async def run_async(
127127 oauth2 = OAuth2Auth (
128128 client_id = self ._auth_config .client_id ,
129129 client_secret = self ._auth_config .client_secret ,
130- scopes = scopes ,
131130 ),
132131 ),
133132 )
134133
135134 # Check if we already have credentials from a previous exchange
136135 try :
137136 # get_auth_response returns AuthCredential if found
138- creds = tool_context .get_auth_response (auth_config_adk )
137+ # Cast to Any because ReadonlyContext definition might be missing these methods in stubs
138+ # but valid at runtime for strict ADK compliance.
139+ ctx_any = cast (Any , tool_context )
140+ creds = ctx_any .get_auth_response (auth_config_adk )
139141 if creds and creds .oauth2 and creds .oauth2 .access_token :
140142 reset_token = USER_TOKEN_CONTEXT_VAR .set (creds .oauth2 .access_token )
141143 else :
142144 # Request credentials. This will signal the runner to pause.
143145 # We return None (or raise) to stop current execution.
144- tool_context .request_credential (auth_config_adk )
146+ ctx_any .request_credential (auth_config_adk )
145147 # Returning None here. The ADK runner will see the requested_auth_configs
146148 # in the tool_context/event and trigger the client event.
147149 return None
@@ -158,7 +160,8 @@ async def run_async(
158160 ): # Loose check, but safest is to re-raise
159161 raise e
160162 # Fallback to request logic if it was a lookup error?
161- tool_context .request_credential (auth_config_adk )
163+ ctx_any = cast (Any , tool_context )
164+ ctx_any .request_credential (auth_config_adk )
162165 return None
163166
164167 try :
0 commit comments