Skip to content

Commit 80440ba

Browse files
Merge branch 'dev' into hotfix
2 parents 75af1fe + b3073cc commit 80440ba

File tree

211 files changed

+21118
-4365
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

211 files changed

+21118
-4365
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: Broken Link Checker
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- '**/*.md'
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
markdown-link-check:
14+
name: Check Markdown Broken Links
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout Repo
19+
uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
22+
23+
# For PR : Get only changed markdown files
24+
- name: Get changed markdown files (PR only)
25+
id: changed-markdown-files
26+
if: github.event_name == 'pull_request'
27+
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46
28+
with:
29+
files: |
30+
**/*.md
31+
32+
33+
# For PR: Check broken links only in changed files
34+
- name: Check Broken Links in Changed Markdown Files
35+
id: lychee-check-pr
36+
if: github.event_name == 'pull_request' && steps.changed-markdown-files.outputs.any_changed == 'true'
37+
uses: lycheeverse/[email protected]
38+
with:
39+
args: >
40+
--verbose --exclude-mail --no-progress --exclude ^https?://
41+
${{ steps.changed-markdown-files.outputs.all_changed_files }}
42+
failIfEmpty: false
43+
env:
44+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
45+
46+
# For manual trigger: Check all markdown files in repo
47+
- name: Check Broken Links in All Markdown Files in Entire Repo (Manual Trigger)
48+
id: lychee-check-manual
49+
if: github.event_name == 'workflow_dispatch'
50+
uses: lycheeverse/[email protected]
51+
with:
52+
args: >
53+
--verbose --exclude-mail --no-progress --exclude ^https?://
54+
'**/*.md'
55+
failIfEmpty: false
56+
env:
57+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/deploy-waf.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ jobs:
106106
virtualMachineConfiguration='{"adminUsername": "adminuser", "adminPassword": "P@ssw0rd1234"}' \
107107
logAnalyticsWorkspaceConfiguration='{"existingWorkspaceResourceId": ""}'
108108
109+
109110
- name: Send Notification on Failure
110111
if: failure()
111112
run: |

.github/workflows/deploy.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
export AZURE_TENANT_ID=${{ secrets.AZURE_TENANT_ID }}
3838
export AZURE_CLIENT_SECRET=${{ secrets.AZURE_CLIENT_SECRET }}
3939
export AZURE_SUBSCRIPTION_ID="${{ secrets.AZURE_SUBSCRIPTION_ID }}"
40-
export GPT_MIN_CAPACITY="140"
40+
export GPT_MIN_CAPACITY="5"
4141
export AZURE_REGIONS="${{ vars.AZURE_REGIONS }}"
4242
4343
chmod +x infra/scripts/checkquota.sh
@@ -128,13 +128,21 @@ jobs:
128128
--resource-group ${{ env.RESOURCE_GROUP_NAME }} \
129129
--template-file infra/main.bicep \
130130
--parameters \
131+
131132
solutionPrefix=${{ env.SOLUTION_PREFIX }} \
132133
solutionLocation="${{ env.AZURE_LOCATION }}" \
133134
azureOpenAILocation="${{ env.AZURE_LOCATION }}" \
134135
modelDeploymentType="GlobalStandard" \
135136
gptModelName="gpt-4o" \
136137
gptModelVersion="2024-08-06" \
137138
imageTag="${IMAGE_TAG}" \
139+
useWafAlignedArchitecture=false \
140+
aiDeploymentsLocation='${{ env.AZURE_LOCATION }}' \
141+
gptModelCapacity=5 \
142+
logAnalyticsWorkspaceConfiguration='{"dataRetentionInDays": 30, "existingWorkspaceResourceId": ""}' \
143+
applicationInsightsConfiguration='{"retentionInDays": 30}' \
144+
virtualNetworkConfiguration='{"enabled": false}' \
145+
webServerFarmConfiguration='{"skuCapacity": 1, "skuName": "B2"}'
138146
--output json
139147
140148
- name: Extract Web App and API App URLs
@@ -148,6 +156,7 @@ jobs:
148156
fi
149157
done
150158
159+
151160
- name: Get Container App Backend URL
152161
id: get_backend_url
153162
run: |

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ Solution overview
2222
The solution leverages Azure OpenAI Service, Azure Container Apps, Azure Cosmos DB, and Azure Container Registry to create an intelligent automation pipeline. It uses a multi-agent approach where specialized AI agents work together to plan, execute, and validate tasks based on user input.
2323

2424
### Solution architecture
25-
|![image](./docs/images/readme/macae-architecture.png)|
25+
|![image](./docs/images/readme/architecture.png)|
2626
|---|
2727

