Skip to content

Commit 746854a

Browse files
authored
Merge pull request #11 from MicrosoftCloudEssentials-LearningHub/patch-product-agent
Patch product agent
2 parents a21a3ee + 7565c2e commit 746854a

9 files changed

Lines changed: 148 additions & 80 deletions

File tree

README.md

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Last updated: 2025-12-04
1212
> [!IMPORTANT]
1313
> Disclaimer: This repository contains a demo of `Zava AI Shopping Assistant`, an enhanced multi-agent system implementing Agent-to-Agent (A2A) protocol for e-commerce. It features a fully automated `"Zero-Touch" deployment` pipeline orchestrated by Terraform, which `provisions infrastructure, ingests data, creates specialized AI agents with delegation patterns in MSFT Foundry, and deploys the complete A2A application stack.` Please refer [TechWorkshop L300: AI Apps and Agents](https://microsoft.github.io/TechWorkshop-L300-AI-Apps-and-agents/), and if needed contact Microsoft directly: [Microsoft Sales and Support](https://support.microsoft.com/contactus?ContactUsExperienceEntryPointAssetId=S.HP.SMC-HOME) for more guidance. There are tons of free resources out there, all eager to support!
1414
15+
> E.g
16+
1517
<img width="1905" height="1086" alt="image" src="https://github.com/user-attachments/assets/5cd2776f-4606-45c2-9482-53ff2d4df74e" />
1618

1719
> [!IMPORTANT]
@@ -116,6 +118,8 @@ graph TD
116118
- Deploys AI Models (`gpt-4o-mini`, `text-embedding-3-small`).
117119
- Sets up A2A protocol infrastructure including event queues and monitoring.
118120

121+
> E.g
122+
119123
<img width="1859" height="900" alt="image" src="https://github.com/user-attachments/assets/cd24ab7f-5ddd-46de-b266-0d0a24c45803" />
120124

121125
2. **A2A Framework Deployment**:
@@ -128,10 +132,14 @@ graph TD
128132
- Sets up a Python virtual environment.
129133
- Ingests `product_catalog.csv` into Cosmos DB with A2A event notifications.
130134

135+
> E.g
136+
131137
<https://github.com/user-attachments/assets/41bf0976-0ca8-47fe-a2fa-8750bcc6f848>
132138

133139
- Creates and populates an Azure AI Search index with vector embeddings through A2A coordination.
134140

141+
> E.g
142+
135143
<https://github.com/user-attachments/assets/37c4a8cd-73e1-4392-8755-fb018481d8cb>
136144

137145
4. **Enhanced Agent Creation & A2A Registration**:
@@ -145,7 +153,9 @@ graph TD
145153
- Configures delegation relationships between Product Manager and specialized agents.
146154
- Saves the unique Agent IDs, delegation endpoints, and A2A configuration to the `.env` file.
147155

148-
<img width="1907" height="990" alt="image" src="https://github.com/user-attachments/assets/4234ead4-16e0-4bec-bbfd-3b8891d113b0" />
156+
> E.g
157+
158+
<img width="1881" height="1000" alt="image" src="https://github.com/user-attachments/assets/59a9dcaf-9291-403c-b8b0-1195c1375aac" />
149159

150160
5. **Application Deployment**:
151161
- Builds the Docker container with A2A protocol support in the cloud (ACR Build).
@@ -161,6 +171,8 @@ graph TD
161171
- Visit `https://<your-app-name>.azurewebsites.net`.
162172
- You should see the Zava chat interface with A2A protocol support.
163173

174+
> E.g
175+
164176
<https://github.com/user-attachments/assets/a1139528-6b37-4ac2-a1cb-771788ff45a4>
165177

166178
2. **Verify A2A Protocol Endpoints**:
@@ -175,6 +187,8 @@ graph TD
175187
- Core agents: Cora, Interior Design, Inventory, Loyalty, Cart Manager
176188
- Product Management Specialist with delegation capabilities
177189

190+
> E.g
191+
178192
<https://github.com/user-attachments/assets/3c562ccd-cff3-4a30-b9f8-44111fb71113>
179193

180194
4. **Test Enhanced A2A Interactions**: For example:
@@ -188,7 +202,7 @@ graph TD
188202

189203
<!-- START BADGE -->
190204
<div align="center">
191-
<img src="https://img.shields.io/badge/Total%20views-1624-limegreen" alt="Total views">
192-
<p>Refresh Date: 2025-12-03</p>
205+
<img src="https://img.shields.io/badge/Total%20views-1696-limegreen" alt="Total views">
206+
<p>Refresh Date: 2025-12-04</p>
193207
</div>
194208
<!-- END BADGE -->

TROUBLESHOOTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ terraform apply
347347

348348
<!-- START BADGE -->
349349
<div align="center">
350-
<img src="https://img.shields.io/badge/Total%20views-1624-limegreen" alt="Total views">
351-
<p>Refresh Date: 2025-12-03</p>
350+
<img src="https://img.shields.io/badge/Total%20views-1696-limegreen" alt="Total views">
351+
<p>Refresh Date: 2025-12-04</p>
352352
</div>
353353
<!-- END BADGE -->

src/Dockerfile

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,16 @@ FROM python:3.11-slim
22

33
WORKDIR /app
44

5+
# Set environment variables to avoid encoding issues
6+
ENV PYTHONUNBUFFERED=1
7+
ENV PYTHONIOENCODING=utf-8
8+
59
# Copy requirements first for better caching
610
COPY requirements.txt .
7-
RUN pip install --no-cache-dir -r requirements.txt
11+
12+
# Install dependencies with better error handling
13+
RUN pip install --no-cache-dir --upgrade pip && \
14+
pip install --no-cache-dir -r requirements.txt
815

916
# Copy application code
1017
COPY . .

src/a2a/.env_automation

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ A2A_PORT=8001
44
A2A_LOG_LEVEL=INFO
55

66
# Base application URL for monitoring
7-
BASE_APP_URL=https://zava-51c07969-app.azurewebsites.net
7+
BASE_APP_URL=https://zava-89c29415-app.azurewebsites.net
88

99
# Azure monitoring integration
10-
APPLICATION_INSIGHTS_CONNECTION_STRING=InstrumentationKey=3ecb7f2d-bf9b-4c15-973f-39e820e44b10;IngestionEndpoint=https://westus3-1.in.applicationinsights.azure.com/;LiveEndpoint=https://westus3.livediagnostics.monitor.azure.com/;ApplicationId=c47cdc80-ebeb-4b09-a7f5-4f9b6c9502dc
11-
LOG_ANALYTICS_WORKSPACE_ID=d3733137-0fd4-48ea-ad35-e3d066ec4d0b
10+
APPLICATION_INSIGHTS_CONNECTION_STRING=InstrumentationKey=db468090-243d-4b9c-8e5a-063f0e5f9ca6;IngestionEndpoint=https://westus3-1.in.applicationinsights.azure.com/;LiveEndpoint=https://westus3.livediagnostics.monitor.azure.com/;ApplicationId=f1a5d58e-12b6-4618-a3c9-c9ede48ab925
11+
LOG_ANALYTICS_WORKSPACE_ID=fcb95690-218c-4e99-a3be-a552f4cf877d
1212

1313
# Automation features
1414
ENABLE_PROCESS_MANAGEMENT=true

src/a2a/status_automation.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ if () {
1111

1212
# Check automation endpoint
1313
try {
14-
= Invoke-RestMethod -Uri "https://zava-51c07969-app.azurewebsites.net/a2a/automation/status" -TimeoutSec 5
14+
= Invoke-RestMethod -Uri "https://zava-89c29415-app.azurewebsites.net/a2a/automation/status" -TimeoutSec 5
1515
Write-Host "Automation Status: "
1616
} catch {
1717
Write-Host "Automation endpoint not accessible"

src/requirements.txt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,5 @@ websockets==13.1
1414
jinja2==3.1.4
1515
python-multipart==0.0.12
1616
orjson==3.10.7
17-
pydantic==2.10.4
17+
pydantic==2.9.2
1818
Pillow>=10.4.0
19-
20-
# Microsoft Agent Framework for A2A Protocol (Preview)
21-
agent-framework-azure-ai --pre

src/requirements_minimal.txt

Lines changed: 0 additions & 2 deletions
This file was deleted.

terraform-infrastructure/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ graph TD;
119119

120120
<!-- START BADGE -->
121121
<div align="center">
122-
<img src="https://img.shields.io/badge/Total%20views-1624-limegreen" alt="Total views">
123-
<p>Refresh Date: 2025-12-03</p>
122+
<img src="https://img.shields.io/badge/Total%20views-1696-limegreen" alt="Total views">
123+
<p>Refresh Date: 2025-12-04</p>
124124
</div>
125125
<!-- END BADGE -->

terraform-infrastructure/main.tf

Lines changed: 114 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,116 @@ resource "azurerm_container_registry_webhook" "webhook" {
294294
]
295295
}
296296

297+
# Standalone Docker Image Build - Always runs to ensure ACR has the required image
298+
resource "null_resource" "docker_image_build" {
299+
# Trigger rebuild when:
300+
# 1. Dockerfile changes
301+
# 2. Application source code changes
302+
# 3. Requirements.txt changes
303+
# 4. ACR or app changes
304+
# 5. Force rebuild on every apply (always_run ensures terraform always executes the provisioner)
305+
triggers = {
306+
dockerfile_hash = local.dockerfile_hash
307+
app_source_hash = local.app_source_hash
308+
requirements_hash = fileexists("../src/requirements.txt") ? filesha256("../src/requirements.txt") : "missing"
309+
acr_id = azurerm_container_registry.acr.id
310+
always_run = timestamp() # Forces provisioner to run on every apply
311+
}
312+
313+
depends_on = [
314+
azurerm_container_registry.acr
315+
]
316+
317+
provisioner "local-exec" {
318+
command = <<-EOT
319+
Write-Host ""
320+
Write-Host "=========================================="
321+
Write-Host "Building & Pushing Docker Image to ACR"
322+
Write-Host "=========================================="
323+
Write-Host ""
324+
325+
$ErrorActionPreference = "Continue" # Don't stop on warnings
326+
cd ..
327+
$srcPath = "src"
328+
329+
Write-Host "Starting Docker build and push to ACR..."
330+
Write-Host "Registry: ${local.registry_name}"
331+
Write-Host "Image: zava-chat-app:latest"
332+
Write-Host "Dockerfile: $srcPath/Dockerfile"
333+
Write-Host "Source Path: $srcPath"
334+
Write-Host ""
335+
336+
# Set encoding for Azure CLI
337+
$env:PYTHONIOENCODING = "utf-8"
338+
chcp 65001 > $null
339+
340+
Write-Host "Executing ACR build command..."
341+
Write-Host ""
342+
343+
try {
344+
# Build and push image
345+
az acr build `
346+
--resource-group ${azurerm_resource_group.rg.name} `
347+
--registry ${local.registry_name} `
348+
--image zava-chat-app:latest `
349+
--file "$srcPath\Dockerfile" `
350+
"$srcPath" `
351+
--no-logs
352+
353+
if ($LASTEXITCODE -eq 0) {
354+
Write-Host ""
355+
Write-Host "[SUCCESS] Docker image successfully built and pushed to ACR"
356+
Write-Host ""
357+
Write-Host "Image details:"
358+
Write-Host " Registry: ${local.registry_name}.azurecr.io"
359+
Write-Host " Repository: zava-chat-app"
360+
Write-Host " Tag: latest"
361+
Write-Host ""
362+
363+
# Wait for image to be available
364+
Write-Host "Waiting for image to be available in registry..."
365+
Start-Sleep -Seconds 10
366+
367+
# Verify image exists in ACR
368+
Write-Host "Verifying image in ACR..."
369+
$imgCheck = az acr repository show --name ${local.registry_name} --image zava-chat-app:latest --query "name" -o tsv 2>$null
370+
371+
if ($LASTEXITCODE -eq 0 -and $imgCheck -eq "zava-chat-app") {
372+
Write-Host "[VERIFIED] Image confirmed in ACR registry"
373+
Write-Host ""
374+
exit 0
375+
} else {
376+
Write-Host "[WARNING] Image verification failed but build succeeded"
377+
Write-Host "This may be a timing issue. Image should be available shortly."
378+
Write-Host ""
379+
exit 0
380+
}
381+
} else {
382+
Write-Host ""
383+
Write-Host "[ERROR] ACR build failed with exit code: $LASTEXITCODE"
384+
Write-Host ""
385+
Write-Host "Troubleshooting steps:"
386+
Write-Host " 1. Check requirements.txt for dependency conflicts"
387+
Write-Host " 2. Verify Dockerfile paths are correct"
388+
Write-Host " 3. Manual build command:"
389+
Write-Host " az acr build --resource-group ${azurerm_resource_group.rg.name} --registry ${local.registry_name} --image zava-chat-app:latest --file $srcPath\Dockerfile $srcPath"
390+
Write-Host ""
391+
exit 1
392+
}
393+
} catch {
394+
Write-Host ""
395+
Write-Host "[ERROR] Exception during build: $_"
396+
Write-Host "Manual build command:"
397+
Write-Host "az acr build --resource-group ${azurerm_resource_group.rg.name} --registry ${local.registry_name} --image zava-chat-app:latest --file $srcPath\Dockerfile $srcPath"
398+
Write-Host ""
399+
exit 1
400+
}
401+
EOT
402+
interpreter = ["PowerShell", "-Command"]
403+
working_dir = path.module
404+
}
405+
}
406+
297407
resource "azurerm_service_plan" "appserviceplan" {
298408
name = local.app_service_plan
299409
resource_group_name = azurerm_resource_group.rg.name
@@ -373,7 +483,8 @@ resource "azurerm_linux_web_app" "app" {
373483

374484
depends_on = [
375485
azurerm_container_registry.acr,
376-
null_resource.ai_model_deployments
486+
null_resource.ai_model_deployments,
487+
null_resource.docker_image_build
377488
]
378489
}
379490

@@ -1677,68 +1788,9 @@ resource "null_resource" "deploy_multi_agents" {
16771788
}
16781789
16791790
Write-Host ""
1680-
Write-Host "Triggering container rebuild with agent configuration..."
1681-
cd ..
1682-
$srcPath = "src"
1683-
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
1684-
$env:PYTHONIOENCODING = "utf-8"
1685-
1686-
Write-Host "Building container image in Azure Container Registry..."
1687-
Write-Host "This may take 2-3 minutes..."
1688-
1689-
# Build with logs enabled to see progress
1690-
$buildSuccess = $false
1691-
try {
1692-
az acr build `
1693-
--resource-group ${azurerm_resource_group.rg.name} `
1694-
--registry ${local.registry_name} `
1695-
--image zava-chat-app:latest `
1696-
--file "$srcPath\Dockerfile" `
1697-
"$srcPath"
1698-
1699-
if ($LASTEXITCODE -eq 0) {
1700-
Write-Host "[SUCCESS] ACR build completed successfully"
1701-
$buildSuccess = $true
1702-
} else {
1703-
Write-Host "[ERROR] ACR build failed with exit code: $LASTEXITCODE"
1704-
}
1705-
} catch {
1706-
Write-Host "[ERROR] ACR build exception: $_"
1707-
}
1708-
1709-
# Verify image exists
1710-
Write-Host ""
1711-
Write-Host "Verifying image in ACR..."
1712-
$imageExists = $false
1713-
for ($attempt = 1; $attempt -le 3; $attempt++) {
1714-
try {
1715-
$imgCheck = az acr repository show --name ${local.registry_name} --image zava-chat-app:latest --query "name" -o tsv 2>&1
1716-
if ($LASTEXITCODE -eq 0 -and $imgCheck -eq "zava-chat-app") {
1717-
Write-Host "[OK] Image verified in ACR: zava-chat-app:latest"
1718-
$imageExists = $true
1719-
break
1720-
}
1721-
} catch { }
1722-
if ($attempt -lt 3) {
1723-
Write-Host "Image not found yet, waiting 10s... (attempt $attempt/3)"
1724-
Start-Sleep -Seconds 10
1725-
}
1726-
}
1727-
1728-
if (-not $imageExists) {
1729-
Write-Host "[CRITICAL] Image not found in ACR after build. Web App cannot start."
1730-
Write-Host "Please check ACR build logs in Azure Portal."
1731-
exit 0 # Non-blocking but logged
1732-
}
1733-
1734-
# Web App will automatically pull image using managed identity (AcrPull role)
1735-
# No need to set ACR credentials - managed identity handles authentication
1736-
Write-Host ""
1737-
Write-Host "[INFO] Web App configured to use managed identity for ACR access"
1738-
Write-Host "[INFO] Webhook will trigger automatic deployment on image push"
1739-
1791+
Write-Host "Docker image already built by standalone resource."
17401792
Write-Host ""
1741-
Write-Host "Restarting Web App to pull new image..."
1793+
Write-Host "Restarting Web App to ensure latest configuration..."
17421794
az webapp restart --resource-group ${azurerm_resource_group.rg.name} --name ${local.web_app_name} | Out-Null
17431795
Write-Host "[OK] Web App restarted"
17441796
Write-Host ""

0 commit comments

Comments
 (0)