diff --git a/shell/agents/Microsoft.Azure.Agent/ChatSession.cs b/shell/agents/Microsoft.Azure.Agent/ChatSession.cs index 2ed666b..f7d69b6 100644 --- a/shell/agents/Microsoft.Azure.Agent/ChatSession.cs +++ b/shell/agents/Microsoft.Azure.Agent/ChatSession.cs @@ -11,9 +11,8 @@ namespace Microsoft.Azure.Agent; internal class ChatSession : IDisposable { - // TODO: production URL not yet working for some regions. - // private const string ACCESS_URL = "https://copilotweb.production.portalrp.azure.com/api/access?api-version=2024-09-01"; - private const string ACCESS_URL = "https://copilotweb.canary.production.portalrp.azure.com/api/access?api-version=2024-09-01"; + private const string PROD_ACCESS_URL = "https://copilotweb.production.portalrp.azure.com/api/access?api-version=2024-09-01"; + private const string TEST_ACCESS_URL = "https://copilotweb.canary.production.portalrp.azure.com/api/access?api-version=2024-09-01"; private const string DL_TOKEN_URL = "https://copilotweb.production.portalrp.azure.com/api/conversations/start?api-version=2024-11-15"; private const string CONVERSATION_URL = "https://directline.botframework.com/v3/directline/conversations"; @@ -141,11 +140,13 @@ private async Task SetupNewChat(IStatusContext context, CancellationToke private async Task CheckAuthorizationAsync(CancellationToken cancellationToken) { - HttpRequestMessage request = new(HttpMethod.Get, ACCESS_URL); - request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken.Token); - - HttpResponseMessage response = await _httpClient.SendAsync(request, cancellationToken); + HttpResponseMessage response = await SendRequestAsync(PROD_ACCESS_URL); + if (response.StatusCode is not System.Net.HttpStatusCode.OK) + { + // We fall back to the test endpoint when the prod endpoint is unavailable. + Telemetry.Trace(AzTrace.Exception($"Prod access endpoint unavailable. HTTP status: {response.StatusCode}. Fall back to canary endpoint.")); + response = await SendRequestAsync(TEST_ACCESS_URL); + } await response.EnsureSuccessStatusCodeForTokenRequest("Failed to check Copilot authorization."); using Stream stream = await response.Content.ReadAsStreamAsync(cancellationToken); @@ -158,6 +159,14 @@ private async Task CheckAuthorizationAsync(CancellationToken cancellationToken) Telemetry.Trace(AzTrace.Exception(message)); throw new TokenRequestException(message) { UserUnauthorized = true }; } + + async Task SendRequestAsync(string url) + { + HttpRequestMessage request = new(HttpMethod.Get, url); + request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken.Token); + return await _httpClient.SendAsync(request, cancellationToken); + } } private async Task GetInitialDLTokenAsync(CancellationToken cancellationToken)