All files / api/src/ai-providers/azure-openai utils.ts

93.5% Statements 72/77
86.66% Branches 13/15
100% Functions 3/3
93.5% Lines 72/77

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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        1x 1x   5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x   5x 5x 5x 5x 5x 5x 5x   5x 1x 1x 1x 3x 3x 3x 2x 2x 5x   6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 1x 1x 1x 5x 5x 6x 1x 1x 1x 1x 6x   1x 3x 3x 3x 3x             3x 3x 3x   3x 2x 2x   3x 3x  
import type { AzureOpenAIFinetuneResponse } from '@api/ai-providers/azure-openai/types';
import type { ResponseTransformFunction } from '@shared/types/ai-providers/config';
import type { ErrorResponseBody } from '@shared/types/api/response';
import type { CreateFineTuningJobResponseBody } from '@shared/types/api/routes/fine-tuning-api';
import { AIProvider } from '@shared/types/constants';
import { openAIErrorResponseTransform } from '../openai/utils';
 
export async function getAccessTokenFromEntraId(
  tenantId: string,
  clientId: string,
  clientSecret: string,
  scope = 'https://cognitiveservices.azure.com/.default',
): Promise<string | undefined> {
  try {
    const url = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
    const params = new URLSearchParams({
      client_id: clientId,
      client_secret: clientSecret,
      scope: scope,
      grant_type: 'client_credentials',
    });
 
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
      },
      body: params,
    });
 
    if (!response.ok) {
      const errorMessage = await response.text();
      throw new Error(`Error from Entra ${errorMessage}`);
    }
    const data: { access_token: string } = await response.json();
    return data.access_token;
  } catch (error) {
    throw new Error(`Error getting access token from Entra ID: ${error}`);
  }
}
 
export async function getAzureManagedIdentityToken(
  resource: string,
  clientId?: string,
): Promise<string | undefined> {
  try {
    const response = await fetch(
      `http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=${encodeURIComponent(resource)}${clientId ? `&client_id=${encodeURIComponent(clientId)}` : ''}`,
      {
        method: 'GET',
        headers: {
          Metadata: 'true',
        },
      },
    );
    if (!response.ok) {
      const errorMessage = await response.text();
      throw new Error(`Error from Managed ${errorMessage}`);
    }
    const data: { access_token: string } = await response.json();
    return data.access_token;
  } catch (error) {
    throw new Error(
      `Error getting access token from Managed Identity: ${error}`,
    );
  }
}
 
export const azureOpenAIFinetuneResponseTransform: ResponseTransformFunction = (
  aiProviderResponseBody,
  aiProviderResponseStatus,
) => {
  if (aiProviderResponseStatus !== 200 && 'error' in aiProviderResponseBody) {
    return openAIErrorResponseTransform(
      aiProviderResponseBody as ErrorResponseBody,
      AIProvider.AZURE_OPENAI,
    );
  }
 
  const _response = {
    ...aiProviderResponseBody,
  } as AzureOpenAIFinetuneResponse;
 
  if (['created', 'pending'].includes(_response.status)) {
    _response.status = 'queued';
  }
 
  return _response as CreateFineTuningJobResponseBody;
};