Skip to content

Commit

Permalink
Merge pull request microsoft#22 from microsoft/sawidder/public-api
Browse files Browse the repository at this point in the history
Refactor to use public API
  • Loading branch information
sarah-widder authored May 25, 2023
2 parents 8a1ce23 + 820a592 commit 2836a5b
Show file tree
Hide file tree
Showing 12 changed files with 221 additions and 196 deletions.
74 changes: 34 additions & 40 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,54 +35,48 @@ def static_file(path):
AZURE_OPENAI_MAX_TOKENS = os.environ.get("AZURE_OPENAI_MAX_TOKENS", 1000)
AZURE_OPENAI_STOP_SEQUENCE = os.environ.get("AZURE_OPENAI_STOP_SEQUENCE")
AZURE_OPENAI_SYSTEM_MESSAGE = os.environ.get("AZURE_OPENAI_SYSTEM_MESSAGE", "You are an AI assistant that helps people find information.")
AZURE_OPENAI_PREVIEW_API_VERSION = os.environ.get("AZURE_OPENAI_PREVIEW_API_VERSION", "2023-03-31-preview")
AZURE_OPENAI_PREVIEW_API_VERSION = os.environ.get("AZURE_OPENAI_PREVIEW_API_VERSION", "2023-06-01-preview")


def prepare_body_headers_with_data(request):
messages = request.json["messages"]
request_messages = request.json["messages"]

body = {
"messages": messages,
"enable_Indomain": True if AZURE_SEARCH_ENABLE_IN_DOMAIN.lower() == "true" else False,
"azure_document_search_top_k": AZURE_SEARCH_TOP_K,
"messages": request_messages,
"temperature": AZURE_OPENAI_TEMPERATURE,
"max_tokens": AZURE_OPENAI_MAX_TOKENS,
"top_p": AZURE_OPENAI_TOP_P,
"max_tokens": AZURE_OPENAI_MAX_TOKENS
"stop": AZURE_OPENAI_STOP_SEQUENCE.split("|") if AZURE_OPENAI_STOP_SEQUENCE else [],
"stream": False,
"dataSources": [
{
"type": "AzureCognitiveSearch",
"parameters": {
"endpoint": f"https://{AZURE_SEARCH_SERVICE}.search.windows.net",
"key": AZURE_SEARCH_KEY,
"indexName": AZURE_SEARCH_INDEX,
"fieldsMapping": {
"contentField": AZURE_SEARCH_CONTENT_COLUMNS.split("|") if AZURE_SEARCH_CONTENT_COLUMNS else [],
"titleField": AZURE_SEARCH_TITLE_COLUMN if AZURE_SEARCH_TITLE_COLUMN else None,
"urlField": AZURE_SEARCH_URL_COLUMN if AZURE_SEARCH_URL_COLUMN else None,
"filepathField": AZURE_SEARCH_FILENAME_COLUMN if AZURE_SEARCH_FILENAME_COLUMN else None
},
"inScope": True if AZURE_SEARCH_ENABLE_IN_DOMAIN.lower() == "true" else False,
"topNDocuments": AZURE_SEARCH_TOP_K,
"queryType": "semantic" if AZURE_SEARCH_USE_SEMANTIC_SEARCH.lower() == "true" else "simple",
"semanticConfiguration": AZURE_SEARCH_SEMANTIC_SEARCH_CONFIG if AZURE_SEARCH_USE_SEMANTIC_SEARCH.lower() == "true" and AZURE_SEARCH_SEMANTIC_SEARCH_CONFIG else "",
"roleInformation": AZURE_OPENAI_SYSTEM_MESSAGE
}
}
]
}

if AZURE_OPENAI_STOP_SEQUENCE:
sequences = AZURE_OPENAI_STOP_SEQUENCE.split("|")
body["stop"] = sequences

if AZURE_OPENAI_SYSTEM_MESSAGE:
body["system_message"] = AZURE_OPENAI_SYSTEM_MESSAGE

