From a618fc774db2f54b58d55f24de5ed448561b69b7 Mon Sep 17 00:00:00 2001 From: Jim Counts Date: Mon, 8 Jul 2024 16:59:44 +0000 Subject: [PATCH 01/36] Initial draft --- deploy/quick-start/scripts/New-Backup.ps1 | 78 +++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 deploy/quick-start/scripts/New-Backup.ps1 diff --git a/deploy/quick-start/scripts/New-Backup.ps1 b/deploy/quick-start/scripts/New-Backup.ps1 new file mode 100644 index 0000000000..ed4dddb6f1 --- /dev/null +++ b/deploy/quick-start/scripts/New-Backup.ps1 @@ -0,0 +1,78 @@ +#!/usr/bin/env pwsh + +Param( + [Parameter(Mandatory = $true)][string]$resourceGroup +) + +Set-PSDebug -Trace 0 # Echo every command (0 to disable, 1 to enable) +Set-StrictMode -Version 3.0 +$ErrorActionPreference = "Stop" + +function Get-AbsolutePath { + <# + .SYNOPSIS + Get the absolute path of a file or directory. Relative path does not need to exist. + #> + param ( + [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)] + [string]$RelatviePath + ) + + return $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($RelatviePath) +} + +function Invoke-CLICommand { + <# + .SYNOPSIS + Invoke a CLI Command and allow all output to print to the terminal. Does not check for return values or pass the output to the caller. + #> + param ( + [Parameter(Mandatory = $true, Position = 0)] + [string]$Message, + + [Parameter(Mandatory = $true, Position = 1)] + [ScriptBlock]$ScriptBlock + ) + + Write-Host "${message}..." -ForegroundColor Blue + & $ScriptBlock + + if ($LASTEXITCODE -ne 0) { + throw "Failed ${message} (code: ${LASTEXITCODE})" + } +} + +# Navigate to the script directory so that we can use relative paths. +Push-Location $($MyInvocation.InvocationName | Split-Path) +try { + $testDataPath = "../data/backup/$resourceGroup" | Get-AbsolutePath + Write-Host "Writing environment files to: $testDataPath" -ForegroundColor Yellow + # Create test data path if it doesn't already exist + if (-not (Test-Path $testDataPath)) { + New-Item -ItemType Directory -Path $testDataPath + } + + # Invoke-CLICommand "Copy vectorization-input data from the storage account: ${storageAccountName}" { + # azcopy copy "https://$($storageAccountName).blob.core.windows.net/e2e/vectorization-input" $testDataPath --recursive + # } + + # Write-Host "Writing index-backup data to: $testDataPath" -ForegroundColor Yellow + # Invoke-CLICommand "Copy index-backup data from the storage account: ${storageAccountName}" { + # azcopy copy "https://$($storageAccountName).blob.core.windows.net/e2e/index-backup" $testDataPath --recursive + # } +} +catch { + $logFile = Get-ChildItem -Path "$env:HOME/.azcopy" -Filter "*.log" | ` + Where-Object { $_.Name -notlike "*-scanning*" } | ` + Sort-Object LastWriteTime -Descending | ` + Select-Object -First 1 + $logFileContent = Get-Content -Raw -Path $logFile.FullName + Write-Host $logFileContent +} +finally { + Pop-Location + Set-PSDebug -Trace 0 # Echo every command (0 to disable, 1 to enable) +} + +# Copy the storage account contents +# Copy the indexes \ No newline at end of file From 6b75d3dbe3a9edb2d395fe76958a984ceb2adef4 Mon Sep 17 00:00:00 2001 From: saimachi Date: Mon, 8 Jul 2024 21:51:26 -0400 Subject: [PATCH 02/36] Added code to recursively back up Storage Account. --- deploy/quick-start/scripts/New-Backup.ps1 | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/deploy/quick-start/scripts/New-Backup.ps1 b/deploy/quick-start/scripts/New-Backup.ps1 index ed4dddb6f1..8365a81aaa 100644 --- a/deploy/quick-start/scripts/New-Backup.ps1 +++ b/deploy/quick-start/scripts/New-Backup.ps1 @@ -52,14 +52,20 @@ try { New-Item -ItemType Directory -Path $testDataPath } - # Invoke-CLICommand "Copy vectorization-input data from the storage account: ${storageAccountName}" { - # azcopy copy "https://$($storageAccountName).blob.core.windows.net/e2e/vectorization-input" $testDataPath --recursive - # } + # Check if container exists in the storage account + az storage container create -n backups --account-name foundationallmdata - # Write-Host "Writing index-backup data to: $testDataPath" -ForegroundColor Yellow - # Invoke-CLICommand "Copy index-backup data from the storage account: ${storageAccountName}" { - # azcopy copy "https://$($storageAccountName).blob.core.windows.net/e2e/index-backup" $testDataPath --recursive - # } + # Get main storage account + $numStorageAccounts = az storage account list -g $resourceGroup --query "length(@ )" + if ($numStorageAccounts -eq 0) { + throw "There are $numStorageAccounts storage accounts in $resourceGroup. Target a resource group with one storage account." + } + $sourceStorageAccountName = (az storage account list -g $resourceGroup --query "@[0].name").Trim('"') + + $env:AZCOPY_AUTO_LOGIN_TYPE="AZCLI" + foreach ($container in ((az storage container list --account-name $sourceStorageAccountName --query "@[].name" --auth-mode login) | ConvertFrom-Json)) { + azcopy copy "https://$($sourceStorageAccountName).blob.core.windows.net/$container/" "https://foundationallmdata.blob.core.windows.net/backups/$resourceGroup/" --recursive + } } catch { $logFile = Get-ChildItem -Path "$env:HOME/.azcopy" -Filter "*.log" | ` From c26000974efa8884b9a1a29a4bc1f41019080248 Mon Sep 17 00:00:00 2001 From: saimachi Date: Tue, 9 Jul 2024 18:39:53 -0400 Subject: [PATCH 03/36] Added index backup step to backup script. Use tags to find unique resources. --- deploy/quick-start/scripts/New-Backup.ps1 | 133 +++++++++++++--------- 1 file changed, 81 insertions(+), 52 deletions(-) diff --git a/deploy/quick-start/scripts/New-Backup.ps1 b/deploy/quick-start/scripts/New-Backup.ps1 index 8365a81aaa..2ca44b9916 100644 --- a/deploy/quick-start/scripts/New-Backup.ps1 +++ b/deploy/quick-start/scripts/New-Backup.ps1 @@ -1,84 +1,113 @@ #!/usr/bin/env pwsh Param( - [Parameter(Mandatory = $true)][string]$resourceGroup + [Parameter(Mandatory = $true)][string]$resourceGroup, + [Parameter(Mandatory = $true)][string]$destinationStorageAccount ) Set-PSDebug -Trace 0 # Echo every command (0 to disable, 1 to enable) Set-StrictMode -Version 3.0 $ErrorActionPreference = "Stop" -function Get-AbsolutePath { - <# - .SYNOPSIS - Get the absolute path of a file or directory. Relative path does not need to exist. - #> - param ( - [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)] - [string]$RelatviePath +function Get-SearchServiceIndexes { + param( + [Parameter(Mandatory = $true)][string]$searchServiceName, + [Parameter(Mandatory = $true)][string]$pathPrefix ) - return $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($RelatviePath) -} + # Credit: https://daron.blog/2021/backup-and-restore-azure-cognitive-search-indexes-with-powershell/ + # Updated script to use Entra tokens for authentication -function Invoke-CLICommand { - <# - .SYNOPSIS - Invoke a CLI Command and allow all output to print to the terminal. Does not check for return values or pass the output to the caller. - #> - param ( - [Parameter(Mandatory = $true, Position = 0)] - [string]$Message, - - [Parameter(Mandatory = $true, Position = 1)] - [ScriptBlock]$ScriptBlock - ) + $serviceUri = "https://$searchServiceName.search.windows.net" + $uri = $serviceUri + "/indexes?api-version=2020-06-30&`$select=name" + $token = $(az account get-access-token --query accessToken --output tsv --scope "https://search.azure.com/.default") + $headers = @{"Authorization" = "Bearer $token"; "Accept" = "application/json"; "ContentType" = "application/json; charset=utf-8"} + + $indexes = $(Invoke-RestMethod -Uri $uri -Method GET -Headers $headers).value.name + foreach ($index in $indexes) { + $uri = $serviceUri ` + + "/indexes/$index/docs/`$count?api-version=2020-06-30" + $req = [System.Net.WebRequest]::Create($uri) + + $req.ContentType = "application/json; charset=utf-8" + $req.Accept = "application/json" + $req.Headers["Authorization"] = "Bearer $token" - Write-Host "${message}..." -ForegroundColor Blue - & $ScriptBlock + $resp = $req.GetResponse() + $reader = new-object System.IO.StreamReader($resp.GetResponseStream()) + $result = $reader.ReadToEnd() + $documentCount = [int]$result - if ($LASTEXITCODE -ne 0) { - throw "Failed ${message} (code: ${LASTEXITCODE})" + $pageCount = [math]::ceiling($documentCount / 500) + + $job = 1..$pageCount | ForEach-Object -Parallel { + $skip = ($_ - 1) * 500 + $uri = $using:serviceUri + "/indexes/$($using:index)/docs?api-version=2020-06-30&search=*&`$skip=$($skip)&`$top=500&searchMode=all" + $outputPath = "$($using:index)_$($_).json" + Invoke-RestMethod -Uri $uri -Method GET -Headers $using:headers -ContentType "application/json" | + ConvertTo-Json -Depth 9 | + Set-Content $outputPath + "Output: $uri" + azcopy copy $outputPath "$($using:pathPrefix)/$($using:index)/" + } -ThrottleLimit 5 -AsJob + $job | Receive-Job -Wait } } # Navigate to the script directory so that we can use relative paths. Push-Location $($MyInvocation.InvocationName | Split-Path) try { - $testDataPath = "../data/backup/$resourceGroup" | Get-AbsolutePath - Write-Host "Writing environment files to: $testDataPath" -ForegroundColor Yellow - # Create test data path if it doesn't already exist - if (-not (Test-Path $testDataPath)) { - New-Item -ItemType Directory -Path $testDataPath - } - - # Check if container exists in the storage account - az storage container create -n backups --account-name foundationallmdata + # Create backups container + az storage container create -n backups --account-name $destinationStorageAccount # Get main storage account - $numStorageAccounts = az storage account list -g $resourceGroup --query "length(@ )" - if ($numStorageAccounts -eq 0) { - throw "There are $numStorageAccounts storage accounts in $resourceGroup. Target a resource group with one storage account." + $sourceStorageAccountName = "" + foreach ($resourceId in (az storage account list -g $resourceGroup --query "@[].id" --output tsv)) { + if ((az tag list --resource-id $resourceId --query "contains(keys(@.properties.tags), 'azd-env-name')") -eq $true) { + $sourceStorageAccountName = $(az resource show --ids $resourceId --query "@.name" --output tsv) + Write-Host "Selecting $sourceStorageAccountName as the storage account" + break; + } + } + + if ([string]::IsNullOrEmpty($sourceStorageAccountName)) { + throw "Could not find any storage accounts with the azd-env-name tag in $resourceGroup." } - $sourceStorageAccountName = (az storage account list -g $resourceGroup --query "@[0].name").Trim('"') + # Recursively copy storage account contents $env:AZCOPY_AUTO_LOGIN_TYPE="AZCLI" - foreach ($container in ((az storage container list --account-name $sourceStorageAccountName --query "@[].name" --auth-mode login) | ConvertFrom-Json)) { - azcopy copy "https://$($sourceStorageAccountName).blob.core.windows.net/$container/" "https://foundationallmdata.blob.core.windows.net/backups/$resourceGroup/" --recursive + foreach ($container in (az storage container list --account-name $sourceStorageAccountName --query "@[].name" --auth-mode login -o tsv)) { + azcopy copy "https://$($sourceStorageAccountName).blob.core.windows.net/$container/" "https://$destinationStorageAccount.blob.core.windows.net/backups/$resourceGroup/" --recursive + } + + $sourceSearchServiceName = "" + foreach ($resourceId in (az search service list -g $resourceGroup --query "@[].id" --output tsv)) { + if ((az tag list --resource-id $resourceId --query "contains(keys(@.properties.tags), 'azd-env-name')") -eq $true) { + $sourceSearchServiceName = $(az resource show --ids $resourceId --query "@.name" --output tsv) + Write-Host "Selecting $sourceSearchServiceName as the search service" + break; + } + } + + if ([string]::IsNullOrEmpty($sourceSearchServiceName)) { + throw "Could not find any search services with the azd-env-name tag in $resourceGroup." } + + # Save Search Indexes + Get-SearchServiceIndexes -searchServiceName $sourceSearchServiceName -pathPrefix "https://$destinationStorageAccount.blob.core.windows.net/backups/$resourceGroup/data-sources/indexes" } catch { - $logFile = Get-ChildItem -Path "$env:HOME/.azcopy" -Filter "*.log" | ` - Where-Object { $_.Name -notlike "*-scanning*" } | ` - Sort-Object LastWriteTime -Descending | ` - Select-Object -First 1 - $logFileContent = Get-Content -Raw -Path $logFile.FullName - Write-Host $logFileContent + if (Test-Path -Path "$env:HOME/.azcopy") { + $logFile = Get-ChildItem -Path "$env:HOME/.azcopy" -Filter "*.log" | ` + Where-Object { $_.Name -notlike "*-scanning*" } | ` + Sort-Object LastWriteTime -Descending | ` + Select-Object -First 1 + $logFileContent = Get-Content -Raw -Path $logFile.FullName + Write-Host $logFileContent + } + Write-Host $_.Exception.Message } finally { Pop-Location Set-PSDebug -Trace 0 # Echo every command (0 to disable, 1 to enable) -} - -# Copy the storage account contents -# Copy the indexes \ No newline at end of file +} \ No newline at end of file From d35937110f20c9345433c65b8d293d3de0235ad4 Mon Sep 17 00:00:00 2001 From: Austin Hulen Date: Mon, 29 Jul 2024 08:01:11 -0700 Subject: [PATCH 04/36] Update attached file label in ChatInput component --- src/ui/UserPortal/components/ChatInput.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/UserPortal/components/ChatInput.vue b/src/ui/UserPortal/components/ChatInput.vue index 85cb6ae57b..8bba2f431c 100644 --- a/src/ui/UserPortal/components/ChatInput.vue +++ b/src/ui/UserPortal/components/ChatInput.vue @@ -14,7 +14,7 @@ />
-