28-
28+
### Agentic architecture
29+
|![image](./docs/images/readme/agent_flow.png)|
30+
|---|
2931

3032
### How to customize
3133
If you'd like to customize the solution accelerator, here are some common areas to start:
@@ -111,7 +113,7 @@ either by deleting the resource group in the Portal or running `azd down`.
111113
Business Scenario
112114
</h2>
113115

114-
|![image](./docs/images/readme/macae-application.png)|
116+
|![image](./docs/images/readme/application.png)|
115117
|---|
116118

117119
<br/>

__azurite_db_queue__.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"filename":"c:\\src\\Multi-Agent-Custom-Automation-Engine-Solution-Accelerator\\__azurite_db_queue__.json","collections":[{"name":"$SERVICES_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{},"constraints":null,"uniqueNames":["accountName"],"transforms":{},"objType":"$SERVICES_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]},{"name":"$QUEUES_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{"accountName":{"name":"accountName","dirty":false,"values":[]},"name":{"name":"name","dirty":false,"values":[]}},"constraints":null,"uniqueNames":[],"transforms":{},"objType":"$QUEUES_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]},{"name":"$MESSAGES_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{"accountName":{"name":"accountName","dirty":false,"values":[]},"queueName":{"name":"queueName","dirty":false,"values":[]},"messageId":{"name":"messageId","dirty":false,"values":[]},"visibleTime":{"name":"visibleTime","dirty":false,"values":[]}},"constraints":null,"uniqueNames":[],"transforms":{},"objType":"$MESSAGES_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]}],"databaseVersion":1.5,"engineVersion":1.5,"autosave":true,"autosaveInterval":5000,"autosaveHandle":null,"throttledSaves":true,"options":{"persistenceMethod":"fs","autosave":true,"autosaveInterval":5000,"serializationMethod":"normal","destructureDelimiter":"$<\n"},"persistenceMethod":"fs","persistenceAdapter":null,"verbose":false,"events":{"init":[null],"loaded":[],"flushChanges":[],"close":[],"changes":[],"warning":[]},"ENV":"NODEJS"}

__azurite_db_queue_extent__.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"filename":"c:\\src\\Multi-Agent-Custom-Automation-Engine-Solution-Accelerator\\__azurite_db_queue_extent__.json","collections":[{"name":"$EXTENTS_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{"id":{"name":"id","dirty":false,"values":[]}},"constraints":null,"uniqueNames":[],"transforms":{},"objType":"$EXTENTS_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]}],"databaseVersion":1.5,"engineVersion":1.5,"autosave":true,"autosaveInterval":5000,"autosaveHandle":null,"throttledSaves":true,"options":{"persistenceMethod":"fs","autosave":true,"autosaveInterval":5000,"serializationMethod":"normal","destructureDelimiter":"$<\n"},"persistenceMethod":"fs","persistenceAdapter":null,"verbose":false,"events":{"init":[null],"loaded":[],"flushChanges":[],"close":[],"changes":[],"warning":[]},"ENV":"NODEJS"}

azure.yaml

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,5 @@
22
name: multi-agent-custom-automation-engine-solution-accelerator
33
metadata:
44
5-
hooks:
6-
preprovision:
7-
posix:
8-
shell: sh
9-
run: >
10-
chmod u+r+x ./infra/scripts/validate_model_deployment_quota.sh; chmod u+r+x ./infra/scripts/validate_model_quota.sh; ./infra/scripts/validate_model_deployment_quota.sh --subscription "$AZURE_SUBSCRIPTION_ID" --location "${AZURE_ENV_OPENAI_LOCATION:-swedencentral}" --models-parameter "aiModelDeployments"
11-
interactive: false
12-
continueOnError: false
13-
14-
windows:
15-
shell: pwsh
16-
run: >
17-
$location = if ($env:AZURE_ENV_OPENAI_LOCATION) { $env:AZURE_ENV_OPENAI_LOCATION } else { "swedencentral" };
18-
./infra/scripts/validate_model_deployment_quotas.ps1 -SubscriptionId $env:AZURE_SUBSCRIPTION_ID -Location $location -ModelsParameter "aiModelDeployments"
19-
interactive: false
20-
continueOnError: false
5+
requiredVersions:
6+
azd: ">=1.15.0 !=1.17.1"

