mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-23 10:46:12 +01:00
🪶 feat: Add Support for Azure OpenAI Base URL (#1596)
* refactor(extractBaseURL): add handling for all possible Cloudflare AI Gateway endpoints * chore: added endpointoption todo for updating type and optimizing handling app-wide * feat(azureUtils): - `genAzureChatCompletion`: allow optional client pass to update azure property - `constructAzureURL`: optionally replace placeholders for instance and deployment names of an azure baseURL - add tests for module * refactor(extractBaseURL): return entire input when cloudflare `azure-openai` suffix detected - also add more tests for both construct and extract URL * refactor(genAzureChatCompletion): only allow omitting instance name if baseURL is not set * refactor(initializeClient): determine `reverseProxyUrl` based on endpoint (azure or openai) * refactor: utitlize `constructAzureURL` when `AZURE_OPENAI_BASEURL` is set * docs: update docs on `AZURE_OPENAI_BASEURL` * fix(ci): update expected error message for `azureUtils` tests
This commit is contained in:
parent
5c94f5330a
commit
e73608ba46
12 changed files with 532 additions and 47 deletions
|
|
@ -2,8 +2,13 @@ const OpenAI = require('openai');
|
|||
const { HttpsProxyAgent } = require('https-proxy-agent');
|
||||
const { getResponseSender, ImageDetailCost, ImageDetail } = require('librechat-data-provider');
|
||||
const { encoding_for_model: encodingForModel, get_encoding: getEncoding } = require('tiktoken');
|
||||
const {
|
||||
getModelMaxTokens,
|
||||
genAzureChatCompletion,
|
||||
extractBaseURL,
|
||||
constructAzureURL,
|
||||
} = require('~/utils');
|
||||
const { encodeAndFormat, validateVisionModel } = require('~/server/services/Files/images');
|
||||
const { getModelMaxTokens, genAzureChatCompletion, extractBaseURL } = require('~/utils');
|
||||
const { truncateText, formatMessage, CUT_OFF_PROMPT } = require('./prompts');
|
||||
const { handleOpenAIErrors } = require('./tools/util');
|
||||
const spendTokens = require('~/models/spendTokens');
|
||||
|
|
@ -32,6 +37,7 @@ class OpenAIClient extends BaseClient {
|
|||
? options.contextStrategy.toLowerCase()
|
||||
: 'discard';
|
||||
this.shouldSummarize = this.contextStrategy === 'summarize';
|
||||
/** @type {AzureOptions} */
|
||||
this.azure = options.azure || false;
|
||||
this.setOptions(options);
|
||||
}
|
||||
|
|
@ -104,10 +110,10 @@ class OpenAIClient extends BaseClient {
|
|||
}
|
||||
|
||||
if (this.azure && process.env.AZURE_OPENAI_DEFAULT_MODEL) {
|
||||
this.azureEndpoint = genAzureChatCompletion(this.azure, this.modelOptions.model);
|
||||
this.azureEndpoint = genAzureChatCompletion(this.azure, this.modelOptions.model, this);
|
||||
this.modelOptions.model = process.env.AZURE_OPENAI_DEFAULT_MODEL;
|
||||
} else if (this.azure) {
|
||||
this.azureEndpoint = genAzureChatCompletion(this.azure, this.modelOptions.model);
|
||||
this.azureEndpoint = genAzureChatCompletion(this.azure, this.modelOptions.model, this);
|
||||
}
|
||||
|
||||
const { model } = this.modelOptions;
|
||||
|
|
@ -711,7 +717,7 @@ class OpenAIClient extends BaseClient {
|
|||
|
||||
if (this.azure) {
|
||||
modelOptions.model = process.env.AZURE_OPENAI_DEFAULT_MODEL ?? modelOptions.model;
|
||||
this.azureEndpoint = genAzureChatCompletion(this.azure, modelOptions.model);
|
||||
this.azureEndpoint = genAzureChatCompletion(this.azure, modelOptions.model, this);
|
||||
}
|
||||
|
||||
const instructionsPayload = [
|
||||
|
|
@ -949,7 +955,12 @@ ${convo}
|
|||
// Azure does not accept `model` in the body, so we need to remove it.
|
||||
delete modelOptions.model;
|
||||
|
||||
opts.baseURL = this.azureEndpoint.split('/chat')[0];
|
||||
opts.baseURL = this.langchainProxy
|
||||
? constructAzureURL({
|
||||
baseURL: this.langchainProxy,
|
||||
azure: this.azure,
|
||||
})
|
||||
: this.azureEndpoint.split(/\/(chat|completion)/)[0];
|
||||
opts.defaultQuery = { 'api-version': this.azure.azureOpenAIApiVersion };
|
||||
opts.defaultHeaders = { ...opts.defaultHeaders, 'api-key': this.apiKey };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
const { ChatOpenAI } = require('langchain/chat_models/openai');
|
||||
const { sanitizeModelName } = require('../../../utils');
|
||||
const { isEnabled } = require('../../../server/utils');
|
||||
const { sanitizeModelName, constructAzureURL } = require('~/utils');
|
||||
const { isEnabled } = require('~/server/utils');
|
||||
|
||||
/**
|
||||
* Creates a new instance of a language model (LLM) for chat interactions.
|
||||
|
|
@ -36,6 +36,7 @@ function createLLM({
|
|||
apiKey: openAIApiKey,
|
||||
};
|
||||
|
||||
/** @type {AzureOptions} */
|
||||
let azureOptions = {};
|
||||
if (azure) {
|
||||
const useModelName = isEnabled(process.env.AZURE_USE_MODEL_AS_DEPLOYMENT_NAME);
|
||||
|
|
@ -53,8 +54,12 @@ function createLLM({
|
|||
modelOptions.modelName = process.env.AZURE_OPENAI_DEFAULT_MODEL;
|
||||
}
|
||||
|
||||
// console.debug('createLLM: configOptions');
|
||||
// console.debug(configOptions);
|
||||
if (azure && configOptions.basePath) {
|
||||
configOptions.basePath = constructAzureURL({
|
||||
baseURL: configOptions.basePath,
|
||||
azure: azureOptions,
|
||||
});
|
||||
}
|
||||
|
||||
return new ChatOpenAI(
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue