-
Notifications
You must be signed in to change notification settings - Fork 47
Expand file tree
/
Copy pathChatClientFactory.cs
More file actions
154 lines (136 loc) · 5.95 KB
/
ChatClientFactory.cs
File metadata and controls
154 lines (136 loc) · 5.95 KB
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
using Azure.AI.OpenAI;
using Azure.Identity;
using Azure.Core;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Logging;
using OpenAI;
using AzureOpenAIOptions = Azure.AI.OpenAI.AzureOpenAIClientOptions;
using AzureServiceVersion = Azure.AI.OpenAI.AzureOpenAIClientOptions.ServiceVersion;
namespace CobolToQuarkusMigration.Agents.Infrastructure;
/// <summary>
/// Factory for creating IChatClient instances for Azure OpenAI or OpenAI.
/// </summary>
public static class ChatClientFactory
{
private static readonly AzureServiceVersion AzureApiVersion = AzureServiceVersion.V2024_06_01;
/// <summary>
/// Creates an IChatClient for Azure OpenAI using API key authentication.
/// </summary>
/// <param name="endpoint">The Azure OpenAI endpoint.</param>
/// <param name="apiKey">The API key.</param>
/// <param name="modelId">The deployment/model name.</param>
/// <param name="logger">Optional logger.</param>
/// <returns>An IChatClient instance.</returns>
public static IChatClient CreateAzureOpenAIChatClient(
string endpoint,
string apiKey,
string modelId,
ILogger? logger = null)
{
if (string.IsNullOrEmpty(endpoint))
throw new ArgumentNullException(nameof(endpoint));
if (string.IsNullOrEmpty(apiKey))
throw new ArgumentNullException(nameof(apiKey));
if (string.IsNullOrEmpty(modelId))
throw new ArgumentNullException(nameof(modelId));
logger?.LogInformation("Creating Azure OpenAI chat client for endpoint: {Endpoint}, model: {Model}",
endpoint, modelId);
var client = new AzureOpenAIClient(
new Uri(endpoint),
new System.ClientModel.ApiKeyCredential(apiKey),
CreateOptions());
return client.GetChatClient(modelId).AsIChatClient();
}
/// <summary>
/// Creates an IChatClient for Azure OpenAI using a TokenCredential (e.g. DefaultAzureCredential).
/// </summary>
/// <param name="endpoint">The Azure OpenAI endpoint.</param>
/// <param name="credential">The token credential.</param>
/// <param name="modelId">The deployment/model name.</param>
/// <param name="logger">Optional logger.</param>
/// <returns>An IChatClient instance.</returns>
public static IChatClient CreateAzureOpenAIChatClient(
string endpoint,
TokenCredential credential,
string modelId,
ILogger? logger = null)
{
if (string.IsNullOrEmpty(endpoint))
throw new ArgumentNullException(nameof(endpoint));
if (credential == null)
throw new ArgumentNullException(nameof(credential));
if (string.IsNullOrEmpty(modelId))
throw new ArgumentNullException(nameof(modelId));
logger?.LogInformation("Creating Azure OpenAI chat client with TokenCredential for endpoint: {Endpoint}, model: {Model}",
endpoint, modelId);
var client = new AzureOpenAIClient(
new Uri(endpoint),
credential,
CreateOptions());
return client.GetChatClient(modelId).AsIChatClient();
}
/// <summary>
/// Creates an IChatClient for Azure OpenAI using DefaultAzureCredential (managed identity, etc.).
/// </summary>
/// <param name="endpoint">The Azure OpenAI endpoint.</param>
/// <param name="modelId">The deployment/model name.</param>
/// <param name="logger">Optional logger.</param>
/// <returns>An IChatClient instance.</returns>
public static IChatClient CreateAzureOpenAIChatClientWithDefaultCredential(
string endpoint,
string modelId,
ILogger? logger = null)
{
return CreateAzureOpenAIChatClient(endpoint, new DefaultAzureCredential(), modelId, logger);
}
/// <summary>
/// Creates an IChatClient for OpenAI (not Azure).
/// </summary>
/// <param name="apiKey">The OpenAI API key.</param>
/// <param name="modelId">The model name (e.g., "gpt-4").</param>
/// <param name="logger">Optional logger.</param>
/// <returns>An IChatClient instance.</returns>
public static IChatClient CreateOpenAIChatClient(
string apiKey,
string modelId,
ILogger? logger = null)
{
if (string.IsNullOrEmpty(apiKey))
throw new ArgumentNullException(nameof(apiKey));
if (string.IsNullOrEmpty(modelId))
throw new ArgumentNullException(nameof(modelId));
logger?.LogInformation("Creating OpenAI chat client for model: {Model}", modelId);
var client = new OpenAIClient(apiKey);
return client.GetChatClient(modelId).AsIChatClient();
}
/// <summary>
/// Creates an IChatClient based on configuration settings.
/// Automatically determines whether to use Azure OpenAI or OpenAI based on the presence of an endpoint.
/// </summary>
/// <param name="endpoint">The Azure OpenAI endpoint (null/empty for OpenAI).</param>
/// <param name="apiKey">The API key.</param>
/// <param name="modelId">The model/deployment name.</param>
/// <param name="useDefaultCredential">Whether to use DefaultAzureCredential for Azure OpenAI.</param>
/// <param name="logger">Optional logger.</param>
/// <returns>An IChatClient instance.</returns>
public static IChatClient CreateChatClient(
string? endpoint,
string apiKey,
string modelId,
bool useDefaultCredential = false,
ILogger? logger = null)
{
// If endpoint is provided, use Azure OpenAI
if (!string.IsNullOrEmpty(endpoint))
{
if (useDefaultCredential)
{
return CreateAzureOpenAIChatClientWithDefaultCredential(endpoint, modelId, logger);
}
return CreateAzureOpenAIChatClient(endpoint, apiKey, modelId, logger);
}
// Otherwise, use OpenAI
return CreateOpenAIChatClient(apiKey, modelId, logger);
}
private static AzureOpenAIOptions CreateOptions() => new AzureOpenAIOptions(AzureApiVersion);
}