Skip to content

Commit ca0d38f

Browse files
ajitpadhiVamshi-MicrosoftAjitPadhi1-Microsoft
authored
feat: Developed scripts and Implement ACR deployment (#2298)
Co-authored-by: Vamshi-Microsoft <v-vamolla@microsoft.com> Co-authored-by: Ajit Padhi <v-ajpadhi@microsoft.com>
1 parent c65a1ca commit ca0d38f

19 files changed

Lines changed: 4477 additions & 451 deletions

File tree

azure.yaml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,13 @@ hooks:
2828
Write-Host "1. Login to Azure CLI (required for post-deployment script):" -ForegroundColor Yellow
2929
Write-Host " az login" -ForegroundColor Cyan
3030
Write-Host ""
31-
Write-Host "2. Run the post-deployment setup script:" -ForegroundColor Yellow
31+
Write-Host "2. If you deployed with container hosting, run the combined ACR build/push/update script:" -ForegroundColor Yellow
32+
Write-Host " ./scripts/acr_build_push_update.ps1 -ResourceGroupName `"$env:AZURE_RESOURCE_GROUP`"" -ForegroundColor Cyan
33+
Write-Host ""
34+
Write-Host " Or using Bash:" -ForegroundColor Yellow
35+
Write-Host " bash scripts/acr_build_push_update.sh `"$env:AZURE_RESOURCE_GROUP`"" -ForegroundColor Cyan
36+
Write-Host ""
37+
Write-Host "3. Run the post-deployment setup script:" -ForegroundColor Yellow
3238
Write-Host " ./scripts/post_deployment_setup.ps1 -ResourceGroupName `"$env:AZURE_RESOURCE_GROUP`"" -ForegroundColor Cyan
3339
Write-Host ""
3440
Write-Host " Or using Bash:" -ForegroundColor Yellow
@@ -47,7 +53,10 @@ hooks:
4753
echo "1. Login to Azure CLI (required for post-deployment script):"
4854
echo " az login"
4955
echo ""
50-
echo "2. Run the post-deployment setup script:"
56+
echo "2. If you deployed with container hosting, run the combined ACR build/push/update script:"
57+
echo " bash scripts/acr_build_push_update.sh \"$AZURE_RESOURCE_GROUP\""
58+
echo ""
59+
echo "3. Run the post-deployment setup script:"
5160
echo " bash scripts/post_deployment_setup.sh \"$AZURE_RESOURCE_GROUP\""
5261
echo ""
5362
continueOnError: false

code/backend/api/chat_history.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
)
1010
from backend.batch.utilities.helpers.config.config_helper import ConfigHelper
1111
from backend.batch.utilities.helpers.env_helper import EnvHelper
12+
from backend.batch.utilities.helpers.openai_utils import build_completion_kwargs
1213
from backend.batch.utilities.chat_history.database_factory import DatabaseFactory
1314
from backend.batch.utilities.loggers.event_utils import track_event_if_configured
1415

@@ -516,7 +517,7 @@ async def generate_title(conversation_messages):
516517
model=env_helper.AZURE_OPENAI_MODEL,
517518
messages=messages,
518519
temperature=1,
519-
max_tokens=64,
520+
**build_completion_kwargs(env_helper.AZURE_OPENAI_MODEL, 64),
520521
)
521522

522523
# Ensure response contains valid choices and content

code/backend/batch/utilities/helpers/llm_helper.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from azure.ai.ml import MLClient
1111
from .azure_credential_utils import get_azure_credential
1212
from .env_helper import EnvHelper
13+
from .openai_utils import build_completion_kwargs
1314

1415
logger = logging.getLogger(__name__)
1516

@@ -45,27 +46,33 @@ def __init__(self):
4546
logger.info("Initializing LLMHelper completed")
4647

4748
def get_llm(self):
49+
completion_kwargs = build_completion_kwargs(
50+
self.llm_model, self.llm_max_tokens
51+
)
4852
if self.auth_type_keys:
4953
return AzureChatOpenAI(
5054
deployment_name=self.llm_model,
5155
temperature=0,
52-
max_tokens=self.llm_max_tokens,
5356
openai_api_version=self.openai_client._api_version,
5457
azure_endpoint=self.env_helper.AZURE_OPENAI_ENDPOINT,
5558
api_key=self.env_helper.OPENAI_API_KEY,
59+
**completion_kwargs,
5660
)
5761
else:
5862
return AzureChatOpenAI(
5963
deployment_name=self.llm_model,
6064
temperature=0,
61-
max_tokens=self.llm_max_tokens,
6265
openai_api_version=self.openai_client._api_version,
6366
azure_endpoint=self.env_helper.AZURE_OPENAI_ENDPOINT,
6467
azure_ad_token_provider=self.token_provider,
68+
**completion_kwargs,
6569
)
6670

6771
# TODO: This needs to have a custom callback to stream back to the UI
6872
def get_streaming_llm(self):
73+
completion_kwargs = build_completion_kwargs(
74+
self.llm_model, self.llm_max_tokens
75+
)
6976
if self.auth_type_keys:
7077
return AzureChatOpenAI(
7178
azure_endpoint=self.env_helper.AZURE_OPENAI_ENDPOINT,
@@ -74,8 +81,8 @@ def get_streaming_llm(self):
7481
callbacks=[StreamingStdOutCallbackHandler],
7582
deployment_name=self.llm_model,
7683
temperature=0,
77-
max_tokens=self.llm_max_tokens,
7884
openai_api_version=self.openai_client._api_version,
85+
**completion_kwargs,
7986
)
8087
else:
8188
return AzureChatOpenAI(
@@ -85,9 +92,9 @@ def get_streaming_llm(self):
8592
callbacks=[StreamingStdOutCallbackHandler],
8693
deployment_name=self.llm_model,
8794
temperature=0,
88-
max_tokens=self.llm_max_tokens,
8995
openai_api_version=self.openai_client._api_version,
9096
azure_ad_token_provider=self.token_provider,
97+
**completion_kwargs,
9198
)
9299

93100
def get_embedding_model(self):
@@ -143,6 +150,7 @@ def get_chat_completion_with_functions(
143150
messages=messages,
144151
functions=functions,
145152
function_call=function_call,
153+
**build_completion_kwargs(self.llm_model, self.llm_max_tokens),
146154
)
147155

148156
def get_chat_completion(
@@ -151,7 +159,7 @@ def get_chat_completion(
151159
return self.openai_client.chat.completions.create(
152160
model=model or self.llm_model,
153161
messages=messages,
154-
max_tokens=self.llm_max_tokens,
162+
**build_completion_kwargs(model or self.llm_model, self.llm_max_tokens),
155163
**kwargs
156164
)
157165

@@ -174,12 +182,13 @@ def get_sk_chat_completion_service(self, service_id: str):
174182
)
175183

176184
def get_sk_service_settings(self, service: AzureChatCompletion):
185+
completion_kwargs = build_completion_kwargs(self.llm_model, self.llm_max_tokens)
177186
return cast(
178187
AzureChatPromptExecutionSettings,
179188
service.instantiate_prompt_execution_settings(
180189
service_id=service.service_id,
181190
temperature=0,
182-
max_tokens=self.llm_max_tokens,
191+
**completion_kwargs,
183192
),
184193
)
185194

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from typing import Any
2+
3+
4+
def build_completion_kwargs(model_name: str | None, max_tokens: int | None, **kwargs: Any) -> dict[str, Any]:
5+
"""Return request kwargs that are compatible with newer Azure OpenAI models."""
6+
if max_tokens is None:
7+
return kwargs
8+
9+
normalized_model = (model_name or "").lower()
10+
if "gpt-5" in normalized_model or normalized_model.startswith(("o1", "o3", "o4")):
11+
kwargs["max_completion_tokens"] = max_tokens
12+
else:
13+
kwargs["max_tokens"] = max_tokens
14+
15+
return kwargs

code/create_app.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from backend.batch.utilities.helpers.azure_search_helper import AzureSearchHelper
2222
from backend.batch.utilities.helpers.orchestrator_helper import Orchestrator
2323
from backend.batch.utilities.helpers.config.config_helper import ConfigHelper
24+
from backend.batch.utilities.helpers.openai_utils import build_completion_kwargs
2425
from backend.batch.utilities.helpers.config.conversation_flow import ConversationFlow
2526
from backend.batch.utilities.helpers.prompt_utils import get_current_date_suffix
2627
from backend.api.chat_history import bp_chat_history_response
@@ -202,8 +203,11 @@ def conversation_with_data(conversation: Request, env_helper: EnvHelper):
202203
model=env_helper.AZURE_OPENAI_MODEL,
203204
messages=messages,
204205
temperature=float(env_helper.AZURE_OPENAI_TEMPERATURE),
205-
max_tokens=int(env_helper.AZURE_OPENAI_MAX_TOKENS),
206206
top_p=float(env_helper.AZURE_OPENAI_TOP_P),
207+
**build_completion_kwargs(
208+
env_helper.AZURE_OPENAI_MODEL,
209+
int(env_helper.AZURE_OPENAI_MAX_TOKENS),
210+
),
207211
stop=(
208212
env_helper.AZURE_OPENAI_STOP_SEQUENCE.split("|")
209213
if env_helper.AZURE_OPENAI_STOP_SEQUENCE
@@ -366,8 +370,11 @@ def conversation_without_data(conversation: Request, env_helper: EnvHelper):
366370
model=env_helper.AZURE_OPENAI_MODEL,
367371
messages=messages,
368372
temperature=float(env_helper.AZURE_OPENAI_TEMPERATURE),
369-
max_tokens=int(env_helper.AZURE_OPENAI_MAX_TOKENS),
370373
top_p=float(env_helper.AZURE_OPENAI_TOP_P),
374+
**build_completion_kwargs(
375+
env_helper.AZURE_OPENAI_MODEL,
376+
int(env_helper.AZURE_OPENAI_MAX_TOKENS),
377+
),
371378
stop=(
372379
env_helper.AZURE_OPENAI_STOP_SEQUENCE.split("|")
373380
if env_helper.AZURE_OPENAI_STOP_SEQUENCE

code/tests/functional/tests/backend_api/default/test_conversation.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ def test_post_makes_correct_call_to_openai_chat_completions_with_functions(
317317
},
318318
},
319319
],
320+
"max_tokens": int(app_config.get("AZURE_OPENAI_MAX_TOKENS")),
320321
},
321322
headers={
322323
"Accept": "application/json",

code/tests/utilities/helpers/test_llm_helper.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,22 @@ def test_get_sk_service_settings():
108108
assert settings.max_tokens == int(AZURE_OPENAI_MAX_TOKENS)
109109

110110

111+
def test_get_chat_completion_uses_max_completion_tokens_for_gpt_5_models(
112+
azure_openai_mock, env_helper_mock
113+
):
114+
# given
115+
env_helper_mock.AZURE_OPENAI_MODEL = "gpt-5.1"
116+
llm_helper = LLMHelper()
117+
118+
# when
119+
llm_helper.get_chat_completion([{"role": "user", "content": "hello"}])
120+
121+
# then
122+
call_kwargs = azure_openai_mock.return_value.chat.completions.create.call_args.kwargs
123+
assert call_kwargs["max_completion_tokens"] == int(AZURE_OPENAI_MAX_TOKENS)
124+
assert "max_tokens" not in call_kwargs
125+
126+
111127
def test_generate_embeddings_embeds_input(azure_openai_mock):
112128
# given
113129
llm_helper = LLMHelper()

docs/AVMPostDeploymentGuide.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,26 @@ cd chat-with-your-data-solution-accelerator
2323
bash scripts/post_deployment_setup.sh "<your-resource-group-name>"
2424
```
2525

26-
### Step 2: Configure App Authentication
26+
### Step 2: Build, Push, and Update Container Images (Container Model Only)
27+
28+
> **📌 Skip this step** if you deployed with the default `hostingModel=code`.
29+
30+
When deploying with `hostingModel=container`, the App Services start with a placeholder hello-world image. Run the combined container workflow to build and push the application images to your Azure Container Registry and update the App Services to use them.
31+
32+
**Run the combined ACR build/push/update script (remote build, no Docker required):**
33+
```bash
34+
bash scripts/acr_build_push_update.sh "<your-resource-group-name>"
35+
```
36+
37+
> The script configures managed-identity based authentication between the App Services and your private ACR, then restarts all services. To build locally with Docker instead, use `--mode local`.
38+
39+
### Step 3: Configure App Authentication
2740

2841
1. After deployment is complete, navigate to your Azure App Service in the Azure portal
2942
2. Follow the detailed instructions in [Set Up Authentication in Azure App Service](./azure_app_service_auth_setup.md) to add authentication to your web app
3043
3. This will ensure only authorized users can access your application
3144

32-
### Step 3: Access and Configure the Admin Site
45+
### Step 4: Access and Configure the Admin Site
3346

3447
1. **Navigate to the admin site** using the following URL pattern:
3548
```
@@ -47,7 +60,7 @@ bash scripts/post_deployment_setup.sh "<your-resource-group-name>"
4760
- Wait for the documents to be processed and indexed
4861
- Verify successful ingestion through the admin interface
4962

50-
### Step 4: Access the Chat Application
63+
### Step 5: Access the Chat Application
5164

5265
1. **Navigate to the main chat application** using this URL pattern:
5366
```

docs/LOCAL_DEPLOYMENT.md

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -334,20 +334,45 @@ bash scripts/post_deployment_setup.sh "<your-resource-group-name>"
334334
335335
> **Note:** The script auto-discovers all resources in the resource group. It handles private networking (WAF) deployments by temporarily enabling public access, performing the setup, then restoring the original state.
336336
337-
### 5.2 Configure Authentication (Required for Chat Application)
337+
### 5.2 Build, Push, and Update Container Images (Container Model Only)
338+
339+
> **📌 Skip this step** if you deployed with the default `hostingModel=code`.
340+
341+
When deploying with `hostingModel=container`, the App Services start with a placeholder hello-world image. After provisioning, run the combined container workflow to build and push the application images to your Azure Container Registry and update the App Services to use them.
342+
343+
*PowerShell (Windows):*
344+
```powershell
345+
.\scripts\acr_build_push_update.ps1 -ResourceGroupName "<your-resource-group-name>"
346+
```
347+
348+
*Bash (Linux/macOS/WSL):*
349+
```bash
350+
bash scripts/acr_build_push_update.sh "<your-resource-group-name>"
351+
```
352+
353+
This script:
354+
- Builds and pushes the images to your ACR
355+
- Updates each App Service to pull its image from your private ACR using managed-identity authentication
356+
- Restarts all services
357+
358+
> By default, images are built remotely using `az acr build` (no local Docker required). To build locally with Docker instead, use `-Mode local` in PowerShell or `--mode local` in Bash. You can also set a custom tag with `-Tag` or `--tag`.
359+
360+
> **Re-deployment note:** If you re-run `azd provision`, run this script again to restore the correct container images.
361+
362+
### 5.3 Configure Authentication (Required for Chat Application)
338363
339364
**This step is mandatory for Chat Application access:**
340365
341366
1. Follow [App Authentication Configuration](./azure_app_service_auth_setup.md)
342367
2. Wait up to 10 minutes for authentication changes to take effect
343368
344-
### 5.3 Verify Deployment
369+
### 5.4 Verify Deployment
345370
346371
1. Access your application using the URL from Step 4.3
347372
2. Confirm the application loads successfully
348373
3. Verify you can sign in with your authenticated account
349374
350-
### 5.4 Test the Application
375+
### 5.5 Test the Application
351376
352377
**Quick Test Steps:**
353378
1. Navigate to the admin site, where you can upload documents. Then select Ingest Data and add your data. You can find sample data in the [data](../data) directory.

0 commit comments

Comments
 (0)