Skip to content

Commit 604f14a

Browse files
Merge branch 'dev' into dependabotchanges
2 parents 34e6c27 + c572154 commit 604f14a

File tree

14 files changed

+510
-230
lines changed

14 files changed

+510
-230
lines changed

.github/workflows/pylint.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,8 @@ jobs:
1818
run: |
1919
python -m pip install --upgrade pip
2020
pip install -r ClientAdvisor/App/requirements.txt
21-
- name: Run flake8
22-
run: flake8 --config=ClientAdvisor/App/.flake8 ClientAdvisor/App
21+
pip install -r ResearchAssistant/App/requirements.txt
22+
- name: Run flake8 and pylint
23+
run: |
24+
flake8 --config=ClientAdvisor/App/.flake8 ClientAdvisor/App
25+
flake8 --config=ResearchAssistant/App/.flake8 ResearchAssistant/App

ClientAdvisor/App/.flake8

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[flake8]
22
max-line-length = 88
3-
extend-ignore = E501, E203
4-
exclude = .venv, frontend,
3+
extend-ignore = E501
4+
exclude = .venv, frontend
5+
ignore = E203, W503, G004, G200

ClientAdvisor/App/requirements-dev.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ httpx==0.28.0
1515
flake8==7.1.1
1616
black==24.8.0
1717
autoflake==2.3.1
18-
isort==5.13.2pytest-asyncio==0.24.0
19-
pytest-cov==5.0.0
20-
isort==5.13.2
18+
isort==5.13.2
19+
pytest-asyncio==0.24.0
20+
pytest-cov==5.0.0

ClientAdvisor/App/requirements.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# Core requirements
12
azure-identity==1.15.0
23
# Flask[async]==2.3.2
34
openai==1.55.3
@@ -12,9 +13,14 @@ aiohttp==3.10.2
1213
quart-session==3.0.0
1314
pymssql==2.3.0
1415
httpx==0.28.0
16+
17+
# Linting and formatting tools
1518
flake8==7.1.1
1619
black==24.8.0
1720
autoflake==2.3.1
1821
isort==5.13.2
22+
23+
# Testing tools
24+
pytest>=8.2,<9 # Compatible version for pytest-asyncio
1925
pytest-asyncio==0.24.0
20-
pytest-cov==5.0.0
26+
pytest-cov==5.0.0

ClientAdvisor/AzureFunction/function_app.py

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -79,28 +79,33 @@ def get_SQL_Response(
7979
)
8080
deployment = os.environ.get("AZURE_OPEN_AI_DEPLOYMENT_MODEL")
8181

82-
sql_prompt = f'''A valid T-SQL query to find {query} for tables and columns provided below:
83-
1. Table: Clients
84-
Columns: ClientId,Client,Email,Occupation,MaritalStatus,Dependents
85-
2. Table: InvestmentGoals
86-
Columns: ClientId,InvestmentGoal
87-
3. Table: Assets
88-
Columns: ClientId,AssetDate,Investment,ROI,Revenue,AssetType
89-
4. Table: ClientSummaries
90-
Columns: ClientId,ClientSummary
91-
5. Table: InvestmentGoalsDetails
92-
Columns: ClientId,InvestmentGoal,TargetAmount,Contribution
93-
6. Table: Retirement
94-
Columns: ClientId,StatusDate,RetirementGoalProgress,EducationGoalProgress
95-
7.Table: ClientMeetings
96-
Columns: ClientId,ConversationId,Title,StartTime,EndTime,Advisor,ClientEmail
97-
Use Investement column from Assets table as value always.
98-
Assets table has snapshots of values by date. Do not add numbers across different dates for total values.
99-
Do not use client name in filter.
100-
Do not include assets values unless asked for.
101-
Always use ClientId = {clientid} in the query filter.
102-
Always return client name in the query.
103-
Only return the generated sql query. do not return anything else'''
82+
sql_prompt = os.environ.get("AZURE_SQL_SYSTEM_PROMPT")
83+
if sql_prompt:
84+
sql_prompt = sql_prompt.replace("{query}", query)
85+
sql_prompt = sql_prompt.replace("{clientid}", clientid)
86+
else:
87+
sql_prompt = f'''A valid T-SQL query to find {query} for tables and columns provided below:
88+
1. Table: Clients
89+
Columns: ClientId,Client,Email,Occupation,MaritalStatus,Dependents
90+
2. Table: InvestmentGoals
91+
Columns: ClientId,InvestmentGoal
92+
3. Table: Assets
93+
Columns: ClientId,AssetDate,Investment,ROI,Revenue,AssetType
94+
4. Table: ClientSummaries
95+
Columns: ClientId,ClientSummary
96+
5. Table: InvestmentGoalsDetails
97+
Columns: ClientId,InvestmentGoal,TargetAmount,Contribution
98+
6. Table: Retirement
99+
Columns: ClientId,StatusDate,RetirementGoalProgress,EducationGoalProgress
100+
7.Table: ClientMeetings
101+
Columns: ClientId,ConversationId,Title,StartTime,EndTime,Advisor,ClientEmail
102+
Use Investement column from Assets table as value always.
103+
Assets table has snapshots of values by date. Do not add numbers across different dates for total values.
104+
Do not use client name in filter.
105+
Do not include assets values unless asked for.
106+
Always use ClientId = {clientid} in the query filter.
107+
Always return client name in the query.
108+
Only return the generated sql query. do not return anything else'''
104109
try:
105110

