| import { |
| genAzureChatCompletion, |
| getAzureCredentials, |
| constructAzureURL, |
| sanitizeModelName, |
| genAzureEndpoint, |
| } from './azure'; |
| import type { GenericClient } from '~/types'; |
|
|
| describe('sanitizeModelName', () => { |
| test('removes periods from the model name', () => { |
| const sanitized = sanitizeModelName('model.name'); |
| expect(sanitized).toBe('modelname'); |
| }); |
|
|
| test('leaves model name unchanged if no periods are present', () => { |
| const sanitized = sanitizeModelName('modelname'); |
| expect(sanitized).toBe('modelname'); |
| }); |
| }); |
|
|
| describe('genAzureEndpoint', () => { |
| test('generates correct endpoint URL', () => { |
| const url = genAzureEndpoint({ |
| azureOpenAIApiInstanceName: 'instanceName', |
| azureOpenAIApiDeploymentName: 'deploymentName', |
| }); |
| expect(url).toBe('https://instanceName.openai.azure.com/openai/deployments/deploymentName'); |
| }); |
| }); |
|
|
| describe('genAzureChatCompletion', () => { |
| |
| test('prefers model name over deployment name when both are provided and feature enabled', () => { |
| process.env.AZURE_USE_MODEL_AS_DEPLOYMENT_NAME = 'true'; |
| const url = genAzureChatCompletion( |
| { |
| azureOpenAIApiInstanceName: 'instanceName', |
| azureOpenAIApiDeploymentName: 'deploymentName', |
| azureOpenAIApiVersion: 'v1', |
| }, |
| 'modelName', |
| ); |
| expect(url).toBe( |
| 'https://instanceName.openai.azure.com/openai/deployments/modelName/chat/completions?api-version=v1', |
| ); |
| }); |
|
|
| |
| test('uses deployment name when model name is not provided', () => { |
| const url = genAzureChatCompletion({ |
| azureOpenAIApiInstanceName: 'instanceName', |
| azureOpenAIApiDeploymentName: 'deploymentName', |
| azureOpenAIApiVersion: 'v1', |
| }); |
| expect(url).toBe( |
| 'https://instanceName.openai.azure.com/openai/deployments/deploymentName/chat/completions?api-version=v1', |
| ); |
| }); |
|
|
| |
| test('uses model name when deployment name is not provided and feature enabled', () => { |
| process.env.AZURE_USE_MODEL_AS_DEPLOYMENT_NAME = 'true'; |
| const url = genAzureChatCompletion( |
| { |
| azureOpenAIApiInstanceName: 'instanceName', |
| azureOpenAIApiVersion: 'v1', |
| }, |
| 'modelName', |
| ); |
| expect(url).toBe( |
| 'https://instanceName.openai.azure.com/openai/deployments/modelName/chat/completions?api-version=v1', |
| ); |
| }); |
|
|
| |
| test('throws error if neither deployment name nor model name is provided', () => { |
| expect(() => { |
| genAzureChatCompletion({ |
| azureOpenAIApiInstanceName: 'instanceName', |
| azureOpenAIApiVersion: 'v1', |
| }); |
| }).toThrow( |
| 'Either a model name with the `AZURE_USE_MODEL_AS_DEPLOYMENT_NAME` setting or a deployment name must be provided if `AZURE_OPENAI_BASEURL` is omitted.', |
| ); |
| }); |
|
|
| |
| test('ignores model name and uses deployment name when feature is disabled', () => { |
| process.env.AZURE_USE_MODEL_AS_DEPLOYMENT_NAME = 'false'; |
| const url = genAzureChatCompletion( |
| { |
| azureOpenAIApiInstanceName: 'instanceName', |
| azureOpenAIApiDeploymentName: 'deploymentName', |
| azureOpenAIApiVersion: 'v1', |
| }, |
| 'modelName', |
| ); |
| expect(url).toBe( |
| 'https://instanceName.openai.azure.com/openai/deployments/deploymentName/chat/completions?api-version=v1', |
| ); |
| }); |
|
|
| |
| test('sanitizes model name when used in URL', () => { |
| process.env.AZURE_USE_MODEL_AS_DEPLOYMENT_NAME = 'true'; |
| const url = genAzureChatCompletion( |
| { |
| azureOpenAIApiInstanceName: 'instanceName', |
| azureOpenAIApiVersion: 'v1', |
| }, |
| 'model.name', |
| ); |
| expect(url).toBe( |
| 'https://instanceName.openai.azure.com/openai/deployments/modelname/chat/completions?api-version=v1', |
| ); |
| }); |
|
|
| |
| test('updates client with sanitized model name when provided and feature enabled', () => { |
| process.env.AZURE_USE_MODEL_AS_DEPLOYMENT_NAME = 'true'; |
| const clientMock = { azure: {} } as GenericClient; |
| const url = genAzureChatCompletion( |
| { |
| azureOpenAIApiInstanceName: 'instanceName', |
| azureOpenAIApiVersion: 'v1', |
| }, |
| 'model.name', |
| clientMock, |
| ); |
| expect(url).toBe( |
| 'https://instanceName.openai.azure.com/openai/deployments/modelname/chat/completions?api-version=v1', |
| ); |
| expect(clientMock.azure.azureOpenAIApiDeploymentName).toBe('modelname'); |
| }); |
|
|
| |
| test('does not update client when model name is not provided', () => { |
| const clientMock = { azure: {} } as GenericClient; |
| const url = genAzureChatCompletion( |
| { |
| azureOpenAIApiInstanceName: 'instanceName', |
| azureOpenAIApiDeploymentName: 'deploymentName', |
| azureOpenAIApiVersion: 'v1', |
| }, |
| undefined, |
| clientMock, |
| ); |
| expect(url).toBe( |
| 'https://instanceName.openai.azure.com/openai/deployments/deploymentName/chat/completions?api-version=v1', |
| ); |
| expect(clientMock.azure.azureOpenAIApiDeploymentName).toBeUndefined(); |
| }); |
|
|
| |
| test('does not update client when feature is disabled', () => { |
| process.env.AZURE_USE_MODEL_AS_DEPLOYMENT_NAME = 'false'; |
| const clientMock = { azure: {} } as GenericClient; |
| const url = genAzureChatCompletion( |
| { |
| azureOpenAIApiInstanceName: 'instanceName', |
| azureOpenAIApiDeploymentName: 'deploymentName', |
| azureOpenAIApiVersion: 'v1', |
| }, |
| 'modelName', |
| clientMock, |
| ); |
| expect(url).toBe( |
| 'https://instanceName.openai.azure.com/openai/deployments/deploymentName/chat/completions?api-version=v1', |
| ); |
| expect(clientMock.azure.azureOpenAIApiDeploymentName).toBeUndefined(); |
| }); |
|
|
| |
| afterEach(() => { |
| delete process.env.AZURE_USE_MODEL_AS_DEPLOYMENT_NAME; |
| }); |
| }); |
|
|
| describe('getAzureCredentials', () => { |
| beforeEach(() => { |
| process.env.AZURE_API_KEY = 'testApiKey'; |
| process.env.AZURE_OPENAI_API_INSTANCE_NAME = 'instanceName'; |
| process.env.AZURE_OPENAI_API_DEPLOYMENT_NAME = 'deploymentName'; |
| process.env.AZURE_OPENAI_API_VERSION = 'v1'; |
| }); |
|
|
| test('retrieves Azure OpenAI API credentials from environment variables', () => { |
| const credentials = getAzureCredentials(); |
| expect(credentials).toEqual({ |
| azureOpenAIApiKey: 'testApiKey', |
| azureOpenAIApiInstanceName: 'instanceName', |
| azureOpenAIApiDeploymentName: 'deploymentName', |
| azureOpenAIApiVersion: 'v1', |
| }); |
| }); |
| }); |
|
|
| describe('constructAzureURL', () => { |
| test('replaces both placeholders when both properties are provided', () => { |
| const url = constructAzureURL({ |
| baseURL: 'https://example.com/${INSTANCE_NAME}/${DEPLOYMENT_NAME}', |
| azureOptions: { |
| azureOpenAIApiInstanceName: 'instance1', |
| azureOpenAIApiDeploymentName: 'deployment1', |
| }, |
| }); |
| expect(url).toBe('https://example.com/instance1/deployment1'); |
| }); |
|
|
| test('replaces only INSTANCE_NAME when only azureOpenAIApiInstanceName is provided', () => { |
| const url = constructAzureURL({ |
| baseURL: 'https://example.com/${INSTANCE_NAME}/${DEPLOYMENT_NAME}', |
| azureOptions: { |
| azureOpenAIApiInstanceName: 'instance2', |
| }, |
| }); |
| expect(url).toBe('https://example.com/instance2/'); |
| }); |
|
|
| test('replaces only DEPLOYMENT_NAME when only azureOpenAIApiDeploymentName is provided', () => { |
| const url = constructAzureURL({ |
| baseURL: 'https://example.com/${INSTANCE_NAME}/${DEPLOYMENT_NAME}', |
| azureOptions: { |
| azureOpenAIApiDeploymentName: 'deployment2', |
| }, |
| }); |
| expect(url).toBe('https://example.com//deployment2'); |
| }); |
|
|
| test('does not replace any placeholders when azure object is empty', () => { |
| const url = constructAzureURL({ |
| baseURL: 'https://example.com/${INSTANCE_NAME}/${DEPLOYMENT_NAME}', |
| azureOptions: {}, |
| }); |
| expect(url).toBe('https://example.com//'); |
| }); |
|
|
| test('returns baseURL as is when `azureOptions` object is not provided', () => { |
| const url = constructAzureURL({ |
| baseURL: 'https://example.com/${INSTANCE_NAME}/${DEPLOYMENT_NAME}', |
| }); |
| expect(url).toBe('https://example.com/${INSTANCE_NAME}/${DEPLOYMENT_NAME}'); |
| }); |
|
|
| test('returns baseURL as is when no placeholders are set', () => { |
| const url = constructAzureURL({ |
| baseURL: 'https://example.com/my_custom_instance/my_deployment', |
| azureOptions: { |
| azureOpenAIApiInstanceName: 'instance1', |
| azureOpenAIApiDeploymentName: 'deployment1', |
| }, |
| }); |
| expect(url).toBe('https://example.com/my_custom_instance/my_deployment'); |
| }); |
|
|
| test('returns regular Azure OpenAI baseURL with placeholders set', () => { |
| const baseURL = |
| 'https://${INSTANCE_NAME}.openai.azure.com/openai/deployments/${DEPLOYMENT_NAME}'; |
| const url = constructAzureURL({ |
| baseURL, |
| azureOptions: { |
| azureOpenAIApiInstanceName: 'instance1', |
| azureOpenAIApiDeploymentName: 'deployment1', |
| }, |
| }); |
| expect(url).toBe('https://instance1.openai.azure.com/openai/deployments/deployment1'); |
| }); |
| }); |
|
|