diff --git a/README.md b/README.md index 391a806ca..b677a1b55 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,9 @@ The Multi-Agent Custom Automation Engine solution accelerator allows users to sp
+**Note:** With any AI solutions you create using these templates, you are responsible for assessing all associated risks and for complying with all applicable laws and safety standards. Learn more in the transparency documents for [Agent Service](https://learn.microsoft.com/en-us/azure/ai-foundry/responsible-ai/agents/transparency-note) and [Agent Framework](https://github.com/microsoft/agent-framework/blob/main/TRANSPARENCY_FAQ.md). +
+

Solution overview

@@ -29,16 +32,11 @@ The solution leverages Azure OpenAI Service, Azure Container Apps, Azure Cosmos |![image](./docs/images/readme/agent_flow.png)| |---| -### How to customize -If you'd like to customize the solution accelerator, here are some common areas to start: - -[Custom scenario](./docs/CustomizeSolution.md) -
### Additional resources -[Semantic Kernel Documentation](https://learn.microsoft.com/en-us/semantic-kernel/) +[Agent Framework Documentation](https://learn.microsoft.com/en-us/agent-framework//) [Azure AI Foundry Documentation](https://learn.microsoft.com/en-us/azure/ai-foundry/) @@ -74,14 +72,18 @@ Follow the quick deploy steps on the deployment guide to deploy this solution to > **Note:** This solution accelerator requires **Azure Developer CLI (azd) version 1.18.0 or higher**. Please ensure you have the latest version installed before proceeding with deployment. [Download azd here](https://learn.microsoft.com/en-us/azure/developer/azure-developer-cli/install-azd). +> **Note:** If deploying from a **local environment** (Option D in the deployment guide), this solution accelerator requires **Bicep CLI version 0.33.0 or higher** to compile infrastructure templates. [Install Bicep](https://learn.microsoft.com/azure/azure-resource-manager/bicep/install). + [Click here to launch the deployment guide](./docs/DeploymentGuide.md)

-| [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/microsoft/Multi-Agent-Custom-Automation-Engine-Solution-Accelerator) | [![Open in Dev Containers](https://img.shields.io/static/v1?style=for-the-badge&label=Dev%20Containers&message=Open&color=blue&logo=visualstudiocode)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/Multi-Agent-Custom-Automation-Engine-Solution-Accelerator) | -|---|---| +| [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/microsoft/Multi-Agent-Custom-Automation-Engine-Solution-Accelerator) | [![Open in Dev Containers](https://img.shields.io/static/v1?style=for-the-badge&label=Dev%20Containers&message=Open&color=blue&logo=visualstudiocode)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/Multi-Agent-Custom-Automation-Engine-Solution-Accelerator) | [![Open in Visual Studio Code Web](https://img.shields.io/static/v1?style=for-the-badge&label=Visual%20Studio%20Code%20(Web)&message=Open&color=blue&logo=visualstudiocode&logoColor=white)](https://vscode.dev/azure/?vscode-azure-exp=foundry&agentPayload=eyJiYXNlVXJsIjogImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9taWNyb3NvZnQvTXVsdGktQWdlbnQtQ3VzdG9tLUF1dG9tYXRpb24tRW5naW5lLVNvbHV0aW9uLUFjY2VsZXJhdG9yL3JlZnMvaGVhZHMvbWFpbi9pbmZyYS92c2NvZGVfd2ViIiwgImluZGV4VXJsIjogIi9pbmRleC5qc29uIiwgInZhcmlhYmxlcyI6IHsiYWdlbnRJZCI6ICIiLCAiY29ubmVjdGlvblN0cmluZyI6ICIiLCAidGhyZWFkSWQiOiAiIiwgInVzZXJNZXNzYWdlIjogIiIsICJwbGF5Z3JvdW5kTmFtZSI6ICIiLCAibG9jYXRpb24iOiAiIiwgInN1YnNjcmlwdGlvbklkIjogIiIsICJyZXNvdXJjZUlkIjogIiIsICJwcm9qZWN0UmVzb3VyY2VJZCI6ICIiLCAiZW5kcG9pbnQiOiAiIn0sICJjb2RlUm91dGUiOiBbImFpLXByb2plY3RzLXNkayIsICJweXRob24iLCAiZGVmYXVsdC1henVyZS1hdXRoIiwgImVuZHBvaW50Il19) | +|---|---|---|
+> **Note**: Some tenants may have additional security restrictions that run periodically and could impact the application (e.g., blocking public network access). If you experience issues or the application stops working, check if these restrictions are the cause. In such cases, consider deploying the WAF-supported version to ensure compliance. To configure, [Click here](./docs/DeploymentGuide.md#31-choose-deployment-type-optional). + > ⚠️ **Important: Check Azure OpenAI Quota Availability**
To ensure sufficient quota is available in your subscription, please follow [quota check instructions guide](./docs/quota_check.md) before you deploy the solution. @@ -91,16 +93,17 @@ Follow the quick deploy steps on the deployment guide to deploy this solution to To deploy this solution accelerator, ensure you have access to an [Azure subscription](https://azure.microsoft.com/free/) with the necessary permissions to create **resource groups and resources**. Follow the steps in [Azure Account Set Up](./docs/AzureAccountSetUp.md). -Check the [Azure Products by Region](https://azure.microsoft.com/en-us/explore/global-infrastructure/products-by-region/table) page and select a **region** where the following services are available: Azure OpenAI Service, Azure AI Search, and Azure Semantic Search. +Check the [Azure Products by Region](https://azure.microsoft.com/en-us/explore/global-infrastructure/products-by-region/table) page and select a **region** where the following services are available: Microsoft Foundry Service, Foundry Models, Azure AI Search, and Search Semantic Ranker. -Here are some example regions where the services are available: East US, East US2, Japan East, UK South, Sweden Central. +Here are some example regions where the services are available: Australia East, East US2, France Central, Japan East, Norway East, Sweden Central, UK South, West US. Pricing varies per region and usage, so it isn't possible to predict exact costs for your usage. The majority of the Azure resources used in this infrastructure are on usage-based pricing tiers. However, Azure Container Registry has a fixed cost per registry per day. Use the [Azure pricing calculator](https://azure.microsoft.com/en-us/pricing/calculator) to calculate the cost of this solution in your subscription. [Review a sample pricing sheet for the architecture](https://azure.com/e/86d0eefbe4dd4a23981c1d3d4f6fe7ed). | Product | Description | Cost | |---|---|---| -| [Azure OpenAI Service](https://learn.microsoft.com/azure/ai-services/openai/) | Powers the AI agents for task automation | [Pricing](https://azure.microsoft.com/pricing/details/cognitive-services/openai-service/) | +| [Microsoft Foundry]( https://learn.microsoft.com/en-us/azure/foundry/) | Powers the AI agents for task automation | [Pricing](https://azure.microsoft.com/en-us/pricing/details/microsoft-foundry/) | +| [Azure AI Search](https://learn.microsoft.com/en-us/azure/search/) | Powers vector based data search | [Pricing]( https://azure.microsoft.com/en-us/pricing/details/search/) | | [Azure Container Apps](https://learn.microsoft.com/azure/container-apps/) | Hosts the web application frontend | [Pricing](https://azure.microsoft.com/pricing/details/container-apps/) | | [Azure Cosmos DB](https://learn.microsoft.com/azure/cosmos-db/) | Stores metadata and processing results | [Pricing](https://azure.microsoft.com/pricing/details/cosmos-db/) | | [Azure Container Registry](https://learn.microsoft.com/azure/container-registry/) | Stores container images for deployment | [Pricing](https://azure.microsoft.com/pricing/details/container-registry/) | @@ -150,6 +153,21 @@ By using the *Multi-Agent Custom Automation Engine* solution accelerator, users +### Use Case +
+ Click to learn more about what use cases this solution provides + +| Use Case | Persona | Challenges | Summary/Approach | +|----------|-----------|------------|------------------| +| Product Marketing | Marketing Executive | Marketing release plans require input from multiple teams (engineering, design, compliance), which often leads to delays and misalignment. Traditional planning involves repetitive tasks like drafting timelines, assigning owners, and validating compliance, which are prone to mistakes. | Through an agentic approach the Multi-agent speeds up release planning by automating repetitive tasks and enhances collaboration with dynamic agent teams that adapt to campaign needs. | +| Onboarding Employee | HR Manager | Traditional onboarding involves multiple disconnected steps—HR paperwork, IT setup, compliance training—which often require manual coordination and lead to delays. Manual steps slow collaboration and increase overhead, reducing efficiency and employee experience. | Designed to streamline the complex process of bringing new hires into an organization using a modular, agentic architecture. | +| Retail Remediation | Customer Success Manager | This approach is seeking a smarter way to manage workflows and ensure customer satisfaction. Challenges include difficulty engaging the right agents, inefficiencies from manual processes, fragmented data, and limited security controls. | Using the Multi-Agent Custom Automation Engine, the Customer Success Manager recruits intelligent agents to analyze satisfaction and recommend steps for remediation. The platform’s modular design and reasoning capabilities allow for analyzing dependencies, planning transitions, and reducing manual rework. | +| RFP Reviewer | VP of Finance | Reviewing RFPs manually under tight deadlines is challenging. Compliance checks and risk assessments slow progress, leaving critical gaps and delaying decisions. | Multi-Agent RFP Reviewer is an intelligent platform addresses these issues by deploying AI agents to review RFPs, identify risks, recommend remediation, and execute actions seamlessly - transforming a labor-intensive process into a fast, accurate, and compliant workflow. | +| Contract Compliance Reviewer | Compliance Counsel | Reviewing Contracts for compliance manually under tight deadlines is challenging. Compliance checks and risk assessments slow progress, leaving critical gaps and delaying decisions. | Multi-Agent Contract Compliance Reviewer is an intelligent platform addresses these issues by deploying AI agents to review Contracts, identify risks, recommend remediation, and execute actions seamlessly - transforming a labor-intensive process into a fast, accurate, and compliant workflow. | +| Content Generation | Marketing Creative | Accelerate your marketing content creation by leveraging AI to interpret creative briefs and generate on-brand, multimodal content. The solution helps marketing teams reduce time-to-market for campaigns by automating the creation of compliant marketing copy and images grounded in product data. | This solution leverages a team of agents to interpret creative briefs, retrieve product information, generate marketing content, and validate brand compliance. | + +
+

@@ -162,7 +180,7 @@ This template uses Azure Key Vault to store all connections to communicate betwe This template also uses [Managed Identity](https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/overview) for local development and deployment. -To ensure continued best practices in your own repository, we recommend that anyone creating solutions based on our templates ensure that the [Github secret scanning](https://docs.github.com/code-security/secret-scanning/about-secret-scanning) setting is enabled. +To ensure continued best practices in your own repository, we recommend that anyone creating solutions based on our templates ensure that the [GitHub secret scanning](https://docs.github.com/code-security/secret-scanning/about-secret-scanning) setting is enabled. You may want to consider additional security measures, such as: @@ -182,6 +200,15 @@ Check out similar solution accelerators
+💡 Want to get familiar with Microsoft's AI and Data Engineering best practices? Check out our playbooks to learn more + +| Playbook | Description | +|:---|:---| +| [AI playbook](https://learn.microsoft.com/en-us/ai/playbook/) | The Artificial Intelligence (AI) Playbook provides enterprise software engineers with solutions, capabilities, and code developed to solve real-world AI problems. | +| [Data playbook](https://learn.microsoft.com/en-us/data-engineering/playbook/understanding-data-playbook) | The data playbook provides enterprise software engineers with solutions which contain code developed to solve real-world problems. Everything in the playbook is developed with, and validated by, some of Microsoft's largest and most influential customers and partners. | + +
+ ## Provide feedback Have questions, find a bug, or want to request a feature? [Submit a new issue](https://github.com/microsoft/Multi-Agent-Custom-Automation-Engine-Solution-Accelerator/issues) on this repo and we'll connect. @@ -194,6 +221,17 @@ Please refer to [Transparency FAQ](./docs/TRANSPARENCY_FAQ.md) for responsible A
## Disclaimers +This release is an artificial intelligence (AI) system that generates text based on user input. The text generated by this system may include ungrounded content, meaning that it is not verified by any reliable source or based on any factual data. The data included in this release is synthetic, meaning that it is artificially created by the system and may contain factual errors or inconsistencies. Users of this release are responsible for determining the accuracy, validity, and suitability of any content generated by the system for their intended purposes. Users should not rely on the system output as a source of truth or as a substitute for human judgment or expertise. + +This release only supports English language input and output. Users should not attempt to use the system with any other language or format. The system output may not be compatible with any translation tools or services, and may lose its meaning or coherence if translated. + +This release does not reflect the opinions, views, or values of Microsoft Corporation or any of its affiliates, subsidiaries, or partners. The system output is solely based on the system's own logic and algorithms, and does not represent any endorsement, recommendation, or advice from Microsoft or any other entity. Microsoft disclaims any liability or responsibility for any damages, losses, or harms arising from the use of this release or its output by any user or third party. + +This release does not provide any financial advice, legal advice and is not designed to replace the role of qualified client advisors in appropriately advising clients. Users should not use the system output for any financial decisions, legal guidance or transactions, and should consult with a professional financial advisor and or legal advisor as appropriate before taking any action based on the system output. Microsoft is not a financial institution or a fiduciary, and does not offer any financial products or services through this release or its output. + +This release is intended as a proof of concept only, and is not a finished or polished product. It is not intended for commercial use or distribution, and is subject to change or discontinuation without notice. Any planned deployment of this release or its output should include comprehensive testing and evaluation to ensure it is fit for purpose and meets the user's requirements and expectations. Microsoft does not guarantee the quality, performance, reliability, or availability of this release or its output, and does not provide any warranty or support for it. + +This Software requires the use of third-party components which are governed by separate proprietary or open-source licenses as identified below, and you must comply with the terms of each applicable license in order to use the Software. You acknowledge and agree that this license does not grant you a license or other right to use any such third-party proprietary or open-source components. To the extent that the Software includes components or code used in or derived from Microsoft products or services, including without limitation Microsoft Azure Services (collectively, "Microsoft Products and Services"), you must also comply with the Product Terms applicable to such Microsoft Products and Services. You acknowledge and agree that the license governing the Software does not grant you a license or other right to use Microsoft Products and Services. Nothing in the license or this ReadMe file will serve to supersede, amend, terminate or modify any terms in the Product Terms for any Microsoft Products and Services. @@ -203,4 +241,4 @@ You acknowledge that the Software and Microsoft Products and Services (1) are no You acknowledge the Software is not subject to SOC 1 and SOC 2 compliance audits. No Microsoft technology, nor any of its component technologies, including the Software, is intended or made available as a substitute for the professional advice, opinion, or judgment of a certified financial services professional. Do not use the Software to replace, substitute, or provide professional financial advice or judgment. -BY ACCESSING OR USING THE SOFTWARE, YOU ACKNOWLEDGE THAT THE SOFTWARE IS NOT DESIGNED OR INTENDED TO SUPPORT ANY USE IN WHICH A SERVICE INTERRUPTION, DEFECT, ERROR, OR OTHER FAILURE OF THE SOFTWARE COULD RESULT IN THE DEATH OR SERIOUS BODILY INJURY OF ANY PERSON OR IN PHYSICAL OR ENVIRONMENTAL DAMAGE (COLLECTIVELY, "HIGH-RISK USE"), AND THAT YOU WILL ENSURE THAT, IN THE EVENT OF ANY INTERRUPTION, DEFECT, ERROR, OR OTHER FAILURE OF THE SOFTWARE, THE SAFETY OF PEOPLE, PROPERTY, AND THE ENVIRONMENT ARE NOT REDUCED BELOW A LEVEL THAT IS REASONABLY, APPROPRIATE, AND LEGAL, WHETHER IN GENERAL OR IN A SPECIFIC INDUSTRY. BY ACCESSING THE SOFTWARE, YOU FURTHER ACKNOWLEDGE THAT YOUR HIGH-RISK USE OF THE SOFTWARE IS AT YOUR OWN RISK. +BY ACCESSING OR USING THE SOFTWARE, YOU ACKNOWLEDGE THAT THE SOFTWARE IS NOT DESIGNED OR INTENDED TO SUPPORT ANY USE IN WHICH A SERVICE INTERRUPTION, DEFECT, ERROR, OR OTHER FAILURE OF THE SOFTWARE COULD RESULT IN THE DEATH OR SERIOUS BODILY INJURY OF ANY PERSON OR IN PHYSICAL OR ENVIRONMENTAL DAMAGE (COLLECTIVELY, "HIGH-RISK USE"), AND THAT YOU WILL ENSURE THAT, IN THE EVENT OF ANY INTERRUPTION, DEFECT, ERROR, OR OTHER FAILURE OF THE SOFTWARE, THE SAFETY OF PEOPLE, PROPERTY, AND THE ENVIRONMENT ARE NOT REDUCED BELOW A LEVEL THAT IS REASONABLY, APPROPRIATE, AND LEGAL, WHETHER IN GENERAL OR IN A SPECIFIC INDUSTRY. BY ACCESSING THE SOFTWARE, YOU FURTHER ACKNOWLEDGE THAT YOUR HIGH-RISK USE OF THE SOFTWARE IS AT YOUR OWN RISK. \ No newline at end of file diff --git a/docs/ADR/003-reasoning-model-for-orchestrator-manager.md b/docs/ADR/003-reasoning-model-for-orchestrator-manager.md index 8f04b3fbb..9278bc300 100644 --- a/docs/ADR/003-reasoning-model-for-orchestrator-manager.md +++ b/docs/ADR/003-reasoning-model-for-orchestrator-manager.md @@ -111,4 +111,4 @@ manager_agent = Agent(manager_chat_client, name="MagenticManager") ## Superseded (2026-07-09) -The reasoning/orchestrator model migrated from `o4-mini` to `gpt-5-mini` because `o4-mini` is deprecated (retires 2026-10-16). Because `gpt-5-mini` reasons by default, it preserves the structured-routing reliability that motivated this decision while consolidating the accelerator onto a single generally available model. The `ORCHESTRATOR_MODEL_NAME` config and the separate manager `FoundryChatClient` described above remain unchanged; only the default model value moved to `gpt-5-mini`. The historical decision text above is retained for context. +The reasoning/orchestrator model migrated from `o4-mini` to `gpt-5.4-mini` because `o4-mini` is deprecated (retires 2026-10-16). Because `gpt-5.4-mini` reasons by default, it preserves the structured-routing reliability that motivated this decision while consolidating the accelerator onto a single generally available model. The `ORCHESTRATOR_MODEL_NAME` config and the separate manager `FoundryChatClient` described above remain unchanged; only the default model value moved to `gpt-5.4-mini`. The historical decision text above is retained for context. diff --git a/infra/avm/main.bicep b/infra/avm/main.bicep index 0e7c4f43f..acb6b6150 100644 --- a/infra/avm/main.bicep +++ b/infra/avm/main.bicep @@ -1383,13 +1383,14 @@ module webSite './modules/compute/app-service.bicep' = { appSettings: { SCM_DO_BUILD_DURING_DEPLOYMENT: 'true' DOCKER_REGISTRY_SERVER_URL: 'https://${acrLoginServer}' - WEBSITES_PORT: '3000' WEBSITES_CONTAINER_START_TIME_LIMIT: '1800' BACKEND_API_URL: 'https://${containerApp.outputs.fqdn}' AUTH_ENABLED: 'false' PROXY_API_REQUESTS: enablePrivateNetworking ? 'true' : 'false' } virtualNetworkSubnetId: enablePrivateNetworking ? virtualNetwork!.outputs.webserverfarmSubnetResourceId : '' + vnetRouteAllEnabled: enablePrivateNetworking + imagePullTraffic: enablePrivateNetworking publicNetworkAccess: 'Enabled' diagnosticSettings: monitoringDiagnosticSettings applicationInsightResourceId: enableMonitoring ? app_insights!.outputs.resourceId : '' diff --git a/infra/bicep/main.bicep b/infra/bicep/main.bicep index 47ebeea11..a10eedd7f 100644 --- a/infra/bicep/main.bicep +++ b/infra/bicep/main.bicep @@ -800,8 +800,7 @@ module frontend_app './modules/compute/app-service.bicep' = { appCommandLine: '' appSettings: { SCM_DO_BUILD_DURING_DEPLOYMENT: 'true' - DOCKER_REGISTRY_SERVER_URL: 'https://${acrLoginServer}' - WEBSITES_PORT: '3000' + DOCKER_REGISTRY_SERVER_URL: 'https://${acrLoginServer}' WEBSITES_CONTAINER_START_TIME_LIMIT: '1800' BACKEND_API_URL: 'https://${backend_container_app.outputs.fqdn}' AUTH_ENABLED: 'false' diff --git a/infra/main.waf.parameters.json b/infra/main.waf.parameters.json index 2402ef2a4..832572f12 100644 --- a/infra/main.waf.parameters.json +++ b/infra/main.waf.parameters.json @@ -90,13 +90,13 @@ "value": "${AZURE_ENV_CONTAINER_REGISTRY_ENDPOINT}" }, "backendContainerImageTag": { - "value": "${AZURE_ENV_IMAGE_TAG=latest_v5}" + "value": "${AZURE_ENV_IMAGE_TAG}" }, "frontendContainerImageTag": { - "value": "${AZURE_ENV_IMAGE_TAG=latest_v5}" + "value": "${AZURE_ENV_IMAGE_TAG}" }, "MCPContainerImageTag": { - "value": "${AZURE_ENV_IMAGE_TAG=latest_v5}" + "value": "${AZURE_ENV_IMAGE_TAG}" } } } \ No newline at end of file diff --git a/infra/modules/virtualNetwork.bicep b/infra/modules/virtualNetwork.bicep deleted file mode 100644 index b9b5f11b6..000000000 --- a/infra/modules/virtualNetwork.bicep +++ /dev/null @@ -1,374 +0,0 @@ -/****************************************************************************************************************************/ -// Networking - NSGs, VNET and Subnets. Each subnet has its own NSG -/****************************************************************************************************************************/ -@description('Name of the virtual network.') -param name string - -@description('Azure region to deploy resources.') -param location string = resourceGroup().location - -@description('Required. An Array of 1 or more IP Address Prefixes for the Virtual Network.') -param addressPrefixes array - -@description('An array of subnets to be created within the virtual network. Each subnet can have its own configuration and associated Network Security Group (NSG).') -param subnets subnetType[] = [ - - - { - name:'backend' - addressPrefixes: ['10.0.0.0/27'] - networkSecurityGroup: { - name: 'nsg-backend' - securityRules: [ - { - name: 'deny-hop-outbound' - properties: { - access: 'Deny' - destinationAddressPrefix: '*' - destinationPortRanges: [ - '22' - '3389' - ] - direction: 'Outbound' - priority: 200 - protocol: 'Tcp' - sourceAddressPrefix: 'VirtualNetwork' - sourcePortRange: '*' - } - } - ] - } - } - { - name: 'containers' - addressPrefixes: ['10.0.2.0/23'] - delegation: 'Microsoft.App/environments' - privateEndpointNetworkPolicies: 'Enabled' - privateLinkServiceNetworkPolicies: 'Enabled' - networkSecurityGroup: { - name: 'nsg-containers' - securityRules: [ - { - name: 'deny-hop-outbound' - properties: { - access: 'Deny' - destinationAddressPrefix: '*' - destinationPortRanges: [ - '22' - '3389' - ] - direction: 'Outbound' - priority: 200 - protocol: 'Tcp' - sourceAddressPrefix: 'VirtualNetwork' - sourcePortRange: '*' - } - } - ] - } - } - { - name: 'webserverfarm' - addressPrefixes: ['10.0.4.0/27'] - delegation: 'Microsoft.Web/serverfarms' - privateEndpointNetworkPolicies: 'Enabled' - privateLinkServiceNetworkPolicies: 'Enabled' - networkSecurityGroup: { - name: 'nsg-webserverfarm' - securityRules: [ - { - name: 'deny-hop-outbound' - properties: { - access: 'Deny' - destinationAddressPrefix: '*' - destinationPortRanges: [ - '22' - '3389' - ] - direction: 'Outbound' - priority: 200 - protocol: 'Tcp' - sourceAddressPrefix: 'VirtualNetwork' - sourcePortRange: '*' - } - } - ] - } - } - { - name: 'administration' - addressPrefixes: ['10.0.0.32/27'] - networkSecurityGroup: { - name: 'nsg-administration' - securityRules: [ - { - name: 'deny-hop-outbound' - properties: { - access: 'Deny' - destinationAddressPrefix: '*' - destinationPortRanges: [ - '22' - '3389' - ] - direction: 'Outbound' - priority: 200 - protocol: 'Tcp' - sourceAddressPrefix: 'VirtualNetwork' - sourcePortRange: '*' - } - } - ] - } - } - { - name: 'AzureBastionSubnet' // Required name for Azure Bastion - addressPrefixes: ['10.0.0.64/26'] - networkSecurityGroup: { - name: 'nsg-bastion' - securityRules: [ - { - name: 'AllowGatewayManager' - properties: { - access: 'Allow' - direction: 'Inbound' - priority: 2702 - protocol: '*' - sourcePortRange: '*' - destinationPortRange: '443' - sourceAddressPrefix: 'GatewayManager' - destinationAddressPrefix: '*' - } - } - { - name: 'AllowHttpsInBound' - properties: { - access: 'Allow' - direction: 'Inbound' - priority: 2703 - protocol: '*' - sourcePortRange: '*' - destinationPortRange: '443' - sourceAddressPrefix: 'Internet' - destinationAddressPrefix: '*' - } - } - { - name: 'AllowSshRdpOutbound' - properties: { - access: 'Allow' - direction: 'Outbound' - priority: 100 - protocol: '*' - sourcePortRange: '*' - destinationPortRanges: ['22', '3389'] - sourceAddressPrefix: '*' - destinationAddressPrefix: 'VirtualNetwork' - } - } - { - name: 'AllowAzureCloudOutbound' - properties: { - access: 'Allow' - direction: 'Outbound' - priority: 110 - protocol: 'Tcp' - sourcePortRange: '*' - destinationPortRange: '443' - sourceAddressPrefix: '*' - destinationAddressPrefix: 'AzureCloud' - } - } - ] - } - } -] - -@description('Optional. Tags to be applied to the resources.') -param tags object = {} - -@description('Optional. The resource ID of the Log Analytics Workspace to send diagnostic logs to.') -param logAnalyticsWorkspaceId string - -@description('Optional. Enable/Disable usage telemetry for module.') -param enableTelemetry bool = true - -@description('Required. Suffix for resource naming.') -param resourceSuffix string - -// VM Size Notes: -// 1 B-series VMs (like Standard_B2ms) do not support accelerated networking. -// 2 Pick a VM size that does support accelerated networking (the usual jump-box candidates): -// Standard_DS2_v2 (2 vCPU, 7 GiB RAM, Premium SSD) // The most broadly available (it’s a legacy SKU supported in virtually every region). -// Standard_D2s_v3 (2 vCPU, 8 GiB RAM, Premium SSD) // next most common -// Standard_D2s_v4 (2 vCPU, 8 GiB RAM, Premium SSD) // Newest, so fewer regions availabl - - -// Subnet Classless Inter-Doman Routing (CIDR) Sizing Reference Table (Best Practices) -// | CIDR | # of Addresses | # of /24s | Notes | -// |-----------|---------------|-----------|----------------------------------------| -// | /24 | 256 | 1 | Smallest recommended for Azure subnets | -// | /23 | 512 | 2 | Good for 1-2 workloads per subnet | -// | /22 | 1024 | 4 | Good for 2-4 workloads per subnet | -// | /21 | 2048 | 8 | | -// | /20 | 4096 | 16 | Used for default VNet in this solution | -// | /19 | 8192 | 32 | | -// | /18 | 16384 | 64 | | -// | /17 | 32768 | 128 | | -// | /16 | 65536 | 256 | | -// | /15 | 131072 | 512 | | -// | /14 | 262144 | 1024 | | -// | /13 | 524288 | 2048 | | -// | /12 | 1048576 | 4096 | | -// | /11 | 2097152 | 8192 | | -// | /10 | 4194304 | 16384 | | -// | /9 | 8388608 | 32768 | | -// | /8 | 16777216 | 65536 | | -// -// Best Practice Notes: -// - Use /24 as the minimum subnet size for Azure (smaller subnets are not supported for most services). -// - Plan for future growth: allocate larger address spaces (e.g., /20 or /21 for VNets) to allow for new subnets. -// - Avoid overlapping address spaces with on-premises or other VNets. -// - Use contiguous, non-overlapping ranges for subnets. -// - Document subnet usage and purpose in code comments. -// - For AVM modules, ensure only one delegation per subnet and leave delegations empty if not required. - -// 1. Create NSGs for subnets -// using AVM Network Security Group module -// https://github.com/Azure/bicep-registry-modules/tree/main/avm/res/network/network-security-group - -@batchSize(1) -module nsgs 'br/public:avm/res/network/network-security-group:0.5.1' = [ - for (subnet, i) in subnets: if (!empty(subnet.?networkSecurityGroup)) { - name: take('avm.res.network.network-security-group.${subnet.?networkSecurityGroup.name}.${resourceSuffix}', 64) - params: { - name: '${subnet.?networkSecurityGroup.name}-${resourceSuffix}' - location: location - securityRules: subnet.?networkSecurityGroup.securityRules - tags: tags - enableTelemetry: enableTelemetry - } - } -] - -// 2. Create VNet and subnets, with subnets associated with corresponding NSGs -// using AVM Virtual Network module -// https://github.com/Azure/bicep-registry-modules/tree/main/avm/res/network/virtual-network - -module virtualNetwork 'br/public:avm/res/network/virtual-network:0.7.0' = { - name: take('avm.res.network.virtual-network.${name}', 64) - params: { - name: name - location: location - addressPrefixes: addressPrefixes - subnets: [ - for (subnet, i) in subnets: { - name: subnet.name - addressPrefixes: subnet.?addressPrefixes - networkSecurityGroupResourceId: !empty(subnet.?networkSecurityGroup) ? nsgs[i]!.outputs.resourceId : null - privateEndpointNetworkPolicies: subnet.?privateEndpointNetworkPolicies - privateLinkServiceNetworkPolicies: subnet.?privateLinkServiceNetworkPolicies - delegation: subnet.?delegation - } - ] - diagnosticSettings: [ - { - name: 'vnetDiagnostics' - workspaceResourceId: logAnalyticsWorkspaceId - logCategoriesAndGroups: [ - { - categoryGroup: 'allLogs' - enabled: true - } - ] - metricCategories: [ - { - category: 'AllMetrics' - enabled: true - } - ] - } - ] - tags: tags - enableTelemetry: enableTelemetry - } -} - -output name string = virtualNetwork.outputs.name -output resourceId string = virtualNetwork.outputs.resourceId - -// combined output array that holds subnet details along with NSG information -output subnets subnetOutputType[] = [ - for (subnet, i) in subnets: { - name: subnet.name - resourceId: virtualNetwork.outputs.subnetResourceIds[i] - nsgName: !empty(subnet.?networkSecurityGroup) ? subnet.?networkSecurityGroup.name : null - nsgResourceId: !empty(subnet.?networkSecurityGroup) ? nsgs[i]!.outputs.resourceId : null - } -] - -// Dynamic outputs for individual subnets for backward compatibility -output backendSubnetResourceId string = contains(map(subnets, subnet => subnet.name), 'backend') ? virtualNetwork.outputs.subnetResourceIds[indexOf(map(subnets, subnet => subnet.name), 'backend')] : '' -output containerSubnetResourceId string = contains(map(subnets, subnet => subnet.name), 'containers') ? virtualNetwork.outputs.subnetResourceIds[indexOf(map(subnets, subnet => subnet.name), 'containers')] : '' -output administrationSubnetResourceId string = contains(map(subnets, subnet => subnet.name), 'administration') ? virtualNetwork.outputs.subnetResourceIds[indexOf(map(subnets, subnet => subnet.name), 'administration')] : '' -output webserverfarmSubnetResourceId string = contains(map(subnets, subnet => subnet.name), 'webserverfarm') ? virtualNetwork.outputs.subnetResourceIds[indexOf(map(subnets, subnet => subnet.name), 'webserverfarm')] : '' -output bastionSubnetResourceId string = contains(map(subnets, subnet => subnet.name), 'AzureBastionSubnet') ? virtualNetwork.outputs.subnetResourceIds[indexOf(map(subnets, subnet => subnet.name), 'AzureBastionSubnet')] : '' - -@export() -@description('Custom type definition for subnet resource information as output') -type subnetOutputType = { - @description('The name of the subnet.') - name: string - - @description('The resource ID of the subnet.') - resourceId: string - - @description('The name of the associated network security group, if any.') - nsgName: string? - - @description('The resource ID of the associated network security group, if any.') - nsgResourceId: string? -} - -@export() -@description('Custom type definition for subnet configuration') -type subnetType = { - @description('Required. The Name of the subnet resource.') - name: string - - @description('Required. Prefixes for the subnet.') // Required to ensure at least one prefix is provided - addressPrefixes: string[] - - @description('Optional. The delegation to enable on the subnet.') - delegation: string? - - @description('Optional. enable or disable apply network policies on private endpoint in the subnet.') - privateEndpointNetworkPolicies: ('Disabled' | 'Enabled' | 'NetworkSecurityGroupEnabled' | 'RouteTableEnabled')? - - @description('Optional. Enable or disable apply network policies on private link service in the subnet.') - privateLinkServiceNetworkPolicies: ('Disabled' | 'Enabled')? - - @description('Optional. Network Security Group configuration for the subnet.') - networkSecurityGroup: networkSecurityGroupType? - - @description('Optional. The resource ID of the route table to assign to the subnet.') - routeTableResourceId: string? - - @description('Optional. An array of service endpoint policies.') - serviceEndpointPolicies: object[]? - - @description('Optional. The service endpoints to enable on the subnet.') - serviceEndpoints: string[]? - - @description('Optional. Set this property to false to disable default outbound connectivity for all VMs in the subnet. This property can only be set at the time of subnet creation and cannot be updated for an existing subnet.') - defaultOutboundAccess: bool? -} - -@export() -@description('Custom type definition for network security group configuration') -type networkSecurityGroupType = { - @description('Required. The name of the network security group.') - name: string - - @description('Required. The security rules for the network security group.') - securityRules: object[] -} diff --git a/infra/scripts/post-provision/Build-And-Push-Images.ps1 b/infra/scripts/post-provision/Build-And-Push-Images.ps1 index 33ae153b4..d6d57dcba 100644 --- a/infra/scripts/post-provision/Build-And-Push-Images.ps1 +++ b/infra/scripts/post-provision/Build-And-Push-Images.ps1 @@ -243,9 +243,6 @@ Write-Host "Ensuring WEBSITES_PORT=$frontendPort on Web App" --output none if ($LASTEXITCODE -ne 0) { throw "Failed to update app settings on Web App '$frontendApp'." } -Write-Host "Restarting Web App '$frontendApp'" -& az webapp restart --name $frontendApp --resource-group $resourceGroup --output none -if ($LASTEXITCODE -ne 0) { throw "Failed to restart Web App '$frontendApp'." } Write-Section 'Image build & push complete' Write-Host "All images built, pushed to '$acrEndpoint' with tag '$ImageTag', and services updated." -ForegroundColor Green @@ -254,7 +251,7 @@ Write-Section 'Next step: Upload Team Configurations and index sample data' Write-Host "Run the following command from the project root to upload the team" -ForegroundColor White Write-Host "configurations and index the sample data:" -ForegroundColor White Write-Host "" -Write-Host " .\infra\scripts\post-provision\Selecting-Team-Config-And-Data.ps1" -ForegroundColor Cyan +Write-Host " .\infra\scripts\post-provision\post_deploy.ps1" -ForegroundColor Cyan Write-Host "" } finally { diff --git a/infra/scripts/post-provision/build_and_push_images.sh b/infra/scripts/post-provision/build_and_push_images.sh index 62c585ab7..6546ae92a 100644 --- a/infra/scripts/post-provision/build_and_push_images.sh +++ b/infra/scripts/post-provision/build_and_push_images.sh @@ -184,9 +184,6 @@ az webapp config appsettings set \ --settings "WEBSITES_PORT=${FRONTEND_PORT}" "DOCKER_REGISTRY_SERVER_URL=https://${ACR_ENDPOINT}" \ --output none -echo "Restarting Web App '${FRONTEND_APP}'" -az webapp restart --name "${FRONTEND_APP}" --resource-group "${RESOURCE_GROUP}" --output none - section "Image build & push complete" echo "All images built, pushed to '${ACR_ENDPOINT}' with tag '${IMAGE_TAG}', and services updated." @@ -194,5 +191,5 @@ section "Next step: Upload Team Configurations and index sample data" echo "Run the following command from the project root to upload the team" echo "configurations and index the sample data:" echo "" -echo " bash infra/scripts/post-provision/selecting_team_config_and_data.sh" +echo " bash infra/scripts/post-provision/post_deploy.sh" echo "" \ No newline at end of file diff --git a/src/backend/services/team_service.py b/src/backend/services/team_service.py index 852dc9451..6d118c8cf 100644 --- a/src/backend/services/team_service.py +++ b/src/backend/services/team_service.py @@ -329,10 +329,6 @@ def extract_models_from_text(self, text: str) -> set: model_patterns = [ r"gpt-5\.\d+(?:-\w+)?", r"gpt-5(?:-\w+)?", - r"gpt-4o(?:-\w+)?", - r"gpt-4(?:-\w+)?", - r"gpt-35-turbo(?:-\w+)?", - r"gpt-3\.5-turbo(?:-\w+)?", r"claude-3(?:-\w+)?", r"claude-2(?:-\w+)?", r"gemini-pro(?:-\w+)?",