|
16 | 16 | from types import SimpleNamespace |
17 | 17 |
|
18 | 18 | import pytest |
| 19 | +from google.adk.agents.run_config import RunConfig, StreamingMode |
| 20 | +from google.adk.models.llm_request import LlmRequest |
| 21 | +from google.adk.models.llm_response import LlmResponse |
| 22 | +from google.genai import types |
19 | 23 | from opentelemetry import metrics as metrics_api |
20 | 24 | from opentelemetry.metrics import _internal as metrics_internal |
21 | 25 | from opentelemetry.sdk import metrics as metrics_sdk |
@@ -138,6 +142,79 @@ def test_proxy_instruments_follow_provider_installed_later( |
138 | 142 | ] |
139 | 143 |
|
140 | 144 |
|
| 145 | +@pytest.mark.parametrize( |
| 146 | + "server_address", |
| 147 | + [ |
| 148 | + "https://ark.cn-beijing.volces.com/api/v3/", |
| 149 | + "https://ark.ap-southeast.bytepluses.com/api/v3", |
| 150 | + ], |
| 151 | + ids=["volcengine", "byteplus"], |
| 152 | +) |
| 153 | +@pytest.mark.parametrize("streaming_mode", [StreamingMode.NONE, StreamingMode.SSE]) |
| 154 | +@pytest.mark.parametrize("cached_tokens", [600, 0, None]) |
| 155 | +def test_cache_read_token_metrics_preserve_input_usage( |
| 156 | + fresh_global_meter_provider, server_address, streaming_mode, cached_tokens |
| 157 | +): |
| 158 | + reader = InMemoryMetricReader() |
| 159 | + metrics_api.set_meter_provider(metrics_sdk.MeterProvider(metric_readers=[reader])) |
| 160 | + recorder = PortalMetricRecorder(name="test-cache-read") |
| 161 | + context = SimpleNamespace( |
| 162 | + agent=SimpleNamespace(model_api_base=server_address), |
| 163 | + run_config=RunConfig(streaming_mode=streaming_mode), |
| 164 | + ) |
| 165 | + request = LlmRequest(model="test-model") |
| 166 | + |
| 167 | + if streaming_mode == StreamingMode.SSE: |
| 168 | + recorder.record_call_llm(context, "partial", request, LlmResponse(partial=True)) |
| 169 | + |
| 170 | + recorder.record_call_llm( |
| 171 | + context, |
| 172 | + "final", |
| 173 | + request, |
| 174 | + LlmResponse( |
| 175 | + usage_metadata=types.GenerateContentResponseUsageMetadata( |
| 176 | + prompt_token_count=1000, |
| 177 | + candidates_token_count=200, |
| 178 | + total_token_count=1200, |
| 179 | + cached_content_token_count=cached_tokens, |
| 180 | + ), |
| 181 | + ), |
| 182 | + ) |
| 183 | + |
| 184 | + metrics_data = reader.get_metrics_data() |
| 185 | + recorded_metrics = { |
| 186 | + metric.name: list(metric.data.data_points) |
| 187 | + for resource_metrics in metrics_data.resource_metrics |
| 188 | + for scope_metrics in resource_metrics.scope_metrics |
| 189 | + for metric in scope_metrics.metrics |
| 190 | + } |
| 191 | + points = recorded_metrics["gen_ai.client.token.usage"] |
| 192 | + expected = {"input": 1000, "output": 200} |
| 193 | + if cached_tokens is not None: |
| 194 | + expected["cache_read"] = cached_tokens |
| 195 | + assert {point.attributes["gen_ai_token_type"]: point.sum for point in points} == ( |
| 196 | + expected |
| 197 | + ) |
| 198 | + assert len(points) == len(expected) |
| 199 | + for point in points: |
| 200 | + assert point.count == 1 |
| 201 | + assert point.attributes["server_address"] == server_address |
| 202 | + assert point.attributes["stream"] == (streaming_mode == StreamingMode.SSE) |
| 203 | + assert point.attributes["gen_ai_response_model"] == "test-model" |
| 204 | + assert [point.value for point in recorded_metrics["gen_ai.chat.count"]] == [1] |
| 205 | + |
| 206 | + |
| 207 | +def test_missing_usage_does_not_record_token_metrics(fresh_global_meter_provider): |
| 208 | + reader = InMemoryMetricReader() |
| 209 | + metrics_api.set_meter_provider(metrics_sdk.MeterProvider(metric_readers=[reader])) |
| 210 | + recorder = PortalMetricRecorder(name="test-missing-usage") |
| 211 | + context = SimpleNamespace(agent=SimpleNamespace(), run_config=None) |
| 212 | + |
| 213 | + recorder.record_call_llm(context, "event", LlmRequest(), LlmResponse()) |
| 214 | + |
| 215 | + assert reader.get_metrics_data() is None |
| 216 | + |
| 217 | + |
141 | 218 | def test_apmplus_reuses_preconfigured_global_provider( |
142 | 219 | fresh_global_meter_provider, |
143 | 220 | monkeypatch, |
|
0 commit comments