diff --git a/sandbox/ais/logic-apps/auto-invest.json b/sandbox/ais/logic-apps/auto-invest.json new file mode 100644 index 00000000..c99155ab --- /dev/null +++ b/sandbox/ais/logic-apps/auto-invest.json @@ -0,0 +1,389 @@ +{ + "definition": { + "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "actions": { + "Check_if_NYSE_and_NASDAQ_are_open": { + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": 200 + }, + "runAfter": {} + }, + "Az_Function_with_Semantic_Kernel_and_Cog_Search_to_invoke_LLM": { + "type": "Function", + "inputs": { + "method": "", + "function": { + "connectionName": "" + } + }, + "runAfter": { + "Populate_prompt_template_with_structured_data": [ + "SUCCEEDED" + ] + } + }, + "Populate_prompt_template_with_structured_data": { + "type": "Join", + "inputs": { + "from": "", + "joinWith": "" + }, + "runAfter": { + "Open_for_trading": [ + "SUCCEEDED" + ] + } + }, + "Validate_LLM_JSON": { + "type": "ParseJson", + "inputs": { + "content": "", + "schema": "" + }, + "runAfter": { + "Az_Function_with_Semantic_Kernel_and_Cog_Search_to_invoke_LLM": [ + "SUCCEEDED" + ] + } + }, + "Fallback_and_retry": { + "type": "If", + "expression": { + "and": [ + { + "equals": [ + "", + "" + ] + } + ] + }, + "actions": { + "Retry_logic": { + "type": "Workflow", + "inputs": { + "host": { + "workflow": { + "id": "" + } + } + } + } + }, + "else": { + "actions": { + "Log": { + "type": "JavaScriptCode", + "inputs": { + "code": "" + } + } + } + }, + "runAfter": { + "Validate_LLM_JSON": [ + "FAILED", + "TIMEDOUT" + ] + } + }, + "Send_user_approval_email": { + "type": "ServiceProvider", + "inputs": { + "parameters": { + "from": "", + "to": "", + "importance": "Normal" + }, + "serviceProviderConfiguration": { + "connectionName": "", + "operationId": "sendEmail", + "serviceProviderId": "/serviceProviders/Smtp" + } + }, + "runAfter": { + "Validate_LLM_JSON": [ + "SUCCEEDED" + ] + } + }, + "When_a_new_email_arrives_(V3)": { + "type": "ApiConnectionNotification", + "inputs": { + "host": { + "connection": { + "referenceName": null + } + }, + "fetch": { + "pathTemplate": { + "template": "/v3/Mail/OnNewEmail" + }, + "method": "get", + "queries": { + "importance": "Any", + "fetchOnlyWithAttachment": false, + "includeAttachments": false, + "folderPath": "Inbox" + } + }, + "subscribe": { + "body": { + "NotificationUrl": "@{listCallbackUrl()}" + }, + "pathTemplate": { + "template": "/GraphMailSubscriptionPoke/$subscriptions" + }, + "method": "post", + "queries": { + "importance": "Any", + "fetchOnlyWithAttachment": false, + "folderPath": "Inbox" + } + } + }, + "runAfter": {} + }, + "Parse_for_approval": { + "type": "InvokeFunction", + "inputs": { + "functionName": "" + }, + "runAfter": { + "When_a_new_email_arrives_(V3)": [ + "SUCCEEDED" + ] + } + }, + "If_approved": { + "type": "Scope", + "actions": { + "Service_Bus_-_start_transaction_to_place_a_trade": { + "type": "ServiceProvider", + "inputs": { + "parameters": { + "entityName": "" + }, + "serviceProviderConfiguration": { + "connectionName": "", + "operationId": "sendMessage", + "serviceProviderId": "/serviceProviders/serviceBus" + } + } + } + }, + "runAfter": { + "Parse_for_approval": [ + "SUCCEEDED" + ] + } + }, + "If_denied_or_replied_with_no": { + "type": "Scope", + "actions": { + "Call_a_local_function_in_this_logic_app_1": { + "type": "InvokeFunction", + "inputs": { + "functionName": "" + } + } + }, + "runAfter": { + "Parse_for_approval": [ + "SUCCEEDED" + ], + "When_a_new_email_arrives_(V3)": [ + "SUCCEEDED" + ] + } + }, + "Open_for_trading": { + "type": "Scope", + "actions": { + "Get_user_preferences_from_existing_API": { + "type": "Response", + "kind": "Http", + "inputs": { + "statusCode": 200 + } + }, + "Transform_request": { + "type": "Xslt", + "kind": "DataMapper", + "inputs": { + "content": "", + "map": { + "source": "LogicApp", + "name": "" + } + }, + "runAfter": { + "Get_user_preferences_from_existing_API": [ + "SUCCEEDED" + ] + } + }, + "Get_stock_investment_thesis": { + "type": "ServiceProvider", + "inputs": { + "parameters": { + "databaseId": "adsf", + "containerId": "asdf", + "queryText": "asdf" + }, + "serviceProviderConfiguration": { + "connectionName": "AzureCosmosDB", + "operationId": "QueryDocuments", + "serviceProviderId": "/serviceProviders/AzureCosmosDB" + } + } + }, + "Current_portfolio_allocation_(SQL)": { + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "referenceName": "sql-2" + } + }, + "method": "post", + "path": "/v2/datasets/@{encodeURIComponent(encodeURIComponent('rty'))},@{encodeURIComponent(encodeURIComponent('rty'))}/query/sql" + } + }, + "Bing_-_Get_company_financial_news": { + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "referenceName": "bingsearch" + } + }, + "method": "get", + "path": "/news/search", + "queries": { + "q": "SDF", + "mkt": "en-US", + "safeSearch": "Moderate", + "count": "20" + } + } + }, + "Mainframe_lookup_-_customer_info": { + "type": "ApiConnection", + "inputs": { + "host": { + "connection": { + "referenceName": "kyndrylmainframe" + } + }, + "method": "get", + "path": "/customernumber/custnum/@{encodeURIComponent('34')}" + } + }, + "Transform_XML": { + "type": "Xslt", + "inputs": { + "content": "", + "map": { + "source": "LogicApp", + "name": "" + } + }, + "runAfter": { + "Mainframe_lookup_-_customer_info": [ + "SUCCEEDED" + ] + } + }, + "JSON_to_text": { + "type": "ParseJson", + "inputs": { + "content": "asdf", + "schema": {} + }, + "runAfter": { + "Bing_-_Get_company_financial_news": [ + "SUCCEEDED" + ] + } + } + }, + "runAfter": { + "Check_if_NYSE_and_NASDAQ_are_open": [ + "SUCCEEDED" + ] + } + } + }, + "contentVersion": "1.0.0.0", + "outputs": {}, + "triggers": { + "Every_weekend_2_hours_after_stock_market_opens": { + "type": "Batch", + "inputs": { + "mode": "Inline", + "configurations": { + "auto-invest": { + "releaseCriteria": { + "recurrence": {} + } + } + } + } + } + } + }, + "connectionReferences": { + "AzureCosmosDB": { + "api": { + "id": "/serviceProviders/AzureCosmosDB" + }, + "connection": { + "id": "/serviceProviders/AzureCosmosDB/connections/AzureCosmosDB" + }, + "connectionName": "AzureCosmosDB", + "authentication": { + "type": "ManagedServiceIdentity" + } + }, + "sql-2": { + "api": { + "id": "/subscriptions/a6029ed2-6d00-4f88-a6a1-5fc071aa5ee7/providers/Microsoft.Web/locations/southcentralus/managedApis/sql" + }, + "connection": { + "id": "/subscriptions/a6029ed2-6d00-4f88-a6a1-5fc071aa5ee7/resourceGroups/miyagi/providers/Microsoft.Web/connections/sql" + }, + "connectionName": "sql", + "authentication": { + "type": "ManagedServiceIdentity" + } + }, + "bingsearch": { + "api": { + "id": "/subscriptions/a6029ed2-6d00-4f88-a6a1-5fc071aa5ee7/providers/Microsoft.Web/locations/southcentralus/managedApis/bingsearch" + }, + "connection": { + "id": "/subscriptions/a6029ed2-6d00-4f88-a6a1-5fc071aa5ee7/resourceGroups/miyagi/providers/Microsoft.Web/connections/bingsearch" + }, + "connectionName": "bingsearch", + "authentication": { + "type": "ManagedServiceIdentity" + } + }, + "kyndrylmainframe": { + "api": { + "id": "/subscriptions/a6029ed2-6d00-4f88-a6a1-5fc071aa5ee7/providers/Microsoft.Web/locations/southcentralus/managedApis/kyndrylmainframe" + }, + "connection": { + "id": "/subscriptions/a6029ed2-6d00-4f88-a6a1-5fc071aa5ee7/resourceGroups/miyagi/providers/Microsoft.Web/connections/kyndrylmainframe" + }, + "connectionName": "kyndrylmainframe", + "authentication": { + "type": "ManagedServiceIdentity" + } + } + }, + "parameters": {} + } \ No newline at end of file diff --git a/services/sk-copilot-chat-api/dotnet/global.json b/services/sk-copilot-chat-api/dotnet/global.json new file mode 100644 index 00000000..dad2db5e --- /dev/null +++ b/services/sk-copilot-chat-api/dotnet/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "version": "8.0.0", + "rollForward": "latestMajor", + "allowPrerelease": true + } +} \ No newline at end of file diff --git a/services/sk-copilot-chat-api/dotnet/memorypipeline/appsettings.json b/services/sk-copilot-chat-api/dotnet/memorypipeline/appsettings.json index 4f14c9ef..d4bc002c 100644 --- a/services/sk-copilot-chat-api/dotnet/memorypipeline/appsettings.json +++ b/services/sk-copilot-chat-api/dotnet/memorypipeline/appsettings.json @@ -43,7 +43,7 @@ // - EmbeddingGeneratorType: Embedding generator configuration: "AzureOpenAIEmbedding" or "OpenAI" // "Retrieval": { - "VectorDbType": "SimpleVectorDb", + "VectorDbType": "AzureCognitiveSearch", "EmbeddingGeneratorType": "AzureOpenAIEmbedding" }, // @@ -125,7 +125,7 @@ "AzureCognitiveSearch": { "Auth": "ApiKey", //"APIKey": "", // dotnet user-secrets set "SemanticMemory:Services:AzureCognitiveSearch:APIKey" "MY_ACS_KEY" - "Endpoint": "" + "Endpoint": "https://gk-miyagi-acs.search.windows.net" }, // // Qdrant configuration for semantic services. @@ -148,8 +148,8 @@ "AzureOpenAIText": { "Auth": "ApiKey", //"APIKey": "", // dotnet user-secrets set "SemanticMemory:Services:AzureOpenAIText:APIKey" "MY_AZUREOPENAI_KEY" - "Endpoint": "", - "Deployment": "gpt-35-turbo", + "Endpoint": "https://gk-ca-gpt4.openai.azure.com/", + "Deployment": "gk-gpt4-32k", "APIType": "ChatCompletion", "MaxRetries": 10 }, @@ -163,8 +163,8 @@ "AzureOpenAIEmbedding": { "Auth": "ApiKey", // "APIKey": "", // dotnet user-secrets set "SemanticMemory:Services:AzureOpenAIEmbedding:APIKey" "MY_AZUREOPENAI_KEY" - "Endpoint": ".openai.azure.com/", - "Deployment": "text-embedding-ada-002" + "Endpoint": "https://gk-ca-gpt4.openai.azure.com/", + "Deployment": "gk-ada" }, // // AI completion and embedding configuration for OpenAI services. diff --git a/services/sk-copilot-chat-api/dotnet/webapi/.gitignore b/services/sk-copilot-chat-api/dotnet/webapi/.gitignore index 14a711e8..317906e3 100644 --- a/services/sk-copilot-chat-api/dotnet/webapi/.gitignore +++ b/services/sk-copilot-chat-api/dotnet/webapi/.gitignore @@ -23,6 +23,8 @@ bld/ [Bb]in/ [Oo]bj/ [Ll]og/ +tmp-cache/ +tmp-database/ # Visual Studio 2015 cache/options directory .vs/ diff --git a/ui/typescript/app/chat-session/route.ts b/ui/typescript/app/chat-session/route.ts index 70b46ecf..9dd9a03f 100644 --- a/ui/typescript/app/chat-session/route.ts +++ b/ui/typescript/app/chat-session/route.ts @@ -3,14 +3,13 @@ import { NextResponse } from 'next/server'; export async function GET(request: Request) { const { searchParams } = new URL(request.url); const userId = searchParams.get('userId'); - const RECCOMMENDATION_SERVICE_URL = `${process.env.NEXT_PUBLIC_COPILOT_CHAT_BASE_URL}/chatSession/getAllChats/${userId}` + const RECCOMMENDATION_SERVICE_URL = `${process.env.NEXT_PUBLIC_COPILOT_CHAT_BASE_URL}/chats` console.log("Request body: "); console.dir(userId) const res = await fetch(RECCOMMENDATION_SERVICE_URL, { method: 'POST', headers: { - 'Content-type': `application/json`, - 'x-sk-api-key': `${process.env.NEXT_PUBLIC_SK_API_KEY}` + 'Content-type': `application/json` } }); diff --git a/ui/typescript/app/chatSession/getAllChats/route.ts b/ui/typescript/app/chatSession/getAllChats/route.ts index 70b46ecf..9dd9a03f 100644 --- a/ui/typescript/app/chatSession/getAllChats/route.ts +++ b/ui/typescript/app/chatSession/getAllChats/route.ts @@ -3,14 +3,13 @@ import { NextResponse } from 'next/server'; export async function GET(request: Request) { const { searchParams } = new URL(request.url); const userId = searchParams.get('userId'); - const RECCOMMENDATION_SERVICE_URL = `${process.env.NEXT_PUBLIC_COPILOT_CHAT_BASE_URL}/chatSession/getAllChats/${userId}` + const RECCOMMENDATION_SERVICE_URL = `${process.env.NEXT_PUBLIC_COPILOT_CHAT_BASE_URL}/chats` console.log("Request body: "); console.dir(userId) const res = await fetch(RECCOMMENDATION_SERVICE_URL, { method: 'POST', headers: { - 'Content-type': `application/json`, - 'x-sk-api-key': `${process.env.NEXT_PUBLIC_SK_API_KEY}` + 'Content-type': `application/json` } }); diff --git a/ui/typescript/package.json b/ui/typescript/package.json index 52007188..296c530f 100644 --- a/ui/typescript/package.json +++ b/ui/typescript/package.json @@ -27,6 +27,7 @@ "js-cookie": "^3.0.1", "little-state-machine": "^4.8.0", "lodash": "^4.17.21", + "moment": "^2.29.4", "next": "^13.3.0", "next-pwa": "^5.6.0", "next-seo": "^6.0.0", diff --git a/ui/typescript/src/components/chat/chat-session-list.tsx b/ui/typescript/src/components/chat/chat-session-list.tsx index 2b9c626f..16598e7b 100644 --- a/ui/typescript/src/components/chat/chat-session-list.tsx +++ b/ui/typescript/src/components/chat/chat-session-list.tsx @@ -16,13 +16,12 @@ export function ChatSessionList({ className, setSelectedSession: updateSelectedS useEffect(() => { async function fetchChatSessions() { - const chatSessionUrl = `${process.env.NEXT_PUBLIC_COPILOT_CHAT_BASE_URL}/chatSession/getAllChats/${userInfo.userName}`; + const chatSessionUrl = `${process.env.NEXT_PUBLIC_COPILOT_CHAT_BASE_URL}/chats/${userInfo.chatId}/messages`; console.log(chatSessionUrl); const response = await fetch(chatSessionUrl, { method: 'GET', headers: { - 'Content-type': `application/json`, - 'x-sk-api-key': `${process.env.NEXT_PUBLIC_SK_API_KEY}` + 'Content-type': `application/json` } }); const data = await response.json(); @@ -35,12 +34,11 @@ export function ChatSessionList({ className, setSelectedSession: updateSelectedS }, []); async function fetchChatMessages(chatId: string) { - const chatMsgEndpoint = `${process.env.NEXT_PUBLIC_COPILOT_CHAT_BASE_URL}/chatSession/getChatMessages/${chatId}?startIdx=0&count=-1` + const chatMsgEndpoint = `${process.env.NEXT_PUBLIC_COPILOT_CHAT_BASE_URL}/chats/${chatId}/messages?startIdx=0&count=-1` const response = await fetch(chatMsgEndpoint, { method: 'GET', headers: { - 'Content-type': `application/json`, - 'x-sk-api-key': `${process.env.NEXT_PUBLIC_SK_API_KEY}` + 'Content-type': `application/json` } }); const data = await response.json(); @@ -52,11 +50,11 @@ export function ChatSessionList({ className, setSelectedSession: updateSelectedS setSelectedSession(currentSession); console.log("Selected current session"); console.dir(currentSession); - await fetchChatMessages(currentSession.id || `${process.env.NEXT_PUBLIC_COPILOT_CHAT_BASE_URL}`); + await fetchChatMessages(currentSession.chatId || `${process.env.NEXT_PUBLIC_COPILOT_CHAT_BASE_URL}`); setUserInfoAtom((prevUserInfo: UserInfoProps) => ({ // Add type to prevUserInfo ...prevUserInfo, - chatId: currentSession.id || `${process.env.NEXT_PUBLIC_COPILOT_CHAT_BASE_URL}`, + chatId: currentSession.chatId || `${process.env.NEXT_PUBLIC_COPILOT_CHAT_BASE_URL}`, })); } diff --git a/ui/typescript/src/data/static/chats.tsx b/ui/typescript/src/data/static/chats.tsx index e557aa8f..4837e616 100644 --- a/ui/typescript/src/data/static/chats.tsx +++ b/ui/typescript/src/data/static/chats.tsx @@ -6,6 +6,6 @@ export const Chats = [ userId: 'bot', userName: 'bot', chatId: '', - authorRole: 1 + messageType: "1" } ] \ No newline at end of file diff --git a/ui/typescript/src/data/static/user-info.tsx b/ui/typescript/src/data/static/user-info.tsx index f471a074..ba9c3dca 100644 --- a/ui/typescript/src/data/static/user-info.tsx +++ b/ui/typescript/src/data/static/user-info.tsx @@ -6,6 +6,7 @@ export const UserInfo = { "firstName": "Govind", "lastName": "Kamtamneni", "age": 50, + "messageType": "0", "riskLevel": "aggressive", "annualHouseholdIncome": 80000, "favoriteBook": "intelligent-investor", diff --git a/ui/typescript/src/layouts/sidebar/chat-blade.tsx b/ui/typescript/src/layouts/sidebar/chat-blade.tsx index 36a6984b..0c36ccb7 100644 --- a/ui/typescript/src/layouts/sidebar/chat-blade.tsx +++ b/ui/typescript/src/layouts/sidebar/chat-blade.tsx @@ -7,7 +7,9 @@ import { useAtom } from "jotai"; import { chatsAtom, userInfoAtom, chatSessionsAtom } from "@/data/personalize/store"; import { ChatSessionList } from "@/components/chat/chat-session-list"; import Button from "@/components/ui/button"; + import React, { useState } from "react"; +import moment from "moment"; type Variable = { key: string; @@ -63,7 +65,7 @@ export default function Sidebar({ className, setSelectedSession, setUserInfoAtom userId: userInfo.userId, userName: userInfo.userName, chatId: userInfo.chatId, - authorRole: 0, + messageType: "0", }; // Update chatsAtom with the user's message first @@ -79,17 +81,15 @@ export default function Sidebar({ className, setSelectedSession, setUserInfoAtom }); - const response = await fetch(`${process.env.NEXT_PUBLIC_COPILOT_CHAT_BASE_URL}/skills/ChatSkill/functions/Chat/invoke`, { + const response = await fetch(`${process.env.NEXT_PUBLIC_COPILOT_CHAT_BASE_URL}/chats/${userInfo.chatId}/messages`, { method: 'POST', headers: { - 'Content-type': `application/json`, - 'x-sk-api-key': `${process.env.NEXT_PUBLIC_SK_API_KEY}` + 'Content-type': `application/json` }, body: JSON.stringify({ input: userInput, variables: [ - { key: 'userId', value: userInfo.userId }, - { key: 'userName', value: userInfo.userName }, + { key: 'messageType', value: userInfo.messageType }, { key: 'chatId', value: userInfo.chatId }, ], }), @@ -111,26 +111,27 @@ export default function Sidebar({ className, setSelectedSession, setUserInfoAtom userId: "bot", userName: "bot", chatId: userInfo.chatId, - authorRole: 1, + messageType: "1", }, ]; }); } + const currentTimestamp = moment().format('MM/DD/YYYY, h:mm:ss A'); + const titleWithTimestamp = `Miyagi chat @ ${currentTimestamp}`; async function createNewChatSession() { setLoading(true); const response = await fetch( - "${process.env.COPILOT_CHAT_BASE_URL}/chatSession/create", + `${process.env.NEXT_PUBLIC_COPILOT_CHAT_BASE_URL}/chats`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ - userId: userInfo.userId, - title: "New Chat Session", + title: titleWithTimestamp, }), } ); diff --git a/ui/typescript/src/types/index.ts b/ui/typescript/src/types/index.ts index c13a488b..0009a7ce 100644 --- a/ui/typescript/src/types/index.ts +++ b/ui/typescript/src/types/index.ts @@ -3,7 +3,7 @@ import type { ReactElement, ReactNode } from 'react'; export type ChatProps = { id: string; - authorRole: number; + messageType: string; content: string; timestamp: string; userId: string; diff --git a/ui/typescript/yarn.lock b/ui/typescript/yarn.lock index 49b0550e..2c4a5199 100644 --- a/ui/typescript/yarn.lock +++ b/ui/typescript/yarn.lock @@ -3986,6 +3986,11 @@ minipass@^5.0.0: resolved "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz" integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== +moment@^2.29.4: + version "2.29.4" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" + integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== + ms@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"