);
// From camelCase to Title Case
const titles = Object.keys(data[0]).map((item: any) => {
return item.replace(/([a-z])([A-Z])/g, "$1 $2");
});
const header = titles.map((item: any, index: number) => {
return (
{item}
);
});
// Fill cells with data
const fillCells = (item: any) => {
const result = [];
const keys = Object.keys(item);
for (let i = 0; i < keys.length; i++) {
result.push(
);
};
================================================
FILE: app/frontend/src/components/Example/ExampleList.tsx
================================================
import { Example } from "./Example";
import styles from "./Example.module.css";
export type ExampleModel = {
text: string;
value: string;
};
// const EXAMPLES: ExampleModel[] = [
// {
// text: "What is included in my Northwind Health Plus plan that is not in standard?",
// value: "What is included in my Northwind Health Plus plan that is not in standard?"
// },
// { text: "What happens in a performance review?", value: "What happens in a performance review?" },
// { text: "What does a Product Manager do?", value: "What does a Product Manager do?" }
// ];
interface Props {
EXAMPLES: ExampleModel[]
onExampleClicked: (value: string) => void;
}
export const ExampleList = ({ onExampleClicked, EXAMPLES }: Props) => {
return (
);
};
export default Admin;
================================================
FILE: app/frontend/src/pages/chatgpt/ChatGpt.module.css
================================================
.container {
flex: 1;
display: flex;
flex-direction: column;
margin-top: 5px;
}
.chatRoot {
flex: 1;
display: flex;
}
.chatContainer {
flex: 1;
/* display: flex; */
flex-direction: column;
align-items: center;
width: 100%;
}
.chatEmptyState {
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
max-height: 1024px;
padding-top: 20px;
}
.chatEmptyStateTitle {
font-size: 2rem;
font-weight: 600;
margin-top: 0;
margin-bottom: 30px;
}
.chatEmptyStateSubtitle {
font-weight: 600;
margin-bottom: 10px;
}
@media only screen and (max-height: 780px) {
.chatEmptyState {
padding-top: 0;
}
.chatEmptyStateTitle {
font-size: 3rem;
margin-bottom: 0px;
}
}
.chatMessageStream {
flex-grow: 1;
/* max-height: 1024px;
max-width: 1028px; */
width: 100%;
overflow-y: auto;
padding-left: 15%;
padding-right: 15%;
display: flex;
flex-direction: column;
}
.chatMessageGpt {
margin-bottom: 20px;
max-width: 80%;
display: flex;
/* min-width: 500px; */
}
.chatMessageGptMinWidth {
/* max-width: 500px; */
margin-bottom: 20px;
}
.chatInput {
position: sticky;
bottom: 0;
flex: 0 0 100px;
padding-top: 12px;
padding-bottom: 24px;
width: 100%;
padding-left: 15%;
padding-right: 15%;
/*max-width: 1028px; */
background: #f2f2f2;
}
.chatAnalysisPanel {
flex: 1;
overflow-y: auto;
/* max-height: 89vh; */
margin-left: 1%;
margin-right: 1%;
max-width: 30%;
}
.chatSettingsSeparator {
margin-top: 15px;
}
.loadingLogo {
font-size: 28px;
}
.commandsContainer {
display: flex;
align-self: flex-end;
}
.commandButton {
margin-right: 20px;
margin-bottom: 20px;
font-size: 14px;
}
.example {
word-break: break-word;
background: #dbdbdb;
border-radius: 8px;
display: flex;
flex-direction: column;
padding: 10px;
margin-bottom: 2px;
cursor: pointer;
}
.example:hover {
box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.14), 0px 0px 2px rgba(0, 0, 0, 0.12);
outline: 2px solid rgba(115, 118, 225, 1);
}
.exampleText {
margin: 0;
font-size: 12px;
width: 850px;
height: 120px;
/* width: 100%; */
}
================================================
FILE: app/frontend/src/pages/chatgpt/ChatGpt.tsx
================================================
import { useRef, useState, useEffect, useMemo } from "react";
import { Checkbox, Panel, DefaultButton, TextField, SpinButton, Spinner, Stack, ChoiceGroup, IChoiceGroupOption } from "@fluentui/react";
import { SparkleFilled } from "@fluentui/react-icons";
import { ShieldLockRegular } from "@fluentui/react-icons";
import { Dropdown, IDropdownStyles, IDropdownOption } from '@fluentui/react/lib/Dropdown';
import styles from "./ChatGpt.module.css";
import { Label } from '@fluentui/react/lib/Label';
import { ExampleList, ExampleModel } from "../../components/Example";
import { chat, Approaches, AskResponse, ChatRequest, ChatTurn, refreshIndex, getSpeechApi, chatGpt, SearchTypes,
getAllIndexSessions, getIndexSession, getIndexSessionDetail, deleteIndexSession, renameIndexSession, getUserInfo, chatStream } from "../../api";
import { Answer, AnswerError, AnswerLoading } from "../../components/Answer";
import { AnswerChat } from "../../components/Answer/AnswerChat";
import { QuestionInput } from "../../components/QuestionInput";
import { UserChatMessage } from "../../components/UserChatMessage";
import { AnalysisPanel, AnalysisPanelTabs } from "../../components/AnalysisPanel";
import { ClearChatButton } from "../../components/ClearChatButton";
import { SettingsButton } from "../../components/SettingsButton";
import { ChatSession } from "../../api/models";
import { DetailsList, DetailsListLayoutMode, SelectionMode, Selection} from '@fluentui/react/lib/DetailsList';
import { SessionButton } from "../../components/SessionButton";
import { mergeStyleSets } from '@fluentui/react/lib/Styling';
import { MarqueeSelection } from '@fluentui/react/lib/MarqueeSelection';
import { RenameButton } from "../../components/RenameButton";
import { Pivot, PivotItem } from '@fluentui/react';
var audio = new Audio();
const ChatGpt = () => {
const [isConfigPanelOpen, setIsConfigPanelOpen] = useState(false);
const [isConfigPanelOpenGpt, setIsConfigPanelOpenGpt] = useState(false);
const [isConfigPanelOpenStream, setIsConfigPanelOpenStream] = useState(false);
const [promptTemplate, setPromptTemplate] = useState("");
const [promptTemplateGpt, setPromptTemplateGpt] = useState("");
const [retrieveCount, setRetrieveCount] = useState(3);
const [useSemanticRanker, setUseSemanticRanker] = useState(true);
const [useSemanticCaptions, setUseSemanticCaptions] = useState(false);
const [excludeCategory, setExcludeCategory] = useState("");
const [useSuggestFollowupQuestions, setUseSuggestFollowupQuestions] = useState(true);
const [useAutoSpeakAnswers, setUseAutoSpeakAnswers] = useState(false);
const [searchTypeOptions, setSearchTypeOptions] = useState(SearchTypes.Similarity);
const [options, setOptions] = useState([])
const [temperature, setTemperature] = useState(0.3);
const [tokenLength, setTokenLength] = useState(500);
const [temperatureGpt, setTemperatureGpt] = useState(0.7);
const [tokenLengthGpt, setTokenLengthGpt] = useState(750);
const [selectedItem, setSelectedItem] = useState();
const dropdownStyles: Partial = { dropdown: { width: 300 } };
const lastQuestionRef = useRef("");
const lastQuestionRefGpt = useRef("");
const lastQuestionRefStream = useRef("");
const chatMessageStreamEnd = useRef(null);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState();
const [activeCitation, setActiveCitation] = useState();
const [activeAnalysisPanelTab, setActiveAnalysisPanelTab] = useState(undefined);
const [selectedAnswer, setSelectedAnswer] = useState(0);
const [answers, setAnswers] = useState<[user: string, response: AskResponse, speechUrl: string | null][]>([]);
const [answerStream, setAnswersStream] = useState<[user: string, response: AskResponse, speechUrl: string | null][]>([]);
const [runningIndex, setRunningIndex] = useState(-1);
const [answersGpt, setAnswersGpt] = useState<[user: string, response: string, speechUrl: string | null][]>([]);
const [chatSession, setChatSession] = useState(null);
const [chatSessionGpt, setChatSessionGpt] = useState(null);
const [sessionId, setSessionId] = useState();
const [sessionIdGpt, setSessionIdGpt] = useState();
const [sessionList, setSessionList] = useState();
const [sessionListGpt, setSessionListGpt] = useState();
const [exampleLoading, setExampleLoading] = useState(false)
const [selectedIndex, setSelectedIndex] = useState();
const [indexMapping, setIndexMapping] = useState<{ key: string; iType: string; summary:string; qa:string; chunkSize:string; chunkOverlap:string; promptType:string }[]>();
const [exampleList, setExampleList] = useState([{text:'', value: ''}]);
const [summary, setSummary] = useState();
const [qa, setQa] = useState('');
const [selectedEmbeddingItem, setSelectedEmbeddingItem] = useState();
const [selectedEmbeddingItemGpt, setSelectedEmbeddingItemGpt] = useState();
const [selectedItems, setSelectedItems] = useState([]);
const [selectedItemsGpt, setSelectedItemsGpt] = useState([]);
const [sessionName, setSessionName] = useState('');
const [oldSessionName, setOldSessionName] = useState('');
const [sessionNameGpt, setSessionNameGpt] = useState('');
const [oldSessionNameGpt, setOldSessionNameGpt] = useState('');
const [showAuthMessage, setShowAuthMessage] = useState(false);
const [selectedDeploymentType, setSelectedDeploymentType] = useState();
const [selectedPromptTypeItem, setSelectedPromptTypeItem] = useState();
const [selectedDeploymentTypeGpt, setSelectedDeploymentTypeGpt] = useState();
const [selectedPromptTypeItemGpt, setSelectedPromptTypeItemGpt] = useState();
const [selectedChunkSize, setSelectedChunkSize] = useState()
const [selectedChunkOverlap, setSelectedChunkOverlap] = useState()
const [selectedPromptType, setSelectedPromptType] = useState()
const [selectedChain, setSelectedChain] = useState();
const [chainTypeOptions, setChainTypeOptions] = useState([])
const [functionCall, setFunctionCall] = useState(false);
const generateQuickGuid = () => {
return Math.random().toString(36).substring(2, 15) +
Math.random().toString(36).substring(2, 15);
}
const classNames = mergeStyleSets({
header: {
margin: 0,
},
row: {
flex: '0 0 auto',
},
focusZone: {
height: '100%',
overflowY: 'auto',
overflowX: 'hidden',
},
selectionZone: {
height: '100%',
overflow: 'hidden',
},
controlWrapper: {
display: 'flex',
flexWrap: 'wrap',
},
});
const promptTypeOptions = [
{
key: 'generic',
text: 'generic'
},
{
key: 'contract',
text: 'contract'
},
{
key: 'medical',
text: 'medical'
},
{
key: 'financial',
text: 'financial'
},
{
key: 'financialtable',
text: 'financialtable'
},
{
key: 'prospectus',
text: 'prospectus'
},
{
key: 'productdocmd',
text: 'productdocmd'
},
{
key: 'insurance',
text: 'insurance'
}
]
const searchTypes: IChoiceGroupOption[] = [
{
key: SearchTypes.Similarity,
text: "Similarity"
},
{
key: SearchTypes.Hybrid,
text: "Hybrid"
},
{
key: SearchTypes.HybridReRank,
text: "Hybrid with ReRank"
}
];
const promptTypeGptOptions = [
{
key: 'custom',
text: 'custom'
},
{
key: 'linuxTerminal',
text: 'Linux Terminal'
},
{
key: 'accountant',
text: 'Accountant'
},
{
key: 'realEstateAgent',
text: 'Real Estate Agent'
},
{
key: 'careerCounseler',
text: 'Career Counseler'
},
{
key: 'personalTrainer',
text: 'Personal Trainer'
}
]
const deploymentTypeOptions = [
{
key: 'gpt35',
text: 'GPT 3.5 Turbo'
},
{
key: 'gpt3516k',
text: 'GPT 3.5 Turbo - 16k'
}
]
const sessionListColumn = [
{
key: 'Session Name',
name: 'Session Name',
fieldName: 'Session Name',
minWidth: 100,
maxWidth: 200,
isResizable: false,
}
]
const chainType = [
{ key: 'stuff', text: 'Stuff'},
{ key: 'map_rerank', text: 'Map ReRank' },
{ key: 'map_reduce', text: 'Map Reduce' },
{ key: 'refine', text: 'Refine'},
]
const embeddingOptions = [
{
key: 'azureopenai',
text: 'Azure Open AI'
},
{
key: 'openai',
text: 'Open AI'
}
// {
// key: 'local',
// text: 'Local Embedding'
// }
]
const selection = useMemo(
() =>
new Selection({
onSelectionChanged: () => {
setSelectedItems(selection.getSelection());
},
selectionMode: SelectionMode.single,
}),
[]);
const selectionGpt = useMemo(
() =>
new Selection({
onSelectionChanged: () => {
setSelectedItemsGpt(selectionGpt.getSelection());
},
selectionMode: SelectionMode.single,
}),
[]);
const getUserInfoList = async () => {
const userInfoList = await getUserInfo();
if (userInfoList.length === 0 && window.location.hostname !== "localhost") {
setShowAuthMessage(true);
}
else {
setShowAuthMessage(false);
}
}
const detailsList = useMemo(
() => (
item.key}
setKey="single"
//isHeaderVisible={false}
//constrainMode={ConstrainMode.unconstrained}
onActiveItemChanged={(item:any) => onSessionClicked(item)}
//focusZoneProps={focusZoneProps}
layoutMode={DetailsListLayoutMode.fixedColumns}
ariaLabelForSelectionColumn="Toggle selection"
checkButtonAriaLabel="select row"
selection={selection}
selectionPreservedOnEmptyClick={false}
/>
),
[selection, sessionListColumn, sessionList]
);
const detailsListChat = useMemo(
() => (
item.key}
setKey="single"
onActiveItemChanged={(item:any) => onSessionGptClicked(item)}
layoutMode={DetailsListLayoutMode.fixedColumns}
ariaLabelForSelectionColumn="Toggle selection"
checkButtonAriaLabel="select row"
selection={selectionGpt}
selectionPreservedOnEmptyClick={false}
/>
),
[selectionGpt, sessionListColumn, sessionListGpt]
);
const onChainChange = (event: React.FormEvent, item?: IDropdownOption): void => {
setSelectedChain(item);
};
const makeApiRequest = async (question: string) => {
let currentSession = chatSession;
let firstSession = false;
if (!lastQuestionRef.current || currentSession === null) {
currentSession = handleNewConversation();
firstSession = true;
let sessionLists = sessionList;
sessionLists?.unshift({
"Session Name": currentSession.sessionId,
});
setSessionList(sessionLists)
}
lastQuestionRef.current = question;
error && setError(undefined);
setIsLoading(true);
setActiveCitation(undefined);
setActiveAnalysisPanelTab(undefined);
try {
const history: ChatTurn[] = answers.map(a => ({ user: a[0], bot: a[1].answer }));
const request: ChatRequest = {
history: [...history, { user: question, bot: undefined }],
approach: Approaches.ReadRetrieveRead,
overrides: {
promptTemplate: promptTemplate.length === 0 ? undefined : promptTemplate,
excludeCategory: excludeCategory.length === 0 ? undefined : excludeCategory,
top: retrieveCount,
temperature: temperature,
semanticRanker: useSemanticRanker,
semanticCaptions: useSemanticCaptions,
suggestFollowupQuestions: useSuggestFollowupQuestions,
tokenLength: tokenLength,
autoSpeakAnswers: useAutoSpeakAnswers,
embeddingModelType: String(selectedEmbeddingItem?.key),
firstSession: firstSession,
session: JSON.stringify(currentSession),
sessionId: currentSession.sessionId,
deploymentType: String(selectedDeploymentType?.key),
chainType: String(selectedChain?.key),
searchType: searchTypeOptions,
}
};
const result = await chat(request, String(selectedItem?.key), String(selectedIndex));
//setAnswers([...answers, [question, result]]);
setAnswers([...answers, [question, result, null]]);
if(useAutoSpeakAnswers){
const speechUrl = await getSpeechApi(result.answer);
setAnswers([...answers, [question, result, speechUrl]]);
startOrStopSynthesis("gpt35", speechUrl, answers.length);
}
} catch (e) {
setError(e);
} finally {
setIsLoading(false);
}
};
const makeApiStreamRequest = async (question: string) => {
// let currentSession = chatSession;
// let firstSession = false;
// if (!lastQuestionRef.current || currentSession === null) {
// currentSession = handleNewConversation();
// firstSession = true;
// let sessionLists = sessionList;
// sessionLists?.unshift({
// "Session Name": currentSession.sessionId,
// });
// setSessionList(sessionLists)
// }
lastQuestionRefStream.current = question;
error && setError(undefined);
setIsLoading(true);
setActiveCitation(undefined);
setActiveAnalysisPanelTab(undefined);
try {
const history: ChatTurn[] = answerStream.map(a => ({ user: a[0], bot: a[1].answer }));
const request: ChatRequest = {
history: [...history, { user: question, bot: undefined }],
approach: Approaches.ReadRetrieveRead,
overrides: {
promptTemplate: promptTemplate.length === 0 ? undefined : promptTemplate,
excludeCategory: excludeCategory.length === 0 ? undefined : excludeCategory,
top: retrieveCount,
temperature: temperature,
semanticRanker: useSemanticRanker,
semanticCaptions: useSemanticCaptions,
suggestFollowupQuestions: useSuggestFollowupQuestions,
tokenLength: tokenLength,
autoSpeakAnswers: useAutoSpeakAnswers,
embeddingModelType: String(selectedEmbeddingItem?.key),
//firstSession: firstSession,
//session: JSON.stringify(currentSession),
//sessionId: currentSession.sessionId,
deploymentType: String(selectedDeploymentType?.key),
chainType: String(selectedChain?.key),
searchType: searchTypeOptions,
}
};
let result: any = {};
let answer: string = '';
let nextQuestion: string = '';
const response = await chatStream(request,String(selectedItem?.key), String(selectedIndex));
let askResponse: AskResponse = {} as AskResponse;
if (response?.body) {
const reader = response.body.getReader();
let runningText = "";
while (true) {
const {done, value} = await reader.read();
if (done) break;
var text = new TextDecoder("utf-8").decode(value);
const objects = text.split("\n");
objects.forEach(async (obj) => {
try {
runningText += obj;
if (obj != "") {
result = JSON.parse(runningText)
// if (result["data_points"]) {
// askResponse = result;
// } else if (result["choices"] && result["choices"][0]["delta"]["content"]) {
// console.log("Came in choices")
// answer += result["choices"][0]["delta"]["content"];
// nextQuestion += answer.indexOf("NEXT QUESTIONS:") > -1 ? answer.substring(answer.indexOf('NEXT QUESTIONS:') + 15) : '';
// let latestResponse: AskResponse = {...askResponse, answer: answer, nextQuestions: nextQuestion};
// setIsLoading(false);
// setAnswersStream([...answerStream, [question, latestResponse, null]]);
// if(useAutoSpeakAnswers){
// const speechUrl = await getSpeechApi(result.answer);
// setAnswersStream([...answerStream, [question, latestResponse, speechUrl]]);
// startOrStopSynthesis("gpt35", speechUrl, answerStream.length);
// }
// }
if (result['answer'])
{
askResponse = result;
answer += result["answer"];
nextQuestion += answer.indexOf("NEXT QUESTIONS:") > -1 ? answer.substring(answer.indexOf('NEXT QUESTIONS:') + 15) : '';
let latestResponse: AskResponse = {...askResponse, answer: answer, nextQuestions: nextQuestion};
setIsLoading(false);
setAnswersStream([...answerStream, [question, latestResponse, null]]);
if(useAutoSpeakAnswers){
const speechUrl = await getSpeechApi(result.answer);
setAnswersStream([...answerStream, [question, latestResponse, speechUrl]]);
startOrStopSynthesis("gpt35", speechUrl, answerStream.length);
}
}
}
runningText = "";
}
catch {
//console.log("Error parsing JSON: " + obj);
}
});
}
}
} catch (e) {
setError(e);
} finally {
setIsLoading(false);
}
};
const makeApiRequestGpt = async (question: string) => {
let currentSession = chatSessionGpt;
let firstSession = false;
if (!lastQuestionRefGpt.current || currentSession === null) {
currentSession = handleNewConversationGpt()
firstSession = true;
let sessionLists = sessionListGpt;
sessionLists?.unshift({
"Session Name": currentSession.sessionId,
});
setSessionListGpt(sessionLists)
}
let promptTemplate = "";
if (firstSession) {
if (selectedPromptTypeItemGpt?.key == "custom")
setPromptTemplateGpt(question);
promptTemplate = question;
}
else {
//promptTemplate = promptTemplateGpt;
promptTemplate = answersGpt[0][0];
}
lastQuestionRefGpt.current = question;
error && setError(undefined);
setIsLoading(true);
try {
const history: ChatTurn[] = answersGpt.map(a => ({ user: a[0], bot: a[1] }));
const request: ChatRequest = {
history: [...history, { user: question, bot: undefined }],
approach: Approaches.ReadRetrieveRead,
overrides: {
promptTemplate: promptTemplate,
temperature: temperatureGpt,
tokenLength: tokenLengthGpt,
embeddingModelType: String(selectedEmbeddingItemGpt?.key),
firstSession: firstSession,
session: JSON.stringify(currentSession),
sessionId: currentSession.sessionId,
deploymentType: String(selectedDeploymentTypeGpt?.key),
functionCall:functionCall,
searchType: searchTypeOptions,
}
};
const result = await chatGpt(request, 'chatgpt', 'cogsearchvs');
setAnswersGpt([...answersGpt, [question, result.answer, null]]);
} catch (e) {
setError(e);
} finally {
setIsLoading(false);
}
};
const getCosmosSession = async (indexNs : string, indexType: string) => {
try {
await getAllIndexSessions(indexNs, indexType, 'chat', 'Session')
.then(async (response:any) => {
const sessionLists = []
if (response.length === 0) {
sessionLists.push({
"Session Name": "No Sessions found",
});
} else
{
for (const session of response) {
sessionLists.push({
"Session Name": session.name,
});
}
}
if (indexNs == "chatgpt") {
setSessionListGpt(sessionLists)
} else {
setSessionList(sessionLists)
}
})
} catch (e) {
setError(e);
} finally {
setIsLoading(false);
}
};
const clearChat = () => {
lastQuestionRef.current = "";
error && setError(undefined);
setActiveCitation(undefined);
setActiveAnalysisPanelTab(undefined);
setChatSession(null)
setAnswers([]);
setSelectedItems([])
setSessionName('');
};
const clearStreamChat = () => {
lastQuestionRefStream.current = "";
error && setError(undefined);
setActiveCitation(undefined);
setActiveAnalysisPanelTab(undefined);
setAnswersStream([]);
setSelectedItems([])
};
const clearChatGpt = () => {
lastQuestionRefGpt.current = "";
error && setError(undefined);
setChatSessionGpt(null)
setAnswersGpt([]);
setSelectedItemsGpt([])
setSessionNameGpt('');
setSelectedPromptTypeItemGpt(promptTypeGptOptions[0])
setPromptTemplateGpt('')
};
const deleteSession = async () => {
//const sessionName = String(selectedItems[0]?.['Session Name'])
if (sessionName === 'No Sessions found' || sessionName === "" || sessionName === undefined) {
alert("Select Session to delete")
}
await deleteIndexSession(String(selectedItem?.key), String(selectedIndex), sessionName)
.then(async (sessionResponse:any) => {
const defaultKey = selectedItem?.key
indexMapping?.findIndex((item) => {
if (item.key == defaultKey) {
getCosmosSession(item?.key, item?.iType)
}
})
clearChat();
})
};
const renameSession = async () => {
//const oldSessionName = String(selectedItems[0]?.['Session Name'])
if (oldSessionName === 'No Sessions found' || oldSessionName === undefined || sessionName === "" || sessionName === undefined
|| oldSessionName === "" || sessionName === 'No Sessions found') {
alert("Select valid session to rename")
}
else {
await renameIndexSession(oldSessionName, sessionName)
.then(async (sessionResponse:any) => {
const defaultKey = selectedItem?.key
indexMapping?.findIndex((item) => {
if (item.key == defaultKey) {
getCosmosSession(item?.key, item?.iType)
}
})
clearChat();
})
}
};
const deleteSessionGpt = async () => {
if (sessionNameGpt === 'No Sessions found' || sessionNameGpt === "" || sessionNameGpt === undefined) {
alert("Select Session to delete")
}
await deleteIndexSession("chatgpt", "cogsearchvs", sessionNameGpt)
.then(async (sessionResponse:any) => {
getCosmosSession("chatgpt", "cogsearchvs")
clearChatGpt();
})
};
const renameSessionGpt = async () => {
if (oldSessionNameGpt === 'No Sessions found' || oldSessionNameGpt === undefined || sessionNameGpt === "" || sessionNameGpt === undefined
|| oldSessionNameGpt === "" || oldSessionNameGpt === 'No Sessions found') {
alert("Select valid session to rename")
}
else {
await renameIndexSession(oldSessionNameGpt, sessionNameGpt)
.then(async (sessionResponse:any) => {
getCosmosSession("chatgpt", "cogsearchvs")
clearChatGpt();
})
}
};
const onSessionNameChange = (event: React.FormEvent, newValue?: string): void => {
const oldSessionName = String(selectedItems[0]?.['Session Name'])
if (newValue === undefined || newValue === "") {
alert("Provide session name")
}
setSessionName(newValue || oldSessionName);
};
const onSessionNameChangeGpt = (event: React.FormEvent, newValue?: string): void => {
const oldSessionNameGpt = String(selectedItemsGpt[0]?.['Session Name'])
if (newValue === undefined || newValue === "") {
alert("Provide session name")
}
setSessionNameGpt(newValue || oldSessionNameGpt);
};
const onEnableAutoSpeakAnswersChange = (_ev?: React.FormEvent, checked?: boolean) => {
setUseAutoSpeakAnswers(!!checked);
};
const onExampleClicked = (example: string) => {
makeApiRequest(example);
};
const onExampleStreamClicked = (example: string) => {
makeApiStreamRequest(example);
};
const onSearchTypeChange = (_ev?: React.FormEvent, option?: IChoiceGroupOption) => {
setSearchTypeOptions((option?.key as SearchTypes) || SearchTypes.Similarity);
};
const startOrStopSynthesis = async (answerType:string, url: string | null, index: number) => {
if(runningIndex === index) {
audio.pause();
setRunningIndex(-1);
return;
}
if(runningIndex !== -1) {
audio.pause();
setRunningIndex(-1);
}
if(url === null) {
let speechAnswer;
if (answerType === 'gpt35') {
answers.map((answer, index) => {
speechAnswer = answer[1].answer
})
}
const speechUrl = await getSpeechApi(speechAnswer || '');
if (speechUrl === null) {
return;
}
audio = new Audio(speechUrl);
audio.play();
setRunningIndex(index);
audio.addEventListener('ended', () => {
setRunningIndex(-1);
});
} else {
audio = new Audio(url);
audio.play();
setRunningIndex(index);
audio.addEventListener('ended', () => {
setRunningIndex(-1);
});
}
};
const refreshBlob = async () => {
const files = []
const indexType = []
//const blobs = containerClient.listBlobsFlat(listOptions)
const blobs = await refreshIndex()
for (const blob of blobs.values) {
if (blob.embedded == "true")
{
files.push({
text: blob.indexName,
key: blob.namespace
})
indexType.push({
key:blob.namespace,
iType:blob.indexType,
summary:blob.summary,
qa:blob.qa,
chunkSize:blob.chunkSize,
chunkOverlap:blob.chunkOverlap,
promptType:blob.promptType
})
}
}
var uniqFiles = files.filter((v,i,a)=>a.findIndex(v2=>(v2.key===v.key))===i)
setOptions(uniqFiles)
setSelectedItem(uniqFiles[0])
const defaultKey = uniqFiles[0].key
var uniqIndexType = indexType.filter((v,i,a)=>a.findIndex(v2=>(v2.key===v.key))===i)
for (const item of uniqIndexType) {
if (item.key == defaultKey) {
setSelectedIndex(item.iType)
setSummary(item.summary)
setQa(item.qa)
setSelectedChunkOverlap(item.chunkOverlap)
setSelectedChunkSize(item.chunkSize)
setSelectedPromptType(item.promptType)
setSelectedPromptTypeItem(promptTypeOptions.find(x => x.key === item.promptType))
updatePrompt(item.promptType)
if (Number(item.chunkSize) > 4000) {
setSelectedDeploymentType(deploymentTypeOptions[1])
} else {
setSelectedDeploymentType(deploymentTypeOptions[0])
}
getCosmosSession(item?.key, item?.iType)
const sampleQuestion = []
const questionList = item.qa.split("\\n")
for (const item of questionList) {
if ((item != '')) {
sampleQuestion.push({
text: item.replace(/^\d+\.\s*/, '').replace('<', '').replace('>', ''),
value: item.replace(/^\d+\.\s*/, '').replace('<', '').replace('>', '')
})
}
}
const generatedExamples: ExampleModel[] = sampleQuestion
setExampleList(generatedExamples)
setExampleLoading(false)
}
}
setIndexMapping(uniqIndexType)
}
const onChange = (event?: React.FormEvent, item?: IDropdownOption): void => {
setSelectedItem(item);
clearChat();
clearStreamChat();
const defaultKey = item?.key
let indexType = 'pinecone'
indexMapping?.findIndex((item) => {
if (item.key == defaultKey) {
indexType = item.iType
setSelectedIndex(item.iType)
setSummary(item.summary)
setQa(item.qa)
setSelectedChunkSize(item.chunkSize)
setSelectedChunkOverlap(item.chunkOverlap)
setSelectedPromptType(item.promptType)
setSelectedPromptTypeItem(promptTypeOptions.find(x => x.key === item.promptType))
updatePrompt(item.promptType)
if (Number(item.chunkSize) > 4000) {
setSelectedDeploymentType(deploymentTypeOptions[1])
} else {
setSelectedDeploymentType(deploymentTypeOptions[0])
}
getCosmosSession(item?.key, item?.iType)
const sampleQuestion = []
const questionList = item.qa.split("\\n")
for (const item of questionList) {
if ((item != '')) {
sampleQuestion.push({
text: item.replace(/^\d+\.\s*/, '').replace('<', '').replace('>', ''),
value: item.replace(/^\d+\.\s*/, '').replace('<', '').replace('>', '')
})
}
}
const generatedExamples: ExampleModel[] = sampleQuestion
setExampleList(generatedExamples)
setExampleLoading(false)
}
})
};
const onSessionClicked = async (sessionFromList: any) => {
//makeApiRequest(sessionFromList.name);
const sessionName = sessionFromList["Session Name"]
setSessionName(sessionName)
setOldSessionName(sessionName)
if (sessionName != "No Session Found") {
try {
await getIndexSession(String(selectedItem?.key), String(selectedIndex), sessionName)
.then(async (sessionResponse:any) => {
const sessionId = sessionResponse[0].sessionId
const newSession: ChatSession = {
id: sessionResponse[0].id,
type: sessionResponse[0].type,
sessionId: sessionResponse[0].sessionId,
name: sessionResponse[0].name,
chainType: sessionResponse[0].chainType,
feature: sessionResponse[0].feature,
indexId: sessionResponse[0].indexId,
indexType: sessionResponse[0].indexType,
indexName: sessionResponse[0].indexName,
llmModel: sessionResponse[0].llmModel,
timestamp: sessionResponse[0].timestamp,
tokenUsed: sessionResponse[0].tokenUsed,
embeddingModelType: sessionResponse[0].embeddingModelType
};
setChatSession(newSession);
await getIndexSessionDetail(sessionId)
.then(async (response:any) => {
const rows = response.reduce(function (rows: any[][], key: any, index: number) {
return (index % 2 == 0 ? rows.push([key])
: rows[rows.length-1].push(key)) && rows;
}, []);
const sessionLists: [string, AskResponse, string | null][] = [];
for (const session of rows)
{
sessionLists.push([session[0].content, session[1].content, null]);
}
lastQuestionRef.current = sessionLists[sessionLists.length - 1][0];
setAnswers(sessionLists);
})
})
} catch (e) {
setError(e);
} finally {
setIsLoading(false);
}
}
}
const onSessionGptClicked = async (sessionFromList: any) => {
//makeApiRequest(sessionFromList.name);
const sessionName = sessionFromList["Session Name"]
setSessionNameGpt(sessionName)
setOldSessionNameGpt(sessionName)
if (sessionName != "No Session Found") {
try {
await getIndexSession("chatgpt", "cogsearchvs", sessionName)
.then(async (sessionResponse:any) => {
const sessionId = sessionResponse[0].sessionId
const newSession: ChatSession = {
id: sessionResponse[0].id,
type: sessionResponse[0].type,
sessionId: sessionResponse[0].sessionId,
name: sessionResponse[0].name,
chainType: sessionResponse[0].chainType,
feature: sessionResponse[0].feature,
indexId: sessionResponse[0].indexId,
indexType: sessionResponse[0].indexType,
indexName: sessionResponse[0].indexName,
llmModel: sessionResponse[0].llmModel,
timestamp: sessionResponse[0].timestamp,
tokenUsed: sessionResponse[0].tokenUsed,
embeddingModelType: sessionResponse[0].embeddingModelType
};
setChatSessionGpt(newSession);
await getIndexSessionDetail(sessionId)
.then(async (response:any) => {
const rows = response.reduce(function (rows: any[][], key: any, index: number) {
return (index % 2 == 0 ? rows.push([key])
: rows[rows.length-1].push(key)) && rows;
}, []);
const sessionLists: [string, string, string | null][] = [];
for (const session of rows)
{
sessionLists.push([session[0].content, session[1].content, null]);
}
lastQuestionRefGpt.current = sessionLists[sessionLists.length - 1][0];
setAnswersGpt(sessionLists);
})
})
} catch (e) {
setError(e);
} finally {
setIsLoading(false);
}
}
}
const updatePrompt = (promptType: string) => {
const genericPrompt = `Given the following extracted parts of a long document and a question, create a final answer.
If you don't know the answer, just say that you don't know. Don't try to make up an answer.
If the answer is not contained within the text below, say \"I don't know\".
{context}
Question: {question}
`
// const contractPrompt = `You are a legal assistant AI trained to help users understand and retrieve information from legal documents,
// such as Contracts, Statements of Work, Non-Disclosure Agreements, and Master Service Agreements.
// Your goal is to assist users by accurately extracting information from the provided documents and explaining the meaning of sections or
// terms when asked.
// You cannot offer legal advice, opinions, or recommendations. If the user asks for legal advice or interpretation, remind them to
// consult a qualified legal professional. You must also ensure that sensitive or confidential information is handled with the utmost care,
// and any requests to misuse, alter, or bypass legal terms must be blocked.
// Always maintain professionalism, avoid ambiguous interpretations, and adhere strictly to the content of the documents.
// {context}
// Question: {question}`
// const contractPrompt = `You are an AI expert specialized in contract analysis and advisory services.
// Your goal is to assist users by providing precise and helpful answers based on a contract document.
// The document in question is an Advisory Services Agreement.
// Given the user query, generate a well-structured and informative response by extracting relevant information from the document.
// Ensure the response is concise, accurate, and directly addresses the query.
// {context}
// Question: {question}
// `
const contractPrompt = `You are a legal expert tasked with acting as the best lawyer and contract analyzer.
Your task is to thoroughly understand the provided context and answer questions related to legal matters, contracts, and relevant laws.
If the necessary information is not present in the context use the given context, then get related contexts and answer the question.
If the question cannot be answered, respond with "I don't know.".
If the question can be answered as either yes or no, respond with either "Yes," or "No," and include the explanation in your response.
In addition, please include the referenced sections in your response.
You must provide accurate responses based solely on the information provided in the context only. Please use the following context only:
{context}
Question: {question}
`
const medicalPrompt = `You are an AI assistant tasked with answering questions and summarizing information from medical records documents.
Your answer should accurately capture the key information in the document while avoiding the omission of any domain-specific words.
Please generate a concise and comprehensive information that includes details such as patient information, medical history,
allergies, chronic conditions, previous surgeries, prescribed medications, and upcoming appointments.
Ensure that it is easy to understand for healthcare professionals and provides an accurate representation of the patient's medical history
and current health status.
Begin with a brief introduction of the patient, followed by the main points of their medical records.
Please remember to use clear language and maintain the integrity of the original information without missing any important details
{context}
Question: {question}
`
const financialPrompt = `You are an AI assistant tasked with answering questions and summarizing information from
earning call transcripts, annual reports, SEC filings and financial statements.
Your answer should accurately capture the key information in the document while avoiding the omission of any domain-specific words.
Please generate a concise and comprehensive information that includes details such as reporting year and amount in millions.
Ensure that it is easy to understand for business professionals and provides an accurate representation of the financial statement history.
Please remember to use clear language and maintain the integrity of the original information without missing any important details
QUESTION: {question}
=========
{context}
=========
`
const financialTablePrompt = `You are an AI assistant tasked with answering questions and summarizing information from
financial statements like income statement, cashflow and balance sheets.
Additionally you may also be asked to answer questions about financial ratios and other financial metrics.
The data that you are presented will be in table format or structure.
Your answer should accurately capture the key information in the document while avoiding the omission of any domain-specific words.
Please generate a concise and comprehensive information that includes details such as reporting year and amount in millions.
Ensure that it is easy to understand for business professionals and provides an accurate representation of the financial statement history.
Please remember to use clear language and maintain the integrity of the original information without missing any important details
QUESTION: {question}
=========
{context}
=========
`
const prospectusPrompt = `"""You are an AI assistant tasked with summarizing documents from large documents that contains information about Initial Public Offerings.
IPO document contains sections with information about the company, its business, strategies, risk, management structure, financial, and other information.
Your summary should accurately capture the key information in the document while avoiding the omission of any domain-specific words.
Please remember to use clear language and maintain the integrity of the original information without missing any important details:
QUESTION: {question}
=========
{context}
=========
"""`
const productDocMdPrompt = `"""You are an AI assistant tasked with answering questions and summarizing information for
product or service from documentations and knowledge base.
Your answer should accurately capture the key information in the document while avoiding the omission of any domain-specific words.
Please generate a concise and comprehensive information that includes details about the product or service.
Please remember to use clear language and maintain the integrity of the original information without missing any important details
QUESTION: {question}
=========
{context}
=========
"""`
if (promptType == "generic") {
setPromptTemplate(genericPrompt)
}
else if (promptType == 'contract')
{
setPromptTemplate(contractPrompt)
}
else if (promptType == "medical") {
setPromptTemplate(medicalPrompt)
} else if (promptType == "financial") {
setPromptTemplate(financialPrompt)
} else if (promptType == "financialtable") {
setPromptTemplate(financialTablePrompt)
} else if (promptType == "prospectus") {
setPromptTemplate(prospectusPrompt)
} else if (promptType == "productdocmd") {
setPromptTemplate(productDocMdPrompt)
} else if (promptType == "custom") {
setPromptTemplate("")
}
}
const updatePromptGpt = (promptType: string) => {
const linuxTerminal = `i want you to act as a linux terminal. I will type commands and you will reply with
what the terminal should show. I want you to only reply with the terminal output inside one unique code block,
and nothing else. do not write explanations. do not type commands unless I instruct you to do so.
when i need to tell you something in english, i will do so by putting text inside curly brackets {like this}.
my first command is pwd
`
const accountant = `I want you to act as an accountant and come up with creative ways to manage finances.
You'll need to consider budgeting, investment strategies and risk management when creating a financial plan
for your client. In some cases, you may also need to provide advice on taxation laws and regulations in
order to help them maximize their profits.
My first suggestion request is "Create a financial plan for a small business that focuses on cost savings and long-term investments".
`
const realEstateAgent = `I want you to act as a real estate agent. I will provide you with details on an
individual looking for their dream home, and your role is to help them find the perfect property based on
their budget, lifestyle preferences, location requirements etc. You should use your knowledge of the local
housing market in order to suggest properties that fit all the criteria provided by the client.
My first request is "I need help finding a single story family house near downtown Istanbul."
`
const careerCounseler = `I want you to act as a career counselor. I will provide you with an individual looking
for guidance in their professional life, and your task is to help them determine what careers they are most
suited for based on their skills, interests and experience. You should also conduct research into the various
options available, explain the job market trends in different industries and advice on which qualifications
would be beneficial for pursuing particular fields.
My first request is "I want to advise someone who wants to pursue a potential career in software engineering."
`
const personalTrainer = `I want you to act as a personal trainer. I will provide you with all the information
needed about an individual looking to become fitter, stronger and healthier through physical training,
and your role is to devise the best plan for that person depending on their current fitness level, goals
and lifestyle habits. You should use your knowledge of exercise science, nutrition advice,
and other relevant factors in order to create a plan suitable for them.
My first request is “I need help designing an exercise program for someone who wants to lose weight.”
`
if (promptType == "linuxTerminal") {
setPromptTemplateGpt(linuxTerminal)
makeApiRequestGpt(linuxTerminal)
}
else if (promptType == "accountant") {
setPromptTemplateGpt(accountant)
makeApiRequestGpt(accountant)
} else if (promptType == "realEstateAgent") {
setPromptTemplateGpt(realEstateAgent)
makeApiRequestGpt(realEstateAgent)
} else if (promptType == "careerCounseler") {
setPromptTemplateGpt(careerCounseler)
makeApiRequestGpt(careerCounseler)
} else if (promptType == "personalTrainer") {
setPromptTemplateGpt(personalTrainer)
makeApiRequestGpt(personalTrainer)
} else if (promptType == "custom") {
setPromptTemplateGpt("")
}
}
useEffect(() => {
if (window.location.hostname != "localhost") {
getUserInfoList();
setShowAuthMessage(true)
} else
setShowAuthMessage(false)
setOptions([])
refreshBlob()
setChainTypeOptions(chainType)
setSelectedChain(chainType[0])
setSelectedEmbeddingItem(embeddingOptions[0])
setSelectedDeploymentType(deploymentTypeOptions[0])
setSelectedEmbeddingItemGpt(embeddingOptions[0])
setSelectedDeploymentTypeGpt(deploymentTypeOptions[0])
setSelectedPromptTypeItem(promptTypeOptions[0])
setSelectedPromptTypeItemGpt(promptTypeGptOptions[0])
}, [])
useEffect(() => chatMessageStreamEnd.current?.scrollIntoView({ behavior: "smooth" }), [isLoading]);
const onPromptTemplateChange = (_ev?: React.FormEvent, newValue?: string) => {
setPromptTemplate(newValue || "");
};
const onPromptTemplateChangeGpt = (_ev?: React.FormEvent, newValue?: string) => {
setPromptTemplateGpt(newValue || "");
};
const onRetrieveCountChange = (_ev?: React.SyntheticEvent, newValue?: string) => {
setRetrieveCount(parseInt(newValue || "3"));
};
const onUseSuggestFollowupQuestionsChange = (_ev?: React.FormEvent, checked?: boolean) => {
setUseSuggestFollowupQuestions(!!checked);
};
const onTemperatureChange = (_ev?: React.SyntheticEvent, newValue?: string) => {
setTemperature(parseInt(newValue || "0.3"));
};
const onTokenLengthChange = (_ev?: React.SyntheticEvent, newValue?: string) => {
setTokenLength(parseInt(newValue || "500"));
};
const onTemperatureChangeGpt = (_ev?: React.SyntheticEvent, newValue?: string) => {
setTemperatureGpt(parseInt(newValue || "0.3"));
};
const onTokenLengthChangeGpt = (_ev?: React.SyntheticEvent, newValue?: string) => {
setTokenLengthGpt(parseInt(newValue || "500"));
};
const onEmbeddingChange = (event?: React.FormEvent, item?: IDropdownOption): void => {
setSelectedEmbeddingItem(item);
};
const onEmbeddingChangeGpt = (event?: React.FormEvent, item?: IDropdownOption): void => {
setSelectedEmbeddingItemGpt(item);
};
const onShowCitation = (citation: string, index: number) => {
if (citation.indexOf('http') > -1 || citation.indexOf('https') > -1) {
window.open(citation.replace('/content/', '').trim(), '_blank');
} else {
if (activeCitation === citation && activeAnalysisPanelTab === AnalysisPanelTabs.CitationTab && selectedAnswer === index) {
setActiveAnalysisPanelTab(undefined);
} else {
setActiveCitation(citation);
setActiveAnalysisPanelTab(AnalysisPanelTabs.CitationTab);
}
}
setSelectedAnswer(index);
};
const handleNewConversationGpt = () => {
const sessId = generateQuickGuid(); //uuidv4();
setSessionIdGpt(sessId);
const newSession: ChatSession = {
id: generateQuickGuid(),
type: 'Session',
sessionId: sessId,
name: sessId,
chainType: 'stuff',
feature: 'chat',
indexId: "chatgpt",
indexType: "cogsearchvs",
indexName: "Chat GPT",
llmModel: 'gpt3.5',
timestamp: String(new Date().getTime()),
tokenUsed: 0,
embeddingModelType: String(selectedEmbeddingItemGpt?.key)
};
setChatSessionGpt(newSession);
return newSession;
};
const handleNewConversation = () => {
const sessId = generateQuickGuid(); //uuidv4();
setSessionId(sessId);
const newSession: ChatSession = {
id: generateQuickGuid(),
type: 'Session',
sessionId: sessId,
name: sessId,
chainType: 'stuff',
feature: 'chat',
indexId: String(selectedItem?.key),
indexType: String(selectedIndex),
indexName: String(selectedItem?.text),
llmModel: 'gpt3.5',
timestamp: String(new Date().getTime()),
tokenUsed: 0,
embeddingModelType: String(selectedEmbeddingItem?.key)
};
setChatSession(newSession);
return newSession;
};
const onDeploymentTypeChange = (event?: React.FormEvent, item?: IDropdownOption): void => {
setSelectedDeploymentType(item);
};
const onDeploymentTypeChangeGpt = (event?: React.FormEvent, item?: IDropdownOption): void => {
setSelectedDeploymentTypeGpt(item);
};
const onPromptTypeChange = (event?: React.FormEvent, item?: IDropdownOption): void => {
setSelectedPromptTypeItem(item);
updatePrompt(String(item?.key));
};
const onPromptTypeChangeGpt = (event?: React.FormEvent, item?: IDropdownOption): void => {
clearChatGpt()
setSelectedPromptTypeItemGpt(item);
updatePromptGpt(String(item?.key));
};
const onFunctionCallChanged = (ev?: React.FormEvent, checked?: boolean): void => {
setFunctionCall(!!checked);
};
const onTabChange = (item?: PivotItem | undefined, ev?: React.MouseEvent | undefined): void => {
if (item?.props.headerText === "Chat On Data") {
getCosmosSession(String(selectedItem?.key), String(selectedIndex))
}
if (item?.props.headerText === "Chat Gpt") {
getCosmosSession("chatgpt", "cogsearchvs")
}
};
const onToggleTab = (tab: AnalysisPanelTabs, index: number) => {
if (activeAnalysisPanelTab === tab && selectedAnswer === index) {
setActiveAnalysisPanelTab(undefined);
} else {
setActiveAnalysisPanelTab(tab);
}
setSelectedAnswer(index);
};
return (
{showAuthMessage ? (
Authentication Not Configured
This app does not have authentication configured. Please add an identity provider by finding your app in the
Azure Portal
and following
these instructions.
Authentication configuration takes a few minutes to apply.
If you deployed in the last 10 minutes, please wait and reload the page after 10 minutes.
) : (
setIsConfigPanelOpen(!isConfigPanelOpen)} />
{selectedItem ?
"Document Name : " + selectedItem.text : undefined}
);
};
export default Help;
================================================
FILE: app/frontend/src/pages/help/README.md
================================================
# ChatGPT + Enterprise data with Azure OpenAI
This accelerator demonstrates a few approaches for creating ChatGPT-like experiences over your own data using the Retrieval Augmented Generation pattern. It uses Azure OpenAI Service to access the ChatGPT model (gpt-35-turbo), and Azure Cognitive Search for data indexing and retrieval.

