Integrate Chat Page With Microsoft Phi4
In this article, we'll walk through the process of integrating a simple chat page with Microsoft Foundry (Phi4) into an existing application. This integration will allow users to interact with the Phi4 model directly from the application's user interface. We'll cover both the frontend and backend aspects, including setting up the necessary configurations and handling potential errors. The goal is to provide a seamless and user-friendly chat experience.
Understanding the Project
Before diving into the implementation, it's crucial to understand the project's scope and requirements. The main objective is to add a new chat functionality to the ZavaStorefront application. This new feature will be accessible as a separate page, allowing users to interact with the Microsoft Foundry Phi4 endpoint. The integration involves creating a user interface for sending messages and displaying the conversation history, as well as a backend service to handle communication with the Phi4 API.
Project Overview
The ZavaStorefront application will be enhanced with a new chat page. This page will include a text input field for users to type their messages, a text area to display the conversation history, and a "Send" button to submit the messages. The application will also show a loading state while waiting for the AI's response to ensure users are aware that their message is being processed. The backend will consist of a ChatController.cs to handle chat requests and a ChatService.cs to communicate with the Microsoft Foundry API. The service will be configured to use the existing Phi4 model endpoint from Azure AI Services, and error handling will be implemented to display user-friendly messages.
Key Components
To achieve this integration, several key components must work together seamlessly:
- Frontend Components:
- A new
/Chatpage accessible from the main navigation. - A text input field for user messages.
- A text area to display the conversation history.
- A "Send" button to submit messages.
- A loading state indicator.
- A new
- Backend Services:
ChatController.cs: Handles incoming chat requests from the frontend.ChatService.cs: Communicates with the Microsoft Foundry API.
- Configuration:
appsettings.json: Stores the Foundry endpoint URL.- Azure AI Services: Uses the existing
AZURE_AI_SERVICES_ENDPOINT.
Frontend Implementation
The frontend implementation focuses on creating the user interface for the chat page. This involves adding the necessary HTML elements, handling user input, and displaying the conversation history. The goal is to create an intuitive and responsive chat interface.
Creating the /Chat Page
The first step is to create a new /Chat page within the ZavaStorefront application. This page should be accessible from the main navigation menu. You can add a new route in your application's routing configuration to map the /Chat URL to the corresponding component or view.
// Example in ASP.NET Core
app.MapControllerRoute(
name: "chat",
pattern: "Chat",
defaults: new { controller = "Chat", action = "Index" });
Adding UI Elements
Next, add the necessary UI elements to the /Chat page. This includes a text input field for users to type their messages, a text area to display the conversation history, and a "Send" button to submit the messages. You can use HTML and CSS to style these elements and make them visually appealing.
<div class="chat-container">
<div class="conversation-history" id="conversationHistory"></div>
<div class="input-area">
<input type="text" id="messageInput" placeholder="Type your message...">
<button id="sendButton">Send</button>
</div>
<div class="loading-indicator" id="loadingIndicator">Loading...</div>
</div>
Handling User Input
To handle user input, you'll need to attach event listeners to the input field and the "Send" button. When the user types a message and clicks the "Send" button (or presses Enter), the message should be sent to the backend for processing. You can use JavaScript to capture the user's input and update the conversation history.
const messageInput = document.getElementById('messageInput');
const sendButton = document.getElementById('sendButton');
const conversationHistory = document.getElementById('conversationHistory');
const loadingIndicator = document.getElementById('loadingIndicator');
sendButton.addEventListener('click', sendMessage);
messageInput.addEventListener('keydown', function(event) {
if (event.key === 'Enter') {
sendMessage();
}
});
async function sendMessage() {
const message = messageInput.value;
if (!message) return;
displayMessage(message, 'user');
messageInput.value = '';
loadingIndicator.style.display = 'block';
try {
const response = await fetch('/Chat/Send', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ message: message })
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
displayMessage(data.response, 'ai');
} catch (error) {
console.error('Error:', error);
displayMessage('Error: Could not get response from AI.', 'error');
} finally {
loadingIndicator.style.display = 'none';
}
}
function displayMessage(message, sender) {
const messageElement = document.createElement('div');
messageElement.classList.add('message', sender);
messageElement.textContent = message;
conversationHistory.appendChild(messageElement);
conversationHistory.scrollTop = conversationHistory.scrollHeight;
}
Displaying Conversation History
The conversation history should be displayed in the text area. Each message should be clearly identified as either a user message or an AI response. You can use CSS to style the messages and differentiate them visually. The JavaScript code above includes a displayMessage function that adds new messages to the conversation history.
Backend Implementation
The backend implementation involves creating the ChatController.cs and ChatService.cs to handle chat requests and communicate with the Microsoft Foundry API. This includes setting up the necessary endpoints, configuring the service to use the Phi4 model endpoint, and handling errors gracefully.
Creating ChatController.cs
The ChatController.cs will handle incoming chat requests from the frontend. It should include an endpoint to receive the user's message and pass it to the ChatService.cs for processing. The controller should also handle any errors that occur during the process and return a user-friendly message to the frontend.
using Microsoft.AspNetCore.Mvc;
using ZavaStorefront.Services;
namespace ZavaStorefront.Controllers
{
[ApiController]
[Route("[controller]")]
public class ChatController : ControllerBase
{
private readonly ChatService _chatService;
public ChatController(ChatService chatService)
{
_chatService = chatService;
}
[HttpPost("Send")]
public async Task<IActionResult> Send([FromBody] ChatRequest request)
{
try
{
var response = await _chatService.SendMessage(request.Message);
return Ok(new { Response = response });
} catch (Exception ex)
{
Console.LogError(ex, "Error while processing chat request");
return StatusCode(500, new { Error = "Failed to get response from AI." });
}
}
}
public class ChatRequest
{
public string Message { get; set; }
}
}
Creating ChatService.cs
The ChatService.cs will communicate with the Microsoft Foundry API. It should include a method to send the user's message to the API and receive the AI's response. The service should be configured to use the existing Phi4 model endpoint from Azure AI Services. This involves setting up the necessary HTTP client and handling the API request and response.
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace ZavaStorefront.Services
{
public class ChatService
{
private readonly HttpClient _httpClient;
private readonly string _foundryEndpointUrl;
private readonly ILogger<ChatService> _logger;
public ChatService(HttpClient httpClient, IConfiguration configuration, ILogger<ChatService> logger)
{
_httpClient = httpClient;
_foundryEndpointUrl = configuration["FoundryEndpointUrl"];
_logger = logger;
}
public async Task<string> SendMessage(string message)
{
try
{
var requestBody = new {
input = message
};
var json = JsonSerializer.Serialize(requestBody);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync(_foundryEndpointUrl, content);
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync();
var responseObject = JsonSerializer.Deserialize<dynamic>(responseBody);
return responseObject.output;
} catch (HttpRequestException ex)
{
_logger.LogError(ex, "Error while sending message to Foundry API");
throw new Exception("Failed to get response from AI.", ex);
}
}
}
}
Configuring the Service
To configure the service, you'll need to add the Foundry endpoint URL to the appsettings.json file. This URL will be used by the ChatService.cs to communicate with the Microsoft Foundry API. You can also use the existing AZURE_AI_SERVICES_ENDPOINT from the infrastructure outputs.
{
"FoundryEndpointUrl": "<Your_Foundry_Endpoint_URL>",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
You will also need to register the ChatService in your Startup.cs or Program.cs file:
builder.Services.AddHttpClient<ChatService>();
builder.Services.AddScoped<ChatService>();
Error Handling
Error handling is crucial to ensure that the application handles errors gracefully and displays user-friendly messages. You should implement error handling in both the ChatController.cs and the ChatService.cs. This includes catching exceptions, logging errors, and returning appropriate error messages to the frontend.
Configuration
Proper configuration is essential for the integration to work correctly. This involves adding the Foundry endpoint URL to the appsettings.json file and implementing authentication using managed identity or API key.
Adding Foundry Endpoint URL
The Foundry endpoint URL should be added to the appsettings.json file. This URL will be used by the ChatService.cs to communicate with the Microsoft Foundry API. Make sure to replace <Your_Foundry_Endpoint_URL> with the actual URL of your Phi4 endpoint.
Implementing Authentication
Authentication is necessary to secure the communication between the application and the Microsoft Foundry API. You can implement authentication using managed identity or API key. Managed identity is a more secure option, as it eliminates the need to store sensitive credentials in the application's configuration. However, if managed identity is not available, you can use an API key.
Acceptance Criteria
The following acceptance criteria should be met to ensure that the integration is successful:
- User can navigate to the Chat page from the main menu.
- User can type a message and receive a response from Phi4.
- Conversation history is displayed in the text area.
- Error states are handled gracefully.
Conclusion
Integrating a chat page with Microsoft Foundry (Phi4) into an existing application involves several steps, including frontend implementation, backend implementation, and configuration. By following the steps outlined in this article, you can successfully add a new chat functionality to your application and provide users with a seamless and user-friendly chat experience. Remember to handle errors gracefully and implement proper authentication to ensure the security of your application.
For more information on Azure AI services, visit the official Microsoft Azure documentation. This resource provides comprehensive details and best practices for leveraging Azure AI in your applications.