Skip to content

Commit ff3d23c

Browse files
author
Jefferson Pires
committed
Included Azure URL override functionality
1 parent fcf1ad4 commit ff3d23c

File tree

5 files changed

+133
-85
lines changed

5 files changed

+133
-85
lines changed

OpenAI_API/OpenAIAPI.cs

+97-81
Original file line numberDiff line numberDiff line change
@@ -9,97 +9,113 @@
99

1010
namespace OpenAI_API
1111
{
12-
/// <summary>
13-
/// Entry point to the OpenAPI API, handling auth and allowing access to the various API endpoints
14-
/// </summary>
15-
public class OpenAIAPI : IOpenAIAPI
16-
{
17-
/// <summary>
18-
/// Base url for OpenAI
19-
/// for OpenAI, should be "https://api.openai.com/{0}/{1}"
20-
/// for Azure, should be "https://(your-resource-name.openai.azure.com/openai/deployments/(deployment-id)/{1}?api-version={0}"
21-
/// </summary>
22-
public string ApiUrlFormat { get; set; } = "https://api.openai.com/{0}/{1}";
12+
/// <summary>
13+
/// Entry point to the OpenAPI API, handling auth and allowing access to the various API endpoints
14+
/// </summary>
15+
public class OpenAIAPI : IOpenAIAPI
16+
{
17+
/// <summary>
18+
/// Base url for OpenAI
19+
/// for OpenAI, should be "https://api.openai.com/{0}/{1}"
20+
/// for Azure, should be "https://(your-resource-name.openai.azure.com/openai/deployments/(deployment-id)/{1}?api-version={0}"
21+
/// </summary>
22+
public string ApiUrlFormat { get; set; } = "https://api.openai.com/{0}/{1}";
2323

24-
/// <summary>
25-
/// Version of the Rest Api
26-
/// </summary>
27-
public string ApiVersion { get; set; } = "v1";
24+
/// <summary>
25+
/// Version of the Rest Api
26+
/// </summary>
27+
public string ApiVersion { get; set; } = "v1";
2828

29-
/// <summary>
30-
/// The API authentication information to use for API calls
31-
/// </summary>
32-
public APIAuthentication Auth { get; set; }
29+
/// <summary>
30+
/// The API authentication information to use for API calls
31+
/// </summary>
32+
public APIAuthentication Auth { get; set; }
3333

34-
/// <summary>
35-
/// Optionally provide an IHttpClientFactory to create the client to send requests.
36-
/// </summary>
37-
public IHttpClientFactory HttpClientFactory { get; set; }
34+
/// <summary>
35+
/// Optionally provide an IHttpClientFactory to create the client to send requests.
36+
/// </summary>
37+
public IHttpClientFactory HttpClientFactory { get; set; }
3838

39-
/// <summary>
40-
/// Creates a new entry point to the OpenAPI API, handling auth and allowing access to the various API endpoints
41-
/// </summary>
42-
/// <param name="apiKeys">The API authentication information to use for API calls, or <see langword="null"/> to attempt to use the <see cref="APIAuthentication.Default"/>, potentially loading from environment vars or from a config file.</param>
43-
public OpenAIAPI(APIAuthentication apiKeys = null)
44-
{
45-
this.Auth = apiKeys.ThisOrDefault();
46-
Completions = new CompletionEndpoint(this);
47-
Models = new ModelsEndpoint(this);
48-
Files = new FilesEndpoint(this);
49-
Embeddings = new EmbeddingEndpoint(this);
50-
Chat = new ChatEndpoint(this);
51-
Moderation = new ModerationEndpoint(this);
52-
ImageGenerations = new ImageGenerationEndpoint(this);
53-
}
39+
/// <summary>
40+
/// Creates a new entry point to the OpenAPI API, handling auth and allowing access to the various API endpoints
41+
/// </summary>
42+
/// <param name="apiKeys">The API authentication information to use for API calls, or <see langword="null"/> to attempt to use the <see cref="APIAuthentication.Default"/>, potentially loading from environment vars or from a config file.</param>
43+
public OpenAIAPI(APIAuthentication apiKeys = null)
44+
{
45+
this.Auth = apiKeys.ThisOrDefault();
46+
Completions = new CompletionEndpoint(this);
47+
Models = new ModelsEndpoint(this);
48+
Files = new FilesEndpoint(this);
49+
Embeddings = new EmbeddingEndpoint(this);
50+
Chat = new ChatEndpoint(this);
51+
Moderation = new ModerationEndpoint(this);
52+
ImageGenerations = new ImageGenerationEndpoint(this);
53+
}
5454

55-
/// <summary>
56-
/// Instantiates a version of the API for connecting to the Azure OpenAI endpoint instead of the main OpenAI endpoint.
57-
/// </summary>
58-
/// <param name="YourResourceName">The name of your Azure OpenAI Resource</param>
59-
/// <param name="deploymentId">The name of your model deployment. You're required to first deploy a model before you can make calls.</param>
60-
/// <param name="apiKey">The API authentication information to use for API calls, or <see langword="null"/> to attempt to use the <see cref="APIAuthentication.Default"/>, potentially loading from environment vars or from a config file. Currently this library only supports the api-key flow, not the AD-Flow.</param>
61-
/// <returns></returns>
62-
public static OpenAIAPI ForAzure(string YourResourceName, string deploymentId, APIAuthentication apiKey = null)
63-
{
64-
OpenAIAPI api = new OpenAIAPI(apiKey);
65-
api.ApiVersion = "2022-12-01";
66-
api.ApiUrlFormat = $"https://{YourResourceName}.openai.azure.com/openai/deployments/{deploymentId}/" + "{1}?api-version={0}";
67-
return api;
68-
}
55+
/// <summary>
56+
/// Creates an instance of the OpenAIAPI configured for Azure with the specified resource name and deployment ID.
57+
/// </summary>
58+
/// <param name="YourResourceName">The name of the Azure resource where the OpenAI service is deployed.</param>
59+
/// <param name="deploymentId">The ID of the specific deployment of the OpenAI model.</param>
60+
/// <param name="apiKey">The API authentication key used to access the OpenAI service.</param>
61+
/// <returns>
62+
/// An instance of the OpenAIAPI configured for Azure with the provided parameters.
63+
/// </returns>
64+
public static OpenAIAPI ForAzure(string YourResourceName, string deploymentId, APIAuthentication apiKey)
65+
{
66+
return new OpenAIAPI(apiKey)
67+
{
68+
ApiVersion = "2022-12-01",
69+
ApiUrlFormat = $"https://{YourResourceName}.openai.azure.com/openai/deployments/{deploymentId}/" + "{1}?api-version={0}"
70+
};
71+
}
6972

70-
/// <summary>
71-
/// Text generation is the core function of the API. You give the API a prompt, and it generates a completion. The way you “program” the API to do a task is by simply describing the task in plain english or providing a few written examples. This simple approach works for a wide range of use cases, including summarization, translation, grammar correction, question answering, chatbots, composing emails, and much more (see the prompt library for inspiration).
72-
/// </summary>
73-
public ICompletionEndpoint Completions { get; }
73+
/// <summary>
74+
/// Creates an instance of the OpenAIAPI configured for Azure with the specified URL and API key.
75+
/// </summary>
76+
/// <param name="url">The endpoint URL for the Azure OpenAI service.</param>
77+
/// <param name="apiKey">The API authentication key used to access the service.</param>
78+
/// <returns>
79+
/// An instance of OpenAIAPI configured to communicate with the Azure service at the specified URL.
80+
/// </returns>
81+
public static OpenAIAPI ForAzure(string url, APIAuthentication apiKey)
82+
{
83+
return new OpenAIAPI(apiKey) { ApiVersion = string.Empty, ApiUrlFormat = url };
84+
}
7485

75-
/// <summary>
76-
/// The API lets you transform text into a vector (list) of floating point numbers. The distance between two vectors measures their relatedness. Small distances suggest high relatedness and large distances suggest low relatedness.
77-
/// </summary>
78-
public IEmbeddingEndpoint Embeddings { get; }
86+
/// <summary>
87+
/// Text generation is the core function of the API. You give the API a prompt, and it generates a completion. The way you “program” the API to do a task is by simply describing the task in plain english or providing a few written examples. This simple approach works for a wide range of use cases, including summarization, translation, grammar correction, question answering, chatbots, composing emails, and much more (see the prompt library for inspiration).
88+
/// </summary>
89+
public ICompletionEndpoint Completions { get; }
7990

80-
/// <summary>
81-
/// Text generation in the form of chat messages. This interacts with the ChatGPT API.
82-
/// </summary>
83-
public IChatEndpoint Chat { get; }
91+
/// <summary>
92+
/// The API lets you transform text into a vector (list) of floating point numbers. The distance between two vectors measures their relatedness. Small distances suggest high relatedness and large distances suggest low relatedness.
93+
/// </summary>
94+
public IEmbeddingEndpoint Embeddings { get; }
8495

85-
/// <summary>
86-
/// Classify text against the OpenAI Content Policy.
87-
/// </summary>
88-
public IModerationEndpoint Moderation { get; }
96+
/// <summary>
97+
/// Text generation in the form of chat messages. This interacts with the ChatGPT API.
98+
/// </summary>
99+
public IChatEndpoint Chat { get; }
89100

90-
/// <summary>
91-
/// The API endpoint for querying available Engines/models
92-
/// </summary>
93-
public IModelsEndpoint Models { get; }
101+
/// <summary>
102+
/// Classify text against the OpenAI Content Policy.
103+
/// </summary>
104+
public IModerationEndpoint Moderation { get; }
94105

95-
/// <summary>
96-
/// The API lets you do operations with files. You can upload, delete or retrieve files. Files can be used for fine-tuning, search, etc.
97-
/// </summary>
98-
public IFilesEndpoint Files { get; }
106+
/// <summary>
107+
/// The API endpoint for querying available Engines/models
108+
/// </summary>
109+
public IModelsEndpoint Models { get; }
99110

100-
/// <summary>
101-
/// The API lets you do operations with images. Given a prompt and/or an input image, the model will generate a new image.
102-
/// </summary>
103-
public IImageGenerationEndpoint ImageGenerations { get; }
104-
}
111+
/// <summary>
112+
/// The API lets you do operations with files. You can upload, delete or retrieve files. Files can be used for fine-tuning, search, etc.
113+
/// </summary>
114+
public IFilesEndpoint Files { get; }
115+
116+
/// <summary>
117+
/// The API lets you do operations with images. Given a prompt and/or an input image, the model will generate a new image.
118+
/// </summary>
119+
public IImageGenerationEndpoint ImageGenerations { get; }
120+
}
105121
}

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,8 @@ To use this tool it is necessary to connect through the OpenAI API, Azure OpenAI
328328

