// Copyright (c) Microsoft. All rights reserved. using ChatWithAgent.AppHost.Extensions; using ChatWithAgent.Configuration; var builder = DistributedApplication.CreateBuilder(args); // Load host configuration. var hostConfig = new HostConfig(builder.Configuration); // Add Api Service AI upstream dependencies var aiServices = AddAIServices(builder, hostConfig); // Add Vector Store var vectorStore = AddVectorStore(builder, hostConfig); // Add Api Service var apiService = builder.AddProject("apiservice") .WithEnvironment(hostConfig) // Add some host configuration as environment variables so that the Api Service can access them .WithReferences(aiServices) .WithReference(vectorStore); // Add Web Frontend builder.AddProject("webfrontend") .WithExternalHttpEndpoints() .WithReference(apiService) .WaitFor(apiService); builder.Build().Run(); static List> AddAIServices(IDistributedApplicationBuilder builder, HostConfig config) { IResourceBuilder? chatResource = null; IResourceBuilder? embeddingsResource = null; // Add Azure OpenAI service and configured AI models if (config.AIChatService == AzureOpenAIChatConfig.ConfigSectionName || config.Rag.AIEmbeddingService == AzureOpenAIEmbeddingsConfig.ConfigSectionName) { if (builder.ExecutionContext.IsPublishMode) { // Add Azure OpenAI service var azureOpenAI = builder.AddAzureOpenAI(HostConfig.AzureOpenAIConnectionStringName); // Add chat deployment if (config.AIChatService == AzureOpenAIChatConfig.ConfigSectionName) { chatResource = azureOpenAI .AddDeployment( name: config.AzureOpenAIChat.DeploymentName, modelName: config.AzureOpenAIChat.ModelName, modelVersion: config.AzureOpenAIChat.ModelVersion) .WithProperties((resource) => { if (config.AzureOpenAIChat.SkuName is { } skuName) { resource.SkuName = skuName; } if (config.AzureOpenAIChat.SkuCapacity is { } skuCapacity) { resource.SkuCapacity = skuCapacity; } }); } // Add deployment if (config.Rag.AIEmbeddingService == AzureOpenAIEmbeddingsConfig.ConfigSectionName) { embeddingsResource = azureOpenAI .AddDeployment( name: config.AzureOpenAIEmbeddings.DeploymentName, modelName: config.AzureOpenAIEmbeddings.ModelName, modelVersion: config.AzureOpenAIEmbeddings.ModelVersion) .WithProperties((resource) => { if (config.AzureOpenAIEmbeddings.SkuName is { } skuName) { resource.SkuName = skuName; } if (config.AzureOpenAIEmbeddings.SkuCapacity is { } skuCapacity) { resource.SkuCapacity = skuCapacity; } }); } } else { // Use an existing Azure OpenAI service via connection string chatResource = embeddingsResource = builder.AddConnectionString(HostConfig.AzureOpenAIConnectionStringName); } } // Add OpenAI service via connection string if (config.AIChatService == OpenAIChatConfig.ConfigSectionName || config.Rag.AIEmbeddingService == OpenAIEmbeddingsConfig.ConfigSectionName) { chatResource = embeddingsResource = builder.AddConnectionString(HostConfig.OpenAIConnectionStringName); } if (chatResource is null) { throw new NotSupportedException($"AI Chat service '{config.AIChatService}' is not supported."); } if (embeddingsResource is null) { throw new NotSupportedException($"AI Embedding service '{config.Rag.AIEmbeddingService}' is not supported."); } return [chatResource, embeddingsResource]; } static IResourceBuilder AddVectorStore(IDistributedApplicationBuilder builder, HostConfig config) { switch (config.Rag.VectorStoreType) { case AzureAISearchConfig.ConfigSectionName: { return builder.ExecutionContext.IsPublishMode ? builder.AddAzureSearch(AzureAISearchConfig.ConnectionStringName) : builder.AddConnectionString(AzureAISearchConfig.ConnectionStringName); } default: { throw new NotSupportedException($"Vector Store type '{config.Rag.VectorStoreType}' is not supported."); } } }