Skip to content

Commit e558c65

Browse files
Merge pull request #625 from microsoft/dev
fix: added retry logic for SQL DB connection, updated agent and thread management
2 parents 857d048 + 53dd2a8 commit e558c65

File tree

18 files changed

+244
-94
lines changed

18 files changed

+244
-94
lines changed

infra/deploy_app_service.bicep

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,10 @@ resource Website 'Microsoft.Web/sites@2020-06-01' = {
184184
serverFarmId: HostingPlanName
185185
siteConfig: {
186186
appSettings: [
187+
{
188+
name: 'APP_ENV'
189+
value: 'Prod'
190+
}
187191
{
188192
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
189193
value: reference(applicationInsightsId, '2015-05-01').InstrumentationKey

infra/main.json

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"_generator": {
66
"name": "bicep",
77
"version": "0.36.177.2456",
8-
"templateHash": "2238194529646818649"
8+
"templateHash": "3253509031453285119"
99
}
1010
},
1111
"parameters": {
@@ -359,7 +359,7 @@
359359
}
360360
},
361361
"solutionLocation": "[if(empty(parameters('AZURE_LOCATION')), resourceGroup().location, parameters('AZURE_LOCATION'))]",
362-
"uniqueId": "[toLower(uniqueString(parameters('environmentName'), subscription().id, variables('solutionLocation')))]",
362+
"uniqueId": "[toLower(uniqueString(parameters('environmentName'), subscription().id, variables('solutionLocation'), resourceGroup().name))]",
363363
"solutionPrefix": "[format('ca{0}', padLeft(take(variables('uniqueId'), 12), 12, '0'))]",
364364
"abbrs": "[variables('$fxv#0')]",
365365
"functionAppSqlPrompt": "Generate a valid T-SQL query to find {query} for tables and columns provided below:\r\n 1. Table: Clients\r\n Columns: ClientId, Client, Email, Occupation, MaritalStatus, Dependents\r\n 2. Table: InvestmentGoals\r\n Columns: ClientId, InvestmentGoal\r\n 3. Table: Assets\r\n Columns: ClientId, AssetDate, Investment, ROI, Revenue, AssetType\r\n 4. Table: ClientSummaries\r\n Columns: ClientId, ClientSummary\r\n 5. Table: InvestmentGoalsDetails\r\n Columns: ClientId, InvestmentGoal, TargetAmount, Contribution\r\n 6. Table: Retirement\r\n Columns: ClientId, StatusDate, RetirementGoalProgress, EducationGoalProgress\r\n 7. Table: ClientMeetings\r\n Columns: ClientId, ConversationId, Title, StartTime, EndTime, Advisor, ClientEmail\r\n Always use the Investment column from the Assets table as the value.\r\n Assets table has snapshots of values by date. Do not add numbers across different dates for total values.\r\n Do not use client name in filters.\r\n Do not include assets values unless asked for.\r\n ALWAYS use ClientId = {clientid} in the query filter.\r\n ALWAYS select Client Name (Column: Client) in the query.\r\n Query filters are IMPORTANT. Add filters like AssetType, AssetDate, etc. if needed.\r\n When answering scheduling or time-based meeting questions, always use the StartTime column from ClientMeetings table. Use correct logic to return the most recent past meeting (last/previous) or the nearest future meeting (next/upcoming), and ensure only StartTime column is used for meeting timing comparisons.\r\n Only return the generated SQL query. Do not return anything else.",
@@ -744,7 +744,7 @@
744744
"_generator": {
745745
"name": "bicep",
746746
"version": "0.36.177.2456",
747-
"templateHash": "1124249040831466979"
747+
"templateHash": "1343961496887433815"
748748
}
749749
},
750750
"parameters": {
@@ -1458,7 +1458,7 @@
14581458
"_generator": {
14591459
"name": "bicep",
14601460
"version": "0.36.177.2456",
1461-
"templateHash": "11899270249637077405"
1461+
"templateHash": "10199364008784095733"
14621462
}
14631463
},
14641464
"parameters": {
@@ -2244,7 +2244,7 @@
22442244
"_generator": {
22452245
"name": "bicep",
22462246
"version": "0.36.177.2456",
2247-
"templateHash": "10507186896960913919"
2247+
"templateHash": "7899619253922538038"
22482248
}
22492249
},
22502250
"parameters": {
@@ -2615,6 +2615,10 @@
26152615
"serverFarmId": "[parameters('HostingPlanName')]",
26162616
"siteConfig": {
26172617
"appSettings": [
2618+
{
2619+
"name": "APP_ENV",
2620+
"value": "Prod"
2621+
},
26182622
{
26192623
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
26202624
"value": "[reference(parameters('applicationInsightsId'), '2015-05-01').InstrumentationKey]"
@@ -2894,7 +2898,7 @@
28942898
"_generator": {
28952899
"name": "bicep",
28962900
"version": "0.36.177.2456",
2897-
"templateHash": "11899270249637077405"
2901+
"templateHash": "10199364008784095733"
28982902
}
28992903
},
29002904
"parameters": {

infra/scripts/fabric_scripts/create_fabric_items.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from azure.identity import DefaultAzureCredential
21
import base64
32
import json
43
import requests
@@ -8,7 +7,6 @@
87
import time
98

109

11-
# credential = DefaultAzureCredential()
1210
from azure.identity import AzureCliCredential
1311
credential = AzureCliCredential()
1412

infra/scripts/index_scripts/create_search_index.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
import time
66

77
import pandas as pd
8-
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
8+
from azure.identity import get_bearer_token_provider
9+
from azure.identity import AzureCliCredential
910
from azure.keyvault.secrets import SecretClient
1011
from azure.search.documents import SearchClient
1112
from azure.search.documents.indexes import SearchIndexClient
@@ -44,9 +45,7 @@
4445
"clienttranscripts/meeting_transcripts_metadata/transcripts_metadata.csv"
4546
)
4647

47-
credential = DefaultAzureCredential(
48-
managed_identity_client_id=managed_identity_client_id
49-
)
48+
credential = AzureCliCredential()
5049
token_provider = get_bearer_token_provider(
5150
credential,
5251
"https://cognitiveservices.azure.com/.default"

infra/scripts/index_scripts/create_sql_tables.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,13 @@
77

88
import pandas as pd
99
import pyodbc
10-
from azure.identity import DefaultAzureCredential
10+
from azure.identity import AzureCliCredential
1111
from azure.keyvault.secrets import SecretClient
1212

1313

1414
def get_secrets_from_kv(kv_name, secret_name):
1515
key_vault_name = kv_name # Set the name of the Azure Key Vault
16-
credential = DefaultAzureCredential(
17-
managed_identity_client_id=managed_identity_client_id
18-
)
16+
credential = AzureCliCredential() # Use Azure CLI Credential
1917
secret_client = SecretClient(
2018
vault_url=f"https://{key_vault_name}.vault.azure.net/", credential=credential
2119
) # Create a secret client object using the credential and Key Vault name
@@ -27,9 +25,7 @@ def get_secrets_from_kv(kv_name, secret_name):
2725
driver = "{ODBC Driver 18 for SQL Server}"
2826

2927

30-
credential = DefaultAzureCredential(
31-
managed_identity_client_id=managed_identity_client_id
32-
)
28+
credential = AzureCliCredential() # Use Azure CLI Credential
3329

3430
token_bytes = credential.get_token(
3531
"https://database.windows.net/.default"
@@ -49,9 +45,7 @@ def get_secrets_from_kv(kv_name, secret_name):
4945
from azure.storage.filedatalake import DataLakeServiceClient
5046

5147
account_name = get_secrets_from_kv(key_vault_name, "ADLS-ACCOUNT-NAME")
52-
credential = DefaultAzureCredential(
53-
managed_identity_client_id=managed_identity_client_id
54-
)
48+
credential = AzureCliCredential() # Use Azure CLI Credential
5549

5650
account_url = f"https://{account_name}.dfs.core.windows.net"
5751

infra/scripts/index_scripts/create_update_sql_dates.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,13 @@
66

77
import pandas as pd
88
import pymssql
9-
from azure.identity import DefaultAzureCredential
9+
from azure.identity import AzureCliCredential
1010
from azure.keyvault.secrets import SecretClient
1111

1212

1313
def get_secrets_from_kv(kv_name, secret_name):
1414
key_vault_name = kv_name # Set the name of the Azure Key Vault
15-
credential = DefaultAzureCredential(
16-
managed_identity_client_id=managed_identity_client_id
17-
)
15+
credential = AzureCliCredential() # Use Azure CLI Credential
1816
secret_client = SecretClient(
1917
vault_url=f"https://{key_vault_name}.vault.azure.net/", credential=credential
2018
) # Create a secret client object using the credential and Key Vault name
@@ -32,9 +30,7 @@ def get_secrets_from_kv(kv_name, secret_name):
3230
from azure.storage.filedatalake import DataLakeServiceClient
3331

3432
account_name = get_secrets_from_kv(key_vault_name, "ADLS-ACCOUNT-NAME")
35-
credential = DefaultAzureCredential(
36-
managed_identity_client_id=managed_identity_client_id
37-
)
33+
credential = AzureCliCredential() # Use Azure CLI Credential
3834

3935
account_url = f"https://{account_name}.dfs.core.windows.net"
4036

src/App/.env.sample

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,5 @@ AZURE_SQL_SYSTEM_PROMPT="Generate a valid T-SQL query to find {query} for tables
6767
# Misc
6868
APPINSIGHTS_INSTRUMENTATIONKEY=
6969
AUTH_ENABLED="false"
70-
USE_INTERNAL_STREAM="True"
70+
USE_INTERNAL_STREAM="True"
71+
APP_ENV="dev"

src/App/WebApp.Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,4 @@ COPY --from=frontend /home/node/app/static /usr/src/app/static/
3636
WORKDIR /usr/src/app
3737
EXPOSE 80
3838

39-
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "80", "--workers", "4", "--log-level", "info", "--access-log"]
39+
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "80", "--workers", "1", "--log-level", "info", "--access-log"]

src/App/app.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
import uuid
77
from types import SimpleNamespace
88

9-
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
9+
from azure.identity import get_bearer_token_provider
10+
from backend.helpers.azure_credential_utils import get_azure_credential
1011
from azure.monitor.opentelemetry import configure_azure_monitor
1112

1213
# from quart.sessions import SecureCookieSessionInterface
@@ -90,6 +91,7 @@ async def shutdown():
9091
await AgentFactory.delete_all_agent_instance()
9192
app.wealth_advisor_agent = None
9293
app.search_agent = None
94+
app.sql_agent = None
9395
logging.info("Agents cleaned up during application shutdown")
9496

9597
# app.secret_key = secrets.token_hex(16)
@@ -185,7 +187,7 @@ def init_openai_client(use_data=SHOULD_USE_DATA):
185187
if not aoai_api_key:
186188
logging.debug("No AZURE_OPENAI_KEY found, using Azure AD auth")
187189
ad_token_provider = get_bearer_token_provider(
188-
DefaultAzureCredential(), "https://cognitiveservices.azure.com/.default"
190+
get_azure_credential(), "https://cognitiveservices.azure.com/.default"
189191
)
190192

191193
# Deployment
@@ -233,7 +235,7 @@ def init_cosmosdb_client():
233235
)
234236

235237
if not config.AZURE_COSMOSDB_ACCOUNT_KEY:
236-
credential = DefaultAzureCredential()
238+
credential = get_azure_credential()
237239
else:
238240
credential = config.AZURE_COSMOSDB_ACCOUNT_KEY
239241

src/App/backend/agents/agent_factory.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
from typing import Optional
1111

1212
from azure.ai.projects import AIProjectClient
13-
from azure.identity import DefaultAzureCredential as DefaultAzureCredentialSync
14-
from azure.identity.aio import DefaultAzureCredential
13+
from backend.helpers.azure_credential_utils import get_azure_credential
14+
from backend.helpers.azure_credential_utils import get_azure_credential_async
1515
from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings
1616

1717
from backend.common.config import config
@@ -35,7 +35,7 @@ async def get_wealth_advisor_agent(cls):
3535
async with cls._lock:
3636
if cls._wealth_advisor_agent is None:
3737
ai_agent_settings = AzureAIAgentSettings()
38-
creds = DefaultAzureCredential()
38+
creds = await get_azure_credential_async()
3939
client = AzureAIAgent.create_client(
4040
credential=creds, endpoint=ai_agent_settings.endpoint
4141
)
@@ -76,7 +76,7 @@ async def get_search_agent(cls):
7676

7777
project_client = AIProjectClient(
7878
endpoint=config.AI_PROJECT_ENDPOINT,
79-
credential=DefaultAzureCredentialSync(),
79+
credential=get_azure_credential(),
8080
api_version="2025-05-01",
8181
)
8282

@@ -137,7 +137,7 @@ async def get_sql_agent(cls) -> dict:
137137

138138
project_client = AIProjectClient(
139139
endpoint=config.AI_PROJECT_ENDPOINT,
140-
credential=DefaultAzureCredentialSync(),
140+
credential=get_azure_credential(),
141141
api_version="2025-05-01",
142142
)
143143

0 commit comments

Comments
 (0)