329329
5 - Set the Azure OpenAI API version. You can check the available versions [here](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#completions).
330330

331+
6 - Optional: Instead of allowing the extension to automatically build the connection URL to Azure OpenAI from the parameters 'Resource Name', 'Deployment Name', and 'API Version', manually define the connection URL through the 'Azure URL Override' parameter, which is ideal for cases where the endpoint for Azure OpenAI is custom for some reason. When a value is set for this parameter, the other parameters ('Resource Name', 'Deployment Name', 'API Version') will be ignored.
332+
331333
<a id="12-3"></a>
332334
### By Azure (Entra ID Authentication)
333335

@@ -417,6 +419,7 @@ You can check your quota here: [https://platform.openai.com/account/usage](https
417419

418420
- Added the ability to request the AI to call REST and SOAP APIs on one or more endpoints through the Turbo Chat window.
419421
- Fixed git-worktree repository detection logic (thanks [Kryeker](https://github.com/Kryeker)).
422+
- Added the new 'Azure URL Override' parameter on options.
420423

421424
### 4.0.0
422425

ReleaseNotes.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- Added the ability to request the AI to call REST and SOAP APIs on one or more endpoints through the Turbo Chat window.
66
- Fixed git-worktree repository detection logic (thanks [Kryeker](https://github.com/Kryeker)).
7+
- Added the new 'Azure URL Override' parameter on options.
78

89
### 4.0.0
910

VisualChatGPTStudioShared/Options/OptionPageGrid.cs

+6
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,12 @@ public class OptionPageGridGeneral : DialogPage
171171
[DefaultValue("2023-05-15")]
172172
public string AzureApiVersion { get; set; } = "2023-05-15";
173173

174+
[Category("Azure")]
175+
[DisplayName("Azure URL Override")]
176+
[Description("Manually define the Azure OpenAI connection URL instead of using 'Resource Name', 'Deployment Name', and 'API Version'. This is useful for custom endpoints. When this parameter is set, the other parameters will be ignored.")]
177+
[DefaultValue("")]
178+
public string AzureUrlOverride { get; set; } = "";
179+
174180
#endregion Azure
175181

176182
#region Azure Entra ID

VisualChatGPTStudioShared/Utils/ApiHandler.cs

+26-4
Original file line numberDiff line numberDiff line change
@@ -356,11 +356,23 @@ private static void CreateAzureApiHandler(OptionPageGridGeneral options)
356356
chatGPTHttpClient.SetProxy(options.Proxy);
357357
}
358358

359-
azureAPI = OpenAIAPI.ForAzure(options.AzureResourceName, options.AzureDeploymentId, options.ApiKey);
359+
if (!string.IsNullOrWhiteSpace(options.AzureUrlOverride))
360+
{
361+
azureAPI = OpenAIAPI.ForAzure(options.AzureUrlOverride, options.ApiKey);
362+
}
363+
else
364+
{
365+
azureAPI = OpenAIAPI.ForAzure(options.AzureResourceName, options.AzureDeploymentId, options.ApiKey);
366+
}
360367

361368
azureAPI.HttpClientFactory = chatGPTHttpClient;
362369
}
363-
else if ((chatGPTHttpClient.Proxy ?? string.Empty) != (options.Proxy ?? string.Empty) || !azureAPI.ApiUrlFormat.Contains(options.AzureResourceName) || !azureAPI.ApiUrlFormat.Contains(options.AzureDeploymentId))
370+
else if ((chatGPTHttpClient.Proxy ?? string.Empty) != (options.Proxy ?? string.Empty) ||
371+
(string.IsNullOrWhiteSpace(options.AzureUrlOverride) &&
372+
(
373+
!azureAPI.ApiUrlFormat.ToLower().Contains(options.AzureResourceName.ToLower()) ||
374+
!azureAPI.ApiUrlFormat.ToLower().Contains(options.AzureDeploymentId.ToLower()))
375+
))
364376
{
365377
azureAPI = null;
366378
CreateAzureApiHandler(options);
@@ -371,9 +383,19 @@ private static void CreateAzureApiHandler(OptionPageGridGeneral options)
371383
azureAPI.Auth.ApiKey = options.ApiKey;
372384
}
373385

374-
if ((azureAPI.ApiVersion ?? string.Empty) != (options.AzureApiVersion ?? string.Empty))
386+
if (!string.IsNullOrWhiteSpace(options.AzureUrlOverride))
387+
{
388+
if (azureAPI.ApiUrlFormat != options.AzureUrlOverride)
389+
{
390+
azureAPI.ApiUrlFormat = options.AzureUrlOverride;
391+
}
392+
}
393+
else
375394
{
376-
azureAPI.ApiVersion = options.AzureApiVersion;
395+
if ((azureAPI.ApiVersion ?? string.Empty) != (options.AzureApiVersion ?? string.Empty))
396+
{
397+
azureAPI.ApiVersion = options.AzureApiVersion;
398+
}
377399
}
378400
}
379401

0 commit comments

Comments
 (0)