From 7c9e9d8a06c46170eb61d0957750276d0d48b164 Mon Sep 17 00:00:00 2001 From: Mohammad Rafi Date: Mon, 29 Jun 2026 13:05:49 +0530 Subject: [PATCH 01/14] chore: update CODEOWNERS handles Replace @Vinay-Microsoft -> @VinaySh-Microsoft and @Prajwal-Microsoft -> @Prajwal1-Microsoft --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c3f76db4..eadcf322 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,4 +2,4 @@ # Each line is a file pattern followed by one or more owners. # These owners will be the default owners for everything in the repo. -* @toherman-msft @brittneek @nchandhi @gpickett @malrose07 @TravisHilbert @Avijit-Microsoft @Roopan-Microsoft @Prajwal-Microsoft @Vinay-Microsoft +* @toherman-msft @brittneek @nchandhi @gpickett @malrose07 @TravisHilbert @Avijit-Microsoft @Roopan-Microsoft @Prajwal1-Microsoft @VinaySh-Microsoft From 712798ab8abb5e9729fc203fc2bc0c1a608c7711 Mon Sep 17 00:00:00 2001 From: HarshB-Microsoft Date: Wed, 1 Jul 2026 18:06:56 +0530 Subject: [PATCH 02/14] update GPT model; add container registry; add build scripts --- infra/main.bicep | 96 ++++++++-- infra/main.parameters.json | 6 - infra/main.waf.parameters.json | 6 - infra/scripts/build_push_images.ps1 | 271 ++++++++++++++++++++++++++++ infra/scripts/build_push_images.sh | 259 ++++++++++++++++++++++++++ 5 files changed, 606 insertions(+), 32 deletions(-) create mode 100644 infra/scripts/build_push_images.ps1 create mode 100644 infra/scripts/build_push_images.sh diff --git a/infra/main.bicep b/infra/main.bicep index 987fd247..3606b017 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -25,12 +25,12 @@ param solutionUniqueText string = take(uniqueString(subscription().id, resourceG param location string // Restricting deployment to regions that support all deployed models: gpt-4.1-mini, text-embedding-3-small, and gpt-realtime-mini (GlobalStandard) -@allowed(['eastus2', 'francecentral', 'swedencentral']) +@allowed(['eastus2', 'francecentral', 'swedencentral', 'centralus', 'southindia']) @metadata({ azd:{ type: 'location' usageName: [ - 'OpenAI.GlobalStandard.gpt4.1-mini,50' + 'OpenAI.GlobalStandard.gpt-5.4-mini,50' 'OpenAI.GlobalStandard.gpt-realtime-mini,1' ] } @@ -43,10 +43,10 @@ param secondaryLocation string = 'canadacentral' @minLength(1) @description('Optional. Name of the GPT model to deploy:') -param gptModelName string = 'gpt-4.1-mini' +param gptModelName string = 'gpt-5.4-mini' @description('Optional. Version of the GPT model to deploy. Defaults to 2025-04-14.') -param gptModelVersion string = '2025-04-14' +param gptModelVersion string = '2026-03-17' @description('Optional. Version of the OpenAI API.') param azureOpenaiAPIVersion string = '2025-01-01-preview' @@ -106,13 +106,6 @@ param vmAdminPassword string? @description('Optional. Size of the Jumpbox Virtual Machine. Allows to customize VM size if `enablePrivateNetworking` is set to true. See https://learn.microsoft.com/azure/virtual-machines/sizes for available sizes.') param vmSize string = 'Standard_D2s_v5' -// These parameters are changed for testing - please reset as part of publication -@description('Optional. The host (excluding https://) of an existing container registry. This is the `loginServer` when using Azure Container Registry.') -param containerRegistryEndpoint string = 'ccbcontainerreg.azurecr.io' - -@description('Optional. The image tag to use for container images. Defaults to "latest_v2".') -param imageTag string = 'latest_v2' - @description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true @@ -301,6 +294,7 @@ module applicationInsights 'br/public:avm/res/insights/component:0.7.1' = if (en flowType: 'Bluefield' // WAF aligned configuration for Monitoring workspaceResourceId: enableMonitoring ? logAnalyticsWorkspaceResourceId : '' + diagnosticSettings: enableMonitoring ? [{ workspaceResourceId: logAnalyticsWorkspaceResourceId }] : null } } @@ -1082,6 +1076,62 @@ module cosmosDb 'br/public:avm/res/document-db/database-account:0.19.0' = { } } +// ========== Container Registry ========== // +module containerRegistry 'br/public:avm/res/container-registry/registry:0.12.1' = { + name: take('avm.res.container-registry.registry.cr${solutionSuffix}', 64) + params: { + name: 'cr${solutionSuffix}' + acrAdminUserEnabled: false + // Premium is required for private endpoints and network rules + acrSku: (enableScalability || enablePrivateNetworking) ? 'Premium' : 'Basic' + azureADAuthenticationAsArmPolicyStatus: 'enabled' + exportPolicyStatus: 'enabled' + location: location + softDeletePolicyDays: 7 + softDeletePolicyStatus: 'disabled' + tags: tags + publicNetworkAccess: enablePrivateNetworking ? 'Disabled' : 'Enabled' + privateEndpoints: enablePrivateNetworking + ? [ + { + name: 'pep-cr${solutionSuffix}' + customNetworkInterfaceName: 'nic-cr${solutionSuffix}' + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.cognitiveServices]!.outputs.resourceId } + ] + } + service: 'registry' + subnetResourceId: virtualNetwork!.outputs.backendSubnetResourceId + } + ] + : [] + trustPolicyStatus: enableScalability ? 'enabled' : 'disabled' + // networkRuleBypassOptions and networkRuleSet are Premium-only; suppress them on Basic. + // The AVM module emits a networkRuleSet whenever defaultAction is 'Deny' (its default) with public access enabled, + // which ARM rejects with 'NetworkRuleNotSupported' on the Basic SKU. + networkRuleBypassOptions: (enableScalability || enablePrivateNetworking) ? 'AzureServices' : null + networkRuleSetDefaultAction: (enableScalability || enablePrivateNetworking) ? 'Deny' : 'Allow' + roleAssignments: [ + { + roleDefinitionIdOrName: acrPullRole + principalType: 'ServicePrincipal' + principalId: webSiteBackend.outputs.systemAssignedMIPrincipalId! + } + { + roleDefinitionIdOrName: acrPullRole + principalType: 'ServicePrincipal' + principalId: webSite.outputs.systemAssignedMIPrincipalId! + } + ] + } +} + +var acrPullRole = subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '7f951dda-4ed3-4680-a7ca-43fe172d538d' +) + // ========== Web server farm ========== // // WAF best practices for Web Application Services: https://learn.microsoft.com/en-us/azure/well-architected/service-guides/app-service-web-apps // PSRule for Web Server Farm: https://azure.github.io/PSRule.Rules.Azure/en/rules/resource/#app-service @@ -1128,11 +1178,13 @@ module webSiteBackend 'modules/web-sites.bicep' = { systemAssigned: true } siteConfig: { - linuxFxVersion: 'DOCKER|${containerRegistryEndpoint}/backend:${imageTag}' + linuxFxVersion: 'DOCKER|mcr.microsoft.com/azuredocs/containerapps-helloworld:latest' minTlsVersion: '1.2' healthCheckPath: '/health' webSocketsEnabled: true + acrUseManagedIdentityCreds: true } + e2eEncryptionEnabled: true configs: [ { name: 'appsettings' @@ -1215,7 +1267,7 @@ module webSiteBackend 'modules/web-sites.bicep' = { } } -// ========== Additional Cosmos DB Role Assignment for Backend App Service ==========// +// ========== Additional Cosmos DB Role Assignment for Backend App Service ========== // // Add the backend App Service's system-assigned managed identity to Cosmos DB role resource cosmosDbBackendRoleAssignment 'Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments@2025-11-01-preview' = { name: '${cosmosDbResourceName}/${guid(subscription().id, resourceGroup().id, backendWebSiteResourceName, 'CosmosDBDataContributor')}' @@ -1318,10 +1370,14 @@ module webSite 'modules/web-sites.bicep' = { tags: tags location: location kind: 'app,linux,container' + managedIdentities: { + systemAssigned: true + } serverFarmResourceId: webServerFarm.?outputs.resourceId siteConfig: { - linuxFxVersion: 'DOCKER|${containerRegistryEndpoint}/frontend:${imageTag}' + linuxFxVersion: 'DOCKER|mcr.microsoft.com/azuredocs/containerapps-helloworld:latest' minTlsVersion: '1.2' + acrUseManagedIdentityCreds: true } configs: [ { @@ -1428,12 +1484,6 @@ output AZURE_FOUNDRY_ENDPOINT string = aiFoundryAiProjectEndpoint @description('Azure AI Agent model deployment name') output AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME string = gptModelName -@description('Name of the Azure Container Registry') -output ACR_NAME string = split(containerRegistryEndpoint, '.')[0] - -@description('Container image tag for the backend service') -output AZURE_ENV_IMAGETAG string = imageTag - @description('Name of the Azure AI Services resource') output AI_SERVICE_NAME string = aiFoundryAiServicesResourceName @@ -1472,3 +1522,9 @@ output AI_SEARCH_SERVICE_RESOURCE_ID string = searchService.id @description('Application environment (Production)') output APP_ENV string = 'Prod' + +@description('Azure Container Registry endpoint URL') +output AZURE_CONTAINER_REGISTRY_ENDPOINT string = containerRegistry.outputs.loginServer + +@description('Azure Container Registry name') +output AZURE_CONTAINER_REGISTRY_NAME string = containerRegistry.outputs.name diff --git a/infra/main.parameters.json b/infra/main.parameters.json index eed5cd39..25b63fec 100644 --- a/infra/main.parameters.json +++ b/infra/main.parameters.json @@ -32,12 +32,6 @@ "existingFoundryProjectResourceId": { "value": "${AZURE_EXISTING_AIPROJECT_RESOURCE_ID}" }, - "containerRegistryEndpoint": { - "value": "${AZURE_ENV_CONTAINER_REGISTRY_ENDPOINT}" - }, - "imageTag": { - "value": "${AZURE_ENV_IMAGETAG=latest_v2}" - }, "embeddingDeploymentCapacity": { "value": "${AZURE_ENV_EMBEDDING_DEPLOYMENT_CAPACITY}" }, diff --git a/infra/main.waf.parameters.json b/infra/main.waf.parameters.json index 75da35b2..7d66ad34 100644 --- a/infra/main.waf.parameters.json +++ b/infra/main.waf.parameters.json @@ -38,12 +38,6 @@ "existingFoundryProjectResourceId": { "value": "${AZURE_EXISTING_AIPROJECT_RESOURCE_ID}" }, - "containerRegistryEndpoint": { - "value": "${AZURE_ENV_CONTAINER_REGISTRY_ENDPOINT}" - }, - "imageTag": { - "value": "${AZURE_ENV_IMAGETAG=latest_v2}" - }, "enableMonitoring": { "value": true }, diff --git a/infra/scripts/build_push_images.ps1 b/infra/scripts/build_push_images.ps1 new file mode 100644 index 00000000..b2de82e9 --- /dev/null +++ b/infra/scripts/build_push_images.ps1 @@ -0,0 +1,271 @@ +#!/usr/bin/env pwsh +#Requires -Version 7.0 + +<# +.SYNOPSIS + Builds the backend (src/api) and frontend (src/App) container images inside + Azure Container Registry using `az acr build`, then updates the two App + Services (api- and app-) to run those images. + +.DESCRIPTION + Uses `az acr build` so image build/push happens in ACR (no local Docker + required). Values are read from the current `azd` environment when + possible, otherwise from the last successful ARM deployment in the + resource group. All parameters can be overridden on the command line. + +.PARAMETER ResourceGroup + Azure resource group that contains ACR and the App Services. +.PARAMETER AcrName + Azure Container Registry name (without the .azurecr.io suffix). +.PARAMETER BackendAppName + Backend App Service name (defaults to api-). +.PARAMETER FrontendAppName + Frontend App Service name (defaults to app-). +.PARAMETER ImageTag + Tag to apply to both images. Defaults to a UTC timestamp. +.PARAMETER BackendImage + Backend image repository name. Defaults to "backend". +.PARAMETER FrontendImage + Frontend image repository name. Defaults to "frontend". +.PARAMETER SkipBackend + Skip building/updating the backend. +.PARAMETER SkipFrontend + Skip building/updating the frontend. + +.EXAMPLE + ./build_push_images.ps1 + +.EXAMPLE + ./build_push_images.ps1 -ResourceGroup rg-ccsa -ImageTag v1.2.3 +#> + +param( + [string]$ResourceGroup, + [string]$AcrName, + [string]$BackendAppName, + [string]$FrontendAppName, + [string]$ImageTag, + [string]$BackendImage = 'backend', + [string]$FrontendImage = 'frontend', + [switch]$SkipBackend, + [switch]$SkipFrontend, + [switch]$ShowLogs +) + +$ErrorActionPreference = 'Stop' + +# --------------------------------------------------------------------------- +# Paths +# --------------------------------------------------------------------------- +$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$repoRoot = Resolve-Path (Join-Path $scriptDir '..' '..') +$backendCtx = Join-Path $repoRoot 'src/api' +$frontendCtx = Join-Path $repoRoot 'src/App' + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- +function Test-CommandAvailable { + param([string]$Name) + return [bool](Get-Command $Name -ErrorAction SilentlyContinue) +} + +function Get-AzdEnvValue { + param([string]$Key) + if (-not (Test-CommandAvailable 'azd')) { return $null } + $value = azd env get-value $Key 2>$null + if ($LASTEXITCODE -ne 0) { return $null } + if ([string]::IsNullOrWhiteSpace($value)) { return $null } + if ($value -match '^ERROR:') { return $null } + return $value.Trim() +} + +function Get-DeploymentOutputs { + param([string]$Rg) + $deploymentName = az group show --name $Rg --query 'tags.DeploymentName' -o tsv 2>$null + if ([string]::IsNullOrWhiteSpace($deploymentName)) { + # Fall back to most recent deployment + $deploymentName = az deployment group list --resource-group $Rg --query '[0].name' -o tsv 2>$null + } + if ([string]::IsNullOrWhiteSpace($deploymentName)) { return $null } + $json = az deployment group show --resource-group $Rg --name $deploymentName --query 'properties.outputs' -o json 2>$null + if ([string]::IsNullOrWhiteSpace($json)) { return $null } + return ($json | ConvertFrom-Json) +} + +function Get-OutputValue { + param($Outputs, [string[]]$Keys) + if ($null -eq $Outputs) { return $null } + foreach ($k in $Keys) { + $prop = $Outputs.PSObject.Properties[$k] + if ($prop -and -not [string]::IsNullOrWhiteSpace($prop.Value.value)) { + return $prop.Value.value.ToString().Trim() + } + } + return $null +} + +function Invoke-AcrBuild { + param( + [string]$Registry, + [string]$Image, + [string]$Tag, + [string]$Context + ) + Write-Host "Building $Registry/$Image`:$Tag from $Context" -ForegroundColor Cyan + + if ($ShowLogs) { + az acr build ` + --registry $Registry ` + --image "$Image`:$Tag" ` + --image "$Image`:latest" ` + --only-show-errors ` + $Context + if ($LASTEXITCODE -ne 0) { throw "az acr build failed for image $Image" } + return + } + + # Quiet mode: no log stream, no CLI warnings, no JSON dump. Only run ID + result. + Write-Host " (streaming logs suppressed; pass -ShowLogs to see full output)" -ForegroundColor DarkGray + $jsonRaw = az acr build ` + --registry $Registry ` + --image "$Image`:$Tag" ` + --image "$Image`:latest" ` + --no-logs ` + --only-show-errors ` + -o json ` + $Context 2>&1 + $exit = $LASTEXITCODE + + $runObj = $null + try { $runObj = ($jsonRaw | Out-String) | ConvertFrom-Json -ErrorAction Stop } catch { } + + if ($exit -ne 0) { + # Success path emits JSON with .runId; failure path emits only + # `ERROR: The run with ID 'caXX' finished with unsuccessful status ...` + $runId = if ($runObj) { $runObj.runId } else { $null } + if (-not $runId) { + $text = ($jsonRaw | Out-String) + $m = [regex]::Match($text, "run with ID '([^']+)'") + if ($m.Success) { $runId = $m.Groups[1].Value } + } + + if ($runId) { + Write-Host "" + Write-Host "Build failed (runId: $runId). Fetching logs..." -ForegroundColor Red + az acr task logs --registry $Registry --run-id $runId --only-show-errors + } else { + $jsonRaw | ForEach-Object { Write-Host $_ } + } + throw "az acr build failed for image $Image" + } + + if ($runObj) { + Write-Host " Succeeded (runId: $($runObj.runId))" -ForegroundColor Green + } +} + +function Set-WebAppContainer { + param( + [string]$Rg, + [string]$AppName, + [string]$AcrLoginServer, + [string]$Image, + [string]$Tag + ) + $fullImage = "$AcrLoginServer/$Image`:$Tag" + Write-Host "Updating web app '$AppName' -> $fullImage" -ForegroundColor Cyan + az webapp config container set ` + --name $AppName ` + --resource-group $Rg ` + --container-image-name $fullImage ` + --only-show-errors | Out-Null + if ($LASTEXITCODE -ne 0) { throw "Failed to update container config for $AppName" } + + Write-Host "Restarting '$AppName'..." -ForegroundColor Cyan + az webapp restart --name $AppName --resource-group $Rg --only-show-errors | Out-Null + if ($LASTEXITCODE -ne 0) { throw "Failed to restart $AppName" } +} + +# --------------------------------------------------------------------------- +# Pre-flight checks +# --------------------------------------------------------------------------- +if (-not (Test-CommandAvailable 'az')) { + throw "Azure CLI ('az') is required but was not found on PATH." +} + +# --------------------------------------------------------------------------- +# Resolve inputs +# --------------------------------------------------------------------------- +if (-not $ResourceGroup) { $ResourceGroup = Get-AzdEnvValue 'AZURE_RESOURCE_GROUP' } +if (-not $AcrName) { $AcrName = Get-AzdEnvValue 'ACR_NAME' } +if (-not $AcrName) { $AcrName = Get-AzdEnvValue 'AZURE_CONTAINER_REGISTRY_NAME' } +if (-not $BackendAppName) { $BackendAppName = Get-AzdEnvValue 'API_APP_NAME' } +$solutionSuffix = Get-AzdEnvValue 'SOLUTION_NAME' +if (-not $FrontendAppName -and $solutionSuffix) { $FrontendAppName = "app-$solutionSuffix" } +if (-not $ImageTag) { $ImageTag = Get-AzdEnvValue 'AZURE_ENV_IMAGETAG' } + +# Fall back to deployment outputs for anything still missing +$needDeployment = -not ($ResourceGroup -and $AcrName -and $BackendAppName -and $FrontendAppName) +if ($needDeployment) { + if (-not $ResourceGroup) { + throw "ResourceGroup is required. Pass -ResourceGroup or run inside an azd environment." + } + Write-Host "Fetching deployment outputs from resource group '$ResourceGroup'..." -ForegroundColor DarkGray + $outputs = Get-DeploymentOutputs -Rg $ResourceGroup + if (-not $AcrName) { $AcrName = Get-OutputValue $outputs @('ACR_NAME','acrName','AZURE_CONTAINER_REGISTRY_NAME','azureContainerRegistryName') } + if (-not $BackendAppName) { $BackendAppName = Get-OutputValue $outputs @('API_APP_NAME','apiAppName') } + if (-not $solutionSuffix) { $solutionSuffix = Get-OutputValue $outputs @('SOLUTION_NAME','solutionName') } + if (-not $FrontendAppName -and $solutionSuffix) { $FrontendAppName = "app-$solutionSuffix" } +} + +if (-not $ImageTag) { + $ImageTag = (Get-Date -Format 'yyyyMMddHHmmss') +} + +if (-not $ResourceGroup) { throw "Missing ResourceGroup." } +if (-not $AcrName) { throw "Missing AcrName." } +if (-not $SkipBackend -and -not $BackendAppName) { throw "Missing BackendAppName." } +if (-not $SkipFrontend -and -not $FrontendAppName) { throw "Missing FrontendAppName." } + +$acrLoginServer = "$AcrName.azurecr.io" + +Write-Host "" +Write-Host "Configuration" -ForegroundColor Green +Write-Host " Resource group : $ResourceGroup" +Write-Host " ACR : $acrLoginServer" +Write-Host " Backend app : $BackendAppName" +Write-Host " Frontend app : $FrontendAppName" +Write-Host " Image tag : $ImageTag" +Write-Host "" + +# --------------------------------------------------------------------------- +# Build & deploy +# --------------------------------------------------------------------------- +if (-not $SkipBackend) { + if (-not (Test-Path (Join-Path $backendCtx 'Dockerfile'))) { + throw "Backend Dockerfile not found at $backendCtx/Dockerfile" + } + Invoke-AcrBuild -Registry $AcrName -Image $BackendImage -Tag $ImageTag -Context $backendCtx + Set-WebAppContainer -Rg $ResourceGroup -AppName $BackendAppName -AcrLoginServer $acrLoginServer -Image $BackendImage -Tag $ImageTag +} else { + Write-Host "Skipping backend (SkipBackend)." -ForegroundColor Yellow +} + +if (-not $SkipFrontend) { + if (-not (Test-Path (Join-Path $frontendCtx 'Dockerfile'))) { + throw "Frontend Dockerfile not found at $frontendCtx/Dockerfile" + } + Invoke-AcrBuild -Registry $AcrName -Image $FrontendImage -Tag $ImageTag -Context $frontendCtx + Set-WebAppContainer -Rg $ResourceGroup -AppName $FrontendAppName -AcrLoginServer $acrLoginServer -Image $FrontendImage -Tag $ImageTag +} else { + Write-Host "Skipping frontend (SkipFrontend)." -ForegroundColor Yellow +} + +# Persist tag for downstream tooling +if (Test-CommandAvailable 'azd') { + azd env set AZURE_ENV_IMAGETAG $ImageTag 2>$null | Out-Null +} + +Write-Host "" +Write-Host "Done. Images published with tag '$ImageTag'." -ForegroundColor Green diff --git a/infra/scripts/build_push_images.sh b/infra/scripts/build_push_images.sh new file mode 100644 index 00000000..ed79d0cb --- /dev/null +++ b/infra/scripts/build_push_images.sh @@ -0,0 +1,259 @@ +#!/usr/bin/env bash +# --------------------------------------------------------------------------- +# Builds the backend (src/api) and frontend (src/App) container images inside +# Azure Container Registry using `az acr build`, then updates the two App +# Services (api- and app-) to run those images. +# +# Values are pulled from the current `azd` environment when available, with +# fallback to the last ARM deployment in the resource group. Any value can be +# overridden on the command line. +# +# Usage: +# ./build_push_images.sh [options] +# +# Options: +# --resource-group Azure resource group +# --acr-name ACR name (without .azurecr.io) +# --backend-app Backend App Service name (api-) +# --frontend-app Frontend App Service name (app-) +# --image-tag Image tag (defaults to UTC timestamp) +# --backend-image Backend repository name (default: backend) +# --frontend-image Frontend repository name (default: frontend) +# --skip-backend Skip backend build/deploy +# --skip-frontend Skip frontend build/deploy +# --show-logs Stream full ACR build logs (default: quiet, only dump logs on failure) +# -h, --help Show this help +# --------------------------------------------------------------------------- +set -euo pipefail + +RESOURCE_GROUP="" +ACR_NAME="" +BACKEND_APP="" +FRONTEND_APP="" +IMAGE_TAG="" +BACKEND_IMAGE="backend" +FRONTEND_IMAGE="frontend" +SKIP_BACKEND=false +SKIP_FRONTEND=false +SHOW_LOGS=false + +usage() { + sed -n '2,25p' "$0" + exit "${1:-0}" +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --resource-group) RESOURCE_GROUP="$2"; shift 2 ;; + --acr-name) ACR_NAME="$2"; shift 2 ;; + --backend-app) BACKEND_APP="$2"; shift 2 ;; + --frontend-app) FRONTEND_APP="$2"; shift 2 ;; + --image-tag) IMAGE_TAG="$2"; shift 2 ;; + --backend-image) BACKEND_IMAGE="$2"; shift 2 ;; + --frontend-image) FRONTEND_IMAGE="$2"; shift 2 ;; + --skip-backend) SKIP_BACKEND=true; shift ;; + --skip-frontend) SKIP_FRONTEND=true; shift ;; + --show-logs) SHOW_LOGS=true; shift ;; + -h|--help) usage 0 ;; + *) echo "Unknown option: $1" >&2; usage 1 ;; + esac +done + +# --------------------------------------------------------------------------- +# Paths +# --------------------------------------------------------------------------- +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +BACKEND_CTX="$REPO_ROOT/src/api" +FRONTEND_CTX="$REPO_ROOT/src/App" + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- +command -v az >/dev/null 2>&1 || { echo "ERROR: Azure CLI ('az') is required." >&2; exit 1; } + +azd_available() { command -v azd >/dev/null 2>&1; } + +azd_get() { + local key="$1" value="" + azd_available || return 0 + value="$(azd env get-value "$key" 2>/dev/null || true)" + [[ "$value" == ERROR:* ]] && value="" + printf '%s' "$value" +} + +# Extract a top-level output value from `az deployment group show` JSON. Uses +# case-insensitive key match and tolerates absence of jq (falls back to grep). +extract_output() { + local json="$1"; shift + local key + for key in "$@"; do + local val="" + if command -v jq >/dev/null 2>&1; then + val="$(echo "$json" | jq -r --arg k "$key" ' + to_entries + | map(select(.key | ascii_downcase == ($k | ascii_downcase))) + | .[0].value.value // empty')" + else + val="$(echo "$json" | grep -i -A 3 "\"$key\"" | grep '"value"' | sed 's/.*"value": *"\([^"]*\)".*/\1/' | head -1)" + fi + val="$(echo -n "$val" | xargs || true)" + if [[ -n "$val" ]]; then + printf '%s' "$val" + return 0 + fi + done +} + +fetch_deployment_outputs() { + local rg="$1" + local dep + dep="$(az group show --name "$rg" --query 'tags.DeploymentName' -o tsv 2>/dev/null || true)" + if [[ -z "$dep" ]]; then + dep="$(az deployment group list --resource-group "$rg" --query '[0].name' -o tsv 2>/dev/null || true)" + fi + [[ -z "$dep" ]] && return 0 + az deployment group show --resource-group "$rg" --name "$dep" --query 'properties.outputs' -o json 2>/dev/null || true +} + +run_acr_build() { + local registry="$1" image="$2" tag="$3" context="$4" + echo "" + echo ">>> Building ${registry}.azurecr.io/${image}:${tag}" + + if $SHOW_LOGS; then + az acr build \ + --registry "$registry" \ + --image "${image}:${tag}" \ + --image "${image}:latest" \ + --only-show-errors \ + "$context" + return + fi + + echo " (streaming logs suppressed; pass --show-logs to see full output)" + local out exit_code=0 run_id="" + set +e + out="$(az acr build \ + --registry "$registry" \ + --image "${image}:${tag}" \ + --image "${image}:latest" \ + --no-logs \ + --only-show-errors \ + -o json \ + "$context" 2>&1)" + exit_code=$? + set -e + + if command -v jq >/dev/null 2>&1; then + run_id="$(printf '%s' "$out" | jq -r '.runId // empty' 2>/dev/null || true)" + else + run_id="$(printf '%s' "$out" | grep -oE '"runId":[[:space:]]*"[^"]+"' | head -1 | sed 's/.*"\([^"]*\)"$/\1/')" + fi + # On failure the CLI does not emit JSON, only: + # ERROR: The run with ID 'caXX' finished with unsuccessful status ... + if [[ -z "$run_id" ]]; then + run_id="$(printf '%s' "$out" | grep -oE "run with ID '[^']+'" | head -1 | sed "s/.*'\([^']*\)'.*/\1/")" + fi + + if [[ $exit_code -ne 0 ]]; then + if [[ -n "$run_id" ]]; then + echo "" + echo "Build failed (runId: $run_id). Fetching logs..." >&2 + az acr task logs --registry "$registry" --run-id "$run_id" --only-show-errors || true + else + printf '%s\n' "$out" >&2 + fi + echo "ERROR: az acr build failed for image $image" >&2 + return $exit_code + fi + + if [[ -n "$run_id" ]]; then + echo " Succeeded (runId: $run_id)" + fi +} + +update_webapp() { + local rg="$1" app="$2" login_server="$3" image="$4" tag="$5" + local full="${login_server}/${image}:${tag}" + echo "" + echo ">>> Updating web app '$app' -> $full" + az webapp config container set \ + --name "$app" \ + --resource-group "$rg" \ + --container-image-name "$full" \ + --only-show-errors >/dev/null + + echo ">>> Restarting '$app'..." + az webapp restart --name "$app" --resource-group "$rg" --only-show-errors >/dev/null +} + +# --------------------------------------------------------------------------- +# Resolve inputs +# --------------------------------------------------------------------------- +[[ -z "$RESOURCE_GROUP" ]] && RESOURCE_GROUP="$(azd_get AZURE_RESOURCE_GROUP)" +[[ -z "$ACR_NAME" ]] && ACR_NAME="$(azd_get ACR_NAME)" +[[ -z "$ACR_NAME" ]] && ACR_NAME="$(azd_get AZURE_CONTAINER_REGISTRY_NAME)" +[[ -z "$BACKEND_APP" ]] && BACKEND_APP="$(azd_get API_APP_NAME)" +SOLUTION_SUFFIX="$(azd_get SOLUTION_NAME)" +[[ -z "$FRONTEND_APP" && -n "$SOLUTION_SUFFIX" ]] && FRONTEND_APP="app-${SOLUTION_SUFFIX}" +[[ -z "$IMAGE_TAG" ]] && IMAGE_TAG="$(azd_get AZURE_ENV_IMAGETAG)" + +if [[ -z "$ACR_NAME" || -z "$BACKEND_APP" || -z "$FRONTEND_APP" ]]; then + [[ -z "$RESOURCE_GROUP" ]] && { echo "ERROR: --resource-group required (or run inside an azd env)." >&2; exit 1; } + echo "Fetching deployment outputs from '$RESOURCE_GROUP'..." + OUTPUTS_JSON="$(fetch_deployment_outputs "$RESOURCE_GROUP")" + if [[ -n "$OUTPUTS_JSON" ]]; then + [[ -z "$ACR_NAME" ]] && ACR_NAME="$(extract_output "$OUTPUTS_JSON" ACR_NAME acrName AZURE_CONTAINER_REGISTRY_NAME azureContainerRegistryName)" + [[ -z "$BACKEND_APP" ]] && BACKEND_APP="$(extract_output "$OUTPUTS_JSON" API_APP_NAME apiAppName)" + if [[ -z "$SOLUTION_SUFFIX" ]]; then + SOLUTION_SUFFIX="$(extract_output "$OUTPUTS_JSON" SOLUTION_NAME solutionName)" + fi + [[ -z "$FRONTEND_APP" && -n "$SOLUTION_SUFFIX" ]] && FRONTEND_APP="app-${SOLUTION_SUFFIX}" + fi +fi + +[[ -z "$IMAGE_TAG" ]] && IMAGE_TAG="$(date -u +%Y%m%d%H%M%S)" + +[[ -z "$RESOURCE_GROUP" ]] && { echo "ERROR: Missing resource group." >&2; exit 1; } +[[ -z "$ACR_NAME" ]] && { echo "ERROR: Missing ACR name." >&2; exit 1; } +$SKIP_BACKEND || [[ -n "$BACKEND_APP" ]] || { echo "ERROR: Missing backend app name." >&2; exit 1; } +$SKIP_FRONTEND || [[ -n "$FRONTEND_APP" ]] || { echo "ERROR: Missing frontend app name." >&2; exit 1; } + +ACR_LOGIN_SERVER="${ACR_NAME}.azurecr.io" + +cat <&2; exit 1; } + run_acr_build "$ACR_NAME" "$BACKEND_IMAGE" "$IMAGE_TAG" "$BACKEND_CTX" + update_webapp "$RESOURCE_GROUP" "$BACKEND_APP" "$ACR_LOGIN_SERVER" "$BACKEND_IMAGE" "$IMAGE_TAG" +else + echo "Skipping backend (--skip-backend)." +fi + +if ! $SKIP_FRONTEND; then + [[ -f "$FRONTEND_CTX/Dockerfile" ]] || { echo "ERROR: $FRONTEND_CTX/Dockerfile not found." >&2; exit 1; } + run_acr_build "$ACR_NAME" "$FRONTEND_IMAGE" "$IMAGE_TAG" "$FRONTEND_CTX" + update_webapp "$RESOURCE_GROUP" "$FRONTEND_APP" "$ACR_LOGIN_SERVER" "$FRONTEND_IMAGE" "$IMAGE_TAG" +else + echo "Skipping frontend (--skip-frontend)." +fi + +if azd_available; then + azd env set AZURE_ENV_IMAGETAG "$IMAGE_TAG" >/dev/null 2>&1 || true +fi + +echo "" +echo "Done. Images published with tag '$IMAGE_TAG'." From f97eefa515bc7a9c407e06e6b0b7a331b78cfb43 Mon Sep 17 00:00:00 2001 From: HarshB-Microsoft Date: Wed, 1 Jul 2026 18:07:07 +0530 Subject: [PATCH 03/14] fix: improve product parsing logic to handle leading product entries correctly --- src/App/src/lib/textParsers.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/App/src/lib/textParsers.ts b/src/App/src/lib/textParsers.ts index 9c775bb9..f2f7d3e4 100644 --- a/src/App/src/lib/textParsers.ts +++ b/src/App/src/lib/textParsers.ts @@ -194,8 +194,16 @@ export function parseProductsFromText(text: string): { products: Product[], intr let introText = ''; let outroText = ''; - - if (parts.length > 0) { + + // JS String.split with a zero-width lookahead at position 0 does NOT emit + // an empty leading element, so parts[0] can itself be the first product + // rather than the intro text. Detect that case so the first product isn't + // rendered as raw markdown. + const productHeadingRegex = /^\s*(?:\d+\.\s*\*\*[^*]+\*\*|\*\*\d+\.\s*[^*]+\*\*)/; + const firstPartIsProduct = parts.length > 0 && productHeadingRegex.test(parts[0]); + const productStartIndex = firstPartIsProduct ? 0 : 1; + + if (parts.length > 0 && !firstPartIsProduct) { introText = parts[0].trim(); introText = introText.replace(/^###\s*[^\n]*\n?/gm, '').trim(); @@ -213,14 +221,14 @@ export function parseProductsFromText(text: string): { products: Product[], intr } } - for (let i = 1; i < parts.length; i++) { + for (let i = productStartIndex; i < parts.length; i++) { const product = parseProductSection(parts[i]); if (product) { products.push(product); } } - const hasImageOrLink = parts.length === 1 && (parts[0].includes('![') || /\[[^\]]+\]\([^)]+\.(jpg|jpeg|png|gif|webp|svg)/i.test(parts[0])); + const hasImageOrLink = parts.length === 1 && !firstPartIsProduct && (parts[0].includes('![') || /\[[^\]]+\]\([^)]+\.(jpg|jpeg|png|gif|webp|svg)/i.test(parts[0])); if (hasImageOrLink) { const product = parseProductSection(parts[0]); if (product) { From b89dd0d7644faf53178d225fba5c433c5928b541 Mon Sep 17 00:00:00 2001 From: HarshB-Microsoft Date: Wed, 1 Jul 2026 18:12:26 +0530 Subject: [PATCH 04/14] remove unused image tag persistence for azd in build scripts --- infra/scripts/build_push_images.ps1 | 5 ----- infra/scripts/build_push_images.sh | 4 ---- 2 files changed, 9 deletions(-) diff --git a/infra/scripts/build_push_images.ps1 b/infra/scripts/build_push_images.ps1 index b2de82e9..58be00df 100644 --- a/infra/scripts/build_push_images.ps1 +++ b/infra/scripts/build_push_images.ps1 @@ -262,10 +262,5 @@ if (-not $SkipFrontend) { Write-Host "Skipping frontend (SkipFrontend)." -ForegroundColor Yellow } -# Persist tag for downstream tooling -if (Test-CommandAvailable 'azd') { - azd env set AZURE_ENV_IMAGETAG $ImageTag 2>$null | Out-Null -} - Write-Host "" Write-Host "Done. Images published with tag '$ImageTag'." -ForegroundColor Green diff --git a/infra/scripts/build_push_images.sh b/infra/scripts/build_push_images.sh index ed79d0cb..9cce3497 100644 --- a/infra/scripts/build_push_images.sh +++ b/infra/scripts/build_push_images.sh @@ -251,9 +251,5 @@ else echo "Skipping frontend (--skip-frontend)." fi -if azd_available; then - azd env set AZURE_ENV_IMAGETAG "$IMAGE_TAG" >/dev/null 2>&1 || true -fi - echo "" echo "Done. Images published with tag '$IMAGE_TAG'." From 5a4e1c5347b084b1d2193e1615750c812687c0d5 Mon Sep 17 00:00:00 2001 From: HarshB-Microsoft Date: Wed, 1 Jul 2026 19:26:18 +0530 Subject: [PATCH 05/14] docs: update deployment guide to include container image build and push instructions fix: remove unused trust policy status in Bicep file --- azure.yaml | 18 +++++++++++++----- documents/DeploymentGuide.md | 35 +++++++++++++++++++++++++++++++++-- infra/main.bicep | 1 - 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/azure.yaml b/azure.yaml index f423a948..13c326c6 100644 --- a/azure.yaml +++ b/azure.yaml @@ -4,7 +4,7 @@ metadata: template: customer-chatbot-solution-accelerator@1.0 requiredVersions: - azd: ">= 1.18.0 != 1.23.9" + azd: ">= 1.18.0 != 1.23.9" hooks: postprovision: @@ -21,10 +21,13 @@ hooks: Write-Host " Post-Deployment Steps" -ForegroundColor Yellow Write-Host "----------------------------------------`n" -ForegroundColor Yellow - Write-Host "1. Run the data setup script to load sample product data:`n" + Write-Host "1. Build and push the backend/frontend container images to ACR, then point the web apps at them:`n" + Write-Host " infra\scripts\build_push_images.ps1`n" -ForegroundColor Cyan + + Write-Host "2. Run the data setup script to load sample product data:`n" Write-Host " infra\scripts\data_scripts\run_upload_data_scripts.ps1`n" -ForegroundColor Cyan - Write-Host "2. Run the agent setup script to create AI Foundry agents:`n" + Write-Host "3. Run the agent setup script to create AI Foundry agents:`n" Write-Host " infra\scripts\agent_scripts\run_create_agents_scripts.ps1`n" -ForegroundColor Cyan shell: pwsh continueOnError: false @@ -46,12 +49,17 @@ hooks: echo "----------------------------------------" echo "" - echo "1. Run the data setup script to load sample product data:" + echo "1. Build and push the backend/frontend container images to ACR, then point the web apps at them:" + echo "" + echo " bash ./infra/scripts/build_push_images.sh" + echo "" + + echo "2. Run the data setup script to load sample product data:" echo "" echo " bash ./infra/scripts/data_scripts/run_upload_data_scripts.sh" echo "" - echo "2. Run the agent setup script to create AI Foundry agents:" + echo "3. Run the agent setup script to create AI Foundry agents:" echo "" echo " bash ./infra/scripts/agent_scripts/run_create_agents_scripts.sh" echo "" diff --git a/documents/DeploymentGuide.md b/documents/DeploymentGuide.md index 4eefc9d0..45c78a3f 100644 --- a/documents/DeploymentGuide.md +++ b/documents/DeploymentGuide.md @@ -335,7 +335,38 @@ source .venv/bin/activate ### 5.2 Initialize Data and Agents -**Step 1: Populate Product Catalogs and Search Indexes** +**Step 1: Build and push container images** + +The initial deployment configures the App Services with a placeholder container. Run the ACR build script to build the real backend/frontend images inside Azure Container Registry and point both web apps at them: + +- **For PowerShell (Windows/Linux/macOS):** + ```shell + infra\scripts\build_push_images.ps1 + ``` +- **For Bash (Linux/macOS/WSL):** + ```bash + bash ./infra/scripts/build_push_images.sh + ``` + +**If you deployed using `AVM`:** + +- **For PowerShell (Windows/Linux/macOS):** + ```shell + infra\scripts\build_push_images.ps1 -ResourceGroup "" + ``` +- **For Bash (Linux/macOS/WSL):** + ```bash + bash ./infra/scripts/build_push_images.sh --resource-group "" + ``` + +This script will: +- Build the backend (`src/api`) and frontend (`src/App`) images remotely using `az acr build` (no local Docker required) +- Push them to your Azure Container Registry +- Update both App Services (`api-` and `app-`) to run the new image and restart them + +> **Tip:** Pass `-ImageTag ` (PowerShell) or `--image-tag ` (bash) to publish a specific tag. Pass `-ShowLogs` / `--show-logs` to stream the full build output. Each run generates a fresh timestamp tag by default. + +**Step 2: Populate Product Catalogs and Search Indexes** Run the data setup script to load sample product data @@ -364,7 +395,7 @@ This script will: - Create and configure Azure AI Search indexes - Populate search indexes with product and policy documents -**Step 2: Create AI Foundry Agents** +**Step 3: Create AI Foundry Agents** Run the data setup script to load sample product data and create search indexes in Azure AI Search: - **For PowerShell (Windows/Linux/macOS):** diff --git a/infra/main.bicep b/infra/main.bicep index 3606b017..ac7de01d 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -1106,7 +1106,6 @@ module containerRegistry 'br/public:avm/res/container-registry/registry:0.12.1' } ] : [] - trustPolicyStatus: enableScalability ? 'enabled' : 'disabled' // networkRuleBypassOptions and networkRuleSet are Premium-only; suppress them on Basic. // The AVM module emits a networkRuleSet whenever defaultAction is 'Deny' (its default) with public access enabled, // which ARM rejects with 'NetworkRuleNotSupported' on the Basic SKU. From 6712e32188a4d308d24de87771e418c7d5bd3338 Mon Sep 17 00:00:00 2001 From: Shubhangi-Microsoft Date: Fri, 3 Jul 2026 06:22:24 +0000 Subject: [PATCH 06/14] Fix ACR name resolution and azd_get error handling in build_push_images scripts --- infra/scripts/build_push_images.ps1 | 7 ++++--- infra/scripts/build_push_images.sh | 12 ++++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/infra/scripts/build_push_images.ps1 b/infra/scripts/build_push_images.ps1 index 58be00df..3870303d 100644 --- a/infra/scripts/build_push_images.ps1 +++ b/infra/scripts/build_push_images.ps1 @@ -76,7 +76,8 @@ function Get-AzdEnvValue { $value = azd env get-value $Key 2>$null if ($LASTEXITCODE -ne 0) { return $null } if ([string]::IsNullOrWhiteSpace($value)) { return $null } - if ($value -match '^ERROR:') { return $null } + # Newer azd may print a "key not found" error to stdout for missing keys. + if ($value -match 'ERROR:' -or $value -match 'not found in environment') { return $null } return $value.Trim() } @@ -198,8 +199,8 @@ if (-not (Test-CommandAvailable 'az')) { # Resolve inputs # --------------------------------------------------------------------------- if (-not $ResourceGroup) { $ResourceGroup = Get-AzdEnvValue 'AZURE_RESOURCE_GROUP' } -if (-not $AcrName) { $AcrName = Get-AzdEnvValue 'ACR_NAME' } if (-not $AcrName) { $AcrName = Get-AzdEnvValue 'AZURE_CONTAINER_REGISTRY_NAME' } +if (-not $AcrName) { $AcrName = Get-AzdEnvValue 'ACR_NAME' } if (-not $BackendAppName) { $BackendAppName = Get-AzdEnvValue 'API_APP_NAME' } $solutionSuffix = Get-AzdEnvValue 'SOLUTION_NAME' if (-not $FrontendAppName -and $solutionSuffix) { $FrontendAppName = "app-$solutionSuffix" } @@ -213,7 +214,7 @@ if ($needDeployment) { } Write-Host "Fetching deployment outputs from resource group '$ResourceGroup'..." -ForegroundColor DarkGray $outputs = Get-DeploymentOutputs -Rg $ResourceGroup - if (-not $AcrName) { $AcrName = Get-OutputValue $outputs @('ACR_NAME','acrName','AZURE_CONTAINER_REGISTRY_NAME','azureContainerRegistryName') } + if (-not $AcrName) { $AcrName = Get-OutputValue $outputs @('AZURE_CONTAINER_REGISTRY_NAME','azureContainerRegistryName','ACR_NAME','acrName') } if (-not $BackendAppName) { $BackendAppName = Get-OutputValue $outputs @('API_APP_NAME','apiAppName') } if (-not $solutionSuffix) { $solutionSuffix = Get-OutputValue $outputs @('SOLUTION_NAME','solutionName') } if (-not $FrontendAppName -and $solutionSuffix) { $FrontendAppName = "app-$solutionSuffix" } diff --git a/infra/scripts/build_push_images.sh b/infra/scripts/build_push_images.sh index 9cce3497..7b937286 100644 --- a/infra/scripts/build_push_images.sh +++ b/infra/scripts/build_push_images.sh @@ -77,8 +77,12 @@ azd_available() { command -v azd >/dev/null 2>&1; } azd_get() { local key="$1" value="" azd_available || return 0 - value="$(azd env get-value "$key" 2>/dev/null || true)" - [[ "$value" == ERROR:* ]] && value="" + # A missing key makes azd exit non-zero (and may print an error to stdout); + # treat that as "not set" so callers fall back to their defaults. + value="$(azd env get-value "$key" 2>/dev/null)" || return 0 + case "$value" in + *ERROR:*|*"not found in environment"*) return 0 ;; + esac printf '%s' "$value" } @@ -192,8 +196,8 @@ update_webapp() { # Resolve inputs # --------------------------------------------------------------------------- [[ -z "$RESOURCE_GROUP" ]] && RESOURCE_GROUP="$(azd_get AZURE_RESOURCE_GROUP)" -[[ -z "$ACR_NAME" ]] && ACR_NAME="$(azd_get ACR_NAME)" [[ -z "$ACR_NAME" ]] && ACR_NAME="$(azd_get AZURE_CONTAINER_REGISTRY_NAME)" +[[ -z "$ACR_NAME" ]] && ACR_NAME="$(azd_get ACR_NAME)" [[ -z "$BACKEND_APP" ]] && BACKEND_APP="$(azd_get API_APP_NAME)" SOLUTION_SUFFIX="$(azd_get SOLUTION_NAME)" [[ -z "$FRONTEND_APP" && -n "$SOLUTION_SUFFIX" ]] && FRONTEND_APP="app-${SOLUTION_SUFFIX}" @@ -204,7 +208,7 @@ if [[ -z "$ACR_NAME" || -z "$BACKEND_APP" || -z "$FRONTEND_APP" ]]; then echo "Fetching deployment outputs from '$RESOURCE_GROUP'..." OUTPUTS_JSON="$(fetch_deployment_outputs "$RESOURCE_GROUP")" if [[ -n "$OUTPUTS_JSON" ]]; then - [[ -z "$ACR_NAME" ]] && ACR_NAME="$(extract_output "$OUTPUTS_JSON" ACR_NAME acrName AZURE_CONTAINER_REGISTRY_NAME azureContainerRegistryName)" + [[ -z "$ACR_NAME" ]] && ACR_NAME="$(extract_output "$OUTPUTS_JSON" AZURE_CONTAINER_REGISTRY_NAME azureContainerRegistryName ACR_NAME acrName)" [[ -z "$BACKEND_APP" ]] && BACKEND_APP="$(extract_output "$OUTPUTS_JSON" API_APP_NAME apiAppName)" if [[ -z "$SOLUTION_SUFFIX" ]]; then SOLUTION_SUFFIX="$(extract_output "$OUTPUTS_JSON" SOLUTION_NAME solutionName)" From f7e39fe1a67d7b396177b7bb871dc21a0fc1093a Mon Sep 17 00:00:00 2001 From: Shubhangi-Microsoft Date: Fri, 3 Jul 2026 16:44:29 +0530 Subject: [PATCH 07/14] updating model in comments Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- infra/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infra/main.bicep b/infra/main.bicep index ac7de01d..db3739a1 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -24,7 +24,7 @@ param solutionUniqueText string = take(uniqueString(subscription().id, resourceG ]) param location string -// Restricting deployment to regions that support all deployed models: gpt-4.1-mini, text-embedding-3-small, and gpt-realtime-mini (GlobalStandard) +// Restricting deployment to regions that support all deployed models: gpt-5.4-mini, text-embedding-3-small, and gpt-realtime-mini (GlobalStandard) @allowed(['eastus2', 'francecentral', 'swedencentral', 'centralus', 'southindia']) @metadata({ azd:{ From 782f15b474985fc07f2fefc0d85e6badfcb807e5 Mon Sep 17 00:00:00 2001 From: Shubhangi-Microsoft Date: Fri, 3 Jul 2026 16:45:12 +0530 Subject: [PATCH 08/14] updating model version in comments Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- infra/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infra/main.bicep b/infra/main.bicep index db3739a1..68e3686f 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -45,7 +45,7 @@ param secondaryLocation string = 'canadacentral' @description('Optional. Name of the GPT model to deploy:') param gptModelName string = 'gpt-5.4-mini' -@description('Optional. Version of the GPT model to deploy. Defaults to 2025-04-14.') +@description('Optional. Version of the GPT model to deploy. Defaults to 2026-03-17.') param gptModelVersion string = '2026-03-17' @description('Optional. Version of the OpenAI API.') From 502ceb071b985db23689f0074930f852865cfd18 Mon Sep 17 00:00:00 2001 From: Shubhangi-Microsoft Date: Fri, 3 Jul 2026 16:46:47 +0530 Subject: [PATCH 09/14] fixed copliot commetns --- infra/main.bicep | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/infra/main.bicep b/infra/main.bicep index 68e3686f..5fc7b896 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -605,6 +605,7 @@ var privateDnsZones = [ 'privatelink.documents.azure.com' 'privatelink.search.windows.net' 'privatelink.azurewebsites.net' + 'privatelink.azurecr.io' ] // DNS Zone Index Constants @@ -615,6 +616,7 @@ var dnsZoneIndex = { cosmosDb: 3 search: 4 webApp: 5 + containerRegistry: 4 } // List of DNS zone indices that correspond to AI-related services. @@ -1098,7 +1100,7 @@ module containerRegistry 'br/public:avm/res/container-registry/registry:0.12.1' customNetworkInterfaceName: 'nic-cr${solutionSuffix}' privateDnsZoneGroup: { privateDnsZoneGroupConfigs: [ - { privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.cognitiveServices]!.outputs.resourceId } + { privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.containerRegistry]!.outputs.resourceId } ] } service: 'registry' From 8c722ed7768fc2a6338019a164a0f2341228a8de Mon Sep 17 00:00:00 2001 From: Shubhangi-Microsoft Date: Mon, 6 Jul 2026 13:09:39 +0530 Subject: [PATCH 10/14] docs: update GPT model references from gpt-4.1-mini to gpt-5.4-mini --- README.md | 4 ++-- documents/AzureGPTQuotaSettings.md | 2 +- documents/CustomizingAzdParameters.md | 2 +- documents/DeploymentGuide.md | 6 +++--- documents/LocalDevelopmentSetup.md | 4 ++-- documents/QuotaCheck.md | 4 ++-- documents/TechnicalArchitecture.md | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 6414230e..0a333f19 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ For detailed technical information, see the component READMEs: Foundry IQ provides fast, accurate product discovery and policy document retrieval using semantic and keyword search, enabling natural language queries across product catalogs and knowledge bases. Specialized agents access search indexes to retrieve relevant information from product catalogs and policy documents. - **Natural language interaction** - Microsoft Foundry's Agent Framework orchestrates multi-agent workflows using GPT-4.1-mini to deliver conversational, context-aware responses that understand customer intent. The framework maintains conversation threads and context across sessions, enabling natural, flowing conversations with specialized agents. + Microsoft Foundry's Agent Framework orchestrates multi-agent workflows using GPT-5.4-mini to deliver conversational, context-aware responses that understand customer intent. The framework maintains conversation threads and context across sessions, enabling natural, flowing conversations with specialized agents. - **Modern e-commerce experience** React-based frontend with dual-panel layout featuring product browsing and integrated AI chat assistant for seamless shopping and support experiences @@ -100,7 +100,7 @@ _Note: This is not meant to outline all costs as selected SKUs, scaled use, cust | Product | Description | Tier / Expected Usage Notes | Cost | |---|---|---|---| | [Microsoft Foundry](https://learn.microsoft.com/en-us/azure/ai-foundry) | Used to orchestrate and build AI workflows with specialized agents for customer service. | Free Tier | [Pricing](https://azure.microsoft.com/pricing/details/ai-studio/) | -| [Azure AI Services (OpenAI)](https://learn.microsoft.com/en-us/azure/cognitive-services/openai/overview) | Enables language understanding and chat capabilities using GPT models for conversational AI. | S0 Tier; pricing depends on token volume and model used (e.g., GPT-4.1-mini). | [Pricing](https://azure.microsoft.com/pricing/details/cognitive-services/) | +| [Azure AI Services (OpenAI)](https://learn.microsoft.com/en-us/azure/cognitive-services/openai/overview) | Enables language understanding and chat capabilities using GPT models for conversational AI. | S0 Tier; pricing depends on token volume and model used (e.g., GPT-5.4-mini). | [Pricing](https://azure.microsoft.com/pricing/details/cognitive-services/) | | [Foundry IQ](https://learn.microsoft.com/en-us/azure/search/search-what-is-azure-search) | Provides hybrid search capabilities for product catalogs and policy documents with semantic and keyword search. | Basic Tier; pricing based on search units and data storage. | [Pricing](https://azure.microsoft.com/pricing/details/search/) | | [Azure App Service](https://learn.microsoft.com/en-us/azure/app-service/overview) | Hosts the frontend React application and backend FastAPI services. | Basic or Standard plan; includes a free tier for development. | [Pricing](https://azure.microsoft.com/pricing/details/app-service/windows/) | | [Azure Container Registry](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-intro) | Stores and serves container images used by Azure App Service. | Basic Tier; fixed daily cost per registry. | [Pricing](https://azure.microsoft.com/pricing/details/container-registry/) | diff --git a/documents/AzureGPTQuotaSettings.md b/documents/AzureGPTQuotaSettings.md index df1ec607..de6e903b 100644 --- a/documents/AzureGPTQuotaSettings.md +++ b/documents/AzureGPTQuotaSettings.md @@ -5,6 +5,6 @@ 3. **Go to** the `Management Center` from the bottom-left navigation menu. 4. Select `Quota` - Click on the `GlobalStandard` dropdown. - - Select the required **GPT model** (`GPT-4.1-mini`) or **Embeddings model** (`text-embedding-3-small`). + - Select the required **GPT model** (`GPT-5.4-mini`) or **Embeddings model** (`text-embedding-3-small`). - Choose the **region** where the deployment is hosted. 5. Request More Quota or delete any unused model deployments as needed. diff --git a/documents/CustomizingAzdParameters.md b/documents/CustomizingAzdParameters.md index 7c22973c..ce7f2f20 100644 --- a/documents/CustomizingAzdParameters.md +++ b/documents/CustomizingAzdParameters.md @@ -13,7 +13,7 @@ By default this template will use the environment name as the prefix to prevent | `AZURE_ENV_NAME` | string | `docgen` | Sets the environment name prefix for all Azure resources. | | | `AZURE_ENV_AI_SERVICE_LOCATION` | string | `` | Sets the Azure region for AI service resource deployment. | | `AZURE_ENV_MODEL_DEPLOYMENT_TYPE` | string | `Standard` | Defines the model deployment type (allowed: `Standard`, `GlobalStandard`). | -| `AZURE_ENV_GPT_MODEL_NAME` | string | `gpt-4.1-mini` | Specifies the GPT model name (allowed: `gpt-4.1-mini`). | +| `AZURE_ENV_GPT_MODEL_NAME` | string | `gpt-5.4-mini` | Specifies the GPT model name (allowed: `gpt-5.4-mini`). | | `AZURE_ENV_GPT_MODEL_VERSION` | string | `2025-04-14` | Set the Azure model version. | | `AZURE_ENV_GPT_MODEL_CAPACITY` | integer | `10` | Sets the GPT model capacity (based on what's available in your subscription). | | `AZURE_ENV_EMBEDDING_DEPLOYMENT_CAPACITY` | integer | `10` | Sets the embedding model deployment capacity (minimum: 10). | diff --git a/documents/DeploymentGuide.md b/documents/DeploymentGuide.md index 45c78a3f..87440ce9 100644 --- a/documents/DeploymentGuide.md +++ b/documents/DeploymentGuide.md @@ -46,7 +46,7 @@ Ensure you have access to an [Azure subscription](https://azure.microsoft.com/fr **Required Azure Services:** - [Azure AI Foundry](https://learn.microsoft.com/en-us/azure/ai-foundry/) - For Agent Framework orchestration and AI project management -- [Azure OpenAI Service](https://learn.microsoft.com/en-us/azure/ai-services/openai/) - For GPT-4.1-mini model deployments +- [Azure OpenAI Service](https://learn.microsoft.com/en-us/azure/ai-services/openai/) - For GPT-5.4-mini model deployments - [Azure AI Search](https://learn.microsoft.com/en-us/azure/search/) - For hybrid search across product catalogs and policy documents - [Azure Cosmos DB](https://learn.microsoft.com/en-us/azure/cosmos-db/) - For storing product catalogs, orders, and chat history - [Azure App Service](https://learn.microsoft.com/en-us/azure/app-service/) - For hosting frontend and backend applications @@ -62,10 +62,10 @@ Ensure you have access to an [Azure subscription](https://azure.microsoft.com/fr 📖 **Follow:** [Quota Check Instructions](./QuotaCheck.md) to ensure sufficient capacity. **Default Quota Configuration:** -- **gpt-4.1-mini:** 50k tokens +- **gpt-5.4-mini:** 50k tokens **Recommended Configuration:** -- **Minimum:** 50k tokens for Global Standard GPT-4.1-mini +- **Minimum:** 50k tokens for Global Standard GPT-5.4-mini - **Optimal:** More than 50k tokens (for best performance) > **Note:** When you run `azd up`, the deployment will automatically show you regions with available quota, so this pre-check is optional but helpful for planning purposes. You can customize these settings later in [Step 3.3: Advanced Configuration](#33-advanced-configuration-optional). diff --git a/documents/LocalDevelopmentSetup.md b/documents/LocalDevelopmentSetup.md index c82555be..fbac4fd5 100644 --- a/documents/LocalDevelopmentSetup.md +++ b/documents/LocalDevelopmentSetup.md @@ -221,12 +221,12 @@ ALLOWED_ORIGINS_STR="*" # Azure AI Foundry AZURE_AI_AGENT_ENDPOINT="https://your-ai-services.services.ai.azure.com/api/projects/your-project" -AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME="gpt-4.1-mini" +AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME="gpt-5.4-mini" AZURE_FOUNDRY_ENDPOINT="https://your-ai-services.services.ai.azure.com/api/projects/your-project" # Azure OpenAI AZURE_OPENAI_ENDPOINT="https://your-openai.openai.azure.com/" -AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4.1-mini" +AZURE_OPENAI_DEPLOYMENT_NAME="gpt-5.4-mini" AZURE_OPENAI_API_VERSION="2025-01-01-preview" # Azure AI Search diff --git a/documents/QuotaCheck.md b/documents/QuotaCheck.md index 2765ab69..ee2100a2 100644 --- a/documents/QuotaCheck.md +++ b/documents/QuotaCheck.md @@ -10,7 +10,7 @@ azd auth login ### 📌 Default Models & Capacities: ``` -gpt-4.1-mini:50,text-embedding-3-small:10,gpt-realtime-mini:1 +gpt-5.4-mini:50,text-embedding-3-small:10,gpt-realtime-mini:1 ``` ### 📌 Default Regions: ``` @@ -48,7 +48,7 @@ eastus, uksouth, eastus2, northcentralus, swedencentral, westus, westus2, southc ``` ✔️ All parameters combined: ``` - ./quota_check_params.sh --models gpt-4:150,gpt-4.1-mini:150 --regions eastus,westus --verbose + ./quota_check_params.sh --models gpt-4:150,gpt-5.4-mini:150 --regions eastus,westus --verbose ``` ### **Sample Output** diff --git a/documents/TechnicalArchitecture.md b/documents/TechnicalArchitecture.md index f02fd759..b7e85318 100644 --- a/documents/TechnicalArchitecture.md +++ b/documents/TechnicalArchitecture.md @@ -12,7 +12,7 @@ Orchestrates multi-agent workflows with an intelligent orchestrator agent that u - **Policy/Knowledge Agent**: Retrieves information from policy documents and knowledge bases to answer customer support questions about warranties, returns, and company policies ### Azure OpenAI Service -Provides large language model (LLM) capabilities using GPT-4.1-mini to power natural language understanding and conversational responses across all AI agents. +Provides large language model (LLM) capabilities using GPT-5.4-mini to power natural language understanding and conversational responses across all AI agents. ### Azure AI Search Provides hybrid search capabilities combining semantic and keyword search across product catalogs and policy documents. Enables fast, accurate retrieval of relevant information for specialized agents. From 78b64cc73ba1e05c67d9b9fe0af48484af4866da Mon Sep 17 00:00:00 2001 From: Shubhangi-Microsoft Date: Mon, 6 Jul 2026 14:53:29 +0530 Subject: [PATCH 11/14] docs: address review feedback - clarify model name wording and align QuotaCheck with quota scripts --- documents/CustomizingAzdParameters.md | 2 +- documents/QuotaCheck.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/documents/CustomizingAzdParameters.md b/documents/CustomizingAzdParameters.md index ce7f2f20..8cee953f 100644 --- a/documents/CustomizingAzdParameters.md +++ b/documents/CustomizingAzdParameters.md @@ -13,7 +13,7 @@ By default this template will use the environment name as the prefix to prevent | `AZURE_ENV_NAME` | string | `docgen` | Sets the environment name prefix for all Azure resources. | | | `AZURE_ENV_AI_SERVICE_LOCATION` | string | `` | Sets the Azure region for AI service resource deployment. | | `AZURE_ENV_MODEL_DEPLOYMENT_TYPE` | string | `Standard` | Defines the model deployment type (allowed: `Standard`, `GlobalStandard`). | -| `AZURE_ENV_GPT_MODEL_NAME` | string | `gpt-5.4-mini` | Specifies the GPT model name (allowed: `gpt-5.4-mini`). | +| `AZURE_ENV_GPT_MODEL_NAME` | string | `gpt-5.4-mini` | Specifies the GPT model name (e.g., `gpt-5.4-mini`). | | `AZURE_ENV_GPT_MODEL_VERSION` | string | `2025-04-14` | Set the Azure model version. | | `AZURE_ENV_GPT_MODEL_CAPACITY` | integer | `10` | Sets the GPT model capacity (based on what's available in your subscription). | | `AZURE_ENV_EMBEDDING_DEPLOYMENT_CAPACITY` | integer | `10` | Sets the embedding model deployment capacity (minimum: 10). | diff --git a/documents/QuotaCheck.md b/documents/QuotaCheck.md index ee2100a2..2765ab69 100644 --- a/documents/QuotaCheck.md +++ b/documents/QuotaCheck.md @@ -10,7 +10,7 @@ azd auth login ### 📌 Default Models & Capacities: ``` -gpt-5.4-mini:50,text-embedding-3-small:10,gpt-realtime-mini:1 +gpt-4.1-mini:50,text-embedding-3-small:10,gpt-realtime-mini:1 ``` ### 📌 Default Regions: ``` @@ -48,7 +48,7 @@ eastus, uksouth, eastus2, northcentralus, swedencentral, westus, westus2, southc ``` ✔️ All parameters combined: ``` - ./quota_check_params.sh --models gpt-4:150,gpt-5.4-mini:150 --regions eastus,westus --verbose + ./quota_check_params.sh --models gpt-4:150,gpt-4.1-mini:150 --regions eastus,westus --verbose ``` ### **Sample Output** From 79fec0a964cac9a0a99a66efcbd94151d7b61242 Mon Sep 17 00:00:00 2001 From: Shubhangi-Microsoft Date: Mon, 6 Jul 2026 15:09:43 +0530 Subject: [PATCH 12/14] docs: align model references with actual code - keep 5.4-mini only where main.bicep uses it, revert local/quota docs to 4.1-mini --- documents/AzureGPTQuotaSettings.md | 2 +- documents/CustomizingAzdParameters.md | 2 +- documents/LocalDevelopmentSetup.md | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/documents/AzureGPTQuotaSettings.md b/documents/AzureGPTQuotaSettings.md index de6e903b..9c0a9471 100644 --- a/documents/AzureGPTQuotaSettings.md +++ b/documents/AzureGPTQuotaSettings.md @@ -5,6 +5,6 @@ 3. **Go to** the `Management Center` from the bottom-left navigation menu. 4. Select `Quota` - Click on the `GlobalStandard` dropdown. - - Select the required **GPT model** (`GPT-5.4-mini`) or **Embeddings model** (`text-embedding-3-small`). + - Select the required **GPT model** (`gpt-4.1-mini`) or **Embeddings model** (`text-embedding-3-small`). - Choose the **region** where the deployment is hosted. 5. Request More Quota or delete any unused model deployments as needed. diff --git a/documents/CustomizingAzdParameters.md b/documents/CustomizingAzdParameters.md index 8cee953f..8eb572c2 100644 --- a/documents/CustomizingAzdParameters.md +++ b/documents/CustomizingAzdParameters.md @@ -14,7 +14,7 @@ By default this template will use the environment name as the prefix to prevent | `AZURE_ENV_AI_SERVICE_LOCATION` | string | `` | Sets the Azure region for AI service resource deployment. | | `AZURE_ENV_MODEL_DEPLOYMENT_TYPE` | string | `Standard` | Defines the model deployment type (allowed: `Standard`, `GlobalStandard`). | | `AZURE_ENV_GPT_MODEL_NAME` | string | `gpt-5.4-mini` | Specifies the GPT model name (e.g., `gpt-5.4-mini`). | -| `AZURE_ENV_GPT_MODEL_VERSION` | string | `2025-04-14` | Set the Azure model version. | +| `AZURE_ENV_GPT_MODEL_VERSION` | string | `2026-03-17` | Set the Azure model version. | | `AZURE_ENV_GPT_MODEL_CAPACITY` | integer | `10` | Sets the GPT model capacity (based on what's available in your subscription). | | `AZURE_ENV_EMBEDDING_DEPLOYMENT_CAPACITY` | integer | `10` | Sets the embedding model deployment capacity (minimum: 10). | | `AZURE_ENV_CONTAINER_REGISTRY_ENDPOINT` | string | `ccbcontainerreg.azurecr.io` | Sets the Azure Container Registry login server/endpoint (for example: `ccbcontainerreg.azurecr.io`). | diff --git a/documents/LocalDevelopmentSetup.md b/documents/LocalDevelopmentSetup.md index fbac4fd5..c82555be 100644 --- a/documents/LocalDevelopmentSetup.md +++ b/documents/LocalDevelopmentSetup.md @@ -221,12 +221,12 @@ ALLOWED_ORIGINS_STR="*" # Azure AI Foundry AZURE_AI_AGENT_ENDPOINT="https://your-ai-services.services.ai.azure.com/api/projects/your-project" -AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME="gpt-5.4-mini" +AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME="gpt-4.1-mini" AZURE_FOUNDRY_ENDPOINT="https://your-ai-services.services.ai.azure.com/api/projects/your-project" # Azure OpenAI AZURE_OPENAI_ENDPOINT="https://your-openai.openai.azure.com/" -AZURE_OPENAI_DEPLOYMENT_NAME="gpt-5.4-mini" +AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4.1-mini" AZURE_OPENAI_API_VERSION="2025-01-01-preview" # Azure AI Search From 53d812304ff658263228cca87e59fd297a5535b8 Mon Sep 17 00:00:00 2001 From: Shubhangi-Microsoft Date: Tue, 7 Jul 2026 10:53:24 +0530 Subject: [PATCH 13/14] docs: make all doc model references uniformly gpt-5.4-mini (code updates tracked separately) --- documents/AzureGPTQuotaSettings.md | 2 +- documents/LocalDevelopmentSetup.md | 4 ++-- documents/QuotaCheck.md | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/documents/AzureGPTQuotaSettings.md b/documents/AzureGPTQuotaSettings.md index 9c0a9471..9f3e69a3 100644 --- a/documents/AzureGPTQuotaSettings.md +++ b/documents/AzureGPTQuotaSettings.md @@ -5,6 +5,6 @@ 3. **Go to** the `Management Center` from the bottom-left navigation menu. 4. Select `Quota` - Click on the `GlobalStandard` dropdown. - - Select the required **GPT model** (`gpt-4.1-mini`) or **Embeddings model** (`text-embedding-3-small`). + - Select the required **GPT model** (`gpt-5.4-mini`) or **Embeddings model** (`text-embedding-3-small`). - Choose the **region** where the deployment is hosted. 5. Request More Quota or delete any unused model deployments as needed. diff --git a/documents/LocalDevelopmentSetup.md b/documents/LocalDevelopmentSetup.md index c82555be..fbac4fd5 100644 --- a/documents/LocalDevelopmentSetup.md +++ b/documents/LocalDevelopmentSetup.md @@ -221,12 +221,12 @@ ALLOWED_ORIGINS_STR="*" # Azure AI Foundry AZURE_AI_AGENT_ENDPOINT="https://your-ai-services.services.ai.azure.com/api/projects/your-project" -AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME="gpt-4.1-mini" +AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME="gpt-5.4-mini" AZURE_FOUNDRY_ENDPOINT="https://your-ai-services.services.ai.azure.com/api/projects/your-project" # Azure OpenAI AZURE_OPENAI_ENDPOINT="https://your-openai.openai.azure.com/" -AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4.1-mini" +AZURE_OPENAI_DEPLOYMENT_NAME="gpt-5.4-mini" AZURE_OPENAI_API_VERSION="2025-01-01-preview" # Azure AI Search diff --git a/documents/QuotaCheck.md b/documents/QuotaCheck.md index 2765ab69..ee2100a2 100644 --- a/documents/QuotaCheck.md +++ b/documents/QuotaCheck.md @@ -10,7 +10,7 @@ azd auth login ### 📌 Default Models & Capacities: ``` -gpt-4.1-mini:50,text-embedding-3-small:10,gpt-realtime-mini:1 +gpt-5.4-mini:50,text-embedding-3-small:10,gpt-realtime-mini:1 ``` ### 📌 Default Regions: ``` @@ -48,7 +48,7 @@ eastus, uksouth, eastus2, northcentralus, swedencentral, westus, westus2, southc ``` ✔️ All parameters combined: ``` - ./quota_check_params.sh --models gpt-4:150,gpt-4.1-mini:150 --regions eastus,westus --verbose + ./quota_check_params.sh --models gpt-4:150,gpt-5.4-mini:150 --regions eastus,westus --verbose ``` ### **Sample Output** From 03e15e2f8fb8dbc5535a6c719fda5512f13a8d91 Mon Sep 17 00:00:00 2001 From: "Niraj Chaudhari (Persistent Systems Limited)" Date: Thu, 16 Jul 2026 12:06:56 +0530 Subject: [PATCH 14/14] Update Owners ID for Vinay and Prajwal --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index eadcf322..c3f76db4 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,4 +2,4 @@ # Each line is a file pattern followed by one or more owners. # These owners will be the default owners for everything in the repo. -* @toherman-msft @brittneek @nchandhi @gpickett @malrose07 @TravisHilbert @Avijit-Microsoft @Roopan-Microsoft @Prajwal1-Microsoft @VinaySh-Microsoft +* @toherman-msft @brittneek @nchandhi @gpickett @malrose07 @TravisHilbert @Avijit-Microsoft @Roopan-Microsoft @Prajwal-Microsoft @Vinay-Microsoft