URL context tool usage tracking problem in C# SDK
#### Environment details
- OS: macOS
- .NET version: 10.0.100
- Package name and version: Google.Cloud.AIPlatform.V1 , version 3.63.0
Hello,
I am having some issues in using the [URL Context](https://ai.google.dev/gemini-api/docs/url-context?hl=en) built-in tool with the C# SDK. The tool is used, but we can't track its usage in the response (which should be shown in the url_context_metadata and its token usage in tool_use_prompt_token_count ) as shown in the documentation link. However, It works perfectly with python SDK.
**Steps to reproduce :**
Here is a C# toy example :
```csharp
using Google.Cloud.AIPlatform.V1;
class Program
{
static async Task Main(string[] args)
{
string projectId = "YOUR_PROJECT_ID";
string location = "us-central1";
string model = "gemini-2.5-flash-lite";
var client = new PredictionServiceClientBuilder
{
Endpoint = $"{location}-aiplatform.googleapis.com"
}.Build();
var generationConfig = new GenerationConfig
{
CandidateCount = 1
};
var request = new GenerateContentRequest
{
Model = $"projects/{projectId}/locations/{location}/publishers/google/models/{model}",
Contents =
{
new Content
{
Role = "USER",
Parts =
{
new Part { Text = "summarize the content of this url: https://fr.wikipedia.org/wiki/LLM" }
}
}
},
GenerationConfig = generationConfig,
Tools =
{
new Tool { UrlContext = new UrlContext() }
}
};
GenerateContentResponse response = await client.GenerateContentAsync(request);
Console.WriteLine("=== FULL RESPONSE ===");
Console.WriteLine(response);
}
}
```
The full response is the following :
```json
{
"candidates": [
{
"content": {
"role": "model",
"parts": [
{
"text": "\n\nThe term \"LLM\" can refer to several things:\n\n* **Large Language Model (LLM):** This is a type of natural language processing computer program.\n* **Legum Magister (LL.M.):** This is a law degree, often translated as Master of Laws.\n* **Limited Late Model (LLM):** This refers to a specific type of stock car.\n* **Logic Learning Machine (LLM):** This is a machine learning method that uses the generation of understandable rules.\n\nAdditionally, \"LLM\" can be a code for Yamal, according to the list of ICAO airline codes."
}
]
},
"finishReason": "STOP",
"groundingMetadata": {}
}
],
"usageMetadata": {
"promptTokenCount": 20,
"candidatesTokenCount": 136,
"totalTokenCount": 638,
"promptTokensDetails": [
{
"modality": "TEXT",
"tokenCount": 20
}
],
"candidatesTokensDetails": [
{
"modality": "TEXT",
"tokenCount": 136
}
]
},
"modelVersion": "gemini-2.5-flash-lite",
"createTime": "2026-02-16T16:21:39.465035Z",
"responseId": "E0STaYuxHNqhlb4PxcqeqQE"
}
```
Now the same example in python gives this :
```python
from google import genai
from google.genai.types import GenerateContentConfig, Tool, UrlContext
# Initialize Vertex AI
project_id = "YOUR_PROJECT_ID"
location = "us-central1"
model = "gemini-2.5-flash-lite"
# Create the client with Vertex AI
client = genai.Client(
vertexai=True,
project=project_id,
location=location
)
# Create generation config
generation_config = GenerateContentConfig(
candidate_count=1,
tools=[Tool(url_context=genai.types.UrlContext)]
)
# Create the request using the model's generate_content method
# This is equivalent to the C# GenerateContentRequest
response = client.models.generate_content(
model=model,
contents="summarize the content of this url: https://fr.wikipedia.org/wiki/LLM",
config=generation_config,
)
# Print the full response
print("=== FULL RESPONSE ===")
print(response)
```
with the following response :
```text
=== FULL RESPONSE ===
sdk_http_response=HttpResponse(
headers=<dict len=10>
)
candidates=[Candidate(
content=Content(
parts=[
Part(
text="""
The url provided is a disambiguation page for the acronym "LLM". It lists several possible meanings, including:
* **Large Language Model**: A type of computer program used in natural language processing.
* **Legum Magister**: A law degree (Master of Laws).
* **Limited Late Model**: A category of stock car racing.
* **Logic Learning Machine**: A machine learning method based on generating understandable rules.
The page also mentions "LLM" as an airline code for Yamal."""
),
],
role='model'
),
finish_reason=<FinishReason.STOP: 'STOP'>,
grounding_metadata=GroundingMetadata(),
url_context_metadata=UrlContextMetadata(
url_metadata=[
UrlMetadata(
retrieved_url='https://fr.wikipedia.org/wiki/LLM',
url_retrieval_status=<UrlRetrievalStatus.URL_RETRIEVAL_STATUS_SUCCESS: 'URL_RETRIEVAL_STATUS_SUCCESS'>
),
]
)
)]
create_time=datetime.datetime(2026, 2, 16, 16, 22, 30, 655509, tzinfo=TzInfo(UTC))
model_version='gemini-2.5-flash-lite'
prompt_feedback=None
response_id='RkSTaZWBKKCBqMgPmOmm0AE'
usage_metadata=GenerateContentResponseUsageMetadata(
candidates_token_count=110,
candidates_tokens_details=[
ModalityTokenCount(
modality=<MediaModality.TEXT: 'TEXT'>,
token_count=110
),
],
prompt_token_count=20,
prompt_tokens_details=[
ModalityTokenCount(
modality=<MediaModality.TEXT: 'TEXT'>,
token_count=20
),
],
tool_use_prompt_token_count=482,
tool_use_prompt_tokens_details=[
ModalityTokenCount(
modality=<MediaModality.TEXT: 'TEXT'>,
token_count=482
),
],
total_token_count=612,
traffic_type=<TrafficType.ON_DEMAND: 'ON_DEMAND'>
)
automatic_function_calling_history=[]
parsed=None
```
**Main differences :**
- In the python response, we have indeed the url_context_metadata field that shows the tool call. This field is not present in the C# response .
- In the python response, we have a field tool_use_prompt_token_count that confirms the tool token usage. This field is not present for the C# code (but we know that the tool was used if we look at total_count which is higher than the sum of tokens for prompt and candidate)
A side note :
I also tested some other models (like 2.5 flash) and sometimes the info about URL context with the C# SDK is shown but in grounding_metadata field.
Thanks !
2 条评论