Attached Files

+

Attached File

{{ file.fileName }}
@@ -30,7 +30,7 @@
- No files attached + No file attached
From 50378fd0aa9b1daa9ee5968bd0c77fbbf27d9240 Mon Sep 17 00:00:00 2001 From: Austin Hulen Date: Mon, 29 Jul 2024 08:28:38 -0700 Subject: [PATCH 05/36] Update file upload confirmation dialog labels --- src/ui/UserPortal/components/ChatInput.vue | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/ui/UserPortal/components/ChatInput.vue b/src/ui/UserPortal/components/ChatInput.vue index 8bba2f431c..7008f9de8d 100644 --- a/src/ui/UserPortal/components/ChatInput.vue +++ b/src/ui/UserPortal/components/ChatInput.vue @@ -262,19 +262,21 @@ export default { message: 'Uploading a new file will replace the file already attached.', header: 'Confirm File Replacement', icon: 'pi pi-exclamation-triangle', + rejectLabel: 'Upload', + acceptLabel: 'Cancel', rejectProps: { + label: 'Upload', + }, + acceptProps: { label: 'Cancel', severity: 'secondary', outlined: true }, - acceptProps: { - label: 'Upload' - }, accept: () => { - uploadCallback(); this.showFileUploadDialog = false; }, reject: () => { + uploadCallback(); this.showFileUploadDialog = false; } }); From 54128c62bd3925788ae6365f8877115e63c7039f Mon Sep 17 00:00:00 2001 From: Austin Hulen Date: Mon, 29 Jul 2024 09:15:17 -0700 Subject: [PATCH 06/36] Update file upload functionality to filter attachments by session ID --- src/ui/UserPortal/components/ChatInput.vue | 18 ++++++++++++------ src/ui/UserPortal/js/types/index.ts | 1 + src/ui/UserPortal/stores/appStore.ts | 15 +++++++++++---- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/ui/UserPortal/components/ChatInput.vue b/src/ui/UserPortal/components/ChatInput.vue index 7008f9de8d..2e525642b8 100644 --- a/src/ui/UserPortal/components/ChatInput.vue +++ b/src/ui/UserPortal/components/ChatInput.vue @@ -8,14 +8,14 @@ class="file-upload-button secondary-button" style="height: 100%;" @click="toggleFileAttachmentOverlay" - :badge="$appStore.attachments.length.toString() || null" - v-tooltip.top="'Attach files' + ($appStore.attachments.length ? ' (' + $appStore.attachments.length.toString() + ' file)' : ' (0 files)')" - :aria-label="'Upload file (' + $appStore.attachments.length.toString() + ' files attached)'" + :badge="fileArrayFiltered.length.toString() || null" + v-tooltip.top="'Attach files' + (fileArrayFiltered.length ? ' (' + fileArrayFiltered.length.toString() + ' file)' : ' (0 files)')" + :aria-label="'Upload file (' + fileArrayFiltered.length.toString() + ' files attached)'" />

