Skip to content

Commit add107b

Browse files
committed
Merge remote-tracking branch 'origin/main' into fix-thought-signature-pruning
2 parents 0e510e3 + e6df097 commit add107b

4 files changed

Lines changed: 59 additions & 52 deletions

File tree

src/google/adk/integrations/agent_identity/_iam_connector_credentials_provider.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ async def get_auth_credential(
238238
logger.debug("Auth credential obtained immediately.")
239239
return _construct_auth_credential(response)
240240

241-
if metadata and metadata.consent_pending:
241+
if metadata is not None and "consent_pending" in metadata:
242242
# Get 2-legged OAuth token. Allow enough time for token exchange.
243243
try:
244244
operation = await self._poll_credentials(

src/google/adk/telemetry/google_cloud.py

Lines changed: 18 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ def get_gcp_exporters(
119119
if enable_cloud_logging:
120120
exporter = _get_gcp_logs_exporter(
121121
project_id=project_id,
122-
credentials=credentials,
123122
)
124123
if exporter:
125124
log_record_processors.append(exporter)
@@ -187,11 +186,9 @@ def _get_gcp_metrics_exporter(project_id: str) -> MetricReader:
187186

188187
def _get_gcp_logs_exporter(
189188
project_id: str,
190-
credentials: Optional["Credentials"] = None,
191189
) -> LogRecordProcessor:
192190
if os.getenv("GOOGLE_CLOUD_AGENT_ENGINE_ID"):
193191
return _get_agent_engine_logs_exporter(
194-
credentials=credentials,
195192
project_id=project_id,
196193
)
197194

@@ -338,18 +335,14 @@ def _use_client_cert_effective() -> bool:
338335

339336
def _get_agent_engine_logs_exporter(
340337
*,
341-
credentials: "Credentials",
342338
project_id: str,
343339
):
344340
"""Configures logging for Agent Engine.
345341
346342
Args:
347-
credentials: Credentials to use for export calls.
348343
project_id: Project to which to write logs.
349344
"""
350345
try:
351-
from google.cloud.logging_v2.services import logging_service_v2
352-
from google.cloud.logging_v2.services.logging_service_v2.transports import grpc
353346
from opentelemetry.exporter import cloud_logging
354347
except (ImportError, AttributeError):
355348
logger.warning(
@@ -363,46 +356,21 @@ def _get_agent_engine_logs_exporter(
363356
)
364357
return
365358

366-
if "gen_ai_latest_experimental" in os.getenv(
367-
"OTEL_SEMCONV_STABILITY_OPT_IN", ""
368-
).split(","):
369-
# Specify credentials to avoid expensive call to `google.auth.default()`
370-
channel = grpc.LoggingServiceV2GrpcTransport.create_channel(
371-
credentials=credentials,
372-
# pylint: disable-next=protected-access
373-
options=cloud_logging._OPTIONS,
374-
)
375-
return BatchLogRecordProcessor(
376-
cloud_logging.CloudLoggingExporter(
377-
client=logging_service_v2.LoggingServiceV2Client(
378-
transport=grpc.LoggingServiceV2GrpcTransport(
379-
credentials=credentials,
380-
channel=channel,
381-
),
382-
),
383-
project_id=project_id,
384-
default_log_name=os.getenv(
385-
"GCP_DEFAULT_LOG_NAME", "adk-on-agent-engine"
386-
),
387-
),
388-
)
389-
else:
390-
391-
class _SimpleLogRecordProcessor(SimpleLogRecordProcessor):
392-
393-
def force_flush(
394-
self, timeout_millis: int = 30000
395-
) -> bool: # pylint: disable=no-self-use
396-
_ = sys.stdout.flush()
397-
_ = sys.stderr.flush()
398-
return super().force_flush()
399-
400-
return _SimpleLogRecordProcessor(
401-
cloud_logging.CloudLoggingExporter(
402-
project_id=project_id,
403-
default_log_name=os.getenv(
404-
"GCP_DEFAULT_LOG_NAME", "adk-on-agent-engine"
405-
),
406-
structured_json_file=sys.stdout,
407-
),
408-
)
359+
class _SimpleLogRecordProcessor(SimpleLogRecordProcessor):
360+
361+
def force_flush(
362+
self, timeout_millis: int = 30000
363+
) -> bool: # pylint: disable=no-self-use
364+
_ = sys.stdout.flush()
365+
_ = sys.stderr.flush()
366+
return super().force_flush()
367+
368+
return _SimpleLogRecordProcessor(
369+
cloud_logging.CloudLoggingExporter(
370+
project_id=project_id,
371+
default_log_name=os.getenv(
372+
"GCP_DEFAULT_LOG_NAME", "adk-on-agent-engine"
373+
),
374+
structured_json_file=sys.stdout,
375+
),
376+
)

tests/unittests/integrations/agent_identity/test_iam_connector_credentials_provider.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,3 +469,42 @@ async def test_get_auth_credential_raises_error_if_consent_canceled(
469469
RuntimeError, match="Failed to retrieve consent based credential."
470470
):
471471
await provider.get_auth_credential(auth_scheme, context)
472+
473+
474+
async def test_get_auth_credential_handles_consent_pending_state_correctly(
475+
mock_client,
476+
auth_scheme,
477+
context,
478+
provider,
479+
):
480+
"""Test get_auth_credential enters the polling loop when consent is pending."""
481+
# 1. Setup the first retrieve_credentials call to return a pending Operation
482+
# containing consent_pending metadata.
483+
meta_pb = RetrieveCredentialsMetadata.pb()()
484+
meta_pb.consent_pending.SetInParent()
485+
486+
op_pending = Operation(done=False)
487+
op_pending.metadata.value = meta_pb.SerializeToString()
488+
489+
# 2. Setup the second retrieve_credentials call (the poll) to return success.
490+
op_success = Operation(done=True)
491+
resp = RetrieveCredentialsResponse(
492+
header="Authorization: Bearer", token="valid-token"
493+
)
494+
op_success.response.value = RetrieveCredentialsResponse.serialize(resp)
495+
496+
# Configure mock client to return pending first, then success
497+
mock_client.retrieve_credentials.side_effect = [
498+
Mock(operation=op_pending),
499+
Mock(operation=op_success),
500+
]
501+
502+
# 3. Call the provider
503+
credential = await provider.get_auth_credential(auth_scheme, context)
504+
505+
# 4. Verify that it polled and successfully returned the token
506+
assert credential is not None
507+
assert credential.http.credentials.token == "valid-token"
508+
509+
# Verify that retrieve_credentials was called twice (initial + 1 poll)
510+
assert mock_client.retrieve_credentials.call_count == 2

tests/unittests/telemetry/test_google_cloud.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def test_get_gcp_exporters(
6262
)
6363
monkeypatch.setattr(
6464
"google.adk.telemetry.google_cloud._get_gcp_logs_exporter",
65-
lambda project_id, credentials: mock.MagicMock(),
65+
lambda project_id: mock.MagicMock(),
6666
)
6767

6868
# Act.

0 commit comments

Comments
 (0)