## Features
- Chat and Q&A interfaces
- Explores various options to help users evaluate the trustworthiness of responses with citations, tracking of source content, etc.
- Shows possible approaches for data preparation, prompt construction, and orchestration of interaction between model (ChatGPT) and retriever (Cognitive Search)
- Settings directly in the UX to tweak the behavior and experiment with options
### Chatting with your own data
The way you interact with large language models like ChatGPT is using natural language, giving the model a “prompt” and requesting it to complete it. This could be a question, a conversation turn, a pattern to extend, etc. When used this way, the responses you get are based on what the model has learned during training, which can be useful for general knowledge questions or an informal chat, but not what you want if you’re building an application where users should see responses based on your own data.
One approach to have ChatGPT generate responses based on your own data is simple: inject this information into the prompt. ChatGPT can read the information along with any instructions, context or questions, and respond accordingly. This approach doesn’t need retraining or fine-tuning of the model, and the responses can reflect any changes in the underlying data immediately.
This presents a new challenge though: these models have a limit on the “context length” they support (the current ChatGPT model can take up to 4000 tokens in a prompt), and even if they didn’t have those limits, it wouldn’t be practical to inject GBs worth of data into a text prompt in each interaction. The alternative is to keep all the data in an external knowledge base that can retrieve pieces quickly and with good relevance, exactly what Cognitive Search & Vector stores are designed for.
This retrieval-augmented generation approach opens the door for starting simple and getting more sophisticated as needed. There are many options for how to construct prompts, how to formulate queries for effective retrieval from the knowledge base, and how to orchestrate back-and-forth interaction between ChatGPT and the knowledge base. Before we dig into those, let’s talk about one more requirement: helping users validate that responses are trustworthy.
#### Generating trustworthy responses
We assume these large language models, prompts, and orchestration systems aren’t perfect, and see the responses generated by them as a candidate response that should include the right information for an end user to validate. As part of exploring this topic we implemented 3 simple experiences as starting points. That’s not to say these are the only ones; we welcome ideas and feedback on the best way to give users better tools to validate that results from the system are factually correct.
- Citations: Each statement in the response includes a citation with a link to the source content. You can see the citations in context (the superscript numbers) as well as the links at the bottom. When you click on one, we display the original content so the user can inspect it.
- Supporting content: Each response or chat bubble generated by ChatGPT has an option (notebook icon) for displaying all the original content that was fed into the prompt as facts.
- Orchestration process: Also present in each response or chat bubble, we include an option (lightbulb icon) to see the entire interaction process, including intermediate results and generated prompts.
================================================
FILE: app/frontend/src/pages/layout/Layout.module.css
================================================
.layout {
display: flex;
flex-direction: column;
height: 100%;
}
.header {
background-color: #222222;
color: #f2f2f2;
}
.headerContainer {
display: flex;
align-items: center;
justify-content: space-around;
margin-right: 12px;
margin-left: 12px;
}
.headerTitleContainer {
display: flex;
align-items: center;
margin-right: 40px;
color: #f2f2f2;
text-decoration: none;
}
.headerLogo {
height: 40px;
}
.headerTitle {
margin-left: 12px;
font-weight: 600;
}
.headerNavList {
display: flex;
list-style: none;
padding-left: 0;
}
.headerNavPageLink {
color: #f2f2f2;
text-decoration: none;
opacity: 0.75;
transition-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
transition-duration: 500ms;
transition-property: opacity;
}
.headerNavPageLink:hover {
opacity: 1;
}
.headerNavPageLinkActive {
color: #f2f2f2;
text-decoration: none;
}
.headerNavLeftMargin {
margin-left: 20px;
}
.headerRightText {
font-weight: normal;
margin-left: 40px;
}
.microsoftLogo {
height: 23px;
font-weight: 600;
}
.githubLogo {
height: 20px;
}
================================================
FILE: app/frontend/src/pages/layout/Layout.tsx
================================================
import { useRef, useState, useEffect } from "react";
import { Outlet, NavLink, Link } from "react-router-dom";
import github from "../../assets/github.svg"
import styles from "./Layout.module.css";
import { SettingsButton } from "../../components/SettingsButton/SettingsButton";
const Layout = () => {
const [isConfigPanelOpen, setIsConfigPanelOpen] = useState(false);
return (
Chat and Ask
Azure OpenAI
);
};
export default Layout;
================================================
FILE: app/frontend/src/pages/oneshot/OneShot.module.css
================================================
.oneshotContainer {
/* display: flex; */
flex: 1;
flex-direction: column;
align-items: center;
}
.oneshotTopSection {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
.oneshotBottomSection {
display: flex;
flex: 1;
flex-wrap: wrap;
justify-content: center;
align-content: flex-start;
width: 100%;
margin-top: 10px;
}
.oneshotTitle {
font-size: 1rem;
font-weight: 600;
margin-top: 1px;
}
@media only screen and (max-width: 800px) {
.oneshotTitle {
font-size: 3rem;
font-weight: 600;
margin-top: 0;
}
}
.oneshotQuestionInput {
max-width: 800px;
width: 100%;
padding-left: 5px;
padding-right: 5px;
}
.oneshotAnswerContainer {
max-width: 800px;
width: 100%;
padding-left: 10px;
padding-right: 10px;
}
.oneshotAnalysisPanel {
width: 600px;
margin-left: 20px;
}
.oneshotSettingsSeparator {
margin-top: 15px;
}
.settingsButton {
align-self: flex-end;
margin-right: 20px;
margin-top: 20px;
}
.container {
flex: 1;
display: flex;
flex-direction: column;
margin-top: 20px;
}
.chatRoot {
flex: 1;
display: flex;
}
.chatContainer {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
.chatEmptyState {
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
max-height: 1024px;
padding-top: 60px;
}
.chatEmptyStateTitle {
font-size: 2rem;
font-weight: 600;
margin-top: 0;
margin-bottom: 10px;
}
.chatEmptyStateSubtitle {
font-weight: 600;
margin-bottom: 5px;
}
@media only screen and (max-height: 780px) {
.chatEmptyState {
padding-top: 0;
}
.chatEmptyStateTitle {
font-size: 3rem;
margin-bottom: 0px;
}
}
.chatMessageStream {
flex-grow: 1;
max-height: 1024px;
max-width: 1028px;
width: 100%;
overflow-y: auto;
padding-left: 24px;
padding-right: 24px;
display: flex;
flex-direction: column;
}
.chatMessageGpt {
margin-bottom: 20px;
max-width: 80%;
display: flex;
min-width: 500px;
}
.chatMessageGptMinWidth {
max-width: 500px;
margin-bottom: 20px;
}
.chatInput {
position: sticky;
bottom: 0;
flex: 0 0 100px;
padding-top: 12px;
padding-bottom: 24px;
padding-left: 24px;
padding-right: 24px;
width: 100%;
max-width: 1028px;
background: #f2f2f2;
}
.chatAnalysisPanel {
flex: 1;
overflow-y: auto;
max-height: 89vh;
margin-left: 20px;
margin-right: 20px;
}
.chatSettingsSeparator {
margin-top: 15px;
}
.loadingLogo {
font-size: 28px;
}
.commandsContainer {
display: flex;
align-self: flex-start;
}
.commandButton {
margin-right: 20px;
margin-bottom: 20px;
}
.example {
word-break: break-word;
background: #dbdbdb;
border-radius: 8px;
display: flex;
flex-direction: column;
padding: 10px;
margin-bottom: 2px;
cursor: pointer;
}
.example:hover {
box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.14), 0px 0px 2px rgba(0, 0, 0, 0.12);
outline: 2px solid rgba(115, 118, 225, 1);
}
.exampleText {
margin: 0;
font-size: 12px;
width: 750px;
height: 120px;
}
.fullText {
margin: 0;
font-size: 12px;
width: 100%;
}
================================================
FILE: app/frontend/src/pages/oneshot/OneShot.tsx
================================================
import { useRef, useState, useEffect } from "react";
import { Checkbox, ChoiceGroup, IChoiceGroupOption, Panel, DefaultButton, Spinner, TextField, SpinButton, Stack} from "@fluentui/react";
import { ShieldLockRegular } from "@fluentui/react-icons";
import styles from "./OneShot.module.css";
import { Dropdown, IDropdownStyles, IDropdownOption } from '@fluentui/react/lib/Dropdown';
import { askApi, Approaches, AskResponse, AskRequest, refreshIndex, getSpeechApi,
refreshQuestions, getUserInfo, SearchTypes } from "../../api";
import { Answer, AnswerError } from "../../components/Answer";
import { QuestionInput } from "../../components/QuestionInput";
import { AnalysisPanel, AnalysisPanelTabs } from "../../components/AnalysisPanel";
import { Label } from '@fluentui/react/lib/Label';
import { ExampleList, ExampleModel } from "../../components/Example";
import { SettingsButton } from "../../components/SettingsButton/SettingsButton";
import { QuestionListButton } from "../../components/QuestionListButton/QuestionListButton";
import { ClearChatButton } from "../../components/ClearChatButton";
import { Pivot, PivotItem } from '@fluentui/react';
import { DetailsList, DetailsListLayoutMode, SelectionMode, ConstrainMode } from '@fluentui/react/lib/DetailsList';
import { mergeStyleSets } from '@fluentui/react/lib/Styling';
var audio = new Audio();
const OneShot = () => {
const [isConfigPanelOpen, setIsConfigPanelOpen] = useState(false);
const [isQuestionPanelOpen, setIsQuestionPanelOpen] = useState(false);
const [approach, setApproach] = useState(Approaches.RetrieveThenRead);
const [searchTypeOptions, setSearchTypeOptions] = useState(SearchTypes.Similarity);
const [promptTemplate, setPromptTemplate] = useState("");
const [promptTemplatePrefix, setPromptTemplatePrefix] = useState("");
const [promptTemplateSuffix, setPromptTemplateSuffix] = useState("");
const [retrieveCount, setRetrieveCount] = useState(3);
const [temperature, setTemperature] = useState(0);
const [tokenLength, setTokenLength] = useState(500);
const [useSemanticRanker, setUseSemanticRanker] = useState(true);
const [useSemanticCaptions, setUseSemanticCaptions] = useState(false);
const [useSuggestFollowupQuestions, setUseSuggestFollowupQuestions] = useState(true);
const [useAutoSpeakAnswers, setUseAutoSpeakAnswers] = useState(false);
const [options, setOptions] = useState([])
const [selectedItem, setSelectedItem] = useState();
const dropdownStyles: Partial = { dropdown: { width: 300 } };
const lastQuestionRef = useRef("");
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState();
const [answer, setAnswer] = useState<[AskResponse, string | null]>();
const [activeCitation, setActiveCitation] = useState();
const [activeAnalysisPanelTab, setActiveAnalysisPanelTab] = useState(undefined);
const [selectedChain, setSelectedChain] = useState();
//const [selectedIndex, setSelectedIndex] = useState();
const [selectedIndex, setSelectedIndex] = useState();
const [indexMapping, setIndexMapping] = useState<{ key: string; iType: string; summary:string; qa:string; chunkSize:string; chunkOverlap:string; promptType:string}[]>();
const [exampleList, setExampleList] = useState([{text:'', value: ''}]);
const [summary, setSummary] = useState();
const [qa, setQa] = useState('');
const [exampleLoading, setExampleLoading] = useState(false)
const [chainTypeOptions, setChainTypeOptions] = useState([])
const [filteredOptions, setFilteredOptions] = useState([])
const [selectedindexTypeItem, setSelectedindexTypeItem] = useState();
const [selectedIndexes, setSelectedIndexes] = useState<{ indexNs: string; indexName: any; returnDirect: string; }[]>([]);
const [isSpeaking, setIsSpeaking] = useState(false);
const [selectedEmbeddingItem, setSelectedEmbeddingItem] = useState();
const [questionList, setQuestionList] = useState();
const [selectedChunkSize, setSelectedChunkSize] = useState()
const [selectedChunkOverlap, setSelectedChunkOverlap] = useState()
const [selectedPromptType, setSelectedPromptType] = useState()
const [selectedDeploymentType, setSelectedDeploymentType] = useState();
const [selectedPromptTypeItem, setSelectedPromptTypeItem] = useState();
const [showAuthMessage, setShowAuthMessage] = useState(false);
const classNames = mergeStyleSets({
header: {
margin: 0,
},
row: {
flex: '0 0 auto',
},
focusZone: {
height: '100%',
overflowY: 'auto',
overflowX: 'hidden',
},
selectionZone: {
height: '100%',
overflow: 'hidden',
},
});
const focusZoneProps = {
className: classNames.focusZone,
'data-is-scrollable': 'true',
} as React.HTMLAttributes;
const embeddingOptions = [
{
key: 'azureopenai',
text: 'Azure Open AI'
},
{
key: 'openai',
text: 'Open AI'
}
// {
// key: 'local',
// text: 'Local Embedding'
// }
]
const promptTypeOptions = [
{
key: 'generic',
text: 'generic'
},
{
key: 'medical',
text: 'medical'
},
{
key: 'financial',
text: 'financial'
},
{
key: 'financialtable',
text: 'financialtable'
},
{
key: 'prospectus',
text: 'prospectus'
},
{
key: 'productdocmd',
text: 'productdocmd'
},
{
key: 'insurance',
text: 'insurance'
}
]
const deploymentTypeOptions = [
{
key: 'gpt35',
text: 'GPT 3.5 Turbo'
},
{
key: 'gpt3516k',
text: 'GPT 3.5 Turbo - 16k'
}
]
const indexTypeOptions = [
{
key: 'pinecone',
text: 'Pinecone'
},
{
key: 'redis',
text: 'Redis Stack'
}
// {
// key: 'chroma',
// text: 'Chroma'
// }
]
const questionListColumn = [
{
key: 'question',
name: 'Question',
fieldName: 'question',
minWidth: 100, maxWidth: 200, isResizable: true
}
]
const chainType = [
{ key: 'stuff', text: 'Stuff'},
{ key: 'map_rerank', text: 'Map ReRank' },
{ key: 'map_reduce', text: 'Map Reduce' },
{ key: 'refine', text: 'Refine'},
]
const getUserInfoList = async () => {
const userInfoList = await getUserInfo();
if (userInfoList.length === 0 && window.location.hostname !== "localhost") {
setShowAuthMessage(true);
}
else {
setShowAuthMessage(false);
}
}
const refreshFilteredBlob = async(selectedIndex : string) => {
const files = []
const indexType = []
//const blobs = containerClient.listBlobsFlat(listOptions)
const blobs = await refreshIndex()
for (const blob of blobs.values) {
if (blob.embedded == "true" && blob.indexType == selectedIndex)
{
files.push({
text: blob.indexName,
key: blob.namespace
})
indexType.push({
key:blob.namespace,
iType:blob.indexType,
summary:blob.summary,
qa:blob.qa,
chunkSize:blob.chunkSize,
chunkOverlap:blob.chunkOverlap,
promptType:blob.promptType
})
}
}
var uniqFiles = files.filter((v,i,a)=>a.findIndex(v2=>(v2.key===v.key))===i)
setFilteredOptions(uniqFiles)
}
const makeApiRequest = async (question: string) => {
lastQuestionRef.current = question;
error && setError(undefined);
setIsLoading(true);
setActiveCitation(undefined);
setActiveAnalysisPanelTab(undefined);
try {
const request: AskRequest = {
question,
approach,
overrides: {
promptTemplate: promptTemplate.length === 0 ? undefined : promptTemplate,
promptTemplatePrefix: promptTemplatePrefix.length === 0 ? undefined : promptTemplatePrefix,
promptTemplateSuffix: promptTemplateSuffix.length === 0 ? undefined : promptTemplateSuffix,
top: retrieveCount,
temperature: temperature,
semanticRanker: useSemanticRanker,
semanticCaptions: useSemanticCaptions,
chainType: String(selectedChain?.key),
tokenLength: tokenLength,
suggestFollowupQuestions: useSuggestFollowupQuestions,
autoSpeakAnswers: useAutoSpeakAnswers,
embeddingModelType: String(selectedEmbeddingItem?.key),
deploymentType: String(selectedDeploymentType?.key),
searchType: searchTypeOptions,
}
};
const result = await askApi(request, String(selectedItem?.key), String(selectedIndex), 'stuff');
setAnswer([result, null]);
if(useAutoSpeakAnswers) {
const speechUrl = await getSpeechApi(result.answer);
setAnswer([result, speechUrl]);
startSynthesis("Answer", speechUrl);
}
} catch (e) {
setError(e);
} finally {
setIsLoading(false);
}
};
const startSynthesis = async (answerType: string, url: string | null) => {
if(isSpeaking) {
audio.pause();
setIsSpeaking(false);
}
if(url === null) {
let speechAnswer;
if (answerType == "Answer")
speechAnswer = answer && answer[0].answer;
const speechUrl = await getSpeechApi(speechAnswer || '');
if (speechUrl === null) {
return;
}
audio = new Audio(speechUrl);
audio.play();
setIsSpeaking(true);
audio.addEventListener('ended', () => {
setIsSpeaking(false);
});
} else {
audio = new Audio(url);
audio.play();
setIsSpeaking(true);
audio.addEventListener('ended', () => {
setIsSpeaking(false);
});
}
};
const onEmbeddingChange = (event?: React.FormEvent, item?: IDropdownOption): void => {
if (item?.key === "openai") {
setSelectedDeploymentType(deploymentTypeOptions[0]);
}
setSelectedEmbeddingItem(item);
};
const onDeploymentTypeChange = (event?: React.FormEvent, item?: IDropdownOption): void => {
setSelectedDeploymentType(item);
};
const stopSynthesis = () => {
audio.pause();
setIsSpeaking(false);
};
const onEnableAutoSpeakAnswersChange = (_ev?: React.FormEvent, checked?: boolean) => {
setUseAutoSpeakAnswers(!!checked);
};
const onPromptTemplateChange = (_ev?: React.FormEvent, newValue?: string) => {
setPromptTemplate(newValue || "");
};
const onUseSuggestFollowupQuestionsChange = (_ev?: React.FormEvent, checked?: boolean) => {
setUseSuggestFollowupQuestions(!!checked);
};
const onRetrieveCountChange = (_ev?: React.SyntheticEvent, newValue?: string) => {
setRetrieveCount(parseInt(newValue || "3"));
};
const onTemperatureChange = (_ev?: React.SyntheticEvent, newValue?: string) => {
setTemperature(parseInt(newValue || "0.3"));
};
const onTokenLengthChange = (_ev?: React.SyntheticEvent, newValue?: string) => {
setTokenLength(parseInt(newValue || "1000"));
};
const onSearchTypeChange = (_ev?: React.FormEvent, option?: IChoiceGroupOption) => {
setSearchTypeOptions((option?.key as SearchTypes) || SearchTypes.Similarity);
};
const onExampleClicked = (example: string) => {
makeApiRequest(example);
};
const onShowCitation = (citation: string) => {
if (citation.indexOf('http') > -1 || citation.indexOf('https') > -1) {
window.open(citation.replace('/content/', ''), '_blank');
} else {
if (activeCitation === citation && activeAnalysisPanelTab === AnalysisPanelTabs.CitationTab) {
setActiveAnalysisPanelTab(undefined);
} else {
setActiveCitation(citation);
setActiveAnalysisPanelTab(AnalysisPanelTabs.CitationTab);
}
}
};
const onToggleTab = (tab: AnalysisPanelTabs) => {
if (activeAnalysisPanelTab === tab) {
setActiveAnalysisPanelTab(undefined);
} else {
setActiveAnalysisPanelTab(tab);
}
};
const onPromptTypeChange = (event?: React.FormEvent, item?: IDropdownOption): void => {
setSelectedPromptTypeItem(item);
updatePrompt(String(item?.key));
};
const refreshBlob = async () => {
const files = []
const indexType = []
//const blobs = containerClient.listBlobsFlat(listOptions)
const blobs = await refreshIndex()
for (const blob of blobs.values) {
if (blob.embedded == "true")
{
files.push({
text: blob.indexName,
key: blob.namespace
})
indexType.push({
key:blob.namespace,
iType:blob.indexType,
summary:blob.summary,
qa:blob.qa == null ? '' : blob.qa,
chunkSize:blob.chunkSize,
chunkOverlap:blob.chunkOverlap,
promptType:blob.promptType
})
}
}
var uniqFiles = files.filter((v,i,a)=>a.findIndex(v2=>(v2.key===v.key))===i)
setOptions(uniqFiles)
setSelectedItem(uniqFiles[0])
const defaultKey = uniqFiles[0].key
var uniqIndexType = indexType.filter((v,i,a)=>a.findIndex(v2=>(v2.key===v.key))===i)
for (const item of uniqIndexType) {
if (item.key == defaultKey) {
setSelectedIndex(item.iType)
setSummary(item.summary)
setQa(item.qa)
setSelectedChunkOverlap(item.chunkOverlap)
setSelectedChunkSize(item.chunkSize)
setSelectedPromptType(item.promptType)
setSelectedPromptTypeItem(promptTypeOptions.find(x => x.key === item.promptType))
updatePrompt(item.promptType)
if (Number(item.chunkSize) > 4000) {
setSelectedDeploymentType(deploymentTypeOptions[1])
} else {
setSelectedDeploymentType(deploymentTypeOptions[0])
}
const sampleQuestion = []
const questionList = item.qa.split("\\n")
for (const item of questionList) {
if ((item != '')) {
sampleQuestion.push({
text: item.replace(/^\d+\.\s*/, '').replace('<', '').replace('>', ''),
value: item.replace(/^\d+\.\s*/, '').replace('<', '').replace('>', ''),
})
}
}
const generatedExamples: ExampleModel[] = sampleQuestion
setExampleList(generatedExamples)
setExampleLoading(false)
}
}
setIndexMapping(uniqIndexType)
}
const clickRefreshQuestions = async () => {
setIsQuestionPanelOpen(!isQuestionPanelOpen)
await refreshQuestionList()
}
const refreshQuestionList = async () => {
let questionList
if (selectedIndex == undefined) {
questionList = await refreshQuestions(selectedIndexes[0].indexName, selectedIndexes[0].indexNs)
}
else
questionList = await refreshQuestions(String(selectedIndex), String(selectedItem?.key))
const sampleQuestionList = []
for (const question of questionList.values) {
sampleQuestionList.push({
question: question.question,
});
}
setQuestionList(sampleQuestionList)
}
const updatePrompt = (promptType: string) => {
const genericPrompt = `Given the following extracted parts of a long document and a question, create a final answer.
If you don't know the answer, just say that you don't know. Don't try to make up an answer.
If the answer is not contained within the text below, say \"I don't know\".
{context}
Question: {question}
`
const contractPrompt = `You are a legal expert tasked with acting as the best lawyer and contract analyzer.
Your task is to thoroughly understand the provided context and answer questions related to legal matters, contracts, and relevant laws.
If the necessary information is not present in the context use the given context, then get related contexts and answer the question.
If the question cannot be answered, respond with "I don't know.".
If the question can be answered as either yes or no, respond with either "Yes," or "No," and include the explanation in your response.
In addition, please include the referenced sections in your response.
You must provide accurate responses based solely on the information provided in the context only. Please use the following context only:
{context}
Question: {question}
`
const medicalPrompt = `You are an AI assistant tasked with answering questions and summarizing information from medical records documents.
Your answer should accurately capture the key information in the document while avoiding the omission of any domain-specific words.
Please generate a concise and comprehensive information that includes details such as patient information, medical history,
allergies, chronic conditions, previous surgeries, prescribed medications, and upcoming appointments.
Ensure that it is easy to understand for healthcare professionals and provides an accurate representation of the patient's medical history
and current health status.
Begin with a brief introduction of the patient, followed by the main points of their medical records.
Please remember to use clear language and maintain the integrity of the original information without missing any important details
{context}
Question: {question}
`
const financialPrompt = `You are an AI assistant tasked with answering questions and summarizing information from
earning call transcripts, annual reports, SEC filings and financial statements.
Your answer should accurately capture the key information in the document while avoiding the omission of any domain-specific words.
Please generate a concise and comprehensive information that includes details such as reporting year and amount in millions.
Ensure that it is easy to understand for business professionals and provides an accurate representation of the financial statement history.
Please remember to use clear language and maintain the integrity of the original information without missing any important details
QUESTION: {question}
=========
{context}
=========
`
const financialTablePrompt = `You are an AI assistant tasked with answering questions and summarizing information from
financial statements like income statement, cashflow and balance sheets.
Additionally you may also be asked to answer questions about financial ratios and other financial metrics.
The data that you are presented will be in table format or structure.
Your answer should accurately capture the key information in the document while avoiding the omission of any domain-specific words.
Please generate a concise and comprehensive information that includes details such as reporting year and amount in millions.
Ensure that it is easy to understand for business professionals and provides an accurate representation of the financial statement history.
Please remember to use clear language and maintain the integrity of the original information without missing any important details
QUESTION: {question}
=========
{context}
=========
`
const prospectusPrompt = `"""You are an AI assistant tasked with summarizing documents from large documents that contains information about Initial Public Offerings.
IPO document contains sections with information about the company, its business, strategies, risk, management structure, financial, and other information.
Your summary should accurately capture the key information in the document while avoiding the omission of any domain-specific words.
Please remember to use clear language and maintain the integrity of the original information without missing any important details:
QUESTION: {question}
=========
{context}
=========
"""`
const productDocMdPrompt = `"""You are an AI assistant tasked with answering questions and summarizing information for
product or service from documentations and knowledge base.
Your answer should accurately capture the key information in the document while avoiding the omission of any domain-specific words.
Please generate a concise and comprehensive information that includes details about the product or service.
Please remember to use clear language and maintain the integrity of the original information without missing any important details
QUESTION: {question}
=========
{context}
=========
"""`
if (promptType == "generic") {
setPromptTemplate(genericPrompt)
}
else if (promptType == 'contract')
{
setPromptTemplate(contractPrompt)
}
else if (promptType == "medical") {
setPromptTemplate(medicalPrompt)
} else if (promptType == "financial") {
setPromptTemplate(financialPrompt)
} else if (promptType == "financialtable") {
setPromptTemplate(financialTablePrompt)
} else if (promptType == "prospectus") {
setPromptTemplate(prospectusPrompt)
} else if (promptType == "productdocmd") {
setPromptTemplate(productDocMdPrompt)
} else if (promptType == "custom") {
setPromptTemplate("")
}
}
const onChange = (event?: React.FormEvent, item?: IDropdownOption): void => {
setSelectedItem(item);
setAnswer(undefined)
const defaultKey = item?.key
indexMapping?.findIndex((item) => {
if (item.key == defaultKey) {
setSelectedIndex(item.iType)
setSelectedChunkSize(item.chunkSize)
setSelectedChunkOverlap(item.chunkOverlap)
setSelectedPromptType(item.promptType)
setSelectedPromptTypeItem(promptTypeOptions.find(x => x.key === item.promptType))
setSummary(item.summary)
setQa(item.qa)
updatePrompt(item.promptType)
if (Number(item.chunkSize) > 4000) {
setSelectedDeploymentType(deploymentTypeOptions[1])
} else {
setSelectedDeploymentType(deploymentTypeOptions[0])
}
const sampleQuestion = []
const questionList = item.qa.split("\\n")
for (const item of questionList) {
if ((item != '')) {
sampleQuestion.push({
text: item.replace(/^\d+\.\s*/, '').replace('<', '').replace('>', ''), //item.replace(/[0-9]./g, ''),
value: item.replace(/^\d+\.\s*/, '').replace('<', '').replace('>', '') //item.replace(/[0-9]./g, ''),
})
}
}
const generatedExamples: ExampleModel[] = sampleQuestion
setExampleList(generatedExamples)
setExampleLoading(false)
}
})
};
const onChainChange = (event: React.FormEvent, item?: IDropdownOption): void => {
setSelectedChain(item);
};
useEffect(() => {
if (window.location.hostname != "localhost") {
getUserInfoList();
setShowAuthMessage(true)
} else
setShowAuthMessage(false)
refreshBlob()
setChainTypeOptions(chainType)
setSelectedChain(chainType[0])
setSelectedindexTypeItem(indexTypeOptions[0])
refreshFilteredBlob(indexTypeOptions[0].key)
setSelectedEmbeddingItem(embeddingOptions[0])
setSelectedDeploymentType(deploymentTypeOptions[0])
}, [])
const approaches: IChoiceGroupOption[] = [
{
key: Approaches.RetrieveThenRead,
text: "Retrieve-Then-Read"
}
];
const searchTypes: IChoiceGroupOption[] = [
{
key: SearchTypes.Similarity,
text: "Similarity"
},
{
key: SearchTypes.Hybrid,
text: "Hybrid"
},
{
key: SearchTypes.HybridReRank,
text: "Hybrid with ReRank"
}
];
const onQuestionClicked = (questionFromList: any) => {
makeApiRequest(questionFromList.question);
}
const clearChat = () => {
lastQuestionRef.current = "";
error && setError(undefined);
setActiveCitation(undefined);
setActiveAnalysisPanelTab(undefined);
setAnswer(undefined);
};
return (
{showAuthMessage ? (
Authentication Not Configured
This app does not have authentication configured. Please add an identity provider by finding your app in the
Azure Portal
and following
these instructions.
Authentication configuration takes a few minutes to apply.
If you deployed in the last 10 minutes, please wait and reload the page after 10 minutes.