Hello Jagan P,
Welcome to the Microsoft Q&A and thank you for posting your questions here.
I understand that you would like to get citation links from Azure AI Agents reposnse through MessageTextAnnotation.
Regarding your code and explanations:
This is a prerequisite before you will implement the code below:
- Check your SDK and make sure you are using the correct SDK using bash command:
dotnet add package Azure.AI.Projects --prerelease
- NOTE:
MessageTextAnnotation
only includes text (the "quote"). File/URL citation metadata is only available if Azure AI Agents used file-based retrieval (i.e., not just text from AI Search).
There are two method you can use to achieve this, either you use reflection or JSON fallback as shown below:
foreach (ThreadMessage threadMessage in messages)
{
foreach (MessageContent contentItem in threadMessage.ContentItems)
{
if (contentItem is MessageTextContent textItem)
{
string text = textItem.Text;
foreach (MessageTextAnnotation annotation in textItem.Annotations)
{
// File-based citation (from uploaded PDFs, etc.)
if (annotation is MessageTextFileCitationAnnotation fileCitation && fileCitation.FileId != null)
{
Console.WriteLine($"Quote: {fileCitation.Text}");
Console.WriteLine($"FileId: {fileCitation.FileId}");
Console.WriteLine($"Quote: {fileCitation.Quote}");
}
// Try URL-based citation (rare - mostly in web-grounded data)
if (annotation.GetType().Name == "MessageTextUrlCitationAnnotation")
{
var citationUrlProp = annotation.GetType().GetProperty("UrlCitation");
var urlCitation = citationUrlProp?.GetValue(annotation);
if (urlCitation != null)
{
var url = urlCitation.GetType().GetProperty("Url")?.GetValue(urlCitation)?.ToString();
var title = urlCitation.GetType().GetProperty("Title")?.GetValue(urlCitation)?.ToString();
Console.WriteLine($"URL Title: {title}, URL: {url}");
}
}
}
}
}
}
Since MessageTextUrlCitationAnnotation
might not be accessible, use reflection to access UrlCitation
dynamically will be one of the best options. This also guards against runtime failures and works in most SDK versions.
Secondly, to use raw JSON inspection, if the above fails (e.g., annotations are completely empty), do:
string json = JsonSerializer.Serialize(threadMessage);
Console.WriteLine(json); // Inspect for "urlCitation" or "fileCitation"
using JsonDocument doc = JsonDocument.Parse(json);
foreach (var msg in doc.RootElement.GetProperty("content_items").EnumerateArray())
{
if (msg.TryGetProperty("annotations", out var annotations))
{
foreach (var annotation in annotations.EnumerateArray())
{
if (annotation.TryGetProperty("urlCitation", out var urlCitation))
{
Console.WriteLine($"Title: {urlCitation.GetProperty("title").GetString()}");
Console.WriteLine($"URL: {urlCitation.GetProperty("url").GetString()}");
}
}
}
}
I hope this is helpful! Do not hesitate to let me know if you have any other questions or clarifications.
Please don't forget to close up the thread here by upvoting and accept it as an answer if it is helpful.