Hi Edgar,
To get citations from your Azure AI Foundry Agent response, you need to access the annotations property of the message content, which contains the citation information. Here's how to modify your code to extract and display citations:
Updated Code with Citations:
@bot_app.activity("message")
async def on_message_activity(context: TurnContext, state: TurnState):
"""Handle incoming messages using Azure AI Foundry Agent Service"""
try:
user_message = context.activity.text
user_id = context.activity.from_property.id
user_name = getattr(context.activity.from_property, 'name', 'User')
print(f"📨 Processing message from {user_name}: {user_message}")
# Handle special commands first
if user_message.lower().strip() in ['help', 'info']:
await context.send_activity(MessageFactory.text(INFO_MESSAGE))
return
elif user_message.lower().strip() in ['intro', 'welcome']:
await context.send_activity(MessageFactory.text(WELCOME_MESSAGE))
return
# Process with Azure AI Foundry
thread_key = f"thread_{user_id}"
thread_id = state.conversation.get(thread_key)
if not thread_id:
print("🔧 Creating new Azure AI Foundry thread...")
thread = project_client.agents.create_thread_and_process_run(
agent_id=config.AZURE_OPENAI_ASSISTANT_ID
)
thread_id = thread.thread_id
state.conversation[thread_key] = thread_id
print(f"✅ Created new thread: {thread_id}")
# Add user message to thread
message = project_client.agents.messages.create(
thread_id=thread_id,
role=MessageRole.USER,
content=user_message
)
# Create and run the agent
run = project_client.agents.runs.create_and_process(
thread_id=thread_id,
agent_id=config.AZURE_OPENAI_ASSISTANT_ID
)
# Get the completed run
completed_run = project_client.agents.runs.get(
thread_id=thread_id,
run_id=run.id
)
if completed_run.status == "completed":
# Get messages
messages = project_client.agents.messages.list(
thread_id=thread_id,
order=ListSortOrder.ASCENDING
)
# Find the latest assistant message with citations
assistant_response = None
citations = []
for msg in messages:
if msg.role == MessageRole.ASSISTANT and msg.text_messages:
latest_text_msg = msg.text_messages[-1]
assistant_response = latest_text_msg.text.value
# Extract citations from annotations
if hasattr(latest_text_msg.text, 'annotations') and latest_text_msg.text.annotations:
for annotation in latest_text_msg.text.annotations:
if hasattr(annotation, 'file_citation'):
file_citation = annotation.file_citation
citations.append({
'file_id': file_citation.file_id,
'quote': getattr(file_citation, 'quote', ''),
'text': annotation.text
})
if assistant_response:
# Format response with citations
formatted_response = await format_response_with_citations(
assistant_response,
citations,
project_client
)
await context.send_activity(MessageFactory.text(formatted_response))
else:
await context.send_activity(MessageFactory.text(
"I processed your message but couldn't generate a response."
))
else:
error_msg = f"Sorry, I encountered a technical issue (status: {completed_run.status})."
await context.send_activity(MessageFactory.text(error_msg))
except Exception as e:
print(f"❌ Error in message handler: {str(e)}")
traceback.print_exc()
await context.send_activity(MessageFactory.text(
"Sorry, I encountered an error processing your message."
))
async def format_response_with_citations(response_text, citations, client):
"""Format the response with citation information"""
if not citations:
return response_text
formatted_response = response_text + "\n\n**Sources:**\n"
for i, citation in enumerate(citations, 1):
try:
# Get file information
file_info = client.files.get(citation['file_id'])
file_name = file_info.filename if hasattr(file_info, 'filename') else f"Document {i}"
formatted_response += f"{i}. {file_name}"
# Add quote if available
if citation.get('quote'):
formatted_response += f" - \"{citation['quote'][:100]}...\""
formatted_response += "\n"
except Exception as e:
print(f"Error getting file info for {citation['file_id']}: {e}")
formatted_response += f"{i}. Source document\n"
return formatted_response
Key Changes:
- Citation Extraction: Access
annotationsfrom the text message to get file citations - File Information: Retrieve file details using the file_id from citations
- Formatted Output: Combine the response with source information
Important Notes:
- Ensure your agent has access to the knowledge base files
- Citations are only available when the agent references specific documents
- File permissions may affect citation retrieval
Testing: Test with questions that should reference your knowledge base documents to verify citations appear correctly.
Hope this helps!
Thanks,
Karan Shewale.
*************************************************************************
If the response is helpful, please click "Accept Answer" and upvote it. You can share your feedback via Microsoft Teams Developer Feedback link. Click here to escalate.