docs/CustomizingAzdParameters.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ By default this template will use the environment name as the prefix to prevent
1313
| `AZURE_ENV_OPENAI_LOCATION` | string | `swedencentral` | Specifies the region for OpenAI resource deployment. |
1414
| `AZURE_ENV_MODEL_DEPLOYMENT_TYPE` | string | `GlobalStandard` | Defines the deployment type for the AI model (e.g., Standard, GlobalStandard). |
1515
| `AZURE_ENV_MODEL_NAME` | string | `gpt-4o` | Specifies the name of the GPT model to be deployed. |
16+
| `AZURE_ENV_FOUNDRY_PROJECT_ID` | string | `<Existing Workspace Id>` | Set this if you want to reuse an AI Foundry Project instead of creating a new one. |
1617
| `AZURE_ENV_MODEL_VERSION` | string | `2024-08-06` | Version of the GPT model to be used for deployment. |
18+
| `AZURE_ENV_MODEL_CAPACITY` | int | `150` | Sets the GPT model capacity. |
1719
| `AZURE_ENV_IMAGETAG` | string | `latest` | Docker image tag used for container deployments. |
1820
| `AZURE_ENV_ENABLE_TELEMETRY` | bool | `true` | Enables telemetry for monitoring and diagnostics. |
19-
21+
| `AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID` | string | `<Existing Workspace Id>` | Set this if you want to reuse an existing Log Analytics Workspace instead of creating a new one. |
2022
---
2123

2224
## How to Set a Parameter
@@ -27,6 +29,11 @@ To customize any of the above values, run the following command **before** `azd
2729
azd env set <PARAMETER_NAME> <VALUE>
2830
```
2931

32+
Set the Log Analytics Workspace Id if you need to reuse the existing workspace which is already existing
33+
```shell
34+
azd env set AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID '/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.OperationalInsights/workspaces/<workspace-name>'
35+
```
36+
3037
**Example:**
3138