index_column_mapping = {}
if AZURE_SEARCH_CONTENT_COLUMNS:
index_column_mapping["content_column"] = AZURE_SEARCH_CONTENT_COLUMNS.split("|")
if AZURE_SEARCH_FILENAME_COLUMN:
index_column_mapping["filepath_column"] = AZURE_SEARCH_FILENAME_COLUMN
if AZURE_SEARCH_TITLE_COLUMN:
index_column_mapping["title_column"] = AZURE_SEARCH_TITLE_COLUMN
if AZURE_SEARCH_URL_COLUMN:
index_column_mapping["url_column"] = AZURE_SEARCH_URL_COLUMN
if index_column_mapping:
body["index_column_mapping"] = index_column_mapping

azure_openai_url = f"https://{AZURE_OPENAI_RESOURCE}.openai.azure.com/openai/deployments/{AZURE_OPENAI_MODEL}/completions?api-version=2022-12-01"
search_url = f"https://{AZURE_SEARCH_SERVICE}.search.windows.net"


headers = {
"Content-Type": "application/json",
"azure_document_search_url": search_url,
"azure_document_search_api_key": AZURE_SEARCH_KEY,
"azure_document_search_index": AZURE_SEARCH_INDEX,
"chatgpt_url": azure_openai_url,
"chatgpt_key": AZURE_OPENAI_KEY,
"Ocp-Apim-Subscription-Key": AZURE_OPENAI_KEY,
'Content-Type': 'application/json',
'api-key': AZURE_OPENAI_KEY,
"azure_document_search_configuration": AZURE_SEARCH_SEMANTIC_SEARCH_CONFIG if AZURE_SEARCH_USE_SEMANTIC_SEARCH.lower() == "true" and AZURE_SEARCH_SEMANTIC_SEARCH_CONFIG else "",
"azure_document_search_query_type": "semantic" if AZURE_SEARCH_USE_SEMANTIC_SEARCH.lower() == "true" else "simple",
"x-ms-useragent": "GitHubSampleWebApp/2.0.1"
'chatgpt_url': f"https://{AZURE_OPENAI_RESOURCE}.openai.azure.com/openai/deployments/{AZURE_OPENAI_MODEL}/completions?api-version=2023-03-31-preview",
'chatgpt_key': AZURE_OPENAI_KEY,
"x-ms-useragent": "GitHubSampleWebApp/PublicAPI/1.0.0"
}

return body, headers
Expand Down Expand Up @@ -133,7 +127,7 @@ def conversation():
use_data = should_use_data()
if use_data:
body, headers = prepare_body_headers_with_data(request)
endpoint = f"{base_url}/openai/wednesday-private/conversation?api-version={AZURE_OPENAI_PREVIEW_API_VERSION}"
endpoint = f"{base_url}/openai/deployments/{AZURE_OPENAI_MODEL}/extensions/chat/completions?api-version={AZURE_OPENAI_PREVIEW_API_VERSION}"
else:
body, headers = prepare_body_headers_without_data(request)
endpoint = f"{base_url}/openai/deployments/{AZURE_OPENAI_MODEL}/chat/completions?api-version=2023-03-15-preview"
Expand Down
53 changes: 53 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
"dependencies": {
"@fluentui/react": "^8.105.3",
"@fluentui/react-icons": "^2.0.195",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-markdown": "^7.0.1",
Expand All @@ -20,6 +22,7 @@
"remark-supersub": "^1.0.0"
},
"devDependencies": {
"@types/lodash-es": "^4.17.7",
"@types/react": "^18.0.27",
"@types/react-dom": "^18.0.10",
"@vitejs/plugin-react": "^3.1.0",
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/api/api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ChatMessage, ConversationRequest } from "./models";
import { ChatResponse, ConversationRequest } from "./models";

