From d677c52872a6a8eb9d0858c254fc1739387244f1 Mon Sep 17 00:00:00 2001 From: Rohini-Microsoft Date: Mon, 9 Sep 2024 10:19:03 +0530 Subject: [PATCH 01/26] update table format system msg in function_app --- ClientAdvisor/App/frontend/src/components/Answer/Answer.tsx | 2 ++ ClientAdvisor/AzureFunction/function_app.py | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ClientAdvisor/App/frontend/src/components/Answer/Answer.tsx b/ClientAdvisor/App/frontend/src/components/Answer/Answer.tsx index 744a003d6..76868bc3a 100644 --- a/ClientAdvisor/App/frontend/src/components/Answer/Answer.tsx +++ b/ClientAdvisor/App/frontend/src/components/Answer/Answer.tsx @@ -16,6 +16,7 @@ import { AppStateContext } from '../../state/AppProvider' import { parseAnswer } from './AnswerParser' import styles from './Answer.module.css' +import rehypeRaw from 'rehype-raw' interface Props { answer: AskResponse @@ -250,6 +251,7 @@ export const Answer = ({ answer, onCitationClicked }: Props) => { StreamingResponse: Always consider to give selected client full name only in response and do not use other example names also consider my client means currently selected client. If you cannot answer the question, always return - I cannot answer this question from the data available. Please rephrase or add more details. ** Remove any client identifiers or ids or numbers or ClientId in the final response. - + For any questions requiring a table, always render the table using the following HTML format:
Header 1Header 2
Data 1Data 2
''' user_query = query.replace('?',' ') From cb313879aba5f54873262943a50093fa7f6671b6 Mon Sep 17 00:00:00 2001 From: Rohini-Microsoft Date: Mon, 9 Sep 2024 15:54:12 +0530 Subject: [PATCH 02/26] added tbble css --- ClientAdvisor/AzureFunction/function_app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ClientAdvisor/AzureFunction/function_app.py b/ClientAdvisor/AzureFunction/function_app.py index 94744a8c8..5ed1e6fb2 100644 --- a/ClientAdvisor/AzureFunction/function_app.py +++ b/ClientAdvisor/AzureFunction/function_app.py @@ -297,7 +297,7 @@ async def stream_openai_text(req: Request) -> StreamingResponse: Always consider to give selected client full name only in response and do not use other example names also consider my client means currently selected client. If you cannot answer the question, always return - I cannot answer this question from the data available. Please rephrase or add more details. ** Remove any client identifiers or ids or numbers or ClientId in the final response. - For any questions requiring a table, always render the table using the following HTML format:
Header 1Header 2
Data 1Data 2
+ For any questions requiring a table, always render the table using the following HTML format:
Header 1Header 2
Data 1Data 2
''' user_query = query.replace('?',' ') From 2249260740a4cc57494be9baec072a9bbe7865da Mon Sep 17 00:00:00 2001 From: Rohini-Microsoft Date: Tue, 10 Sep 2024 21:20:24 +0530 Subject: [PATCH 03/26] added html code into separate file --- ClientAdvisor/AzureFunction/function_app.py | 9 +++++++-- ClientAdvisor/AzureFunction/table.html | 11 +++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 ClientAdvisor/AzureFunction/table.html diff --git a/ClientAdvisor/AzureFunction/function_app.py b/ClientAdvisor/AzureFunction/function_app.py index 5ed1e6fb2..a28b8c875 100644 --- a/ClientAdvisor/AzureFunction/function_app.py +++ b/ClientAdvisor/AzureFunction/function_app.py @@ -276,6 +276,10 @@ async def stream_openai_text(req: Request) -> StreamingResponse: settings.max_tokens = 800 settings.temperature = 0 + # Read the HTML file + with open("table.html", "r") as file: + html_content = file.read() + system_message = '''you are a helpful assistant to a wealth advisor. Do not answer any questions not related to wealth advisors queries. If asked, provide information about client meetings according to the requested timeframe: give details about upcoming meetings if asked for "next" or "upcoming" meetings, and provide details about past meetings if asked for "previous" or "last" meetings including the scheduled time. @@ -297,9 +301,10 @@ async def stream_openai_text(req: Request) -> StreamingResponse: Always consider to give selected client full name only in response and do not use other example names also consider my client means currently selected client. If you cannot answer the question, always return - I cannot answer this question from the data available. Please rephrase or add more details. ** Remove any client identifiers or ids or numbers or ClientId in the final response. - For any questions requiring a table, always render the table using the following HTML format:
Header 1Header 2
Data 1Data 2
+ For any questions requiring a table, always render the table using the following HTML format: ''' - + system_message += html_content + user_query = query.replace('?',' ') user_query_prompt = f'''{user_query}. Always send clientId as {user_query.split(':::')[-1]} ''' diff --git a/ClientAdvisor/AzureFunction/table.html b/ClientAdvisor/AzureFunction/table.html new file mode 100644 index 000000000..51ded0bea --- /dev/null +++ b/ClientAdvisor/AzureFunction/table.html @@ -0,0 +1,11 @@ + + + + + + + + + + +
Header 1Header 2
Data 1Data 2
\ No newline at end of file From d18af4213ed8353edad8cf34e71521cdf72b3b2e Mon Sep 17 00:00:00 2001 From: Rohini-Microsoft Date: Mon, 16 Sep 2024 18:20:45 +0530 Subject: [PATCH 04/26] added Accessibility changes for Client 360 profile --- .../src/components/Cards/Cards.module.css | 2 +- .../QuestionInput/QuestionInput.module.css | 9 +++++++++ .../components/UserCard/UserCard.module.css | 2 +- .../src/components/UserCard/UserCard.tsx | 2 +- .../src/pages/layout/Layout.module.css | 8 ++++++++ .../App/frontend/src/pages/layout/Layout.tsx | 2 +- .../WealthAdvisor-Client360Report.pbix | Bin 156759 -> 160296 bytes 7 files changed, 21 insertions(+), 4 deletions(-) diff --git a/ClientAdvisor/App/frontend/src/components/Cards/Cards.module.css b/ClientAdvisor/App/frontend/src/components/Cards/Cards.module.css index 69033755d..40377aef7 100644 --- a/ClientAdvisor/App/frontend/src/components/Cards/Cards.module.css +++ b/ClientAdvisor/App/frontend/src/components/Cards/Cards.module.css @@ -39,7 +39,7 @@ } .userCardContainer.selected { - background-color: #0078D7; + background-color: #0F6CBD; color: white; box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.14), 0px 0px 2px 0px rgba(0, 0, 0, 0.12); } diff --git a/ClientAdvisor/App/frontend/src/components/QuestionInput/QuestionInput.module.css b/ClientAdvisor/App/frontend/src/components/QuestionInput/QuestionInput.module.css index b9dc041e5..ad8709218 100644 --- a/ClientAdvisor/App/frontend/src/components/QuestionInput/QuestionInput.module.css +++ b/ClientAdvisor/App/frontend/src/components/QuestionInput/QuestionInput.module.css @@ -62,3 +62,12 @@ left: 16.5%; } } + +@media screen and (-ms-high-contrast: active), (forced-colors: active) { + + .questionInputContainer{ + border: 2px solid WindowText; + background-color: Window; + color: WindowText; + } +} diff --git a/ClientAdvisor/App/frontend/src/components/UserCard/UserCard.module.css b/ClientAdvisor/App/frontend/src/components/UserCard/UserCard.module.css index d50e5ae3c..71032898f 100644 --- a/ClientAdvisor/App/frontend/src/components/UserCard/UserCard.module.css +++ b/ClientAdvisor/App/frontend/src/components/UserCard/UserCard.module.css @@ -29,7 +29,7 @@ } .selected { - background-color: #0078D7; + background-color: #0F6CBD; color: white !important; box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.14), 0px 0px 2px 0px rgba(0, 0, 0, 0.12); } diff --git a/ClientAdvisor/App/frontend/src/components/UserCard/UserCard.tsx b/ClientAdvisor/App/frontend/src/components/UserCard/UserCard.tsx index 1b5d4c25a..2847e3c16 100644 --- a/ClientAdvisor/App/frontend/src/components/UserCard/UserCard.tsx +++ b/ClientAdvisor/App/frontend/src/components/UserCard/UserCard.tsx @@ -50,7 +50,7 @@ const UserCard: React.FC = ({
{ if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); // Prevent the default action like scrolling. - handleShowMoreClick(e); // Call the same function as onClick. + onCardClick(); // Call the same function as onClick. } }}>
{ClientName}
diff --git a/ClientAdvisor/App/frontend/src/pages/layout/Layout.module.css b/ClientAdvisor/App/frontend/src/pages/layout/Layout.module.css index abcbbfab1..754ef9795 100644 --- a/ClientAdvisor/App/frontend/src/pages/layout/Layout.module.css +++ b/ClientAdvisor/App/frontend/src/pages/layout/Layout.module.css @@ -179,6 +179,7 @@ height: 100%; */ display: flex; flex-direction: column; + padding-top : 10px ; } .pivotContainer > div { @@ -316,4 +317,11 @@ background-color: Window; color: WindowText; } + + .selectedName{ + border-radius:25px; + border: 2px solid WindowText; + background-color: Window; + color: WindowText; + } } \ No newline at end of file diff --git a/ClientAdvisor/App/frontend/src/pages/layout/Layout.tsx b/ClientAdvisor/App/frontend/src/pages/layout/Layout.tsx index 7681c263f..272576fed 100644 --- a/ClientAdvisor/App/frontend/src/pages/layout/Layout.tsx +++ b/ClientAdvisor/App/frontend/src/pages/layout/Layout.tsx @@ -212,7 +212,7 @@ const Layout = () => { {selectedUser ? selectedUser.ClientName : 'None'}
)} - + diff --git a/ClientAdvisor/PowerBIReport/WealthAdvisor-Client360Report.pbix b/ClientAdvisor/PowerBIReport/WealthAdvisor-Client360Report.pbix index 69c6ba92f000bdfbdf6d93421d87126454070270..5bfefa923d375a6f435545ed2ccfcd127a1c867b 100644 GIT binary patch delta 51026 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

wyWF$ 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 delta 47439 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 Date: Thu, 19 Sep 2024 11:29:46 +0530 Subject: [PATCH 05/26] Update function_app.py --- ClientAdvisor/AzureFunction/function_app.py | 28 +++++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/ClientAdvisor/AzureFunction/function_app.py b/ClientAdvisor/AzureFunction/function_app.py index f9bfd8dc8..e8930d6fd 100644 --- a/ClientAdvisor/AzureFunction/function_app.py +++ b/ClientAdvisor/AzureFunction/function_app.py @@ -40,7 +40,7 @@ def greeting(self, input: Annotated[str, "the question"]) -> Annotated[str, "The client = openai.AzureOpenAI( azure_endpoint=endpoint, api_key=api_key, - api_version="2023-09-01-preview" + api_version=api_version ) deployment = os.environ.get("AZURE_OPEN_AI_DEPLOYMENT_MODEL") try: @@ -75,7 +75,7 @@ def get_SQL_Response( client = openai.AzureOpenAI( azure_endpoint=endpoint, api_key=api_key, - api_version="2023-09-01-preview" + api_version=api_version ) deployment = os.environ.get("AZURE_OPEN_AI_DEPLOYMENT_MODEL") @@ -100,6 +100,18 @@ def get_SQL_Response( Do not include assets values unless asked for. Always use ClientId = {clientid} in the query filter. Always return client name in the query. + If a question involves date and time, always use FORMAT(YourDateTimeColumn, 'yyyy-MM-dd HH:mm:ss') in the query. + If asked, provide information about client meetings according to the requested timeframe: give details about upcoming meetings if asked for "next" or "upcoming" meetings, and provide details about past meetings if asked for "previous" or "last" meetings including the scheduled time and don't filter with "LIMIT 1" in the query. + If asked about the number of past meetings with this client, provide the count of records where the ConversationId is neither null nor an empty string and the EndTime is before the current date in the query. + If asked, provide a summary of the most recent meeting with the client from past dates in the query. + If asked, provide information on the client's investment risk tolerance level in the query. + If asked, provide information on the client's portfolio performance in the query. + If asked, provide information about the client's top-performing investments in the query. + If asked, provide information about any recent changes in the client's investment allocations in the query. + If asked about the client's portfolio performance over the last quarter, calculate the total investment by summing the investment amounts where AssetDate is greater than or equal to the date from one quarter ago using DATEADD(QUARTER, -1, GETDATE()) in the query. + If asked about upcoming important dates or deadlines for the client, always ensure that StartTime is greater than the current date. Do not convert the formats of StartTime and EndTime and consistently provide the upcoming dates along with the scheduled times in the query. + To determine the asset value, sum the investment values for the most recent available date. If asked for the asset types in the portfolio and the present of each, provide a list of each asset type with its most recent investment value. + If the user inquires about asset on a specific date ,sum the investment values for the specific date avoid summing values from all dates prior to the requested date.If asked for the asset types in the portfolio and the value of each for specific date , provide a list of each asset type with specific date investment value avoid summing values from all dates prior to the requested date. Only return the generated sql query. do not return anything else''' try: @@ -152,13 +164,17 @@ def get_answers_from_calltranscripts( client = openai.AzureOpenAI( azure_endpoint= endpoint, #f"{endpoint}/openai/deployments/{deployment}/extensions", api_key=apikey, - api_version="2024-02-01" + api_version=api_version ) query = question system_message = '''You are an assistant who provides wealth advisors with helpful information to prepare for client meetings. You have access to the client’s meeting call transcripts. - You can use this information to answer questions about the clients''' + You can use this information to answer questions about the clients + When asked about action items from previous meetings with the client, **ALWAYS provide information only for the most recent dates**. + If asked, consistently provide the summary of the last meeting with the client only for past dates. + If asked to summarize each transcript, consistently provide a summary with Date and time for all available transcripts and ensure all call transcript's summary should returned with date and time. (i.e "First Call summary Date Time", "Second Call Summary Date Time" and so on.) + Always return time in "HH:mm" format for the client in response.''' completion = client.chat.completions.create( model = deployment, @@ -263,8 +279,10 @@ async def stream_openai_text(req: Request) -> StreamingResponse: Do not answer any questions not related to wealth advisors queries. 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. Only use the client name returned from database in the response. + Always consider to give selected client full name only in response and do not use other example names also consider my client means currently selected client. If you cannot answer the question, always return - I cannot answer this question from the data available. Please rephrase or add more details. ** Remove any client identifiers or ids or numbers or ClientId in the final response. + Do not include or specify any client IDs in the responses. ''' user_query = query.replace('?',' ') @@ -280,4 +298,4 @@ async def stream_openai_text(req: Request) -> StreamingResponse: settings=settings ) - return StreamingResponse(stream_processor(sk_response), media_type="text/event-stream") \ No newline at end of file + return StreamingResponse(stream_processor(sk_response), media_type="text/event-stream") From 10f0599ec7279a3042996d65278d0058421266e3 Mon Sep 17 00:00:00 2001 From: Roopan-Microsoft <168007406+Roopan-Microsoft@users.noreply.github.com> Date: Thu, 19 Sep 2024 11:35:14 +0530 Subject: [PATCH 06/26] Update app.py --- ClientAdvisor/App/app.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ClientAdvisor/App/app.py b/ClientAdvisor/App/app.py index 4bafe554e..90f97ab76 100644 --- a/ClientAdvisor/App/app.py +++ b/ClientAdvisor/App/app.py @@ -970,7 +970,8 @@ async def stream_chat_request(request_body, request_headers): if client_id is None: return jsonify({"error": "No client ID provided"}), 400 query = request_body.get("messages")[-1].get("content") - + query = query.strip() + async def generate(): deltaText = '' #async for completionChunk in response: @@ -1549,12 +1550,12 @@ def get_users(): ClientSummary, CAST(LastMeeting AS DATE) AS LastMeetingDate, FORMAT(CAST(LastMeeting AS DATE), 'dddd MMMM d, yyyy') AS LastMeetingDateFormatted, -      FORMAT(LastMeeting, 'hh:mm tt') AS LastMeetingStartTime, - FORMAT(LastMeetingEnd, 'hh:mm tt') AS LastMeetingEndTime, +       FORMAT(LastMeeting, 'HH:mm ') AS LastMeetingStartTime, + FORMAT(LastMeetingEnd, 'HH:mm') AS LastMeetingEndTime, CAST(NextMeeting AS DATE) AS NextMeetingDate, FORMAT(CAST(NextMeeting AS DATE), 'dddd MMMM d, yyyy') AS NextMeetingFormatted, - FORMAT(NextMeeting, 'hh:mm tt') AS NextMeetingStartTime, - FORMAT(NextMeetingEnd, 'hh:mm tt') AS NextMeetingEndTime + FORMAT(NextMeeting, 'HH:mm') AS NextMeetingStartTime, + FORMAT(NextMeetingEnd, 'HH:mm') AS NextMeetingEndTime FROM ( SELECT ca.ClientId, Client, Email, AssetValue, ClientSummary, LastMeeting, LastMeetingEnd, NextMeeting, NextMeetingEnd FROM ( @@ -1641,4 +1642,4 @@ def get_users(): if conn: conn.close() -app = create_app() \ No newline at end of file +app = create_app() From a4bdc621a240757b383a5940a498f331963e7299 Mon Sep 17 00:00:00 2001 From: Roopan-Microsoft <168007406+Roopan-Microsoft@users.noreply.github.com> Date: Thu, 19 Sep 2024 11:51:53 +0530 Subject: [PATCH 07/26] Update create_azure_functions.sh --- ClientAdvisor/Deployment/scripts/create_azure_functions.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ClientAdvisor/Deployment/scripts/create_azure_functions.sh b/ClientAdvisor/Deployment/scripts/create_azure_functions.sh index 89f4d90ab..4d64bfd94 100644 --- a/ClientAdvisor/Deployment/scripts/create_azure_functions.sh +++ b/ClientAdvisor/Deployment/scripts/create_azure_functions.sh @@ -36,7 +36,7 @@ az storage account create --name $storageAccount --location eastus --resource-gr az functionapp create --resource-group $resourceGroupName --name $functionappname \ --environment $env_name --storage-account $storageAccount \ --functions-version 4 --runtime python \ - --image bycwacontainerreg.azurecr.io/byc-wa-fn:latest + --image bycwacontainerreg.azurecr.io/byc-wa-fn:dev # Sleep for 120 seconds echo "Waiting for 120 seconds to ensure the Function App is properly created..." @@ -50,4 +50,4 @@ az functionapp config appsettings set --name $functionappname -g $resourceGroupN AZURE_SEARCH_INDEX=$azureSearchIndex \ PYTHON_ENABLE_INIT_INDEXING=$valueone PYTHON_ISOLATE_WORKER_DEPENDENCIES=$valueone \ SQLDB_CONNECTION_STRING=$sqlDBConn \ - SQLDB_SERVER=$sqlServerName SQLDB_DATABASE=$sqlDbName SQLDB_USERNAME=$sqlDbUser SQLDB_PASSWORD=$sqlDbPwd \ No newline at end of file + SQLDB_SERVER=$sqlServerName SQLDB_DATABASE=$sqlDbName SQLDB_USERNAME=$sqlDbUser SQLDB_PASSWORD=$sqlDbPwd From f613a949f9ac495e6a2ed599411f9c00e34e8362 Mon Sep 17 00:00:00 2001 From: Roopan P M Date: Thu, 19 Sep 2024 14:00:33 +0530 Subject: [PATCH 08/26] dev tag introduced --- .../Deployment/bicep/deploy_app_service.bicep | 2 +- .../bicep/deploy_azure_function_script.bicep | 3 ++- ClientAdvisor/Deployment/bicep/main.bicep | 2 ++ ClientAdvisor/Deployment/bicep/main.json | 15 +++++++++++---- .../Deployment/scripts/create_azure_functions.sh | 5 +++-- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/ClientAdvisor/Deployment/bicep/deploy_app_service.bicep b/ClientAdvisor/Deployment/bicep/deploy_app_service.bicep index d2dbeb9a3..1b66e034b 100644 --- a/ClientAdvisor/Deployment/bicep/deploy_app_service.bicep +++ b/ClientAdvisor/Deployment/bicep/deploy_app_service.bicep @@ -172,7 +172,7 @@ param VITE_POWERBI_EMBED_URL string = '' // var WebAppImageName = 'DOCKER|ncwaappcontainerreg1.azurecr.io/ncqaappimage:v1.0.0' -var WebAppImageName = 'DOCKER|bycwacontainerreg.azurecr.io/byc-wa-app:latest' +var WebAppImageName = 'DOCKER|bycwacontainerreg.azurecr.io/byc-wa-app:dev' resource HostingPlan 'Microsoft.Web/serverfarms@2020-06-01' = { name: HostingPlanName diff --git a/ClientAdvisor/Deployment/bicep/deploy_azure_function_script.bicep b/ClientAdvisor/Deployment/bicep/deploy_azure_function_script.bicep index cdda63957..2ad7ff55e 100644 --- a/ClientAdvisor/Deployment/bicep/deploy_azure_function_script.bicep +++ b/ClientAdvisor/Deployment/bicep/deploy_azure_function_script.bicep @@ -17,6 +17,7 @@ param sqlDbName string param sqlDbUser string @secure() param sqlDbPwd string +param functionAppVersion string resource deploy_azure_function 'Microsoft.Resources/deploymentScripts@2020-10-01' = { kind:'AzureCLI' @@ -31,7 +32,7 @@ resource deploy_azure_function 'Microsoft.Resources/deploymentScripts@2020-10-01 properties: { azCliVersion: '2.50.0' primaryScriptUri: '${baseUrl}Deployment/scripts/create_azure_functions.sh' // deploy-azure-synapse-pipelines.sh - arguments: '${solutionName} ${solutionLocation} ${resourceGroupName} ${baseUrl} ${azureOpenAIApiKey} ${azureOpenAIApiVersion} ${azureOpenAIEndpoint} ${azureSearchAdminKey} ${azureSearchServiceEndpoint} ${azureSearchIndex} ${sqlServerName} ${sqlDbName} ${sqlDbUser} ${sqlDbPwd}' // Specify any arguments for the script + arguments: '${solutionName} ${solutionLocation} ${resourceGroupName} ${baseUrl} ${azureOpenAIApiKey} ${azureOpenAIApiVersion} ${azureOpenAIEndpoint} ${azureSearchAdminKey} ${azureSearchServiceEndpoint} ${azureSearchIndex} ${sqlServerName} ${sqlDbName} ${sqlDbUser} ${sqlDbPwd} ${functionAppVersion}' // Specify any arguments for the script timeout: 'PT1H' // Specify the desired timeout duration retentionInterval: 'PT1H' // Specify the desired retention interval cleanupPreference:'OnSuccess' diff --git a/ClientAdvisor/Deployment/bicep/main.bicep b/ClientAdvisor/Deployment/bicep/main.bicep index cb99dc114..ad81de2be 100644 --- a/ClientAdvisor/Deployment/bicep/main.bicep +++ b/ClientAdvisor/Deployment/bicep/main.bicep @@ -18,6 +18,7 @@ var resourceGroupName = resourceGroup().name var solutionLocation = resourceGroupLocation var baseUrl = 'https://raw.githubusercontent.com/microsoft/Build-your-own-copilot-Solution-Accelerator/main/ClientAdvisor/' +var functionAppversion = 'latest' // ========== Managed Identity ========== // module managedIdentityModule 'deploy_managed_identity.bicep' = { @@ -120,6 +121,7 @@ module azureFunctions 'deploy_azure_function_script.bicep' = { sqlDbPwd:sqlDBModule.outputs.sqlDbOutput.sqlDbPwd identity:managedIdentityModule.outputs.managedIdentityOutput.id baseUrl:baseUrl + functionAppVersion: functionAppversion } dependsOn:[storageAccountModule] } diff --git a/ClientAdvisor/Deployment/bicep/main.json b/ClientAdvisor/Deployment/bicep/main.json index dc3f5f855..136c43000 100644 --- a/ClientAdvisor/Deployment/bicep/main.json +++ b/ClientAdvisor/Deployment/bicep/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "13616077515444443649" + "templateHash": "15852551930387661408" } }, "parameters": { @@ -28,7 +28,8 @@ "resourceGroupLocation": "[resourceGroup().location]", "resourceGroupName": "[resourceGroup().name]", "solutionLocation": "[variables('resourceGroupLocation')]", - "baseUrl": "https://raw.githubusercontent.com/microsoft/Build-your-own-copilot-Solution-Accelerator/main/ClientAdvisor/" + "baseUrl": "https://raw.githubusercontent.com/microsoft/Build-your-own-copilot-Solution-Accelerator/main/ClientAdvisor/", + "functionAppversion": "latest" }, "resources": [ { @@ -1046,6 +1047,9 @@ }, "baseUrl": { "value": "[variables('baseUrl')]" + }, + "functionAppVersion": { + "value": "[variables('functionAppversion')]" } }, "template": { @@ -1055,7 +1059,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "3863583258880925565" + "templateHash": "12686893977991317957" } }, "parameters": { @@ -1106,6 +1110,9 @@ }, "sqlDbPwd": { "type": "securestring" + }, + "functionAppVersion": { + "type": "string" } }, "resources": [ @@ -1124,7 +1131,7 @@ "properties": { "azCliVersion": "2.50.0", "primaryScriptUri": "[format('{0}Deployment/scripts/create_azure_functions.sh', parameters('baseUrl'))]", - "arguments": "[format('{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} {13}', parameters('solutionName'), parameters('solutionLocation'), parameters('resourceGroupName'), parameters('baseUrl'), parameters('azureOpenAIApiKey'), parameters('azureOpenAIApiVersion'), parameters('azureOpenAIEndpoint'), parameters('azureSearchAdminKey'), parameters('azureSearchServiceEndpoint'), parameters('azureSearchIndex'), parameters('sqlServerName'), parameters('sqlDbName'), parameters('sqlDbUser'), parameters('sqlDbPwd'))]", + "arguments": "[format('{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} {13} {14}', parameters('solutionName'), parameters('solutionLocation'), parameters('resourceGroupName'), parameters('baseUrl'), parameters('azureOpenAIApiKey'), parameters('azureOpenAIApiVersion'), parameters('azureOpenAIEndpoint'), parameters('azureSearchAdminKey'), parameters('azureSearchServiceEndpoint'), parameters('azureSearchIndex'), parameters('sqlServerName'), parameters('sqlDbName'), parameters('sqlDbUser'), parameters('sqlDbPwd'), parameters('functionAppVersion'))]", "timeout": "PT1H", "retentionInterval": "PT1H", "cleanupPreference": "OnSuccess" diff --git a/ClientAdvisor/Deployment/scripts/create_azure_functions.sh b/ClientAdvisor/Deployment/scripts/create_azure_functions.sh index 4d64bfd94..3d96ffe34 100644 --- a/ClientAdvisor/Deployment/scripts/create_azure_functions.sh +++ b/ClientAdvisor/Deployment/scripts/create_azure_functions.sh @@ -15,6 +15,7 @@ sqlServerName="${11}" sqlDbName="${12}" sqlDbUser="${13}" sqlDbPwd="${14}" +functionAppVersion="${15}" azureOpenAIDeploymentModel="gpt-4" azureOpenAIEmbeddingDeployment="text-embedding-ada-002" @@ -36,7 +37,7 @@ az storage account create --name $storageAccount --location eastus --resource-gr az functionapp create --resource-group $resourceGroupName --name $functionappname \ --environment $env_name --storage-account $storageAccount \ --functions-version 4 --runtime python \ - --image bycwacontainerreg.azurecr.io/byc-wa-fn:dev + --image bycwacontainerreg.azurecr.io/byc-wa-fn:$functionAppVersion # Sleep for 120 seconds echo "Waiting for 120 seconds to ensure the Function App is properly created..." @@ -50,4 +51,4 @@ az functionapp config appsettings set --name $functionappname -g $resourceGroupN AZURE_SEARCH_INDEX=$azureSearchIndex \ PYTHON_ENABLE_INIT_INDEXING=$valueone PYTHON_ISOLATE_WORKER_DEPENDENCIES=$valueone \ SQLDB_CONNECTION_STRING=$sqlDBConn \ - SQLDB_SERVER=$sqlServerName SQLDB_DATABASE=$sqlDbName SQLDB_USERNAME=$sqlDbUser SQLDB_PASSWORD=$sqlDbPwd + SQLDB_SERVER=$sqlServerName SQLDB_DATABASE=$sqlDbName SQLDB_USERNAME=$sqlDbUser SQLDB_PASSWORD=$sqlDbPwd \ No newline at end of file From 7728b49de8332ebd87067f9844264544451eb0bb Mon Sep 17 00:00:00 2001 From: Roopan P M Date: Thu, 19 Sep 2024 14:09:45 +0530 Subject: [PATCH 09/26] updated azure deployment url --- ClientAdvisor/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ClientAdvisor/README.md b/ClientAdvisor/README.md index 949041e69..1b4e6f961 100644 --- a/ClientAdvisor/README.md +++ b/ClientAdvisor/README.md @@ -69,7 +69,7 @@ https://azure.microsoft.com/en-us/explore/global-infrastructure/products-by-regi 2. Click the following deployment button to create the required resources for this accelerator in your Azure Subscription. - [![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2FBuild-your-own-copilot-Solution-Accelerator%2Fmain%2FClientAdvisor%2FDeployment%2Fbicep%2Fmain.json) + [![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FRoopan-Microsoft%2Frp0907%2Fmain%2FClientAdvisor%2FDeployment%2Fbicep%2Fmain.json) 3. You will need to select an Azure Subscription, create/select a Resource group, Region, a unique Solution Prefix and an Azure location for Cosmos DB. From c53490d1ea22b49e3f2572038e949fbad7da61a6 Mon Sep 17 00:00:00 2001 From: Roopan P M Date: Thu, 19 Sep 2024 14:12:47 +0530 Subject: [PATCH 10/26] base url udpated --- ClientAdvisor/Deployment/bicep/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ClientAdvisor/Deployment/bicep/main.bicep b/ClientAdvisor/Deployment/bicep/main.bicep index ad81de2be..142703743 100644 --- a/ClientAdvisor/Deployment/bicep/main.bicep +++ b/ClientAdvisor/Deployment/bicep/main.bicep @@ -17,7 +17,7 @@ var resourceGroupName = resourceGroup().name // var subscriptionId = subscription().subscriptionId var solutionLocation = resourceGroupLocation -var baseUrl = 'https://raw.githubusercontent.com/microsoft/Build-your-own-copilot-Solution-Accelerator/main/ClientAdvisor/' +var baseUrl = 'https://raw.githubusercontent.com/Roopan-Microsoft/rp0907/main/ClientAdvisor/' var functionAppversion = 'latest' // ========== Managed Identity ========== // From 202bdec68d0e4be335c5f15992e8b1538c0b8810 Mon Sep 17 00:00:00 2001 From: Roopan P M Date: Thu, 19 Sep 2024 14:13:38 +0530 Subject: [PATCH 11/26] main json updated --- ClientAdvisor/Deployment/bicep/main.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ClientAdvisor/Deployment/bicep/main.json b/ClientAdvisor/Deployment/bicep/main.json index 136c43000..b8f5f5e19 100644 --- a/ClientAdvisor/Deployment/bicep/main.json +++ b/ClientAdvisor/Deployment/bicep/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "15852551930387661408" + "templateHash": "7603870024060537115" } }, "parameters": { @@ -28,7 +28,7 @@ "resourceGroupLocation": "[resourceGroup().location]", "resourceGroupName": "[resourceGroup().name]", "solutionLocation": "[variables('resourceGroupLocation')]", - "baseUrl": "https://raw.githubusercontent.com/microsoft/Build-your-own-copilot-Solution-Accelerator/main/ClientAdvisor/", + "baseUrl": "https://raw.githubusercontent.com/Roopan-Microsoft/rp0907/main/ClientAdvisor/", "functionAppversion": "latest" }, "resources": [ @@ -1999,7 +1999,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "5513270017559796037" + "templateHash": "10803780472687780653" } }, "parameters": { @@ -2384,7 +2384,7 @@ } }, "variables": { - "WebAppImageName": "DOCKER|bycwacontainerreg.azurecr.io/byc-wa-app:latest" + "WebAppImageName": "DOCKER|bycwacontainerreg.azurecr.io/byc-wa-app:dev" }, "resources": [ { From b830224c7485b90ef893039ac6c7062c575fefb6 Mon Sep 17 00:00:00 2001 From: Roopan P M Date: Thu, 19 Sep 2024 16:48:28 +0530 Subject: [PATCH 12/26] updated system message for client name --- ClientAdvisor/AzureFunction/function_app.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ClientAdvisor/AzureFunction/function_app.py b/ClientAdvisor/AzureFunction/function_app.py index e8930d6fd..aaa3ed958 100644 --- a/ClientAdvisor/AzureFunction/function_app.py +++ b/ClientAdvisor/AzureFunction/function_app.py @@ -282,6 +282,7 @@ async def stream_openai_text(req: Request) -> StreamingResponse: Always consider to give selected client full name only in response and do not use other example names also consider my client means currently selected client. If you cannot answer the question, always return - I cannot answer this question from the data available. Please rephrase or add more details. ** Remove any client identifiers or ids or numbers or ClientId in the final response. + Do not include client names other than available in the source data. Do not include or specify any client IDs in the responses. ''' From 243783d99255805c12ac8db568c674463e2f0dd0 Mon Sep 17 00:00:00 2001 From: Rohini-Microsoft Date: Thu, 26 Sep 2024 14:52:56 +0530 Subject: [PATCH 13/26] removed load_env --- ClientAdvisor/AzureFunction/function_app.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/ClientAdvisor/AzureFunction/function_app.py b/ClientAdvisor/AzureFunction/function_app.py index 0d9e2e61c..7c250c8d5 100644 --- a/ClientAdvisor/AzureFunction/function_app.py +++ b/ClientAdvisor/AzureFunction/function_app.py @@ -18,8 +18,6 @@ from semantic_kernel.functions.kernel_function_decorator import kernel_function from semantic_kernel.kernel import Kernel import pymssql -from dotenv import load_dotenv -load_dotenv() # Azure Function App app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS) From 928d5e7aff7e012c36fa4e6a1347fc31de0640be Mon Sep 17 00:00:00 2001 From: Roopan-Microsoft <168007406+Roopan-Microsoft@users.noreply.github.com> Date: Mon, 30 Sep 2024 22:45:14 +0530 Subject: [PATCH 14/26] Update main.bicep --- ClientAdvisor/Deployment/bicep/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ClientAdvisor/Deployment/bicep/main.bicep b/ClientAdvisor/Deployment/bicep/main.bicep index 142703743..4a367089c 100644 --- a/ClientAdvisor/Deployment/bicep/main.bicep +++ b/ClientAdvisor/Deployment/bicep/main.bicep @@ -17,7 +17,7 @@ var resourceGroupName = resourceGroup().name // var subscriptionId = subscription().subscriptionId var solutionLocation = resourceGroupLocation -var baseUrl = 'https://raw.githubusercontent.com/Roopan-Microsoft/rp0907/main/ClientAdvisor/' +var baseUrl = 'https://raw.githubusercontent.com/Roopan-Microsoft/psl-byo-main/main/ClientAdvisor/' var functionAppversion = 'latest' // ========== Managed Identity ========== // From ef77694ed9d2e6e7b8693096d0708d68db0dc78b Mon Sep 17 00:00:00 2001 From: Rohini-Microsoft Date: Mon, 7 Oct 2024 19:01:35 +0530 Subject: [PATCH 15/26] added accessibility changes --- .../App/frontend/src/components/Cards/Cards.tsx | 7 +++++++ .../ChatHistory/ChatHistoryPanel.module.css | 8 ++++++++ .../src/components/ChatHistory/ChatHistoryPanel.tsx | 2 +- .../src/components/common/Button.module.css | 1 + .../App/frontend/src/pages/chat/Chat.module.css | 2 +- ClientAdvisor/App/frontend/src/pages/chat/Chat.tsx | 2 +- .../App/frontend/src/pages/layout/Layout.tsx | 13 +++++++++---- .../App/frontend/src/state/AppProvider.tsx | 3 ++- ClientAdvisor/App/frontend/src/state/AppReducer.tsx | 2 ++ 9 files changed, 32 insertions(+), 8 deletions(-) diff --git a/ClientAdvisor/App/frontend/src/components/Cards/Cards.tsx b/ClientAdvisor/App/frontend/src/components/Cards/Cards.tsx index 99a95abd8..a935363fc 100644 --- a/ClientAdvisor/App/frontend/src/components/Cards/Cards.tsx +++ b/ClientAdvisor/App/frontend/src/components/Cards/Cards.tsx @@ -17,6 +17,13 @@ const Cards: React.FC = ({ onCardClick }) => { const [selectedClientId, setSelectedClientId] = useState(null); const [loadingUsers, setLoadingUsers] = useState(true); + + useEffect(() => { + if(selectedClientId != null && appStateContext?.state.clientId == ''){ + setSelectedClientId('') + } + },[appStateContext?.state.clientId]); + useEffect(() => { const fetchUsers = async () => { try { diff --git a/ClientAdvisor/App/frontend/src/components/ChatHistory/ChatHistoryPanel.module.css b/ClientAdvisor/App/frontend/src/components/ChatHistory/ChatHistoryPanel.module.css index 784838fe7..abb301598 100644 --- a/ClientAdvisor/App/frontend/src/components/ChatHistory/ChatHistoryPanel.module.css +++ b/ClientAdvisor/App/frontend/src/components/ChatHistory/ChatHistoryPanel.module.css @@ -77,3 +77,11 @@ width: 100%; } } + +@media screen and (-ms-high-contrast: active), (forced-colors: active) { + .container{ + border: 2px solid WindowText; + background-color: Window; + color: WindowText; + } +} \ No newline at end of file diff --git a/ClientAdvisor/App/frontend/src/components/ChatHistory/ChatHistoryPanel.tsx b/ClientAdvisor/App/frontend/src/components/ChatHistory/ChatHistoryPanel.tsx index 7a23f4d56..3232293fc 100644 --- a/ClientAdvisor/App/frontend/src/components/ChatHistory/ChatHistoryPanel.tsx +++ b/ClientAdvisor/App/frontend/src/components/ChatHistory/ChatHistoryPanel.tsx @@ -111,7 +111,7 @@ export function ChatHistoryPanel(_props: ChatHistoryPanelProps) { {

{ui?.chat_title}

-

{ui?.chat_description}

+

{ui?.chat_description}

) : (
diff --git a/ClientAdvisor/App/frontend/src/pages/layout/Layout.tsx b/ClientAdvisor/App/frontend/src/pages/layout/Layout.tsx index 272576fed..3c650d070 100644 --- a/ClientAdvisor/App/frontend/src/pages/layout/Layout.tsx +++ b/ClientAdvisor/App/frontend/src/pages/layout/Layout.tsx @@ -52,6 +52,11 @@ const Layout = () => { fetchpbi() }, []) + const resetClientId= ()=>{ + appStateContext?.dispatch({ type: 'RESET_CLIENT_ID' }); + setSelectedUser(null); + setShowWelcomeCard(true); + } const closePopup = () => { setIsVisible(!isVisible); @@ -157,7 +162,7 @@ const Layout = () => { />
-

Upcoming meetings

+

Upcoming meetings

@@ -167,9 +172,9 @@ const Layout = () => { - -

{ui?.title}

- +
(e.key === 'Enter' || e.key === ' ' ? resetClientId() : null)} tabIndex={-1}> +

{ui?.title}

+
{appStateContext?.state.isCosmosDBAvailable?.status !== CosmosDBStatus.NotConfigured && ( diff --git a/ClientAdvisor/App/frontend/src/state/AppProvider.tsx b/ClientAdvisor/App/frontend/src/state/AppProvider.tsx index d0166462d..2ae54afed 100644 --- a/ClientAdvisor/App/frontend/src/state/AppProvider.tsx +++ b/ClientAdvisor/App/frontend/src/state/AppProvider.tsx @@ -51,7 +51,8 @@ export type Action = | { type: 'GET_FEEDBACK_STATE'; payload: string } | { type: 'UPDATE_CLIENT_ID'; payload: string } | { type: 'SET_IS_REQUEST_INITIATED'; payload: boolean } - | { type: 'TOGGLE_LOADER' }; + | { type: 'TOGGLE_LOADER' } + | { type: 'RESET_CLIENT_ID'}; const initialState: AppState = { isChatHistoryOpen: false, diff --git a/ClientAdvisor/App/frontend/src/state/AppReducer.tsx b/ClientAdvisor/App/frontend/src/state/AppReducer.tsx index 21a126dab..03a778cc2 100644 --- a/ClientAdvisor/App/frontend/src/state/AppReducer.tsx +++ b/ClientAdvisor/App/frontend/src/state/AppReducer.tsx @@ -80,6 +80,8 @@ export const appStateReducer = (state: AppState, action: Action): AppState => { return {...state, isRequestInitiated : action.payload} case 'TOGGLE_LOADER': return {...state, isLoader : !state.isLoader} + case 'RESET_CLIENT_ID': + return {...state, clientId: ''} default: return state } From 433da7268efd36bf1d8c9941a4c9ac39dbb56123 Mon Sep 17 00:00:00 2001 From: Roopan-Microsoft <168007406+Roopan-Microsoft@users.noreply.github.com> Date: Mon, 7 Oct 2024 23:51:07 +0530 Subject: [PATCH 16/26] Create codeql.yml --- .github/workflows/codeql.yml | 94 ++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 000000000..5f6ba6220 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,94 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL Advanced" + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + schedule: + - cron: '22 13 * * 0' + +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + # Runner size impacts CodeQL analysis time. To learn more, please see: + # - https://gh.io/recommended-hardware-resources-for-running-codeql + # - https://gh.io/supported-runners-and-hardware-resources + # - https://gh.io/using-larger-runners (GitHub.com only) + # Consider using larger runners or machines with greater resources for possible analysis time improvements. + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} + permissions: + # required for all workflows + security-events: write + + # required to fetch internal or private CodeQL packs + packages: read + + # only required for workflows in private repositories + actions: read + contents: read + + strategy: + fail-fast: false + matrix: + include: + - language: javascript-typescript + build-mode: none + - language: python + build-mode: none + # CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' + # Use `c-cpp` to analyze code written in C, C++ or both + # Use 'java-kotlin' to analyze code written in Java, Kotlin or both + # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both + # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, + # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. + # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how + # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + # If the analyze step fails for one of the languages you are analyzing with + # "We were unable to automatically build your code", modify the matrix above + # to set the build mode to "manual" for that language. Then modify this step + # to build your code. + # ℹ️ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + - if: matrix.build-mode == 'manual' + shell: bash + run: | + echo 'If you are using a "manual" build mode for one or more of the' \ + 'languages you are analyzing, replace this with the commands to build' \ + 'your code, for example:' + echo ' make bootstrap' + echo ' make release' + exit 1 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" From 16fd5bd98da73373842d36f1bfe34573eee8bb4d Mon Sep 17 00:00:00 2001 From: Roopan-Microsoft <168007406+Roopan-Microsoft@users.noreply.github.com> Date: Mon, 7 Oct 2024 23:54:38 +0530 Subject: [PATCH 17/26] Create label.yml --- .github/workflows/label.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/label.yml diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml new file mode 100644 index 000000000..461356907 --- /dev/null +++ b/.github/workflows/label.yml @@ -0,0 +1,22 @@ +# This workflow will triage pull requests and apply a label based on the +# paths that are modified in the pull request. +# +# To use this workflow, you will need to set up a .github/labeler.yml +# file with configuration. For more information, see: +# https://github.com/actions/labeler + +name: Labeler +on: [pull_request_target] + +jobs: + label: + + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + + steps: + - uses: actions/labeler@v4 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" From 8b0b22a862c7658a6df874c115f1b74b5da0373a Mon Sep 17 00:00:00 2001 From: Roopan P M Date: Tue, 8 Oct 2024 00:12:00 +0530 Subject: [PATCH 18/26] Bicep updated to point dev for client advisor --- ClientAdvisor/Deployment/bicep/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ClientAdvisor/Deployment/bicep/main.bicep b/ClientAdvisor/Deployment/bicep/main.bicep index 4a367089c..6c0f3a296 100644 --- a/ClientAdvisor/Deployment/bicep/main.bicep +++ b/ClientAdvisor/Deployment/bicep/main.bicep @@ -18,7 +18,7 @@ var resourceGroupName = resourceGroup().name var solutionLocation = resourceGroupLocation var baseUrl = 'https://raw.githubusercontent.com/Roopan-Microsoft/psl-byo-main/main/ClientAdvisor/' -var functionAppversion = 'latest' +var functionAppversion = 'dev' // ========== Managed Identity ========== // module managedIdentityModule 'deploy_managed_identity.bicep' = { From 0ea3a9fc962caa3516a0a6923429fbcbde907de2 Mon Sep 17 00:00:00 2001 From: Roopan P M Date: Tue, 8 Oct 2024 00:14:56 +0530 Subject: [PATCH 19/26] main json updated --- ClientAdvisor/Deployment/bicep/main.json | 6 +++--- ResearchAssistant/Deployment/bicep/main.bicep | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ClientAdvisor/Deployment/bicep/main.json b/ClientAdvisor/Deployment/bicep/main.json index b8f5f5e19..6f50a220d 100644 --- a/ClientAdvisor/Deployment/bicep/main.json +++ b/ClientAdvisor/Deployment/bicep/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "7603870024060537115" + "templateHash": "5062834210065422729" } }, "parameters": { @@ -28,8 +28,8 @@ "resourceGroupLocation": "[resourceGroup().location]", "resourceGroupName": "[resourceGroup().name]", "solutionLocation": "[variables('resourceGroupLocation')]", - "baseUrl": "https://raw.githubusercontent.com/Roopan-Microsoft/rp0907/main/ClientAdvisor/", - "functionAppversion": "latest" + "baseUrl": "https://raw.githubusercontent.com/Roopan-Microsoft/psl-byo-main/main/ClientAdvisor/", + "functionAppversion": "dev" }, "resources": [ { diff --git a/ResearchAssistant/Deployment/bicep/main.bicep b/ResearchAssistant/Deployment/bicep/main.bicep index c81d19624..ea5f564c2 100644 --- a/ResearchAssistant/Deployment/bicep/main.bicep +++ b/ResearchAssistant/Deployment/bicep/main.bicep @@ -14,7 +14,7 @@ var resourceGroupName = resourceGroup().name var subscriptionId = subscription().subscriptionId var solutionLocation = resourceGroupLocation -var baseUrl = 'https://raw.githubusercontent.com/microsoft/Build-your-own-copilot-Solution-Accelerator/main/' +var baseUrl = 'https://raw.githubusercontent.com/Roopan-Microsoft/Build-your-own-copilot-Solution-Accelerator/main/' // ========== Managed Identity ========== // module managedIdentityModule 'deploy_managed_identity.bicep' = { From 8f9909add81c293c8bca86f1535ec8901af94f6c Mon Sep 17 00:00:00 2001 From: Roopan P M Date: Tue, 8 Oct 2024 00:40:22 +0530 Subject: [PATCH 20/26] Bicep updated --- .../Deployment/bicep/deploy_app_service.bicep | 2 +- ResearchAssistant/Deployment/bicep/main.json | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ResearchAssistant/Deployment/bicep/deploy_app_service.bicep b/ResearchAssistant/Deployment/bicep/deploy_app_service.bicep index 69bc0c1ee..f733d9f0a 100644 --- a/ResearchAssistant/Deployment/bicep/deploy_app_service.bicep +++ b/ResearchAssistant/Deployment/bicep/deploy_app_service.bicep @@ -162,7 +162,7 @@ param AIStudioDraftFlowDeploymentName string = '' param AIStudioUse string = 'False' -var WebAppImageName = 'DOCKER|byoaiacontainerreg.azurecr.io/byoaia-app:latest' +var WebAppImageName = 'DOCKER|byoaiacontainerreg.azurecr.io/byoaia-app:dev' resource HostingPlan 'Microsoft.Web/serverfarms@2020-06-01' = { name: HostingPlanName diff --git a/ResearchAssistant/Deployment/bicep/main.json b/ResearchAssistant/Deployment/bicep/main.json index 6d4cacd0c..a64e3bfd8 100644 --- a/ResearchAssistant/Deployment/bicep/main.json +++ b/ResearchAssistant/Deployment/bicep/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "7163812400877459703" + "templateHash": "10711406236308727919" } }, "parameters": { @@ -23,7 +23,7 @@ "resourceGroupName": "[resourceGroup().name]", "subscriptionId": "[subscription().subscriptionId]", "solutionLocation": "[variables('resourceGroupLocation')]", - "baseUrl": "https://raw.githubusercontent.com/microsoft/Build-your-own-copilot-Solution-Accelerator/main/" + "baseUrl": "https://raw.githubusercontent.com/Roopan-Microsoft/Build-your-own-copilot-Solution-Accelerator/main/" }, "resources": [ { @@ -1508,7 +1508,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "7109834445090495169" + "templateHash": "1558876662595106054" } }, "parameters": { @@ -1878,7 +1878,7 @@ } }, "variables": { - "WebAppImageName": "DOCKER|byoaiacontainerreg.azurecr.io/byoaia-app:latest" + "WebAppImageName": "DOCKER|byoaiacontainerreg.azurecr.io/byoaia-app:dev" }, "resources": [ { From f188e8a37764d6ff7ffd34b8e4005ac5dee70043 Mon Sep 17 00:00:00 2001 From: Roopan P M Date: Tue, 8 Oct 2024 00:43:59 +0530 Subject: [PATCH 21/26] label yml removed --- .github/workflows/label.yml | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 .github/workflows/label.yml diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml deleted file mode 100644 index 461356907..000000000 --- a/.github/workflows/label.yml +++ /dev/null @@ -1,22 +0,0 @@ -# This workflow will triage pull requests and apply a label based on the -# paths that are modified in the pull request. -# -# To use this workflow, you will need to set up a .github/labeler.yml -# file with configuration. For more information, see: -# https://github.com/actions/labeler - -name: Labeler -on: [pull_request_target] - -jobs: - label: - - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: write - - steps: - - uses: actions/labeler@v4 - with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" From d6126ec02017296dcdd47e56061c217ac73efb0d Mon Sep 17 00:00:00 2001 From: Roopan-Microsoft <168007406+Roopan-Microsoft@users.noreply.github.com> Date: Tue, 8 Oct 2024 00:45:16 +0530 Subject: [PATCH 22/26] Create label.yml --- .github/workflows/label.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/label.yml diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml new file mode 100644 index 000000000..461356907 --- /dev/null +++ b/.github/workflows/label.yml @@ -0,0 +1,22 @@ +# This workflow will triage pull requests and apply a label based on the +# paths that are modified in the pull request. +# +# To use this workflow, you will need to set up a .github/labeler.yml +# file with configuration. For more information, see: +# https://github.com/actions/labeler + +name: Labeler +on: [pull_request_target] + +jobs: + label: + + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + + steps: + - uses: actions/labeler@v4 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" From 94112e8e79302a5d491b832ebb36da2ab8aa5578 Mon Sep 17 00:00:00 2001 From: Roopan P M Date: Tue, 8 Oct 2024 00:48:58 +0530 Subject: [PATCH 23/26] labeler moved --- .github/{workflows/label.yml => labeler.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{workflows/label.yml => labeler.yml} (100%) diff --git a/.github/workflows/label.yml b/.github/labeler.yml similarity index 100% rename from .github/workflows/label.yml rename to .github/labeler.yml From e60f18e6c44260bfcb15b4889535ea8be303dd05 Mon Sep 17 00:00:00 2001 From: Roopan P M Date: Tue, 8 Oct 2024 00:51:00 +0530 Subject: [PATCH 24/26] deleted labeler yml --- .github/labeler.yml | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 .github/labeler.yml diff --git a/.github/labeler.yml b/.github/labeler.yml deleted file mode 100644 index 461356907..000000000 --- a/.github/labeler.yml +++ /dev/null @@ -1,22 +0,0 @@ -# This workflow will triage pull requests and apply a label based on the -# paths that are modified in the pull request. -# -# To use this workflow, you will need to set up a .github/labeler.yml -# file with configuration. For more information, see: -# https://github.com/actions/labeler - -name: Labeler -on: [pull_request_target] - -jobs: - label: - - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: write - - steps: - - uses: actions/labeler@v4 - with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" From dab0d43b2433d64977c6385c7793e0c28848ba84 Mon Sep 17 00:00:00 2001 From: Roopan-Microsoft <168007406+Roopan-Microsoft@users.noreply.github.com> Date: Tue, 8 Oct 2024 00:52:18 +0530 Subject: [PATCH 25/26] Create pylint.yml --- .github/workflows/pylint.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/pylint.yml diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml new file mode 100644 index 000000000..c73e032c0 --- /dev/null +++ b/.github/workflows/pylint.yml @@ -0,0 +1,23 @@ +name: Pylint + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.8", "3.9", "3.10"] + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pylint + - name: Analysing the code with pylint + run: | + pylint $(git ls-files '*.py') From 0cf1f6c4a1be52614b315db32f1bb3062e57a4a5 Mon Sep 17 00:00:00 2001 From: Roopan-Microsoft <168007406+Roopan-Microsoft@users.noreply.github.com> Date: Tue, 8 Oct 2024 00:53:16 +0530 Subject: [PATCH 26/26] Create eslint.yml --- .github/workflows/eslint.yml | 52 ++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 .github/workflows/eslint.yml diff --git a/.github/workflows/eslint.yml b/.github/workflows/eslint.yml new file mode 100644 index 000000000..c4d6d6b18 --- /dev/null +++ b/.github/workflows/eslint.yml @@ -0,0 +1,52 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. +# ESLint is a tool for identifying and reporting on patterns +# found in ECMAScript/JavaScript code. +# More details at https://github.com/eslint/eslint +# and https://eslint.org + +name: ESLint + +on: + push: + branches: [ "main" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "main" ] + schedule: + - cron: '43 7 * * 5' + +jobs: + eslint: + name: Run eslint scanning + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write + actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install ESLint + run: | + npm install eslint@8.10.0 + npm install @microsoft/eslint-formatter-sarif@3.1.0 + + - name: Run ESLint + env: + SARIF_ESLINT_IGNORE_SUPPRESSED: "true" + run: npx eslint . + --config .eslintrc.js + --ext .js,.jsx,.ts,.tsx + --format @microsoft/eslint-formatter-sarif + --output-file eslint-results.sarif + continue-on-error: true + + - name: Upload analysis results to GitHub + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: eslint-results.sarif + wait-for-processing: true