3239
```bash

docs/DeploymentGuide.md

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,29 @@ This will allow the scripts to run for the current session without permanently c
3232

3333
The [`infra`](../infra) folder of the Multi Agent Solution Accelerator contains the [`main.bicep`](../infra/main.bicep) Bicep script, which defines all Azure infrastructure components for this solution.
3434

35-
By default, the `azd up` command uses the [`main.bicepparam`](../infra/main.bicepparam) file to deploy the solution. This file is pre-configured for a **sandbox environment** — ideal for development and proof-of-concept scenarios, with minimal security and cost controls for rapid iteration.
35+
When running `azd up`, you’ll now be prompted to choose between a **WAF-aligned configuration** and a **sandbox configuration** using a simple selection:
3636

37-
For **production deployments**, the repository also provides [`main.waf-aligned.bicepparam`](../infra/main.waf-aligned.bicepparam), which applies a [Well-Architected Framework (WAF) aligned](https://learn.microsoft.com/en-us/azure/well-architected/) configuration. This option enables additional Azure best practices for reliability, security, cost optimization, operational excellence, and performance efficiency, such as:
37+
- A **sandbox environment** — ideal for development and proof-of-concept scenarios, with minimal security and cost controls for rapid iteration.
3838

39-
- Enhanced network security (e.g., Network protection with private endpoints)
40-
- Stricter access controls and managed identities
41-
- Logging, monitoring, and diagnostics enabled by default
42-
- Resource tagging and cost management recommendations
39+
- A **production deployments environment**, which applies a [Well-Architected Framework (WAF) aligned](https://learn.microsoft.com/en-us/azure/well-architected/) configuration. This option enables additional Azure best practices for reliability, security, cost optimization, operational excellence, and performance efficiency, such as:
40+
- Enhanced network security (e.g., Network protection with private endpoints)
41+
- Stricter access controls and managed identities
42+
- Logging, monitoring, and diagnostics enabled by default
43+
- Resource tagging and cost management recommendations
4344

4445
**How to choose your deployment configuration:**
45-
- Use the default [`main.bicepparam`](../infra/main.bicepparam) for a sandbox/dev environment.
46-
- For a WAF-aligned, production-ready deployment, copy the contents of [`main.waf-aligned.bicepparam`](../infra/main.waf-aligned.bicepparam) into `main.bicepparam` before running `azd up`.
46+
47+
When prompted during `azd up`:
48+
49+
![useWAFAlignedArchitecture](images/macae_waf_prompt.png)
50+
51+
- Select **`true`** to deploy a **WAF-aligned, production-ready environment**
52+
- Select **`false`** to deploy a **lightweight sandbox/dev environment**
4753

4854
> [!TIP]
4955
> Always review and adjust parameter values (such as region, capacity, security settings and log analytics workspace configuration) to match your organization’s requirements before deploying. For production, ensure you have sufficient quota and follow the principle of least privilege for all identities and role assignments.
5056
51-
> To reuse an existing Log Analytics workspace, update the existingWorkspaceResourceId field under the logAnalyticsWorkspaceConfiguration parameter in the bicepparam file with the resource ID of your existing workspace.
57+
> To reuse an existing Log Analytics workspace, update the existingWorkspaceResourceId field under the logAnalyticsWorkspaceConfiguration parameter in the .bicep file with the resource ID of your existing workspace.
5258
For example:
5359
```
5460
param logAnalyticsWorkspaceConfiguration = {
@@ -111,7 +117,7 @@ If you're not using one of the above options for opening the project, then you'l
111117
1. Make sure the following tools are installed:
112118

113119
- [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell?view=powershell-7.5) <small>(v7.0+)</small> - available for Windows, macOS, and Linux.
114-
- [Azure Developer CLI (azd)](https://aka.ms/install-azd)
120+
- [Azure Developer CLI (azd)](https://aka.ms/install-azd) <small>(v1.15.0+)</small> - version
115121
- [Python 3.9+](https://www.python.org/downloads/)
116122
- [Docker Desktop](https://www.docker.com/products/docker-desktop/)
117123
- [Git](https://git-scm.com/downloads)
@@ -144,6 +150,7 @@ When you start the deployment, most parameters will have **default values**, but
144150
| **Model Deployment Type** | Defines the deployment type for the AI model (e.g., Standard, GlobalStandard). | GlobalStandard |
145151
| **GPT Model Name** | Specifies the name of the GPT model to be deployed. | gpt-4o |
146152
| **GPT Model Version** | Version of the GPT model to be used for deployment. | 2024-08-06 |
153+
| **GPT Model Capacity** | Sets the GPT model capacity. | 150 |
147154
| **Image Tag** | Docker image tag used for container deployments. | latest |
148155
| **Enable Telemetry** | Enables telemetry for monitoring and diagnostics. | true |
149156

@@ -161,6 +168,14 @@ To adjust quota settings, follow these [steps](./AzureGPTQuotaSettings.md).
161168

162169
</details>
163170

171+
<details>
172+
173+
<summary><b>Reusing an Existing Log Analytics Workspace</b></summary>
174+
175+
Guide to get your [Existing Workspace ID](/docs/re-use-log-analytics.md)
176+
177+
</details>
178+
164179
### Deploying with AZD
165180

166181
Once you've opened the project in [Codespaces](#github-codespaces), [Dev Containers](#vs-code-dev-containers), or [locally](#local-environment), you can deploy it to Azure by following these steps:
@@ -318,7 +333,7 @@ The files for the dev container are located in `/.devcontainer/` folder.
318333
```
319334
320335
```bash
321-
az role assignment create --assignee <aad-user-upn> --role "Cognitive Services OpenAI User" --scope /subscriptions/<subscription-id>/resourceGroups/<solution-accelerator-rg>/providers/Microsoft.CognitiveServices/accounts/<azure-openai-account-name>
336+
az role assignment create --assignee <aad-user-upn> --role "Azure AI User" --scope /subscriptions/<subscription-id>/resourceGroups/<solution-accelerator-rg>/providers/Microsoft.CognitiveServices/accounts/<azure-ai-foundry-name>
322337
```
323338
324339
**Using a Different Database in Cosmos:**
@@ -353,7 +368,7 @@ The files for the dev container are located in `/.devcontainer/` folder.
353368
- From the src/backend directory:
354369
355370
```bash
356-
python app.py
371+
python app_kernel.py
357372
```
358373
359374
- In a new terminal from the src/frontend directory

docs/LocalDeployment.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ The files for the dev container are located in `/.devcontainer/` folder.
9292
```
9393
9494
```bash
95-
az role assignment create --assignee <aad-user-upn> --role "Cognitive Services OpenAI User" --scope /subscriptions/<subscription-id>/resourceGroups/<solution-accelerator-rg>/providers/Microsoft.CognitiveServices/accounts/<azure-openai-account-name>
95+
az role assignment create --assignee <aad-user-upn> --role "Azure AI User" --scope /subscriptions/<subscription-id>/resourceGroups/<solution-accelerator-rg>/providers/Microsoft.CognitiveServices/accounts/<azure-ai-foundry-name>
9696
```
9797
**Using a Different Database in Cosmos:**
9898
@@ -123,7 +123,7 @@ The files for the dev container are located in `/.devcontainer/` folder.
123123
10. **Run the application:**
124124
- From the src/backend directory:
125125
```bash
126-
python app.py
126+
python app_kernel.py
127127
```
128128
- In a new terminal from the src/frontend directory
129129
```bash

0 commit comments

Comments
 (0)