Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
08eafce
Add toaster message of failure in logs
NirajC-Microsoft May 15, 2026
c0dd8c0
Resolve copilot comments and fix test pipeline coverage
NirajC-Microsoft May 15, 2026
f736f36
Updated Foundry Roles name
AjitPadhi-Microsoft May 18, 2026
1a6deb7
Merge pull request #986 from microsoft/dev-v4
Roopan-Microsoft May 18, 2026
723cb0c
remove AI Agennt after System
NirajC-Microsoft May 18, 2026
6e744e7
Merge pull request #985 from microsoft/psl-fix-43544
Roopan-Microsoft May 18, 2026
6897eab
Merge pull request #987 from microsoft/main
Roopan-Microsoft May 18, 2026
9d7cb94
fix: address SFI security compliance issues
VishalS-Microsoft May 19, 2026
34df066
Enhance email template, add RG owner tag, scalability input
Vamshi-Microsoft May 19, 2026
e5afd16
refactor: reorder inputs in deploy-v2.yml for clarity
Vamshi-Microsoft May 19, 2026
dcc1aaf
chore: dev-v4 to dependabotchanges downmerge
Ayaz-Microsoft May 19, 2026
78f87fa
build: bump authlib from 1.6.11 to 1.6.12 in /src/mcp_server
Ayaz-Microsoft May 19, 2026
c7a5649
fix: enforce HTTPS-only ingress for container apps
VishalS-Microsoft May 19, 2026
55bcdaa
Merge pull request #988 from microsoft/PSL-US-43670
May 19, 2026
2cc70f7
Merge branch 'dev-v4' into psl-fixexpsfiissues-macae
VishalS-Microsoft May 19, 2026
f894fc9
fix: correct line endings in module description for consistency
VishalS-Microsoft May 19, 2026
832628e
fix: update metadata descriptions for consistency and formatting
VishalS-Microsoft May 19, 2026
3a42ec9
fix: update log analytics destination name variable for consistency
VishalS-Microsoft May 20, 2026
7b62e6c
fix: reorder dependencies in main.json for correct deployment sequence
VishalS-Microsoft May 20, 2026
064ae55
fix: Downmerge from main to dev-v4
Avijit-Microsoft May 21, 2026
107a4e8
Merge pull request #992 from microsoft/psl-workflowchanges
Roopan-Microsoft May 21, 2026
ca1b67d
Merge pull request #993 from microsoft/psl-dependabot-may2026
Roopan-Microsoft May 21, 2026
a346194
Merge pull request #989 from microsoft/psl-fixexpsfiissues-macae
May 21, 2026
5a5a550
resolve copilot comments
Ayaz-Microsoft May 25, 2026
238db79
fix: update timestamp retrieval to use asyncio event loop
Ayaz-Microsoft May 25, 2026
9f7a2fc
Merge pull request #1005 from microsoft/copilot-comments
Roopan-Microsoft May 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/LocalDevelopmentSetup.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,8 @@ az cosmosdb sql role assignment create --resource-group <solution-accelerator-rg
**Assign the required roles:**

```bash
# Azure AI User role
az role assignment create --assignee <aad-user-upn> --role "Azure AI User" --scope /subscriptions/<subscription-id>/resourceGroups/<solution-accelerator-rg>/providers/Microsoft.CognitiveServices/accounts/<foundry-account-name>/projects/<foundry-project-name>
# Foundry User role
az role assignment create --assignee <aad-user-upn> --role "Foundry User" --scope /subscriptions/<subscription-id>/resourceGroups/<solution-accelerator-rg>/providers/Microsoft.CognitiveServices/accounts/<foundry-account-name>/projects/<foundry-project-name>
```

