diff --git a/README.md b/README.md index 4443a734..657d18d5 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,20 @@ oc ## Features +### Switch to Azure OpenAI + +By default OpenCommit uses [OpenAI](https://openai.com). + +You could switch to [Azure OpenAI Service](https://learn.microsoft.com/azure/cognitive-services/openai/)🚀 + +```sh +opencommit config set OPENAI_API_TYPE=azure +``` + +Of course need to set 'OPENAI_API_KEY'. And also need to set the +'OPENAI_BASE_PATH' for the endpoint and set the deployment name to +'model'. + ### Switch to GPT-4 By default OpenCommit uses GPT-3.5-turbo (ChatGPT). diff --git a/src/api.ts b/src/api.ts index 3b387334..b0806149 100644 --- a/src/api.ts +++ b/src/api.ts @@ -14,6 +14,7 @@ const config = getConfig(); let apiKey = config?.OPENAI_API_KEY; let basePath = config?.OPENAI_BASE_PATH; let maxTokens = config?.OPENAI_MAX_TOKENS; +let apiType = config?.OPENAI_API_TYPE || 'openai'; const [command, mode] = process.argv.slice(2); @@ -39,8 +40,26 @@ class OpenAi { private openAI!: OpenAIApi; constructor() { - if (basePath) { - this.openAiApiConfiguration.basePath = basePath; + switch (apiType) { + case 'azure': + this.openAiApiConfiguration.baseOptions = { + headers: { + "api-key": apiKey, + }, + params: { + 'api-version': '2023-03-15-preview', + } + }; + if (basePath) { + this.openAiApiConfiguration.basePath = basePath + 'openai/deployments/' + MODEL; + } + break; + case 'openai': + default: + if (basePath) { + this.openAiApiConfiguration.basePath = basePath; + } + break; } this.openAI = new OpenAIApi(this.openAiApiConfiguration); } diff --git a/src/commands/config.ts b/src/commands/config.ts index 9f160348..b9fa8eb7 100644 --- a/src/commands/config.ts +++ b/src/commands/config.ts @@ -12,6 +12,7 @@ export enum CONFIG_KEYS { OPENAI_API_KEY = 'OPENAI_API_KEY', OPENAI_MAX_TOKENS = 'OPENAI_MAX_TOKENS', OPENAI_BASE_PATH = 'OPENAI_BASE_PATH', + OPENAI_API_TYPE = 'OPENAI_API_TYPE', description = 'description', emoji = 'emoji', model = 'model', @@ -42,13 +43,13 @@ export const configValidators = { validateConfig(CONFIG_KEYS.OPENAI_API_KEY, value, 'Cannot be empty'); validateConfig( CONFIG_KEYS.OPENAI_API_KEY, - value.startsWith('sk-'), - 'Must start with "sk-"' + value.startsWith('sk-') || value.match(/^[a-z0-9]{32}$/), + 'Must start with "sk-". Or a valid Azure OpenAI API key' ); validateConfig( CONFIG_KEYS.OPENAI_API_KEY, - value.length === 51, - 'Must be 51 characters long' + value.length === 51 || value.length === 32, + 'Must be 51 or 32 characters long' ); return value; @@ -102,11 +103,26 @@ export const configValidators = { return value; }, + [CONFIG_KEYS.OPENAI_API_TYPE](value: any) { + validateConfig( + CONFIG_KEYS.OPENAI_API_TYPE, + typeof value === 'string', + 'Must be string' + ); + validateConfig( + CONFIG_KEYS.OPENAI_API_TYPE, + value === 'azure' || value === 'openai' || value === '', + `${value} is not supported yet, use 'azure' or 'openai' (default)` + ); + return value; + }, + [CONFIG_KEYS.model](value: any) { validateConfig( - CONFIG_KEYS.OPENAI_BASE_PATH, - value === 'gpt-3.5-turbo' || value === 'gpt-4', - `${value} is not supported yet, use 'gpt-4' or 'gpt-3.5-turbo' (default)` + CONFIG_KEYS.model, + value === 'gpt-3.5-turbo' || value === 'gpt-4' + || ( typeof value === 'string' && value.match(/^[a-zA-Z0-9~\-]{1,63}[a-zA-Z0-9]$/) ), + `${value} is not supported yet, use 'gpt-4' or 'gpt-3.5-turbo' (default) or model deployed name.` ); return value; }