Skip to content

Commit fe977ec

Browse files
committed
Refactor OpenAI configuration to use parameters
1 parent 75f065b commit fe977ec

File tree

2 files changed

+76
-36
lines changed

2 files changed

+76
-36
lines changed

src/eShop.AppHost/Extensions.cs

Lines changed: 75 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
using Aspire.Hosting.Lifecycle;
22
using Aspire.Hosting.Yarp;
33
using Aspire.Hosting.Yarp.Transforms;
4-
using Microsoft.Extensions.Configuration;
54
using Yarp.ReverseProxy.Configuration;
65

76
namespace eShop.AppHost;
87

8+
internal enum OpenAITarget
9+
{
10+
OpenAI,
11+
AzureOpenAI,
12+
AzureOpenAIExisting,
13+
AzureOpenAIExistingWithKey
14+
}
15+
916
internal static class Extensions
1017
{
1118
/// <summary>
@@ -38,7 +45,8 @@ public Task BeforeStartAsync(DistributedApplicationModel appModel, CancellationT
3845
/// </summary>
3946
public static IDistributedApplicationBuilder AddOpenAI(this IDistributedApplicationBuilder builder,
4047
IResourceBuilder<ProjectResource> catalogApi,
41-
IResourceBuilder<ProjectResource> webApp)
48+
IResourceBuilder<ProjectResource> webApp,
49+
OpenAITarget openAITarget)
4250
{
4351
const string openAIName = "openai";
4452

@@ -48,44 +56,76 @@ public static IDistributedApplicationBuilder AddOpenAI(this IDistributedApplicat
4856
const string chatName = "chatModel";
4957
const string chatModelName = "gpt-4.1-mini";
5058

51-
// to use an existing OpenAI resource as a connection string, add the following to the AppHost user secrets:
52-
// "ConnectionStrings": {
53-
// "openai": "Key=<API Key>" (to use https://api.openai.com/)
54-
// -or-
55-
// "openai": "Endpoint=https://<name>.openai.azure.com/" (to use Azure OpenAI)
56-
// }
57-
if (builder.Configuration.GetConnectionString(openAIName) is string openAIConnectionString)
58-
{
59-
catalogApi.WithReference(
60-
builder.AddConnectionString(textEmbeddingName, ReferenceExpression.Create($"{openAIConnectionString};Deployment={textEmbeddingModelName}")));
61-
webApp.WithReference(
62-
builder.AddConnectionString(chatName, ReferenceExpression.Create($"{openAIConnectionString};Deployment={chatModelName}")));
63-
}
64-
else
59+
if (openAITarget != OpenAITarget.AzureOpenAI)
6560
{
66-
// to use Azure provisioning, add the following to the AppHost user secrets:
67-
// "Azure": {
68-
// "SubscriptionId": "<your subscription ID>",
69-
// "ResourceGroupPrefix": "<prefix>",
70-
// "Location": "<location>"
71-
// }
61+
#pragma warning disable ASPIREINTERACTION001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
62+
IResourceBuilder<ParameterResource>? endpoint = null;
63+
if (openAITarget != OpenAITarget.OpenAI)
64+
{
65+
endpoint = builder.AddParameter("OpenAIEndpointParameter")
66+
.WithDescription("The Azure OpenAI endpoint to use, e.g. https://<name>.openai.azure.com/")
67+
.WithCustomInput(p => new()
68+
{
69+
Label = "Azure OpenAI Endpoint",
70+
InputType = InputType.Text,
71+
Value = "https://<name>.openai.azure.com/",
72+
});
73+
}
7274

73-
var openAI = builder.AddAzureOpenAI(openAIName);
75+
IResourceBuilder<ParameterResource>? key = null;
76+
if (openAITarget is OpenAITarget.OpenAI or OpenAITarget.AzureOpenAIExistingWithKey)
77+
{
78+
key = builder.AddParameter("OpenAIKeyParameter", secret: true)
79+
.WithDescription("The OpenAI API key to use.")
80+
.WithCustomInput(p => new()
81+
{
82+
Label = "API Key",
83+
InputType = InputType.SecretText
84+
});
85+
}
7486

75-
// to use an existing Azure OpenAI resource via provisioning, add the following to the AppHost user secrets:
76-
// "Parameters": {
77-
// "openaiName": "<Azure OpenAI resource name>",
78-
// "openaiResourceGroup": "<Azure OpenAI resource group>"
79-
// }
80-
// - or -
81-
// leave the parameters out to create a new Azure OpenAI resource
82-
if (builder.Configuration["Parameters:openaiName"] is not null &&
83-
builder.Configuration["Parameters:openaiResourceGroup"] is not null)
87+
var chatModel = builder.AddParameter("ChatModelParameter")
88+
.WithDescription("The chat model to use.")
89+
.WithCustomInput(p => new()
90+
{
91+
Label = "Chat Model",
92+
InputType = InputType.Text,
93+
Value = chatModelName,
94+
});
95+
96+
var embeddingModel = builder.AddParameter("EmbeddingModelParameter")
97+
.WithDescription("The embedding model to use.")
98+
.WithCustomInput(p => new()
99+
{
100+
Label = "Text Embedding Model",
101+
InputType = InputType.Text,
102+
Value = textEmbeddingModelName,
103+
});
104+
#pragma warning restore ASPIREINTERACTION001
105+
106+
var openAIConnectionBuilder = new ReferenceExpressionBuilder();
107+
if (endpoint is not null)
84108
{
85-
openAI.AsExisting(
86-
builder.AddParameter("openaiName"),
87-
builder.AddParameter("openaiResourceGroup"));
109+
openAIConnectionBuilder.Append($"Endpoint={endpoint}");
88110
}
111+
if (key is not null)
112+
{
113+
openAIConnectionBuilder.Append($";Key={key}");
114+
}
115+
var openAIConnectionString = openAIConnectionBuilder.Build();
116+
117+
catalogApi.WithReference(builder.AddConnectionString(textEmbeddingName, cs =>
118+
{
119+
cs.Append($"{openAIConnectionString};Deployment={embeddingModel}");
120+
}));
121+
webApp.WithReference(builder.AddConnectionString(chatName, cs =>
122+
{
123+
cs.Append($"{openAIConnectionString};Deployment={chatModel}");
124+
}));
125+
}
126+
else
127+
{
128+
var openAI = builder.AddAzureOpenAI(openAIName);
89129

90130
var chat = openAI.AddDeployment(chatName, chatModelName, "2025-04-14")
91131
.WithProperties(d =>

src/eShop.AppHost/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@
7878
bool useOpenAI = false;
7979
if (useOpenAI)
8080
{
81-
builder.AddOpenAI(catalogApi, webApp);
81+
builder.AddOpenAI(catalogApi, webApp, OpenAITarget.OpenAI); // set to AzureOpenAI if you want to use Azure OpenAI
8282
}
8383

8484
bool useOllama = false;

0 commit comments

Comments
 (0)