diff --git a/Makefile b/Makefile index ebaf7315..1fd42905 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # Versioning version_full ?= $(shell $(MAKE) --silent version-full) version_small ?= $(shell $(MAKE) --silent version) -# DevTunnel configuration +# Dev tunnels configuration tunnel_name := call-center-ai-$(shell hostname | sed 's/[^a-zA-Z0-9]//g' | tr '[:upper:]' '[:lower:]') tunnel_url ?= $(shell res=$$(devtunnel show $(tunnel_name) | grep -o 'http[s]*://[^"]*' | xargs) && echo $${res%/}) # App location @@ -121,6 +121,22 @@ dev: VERSION=$(version_full) PUBLIC_DOMAIN=$(tunnel_url) func start deploy: + $(MAKE) deploy-bicep + + @echo "💤 Wait 10 secs for output to be available..." + sleep 10 + + @echo "🛠️ Deploying Function App..." + func azure functionapp publish $(function_app_name) \ + --build local \ + --build-native-deps \ + --python + + @echo "🚀 Call Center AI is running on $(app_url)" + + @$(MAKE) deploy-post + +deploy-bicep: @echo "👀 Current subscription:" @az account show --query "{subscriptionId:id, subscriptionName:name, tenantId:tenantId}" --output table @@ -137,20 +153,7 @@ deploy: --template-file bicep/main.bicep \ --name $(name_sanitized) - @echo "💤 Wait 10 secs for output to be available..." - sleep 10 - - @echo "🛠️ Deploying Function App..." - func azure functionapp publish $(function_app_name) \ - --build local \ - --build-native-deps \ - --python - - @echo "🚀 Call Center AI is running on $(app_url)" - - @$(MAKE) post-deploy name=$(name_sanitized) - -post-deploy: +deploy-post: @$(MAKE) copy-resources \ name=$(blob_storage_public_name) diff --git a/README.md b/README.md index e1e58c87..ee6c338b 100644 --- a/README.md +++ b/README.md @@ -243,7 +243,7 @@ sequenceDiagram ## Deployment -Some prerequisites are needed to deploy the solution. +### Prerequisites [Prefer using GitHub Codespaces for a quick start.](https://codespaces.new/microsoft/call-center-ai?quickstart=1) The environment will setup automatically with all the required tools. @@ -258,65 +258,97 @@ For other systems, make sure you have the following installed: - [Azure Functions Core Tools](https://github.com/Azure/azure-functions-core-tools?tab=readme-ov-file#installing) - [Twilio CLI](https://www.twilio.com/docs/twilio-cli/getting-started/install) (optional) -### Remote (on Azure) +Then, Azure resources are needed: + +#### 1. [Create a new resource group](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/manage-resource-groups-portal) + +- Prefer to use lowercase and no special characters other than dashes (e.g. `ccai-customer-a`) -Steps to deploy: +#### 2. [Create a Communication Services resource](https://learn.microsoft.com/en-us/azure/communication-services/quickstarts/create-communication-resource?tabs=linux&pivots=platform-azp) -1. [Create a new resource group](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/manage-resource-groups-portal) +- Same name as the resource group +- Enable system managed identity - - Prefer to use lowercase and no special characters other than dashes (e.g. `ccai-customer-a`) +#### 3. [Buy a phone number](https://learn.microsoft.com/en-us/azure/communication-services/quickstarts/telephony/get-phone-number?tabs=linux&pivots=platform-azp-new) -2. [Create a Communication Services resource](https://learn.microsoft.com/en-us/azure/communication-services/quickstarts/create-communication-resource?tabs=linux&pivots=platform-azp) +- From the Communication Services resource +- Allow inbound and outbound communication +- Enable voice (required) and SMS (optional) capabilities - - Same name as the resource group - - Enable system managed identity +Now that the prerequisites are configured (local + Azure), the deployment can be done. + +### Remote (on Azure) -3. [Buy a phone number](https://learn.microsoft.com/en-us/azure/communication-services/quickstarts/telephony/get-phone-number?tabs=linux&pivots=platform-azp-new) +#### 1. Create the light config file - - From the Communication Services resource - - Allow inbound and outbound communication - - Enable voice (required) and SMS (optional) capabilities +File is named `config.yaml`: -4. Create a local `config.yaml` file +```yaml +# config.yaml +conversation: + initiate: + # Phone number the bot will transfer the call to if customer asks for a human agent + agent_phone_number: "+33612345678" + bot_company: Contoso + bot_name: Amélie + lang: {} + +communication_services: + # Phone number purshased from Communication Services + phone_number: "+33612345678" + +sms: {} + +prompts: + llm: {} + tts: {} +``` - ```yaml - # config.yaml - conversation: - initiate: - # Phone number the bot will transfer the call to if customer asks for a human agent - agent_phone_number: "+33612345678" - bot_company: Contoso - bot_name: Amélie - lang: {} +#### 2. Connect to your Azure environment - communication_services: - # Phone number purshased from Communication Services - phone_number: "+33612345678" +```zsh +az login +``` - sms: {} +#### 3. Run deployment automation - prompts: - llm: {} - tts: {} - ``` +```zsh +make deploy name=my-rg-name +``` -5. Connect to your Azure environment (e.g. `az login`) -6. Run deployment automation with `make deploy name=my-rg-name` +- Wait for the deployment to finish - - Wait for the deployment to finish +#### 4. [Create a AI Search resource](https://learn.microsoft.com/en-us/azure/search/search-create-service-portal) -7. [Create a AI Search resource](https://learn.microsoft.com/en-us/azure/search/search-create-service-portal) +- An index named `trainings` +- A semantic search configuration on the index named `default` - - An index named `trainings` - - A semantic search configuration on the index named `default` +#### 5. Get the logs -Get the logs with `make logs name=my-rg-name`. +```zsh +make logs name=my-rg-name +``` ### Local (on your machine) -#### Prerequisites for local development +#### 1. Create the full config file + +> [!TIP] +> To use a Service Principal to authenticate to Azure, you can also add the following in a `.env` file: +> +> ```dotenv +> AZURE_CLIENT_ID=xxx +> AZURE_CLIENT_SECRET=xxx +> AZURE_TENANT_ID=xxx +> ``` -Place a file called `config.yaml` in the root of the project with the following content: +> [!TIP] +> If you already deployed the application to Azure and if it is working, you can: +> +> - Copy the configuration from the Azure Function App to your local machine by using the content of the `CONFIG_JSON` application setting +> - Then convert it to YAML format + +File is named `config.yaml`: ```yaml # config.yaml @@ -372,52 +404,49 @@ ai_translation: endpoint: https://xxx.cognitiveservices.azure.com ``` -To use a Service Principal to authenticate to Azure, you can also add the following in a `.env` file: +#### 2. Run the deployment automation -```dotenv -AZURE_CLIENT_ID=xxx -AZURE_CLIENT_SECRET=xxx -AZURE_TENANT_ID=xxx +```zsh +make deploy-bicep deploy-post name=my-rg-name ``` -To override a specific configuration value, you can also use environment variables. For example, to override the `llm.fast.endpoint` value, you can use the `LLM__FAST__ENDPOINT` variable: +- This will deploy the Azure resources without the API server, allowing you to test the bot locally +- Wait for the deployment to finish -```dotenv -LLM__FAST__ENDPOINT=https://xxx.openai.azure.com -``` +#### 3. Initialize local function config -Then run: +Copy `local.example.settings.json` to `local.settings.json`, then fill the required fields: -```bash -# Install dependencies -make install -``` +- `APPLICATIONINSIGHTS_CONNECTION_STRING`, as the connection string of the Application Insights resource +- `AzureWebJobsStorage`, as the connection string of the Azure Storage account -Also, a public file server is needed to host the audio files. Upload the files with `make copy-resources name=my-rg-name` (`my-rg-name` is the storage account name), or manually. +#### 4. Connect to Azure Dev tunnels with `devtunnel login`, then run it with `make tunnel` -For your knowledge, this `resources` folder contains: +> [!IMPORTANT] +> Tunnel requires to be run in a separate terminal, because it needs to be running all the time -- Audio files (`xxx.wav`) to be played during the call -- [Lexicon file (`lexicon.xml`)](https://learn.microsoft.com/en-us/azure/ai-services/speech-service/speech-synthesis-markup-pronunciation#custom-lexicon) to be used by the bot to understand the company products (note: any change [makes up to 15 minutes](https://learn.microsoft.com/en-us/azure/ai-services/speech-service/speech-synthesis-markup-pronunciation#custom-lexicon-file) to be taken into account) +#### 5. Iterate quickly with the code -#### Run +> [!NOTE] +> To override a specific configuration value, you can use environment variables. For example, to override the `llm.fast.endpoint` value, you can use the `LLM__FAST__ENDPOINT` variable: +> +> ```dotenv +> LLM__FAST__ENDPOINT=https://xxx.openai.azure.com +> ``` -Finally, run: +> [!NOTE] +> Also, `local.py` script is available to test the application without the need of a phone call (= without Communication Services). Run the script with: +> +> ```bash +> python3 -m tests.local +> ``` -```bash -# Start the local API server +```zsh make dev ``` -#### Debug - -Breakpoints can be added in the code to debug the application with your favorite IDE. - -Also, `local.py` script is available to test the application without the need of a phone call (= without Communication Services). Run the script with: - -```bash -python3 -m tests.local -``` +- Code is automatically reloaded on file changes, no need to restart the server +- The API server is available at `http://localhost:8080` ## Advanced usage