From 7144c76f14c3b477fb5e83b5a3819c65488740ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 14:10:48 +0000 Subject: [PATCH 1/7] Bump docker/login-action from 2 to 3 (#274) Bumps [docker/login-action](https://github.com/docker/login-action) from 2 to 3. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/v2...v3) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/AdminWebApp.yml | 2 +- .github/workflows/Backend.yml | 2 +- .github/workflows/CwyodBackend.yml | 2 +- .github/workflows/WebApp.yml | 2 +- .github/workflows/ci.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/AdminWebApp.yml b/.github/workflows/AdminWebApp.yml index 20799d8c8..eb1b5d5fd 100644 --- a/.github/workflows/AdminWebApp.yml +++ b/.github/workflows/AdminWebApp.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Docker Login - uses: docker/login-action@v3.0.0 + uses: docker/login-action@v3 with: registry: fruoccopublic.azurecr.io username: fruoccopublic diff --git a/.github/workflows/Backend.yml b/.github/workflows/Backend.yml index 119da0a1d..2791adeb5 100644 --- a/.github/workflows/Backend.yml +++ b/.github/workflows/Backend.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Docker Login - uses: docker/login-action@v3.0.0 + uses: docker/login-action@v3 with: registry: fruoccopublic.azurecr.io username: fruoccopublic diff --git a/.github/workflows/CwyodBackend.yml b/.github/workflows/CwyodBackend.yml index b69aabc35..64352adca 100644 --- a/.github/workflows/CwyodBackend.yml +++ b/.github/workflows/CwyodBackend.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Docker Login - uses: docker/login-action@v3.0.0 + uses: docker/login-action@v3 with: registry: fruoccopublic.azurecr.io username: fruoccopublic diff --git a/.github/workflows/WebApp.yml b/.github/workflows/WebApp.yml index f6c9cee21..789d8cef1 100644 --- a/.github/workflows/WebApp.yml +++ b/.github/workflows/WebApp.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Docker Login - uses: docker/login-action@v3.0.0 + uses: docker/login-action@v3 with: registry: fruoccopublic.azurecr.io username: fruoccopublic diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc40e65ef..c6f7ff1fc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: uses: actions/checkout@v3 - name: Login to GitHub Container Registry - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.repository_owner }} From 3fbbe72d6ce387768f2e0e2ba3100fb920995c8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 14:11:04 +0000 Subject: [PATCH 2/7] Bump actions/checkout from 3 to 4 (#275) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c6f7ff1fc..0368a25b2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Login to GitHub Container Registry uses: docker/login-action@v3 From d8082118118cb82c7c5987d53eef2156d60bed02 Mon Sep 17 00:00:00 2001 From: Chinedum Echeta <60179183+cecheta@users.noreply.github.com> Date: Mon, 5 Feb 2024 18:45:09 +0000 Subject: [PATCH 3/7] Add pre-commit for Bicep files (#273) * Add pre-commit for Bicep files * Format all Bicep files * Bump pre-commit --- .pre-commit-config.yaml | 19 ++- code/dev-requirements.txt | 2 +- extensions/infrastructure/main.bicep | 70 ++++---- extensions/teams/infra/azure.bicep | 2 +- .../infra/botRegistration/azurebot.bicep | 2 +- infra/deployment.bicep | 151 +++++++++--------- infra/security/role.bicep | 2 +- scripts/generate_arm_templates.sh | 24 +++ 8 files changed, 154 insertions(+), 118 deletions(-) create mode 100755 scripts/generate_arm_templates.sh diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bc2f44220..24a6a6cae 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,9 +4,22 @@ repos: hooks: - id: black language_version: python3 - + - repo: https://github.com/pycqa/flake8 rev: 7.0.0 hooks: - - id: flake8 - args: [--extend-ignore=E501] \ No newline at end of file + - id: flake8 + args: [--extend-ignore=E501] + + - repo: local + hooks: + - id: bicep + name: bicep + description: Lint and build Bicep files + entry: ./scripts/generate_arm_templates.sh + language: script + files: \.bicep$ + require_serial: true + args: # Bicep files that we want to generate ARM templates from + - -f=./infra/deployment.bicep + - -f=./extensions/infrastructure/main.bicep diff --git a/code/dev-requirements.txt b/code/dev-requirements.txt index 4f41e9faf..39cf2c15b 100644 --- a/code/dev-requirements.txt +++ b/code/dev-requirements.txt @@ -1,5 +1,5 @@ pytest==8.0.0 pytest-cov==4.1.0 flake8==7.0.0 -pre-commit==3.5.0 +pre-commit==3.6.0 black==23.12.1 diff --git a/extensions/infrastructure/main.bicep b/extensions/infrastructure/main.bicep index 22d52530f..0e8080717 100644 --- a/extensions/infrastructure/main.bicep +++ b/extensions/infrastructure/main.bicep @@ -119,7 +119,7 @@ param AzureFormRecognizerEndpoint string @secure() param AzureFormRecognizerKey string -@description('Storage Account Name - Created during the "Chat with your data" Solution Accelerator') +@description('Storage Account Name - Created during the "Chat with your data" Solution Accelerator') param AzureBlobAccountName string @description('Storage Account Key - Created during the "Chat with your data" Solution Accelerator') @@ -151,39 +151,39 @@ resource Function 'Microsoft.Web/sites@2018-11-01' = { properties: { siteConfig: { appSettings: [ - { name: 'FUNCTIONS_EXTENSION_VERSION', value: '~4'} - { name: 'WEBSITES_ENABLE_APP_SERVICE_STORAGE', value: 'false'} - { name: 'APPINSIGHTS_CONNECTION_STRING', value: AppInsightsConnectionString} - { name: 'AZURE_SEARCH_SERVICE', value: 'https://${AzureSearchName}.search.windows.net'} - { name: 'AZURE_SEARCH_INDEX', value: AzureSearchIndex} - { name: 'AZURE_SEARCH_CONVERSATIONS_LOG_INDEX', value: AzureSearchConversationLogIndex} - { name: 'AZURE_SEARCH_KEY', value: AzureSearchKey} - { name: 'AZURE_SEARCH_SEMANTIC_SEARCH_CONFIG', value: AzureSearchSemanticSearchConfig} - { name: 'AZURE_SEARCH_INDEX_IS_PRECHUNKED', value: AzureSearchIndexIsPrechunked} - { name: 'AZURE_SEARCH_TOP_K', value: AzureSearchTopK} - { name: 'AZURE_SEARCH_ENABLE_IN_DOMAIN', value: AzureSearchEnableInDomain} - { name: 'AZURE_SEARCH_CONTENT_COLUMNS', value: AzureSearchContentColumns} - { name: 'AZURE_SEARCH_FILENAME_COLUMN', value: AzureSearchFilenameColumn} - { name: 'AZURE_SEARCH_TITLE_COLUMN', value: AzureSearchTitleColumn} - { name: 'AZURE_SEARCH_URL_COLUMN', value: AzureSearchUrlColumn} - { name: 'AZURE_OPENAI_RESOURCE', value: AzureOpenAIResource} - { name: 'AZURE_OPENAI_KEY', value: AzureOpenAIKey} - { name: 'AZURE_OPENAI_MODEL', value: AzureOpenAIModel} - { name: 'AZURE_OPENAI_MODEL_NAME', value: AzureOpenAIModelName} - { name: 'AZURE_OPENAI_TEMPERATURE', value: AzureOpenAITemperature} - { name: 'AZURE_OPENAI_TOP_P', value: AzureOpenAITopP} - { name: 'AZURE_OPENAI_MAX_TOKENS', value: AzureOpenAIMaxTokens} - { name: 'AZURE_OPENAI_STOP_SEQUENCE', value: AzureOpenAIStopSequence} - { name: 'AZURE_OPENAI_SYSTEM_MESSAGE', value: AzureOpenAISystemMessage} - { name: 'AZURE_OPENAI_API_VERSION', value: AzureOpenAIApiVersion} - { name: 'AZURE_OPENAI_STREAM', value: AzureOpenAIStream} - { name: 'AZURE_OPENAI_EMBEDDING_MODEL', value: AzureOpenAIEmbeddingModel} - { name: 'AZURE_FORM_RECOGNIZER_ENDPOINT', value: AzureFormRecognizerEndpoint} - { name: 'AZURE_FORM_RECOGNIZER_KEY', value: AzureFormRecognizerKey} - { name: 'AZURE_BLOB_ACCOUNT_NAME', value: AzureBlobAccountName} - { name: 'AZURE_BLOB_ACCOUNT_KEY', value: AzureBlobAccountKey} - { name: 'AZURE_BLOB_CONTAINER_NAME', value: AzureBlobContainerName} - { name: 'ORCHESTRATION_STRATEGY', value: OrchestrationStrategy} + { name: 'FUNCTIONS_EXTENSION_VERSION', value: '~4' } + { name: 'WEBSITES_ENABLE_APP_SERVICE_STORAGE', value: 'false' } + { name: 'APPINSIGHTS_CONNECTION_STRING', value: AppInsightsConnectionString } + { name: 'AZURE_SEARCH_SERVICE', value: 'https://${AzureSearchName}.search.windows.net' } + { name: 'AZURE_SEARCH_INDEX', value: AzureSearchIndex } + { name: 'AZURE_SEARCH_CONVERSATIONS_LOG_INDEX', value: AzureSearchConversationLogIndex } + { name: 'AZURE_SEARCH_KEY', value: AzureSearchKey } + { name: 'AZURE_SEARCH_SEMANTIC_SEARCH_CONFIG', value: AzureSearchSemanticSearchConfig } + { name: 'AZURE_SEARCH_INDEX_IS_PRECHUNKED', value: AzureSearchIndexIsPrechunked } + { name: 'AZURE_SEARCH_TOP_K', value: AzureSearchTopK } + { name: 'AZURE_SEARCH_ENABLE_IN_DOMAIN', value: AzureSearchEnableInDomain } + { name: 'AZURE_SEARCH_CONTENT_COLUMNS', value: AzureSearchContentColumns } + { name: 'AZURE_SEARCH_FILENAME_COLUMN', value: AzureSearchFilenameColumn } + { name: 'AZURE_SEARCH_TITLE_COLUMN', value: AzureSearchTitleColumn } + { name: 'AZURE_SEARCH_URL_COLUMN', value: AzureSearchUrlColumn } + { name: 'AZURE_OPENAI_RESOURCE', value: AzureOpenAIResource } + { name: 'AZURE_OPENAI_KEY', value: AzureOpenAIKey } + { name: 'AZURE_OPENAI_MODEL', value: AzureOpenAIModel } + { name: 'AZURE_OPENAI_MODEL_NAME', value: AzureOpenAIModelName } + { name: 'AZURE_OPENAI_TEMPERATURE', value: AzureOpenAITemperature } + { name: 'AZURE_OPENAI_TOP_P', value: AzureOpenAITopP } + { name: 'AZURE_OPENAI_MAX_TOKENS', value: AzureOpenAIMaxTokens } + { name: 'AZURE_OPENAI_STOP_SEQUENCE', value: AzureOpenAIStopSequence } + { name: 'AZURE_OPENAI_SYSTEM_MESSAGE', value: AzureOpenAISystemMessage } + { name: 'AZURE_OPENAI_API_VERSION', value: AzureOpenAIApiVersion } + { name: 'AZURE_OPENAI_STREAM', value: AzureOpenAIStream } + { name: 'AZURE_OPENAI_EMBEDDING_MODEL', value: AzureOpenAIEmbeddingModel } + { name: 'AZURE_FORM_RECOGNIZER_ENDPOINT', value: AzureFormRecognizerEndpoint } + { name: 'AZURE_FORM_RECOGNIZER_KEY', value: AzureFormRecognizerKey } + { name: 'AZURE_BLOB_ACCOUNT_NAME', value: AzureBlobAccountName } + { name: 'AZURE_BLOB_ACCOUNT_KEY', value: AzureBlobAccountKey } + { name: 'AZURE_BLOB_CONTAINER_NAME', value: AzureBlobContainerName } + { name: 'ORCHESTRATION_STRATEGY', value: OrchestrationStrategy } ] cors: { allowedOrigins: [ @@ -214,4 +214,4 @@ resource WaitFunctionDeploymentSection 'Microsoft.Resources/deploymentScripts@20 dependsOn: [ Function ] -} +} \ No newline at end of file diff --git a/extensions/teams/infra/azure.bicep b/extensions/teams/infra/azure.bicep index 67dcc366d..7ef6223c2 100644 --- a/extensions/teams/infra/azure.bicep +++ b/extensions/teams/infra/azure.bicep @@ -79,4 +79,4 @@ module azureBotRegistration './botRegistration/azurebot.bicep' = { // The output will be persisted in .env.{envName}. Visit https://aka.ms/teamsfx-actions/arm-deploy for more details. output BOT_AZURE_APP_SERVICE_RESOURCE_ID string = webApp.id -output BOT_DOMAIN string = webApp.properties.defaultHostName +output BOT_DOMAIN string = webApp.properties.defaultHostName \ No newline at end of file diff --git a/extensions/teams/infra/botRegistration/azurebot.bicep b/extensions/teams/infra/botRegistration/azurebot.bicep index ab67c7a56..fbf492bf8 100644 --- a/extensions/teams/infra/botRegistration/azurebot.bicep +++ b/extensions/teams/infra/botRegistration/azurebot.bicep @@ -34,4 +34,4 @@ resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@202 properties: { channelName: 'MsTeamsChannel' } -} +} \ No newline at end of file diff --git a/infra/deployment.bicep b/infra/deployment.bicep index 396e0aad4..8f6da40ad 100644 --- a/infra/deployment.bicep +++ b/infra/deployment.bicep @@ -217,7 +217,7 @@ resource AzureCognitiveSearch_resource 'Microsoft.Search/searchServices@2022-09- name: AzureCognitiveSearch location: Location tags: { - deployment : 'chatwithyourdata-sa' + deployment: 'chatwithyourdata-sa' } sku: { name: AzureCognitiveSearchSku @@ -315,44 +315,44 @@ resource Website 'Microsoft.Web/sites@2020-06-01' = { serverFarmId: HostingPlanName siteConfig: { appSettings: [ - { name: 'APPINSIGHTS_CONNECTION_STRING', value: reference(ApplicationInsights.id, '2015-05-01').ConnectionString} - { name: 'AZURE_SEARCH_SERVICE', value: 'https://${AzureCognitiveSearch}.search.windows.net'} - { name: 'AZURE_SEARCH_INDEX', value: AzureSearchIndex} + { name: 'APPINSIGHTS_CONNECTION_STRING', value: reference(ApplicationInsights.id, '2015-05-01').ConnectionString } + { name: 'AZURE_SEARCH_SERVICE', value: 'https://${AzureCognitiveSearch}.search.windows.net' } + { name: 'AZURE_SEARCH_INDEX', value: AzureSearchIndex } { name: 'AZURE_SEARCH_USE_SEMANTIC_SEARCH', value: AzureSearchUseSemanticSearch } - { name: 'AZURE_SEARCH_CONVERSATIONS_LOG_INDEX', value: AzureSearchConversationLogIndex} + { name: 'AZURE_SEARCH_CONVERSATIONS_LOG_INDEX', value: AzureSearchConversationLogIndex } { name: 'AZURE_AUTH_TYPE', value: authType } - { name: 'AZURE_SEARCH_KEY', value: authType == 'keys' ? listAdminKeys('Microsoft.Search/searchServices/${AzureCognitiveSearch}', '2021-04-01-preview').primaryKey : null} - { name: 'AZURE_SEARCH_SEMANTIC_SEARCH_CONFIG', value: AzureSearchSemanticSearchConfig} - { name: 'AZURE_SEARCH_INDEX_IS_PRECHUNKED', value: AzureSearchIndexIsPrechunked} - { name: 'AZURE_SEARCH_TOP_K', value: AzureSearchTopK} - { name: 'AZURE_SEARCH_ENABLE_IN_DOMAIN', value: AzureSearchEnableInDomain} - { name: 'AZURE_SEARCH_CONTENT_COLUMNS', value: AzureSearchContentColumns} - { name: 'AZURE_SEARCH_FILENAME_COLUMN', value: AzureSearchFilenameColumn} - { name: 'AZURE_SEARCH_TITLE_COLUMN', value: AzureSearchTitleColumn} - { name: 'AZURE_SEARCH_URL_COLUMN', value: AzureSearchUrlColumn} - { name: 'AZURE_OPENAI_RESOURCE', value: AzureOpenAIResource} - { name: 'AZURE_OPENAI_KEY', value: authType == 'keys' ? OpenAI.listKeys('2023-05-01').key1 : null} - { name: 'AZURE_OPENAI_MODEL', value: AzureOpenAIGPTModel} - { name: 'AZURE_OPENAI_MODEL_NAME', value: AzureOpenAIGPTModelName} - { name: 'AZURE_OPENAI_TEMPERATURE', value: AzureOpenAITemperature} - { name: 'AZURE_OPENAI_TOP_P', value: AzureOpenAITopP} - { name: 'AZURE_OPENAI_MAX_TOKENS', value: AzureOpenAIMaxTokens} - { name: 'AZURE_OPENAI_STOP_SEQUENCE', value: AzureOpenAIStopSequence} - { name: 'AZURE_OPENAI_SYSTEM_MESSAGE', value: AzureOpenAISystemMessage} - { name: 'AZURE_OPENAI_API_VERSION', value: AzureOpenAIApiVersion} - { name: 'AZURE_OPENAI_STREAM', value: AzureOpenAIStream} - { name: 'AZURE_OPENAI_EMBEDDING_MODEL', value: AzureOpenAIEmbeddingModel} - { name: 'AZURE_FORM_RECOGNIZER_ENDPOINT', value: 'https://${Location}.api.cognitive.microsoft.com/'} - { name: 'AZURE_FORM_RECOGNIZER_KEY', value: listKeys('Microsoft.CognitiveServices/accounts/${FormRecognizerName}', '2023-05-01').key1} - { name: 'AZURE_BLOB_ACCOUNT_NAME', value: StorageAccountName} - { name: 'AZURE_BLOB_ACCOUNT_KEY', value: listKeys(StorageAccount.id, '2019-06-01').keys[0].value} - { name: 'AZURE_BLOB_CONTAINER_NAME', value: BlobContainerName} - { name: 'ORCHESTRATION_STRATEGY', value: OrchestrationStrategy} - { name: 'AZURE_CONTENT_SAFETY_ENDPOINT', value: 'https://${Location}.api.cognitive.microsoft.com/'} - { name: 'AZURE_CONTENT_SAFETY_KEY', value: listKeys('Microsoft.CognitiveServices/accounts/${ContentSafetyName}', '2023-05-01').key1} - { name: 'AZURE_SPEECH_SERVICE_NAME', value: SpeechServiceName} - { name: 'AZURE_SPEECH_SERVICE_KEY', value: listKeys('Microsoft.CognitiveServices/accounts/${SpeechServiceName}', '2023-05-01').key1} - { name: 'AZURE_SPEECH_SERVICE_REGION', value: Location} + { name: 'AZURE_SEARCH_KEY', value: authType == 'keys' ? listAdminKeys('Microsoft.Search/searchServices/${AzureCognitiveSearch}', '2021-04-01-preview').primaryKey : null } + { name: 'AZURE_SEARCH_SEMANTIC_SEARCH_CONFIG', value: AzureSearchSemanticSearchConfig } + { name: 'AZURE_SEARCH_INDEX_IS_PRECHUNKED', value: AzureSearchIndexIsPrechunked } + { name: 'AZURE_SEARCH_TOP_K', value: AzureSearchTopK } + { name: 'AZURE_SEARCH_ENABLE_IN_DOMAIN', value: AzureSearchEnableInDomain } + { name: 'AZURE_SEARCH_CONTENT_COLUMNS', value: AzureSearchContentColumns } + { name: 'AZURE_SEARCH_FILENAME_COLUMN', value: AzureSearchFilenameColumn } + { name: 'AZURE_SEARCH_TITLE_COLUMN', value: AzureSearchTitleColumn } + { name: 'AZURE_SEARCH_URL_COLUMN', value: AzureSearchUrlColumn } + { name: 'AZURE_OPENAI_RESOURCE', value: AzureOpenAIResource } + { name: 'AZURE_OPENAI_KEY', value: authType == 'keys' ? OpenAI.listKeys('2023-05-01').key1 : null } + { name: 'AZURE_OPENAI_MODEL', value: AzureOpenAIGPTModel } + { name: 'AZURE_OPENAI_MODEL_NAME', value: AzureOpenAIGPTModelName } + { name: 'AZURE_OPENAI_TEMPERATURE', value: AzureOpenAITemperature } + { name: 'AZURE_OPENAI_TOP_P', value: AzureOpenAITopP } + { name: 'AZURE_OPENAI_MAX_TOKENS', value: AzureOpenAIMaxTokens } + { name: 'AZURE_OPENAI_STOP_SEQUENCE', value: AzureOpenAIStopSequence } + { name: 'AZURE_OPENAI_SYSTEM_MESSAGE', value: AzureOpenAISystemMessage } + { name: 'AZURE_OPENAI_API_VERSION', value: AzureOpenAIApiVersion } + { name: 'AZURE_OPENAI_STREAM', value: AzureOpenAIStream } + { name: 'AZURE_OPENAI_EMBEDDING_MODEL', value: AzureOpenAIEmbeddingModel } + { name: 'AZURE_FORM_RECOGNIZER_ENDPOINT', value: 'https://${Location}.api.cognitive.microsoft.com/' } + { name: 'AZURE_FORM_RECOGNIZER_KEY', value: listKeys('Microsoft.CognitiveServices/accounts/${FormRecognizerName}', '2023-05-01').key1 } + { name: 'AZURE_BLOB_ACCOUNT_NAME', value: StorageAccountName } + { name: 'AZURE_BLOB_ACCOUNT_KEY', value: listKeys(StorageAccount.id, '2019-06-01').keys[0].value } + { name: 'AZURE_BLOB_CONTAINER_NAME', value: BlobContainerName } + { name: 'ORCHESTRATION_STRATEGY', value: OrchestrationStrategy } + { name: 'AZURE_CONTENT_SAFETY_ENDPOINT', value: 'https://${Location}.api.cognitive.microsoft.com/' } + { name: 'AZURE_CONTENT_SAFETY_KEY', value: listKeys('Microsoft.CognitiveServices/accounts/${ContentSafetyName}', '2023-05-01').key1 } + { name: 'AZURE_SPEECH_SERVICE_NAME', value: SpeechServiceName } + { name: 'AZURE_SPEECH_SERVICE_KEY', value: listKeys('Microsoft.CognitiveServices/accounts/${SpeechServiceName}', '2023-05-01').key1 } + { name: 'AZURE_SPEECH_SERVICE_REGION', value: Location } ] linuxFxVersion: WebAppImageName minTlsVersion: '1.2' @@ -374,19 +374,19 @@ resource WebsiteName_admin 'Microsoft.Web/sites@2020-06-01' = { { name: 'APPINSIGHTS_INSTRUMENTATIONKEY', value: reference(ApplicationInsights.id, '2015-05-01').InstrumentationKey } { name: 'AZURE_SEARCH_SERVICE', value: 'https://${AzureCognitiveSearch}.search.windows.net' } { name: 'AZURE_AUTH_TYPE', value: authType } - { name: 'AZURE_SEARCH_KEY', value: authType == 'keys' ? listAdminKeys('Microsoft.Search/searchServices/${AzureCognitiveSearch}', '2021-04-01-preview').primaryKey : null} + { name: 'AZURE_SEARCH_KEY', value: authType == 'keys' ? listAdminKeys('Microsoft.Search/searchServices/${AzureCognitiveSearch}', '2021-04-01-preview').primaryKey : null } { name: 'AZURE_SEARCH_INDEX', value: AzureSearchIndex } { name: 'AZURE_SEARCH_USE_SEMANTIC_SEARCH', value: AzureSearchUseSemanticSearch } { name: 'AZURE_SEARCH_SEMANTIC_SEARCH_CONFIG', value: AzureSearchSemanticSearchConfig } { name: 'AZURE_SEARCH_INDEX_IS_PRECHUNKED', value: AzureSearchIndexIsPrechunked } { name: 'AZURE_SEARCH_TOP_K', value: AzureSearchTopK } { name: 'AZURE_SEARCH_ENABLE_IN_DOMAIN', value: AzureSearchEnableInDomain } - { name: 'AZURE_SEARCH_CONTENT_COLUMNS', value: AzureSearchContentColumns} + { name: 'AZURE_SEARCH_CONTENT_COLUMNS', value: AzureSearchContentColumns } { name: 'AZURE_SEARCH_FILENAME_COLUMN', value: AzureSearchFilenameColumn } - { name: 'AZURE_SEARCH_TITLE_COLUMN', value: AzureSearchTitleColumn} + { name: 'AZURE_SEARCH_TITLE_COLUMN', value: AzureSearchTitleColumn } { name: 'AZURE_SEARCH_URL_COLUMN', value: AzureSearchUrlColumn } - { name: 'AZURE_OPENAI_RESOURCE', value: AzureOpenAIResource} - { name: 'AZURE_OPENAI_KEY', value: authType == 'keys' ? OpenAI.listKeys('2023-05-01').key1 : null} + { name: 'AZURE_OPENAI_RESOURCE', value: AzureOpenAIResource } + { name: 'AZURE_OPENAI_KEY', value: authType == 'keys' ? OpenAI.listKeys('2023-05-01').key1 : null } { name: 'AZURE_OPENAI_MODEL', value: AzureOpenAIGPTModel } { name: 'AZURE_OPENAI_MODEL_NAME', value: AzureOpenAIGPTModelName } { name: 'AZURE_OPENAI_TEMPERATURE', value: AzureOpenAITemperature } @@ -402,12 +402,12 @@ resource WebsiteName_admin 'Microsoft.Web/sites@2020-06-01' = { { name: 'AZURE_BLOB_ACCOUNT_NAME', value: StorageAccountName } { name: 'AZURE_BLOB_ACCOUNT_KEY', value: listKeys(StorageAccount.id, '2019-06-01').keys[0].value } { name: 'AZURE_BLOB_CONTAINER_NAME', value: BlobContainerName } - { name: 'DOCUMENT_PROCESSING_QUEUE_NAME', value: QueueName} - { name: 'BACKEND_URL', value: 'https://${FunctionName}.azurewebsites.net'} - { name: 'FUNCTION_KEY', value: ClientKey} - { name: 'ORCHESTRATION_STRATEGY', value: OrchestrationStrategy} - { name: 'AZURE_CONTENT_SAFETY_ENDPOINT', value: 'https://${Location}.api.cognitive.microsoft.com/'} - { name: 'AZURE_CONTENT_SAFETY_KEY', value: listKeys('Microsoft.CognitiveServices/accounts/${ContentSafetyName}', '2023-05-01').key1} + { name: 'DOCUMENT_PROCESSING_QUEUE_NAME', value: QueueName } + { name: 'BACKEND_URL', value: 'https://${FunctionName}.azurewebsites.net' } + { name: 'FUNCTION_KEY', value: ClientKey } + { name: 'ORCHESTRATION_STRATEGY', value: OrchestrationStrategy } + { name: 'AZURE_CONTENT_SAFETY_ENDPOINT', value: 'https://${Location}.api.cognitive.microsoft.com/' } + { name: 'AZURE_CONTENT_SAFETY_KEY', value: listKeys('Microsoft.CognitiveServices/accounts/${ContentSafetyName}', '2023-05-01').key1 } ] linuxFxVersion: AdminWebAppImageName minTlsVersion: '1.2' @@ -479,7 +479,6 @@ resource StorageAccountName_default_doc_processing_poison 'Microsoft.Storage/sto dependsOn: [] } - resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-06-01' = { name: logAnalyticsWorkspaceName location: Location @@ -511,28 +510,28 @@ resource Function 'Microsoft.Web/sites@2018-11-01' = { properties: { siteConfig: { appSettings: [ - { name: 'FUNCTIONS_EXTENSION_VERSION', value: '~4'} - { name: 'WEBSITES_ENABLE_APP_SERVICE_STORAGE', value: 'false'} - { name: 'APPINSIGHTS_INSTRUMENTATIONKEY', value: reference(ApplicationInsights.id, '2015-05-01').InstrumentationKey} - { name: 'AzureWebJobsStorage', value: 'DefaultEndpointsProtocol=https;AccountName=${StorageAccountName};AccountKey=${listKeys(StorageAccount.id, '2019-06-01').keys[0].value};EndpointSuffix=core.windows.net'} + { name: 'FUNCTIONS_EXTENSION_VERSION', value: '~4' } + { name: 'WEBSITES_ENABLE_APP_SERVICE_STORAGE', value: 'false' } + { name: 'APPINSIGHTS_INSTRUMENTATIONKEY', value: reference(ApplicationInsights.id, '2015-05-01').InstrumentationKey } + { name: 'AzureWebJobsStorage', value: 'DefaultEndpointsProtocol=https;AccountName=${StorageAccountName};AccountKey=${listKeys(StorageAccount.id, '2019-06-01').keys[0].value};EndpointSuffix=core.windows.net' } { name: 'AZURE_AUTH_TYPE', value: authType } - { name: 'AZURE_OPENAI_MODEL', value: AzureOpenAIGPTModel} - { name: 'AZURE_OPENAI_EMBEDDING_MODEL', value: AzureOpenAIEmbeddingModel} - { name: 'AZURE_OPENAI_RESOURCE', value: AzureOpenAIResource} - { name: 'AZURE_OPENAI_KEY', value: authType == 'keys' ? OpenAI.listKeys('2023-05-01').key1 : null} - { name: 'AZURE_BLOB_ACCOUNT_NAME', value: StorageAccountName} - { name: 'AZURE_BLOB_ACCOUNT_KEY', value: listKeys(StorageAccount.id, '2019-06-01').keys[0].value} - { name: 'AZURE_BLOB_CONTAINER_NAME', value: BlobContainerName} - { name: 'AZURE_FORM_RECOGNIZER_ENDPOINT', value: 'https://${Location}.api.cognitive.microsoft.com/'} - { name: 'AZURE_FORM_RECOGNIZER_KEY', value: listKeys('Microsoft.CognitiveServices/accounts/${FormRecognizerName}', '2023-05-01').key1} - { name: 'AZURE_SEARCH_SERVICE', value: 'https://${AzureCognitiveSearch}.search.windows.net'} - { name: 'AZURE_SEARCH_KEY', value: authType == 'keys' ? listAdminKeys('Microsoft.Search/searchServices/${AzureCognitiveSearch}', '2021-04-01-preview').primaryKey : null} - { name: 'DOCUMENT_PROCESSING_QUEUE_NAME', value: QueueName} - { name: 'AZURE_OPENAI_API_VERSION', value: AzureOpenAIApiVersion} - { name: 'AZURE_SEARCH_INDEX', value: AzureSearchIndex} - { name: 'ORCHESTRATION_STRATEGY', value: OrchestrationStrategy} - { name: 'AZURE_CONTENT_SAFETY_ENDPOINT', value: 'https://${Location}.api.cognitive.microsoft.com/'} - { name: 'AZURE_CONTENT_SAFETY_KEY', value: listKeys('Microsoft.CognitiveServices/accounts/${ContentSafetyName}', '2023-05-01').key1} + { name: 'AZURE_OPENAI_MODEL', value: AzureOpenAIGPTModel } + { name: 'AZURE_OPENAI_EMBEDDING_MODEL', value: AzureOpenAIEmbeddingModel } + { name: 'AZURE_OPENAI_RESOURCE', value: AzureOpenAIResource } + { name: 'AZURE_OPENAI_KEY', value: authType == 'keys' ? OpenAI.listKeys('2023-05-01').key1 : null } + { name: 'AZURE_BLOB_ACCOUNT_NAME', value: StorageAccountName } + { name: 'AZURE_BLOB_ACCOUNT_KEY', value: listKeys(StorageAccount.id, '2019-06-01').keys[0].value } + { name: 'AZURE_BLOB_CONTAINER_NAME', value: BlobContainerName } + { name: 'AZURE_FORM_RECOGNIZER_ENDPOINT', value: 'https://${Location}.api.cognitive.microsoft.com/' } + { name: 'AZURE_FORM_RECOGNIZER_KEY', value: listKeys('Microsoft.CognitiveServices/accounts/${FormRecognizerName}', '2023-05-01').key1 } + { name: 'AZURE_SEARCH_SERVICE', value: 'https://${AzureCognitiveSearch}.search.windows.net' } + { name: 'AZURE_SEARCH_KEY', value: authType == 'keys' ? listAdminKeys('Microsoft.Search/searchServices/${AzureCognitiveSearch}', '2021-04-01-preview').primaryKey : null } + { name: 'DOCUMENT_PROCESSING_QUEUE_NAME', value: QueueName } + { name: 'AZURE_OPENAI_API_VERSION', value: AzureOpenAIApiVersion } + { name: 'AZURE_SEARCH_INDEX', value: AzureSearchIndex } + { name: 'ORCHESTRATION_STRATEGY', value: OrchestrationStrategy } + { name: 'AZURE_CONTENT_SAFETY_ENDPOINT', value: 'https://${Location}.api.cognitive.microsoft.com/' } + { name: 'AZURE_CONTENT_SAFETY_KEY', value: listKeys('Microsoft.CognitiveServices/accounts/${ContentSafetyName}', '2023-05-01').key1 } ] cors: { allowedOrigins: [ @@ -688,7 +687,7 @@ module openAiRoleBackend 'security/role.bicep' = if (authType == 'rbac') { scope: resourceGroup() name: 'openai-role-backend' params: { - principalId: Website.identity.principalId + principalId: Website.identity.principalId roleDefinitionId: '5e0bd9bd-7b93-4f28-af87-19fc36ad61bd' principalType: 'ServicePrincipal' } @@ -828,7 +827,7 @@ module searchReaderRoleBackend 'security/role.bicep' = if (authType == 'rbac') { } // Reader role for Function resource - // Used to read index definitions +// Used to read index definitions module searchReaderRoleFunction 'security/role.bicep' = if (authType == 'rbac') { scope: resourceGroup() name: 'search-reader-role-function' @@ -840,7 +839,7 @@ module searchReaderRoleFunction 'security/role.bicep' = if (authType == 'rbac') } // Reader role for Admin Website resource - // Used to read index definitions +// Used to read index definitions module searchReaderRoleAdmin 'security/role.bicep' = if (authType == 'rbac') { scope: resourceGroup() name: 'search-reader-role-admin' @@ -852,8 +851,8 @@ module searchReaderRoleAdmin 'security/role.bicep' = if (authType == 'rbac') { } // Reader role for Admin Website resource - // Used to read index definitions - module searchReaderRoleUser 'security/role.bicep' = if (authType == 'rbac' && principalId != '') { +// Used to read index definitions +module searchReaderRoleUser 'security/role.bicep' = if (authType == 'rbac' && principalId != '') { scope: resourceGroup() name: 'search-reader-role-user' params: { @@ -905,4 +904,4 @@ module searchIndexDataContUser 'security/role.bicep' = if (authType == 'rbac' && roleDefinitionId: '8ebe5a00-799e-43f5-93ac-243d3dce84a7' principalType: 'User' } -} +} \ No newline at end of file diff --git a/infra/security/role.bicep b/infra/security/role.bicep index 0b30cfd34..255ad51b4 100644 --- a/infra/security/role.bicep +++ b/infra/security/role.bicep @@ -18,4 +18,4 @@ resource role 'Microsoft.Authorization/roleAssignments@2022-04-01' = { principalType: principalType roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId) } -} +} \ No newline at end of file diff --git a/scripts/generate_arm_templates.sh b/scripts/generate_arm_templates.sh new file mode 100755 index 000000000..a9208105f --- /dev/null +++ b/scripts/generate_arm_templates.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +set -e + +az bicep version 2>/dev/null || az bicep install + +TEMPLATES=() + +for ARG in $@; do + # If the argument is supplied with "-f", then it is a template file that needs to be built + if [[ $ARG == -f=* ]]; then + TEMPLATES+=(${ARG#-f=}) + else + # Otherwise, it is a file that has been edited + az bicep format -f $ARG + git add $ARG + fi +done + +# Build the templates +for TEMPLATE in ${TEMPLATES[@]}; do + az bicep build -f $TEMPLATE + git add "${TEMPLATE%.bicep}.json" # Change the extension from .bicep to .json +done From e2c0f08481084f6e7fd1151e46254feb8f9e8390 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 09:44:29 +0000 Subject: [PATCH 4/7] Bump flask from 3.0.0 to 3.0.2 in /code (#269) Bumps [flask](https://github.com/pallets/flask) from 3.0.0 to 3.0.2. - [Release notes](https://github.com/pallets/flask/releases) - [Changelog](https://github.com/pallets/flask/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/flask/compare/3.0.0...3.0.2) --- updated-dependencies: - dependency-name: flask dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- code/app/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/app/requirements.txt b/code/app/requirements.txt index 29265d841..e2c6a0132 100644 --- a/code/app/requirements.txt +++ b/code/app/requirements.txt @@ -1,5 +1,5 @@ azure-identity==1.15.0 -Flask==3.0.0 +Flask==3.0.2 openai==0.27.8 azure-storage-blob==12.19.0 python-dotenv==1.0.1 From f04d6e16be435e0bcfeb0f8986ea723a888c6200 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 09:44:49 +0000 Subject: [PATCH 5/7] Bump black from 23.12.1 to 24.1.1 in /code (#270) Bumps [black](https://github.com/psf/black) from 23.12.1 to 24.1.1. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/23.12.1...24.1.1) --- updated-dependencies: - dependency-name: black dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- code/dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/dev-requirements.txt b/code/dev-requirements.txt index 39cf2c15b..396b6abac 100644 --- a/code/dev-requirements.txt +++ b/code/dev-requirements.txt @@ -2,4 +2,4 @@ pytest==8.0.0 pytest-cov==4.1.0 flake8==7.0.0 pre-commit==3.6.0 -black==23.12.1 +black==24.1.1 From 4756cd1d009a2afd3b34cba6c3c38df5d66cb4e9 Mon Sep 17 00:00:00 2001 From: Adam Dougal Date: Thu, 8 Feb 2024 20:51:40 +0000 Subject: [PATCH 6/7] Fix IndexError when collating chat history (#195) * Fix IndexError when collating chat history This fixes a bug which causes the exception: ``` ERROR:root:Exception in /api/conversation/custom | list index out of range Traceback (most recent call last): File "/workspaces/chat-with-your-data-solution-accelerator/code/app/app.py", line 283, in conversation_custom chat_history.append((user_assistant_messages[i]['content'],user_assistant_messages[i+1]['content'])) ``` This is caused when there has been an error providing a response, and the latest message in the history is from a user, rather than the assitant. Our code assumes a user message is always followed by an assistant message. This change removes that assumption and explitely retreives the role for each message when collating the chat history. Required by https://github.com/Azure-Samples/chat-with-your-data-solution-accelerator/issues/114 * Add python formatter to dev container * Add tests for conversation custom - Extract some elements to dedicated function to allow mocking * Switch to black formatter to align with precommit hook * Add test to cover error scenario when message index is out of range * Add dependencies required for running app tests --------- Co-authored-by: Ross Smith --- .devcontainer/devcontainer.json | 1 + .github/workflows/unittests.yml | 2 +- code/app/app.py | 30 ++-- code/utilities/orchestrator/LangChainAgent.py | 6 +- .../utilities/orchestrator/OpenAIFunctions.py | 3 +- tests/test_app.py | 161 ++++++++++++++++++ 6 files changed, 183 insertions(+), 20 deletions(-) create mode 100644 tests/test_app.py diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 6e66ca3a3..b213342df 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -23,6 +23,7 @@ "ms-azuretools.vscode-bicep", "ms-azuretools.vscode-docker", "ms-python.python", + "ms-python.black-formatter", "ms-python.vscode-pylance", "ms-vscode.vscode-node-azure-pack", "TeamsDevApp.ms-teams-vscode-extension" diff --git a/.github/workflows/unittests.yml b/.github/workflows/unittests.yml index eb0cefec8..7c0f6583f 100644 --- a/.github/workflows/unittests.yml +++ b/.github/workflows/unittests.yml @@ -20,6 +20,6 @@ jobs: architecture: x64 - name: Install dependencies run: | - pip install -r code/requirements.txt -r code/dev-requirements.txt + pip install -r code/requirements.txt -r code/dev-requirements.txt -r code/app/requirements.txt - name: Run Python tests run: python -m pytest --rootdir=code -m "not azure" diff --git a/code/app/app.py b/code/app/app.py index 3b92116b7..5ec28fd4b 100644 --- a/code/app/app.py +++ b/code/app/app.py @@ -313,11 +313,21 @@ def conversation_azure_byod(): ) -@app.route("/api/conversation/custom", methods=["GET", "POST"]) -def conversation_custom(): +def get_message_orchestrator(): from utilities.helpers.OrchestratorHelper import Orchestrator - message_orchestrator = Orchestrator() + return Orchestrator() + + +def get_orchestrator_config(): + from utilities.helpers.ConfigHelper import ConfigHelper + + return ConfigHelper.get_active_config_or_default().orchestrator + + +@app.route("/api/conversation/custom", methods=["GET", "POST"]) +def conversation_custom(): + message_orchestrator = get_message_orchestrator() try: user_message = request.json["messages"][-1]["content"] @@ -328,22 +338,12 @@ def conversation_custom(): request.json["messages"][0:-1], ) ) - chat_history = [] - for i, k in enumerate(user_assistant_messages): - if i % 2 == 0: - chat_history.append( - ( - user_assistant_messages[i]["content"], - user_assistant_messages[i + 1]["content"], - ) - ) - from utilities.helpers.ConfigHelper import ConfigHelper messages = message_orchestrator.handle_message( user_message=user_message, - chat_history=chat_history, + chat_history=user_assistant_messages, conversation_id=conversation_id, - orchestrator=ConfigHelper.get_active_config_or_default().orchestrator, + orchestrator=get_orchestrator_config(), ) response_obj = { diff --git a/code/utilities/orchestrator/LangChainAgent.py b/code/utilities/orchestrator/LangChainAgent.py index 445cf1598..5f02f60b7 100644 --- a/code/utilities/orchestrator/LangChainAgent.py +++ b/code/utilities/orchestrator/LangChainAgent.py @@ -89,8 +89,10 @@ def orchestrate( memory_key="chat_history", return_messages=True ) for message in chat_history: - memory.chat_memory.add_user_message(message[0]) - memory.chat_memory.add_ai_message(message[1]) + if message["role"] == "user": + memory.chat_memory.add_user_message(message["content"]) + elif message["role"] == "assistant": + memory.chat_memory.add_ai_message(message["content"]) # Define Agent and Agent Chain llm_chain = LLMChain(llm=llm_helper.get_llm(), prompt=prompt) agent = ZeroShotAgent(llm_chain=llm_chain, tools=self.tools, verbose=True) diff --git a/code/utilities/orchestrator/OpenAIFunctions.py b/code/utilities/orchestrator/OpenAIFunctions.py index c132f2ce0..ab7c8b8f4 100644 --- a/code/utilities/orchestrator/OpenAIFunctions.py +++ b/code/utilities/orchestrator/OpenAIFunctions.py @@ -81,8 +81,7 @@ def orchestrate( # Create conversation history messages = [{"role": "system", "content": system_message}] for message in chat_history: - messages.append({"role": "user", "content": message[0]}) - messages.append({"role": "assistant", "content": message[1]}) + messages.append({"role": message["role"], "content": message["content"]}) messages.append({"role": "user", "content": user_message}) result = llm_helper.get_chat_completion_with_functions( diff --git a/tests/test_app.py b/tests/test_app.py new file mode 100644 index 000000000..6466f5698 --- /dev/null +++ b/tests/test_app.py @@ -0,0 +1,161 @@ +import os + +from unittest.mock import Mock +from unittest.mock import patch + +from code.app.app import app + + +class TestConfig: + def test_returns_correct_config(self): + response = app.test_client().get("/api/config") + + assert response.status_code == 200 + assert response.json == {"azureSpeechKey": None, "azureSpeechRegion": None} + + +class TestCoversationCustom: + def setup_method(self): + self.orchestrator_config = {"strategy": "langchain"} + self.messages = [ + { + "content": '{"citations": [], "intent": "A question?"}', + "end_turn": False, + "role": "tool", + }, + {"content": "An answer", "end_turn": True, "role": "assistant"}, + ] + self.openai_model = "some-model" + self.body = { + "conversation_id": "123", + "messages": [ + {"role": "user", "content": "Hello"}, + {"role": "assistant", "content": "Hi, how can I help?"}, + {"role": "user", "content": "What is the meaning of life?"}, + ], + } + + @patch("code.app.app.get_message_orchestrator") + @patch("code.app.app.get_orchestrator_config") + def test_converstation_custom_returns_correct_response( + self, get_orchestrator_config_mock, get_message_orchestrator_mock + ): + # given + get_orchestrator_config_mock.return_value = self.orchestrator_config + + message_orchestrator_mock = Mock() + message_orchestrator_mock.handle_message.return_value = self.messages + get_message_orchestrator_mock.return_value = message_orchestrator_mock + + os.environ["AZURE_OPENAI_MODEL"] = self.openai_model + + # when + response = app.test_client().post( + "/api/conversation/custom", + headers={"content-type": "application/json"}, + json=self.body, + ) + + # then + assert response.status_code == 200 + assert response.json == { + "choices": [{"messages": self.messages}], + "created": "response.created", + "id": "response.id", + "model": self.openai_model, + "object": "response.object", + } + + @patch("code.app.app.get_message_orchestrator") + @patch("code.app.app.get_orchestrator_config") + def test_converstation_custom_calls_message_orchestrator_correctly( + self, get_orchestrator_config_mock, get_message_orchestrator_mock + ): + # given + get_orchestrator_config_mock.return_value = self.orchestrator_config + + message_orchestrator_mock = Mock() + message_orchestrator_mock.handle_message.return_value = self.messages + get_message_orchestrator_mock.return_value = message_orchestrator_mock + + os.environ["AZURE_OPENAI_MODEL"] = self.openai_model + + # when + app.test_client().post( + "/api/conversation/custom", + headers={"content-type": "application/json"}, + json=self.body, + ) + + # then + message_orchestrator_mock.handle_message.assert_called_once_with( + user_message=self.body["messages"][-1]["content"], + chat_history=self.body["messages"][:-1], + conversation_id=self.body["conversation_id"], + orchestrator=self.orchestrator_config, + ) + + @patch("code.app.app.get_orchestrator_config") + def test_converstation_custom_returns_error_resonse_on_exception( + self, get_orchestrator_config_mock + ): + # given + get_orchestrator_config_mock.side_effect = Exception("An error occurred") + + # when + response = app.test_client().post( + "/api/conversation/custom", + headers={"content-type": "application/json"}, + json=self.body, + ) + + # then + assert response.status_code == 500 + assert response.json == { + "error": "Exception in /api/conversation/custom. See log for more details." + } + + @patch("code.app.app.get_message_orchestrator") + @patch("code.app.app.get_orchestrator_config") + def test_converstation_custom_allows_multiple_messages_from_user( + self, get_orchestrator_config_mock, get_message_orchestrator_mock + ): + """This can happen if there was an error getting a response from the assistant for the previous user message.""" + + # given + get_orchestrator_config_mock.return_value = self.orchestrator_config + + message_orchestrator_mock = Mock() + message_orchestrator_mock.handle_message.return_value = self.messages + get_message_orchestrator_mock.return_value = message_orchestrator_mock + + os.environ["AZURE_OPENAI_MODEL"] = self.openai_model + + body = { + "conversation_id": "123", + "messages": [ + {"role": "user", "content": "Hello"}, + {"role": "assistant", "content": "Hi, how can I help?"}, + {"role": "user", "content": "What is the meaning of life?"}, + { + "role": "user", + "content": "Please, what is the meaning of life?", + }, + ], + } + + # when + response = app.test_client().post( + "/api/conversation/custom", + headers={"content-type": "application/json"}, + json=body, + ) + + # then + assert response.status_code == 200 + message_orchestrator_mock.handle_message.assert_called_once_with( + user_message=body["messages"][-1]["content"], + chat_history=body["messages"][:-1], + conversation_id=body["conversation_id"], + orchestrator=self.orchestrator_config, + ) From f7dd41ed4def1007465c526320fe9eb9173ecbee Mon Sep 17 00:00:00 2001 From: komalg1 Date: Mon, 12 Feb 2024 13:20:07 +0000 Subject: [PATCH 7/7] fix for uploading jpg & png (#286) --- code/utilities/helpers/ConfigHelper.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/code/utilities/helpers/ConfigHelper.py b/code/utilities/helpers/ConfigHelper.py index bb6473488..43cab0090 100644 --- a/code/utilities/helpers/ConfigHelper.py +++ b/code/utilities/helpers/ConfigHelper.py @@ -184,6 +184,24 @@ def get_default_config(): }, "loading": {"strategy": LoadingStrategy.DOCX}, }, + { + "document_type": "jpg", + "chunking": { + "strategy": ChunkingStrategy.LAYOUT, + "size": 500, + "overlap": 100, + }, + "loading": {"strategy": LoadingStrategy.LAYOUT}, + }, + { + "document_type": "png", + "chunking": { + "strategy": ChunkingStrategy.LAYOUT, + "size": 500, + "overlap": 100, + }, + "loading": {"strategy": LoadingStrategy.LAYOUT}, + }, ], "logging": {"log_user_interactions": True, "log_tokens": True}, "orchestrator": {"strategy": "openai_function"},