forked from microsoft/chat-copilot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Program.cs
131 lines (113 loc) · 4.82 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright (c) Microsoft. All rights reserved.
using System;
using System.Diagnostics;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using CopilotChat.WebApi.Extensions;
using CopilotChat.WebApi.Hubs;
using CopilotChat.WebApi.Services;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.Implementation;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace CopilotChat.WebApi;
/// <summary>
/// Chat Copilot Service
/// </summary>
public sealed class Program
{
/// <summary>
/// Entry point
/// </summary>
/// <param name="args">Web application command-line arguments.</param>
// ReSharper disable once InconsistentNaming
public static async Task Main(string[] args)
{
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
// Load in configuration settings from appsettings.json, user-secrets, key vaults, etc...
builder.Host.AddConfiguration();
builder.WebHost.UseUrls(); // Disables endpoint override warning message when using IConfiguration for Kestrel endpoint.
// Add in configuration options and required services.
builder.Services
.AddSingleton<ILogger>(sp => sp.GetRequiredService<ILogger<Program>>()) // some services require an un-templated ILogger
.AddOptions(builder.Configuration)
.AddPersistentChatStore()
.AddPlugins(builder.Configuration)
.AddChatCopilotAuthentication(builder.Configuration)
.AddChatCopilotAuthorization();
// Configure and add semantic services
builder
.AddBotConfig()
.AddSemanticKernelServices()
.AddSemanticMemoryServices();
// Add SignalR as the real time relay service
builder.Services.AddSignalR();
// Add AppInsights telemetry
builder.Services
.AddHttpContextAccessor()
.AddApplicationInsightsTelemetry(options => { options.ConnectionString = builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"]; })
.AddSingleton<ITelemetryInitializer, AppInsightsUserTelemetryInitializerService>()
.AddLogging(logBuilder => logBuilder.AddApplicationInsights())
.AddSingleton<ITelemetryService, AppInsightsTelemetryService>();
TelemetryDebugWriter.IsTracingDisabled = Debugger.IsAttached;
// Add named HTTP clients for IHttpClientFactory
builder.Services.AddHttpClient();
// Add in the rest of the services.
builder.Services
.AddMaintenanceServices()
.AddEndpointsApiExplorer()
.AddSwaggerGen()
.AddCorsPolicy(builder.Configuration)
.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
});
builder.Services.AddHealthChecks();
// Configure middleware and endpoints
WebApplication app = builder.Build();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
app.UseMiddleware<MaintenanceMiddleware>();
app.MapControllers()
.RequireAuthorization();
app.MapHealthChecks("/healthz");
// Add Chat Copilot hub for real time communication
app.MapHub<MessageRelayHub>("/messageRelayHub");
// Enable Swagger for development environments.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
// Redirect root URL to Swagger UI URL
app.MapWhen(
context => context.Request.Path == "/",
appBuilder =>
appBuilder.Run(
async context => await Task.Run(() => context.Response.Redirect("/swagger"))));
}
// Start the service
Task runTask = app.RunAsync();
// Log the health probe URL for users to validate the service is running.
try
{
string? address = app.Services.GetRequiredService<IServer>().Features.Get<IServerAddressesFeature>()?.Addresses.FirstOrDefault();
app.Services.GetRequiredService<ILogger>().LogInformation("Health probe: {0}/healthz", address);
}
catch (ObjectDisposedException)
{
// We likely failed startup which disposes 'app.Services' - don't attempt to display the health probe URL.
}
// Wait for the service to complete.
await runTask;
}
}