Skip to content

Commit

Permalink
CopilotChat: Combine AIOptions into a common setting. (microsoft#1031)
Browse files Browse the repository at this point in the history
### Motivation and Context
Configuring AI service options in CopilotChat required 3 separate
sections that are all identical. This change combines those section into
a single section that shares the type (Azure/OpenAI), endpoint, and API
key.

### Description
- Removed "Completion", "Embedding", and "Planner:AIService" from
settings
- Added "AIService" sections containing all previous sections and a
"Models" section to define models to use for completions, embeddings,
and planning
- Added a "config.ps1" script to set the API key as a user-secret and
generate an 'appsettings.Development.json' with AIService overrides.
  • Loading branch information
adrianwyatt authored and name committed May 19, 2023
1 parent 52c4ba8 commit 6293ad6
Show file tree
Hide file tree
Showing 22 changed files with 603 additions and 397 deletions.
133 changes: 133 additions & 0 deletions samples/apps/copilot-chat-app/scripts/Configure.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<#
.SYNOPSIS
Configure user secrets, appsettings.Development.json, and .env for Copilot Chat.
.PARAMETER OpenAI
Switch to configure for OpenAI.
.PARAMETER AzureOpenAI
Switch to configure for Azure OpenAI.
.PARAMETER Endpoint
Set when using Azure OpenAI.
.PARAMETER ApiKey
The API key for the AI service.
.PARAMETER CompletionModel
The chat completion model to use (e.g., gpt-3.5-turbo or gpt-4).
.PARAMETER EmbeddingModel
The embedding model to use (e.g., text-embedding-ada-002).
.PARAMETER PlannerModel
The chat completion model to use for planning (e.g., gpt-3.5-turbo or gpt-4).
.PARAMETER ClientID
The client (application) ID associated with your AAD app registration.
.PARAMETER Tenant
The tenant (directory) associated with your AAD app registration.
Defaults to 'common'.
See https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-client-application-configuration#authority.
#>

param(
[Parameter(ParameterSetName='OpenAI',Mandatory=$false)]
[switch]$OpenAI,

[Parameter(ParameterSetName='AzureOpenAI',Mandatory=$false)]
[switch]$AzureOpenAI,

[Parameter(ParameterSetName='AzureOpenAI',Mandatory=$true)]
[string]$Endpoint,

[Parameter(Mandatory=$true)]
[string]$ApiKey,

[Parameter(Mandatory=$false)]
[string]$CompletionModel = "gpt-3.5-turbo",

[Parameter(Mandatory=$false)]
[string]$EmbeddingModel = "text-embedding-ada-002",

[Parameter(Mandatory=$false)]
[string]$PlannerModel = "gpt-3.5-turbo",

[Parameter(Mandatory = $true)]
[string] $ClientId,

[Parameter(Mandatory = $false)]
[string] $Tenant = 'common'
)

Write-Host "#########################"
Write-Host "# Backend configuration #"
Write-Host "#########################"

# Install dev certificate
if ($IsLinux)
{
dotnet dev-certs https
if ($LASTEXITCODE -ne 0) { exit(1) }
}
else # Windows/MacOS
{
dotnet dev-certs https --trust
if ($LASTEXITCODE -ne 0) { exit(1) }
}

if ($OpenAI)
{
$aiServiceType = "OpenAI"
$Endpoint = ""
}
elseif ($AzureOpenAI)
{
$aiServiceType = "AzureOpenAI"

# Azure OpenAI has a different model name for gpt-3.5-turbo (no decimal).
$CompletionModel = $CompletionModel.Replace("3.5", "35")
$EmbeddingModel = $EmbeddingModel.Replace("3.5", "35")
$PlannerModel = $PlannerModel.Replace("3.5", "35")
}
else {
Write-Error "Please specify either -OpenAI or -AzureOpenAI"
exit(1)
}

$appsettingsOverrides = @{ AIService = @{ Type = $aiServiceType; Endpoint = $Endpoint; Models = @{ Completion = $CompletionModel; Embedding = $EmbeddingModel; Planner = $PlannerModel } } }

$webapiProjectPath = Join-Path "$PSScriptRoot" '../webapi'
$appsettingsOverridesFilePath = Join-Path $webapiProjectPath 'appsettings.Development.json'

Write-Host "Setting 'AIService:Key' user secret for $aiServiceType..."
dotnet user-secrets set --project $webapiProjectPath AIService:Key $ApiKey
if ($LASTEXITCODE -ne 0) { exit(1) }

Write-Host "Setting up 'appsettings.Development.json' for $aiServiceType..."
ConvertTo-Json $appsettingsOverrides | Out-File -Encoding utf8 $appsettingsOverridesFilePath

Write-Host "($appsettingsOverridesFilePath)"
Write-Host "========"
Get-Content $appsettingsOverridesFilePath | Write-Host
Write-Host "========"

Write-Host ""
Write-Host "##########################"
Write-Host "# Frontend configuration #"
Write-Host "##########################"

$envFilePath = Join-Path "$PSScriptRoot" '../webapp/.env'

Write-Host "Setting up '.env'..."
Set-Content -Path $envFilePath -Value "REACT_APP_BACKEND_URI=https://localhost:40443/"
Add-Content -Path $envFilePath -Value "REACT_APP_AAD_AUTHORITY=https://login.microsoftonline.com/$Tenant"
Add-Content -Path $envFilePath -Value "REACT_APP_AAD_CLIENT_ID=$ClientId"

Write-Host "($envFilePath)"
Write-Host "========"
Get-Content $envFilePath | Write-Host
Write-Host "========"

Write-Host "Done!"
152 changes: 152 additions & 0 deletions samples/apps/copilot-chat-app/scripts/Configure.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#!/bin/bash
# Configure user secrets, appsettings.Development.json, and .env for Copilot Chat.

set -e

# Defaults
COMPLETION_MODEL="gpt-3.5-turbo"
EMBEDDING_MODEL="text-embedding-ada-002"
PLANNER_MODEL="gpt-3.5-turbo"
TENANT_ID="common"

# Argument parsing
POSITIONAL_ARGS=()

while [[ $# -gt 0 ]]; do
case $1 in
--openai)
OPENAI=YES
shift # past argument
;;
--azureopenai)
AZURE_OPENAI=YES
shift
;;
-e|--endpoint)
ENDPOINT="$2"
shift # past argument
shift # past value
;;
-a|--apikey)
API_KEY="$2"
shift
shift
;;
--completion)
COMPLETION_MODEL="$2"
shift
shift
;;
--embedding)
EMBEDDING_MODEL="$2"
shift
shift
;;
--planner)
PLANNER_MODEL="$2"
shift
shift
;;
-c|--clientid)
CLIENT_ID="$2"
shift
shift
;;
-t|--tenantid)
TENANT_ID="$2"
shift
shift
;;
-*|--*)
echo "Unknown option $1"
exit 1
;;
*)
POSITIONAL_ARGS+=("$1") # save positional arg
shift # past argument
;;
esac
done