Attached File

-
+
{{ file.fileName }}
@@ -22,8 +22,8 @@ v-for="api in externalOrchestrationServices" :key="api.name" :apiName="api.name" - :apiUrl="api.resolved_api_url" - :description="api.description" + :apiUrl="api.url" + :description="api.description" />
@@ -44,7 +44,7 @@ export default { data() { return { - apiUrls: [], + apiUrls: [] as Array, externalOrchestrationServices: [] as ExternalOrchestrationService[], loading: false as boolean, loadingStatusText: 'Retrieving data...' as string, @@ -58,57 +58,76 @@ export default { methods: { async fetchApiUrls() { this.loading = true; + let instancePart = `/instances/${this.$appConfigStore.instanceId}`; this.apiUrls = [ { name: 'coreApiUrl', displayName: 'Core API', description: 'The Core API is the main user-based API for the FoundationaLLM platform. It is accessed by the User Portal.', - url: this.$appConfigStore.coreApiUrl + url: `${this.$appConfigStore.coreApiUrl}${instancePart}`, }, { name: 'apiUrl', displayName: 'Management API', description: 'The Management API is used by the Management Portal to manage the FoundationaLLM platform.', - url: this.$appConfigStore.apiUrl - }, - { - name: 'gatekeeperApiUrl', - displayName: 'Gatekeeper API', - description: 'The Gatekeeper API adds an additional layer of security to the FoundationaLLM platform. It is accessed by the Core API.', - url: this.$appConfigStore.gatekeeperApiUrl, - }, - { - name: 'gatekeeperIntegrationApiUrl', - displayName: 'Gatekeeper Integration API', - description: 'The Gatekeeper Integration API is used to integrate additional filtering and safety services into the Gatekeeper API.', - url: this.$appConfigStore.gatekeeperIntegrationApiUrl, - }, - { - name: 'gatewayApiUrl', - displayName: 'Gateway API', - description: 'The Gateway API is used to manage the connection between the FoundationaLLM platform and LLMs.', - url: this.$appConfigStore.gatewayApiUrl, - }, - { - name: 'orchestrationApiUrl', - displayName: 'Orchestration API', - description: 'The Orchestration API is used to manage the orchestration of LLMs and other services in the FoundationaLLM platform.', - url: this.$appConfigStore.orchestrationApiUrl, + url: `${this.$appConfigStore.apiUrl}${instancePart}`, }, { - name: 'vectorizationApiUrl', - displayName: 'Vectorization API', - description: 'The Vectorization API is used to manage vectorization requests for the Vectorization Worker service.', - url: this.$appConfigStore.vectorizationApiUrl, + name: 'authorizationApiUrl', + displayName: 'Authorization API', + description: 'The Authorization API manages role-based access control (RBAC) and other auth-related functions for the FoundationaLLM platform.', + url: `${this.$appConfigStore.authorizationApiUrl}`, }, { - name: 'vectorizationWorkerApiUrl', - displayName: 'Vectorization Worker API', - description: 'The Vectorization Worker API provides access to the internal state of the vectorization workers.', - url: this.$appConfigStore.vectorizationWorkerApiUrl, + name: 'stateApiUrl', + displayName: 'State API', + description: 'The State API manages background task and long-running operation state information for the FoundationaLLM platform.', + url: `${this.$appConfigStore.stateApiUrl}`, }, - ]; + // { + // name: 'gatekeeperApiUrl', + // displayName: 'Gatekeeper API', + // description: 'The Gatekeeper API adds an additional layer of security to the FoundationaLLM platform. It is accessed by the Core API.', + // url: `${this.$appConfigStore.gatekeeperApiUrl}${instancePart}`, + // }, + // { + // name: 'gatekeeperIntegrationApiUrl', + // displayName: 'Gatekeeper Integration API', + // description: 'The Gatekeeper Integration API is used to integrate additional filtering and safety services into the Gatekeeper API.', + // url: `${this.$appConfigStore.gatekeeperIntegrationApiUrl}${instancePart}`, + // }, + // { + // name: 'gatewayApiUrl', + // displayName: 'Gateway API', + // description: 'The Gateway API is used to manage the connection between the FoundationaLLM platform and LLMs.', + // url: `${this.$appConfigStore.gatewayApiUrl}${instancePart}`, + // }, + // { + // name: 'orchestrationApiUrl', + // displayName: 'Orchestration API', + // description: 'The Orchestration API is used to manage the orchestration of LLMs and other services in the FoundationaLLM platform.', + // url: `${this.$appConfigStore.orchestrationApiUrl}${instancePart}`, + // }, + // { + // name: 'semanticKernelApiUrl', + // displayName: 'SemanticKernel API', + // description: 'The SemanticKernel API provides SemanticKernel-based orchestration services to facilitate communicating with large-language models.', + // url: `${this.$appConfigStore.semanticKernelApiUrl}${instancePart}`, + // }, + // { + // name: 'vectorizationApiUrl', + // displayName: 'Vectorization API', + // description: 'The Vectorization API is used to manage vectorization requests for the Vectorization Worker service.', + // url: `${this.$appConfigStore.vectorizationApiUrl}${instancePart}`, + // }, + // { + // name: 'vectorizationWorkerApiUrl', + // displayName: 'Vectorization Worker API', + // description: 'The Vectorization Worker API provides access to the internal state of the vectorization workers.', + // url: `${this.$appConfigStore.vectorizationWorkerApiUrl}${instancePart}`, + // }, + ] as Array; try { this.loadingStatusText = 'Retrieving external orchestration services...'; From ee92132b8c21cc6302e3231b687ecc6f6e3b0f6a Mon Sep 17 00:00:00 2001 From: joelhulen Date: Wed, 31 Jul 2024 12:25:18 -0400 Subject: [PATCH 34/36] Merge --- src/dotnet/Common/Clients/PollingHttpClient`2.cs | 11 +++++++---- src/dotnet/Orchestration/Services/LangChainService.cs | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/dotnet/Common/Clients/PollingHttpClient`2.cs b/src/dotnet/Common/Clients/PollingHttpClient`2.cs index 94aee75818..b1edb30abd 100644 --- a/src/dotnet/Common/Clients/PollingHttpClient`2.cs +++ b/src/dotnet/Common/Clients/PollingHttpClient`2.cs @@ -80,11 +80,10 @@ public class PollingHttpClient( var pollingStartTime = DateTime.UtcNow; var pollingCounter = 0; + var currentPollingInterval = _pollingInterval; while (true) { - await Task.Delay(_pollingInterval, cancellationToken); - var totalPollingTime = DateTime.UtcNow - pollingStartTime; pollingCounter++; _logger.LogInformation( @@ -123,14 +122,18 @@ public class PollingHttpClient( { _logger.LogWarning("Total polling time ({TotalTime} seconds) exceeded to maximum allowed ({MaxTime} seconds).", totalPollingTime.TotalSeconds, - _maxWaitTime.TotalSeconds); + _maxWaitTime.TotalSeconds); return default; } - continue; + + break; default: _logger.LogError("An error occurred while polling for the response. The response status code was {StatusCode}.", responseMessage.StatusCode); return default; } + await Task.Delay(currentPollingInterval, cancellationToken); + // Exponential backoff + currentPollingInterval = TimeSpan.FromSeconds(currentPollingInterval.TotalSeconds * 2); } } catch (Exception ex) diff --git a/src/dotnet/Orchestration/Services/LangChainService.cs b/src/dotnet/Orchestration/Services/LangChainService.cs index 00cb5572b4..8e9ae2c4ba 100644 --- a/src/dotnet/Orchestration/Services/LangChainService.cs +++ b/src/dotnet/Orchestration/Services/LangChainService.cs @@ -71,7 +71,7 @@ public async Task GetCompletion(string instanceId, LLMCom client, request, $"instances/{instanceId}/async-completions", - TimeSpan.FromSeconds(10), + TimeSpan.FromSeconds(0.5), client.Timeout.Subtract(TimeSpan.FromSeconds(1)), _logger); From df5b3a49ea5b49810eef5e0ccdf36aaf283c8436 Mon Sep 17 00:00:00 2001 From: codingbandit Date: Wed, 31 Jul 2024 13:31:18 -0400 Subject: [PATCH 35/36] Remove debug code --- .../PythonSDK/foundationallm/operations/operations_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/python/PythonSDK/foundationallm/operations/operations_manager.py b/src/python/PythonSDK/foundationallm/operations/operations_manager.py index 6d94fd5d28..5b286dc6fd 100644 --- a/src/python/PythonSDK/foundationallm/operations/operations_manager.py +++ b/src/python/PythonSDK/foundationallm/operations/operations_manager.py @@ -17,7 +17,7 @@ class OperationsManager(): def __init__(self, config: Configuration): self.config = config # Retrieve the State API configuration settings. - self.state_api_url = config.get_value('FoundationaLLM:APIEndpoints:StateAPI:Essentials:APIUrl').rstrip('/') + self.state_api_url = config.get_value('FoundationaLLM:APIEndpoints:StateAPI:Essentials:APIUrl').rstrip('/') self.state_api_key = config.get_value('FoundationaLLM:APIEndpoints:StateAPI:Essentials:APIKey') env = os.environ.get('FOUNDATIONALLM_ENV', 'prod') self.verify_certs = False if env == 'dev' else True @@ -49,7 +49,7 @@ async def create_operation( "charset":"utf-8", "Content-Type":"application/json" } - print(f'{self.state_api_url}/instances/{instance_id}/operations/{operation_id}') + # Call the State API to create a new operation. r = requests.post( f'{self.state_api_url}/instances/{instance_id}/operations/{operation_id}', From b4c429bb7f67e46a3a3663b8a2dce400c4c9d7ab Mon Sep 17 00:00:00 2001 From: joelhulen Date: Wed, 31 Jul 2024 13:33:04 -0400 Subject: [PATCH 36/36] Null check --- src/ui/ManagementPortal/pages/agents/create.vue | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/ui/ManagementPortal/pages/agents/create.vue b/src/ui/ManagementPortal/pages/agents/create.vue index 1b6063711d..33eaa75d41 100644 --- a/src/ui/ManagementPortal/pages/agents/create.vue +++ b/src/ui/ManagementPortal/pages/agents/create.vue @@ -1016,14 +1016,15 @@ export default { this.gatekeeperEnabled = Boolean(agent.gatekeeper?.use_system_setting); - this.selectedGatekeeperContentSafety = this.gatekeeperContentSafetyOptions.filter((localOption) => - agent.gatekeeper.options.includes(localOption.code) - ) || this.selectedGatekeeperContentSafety; + if (agent.gatekeeper && agent.gatekeeper.options) { + this.selectedGatekeeperContentSafety = this.gatekeeperContentSafetyOptions.filter((localOption) => + agent.gatekeeper?.options?.includes(localOption.code) + ) || this.selectedGatekeeperContentSafety; - this.selectedGatekeeperDataProtection = - this.gatekeeperDataProtectionOptions.filter((localOption) => - agent.gatekeeper.options.includes(localOption.code) + this.selectedGatekeeperDataProtection = this.gatekeeperDataProtectionOptions.filter((localOption) => + agent.gatekeeper?.options?.includes(localOption.code) ) || this.selectedGatekeeperDataProtection; + } }, async checkName() {