106111
completion = client.chat.completions.create(
@@ -156,9 +161,11 @@ def get_answers_from_calltranscripts(
156161
)
157162

158163
query = question
159-
system_message = '''You are an assistant who provides wealth advisors with helpful information to prepare for client meetings.
160-
You have access to the client’s meeting call transcripts.
161-
You can use this information to answer questions about the clients'''
164+
system_message = os.environ.get("AZURE_CALL_TRANSCRIPT_SYSTEM_PROMPT")
165+
if not system_message:
166+
system_message = '''You are an assistant who provides wealth advisors with helpful information to prepare for client meetings.
167+
You have access to the client’s meeting call transcripts.
168+
You can use this information to answer questions about the clients'''
162169

163170
completion = client.chat.completions.create(
164171
model = deployment,
@@ -259,13 +266,15 @@ async def stream_openai_text(req: Request) -> StreamingResponse:
259266
settings.max_tokens = 800
260267
settings.temperature = 0
261268

262-
system_message = '''you are a helpful assistant to a wealth advisor.
263-
Do not answer any questions not related to wealth advisors queries.
264-
If the client name and client id do not match, only return - Please only ask questions about the selected client or select another client to inquire about their details. do not return any other information.
265-
Only use the client name returned from database in the response.
266-
If you cannot answer the question, always return - I cannot answer this question from the data available. Please rephrase or add more details.
267-
** Remove any client identifiers or ids or numbers or ClientId in the final response.
268-
'''
269+
system_message = os.environ.get("AZURE_OPENAI_STREAM_TEXT_SYSTEM_PROMPT")
270+
if not system_message:
271+
system_message = '''you are a helpful assistant to a wealth advisor.
272+
Do not answer any questions not related to wealth advisors queries.
273+
If the client name and client id do not match, only return - Please only ask questions about the selected client or select another client to inquire about their details. do not return any other information.
274+
Only use the client name returned from database in the response.
275+
If you cannot answer the question, always return - I cannot answer this question from the data available. Please rephrase or add more details.
276+
** Remove any client identifiers or ids or numbers or ClientId in the final response.
277+
'''
269278

270279
user_query = query.replace('?',' ')
271280

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
@description('Specifies the location for resources.')
2+
param solutionName string
3+
param solutionLocation string
4+
@secure()
5+
param azureOpenAIApiKey string
6+
param azureOpenAIApiVersion string
7+
param azureOpenAIEndpoint string
8+
@secure()
9+
param azureSearchAdminKey string
10+
param azureSearchServiceEndpoint string
11+
param azureSearchIndex string
12+
param sqlServerName string
13+
param sqlDbName string
14+
param sqlDbUser string
15+
@secure()
16+
param sqlDbPwd string
17+
param functionAppVersion string
18+
@description('Azure Function App SQL System Prompt')
19+
param sqlSystemPrompt string
20+
@description('Azure Function App CallTranscript System Prompt')
21+
param callTranscriptSystemPrompt string
22+
@description('Azure Function App Stream Text System Prompt')
23+
param streamTextSystemPrompt string
24+
25+
var functionAppName = '${solutionName}fn'
26+
var azureOpenAIDeploymentModel = 'gpt-4'
27+
var azureOpenAIEmbeddingDeployment = 'text-embedding-ada-002'
28+
var valueOne = '1'
29+
30+
resource storageAccount 'Microsoft.Storage/storageAccounts@2021-04-01' = {
31+
name: '${solutionName}fnstorage'
32+
location: solutionLocation
33+
sku: {
34+
name: 'Standard_LRS'
35+
}
36+
kind: 'StorageV2'
37+
properties: {
38+
allowSharedKeyAccess: false
39+
}
40+
}
41+
42+
resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
43+
name: 'workspace-${solutionName}'
44+
location: solutionLocation
45+
}
46+
47+
resource ApplicationInsights 'Microsoft.Insights/components@2020-02-02' = {
48+
name: functionAppName
49+
location: solutionLocation
50+
kind: 'web'
51+
properties: {
52+
Application_Type: 'web'
53+
publicNetworkAccessForIngestion: 'Enabled'
54+
publicNetworkAccessForQuery: 'Enabled'
55+
WorkspaceResourceId: logAnalyticsWorkspace.id
56+
}
57+
}
58+
59+
resource containerAppEnv 'Microsoft.App/managedEnvironments@2022-06-01-preview' = {
60+
name: '${solutionName}env'
61+
location: solutionLocation
62+
sku: {
63+
name: 'Consumption'
64+
}
65+
properties: {
66+
appLogsConfiguration: {
67+
destination: 'log-analytics'
68+
logAnalyticsConfiguration: {
69+
customerId: logAnalyticsWorkspace.properties.customerId
70+
sharedKey: logAnalyticsWorkspace.listKeys().primarySharedKey
71+
}
72+
}
73+
}
74+
}
75+
76+
resource functionApp 'Microsoft.Web/sites@2024-04-01' = {
77+
name: functionAppName
78+
location: solutionLocation
79+
kind: 'functionapp'
80+
identity: {
81+
type: 'SystemAssigned'
82+
}
83+
properties: {
84+
managedEnvironmentId: containerAppEnv.id
85+
siteConfig: {
86+
linuxFxVersion: 'DOCKER|bycwacontainerreg.azurecr.io/byc-wa-fn:${functionAppVersion}'
87+
appSettings: [
88+
{
89+
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
90+
value: reference(ApplicationInsights.id, '2015-05-01').InstrumentationKey
91+
}
92+
{
93+
name: 'AZURE_OPEN_AI_API_KEY'
94+
value: azureOpenAIApiKey
95+
}
96+
{
97+
name: 'AZURE_OPEN_AI_DEPLOYMENT_MODEL'
98+
value: azureOpenAIDeploymentModel
99+
}
100+
{
101+
name: 'AZURE_OPEN_AI_ENDPOINT'
102+
value: azureOpenAIEndpoint
103+
}
104+
{
105+
name: 'AZURE_OPENAI_EMBEDDING_DEPLOYMENT'
106+
value: azureOpenAIEmbeddingDeployment
107+
}
108+
{
109+
name: 'OPENAI_API_VERSION'
110+
value: azureOpenAIApiVersion
111+
}
112+
{
113+
name: 'AZURE_AI_SEARCH_API_KEY'
114+
value: azureSearchAdminKey
115+
}
116+
{
117+
name: 'AZURE_AI_SEARCH_ENDPOINT'
118+
value: azureSearchServiceEndpoint
119+
}
120+
{
121+
name: 'AZURE_SEARCH_INDEX'
122+
value: azureSearchIndex
123+
}
124+
{
125+
name: 'PYTHON_ENABLE_INIT_INDEXING'
126+
value: valueOne
127+
}
128+
{
129+
name: 'PYTHON_ISOLATE_WORKER_DEPENDENCIES'
130+
value: valueOne
131+
}
132+
{
133+
name: 'SQLDB_CONNECTION_STRING'
134+
value: 'TBD'
135+
}
136+
{
137+
name: 'SQLDB_SERVER'
138+
value: sqlServerName
139+
}
140+
{
141+
name: 'SQLDB_DATABASE'
142+
value: sqlDbName
143+
}
144+
{
145+
name: 'SQLDB_USERNAME'
146+
value: sqlDbUser
147+
}
148+
{
149+
name: 'SQLDB_PASSWORD'
150+
value: sqlDbPwd
151+
}
152+
{
153+
name: 'AZURE_SQL_SYSTEM_PROMPT'
154+
value: sqlSystemPrompt
155+
}
156+
{
157+
name: 'AZURE_CALL_TRANSCRIPT_SYSTEM_PROMPT'
158+
value: callTranscriptSystemPrompt
159+
}
160+
{
161+
name: 'AZURE_OPENAI_STREAM_TEXT_SYSTEM_PROMPT'
162+
value: streamTextSystemPrompt
163+
}
164+
]
165+
}
166+
}
167+
}

ClientAdvisor/Deployment/bicep/deploy_azure_function_script.bicep

Lines changed: 0 additions & 42 deletions
This file was deleted.

0 commit comments

Comments
 (0)