Skip to content

Commit 98f855c

Browse files
Api changes reverted
1 parent ccc86fe commit 98f855c

File tree

3 files changed

+50
-8799
lines changed

3 files changed

+50
-8799
lines changed

App/frontend-app/src/components/chat/chatRoom.tsx

Lines changed: 12 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,21 @@ import {
99
DialogSurface,
1010
DialogTitle,
1111
Tag,
12-
Tooltip,
1312
makeStyles,
1413
} from "@fluentui/react-components";
1514
import { DocDialog } from "../documentViewer/documentViewer";
1615
import { Textarea } from "@fluentai/textarea";
1716
import type { TextareaSubmitEvents, TextareaValueData } from "@fluentai/textarea";
1817
import { CopilotChat, UserMessage, CopilotMessage } from "@fluentai/react-copilot-chat";
19-
import { ChatAdd24Regular, DocumentOnePageLink20Regular } from "@fluentui/react-icons";
20-
import { AttachmentTag } from "@fluentai/attachments";
18+
import { ChatAdd24Regular } from "@fluentui/react-icons";
2119
import styles from "./chatRoom.module.scss";
22-
import { CopilotProvider, FeedbackButtons, Suggestion } from "@fluentai/react-copilot";
23-
import { Result, SingleDocument, Tokens } from "../../api/apiTypes/singleDocument";
24-
//import { getDocument } from "../../api/documentsService";
20+
import { CopilotProvider, Suggestion } from "@fluentai/react-copilot";
21+
import { Tokens } from "../../api/apiTypes/singleDocument";
2522
import { Completion, PostFeedback } from "../../api/chatService";
2623
import { FeedbackForm } from "./FeedbackForm";
2724
import { Document } from "../../api/apiTypes/documentResults";
2825
import { AppContext } from "../../AppContext";
2926
import { useTranslation } from "react-i18next";
30-
import ReactMarkdown from "react-markdown";
31-
import { renderToStaticMarkup } from "react-dom/server";
3227
import { marked } from 'marked';
3328
const DefaultChatModel = "chat_4o";
3429

@@ -48,12 +43,10 @@ interface ChatRoomProps {
4843
}
4944

5045
export function ChatRoom({ searchResultDocuments, selectedDocuments, chatWithDocument, disableOptionsPanel, clearChatFlag }: ChatRoomProps) {
51-
const customStyles = useStyles();
5246
const { t } = useTranslation();
5347
const [chatSessionId, setChatSessionId] = useState<string | null>(null);
5448
const [isLoading, setIsLoading] = useState<boolean>(false);
5549
const [disableSources, setDisableSources] = useState<boolean>(false);
56-
const [error, setError] = useState<unknown>();
5750
const [model, setModel] = useState<string>("chat_35");
5851
const [source, setSource] = useState<string>("rag");
5952
const [temperature, setTemperature] = useState<number>(0.8);
@@ -105,7 +98,7 @@ export function ChatRoom({ searchResultDocuments, selectedDocuments, chatWithDoc
10598
if (clearChatFlag) {
10699
clearChat();
107100
}
108-
}, [clearChatFlag]); // Runs whenever clearChat changes
101+
}, [clearChatFlag]);
109102

110103

111104