export async function conversationApi(options: ConversationRequest, abortSignal: AbortSignal): Promise<ChatMessage> {
export async function conversationApi(options: ConversationRequest, abortSignal: AbortSignal): Promise<ChatResponse> {
const response = await fetch("/conversation", {
method: "POST",
headers: {
Expand All @@ -12,7 +12,7 @@ export async function conversationApi(options: ConversationRequest, abortSignal:
signal: abortSignal
});

const parsedResponse: ChatMessage = await response.json();
const parsedResponse: ChatResponse = await response.json();

if (response.status > 299 || !response.ok) {
console.log("Error response from /conversation", parsedResponse)
Expand Down
42 changes: 28 additions & 14 deletions frontend/src/api/models.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,49 @@
export type AskResponse = {
answer: string;
thoughts: string | null;
data_points: string[];
top_docs: DocumentResult[];
citations: Citation[];
error?: string;
};

export type MessageContent = {
content_type: string;
parts: string[];
top_docs: DocumentResult[];
intent: string | null;
};

export type DocumentResult = {
export type Citation = {
content: string;
id: string;
title: string | null;
filepath: string | null;
url: string | null;
metadata: string | null;
chunk_id: string | null;
reindex_id: string | null;
}

export type ToolMessageContent = {
citations: Citation[];
intent: string;
}

export type ChatMessage = {
message_id: string;
parent_message_id: string | null;
role: string;
content: MessageContent;
content: string;
end_turn: boolean | null;
};

export enum ChatCompletionType {
ChatCompletion = "chat.completion",
ChatCompletionChunk = "chat.completion.chunk"
}

export type ChatResponseChoice = {
index: number;
messages: ChatMessage[];
}

export type ChatResponse = {
id: string;
model: string;
created: number;
object: ChatCompletionType;
choices: ChatResponseChoice[];
}

export type ConversationRequest = {
messages: ChatMessage[];
};
29 changes: 10 additions & 19 deletions frontend/src/components/Answer/Answer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,26 @@ import { FontIcon, Stack, Text } from "@fluentui/react";

import styles from "./Answer.module.css";

import { AskResponse, DocumentResult } from "../../api";
import { parseAnswerToJsx } from "./AnswerParser";
import { AskResponse, Citation } from "../../api";
import { parseAnswer } from "./AnswerParser";

import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import supersub from 'remark-supersub'

interface Props {
answer: AskResponse;
onCitationClicked: (citedDocument: DocumentResult) => void;
onCitationClicked: (citedDocument: Citation) => void;
}

export const Answer = ({
answer,
onCitationClicked
}: Props) => {
const [isRefAccordionOpen, { toggle: toggleIsRefAccordionOpen }] = useBoolean(false);
const onInlineCitationClicked = () => {
if (!isRefAccordionOpen) {
toggleIsRefAccordionOpen();
}
};

const useMarkdownFormat = true; // set to false to use inline clickable citations without markdown formatting
const filePathTruncationLimit = 50;

const parsedAnswer = useMemo(() => parseAnswerToJsx(answer, onInlineCitationClicked), [answer]);
const parsedAnswer = useMemo(() => parseAnswer(answer), [answer]);
const [chevronIsExpanded, setChevronIsExpanded] = useState(isRefAccordionOpen);

const handleChevronClick = () => {
Expand All @@ -42,7 +35,7 @@ export const Answer = ({
setChevronIsExpanded(isRefAccordionOpen);
}, [isRefAccordionOpen]);

const createCitationFilepath = (citation: DocumentResult, index: number, truncate: boolean = false) => {
const createCitationFilepath = (citation: Citation, index: number, truncate: boolean = false) => {
let citationFilename = "";

if (citation.filepath && citation.chunk_id) {
Expand All @@ -64,13 +57,11 @@ export const Answer = ({
<>
<Stack className={styles.answerContainer}>
<Stack.Item grow>
{useMarkdownFormat ? (
<ReactMarkdown
remarkPlugins={[remarkGfm, supersub]}
children={parsedAnswer.markdownFormatText}
className={styles.answerText}
/> ) : (
<p className={styles.answerText}>{parsedAnswer.answerJsx}</p>)}
<ReactMarkdown
remarkPlugins={[remarkGfm, supersub]}
children={parsedAnswer.markdownFormatText}
className={styles.answerText}
/>
</Stack.Item>
<Stack horizontal className={styles.answerFooter}>
{!!parsedAnswer.citations.length && (
Expand Down
Loading

0 comments on commit 2836a5b

Please sign in to comment.