set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters

SCRIPT_DIRECTORY="$(dirname $0)"

# Validate arguments
if [ -z "$API_KEY" ]; then
echo "Please specify an API key with -a or --apikey."; exit 1;
fi
if [ -z "$CLIENT_ID" ]; then
echo "Please specify a client (application) ID with -c or --clientid."; exit 1;
fi
if [ "$AZURE_OPENAI" = "YES" ] && [ -z "$ENDPOINT" ]; then
echo "When using --azureopenti, please specify an endpoint with -e or --endpoint."; exit 1;
fi

echo "#########################"
echo "# Backend configuration #"
echo "#########################"

# Install dev certificate
case "$OSTYPE" in
darwin*)
dotnet dev-certs https --trust
if [ $? -ne 0 ]; then `exit` 1; fi ;;
msys*)
dotnet dev-certs https --trust
if [ $? -ne 0 ]; then exit 1; fi ;;
cygwin*)
dotnet dev-certs https --trust
if [ $? -ne 0 ]; then exit 1; fi ;;
linux*)
dotnet dev-certs https
if [ $? -ne 0 ]; then exit 1; fi ;;
esac

if [ "$OPENAI" = "YES" ]; then
AI_SERVICE_TYPE="OpenAI"
elif [ "$AZURE_OPENAI" = "YES" ]; then
# Azure OpenAI has a different model name for gpt-3.5-turbo (no decimal).
AI_SERVICE_TYPE="AzureOpenAI"
COMPLETION_MODEL="${COMPLETION_MODEL/3.5/"35"}"
EMBEDDING_MODEL="${EMBEDDING_MODEL/3.5/"35"}"
PLANNER_MODEL="${PLANNER_MODEL/3.5/"35"}"
else
echo "Please specify either --openai or --azureopenai."
exit 1
fi

APPSETTINGS_JSON="{ \"AIService\": { \"Type\": \"${AI_SERVICE_TYPE}\", \"Endpoint\": \"${ENDPOINT}\", \"Models\": { \"Completion\": \"${COMPLETION_MODEL}\", \"Embedding\": \"${EMBEDDING_MODEL}\", \"Planner\": \"${PLANNER_MODEL}\" } } }"
WEBAPI_PROJECT_PATH="${SCRIPT_DIRECTORY}/../webapi"
APPSETTINGS_OVERRIDES_FILEPATH="${WEBAPI_PROJECT_PATH}/appsettings.Development.json"

echo "Setting 'AIService:Key' user secret for $AI_SERVICE_TYPE..."
dotnet user-secrets set --project $WEBAPI_PROJECT_PATH AIService:Key $API_KEY
if [ $? -ne 0 ]; then exit 1; fi

echo "Setting up 'appsettings.Development.json' for $AI_SERVICE_TYPE..."
echo $APPSETTINGS_JSON > $APPSETTINGS_OVERRIDES_FILEPATH

echo "($APPSETTINGS_OVERRIDES_FILEPATH)"
echo "========"
cat $APPSETTINGS_OVERRIDES_FILEPATH
echo "========"

echo ""
echo "##########################"
echo "# Frontend configuration #"
echo "##########################"

ENV_FILEPATH="${SCRIPT_DIRECTORY}/../webapp/.env"

echo "Setting up '.env'..."
echo "REACT_APP_BACKEND_URI=https://localhost:40443/" > $ENV_FILEPATH
echo "REACT_APP_AAD_AUTHORITY=https://login.microsoftonline.com/$TENANT_ID" >> $ENV_FILEPATH
echo "REACT_APP_AAD_CLIENT_ID=$CLIENT_ID" >> $ENV_FILEPATH

echo "($ENV_FILEPATH)"
echo "========"
cat $ENV_FILEPATH
echo "========"

echo "Done!"
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/bash

# Installs the requirements for running Copilot Chat.

set -e

# Add Yarn's package repository to the system
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list

# Add .NET's package repository to the system
wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb

# Add NodeJS's package repository to the system
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -

# Install the requirements
sudo apt update;
sudo apt install yarn -y;
sudo apt install dotnet-sdk-6.0 -y;
sudo apt install nodejs -y;

echo ""
echo "YARN $(yarn --version) installed."
echo "NODEJS $(node --version) installed."
echo "DOTNET $(dotnet --version) installed."
Loading

0 comments on commit 6293ad6

Please sign in to comment.