@@ -124,85 +117,30 @@ export function ChatRoom({ searchResultDocuments, selectedDocuments, chatWithDoc
124117

125118
const makeApiRequest = async (question: string) => {
126119
setTextAreaValue("");
127-
//Force Textarea re-render to reset internal showCount
128120
setTextareaKey(prev => prev + 1);
129121
setDisableSources(true);
130122
setIsLoading(true);
131123

132-
// A simple function to check if the text contains Markdown
133-
const isMarkdown = (text: string) => {
134-
const markdownPattern = /(^|\s)(#{1,6}|\*\*|__|[-*]|\d+\.\s|\[.*\]\(.*\)|```|`[^`]*`)/;
135-
return markdownPattern.test(text);
136-
};
137-
138124
const userTimestamp = new Date();
139-
// Ensure we have a chatSessionId or create one if null/undefined
140-
141-
142-
let currentSessionId = chatSessionId; // Get the current value of chatSessionId
125+
126+
let currentSessionId = chatSessionId;
143127
if (!currentSessionId) {
144-
const newSessionId = uuidv4(); // Generate a new UUID if no session exists
145-
setChatSessionId(newSessionId); // Save it for future renders
146-
currentSessionId = newSessionId; // Immediately use the new session ID in this function
147-
128+
const newSessionId = uuidv4();
129+
setChatSessionId(newSessionId);
130+
currentSessionId = newSessionId;
148131
}
149-
const markdownToHtmlString = (markdown: string) => {
150-
return renderToStaticMarkup(<ReactMarkdown>{markdown}</ReactMarkdown>);
151-
};
152-
const markdown = `| Data Point | Value | Document Name | Page Number |
153-
|----------------|-----------|-------------------|------------------|
154-
| Households with accessibility needs | 23.1 million | Accessibility in Housing Report | Page 1 |
155-
| Households with mobility-related disabilities | 19% of U.S. households | Accessibility in Housing Report | Page 1 |
156-
| Households without entry-level bedroom or full bathroom planning to add features | 1% | Accessibility in Housing Report | Page 3 |
157-
| Households planning to make homes more accessible | 5% | Accessibility in Housing Report | Page 3 |
158-
| Households with someone using mobility devices | 13% | Accessibility in Housing Report | Page 1 |
159-
| Households with serious difficulty hearing | 12% | Accessibility in Housing Report | Page 24 |
160-
| Households with serious difficulty seeing | 12% | Accessibility in Housing Report | Page 24 |
161-
| Households with difficulty walking or climbing stairs | 12% | Accessibility in Housing Report | Page 24 |
162-
| Households with difficulty dressing or bathing | 12% | Accessibility in Housing Report | Page 24 |
163-
| Households with difficulty doing errands alone | 12% | Accessibility in Housing Report | Page 24 |
164-
| Households with full bathrooms on entry level | 58% | Accessibility in Housing Report | Page 11 |
165-
| Households with bedrooms on entry level | 46% | Accessibility in Housing Report | Page 11 |
166-
| Total single-family loans acquired by Fannie Mae in 2021 | $2.6 trillion | Annual Housing Report 2022 | Page 36 |
167-
| Total single-family loans acquired by Freddie Mac in 2021 | $2.6 trillion | Annual Housing Report 2022 | Page 36 |
168-
| Percentage of loans with LTV > 95% | 13.5% | Annual Housing Report 2022 | Page 44 |
169-
| Percentage of loans with LTV <= 60% | 15.6% | Annual Housing Report 2022 | Page 44 |
170-
| Total NPLs sold by Enterprises through December 2023 | 168,364 | FHFA Non-Performing Loan Sales Report | Page 2 |
171-
| Average delinquency of NPLs sold | 2.8 years | FHFA Non-Performing Loan Sales Report | Page 2 |
172-
| Average current mark-to-market LTV ratio of NPLs | 83% | FHFA Non-Performing Loan Sales Report | Page 2 |`;
173-
174-
const htmlString = await marked.parse(markdown);
175-
const htmlString2 = markdownToHtmlString(markdown);
176132

177133
setConversationAnswers((prevAnswers) => [
178134
...prevAnswers,
179135
[question, {
180-
answer: t('components.chat.fetching-answer'), suggestingQuestions: [],
136+
answer: t('components.chat.fetching-answer'),
137+
suggestingQuestions: [],
181138
documentIds: [],
182139
keywords: []
183140
}],
184141
]);
185142

186-
187-
188-
189-
190-
let filterByDocumentIds: string[] = [];
191-
192-
193-
const transformDocuments = (documents: any[]) => {
194-
return documents.map(doc => doc.documentId); // Extracting documentId from each document
195-
};
196-
const formattedDocuments = transformDocuments(selectedDocuments);
197-
198-
199-
if (button === "Selected Document" && selectedDocument) {
200-
filterByDocumentIds = [selectedDocument[0].documentId];
201-
} else if (button === "Search Results") {
202-
filterByDocumentIds = searchResultDocuments.map((document) => document.documentId);
203-
} else if (button === "Selected Documents") {
204-
filterByDocumentIds = selectedDocuments.map((document) => document.documentId);
205-
}
143+
const formattedDocuments = selectedDocuments.map(doc => doc.documentId);
206144

207145
try {
208146
const request: ChatRequest = {
@@ -212,24 +150,18 @@ export function ChatRoom({ searchResultDocuments, selectedDocuments, chatWithDoc
212150
};
213151

214152
const response: ChatApiResponse = await Completion(request);
215-
216-
setIsLoading(false);
217-
218153
const answerTimestamp = new Date();
219154

220155
if (response && response.answer) {
221156
const formattedAnswer = removeNewlines(response.answer);
222157
const chatResp = await marked.parse(formattedAnswer);
223158

224-
// Update the conversation with the formatted answer
225159
setConversationAnswers((prevAnswers) => {
226160
const newAnswers = [...prevAnswers];
227161
newAnswers[newAnswers.length - 1] = [question, { ...response, answer: chatResp }, userTimestamp, answerTimestamp];
228162
return newAnswers;
229163
});
230164
} else {
231-
console.error("Invalid response received:", response);
232-
// Update with error message
233165
setConversationAnswers((prevAnswers) => {
234166
const newAnswers = [...prevAnswers];
235167
newAnswers[newAnswers.length - 1] = [question, {
@@ -242,10 +174,6 @@ export function ChatRoom({ searchResultDocuments, selectedDocuments, chatWithDoc
242174
});
243175
}
244176
} catch (error) {
245-
console.error("Error in makeApiRequest:", error);
246-
setIsLoading(false);
247-
248-
// Update conversation with error message
249177
const answerTimestamp = new Date();
250178
setConversationAnswers((prevAnswers) => {
251179
const newAnswers = [...prevAnswers];
@@ -303,21 +231,6 @@ export function ChatRoom({ searchResultDocuments, selectedDocuments, chatWithDoc
303231
}
304232
}
305233

306-
// const handleOpenReference = async (referenceId: string, chunkTexts: string[]) => {
307-
// try {
308-
// const response: SingleDocument = await getDocument(referenceId);
309-
310-
// if (response && response.result) {
311-
// setTokens(response.tokens);
312-
// setIsDialogOpen(true);
313-
// setDialogMetadata(response.result);
314-
// setAllChunkTexts(chunkTexts);
315-
// }
316-
// } catch (error) {
317-
// console.error("Error fetching data: ", error);
318-
// }
319-
// };
320-
321234
const handleOpenFeedbackForm = (sources: Reference[]) => {
322235
setReferencesForFeedbackForm(sources);
323236
setIsFeedbackFormOpen(true);
Lines changed: 38 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,152 +1,68 @@
1-
import { ApiError } from "../../types/apiError";
2-
31
export const httpClient = {
4-
fetch,
52
get,
63
post,
74
put,
85
delete: _delete,
96
download,
107
patch,
118
upload,
12-
fetchRaw,
139
};
1410

15-
export async function fetch<T>(endpoint: RequestInfo, init: RequestInit & { notifyOnError?: boolean } = {}): Promise<T> {
16-
const { notifyOnError, ...config } = init;
17-
18-
try {
19-
// Directly use window.fetch without authFetch
20-
const response = await window.fetch(endpoint, config);
21-
22-
if (response.ok) {
23-
// First, clone the response to avoid consuming the body multiple times
24-
const clonedResponse = response.clone();
25-
try {
26-
return await clonedResponse.json();
27-
} catch (jsonError) {
28-
// If JSON parsing fails, return empty object
29-
console.warn('Failed to parse JSON response:', jsonError);
30-
return {} as T;
31-
}
32-
} else {
33-
// Clone the response before reading text to avoid consumption issues
34-
const clonedResponse = response.clone();
35-
let errorMessage = response.status.toString();
36-
37-
try {
38-
errorMessage = await clonedResponse.text() || errorMessage;
39-
} catch (textError) {
40-
console.warn('Failed to read error response text:', textError);
41-
}
42-
43-
console.error(`HTTP ${response.status}: ${errorMessage}`, response);
44-
if (notifyOnError || notifyOnError === undefined) notifyError(errorMessage);
45-
return Promise.reject(new Error(errorMessage));
46-
}
47-
} catch (e: unknown) {
48-
if (e instanceof Error) {
49-
console.error(e.message);
50-
if (notifyOnError || notifyOnError === undefined) notifyError(e.message);
51-
return Promise.reject(e);
52-
} else {
53-
console.error(e || "Unknown error");
54-
if (notifyOnError || notifyOnError === undefined) notifyError(String(e));
55-
return Promise.reject(new Error(String(e)));
56-
}
57-
}
11+
async function get<T>(path: string): Promise<T> {
12+
const response = await fetch(path, { method: "GET" });
13+
return response.json();
5814
}
5915

60-
export async function fetchRaw(endpoint: RequestInfo, init: RequestInit & { notifyOnError?: boolean } = {}): Promise<Response> {
61-
const { notifyOnError, ...config } = init;
62-
63-
try {
64-
// Directly use window.fetch without authFetch
65-
return await window.fetch(endpoint, config);
66-
} catch (e: unknown) {
67-
if (e instanceof Error) {
68-
console.error(e.message);
69-
if (notifyOnError || notifyOnError === undefined) notifyError(e.message);
70-
return Promise.reject(e);
71-
} else {
72-
console.error(e || "Unknown error");
73-
if (notifyOnError || notifyOnError === undefined) notifyError(String(e));
74-
return Promise.reject(new Error(String(e)));
75-
}
76-
}
77-
}
78-
79-
// Other methods remain unchanged...
80-
async function get<T>(path: string, config?: RequestInit & { notifyOnError?: boolean }): Promise<T> {
81-
const init = { method: "GET", ...config };
82-
return fetch<T>(path, init);
83-
}
84-
85-
async function post<T, U>(path: string, body?: T, config?: RequestInit & { notifyOnError?: boolean }): Promise<U> {
86-
const defaultHeaders = {
87-
'Content-Type': 'application/json',
88-
};
89-
90-
const init = {
91-
method: "POST",
92-
body: body ? JSON.stringify(body) : undefined,
93-
headers: {
94-
...defaultHeaders,
95-
...(config?.headers || {})
96-
},
97-
...config
98-
};
99-
return fetch<U>(path, init);
16+
async function post<T, U>(path: string, body?: T): Promise<U> {
17+
const response = await fetch(path, {
18+
method: "POST",
19+
headers: { "Content-Type": "application/json" },
20+
body: body ? JSON.stringify(body) : undefined
21+
});
22+
return response.json();
10023
}
10124

102-
async function put<T, U>(path: string, body?: T, config?: RequestInit & { notifyOnError?: boolean }): Promise<U> {
103-
const init = { method: "PUT", body: JSON.stringify(body), ...config };
104-
return fetch<U>(path, init);
25+
async function put<T, U>(path: string, body: T): Promise<U> {
26+
const response = await fetch(path, {
27+
method: "PUT",
28+
headers: { "Content-Type": "application/json" },
29+
body: JSON.stringify(body)
30+
});
31+
return response.json();
10532
}
10633

107-
async function _delete<T>(path: string, config?: RequestInit & { notifyOnError?: boolean }): Promise<T> {
108-
const init = { method: "DELETE", ...config };
109-
return fetch<T>(path, init);
34+
async function _delete<T>(path: string): Promise<T> {
35+
const response = await fetch(path, { method: "DELETE" });
36+
return response.json();
11037
}
11138

112-
async function download(path: string, fileName: string, config?: RequestInit & { notifyOnError?: boolean }): Promise<void> {
113-
const init = { method: "GET", ...config };
114-
const response = await fetchRaw(path, init);
39+
async function download(path: string, fileName: string): Promise<void> {
40+
const response = await fetch(path);
11541
const blob = await response.blob();
116-
117-
const url = window.URL.createObjectURL(new Blob([blob]));
42+
43+
const url = window.URL.createObjectURL(blob);
11844
const link = document.createElement("a");
11945
link.href = url;
12046
link.setAttribute("download", fileName);
121-
47+
12248
document.body.appendChild(link);
12349
link.click();
12450
link.parentNode?.removeChild(link);
12551
}
12652

127-
async function patch<T, U>(path: string, body: T, config?: RequestInit & { notifyOnError?: boolean }): Promise<U> {
128-
const init = { method: "PATCH", body: JSON.stringify(body), ...config };
129-
return fetch<U>(path, init);
130-
}
131-
132-
export async function upload<T>(path: string, formData: FormData, config?: RequestInit & { notifyOnError?: boolean }): Promise<T> {
133-
const init = { method: "POST", body: formData, ...config };
134-
return fetch<T>(path, init);
135-
}
136-
137-
function notifyError(_message: string) {
138-
// TO DO: Implement error notification logic
53+
async function patch<T, U>(path: string, body: T): Promise<U> {
54+
const response = await fetch(path, {
55+
method: "PATCH",
56+
headers: { "Content-Type": "application/json" },
57+
body: JSON.stringify(body)
58+
});
59+
return response.json();
13960
}
14061

141-
export function parseHttpException(ex: any, t: (key: string) => string): string[] {
142-
if (ex instanceof Error && ex.message.startsWith("{")) {
143-
const error = JSON.parse(ex.message);
144-
if ("errors" in error) {
145-
const messages = Object.entries(error.errors).map((field) => error.errors[field[0]].join(", "));
146-
return messages;
147-
}
148-
} else if (ex instanceof Error && ex.message === "403") {
149-
return [t("common.forbidden")];
150-
}
151-
return [t("common.error")];
62+
async function upload<T>(path: string, formData: FormData): Promise<T> {
63+
const response = await fetch(path, {
64+
method: "POST",
65+
body: formData
66+
});
67+
return response.json();
15268
}

0 commit comments

Comments
 (0)