diff --git a/travel-agent/M365Agent/infra/azure.bicep b/travel-agent/M365Agent/infra/azure.bicep
index ad4da3ce..73b27353 100644
--- a/travel-agent/M365Agent/infra/azure.bicep
+++ b/travel-agent/M365Agent/infra/azure.bicep
@@ -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
@@ -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
diff --git a/travel-agent/M365Agent/infra/botRegistration/azurebot.bicep b/travel-agent/M365Agent/infra/botRegistration/azurebot.bicep
index 800228fe..7b07bf95 100644
--- a/travel-agent/M365Agent/infra/botRegistration/azurebot.bicep
+++ b/travel-agent/M365Agent/infra/botRegistration/azurebot.bicep
@@ -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
diff --git a/travel-agent/TravelAgent/Bot/Agents/TravelAgent.cs b/travel-agent/TravelAgent/Bot/Agents/TravelAgent.cs
index d5901f34..cb953610 100644
--- a/travel-agent/TravelAgent/Bot/Agents/TravelAgent.cs
+++ b/travel-agent/TravelAgent/Bot/Agents/TravelAgent.cs
@@ -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;
@@ -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.
@@ -42,7 +43,9 @@ Each choice should followed by justification of related policies. Make sure just
/// Initializes a new instance of the class.
///
/// An instance of for interacting with an LLM.
- public TravelAgent(IChatClient chatClient, AgentApplication app)
+ /// The agent application instance.
+ /// The turn context for the current conversation.
+ public TravelAgent(IChatClient chatClient, AgentApplication app, ITurnContext turnContext)
{
var tools = new List();
@@ -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);
diff --git a/travel-agent/TravelAgent/Bot/Plugins/RetrievalPlugin.cs b/travel-agent/TravelAgent/Bot/Plugins/RetrievalPlugin.cs
index d4c4898b..b38eddbc 100644
--- a/travel-agent/TravelAgent/Bot/Plugins/RetrievalPlugin.cs
+++ b/travel-agent/TravelAgent/Bot/Plugins/RetrievalPlugin.cs
@@ -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;
-
///
/// Retrieve travel policies about expenses use graph API.
///
@@ -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 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);
diff --git a/travel-agent/TravelAgent/Bot/TravelAgentBot.cs b/travel-agent/TravelAgent/Bot/TravelAgentBot.cs
index 92a8de44..4ba171cb 100644
--- a/travel-agent/TravelAgent/Bot/TravelAgentBot.cs
+++ b/travel-agent/TravelAgent/Bot/TravelAgentBot.cs
@@ -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)
@@ -35,7 +35,7 @@ protected async Task MessageActivityAsync(ITurnContext turnContext, ITurnState t
await turnContext.StreamingResponse.QueueInformativeUpdateAsync("Working on a response for you");
IList chatHistory = turnState.GetValue("conversation.chatHistory", () => new List());
- _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);
diff --git a/travel-agent/TravelAgent/appsettings.Development.json b/travel-agent/TravelAgent/appsettings.Development.json
index 9f36b72a..7ad78877 100644
--- a/travel-agent/TravelAgent/appsettings.Development.json
+++ b/travel-agent/TravelAgent/appsettings.Development.json
@@ -5,7 +5,7 @@
"NormalizeMentions": false,
"UserAuthorization": {
"Default": "graph",
- "AutoSignIn": true,
+ "AutoSignIn": false,
"Handlers": {
"graph": {
"Settings": {
diff --git a/travel-agent/TravelAgent/appsettings.json b/travel-agent/TravelAgent/appsettings.json
index 21a066f5..5942be7f 100644
--- a/travel-agent/TravelAgent/appsettings.json
+++ b/travel-agent/TravelAgent/appsettings.json
@@ -5,7 +5,7 @@
"NormalizeMentions": false,
"UserAuthorization": {
"Default": "graph",
- "AutoSignIn": true,
+ "AutoSignIn": false,
"Handlers": {
"graph": {
"Settings": {