```bash
Expand Down
4 changes: 2 additions & 2 deletions docs/re-use-foundry-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ Replace `<Existing Foundry Project Resource ID>` with the value obtained from St
Proceed with the next steps in the [deployment guide](DeploymentGuide.md#deployment-steps).

> **Note:**
> After deployment, if you want to access agents created by the accelerator via the Azure AI Foundry Portal, or if you plan to debug or run the application locally, you must assign yourself either the **Azure AI User** or **Azure AI Developer** role for the Foundry resource.
> After deployment, if you want to access agents created by the accelerator via the Azure AI Foundry Portal, or if you plan to debug or run the application locally, you must assign yourself either the **Foundry User** or **Azure AI Developer** role for the Foundry resource.
> You can do this in the Azure Portal under the Foundry resource's "Access control (IAM)" section,
> **or** run the following command in your terminal (replace `<aad-user-upn>` with your Azure AD user principal name and `<resource-id>` with the Resource ID you copied in Step 5):
> ```bash
> az role assignment create --assignee <aad-user-upn> --role "Azure AI User" --scope <resource-id>
> az role assignment create --assignee <aad-user-upn> --role "Foundry User" --scope <resource-id>
> ```
6 changes: 3 additions & 3 deletions infra/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,7 @@ module existingAiFoundryAiServicesDeployments 'modules/ai-services-deployments.b
]
roleAssignments: [
{
roleDefinitionIdOrName: '53ca6127-db72-4b80-b1b0-d745d6d5456d' // Azure AI User
roleDefinitionIdOrName: '53ca6127-db72-4b80-b1b0-d745d6d5456d' // Foundry User
principalId: userAssignedIdentity.outputs.principalId
principalType: 'ServicePrincipal'
}
Expand Down Expand Up @@ -935,7 +935,7 @@ module aiFoundryAiServices 'br:mcr.microsoft.com/bicep/avm/res/cognitive-service
managedIdentities: { userAssignedResourceIds: [userAssignedIdentity!.outputs.resourceId] } //To create accounts or projects, you must enable a managed identity on your resource
roleAssignments: [
{
roleDefinitionIdOrName: '53ca6127-db72-4b80-b1b0-d745d6d5456d' // Azure AI User
roleDefinitionIdOrName: '53ca6127-db72-4b80-b1b0-d745d6d5456d' // Foundry User
principalId: userAssignedIdentity.outputs.principalId
principalType: 'ServicePrincipal'
}
Expand All @@ -950,7 +950,7 @@ module aiFoundryAiServices 'br:mcr.microsoft.com/bicep/avm/res/cognitive-service
principalType: 'ServicePrincipal'
}
{
roleDefinitionIdOrName: '53ca6127-db72-4b80-b1b0-d745d6d5456d' // Azure AI User
roleDefinitionIdOrName: '53ca6127-db72-4b80-b1b0-d745d6d5456d' // Foundry User
principalId: deployingUserPrincipalId
principalType: deployerPrincipalType
}
Expand Down
30 changes: 15 additions & 15 deletions infra/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.42.1.51946",
"templateHash": "8490920419623942773"
"version": "0.43.8.12551",
"templateHash": "12475542446442392463"
},
"name": "Multi-Agent Custom Automation Engine",
"description": "This module contains the resources required to deploy the [Multi-Agent Custom Automation Engine solution accelerator](https://github.com/microsoft/Multi-Agent-Custom-Automation-Engine-Solution-Accelerator) for both Sandbox environments and WAF aligned environments.\r\n\r\n> **Note:** This module is not intended for broad, generic use, as it was designed by the Commercial Solution Areas CTO team, as a Microsoft Solution Accelerator. Feature requests and bug fix requests are welcome if they support the needs of this organization but may not be incorporated if they aim to make this module more generic than what it needs to be for its primary use case. This module will likely be updated to leverage AVM resource modules in the future. This may result in breaking changes in upcoming versions when these features are implemented.\r\n"
"description": "This module contains the resources required to deploy the [Multi-Agent Custom Automation Engine solution accelerator](https://github.com/microsoft/Multi-Agent-Custom-Automation-Engine-Solution-Accelerator) for both Sandbox environments and WAF aligned environments.\n\n> **Note:** This module is not intended for broad, generic use, as it was designed by the Commercial Solution Areas CTO team, as a Microsoft Solution Accelerator. Feature requests and bug fix requests are welcome if they support the needs of this organization but may not be incorporated if they aim to make this module more generic than what it needs to be for its primary use case. This module will likely be updated to leverage AVM resource modules in the future. This may result in breaking changes in upcoming versions when these features are implemented.\n"
},
"parameters": {
"solutionName": {
Expand Down Expand Up @@ -4991,8 +4991,8 @@
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.42.1.51946",
"templateHash": "4286500745908716598"
"version": "0.43.8.12551",
"templateHash": "9540091515555271756"
}
},
"definitions": {
Expand Down Expand Up @@ -24308,8 +24308,8 @@
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.42.1.51946",
"templateHash": "6570260143045999127"
"version": "0.43.8.12551",
"templateHash": "7866379492866507946"
}
},
"definitions": {
Expand Down Expand Up @@ -28012,8 +28012,8 @@
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.42.1.51946",
"templateHash": "14513113443903512301"
"version": "0.43.8.12551",
"templateHash": "2868048678223903575"
}
},
"parameters": {
Expand Down Expand Up @@ -42561,8 +42561,8 @@
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.42.1.51946",
"templateHash": "15053339789155096730"
"version": "0.43.8.12551",
"templateHash": "18345308984648474640"
}
},
"definitions": {
Expand Down Expand Up @@ -43593,8 +43593,8 @@
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.42.1.51946",
"templateHash": "16493651611122310009"
"version": "0.43.8.12551",
"templateHash": "1009721598684973971"
},
"name": "Site App Settings",
"description": "This module deploys a Site App Setting."
Expand Down Expand Up @@ -54840,8 +54840,8 @@
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.42.1.51946",
"templateHash": "4859654437121510695"
"version": "0.43.8.12551",
"templateHash": "9739523049889844356"
}
},
"parameters": {
Expand Down
6 changes: 3 additions & 3 deletions infra/main_custom.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -853,7 +853,7 @@ module existingAiFoundryAiServicesDeployments 'modules/ai-services-deployments.b
]
roleAssignments: [
{
roleDefinitionIdOrName: '53ca6127-db72-4b80-b1b0-d745d6d5456d' // Azure AI User
roleDefinitionIdOrName: '53ca6127-db72-4b80-b1b0-d745d6d5456d' // Foundry User
principalId: userAssignedIdentity.outputs.principalId
principalType: 'ServicePrincipal'
}
Expand Down Expand Up @@ -934,7 +934,7 @@ module aiFoundryAiServices 'br:mcr.microsoft.com/bicep/avm/res/cognitive-service
managedIdentities: { userAssignedResourceIds: [userAssignedIdentity!.outputs.resourceId] } //To create accounts or projects, you must enable a managed identity on your resource
roleAssignments: [
{
roleDefinitionIdOrName: '53ca6127-db72-4b80-b1b0-d745d6d5456d' // Azure AI User
roleDefinitionIdOrName: '53ca6127-db72-4b80-b1b0-d745d6d5456d' // Foundry User
principalId: userAssignedIdentity.outputs.principalId
principalType: 'ServicePrincipal'
}
Expand All @@ -949,7 +949,7 @@ module aiFoundryAiServices 'br:mcr.microsoft.com/bicep/avm/res/cognitive-service
principalType: 'ServicePrincipal'
}
{
roleDefinitionIdOrName: '53ca6127-db72-4b80-b1b0-d745d6d5456d' // Azure AI User
roleDefinitionIdOrName: '53ca6127-db72-4b80-b1b0-d745d6d5456d' // Foundry User
principalId: deployingUserPrincipalId
principalType: deployerPrincipalType
}
Expand Down
14 changes: 7 additions & 7 deletions infra/scripts/assign_azure_ai_user_role.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,25 @@ fi

IFS=',' read -r -a principal_ids_array <<< $principal_ids

echo "Assigning Azure AI User role role to users"
echo "Assigning Foundry User role to users"

echo "Using provided Azure AI resource id: $aif_resource_id"
Comment thread
Ayaz-Microsoft marked this conversation as resolved.
Outdated
Comment thread
Ayaz-Microsoft marked this conversation as resolved.
Outdated

for principal_id in "${principal_ids_array[@]}"; do

# Check if the user has the Azure AI User role
echo "Checking if user - ${principal_id} has the Azure AI User role"
# Check if the user has the Foundry User role
echo "Checking if user - ${principal_id} has the Foundry User role"
role_assignment=$(MSYS_NO_PATHCONV=1 az role assignment list --role 53ca6127-db72-4b80-b1b0-d745d6d5456d --scope $aif_resource_id --assignee $principal_id --query "[].roleDefinitionId" -o tsv)
if [ -z "$role_assignment" ]; then
echo "User - ${principal_id} does not have the Azure AI User role. Assigning the role."
echo "User - ${principal_id} does not have the Foundry User role. Assigning the role."
MSYS_NO_PATHCONV=1 az role assignment create --assignee $principal_id --role 53ca6127-db72-4b80-b1b0-d745d6d5456d --scope $aif_resource_id --output none
if [ $? -eq 0 ]; then
echo "Azure AI User role assigned successfully."
echo "Foundry User role assigned successfully."
else
echo "Failed to assign Azure AI User role."
echo "Failed to assign Foundry User role."
exit 1
fi
else
echo "User - ${principal_id} already has the Azure AI User role."
echo "User - ${principal_id} already has the Foundry User role."
fi
done
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,13 @@ const renderAgentMessages = (
<Body1 className={styles.agentName}>
{getAgentDisplayName(msg.agent)}
</Body1>
<Tag
appearance="brand"
>
AI Agent
</Tag>
{msg.agent_type !== AgentMessageType.SYSTEM_AGENT && msg.agent?.toLowerCase() !== 'system' && (
<Tag
appearance="brand"
>
AI Agent
</Tag>
)}
</div>
)}

Expand Down
47 changes: 34 additions & 13 deletions src/App/src/hooks/usePlanWebSocket.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
selectPlanApproved,
approvalRequestReceived,
planCompletedFinal,
planFailedFinal,
} from '@/store/slices/planSlice';
import {
setSubmittingChatDisableInput,
Expand Down Expand Up @@ -178,16 +179,18 @@ export function usePlanWebSocket({
WebsocketMessageType.FINAL_RESULT_MESSAGE,
(finalMessage: any) => {
if (!finalMessage) return;
const agentMessageData: AgentMessageData = {
agent: AgentType.GROUP_CHAT_MANAGER,
agent_type: AgentMessageType.AI_AGENT,
timestamp: Date.now(),
steps: [],
next_steps: [],
content: '\u{1F389}\u{1F389} ' + (finalMessage.data?.content || ''),
raw_data: finalMessage,
};
if (finalMessage?.data?.status === PlanStatus.COMPLETED) {
const messageStatus = finalMessage?.data?.status;

if (messageStatus === PlanStatus.COMPLETED) {
const agentMessageData: AgentMessageData = {
agent: AgentType.GROUP_CHAT_MANAGER,
agent_type: AgentMessageType.AI_AGENT,
timestamp: Date.now(),
steps: [],
next_steps: [],
content: '\u{1F389}\u{1F389} ' + (finalMessage.data?.content || ''),
raw_data: finalMessage,
};
dispatch(setShowBufferingText(true));
dispatch(addAgentMessage(agentMessageData));
dispatch(setSelectedTeam(planData?.team || null));
Expand All @@ -196,11 +199,29 @@ export function usePlanWebSocket({
scrollToBottom();
webSocketService.disconnect();
persistAgentMessage(agentMessageData, planData, dispatch, true, streamingMessageBuffer);
} else if (messageStatus === 'error') {
// Safety net: handle error status sent as FINAL_RESULT_MESSAGE
const errorContent = finalMessage.data?.content || 'An unexpected error occurred. Please try again later.';
const errorAgent: AgentMessageData = {
agent: 'system',
agent_type: AgentMessageType.SYSTEM_AGENT,
timestamp: Date.now(),
steps: [],
next_steps: [],
content: formatErrorMessage(errorContent),
raw_data: finalMessage || '',
Comment thread
NirajC-Microsoft marked this conversation as resolved.
Dismissed
};
dispatch(addAgentMessage(errorAgent));
dispatch(planFailedFinal());
dispatch(setShowBufferingText(false));
scrollToBottom();
showToast(errorContent, 'error');
webSocketService.disconnect();
}
Comment thread
Ayaz-Microsoft marked this conversation as resolved.
},
);
return unsub;
}, [dispatch, scrollToBottom, planData, streamingMessageBuffer]);
}, [dispatch, scrollToBottom, planData, streamingMessageBuffer, formatErrorMessage, showToast]);

// ── ERROR_MESSAGE ─────────────────────────────────────────────
useEffect(() => {
Expand Down Expand Up @@ -231,11 +252,11 @@ export function usePlanWebSocket({
raw_data: errorMessage || '',
};
dispatch(addAgentMessage(errorAgent));
dispatch(setShowProcessingPlanSpinner(false));
dispatch(planFailedFinal());
dispatch(setShowBufferingText(false));
dispatch(setSubmittingChatDisableInput(false));
scrollToBottom();
showToast(errorContent, 'error');
webSocketService.disconnect();
},
);
return unsub;
Expand Down
9 changes: 9 additions & 0 deletions src/App/src/store/slices/planSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,14 @@ const planSlice = createSlice({
}
},

/** Single dispatch when an error occurs during plan execution */
planFailedFinal(state) {
state.showProcessingPlanSpinner = false;
if (state.planData?.plan) {
(state.planData as any).plan.overall_status = PlanStatus.FAILED;
}
},

/** Reset everything back to initial state (used when navigating to a new plan) */
resetPlan() {
return { ...initialState };
Expand Down Expand Up @@ -229,6 +237,7 @@ export const {
planApprovalRejected,
approvalRequestReceived,
planCompletedFinal,
planFailedFinal,
resetPlan,
} = planSlice.actions;

Expand Down
15 changes: 14 additions & 1 deletion src/backend/v4/api/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,20 @@ async def process_request(
try:

async def run_orchestration_task():
await OrchestrationManager().run_orchestration(user_id, input_task)
try:
await OrchestrationManager().run_orchestration(user_id, input_task, plan_id=plan_id)
except Exception as orch_error:
logger.error("Background orchestration failed for plan '%s': %s", plan_id, orch_error)
track_event_if_configured(
"Error_Orchestration_Failed",
{
"plan_id": plan_id,
"session_id": input_task.session_id,
"user_id": user_id,
"error": str(orch_error),
"error_type": type(orch_error).__name__,
},
)

background_tasks.add_task(run_orchestration_task)

Expand Down
Loading
Loading