mirror of
https://github.com/BerriAI/litellm.git
synced 2026-08-28 05:25:59 +00:00
Merge pull request #36397 from ousamabenyounes/litellm_fix_gemini_web_search_unique_queries_36377
fix(vertex_ai): bill Gemini grounding per unique web search query
This commit is contained in:
commit
855a8bc764
2 changed files with 32 additions and 11 deletions
|
|
@ -1979,16 +1979,15 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig):
|
|||
|
||||
@staticmethod
|
||||
def _calculate_web_search_requests(grounding_metadata: list[dict]) -> int | None:
|
||||
web_search_requests: int | None = None
|
||||
|
||||
if grounding_metadata and isinstance(grounding_metadata, list) and len(grounding_metadata) > 0:
|
||||
for grounding_metadata_item in grounding_metadata:
|
||||
web_search_queries = grounding_metadata_item.get("webSearchQueries")
|
||||
if web_search_queries and web_search_requests:
|
||||
web_search_requests += len([q for q in web_search_queries if q])
|
||||
elif web_search_queries:
|
||||
web_search_requests = len([q for q in web_search_queries if q])
|
||||
return web_search_requests
|
||||
if not (grounding_metadata and isinstance(grounding_metadata, list)):
|
||||
return None
|
||||
unique_queries: Final = {
|
||||
query
|
||||
for grounding_metadata_item in grounding_metadata
|
||||
for query in (grounding_metadata_item.get("webSearchQueries") or [])
|
||||
if query
|
||||
}
|
||||
return len(unique_queries) or None
|
||||
|
||||
@staticmethod
|
||||
def _create_streaming_choice(
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import asyncio
|
|||
import json
|
||||
import re
|
||||
from copy import deepcopy
|
||||
from typing import List, cast
|
||||
from typing import Final, List, cast
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
|
@ -5579,3 +5579,25 @@ def test_accumulated_json_async_end_of_stream_drains_buffered_value():
|
|||
result = asyncio.run(iterator.__anext__())
|
||||
assert result is not None
|
||||
assert result.choices[0].delta.content == "a"
|
||||
|
||||
|
||||
def test_calculate_web_search_requests_counts_unique_queries():
|
||||
"""Gemini 3 per_query billing charges per unique query executed, not per emitted string.
|
||||
|
||||
Regression for #36377: duplicate webSearchQueries within and across grounding
|
||||
metadata items must collapse to the distinct-query count, and empty strings must
|
||||
be ignored, matching Google's documented Grounding-with-Search billing rule.
|
||||
"""
|
||||
duplicates_in_one_item: Final = [
|
||||
{"webSearchQueries": ["euro 2024 winner", "euro 2024 winner", "spain england final", ""]}
|
||||
]
|
||||
assert VertexGeminiConfig._calculate_web_search_requests(duplicates_in_one_item) == 2
|
||||
|
||||
duplicates_across_items: Final = [
|
||||
{"webSearchQueries": ["euro 2024 winner"]},
|
||||
{"webSearchQueries": ["euro 2024 winner", "spain england final"]},
|
||||
]
|
||||
assert VertexGeminiConfig._calculate_web_search_requests(duplicates_across_items) == 2
|
||||
|
||||
assert VertexGeminiConfig._calculate_web_search_requests([]) is None
|
||||
assert VertexGeminiConfig._calculate_web_search_requests([{"webSearchQueries": ["", ""]}]) is None
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue