Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion travel-agent/M365Agent/infra/azure.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ param webAppSKU string
param botDisplayName string

param environment string
param botDomain string
param botDomain string = ''
param deployAppService bool = environment != 'local'

// For OAuth connection of bot service, created outside of Bicep
Expand Down Expand Up @@ -114,6 +114,7 @@ module azureBotRegistration './botRegistration/azurebot.bicep' = {
}

// The output will be persisted in .env.{envName}. Visit https://aka.ms/teamsfx-actions/arm-deploy for more details.
output BOT_AZURE_APP_SERVICE_RESOURCE_ID string = deployAppService ? webApp.id : ''
output BOT_DOMAIN string = deployAppService ? webApp.properties.defaultHostName : botDomain
output BOT_ID string = deployAppService ? identity.properties.clientId :aadAppClientId
output BOT_TENANT_ID string = identity.properties.tenantId
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ resource botService 'Microsoft.BotService/botServices@2021-03-01' = {
msaAppId: deployAppService ? identityClientId : botConnectionClientId
msaAppMSIResourceId: deployAppService ? identityResourceId : ''
msaAppTenantId: identityTenantId
msaAppType: deployAppService ? 'ManagedIdentity' : 'SingleTenant'
msaAppType: deployAppService ? 'UserAssignedMSI' : 'SingleTenant'
}
sku: {
name: botServiceSku
Expand Down
9 changes: 6 additions & 3 deletions travel-agent/TravelAgent/Bot/Agents/TravelAgent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.Agents.AI;
using Microsoft.Agents.Builder;
using Microsoft.Agents.Builder.App;
using Microsoft.Extensions.AI;
using System.Text.Json.Nodes;
Expand All @@ -22,7 +23,7 @@ You have access to all user information.

When a customer asks a question about travel policies in domains mentioned, use the Retrieval Plugin to search the documents and find relevant information, and summarize result with referenced document to user.

When a customer asks a question about booking hotel/flight, first use the Retrieval Plugin to search the documents and find relevant information.
When a customer asks a question about booking hotel/flight, first use the RetrievalPlugin to search the documents and find relevant information.
Then, summarize the relevant information into a set of rules of related policies and the referenced documents.
After that, use DataPlugin to call the external flight/hotel API to get data. Leave location/destination parameter empty string is user does not specify. Ask for user input if date parameter is missing.
Finally, combine the rules from documents and the data from external API to answer the user's question.
Expand All @@ -42,7 +43,9 @@ Each choice should followed by justification of related policies. Make sure just
/// Initializes a new instance of the <see cref="TravelAgent"/> class.
/// </summary>
/// <param name="chatClient">An instance of <see cref="IChatClient"/> for interacting with an LLM.</param>
public TravelAgent(IChatClient chatClient, AgentApplication app)
/// <param name="app">The agent application instance.</param>
/// <param name="turnContext">The turn context for the current conversation.</param>
public TravelAgent(IChatClient chatClient, AgentApplication app, ITurnContext turnContext)
{
var tools = new List<AITool>();

Expand All @@ -55,7 +58,7 @@ public TravelAgent(IChatClient chatClient, AgentApplication app)
var dataPlugin = new DataPlugin();
tools.Add(AIFunctionFactory.Create(dataPlugin.GetHotelFlightDataAsync));

var retrievalPlugin = new RetrievalPlugin(app);
var retrievalPlugin = new RetrievalPlugin(app, turnContext);
tools.Add(AIFunctionFactory.Create(retrievalPlugin.BuildRetrievalAsync));

_agent = chatClient.CreateAIAgent(instructions: AgentInstructions, tools: tools);
Expand Down
9 changes: 3 additions & 6 deletions travel-agent/TravelAgent/Bot/Plugins/RetrievalPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@
using Microsoft.Kiota.Abstractions.Authentication;
using Microsoft.Kiota.Http.HttpClientLibrary;
using Microsoft.Agents.M365Copilot.Beta.Models;
using Microsoft.Agents.Builder;

namespace TravelAgent.Bot.Plugins
{
public class RetrievalPlugin(AgentApplication app)
public class RetrievalPlugin(AgentApplication app, ITurnContext turnContext)
{
AgentApplication _app = app;

/// <summary>
/// Retrieve travel policies about expenses use graph API.
/// </summary>
Expand All @@ -20,9 +19,7 @@ public class RetrievalPlugin(AgentApplication app)
[Description("This function talks to Microsoft 365 Copilot Retrieval API and gets travel policies about expenses and reimbursements, flight booking, ground transportation, hotel accommodations which are nicely formatted. It accepts user query as input and send out a chunk of relevant text and a link to the file in the results.")]
public async Task<string> BuildRetrievalAsync(string userquery)
{
#pragma warning disable CS0618 // Type or member is obsolete
string accessToken = _app.UserAuthorization.GetTurnToken("graph");
#pragma warning restore CS0618 // Type or member is obsolete
string accessToken = await app.UserAuthorization.GetTurnTokenAsync(turnContext, "graph");
var tokenProvider = new StaticTokenProvider(accessToken);
var authProvider = new BaseBearerTokenAuthenticationProvider(tokenProvider);
var requestAdapter = new HttpClientRequestAdapter(authProvider);
Expand Down
4 changes: 2 additions & 2 deletions travel-agent/TravelAgent/Bot/TravelAgentBot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public TravelAgentBot(AgentApplicationOptions options, IChatClient chatClient) :
_chatClient = chatClient ?? throw new ArgumentNullException(nameof(chatClient));

OnConversationUpdate(ConversationUpdateEvents.MembersAdded, WelcomeMessageAsync);
OnActivity(ActivityTypes.Message, MessageActivityAsync, rank: RouteRank.Last);
OnActivity(ActivityTypes.Message, MessageActivityAsync, rank: RouteRank.Last, autoSignInHandlers: ["graph"]);
}

protected async Task MessageActivityAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken cancellationToken)
Expand All @@ -35,7 +35,7 @@ protected async Task MessageActivityAsync(ITurnContext turnContext, ITurnState t
await turnContext.StreamingResponse.QueueInformativeUpdateAsync("Working on a response for you");

IList<ChatMessage> chatHistory = turnState.GetValue("conversation.chatHistory", () => new List<ChatMessage>());
_travelAgent = new Agents.TravelAgent(_chatClient, this);
_travelAgent = new Agents.TravelAgent(_chatClient, this, turnContext);

// Invoke the TravelAgent to process the message
TravelAgentResponse travelResponse = await _travelAgent.InvokeAgentAsync(turnContext.Activity.Text, chatHistory);
Expand Down
2 changes: 1 addition & 1 deletion travel-agent/TravelAgent/appsettings.Development.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"NormalizeMentions": false,
"UserAuthorization": {
"Default": "graph",
"AutoSignIn": true,
"AutoSignIn": false,
"Handlers": {
"graph": {
"Settings": {
Expand Down
2 changes: 1 addition & 1 deletion travel-agent/TravelAgent/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"NormalizeMentions": false,
"UserAuthorization": {
"Default": "graph",
"AutoSignIn": true,
"AutoSignIn": false,
"Handlers": {
"graph": {
"Settings": {
Expand Down
Loading