Public/Invoke-PSAOAIChatCompletion.ps1

function Invoke-PSAOAIChatCompletion {
    <#
    .SYNOPSIS
    This function facilitates interaction with an Azure OpenAI chatbot by sending an API request and retrieving the chatbot's response.
 
    .DESCRIPTION
    Invoke-AzureOpenAIChatCompletion is a function that establishes communication with an Azure OpenAI chatbot by sending an API request and receiving the chatbot's response. It provides users with the ability to customize their messages and tweak parameters such as temperature, frequency penalty, and others to shape the chatbot's responses.
 
    .PARAMETER APIVersion
    Defines the version of the Azure OpenAI API to be utilized.
 
    .PARAMETER Endpoint
    Specifies the endpoint URL for the Azure OpenAI API.
 
    .PARAMETER Deployment
    Denotes the name of the OpenAI deployment to be utilized.
 
    .PARAMETER User
    Identifies the user initiating the API request.
 
    .PARAMETER Temperature
    Adjusts the temperature parameter for the API request, influencing the unpredictability of the chatbot's responses.
 
    .PARAMETER N
    Sets the number of messages to be generated for the API request.
 
    .PARAMETER FrequencyPenalty
    Adjusts the frequency penalty parameter for the API request, influencing the chatbot's preference for less frequently used words.
 
    .PARAMETER PresencePenalty
    Adjusts the presence penalty parameter for the API request, influencing the chatbot's preference for contextually relevant words.
 
    .PARAMETER TopP
    Adjusts the top-p parameter for the API request, influencing the diversity of the chatbot's responses.
 
    .PARAMETER Stop
    Sets the stop parameter for the API request, indicating when the chatbot should cease generating a response.
 
    .PARAMETER Stream
    Adjusts the stream parameter for the API request, determining whether the chatbot should stream its responses.
 
    .PARAMETER SystemPromptFilePath
    Specifies the path of the file containing the system prompt.
     
    .PARAMETER SystemPrompt
    Identifies the system prompt.
 
    .PARAMETER OneTimeUserPrompt
    Identifies a one-time user prompt.
 
    .PARAMETER logfile
    Identifies the log file.
 
    .PARAMETER usermessage
    Identifies the user message.
 
    .PARAMETER usermessagelogfile
    Identifies the user message log file.
 
    .PARAMETER Precise
    Indicates whether the precise parameter is enabled.
 
    .PARAMETER Creative
    Indicates whether the creative parameter is enabled.
 
    .PARAMETER simpleresponse
    Indicates whether the simpleresponse parameter is enabled.
 
    .EXAMPLE
    PS C:\> Invoke-PSAOAIChatCompletion -APIVersion "2023-06-01-preview" -Endpoint "https://example.openai.azure.com" -Deployment "example_model_gpt35_!" -User "BobbyK" -Temperature 0.6 -N 1 -FrequencyPenalty 0 -PresencePenalty 0 -TopP 0 -Stop $null -Stream $false
 
    This example illustrates how to send an API request to an Azure OpenAI chatbot and receive the response message.
 
    .NOTES
    Author: Wojciech Napierala
    Date: 2023-06-27
     
    .LINK
    https://learn.microsoft.com/en-us/azure/ai-services/openai/
    #>

    [CmdletBinding(DefaultParameterSetName = 'SystemPrompt_Mode')]
    param(
        [Parameter(Position = 0, ParameterSetName = 'SystemPrompt_Mode', Mandatory = $true)]
        [Parameter(Position = 0, ParameterSetName = 'SystemPrompt_TempTop', Mandatory = $true)]
        [string]$SystemPrompt,
        [Parameter(ParameterSetName = 'SystemPromptFileName_Mode', Mandatory = $true)]
        [Parameter(ParameterSetName = 'SystemPromptFileName_TempTop', Mandatory = $true)]
        [string]$SystemPromptFileName,
        [Parameter(Position = 1, Mandatory = $true, ValueFromPipeline = $true)]
        [string]$usermessage,
        [Parameter(Position = 3, Mandatory = $false)]
        [switch]$OneTimeUserPrompt,
        [Parameter(Position = 2, ParameterSetName = 'SystemPrompt_Mode', Mandatory = $false)]
        [Parameter(Position = 2, ParameterSetName = 'SystemPromptFileName_Mode', Mandatory = $false)]
        [ValidateSet("UltraPrecise", "Precise", "Focused", "Balanced", "Informative", "Creative", "Surreal")]
        [string]$Mode,
        [Parameter(ParameterSetName = 'SystemPrompt_TempTop', Mandatory = $false)]
        [Parameter(ParameterSetName = 'SystemPromptFileName_TempTop', Mandatory = $false)]
        [Parameter(ParameterSetName = 'temptop')]
        [double]$Temperature = 1,
        [Parameter(ParameterSetName = 'SystemPrompt_TempTop', Mandatory = $false)]
        [Parameter(ParameterSetName = 'SystemPromptFileName_TempTop', Mandatory = $false)]
        [Parameter(ParameterSetName = 'temptop')]
        [double]$TopP = 1,
        [Parameter(Mandatory = $false)]
        [string]$logfile,
        [Parameter(Mandatory = $false)]
        [string]$usermessagelogfile,
        [Parameter(Position = 4, Mandatory = $false)]
        [switch]$simpleresponse,
        [Parameter(Mandatory = $false)]
        [string]$APIVersion = (Get-EnvironmentVariable -VariableName $script:API_AZURE_OPENAI_APIVERSION),
        [Parameter(Mandatory = $false)]
        [string]$Endpoint = (Set-EnvironmentVariable -VariableName $script:API_AZURE_OPENAI_ENDPOINT -PromptMessage "Please enter the endpoint"),
        [Parameter(Position = 6, Mandatory = $false)]
        [string]$Deployment = (Set-EnvironmentVariable -VariableName $script:API_AZURE_OPENAI_CC_DEPLOYMENT -PromptMessage "Please enter the deployment"),
        [Parameter(Position = 5, Mandatory = $false)]
        [string]$User = "",
        [Parameter(Mandatory = $false)]
        [int]$N = 1,
        [Parameter(Mandatory = $false)]
        [double]$FrequencyPenalty = 0,
        [Parameter(Mandatory = $false)]
        [double]$PresencePenalty = 0,
        [Parameter(Mandatory = $false)]
        [string]$Stop = $null,
        [Parameter(Mandatory = $false)]
        [bool]$Stream = $false
    )

    # Function to assemble system and user messages
    function Get-Messages {
        <#
        .SYNOPSIS
        Assembles system and user messages into a structured array.
         
        .DESCRIPTION
        This function accepts a system message and a user message as parameters. It then structures these messages into an array, with each message represented as a hashtable with 'role' and 'content' keys.
         
        .PARAMETER system_message
        The system message to be included in the chat. This parameter is mandatory.
         
        .PARAMETER UserMessage
        The user message to be included in the chat. This parameter is mandatory.
         
        .EXAMPLE
        Get-Messages -system_message "Hello, how can I assist you today?" -UserMessage "I need help with my code."
         
        .OUTPUTS
        Array of hashtables, each representing a system or user message.
        #>
    
        param(
            [Parameter(Mandatory = $true)]
            [string]$system_message,
            [Parameter(Mandatory = $true)]
            [string]$UserMessage
        )

        # Log the system and user messages for debugging purposes
        Write-Verbose "System message in Get-Messages: $system_message"
        Write-Verbose "User message in Get-Messages: $UserMessage"
            
        # Return an array of hashtables representing the system and user messages
        return @(
            @{
                "role"    = "system"
                "content" = $system_message
            },
            @{
                "role"    = "user"
                "content" = $UserMessage
            }
        )
    }

    
    # Function to output the response message
    function Show-ResponseMessage {
        <#
        .SYNOPSIS
        This function outputs the response message to the console.
         
        .DESCRIPTION
        Show-ResponseMessage is a function that takes in a content and a stream type and outputs the response message.
        The output format can be simplified by using the -simpleresponse switch.
         
        .PARAMETER content
        The content to be displayed. This parameter is mandatory.
         
        .PARAMETER stream
        The stream type of the content. This parameter is mandatory.
         
        .PARAMETER simpleresponse
        A switch parameter. If used, the function will return only the content, without the stream type.
         
        .EXAMPLE
        Show-ResponseMessage -content "Hello, how can I assist you today?" -stream "system"
         
        .EXAMPLE
        Show-ResponseMessage -content "Hello, how can I assist you today?" -stream "system" -simpleresponse
         
        .OUTPUTS
        String. This function outputs the response message to the console.
        #>
 
        param(
            [Parameter(Mandatory = $true)]
            [string]$content, # The content to be displayed

            [Parameter(Mandatory = $true)]
            [string]$stream, # The stream type of the content

            [switch]$simpleresponse # A switch to simplify the response output
        )
    
        # Check if the simpleresponse switch is used
        if (-not $simpleresponse) {
            # Return the response message with the stream type
            return ("Response assistant ($stream):`n${content}")
        }
        else {
            # Return only the content
            return $content
        }
    }
    
    function Show-PromptFilterResults {
        <#
        .SYNOPSIS
        Displays the results of the prompt filter.
 
        .DESCRIPTION
        This function takes a response object as input and iterates through the 'prompt_filter_results' property of the object.
        For each item in 'prompt_filter_results', it extracts the 'content_filter_results' and converts it to a string.
        The function then outputs the 'content_filter_results' for each 'prompt_index'.
 
        .PARAMETER response
        A PSCustomObject that contains the prompt filter results to be displayed. This parameter is mandatory.
 
        .EXAMPLE
        Show-PromptFilterResults -response $response
 
        .OUTPUTS
        String. Outputs the 'content_filter_results' for each 'prompt_index' in the console.
        #>
 
        param(
            [Parameter(Mandatory = $true)]
            [PSCustomObject]$response # The response object containing the prompt filter results
        )
    
        # Print an empty line for better readability
        Write-Host ""
        # Print the title for the output
        Write-Host "Prompt Filter Results:"

        # Iterate through each item in the 'prompt_filter_results' property of the response object
        foreach ($result in $response.prompt_filter_results) {
            # Extract the 'content_filter_results' property from the current item
            $contentFilterResults = $result.content_filter_results

            # Convert the 'content_filter_results' to a string
            $contentFilterObject = $contentFilterResults | Out-String

            # Print the 'content_filter_results' for the current 'prompt_index'
            Write-Host "Results for prompt_index $($result.prompt_index):"
            return $contentFilterObject
        }
    }
        
    function Write-LogMessage {
        <#
    .SYNOPSIS
    This function writes a log message to a specified log file.
 
    .DESCRIPTION
    The Write-LogMessage function takes in a message, a log file path, and an optional log level (default is "INFO").
    It then writes the message to the log file with a timestamp and the specified log level.
 
    .PARAMETER Message
    The message to be logged. This parameter is mandatory.
 
    .PARAMETER LogFile
    The path of the log file where the message will be written. This parameter is mandatory.
 
    .PARAMETER Level
    The level of the log message (e.g., "INFO", "VERBOSE", "ERROR"). This parameter is optional and defaults to "INFO".
 
    .EXAMPLE
    Write-LogMessage -Message "System prompt:`n$system_message" -LogFile $logfile -Level "VERBOSE"
    #>

        param(
            [Parameter(Mandatory = $true)]
            [string]$Message,
            [Parameter(Mandatory = $true)]
            [string]$LogFile,
            [Parameter(Mandatory = $false)]
            [string]$Level = "INFO"
        )
        # Get the current date and time in the format "yyyy-MM-dd HH:mm:ss"
        $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"

        # Format the log entry
        $logEntry = "[$timestamp [$Level]] $Message"

        # Write the log entry to the log file
        Add-Content -Path $LogFile -Value $logEntry -Force
    }

    while (-not $APIVersion) {
        $APIVersion = Set-EnvironmentVariable -VariableName $script:API_AZURE_OPENAI_APIVERSION -PromptMessage "Please enter the API Version"
    }

    while (-not $Endpoint) {
        # Get the endpoint from the environment variable
        $Endpoint = Set-EnvironmentVariable -VariableName $script:API_AZURE_OPENAI_ENDPOINT -PromptMessage "Please enter the Endpoint"
    }

    while (-not $Deployment) {
        # Get the deployment from the environment variable
        $Deployment = Set-EnvironmentVariable -VariableName $script:API_AZURE_OPENAI_CC_DEPLOYMENT -PromptMessage "Please enter the Deployment"
    }

    Write-Verbose "APIKEY: $ApiKey"
    while ([string]::IsNullOrEmpty($ApiKey)) {
        if (-not ($ApiKey = Set-EnvironmentVariable -VariableName $script:API_AZURE_OPENAI_KEY -PromptMessage "Please enter the API Key" -Secure)) {
            Set-EnvironmentVariable -VariableName $script:API_AZURE_OPENAI_KEY -VariableValue $null
            $ApiKey = Set-EnvironmentVariable -VariableName $script:API_AZURE_OPENAI_KEY -PromptMessage "Please enter the API Key" -Secure
        }
        
    }

    switch ($Mode) {
        "Precise" {
            $UltraPrecise = $false
            $Precise = $true
            $Focused = $false
            $Balanced = $false
            $Informative = $false
            $Creative = $false
            $Surreal = $false                
        }
        "Creative" {
            $UltraPrecise = $false
            $Precise = $false
            $Focused = $false
            $Balanced = $false
            $Informative = $false
            $Creative = $true
            $Surreal = $false                
        }
        "UltraPrecise" {
            $UltraPrecise = $true
            $Precise = $false
            $Focused = $false
            $Balanced = $false
            $Informative = $false
            $Creative = $false
            $Surreal = $false                
        }
        "Focused" {
            $UltraPrecise = $false
            $Precise = $false
            $Focused = $true
            $Balanced = $false
            $Informative = $false
            $Creative = $false
            $Surreal = $false                
        }
        "Balanced" {
            $UltraPrecise = $false
            $Precise = $false
            $Focused = $false
            $Balanced = $true
            $Informative = $false
            $Creative = $false
            $Surreal = $false                
        }
        "Informative" {
            $UltraPrecise = $false
            $Precise = $false
            $Focused = $false
            $Balanced = $false
            $Informative = $true
            $Creative = $false
            $Surreal = $false                
        }
        "Surreal" {
            $UltraPrecise = $false
            $Precise = $false
            $Focused = $false
            $Balanced = $false
            $Informative = $false
            $Creative = $false
            $Surreal = $true                
        }
        default {
            # Code for default case
            [double]$Temperature = $Temperature
            [double]$TopP = $TopP
        }
    }

    # Adjust parameters based on switches.
    #if ($Creative -or $Precise) {
    if ($UltraPrecise -or $Precise -or $Focused -or $Balanced -or $Informative -or $Creative -or $Surreal) {
        $parameters = Set-ParametersForSwitches -Creative:$Creative -Precise:$Precise -UltraPrecise:$UltraPrecise -Focused:$Focused -Balanced:$Balanced -Informative:$Informative -Surreal:$Surreal
        $Temperature = $parameters['Temperature']
        $TopP = $parameters['TopP']
    }
    elseif ($Temperature -and $TopP) {
        $parameters = @{
            'Temperature' = $Temperature
            'TopP'        = $TopP
        }
    }
    else {
        $parameters = @{
            'Temperature' = $Temperature
            'TopP'        = $TopP
        }
    }


    if ($OneTimeUserPrompt) {
        [string]$OneTimeUserPrompt = ($usermessage | out-string)
    }

    if ($VerbosePreference -eq "Continue") {
        Write-Host "APIVersion: $APIVersion"
        Write-Host "Endpoint: $Endpoint"
        Write-Host "Deployment: $Deployment"
        Write-Host "Mode: $Mode"
        Write-Host "SystemPromptFileName: $(if($SystemPromptFileName){"exists"}else{"does not exist"})"
        Write-Host "SystemPrompt: $(if($SystemPrompt){"exists"}else{"does not exist"})"
        Write-Host "usermessage: $(if($usermessage){"exists"}else{"does not exist"})"
        Write-Host "OneTimeUserPrompt: $(if($OneTimeUserPrompt){"true"}else{"false"})"
        Write-Host "Temperature: $Temperature"
        Write-Host "TopP: $TopP"
        Write-Host "FrequencyPenalty: $FrequencyPenalty"
        Write-Host "PresencePenalty: $PresencePenalty"
        Write-Host "User: $User"
        Write-Host "N: $N"
        Write-Host "Stop: $(if($stop){"set"}else{"not set"})"
        Write-Host "Stream: $(if($stream){"true"}else{"false"})"
        Write-Host "logfile: $(if($logfile){$logfile}else{"not set"})"
        Write-Host "simpleresponse: $simpleresponse"
        Write-Host "usermessagelogfile: $usermessagelogfile"
    }

    try {
        # Check if usermessage is not set and usermessagelogfile is set
        if (-not $usermessage -and $usermessagelogfile) {
            # If so, read the content of usermessagelogfile and assign it to usermessage
            $usermessage = (get-content $usermessagelogfile | out-string)
        }

        # Check if logfile is not set
        if (-not $logfile) {
            $logfileDirectory = Join-Path -Path ([Environment]::GetFolderPath("MyDocuments")) -ChildPath $script:modulename

            if (!(Test-Path -Path $logfileDirectory)) {
                # Create the directory if it does not exist
                New-Item -ItemType Directory -Path $logfileDirectory -Force | Out-Null
            }
    
            $logfileBaseName = ""
            $logfileExtension = ".txt"
            if ($usermessage) {
                $userMessageHash = Get-Hash -InputString $usermessage -HashType MD5
                $logfileBaseName = "usermessage-$userMessageHash-"
                if ($OneTimeUserPrompt) {
                    $logfileBaseName = "usermessage-OneTimeUserPrompt-$userMessageHash-"
                }
            }
            if ($SystemPrompt) {
                $SystemMessageHash = Get-Hash -InputString $SystemPrompt -HashType MD5
                $logfileBaseName += "SystemPrompt-$SystemMessageHash-"
            }
            elseif ($SystemPromptFileName) {
                $logfileBaseName += "SystemPrompt-" + [System.IO.Path]::GetFileNameWithoutExtension($SystemPromptFileName) + "-"
            }

            # Initialize logfileNumber to 1
            $logfileNumber = 1
            # Increment logfileNumber until a unique logfile name is found
            while (Test-Path -Path (Join-Path $logfileDirectory ($logfileBaseName + $logfileNumber + $logfileExtension))) {
                $logfileNumber++
            }
            # Set logfile to the unique logfile name
            $logfile = Join-Path $logfileDirectory ($logfileBaseName + $logfileNumber + $logfileExtension)
        }

        # Call functions to execute API request and output results
        $headers = Get-Headers -ApiKeyVariable $script:API_AZURE_OPENAI_KEY -Secure

        # system prompt
        if ($SystemPromptFileName) {
            #$system_message = get-content -path (Join-Path $PSScriptRoot "prompts\$SystemPromptFileName") -Encoding UTF8 -Raw
            $system_message = get-content -path $SystemPromptFileName -Encoding UTF8 -Raw 
        }
        else {
            $system_message = $SystemPrompt
        }
        
        # cleaning system prompt
        $system_message = [System.Text.RegularExpressions.Regex]::Replace($system_message, "[^\x00-\x7F]", "")        

        if ($VerbosePreference -eq "Continue") {
            Write-verbose (Show-ResponseMessage -content $system_message -stream "system" | Out-String)
        }

        # user prompt message
        if ($OneTimeUserPrompt) {
            # cleaning user message
            #$userMessage = [System.Text.RegularExpressions.Regex]::Replace($OneTimeUserPrompt, "[^\x00-\x7F]", "") | Out-String # must be string not array of strings
            $userMessage = Format-Message -Message $OneTimeUserPrompt
            Write-Verbose "OneTimeUserPrompt: $userMessage"
        }
        else {
            Write-Verbose "NO OneTimeUserPrompt: $userMessage"
            if (-not $userMessage) {
                $userMessage = Read-Host "Enter chat message (user)"
            }
            #$userMessage = [System.Text.RegularExpressions.Regex]::Replace($usermessage, "[^\x00-\x7F]", "") | Out-String # must be string not array of strings
            $userMessage = Format-Message -Message $userMessage
            Write-Verbose $userMessage
        }
        
        # Get the messages from the system and user
        $messages = Get-Messages -system_message $system_message -UserMessage $userMessage
        # Write the messages to the verbose output
        Write-Verbose "Messages: $($messages | out-string)"

        # Get the URL for the chat
        $urlChat = Get-PSAOAIUrl -Endpoint $Endpoint -Deployment $Deployment -APIVersion $APIVersion -Mode chat

        # Write the URL to the verbose output
        Write-Verbose "urtChat: $urlChat"

        # Write the system prompt to the log file
        Write-LogMessage -Message "System promp:`n$system_message" -LogFile $logfile
        # Write the user message to the log file
        Write-LogMessage -Message "User message:`n$userMessage" -LogFile $logfile

        do {
            # Get the body of the message
            $body = Get-PSAOAIChatBody -messages $messages -temperature $parameters['Temperature'] -top_p $parameters['TopP'] -frequency_penalty $FrequencyPenalty -presence_penalty $PresencePenalty -user $User -n $N -stop $Stop -stream $Stream

            # Convert the body to JSON
            $bodyJSON = ($body | ConvertTo-Json)
            
            # If not a simple response, display chat completion and other details
            if (-not $simpleresponse) {
                Write-Host "[Chat completion]" -ForegroundColor Green
                if ($logfile) {
                    Write-Host "{Logfile:'${logfile}'} " -ForegroundColor Magenta
                }
                if ($SystemPromptFileName) {
                    Write-Host "{SysPFile:'$(Split-Path -Path $SystemPromptFileName -Leaf)', temp:'$($parameters['Temperature'])', top_p:'$($parameters['TopP'])', fp:'${FrequencyPenalty}', pp:'${PresencePenalty}', user:'${User}', n:'${N}', stop:'${Stop}', stream:'${Stream}'} " -NoNewline -ForegroundColor Magenta
                }
                else {
                    Write-Host "{SysPrompt, temp:'$($parameters['Temperature'])', top_p:'$($parameters['TopP'])', fp:'${FrequencyPenalty}', pp:'${PresencePenalty}', user:'${User}', n:'${N}', stop:'${Stop}', stream:'${Stream}'} " -NoNewline -ForegroundColor Magenta
                }
            }
            
            # Invoke the API request
            $response = Invoke-PSAOAIApiRequest -url $urlChat -headers $headers -bodyJSON $bodyJSON -timeout 240
            
            # If the response is null, break the loop
            if ($null -eq $response) {
                Write-Verbose "Response is empty"
                break
            }

            # Write the received job to verbose output
            Write-Verbose ("Receive job:`n$($response | ConvertTo-Json)" | Out-String)

            # Get the assistant response
            $assistant_response = $response.choices[0].message.content

            # Add the assistant response to the messages
            $messages += @{"role" = "assistant"; "content" = $assistant_response }

            # If there is a one-time user prompt, process it
            if ($OneTimeUserPrompt) {
                Write-Verbose "OneTimeUserPrompt output with return"
                if (-not $simpleresponse) {
                    Write-Verbose "Show-FinishReason"
                    Write-Information -MessageData (Show-FinishReason -finishReason $response.choices.finish_reason | Out-String) -InformationAction Continue
                    Write-Verbose "Show-PromptFilterResults"
                    Write-Information -MessageData (Show-PromptFilterResults -response $response | Out-String) -InformationAction Continue
                    Write-Verbose "Show-Usage"
                    Write-Information -MessageData (Show-Usage -usage $response.usage | Out-String) -InformationAction Continue
                }
                Write-Verbose "Show-ResponseMessage - return"

                # Get the response text
                $responseText = (Show-ResponseMessage -content $assistant_response -stream "assistant" -simpleresponse:$simpleresponse | Out-String)

                # Write the one-time user prompt and response text to the log file
                Write-LogMessage -Message "OneTimeUserPrompt:`n$OneTimeUserPrompt" -LogFile $logfile
                Write-LogMessage -Message "ResponseText:`n$responseText" -LogFile $logfile

                # Return the response text
                return $responseText
            }
            else {
                Write-Verbose "NO OneTimeUserPrompt"

                # Show the response message
                Show-ResponseMessage -content $assistant_response -stream "assistant" -simpleresponse:$simpleresponse
            
                # Write the assistant response to the log file
                Write-LogMessage -Message "Assistant response:`n$assistant_response" -LogFile $logfile

                # Get the user message
                $user_message = Read-Host "Enter chat message (user)" 
                # Add the user message to the messages
                $messages += @{"role" = "user"; "content" = $user_message }

                # Write the user response to the log file
                Write-LogMessage -Message "User response:`n$user_message" -LogFile $logfile
            }
            
        } while ($true)
    }
    catch {
        Format-Error -ErrorVar $_
        Show-Error -ErrorVar $_
    }

}

<#
# Define constants for environment variable names
$API_AZURE_OPENAI_APIVERSION = "API_AZURE_OPENAI_APIVERSION"
$API_AZURE_OPENAI_ENDPOINT = "API_AZURE_OPENAI_ENDPOINT"
$API_AZURE_OPENAI_DEPLOYMENT = "API_AZURE_OPENAI_DEPLOYMENT"
$API_AZURE_OPENAI_KEY = "API_AZURE_OPENAI_KEY"
 
# Get the API version from the environment variable
$APIVersion = Set-EnvironmentVariable -VariableName $API_AZURE_OPENAI_APIVERSION -PromptMessage "Please enter the API version"
# Get the endpoint from the environment variable
$Endpoint = Set-EnvironmentVariable -VariableName $API_AZURE_OPENAI_ENDPOINT -PromptMessage "Please enter the endpoint"
# Get the deployment from the environment variable
$Deployment = Set-EnvironmentVariable -VariableName $API_AZURE_OPENAI_DEPLOYMENT -PromptMessage "Please enter the deployment"
# Get the API key from the environment variable
$ApiKey = Set-EnvironmentVariable -VariableName $API_AZURE_OPENAI_KEY -PromptMessage "Please enter the API key"
#>