diff --git a/infra/main_custom.bicep b/infra/main_custom.bicep
index 9c71835f8..26cffaa5b 100644
--- a/infra/main_custom.bicep
+++ b/infra/main_custom.bicep
@@ -1102,6 +1102,10 @@ module keyvault 'br/public:avm/res/key-vault/vault:0.12.1' = {
{name: 'AZURE-OPENAI-PREVIEW-API-VERSION', value: azureOpenaiAPIVersion}
{name: 'AZURE-OPEN-AI-DEPLOYMENT-MODEL', value: gptModelName}
{name: 'TENANT-ID', value: subscription().tenantId}
+ {
+ name: 'AZURE-AI-AGENT-ENDPOINT'
+ value: aiFoundryAiProjectEndpoint
+ }
]
}
dependsOn:[
@@ -1160,7 +1164,8 @@ module webSite 'modules/web-sites.bicep' = {
{
name: 'appsettings'
properties: {
- SCM_DO_BUILD_DURING_DEPLOYMENT: 'false'
+ SCM_DO_BUILD_DURING_DEPLOYMENT: 'True'
+ ENABLE_ORYX_BUILD: 'True'
AUTH_ENABLED: 'false'
AZURE_SEARCH_SERVICE: aiSearch.outputs.name
AZURE_SEARCH_INDEX: azureSearchIndex
diff --git a/infra/scripts/index_scripts/02_process_data.py b/infra/scripts/index_scripts/02_process_data.py
index 4b01e3f17..12fa617e5 100644
--- a/infra/scripts/index_scripts/02_process_data.py
+++ b/infra/scripts/index_scripts/02_process_data.py
@@ -177,6 +177,6 @@ def prepare_search_doc(content, document_id):
docs = []
if docs != []:
- results = search_client.upload_documents(documents=docs)
+ search_client.upload_documents(documents=docs)
print(f'{str(counter)} files processed.')
diff --git a/scripts/data_utils.py b/scripts/data_utils.py
index 1e8dc44cf..e5cf535be 100644
--- a/scripts/data_utils.py
+++ b/scripts/data_utils.py
@@ -157,7 +157,13 @@ def extract_caption(self, text):
def mask_urls_and_imgs(self, text) -> Tuple[Dict[str, str], str]:
def find_urls(string):
- regex = r"(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^()\s<>]+|\(([^()\s<>]+|(\([^()\s<>]+\)))*\))+(?:\(([^()\s<>]+|(\([^()\s<>]+\)))*\)|[^()\s`!()\[\]{};:'\".,<>?«»“”‘’]))"
+ regex = (
+ r"(?i)\b("
+ r"(?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)"
+ r"(?:[^()\s<>]+|\(([^()\s<>]+|(\([^()\s<>]+\)))*\))+"
+ r"(?:\(([^()\s<>]+|(\([^()\s<>]+\)))*\)|[^()\s`!()\[\]{};:'\".,<>?«»“”‘’])"
+ r")"
+ )
urls = re.findall(regex, string)
return [x[0] for x in urls]
@@ -693,7 +699,9 @@ def extract_pdf_content(file_path, form_recognizer_client, use_layout=False):
page_map = []
model = "prebuilt-layout" if use_layout else "prebuilt-read"
- base64file = base64.b64encode(open(file_path, "rb").read()).decode()
+ with open(file_path, "rb") as f:
+ file_bytes = f.read()
+ base64file = base64.b64encode(file_bytes).decode()
poller = form_recognizer_client.begin_analyze_document(
model, AnalyzeDocumentRequest(bytes_source=base64file)
)
@@ -1048,7 +1056,8 @@ def image_content_to_tag(image_content: str) -> str:
def get_caption(image_path, captioning_model_endpoint, captioning_model_key):
- encoded_image = base64.b64encode(open(image_path, "rb").read()).decode("ascii")
+ with open(image_path, "rb") as image_file:
+ encoded_image = base64.b64encode(image_file.read()).decode("ascii")
file_ext = image_path.split(".")[-1]
headers = {
"Content-Type": "application/json",
diff --git a/src/app.py b/src/app.py
index a7bf5ffea..7416c472d 100644
--- a/src/app.py
+++ b/src/app.py
@@ -167,7 +167,6 @@ async def init_ai_foundry_client():
return ai_foundry_client
except Exception as e:
logging.exception("Exception in AI Foundry initialization", e)
- ai_foundry_client = None
raise e
@@ -197,7 +196,6 @@ def init_cosmosdb_client():
if span is not None:
span.record_exception(e)
span.set_status(Status(StatusCode.ERROR, str(e)))
- cosmos_conversation_client = None
raise e
else:
logging.debug("CosmosDB not configured")
diff --git a/src/backend/history/cosmosdbservice.py b/src/backend/history/cosmosdbservice.py
index 9add46ea2..66e19b514 100644
--- a/src/backend/history/cosmosdbservice.py
+++ b/src/backend/history/cosmosdbservice.py
@@ -110,7 +110,7 @@ async def delete_messages(self, conversation_id, user_id):
item=message["id"], partition_key=user_id
)
response_list.append(resp)
- return response_list
+ return response_list
async def get_conversations(self, user_id, limit, sort_order="DESC", offset=0):
parameters = [{"name": "@userId", "value": user_id}]
diff --git a/src/backend/settings.py b/src/backend/settings.py
index 206a7d3b7..87c589c86 100644
--- a/src/backend/settings.py
+++ b/src/backend/settings.py
@@ -249,8 +249,9 @@ def split_contexts(
class DatasourcePayloadConstructor(BaseModel, ABC):
_settings: "_AppSettings" = PrivateAttr()
- def __init__(self, settings: "_AppSettings", **data):
- super().__init__(**data)
+ def __init__(self, *args, settings: "_AppSettings", **data):
+ # Call next __init__ in MRO to allow cooperative multiple inheritance
+ super().__init__(*args, **data)
self._settings = settings
@abstractmethod
@@ -302,6 +303,10 @@ class _AzureSearchSettings(BaseSettings, DatasourcePayloadConstructor):
fields_mapping: Optional[dict] = None
filter: Optional[str] = Field(default=None, exclude=True)
+ def __init__(self, settings: "_AppSettings", **data):
+ # Ensure both BaseSettings and DatasourcePayloadConstructor are initialized
+ super().__init__(settings=settings, **data)
+
@field_validator("content_columns", "vector_columns", mode="before")
@classmethod
def split_columns(cls, comma_separated_string: str) -> List[str]:
@@ -439,6 +444,7 @@ def set_datasource_settings(self) -> Self:
logging.warning(
"No datasource configuration found in the environment -- calls will be made to Azure OpenAI without grounding data."
)
+ return self
app_settings = _AppSettings()
diff --git a/src/frontend/__mocks__/react-markdown.tsx b/src/frontend/__mocks__/react-markdown.tsx
index 9e5efd5dc..df4c3bad2 100644
--- a/src/frontend/__mocks__/react-markdown.tsx
+++ b/src/frontend/__mocks__/react-markdown.tsx
@@ -2,15 +2,9 @@
import React from 'react';
-// Mock implementation of react-markdown
-const mockNode = {
- children: [{ value: 'console.log("Test Code");' }]
-};
-const mockProps = { className: 'language-javascript' };
-
const ReactMarkdown: React.FC<{ children: React.ReactNode , components: any }> = ({ children,components }) => {
return
- {/* {components && components.code({ node: mockNode, ...mockProps })} */}
+ {/* {components && components.code({ node: { children: [{ value: 'console.log("Test Code");' }] }, ...mockProps })} */}
{children}
; // Simply render the children
};
diff --git a/src/frontend/src/api/models.ts b/src/frontend/src/api/models.ts
index af2d89850..511783357 100644
--- a/src/frontend/src/api/models.ts
+++ b/src/frontend/src/api/models.ts
@@ -1,5 +1,3 @@
-import Plotly from 'react-plotly.js'
-
export type AskResponse = {
answer: string
citations: Citation[]
diff --git a/src/frontend/src/components/Answer/Answer.test.tsx b/src/frontend/src/components/Answer/Answer.test.tsx
index bf1a509c4..7e4a3817d 100644
--- a/src/frontend/src/components/Answer/Answer.test.tsx
+++ b/src/frontend/src/components/Answer/Answer.test.tsx
@@ -1,11 +1,9 @@
-import { renderWithContext, screen, waitFor, fireEvent, act, logRoles } from '../../test/test.utils';
+import { renderWithContext, screen, waitFor, fireEvent, act } from '../../test/test.utils';
import { Answer } from './Answer'
-import { AppStateContext } from '../../state/AppProvider'
import {AskResponse, Citation, Feedback, historyMessageFeedback } from '../../api';
//import { Feedback, AskResponse, Citation } from '../../api/models'
import { cloneDeep } from 'lodash'
import userEvent from '@testing-library/user-event';
-import { CitationPanel } from '../../pages/chat/Components/CitationPanel';
// Mock required modules and functions
jest.mock('../../api/api', () => ({
@@ -27,9 +25,6 @@ jest.mock('remark-gfm', () => jest.fn());
jest.mock('rehype-raw', () => jest.fn());
jest.mock('remark-supersub', () => jest.fn());
-const mockDispatch = jest.fn();
-const mockOnCitationClicked = jest.fn();
-
// Mock context provider values
let mockAppState = {
frontendSettings: { feedback_enabled: true, sanitize_answer: true },
@@ -360,7 +355,6 @@ describe('Answer Component', () => {
it('should open and submit negative feedback dialog', async () => {
userEvent.setup();
renderComponent();
- const handleChange = jest.fn();
const dislikeButton = screen.getByLabelText('Dislike this response');
// Click dislike to open dialog
@@ -368,7 +362,7 @@ describe('Answer Component', () => {
expect(screen.getByText("Why wasn't this response helpful?")).toBeInTheDocument();
// Select feedback and submit
- const checkboxEle = await screen.findByLabelText(/Citations are wrong/i)
+ const checkboxEle = await screen.findByLabelText(/Citations are wrong/i);
//logRoles(checkboxEle)
await waitFor(() => {
userEvent.click(checkboxEle);
@@ -382,12 +376,8 @@ describe('Answer Component', () => {
it('calls resetFeedbackDialog and setFeedbackState with Feedback.Neutral on dialog dismiss', async () => {
- const resetFeedbackDialogMock = jest.fn();
- const setFeedbackStateMock = jest.fn();
-
userEvent.setup();
renderComponent();
- const handleChange = jest.fn();
const dislikeButton = screen.getByLabelText('Dislike this response');
// Click dislike to open dialog
@@ -410,7 +400,6 @@ describe('Answer Component', () => {
it('Dialog Options should be able to select and unSelect', async () => {
userEvent.setup();
renderComponent();
- const handleChange = jest.fn();
const dislikeButton = screen.getByLabelText('Dislike this response');
// Click dislike to open dialog
@@ -419,7 +408,7 @@ describe('Answer Component', () => {
expect(screen.getByText("Why wasn't this response helpful?")).toBeInTheDocument();
// Select feedback and submit
- const checkboxEle = await screen.findByLabelText(/Citations are wrong/i)
+ const checkboxEle = await screen.findByLabelText(/Citations are wrong/i);
expect(checkboxEle).not.toBeChecked();
await userEvent.click(checkboxEle);
@@ -427,7 +416,7 @@ describe('Answer Component', () => {
expect(checkboxEle).toBeChecked();
});
- const checkboxEle1 = await screen.findByLabelText(/Citations are wrong/i)
+ const checkboxEle1 = await screen.findByLabelText(/Citations are wrong/i);
await userEvent.click(checkboxEle1);
await waitFor(() => {
@@ -439,7 +428,6 @@ describe('Answer Component', () => {
it('Should able to show ReportInappropriateFeedbackContent form while click on "InappropriateFeedback" button ', async () => {
userEvent.setup();
renderComponent();
- const handleChange = jest.fn();
const dislikeButton = screen.getByLabelText('Dislike this response');
// Click dislike to open dialog
@@ -514,7 +502,6 @@ describe('Answer Component', () => {
feedbackState: { '123': Feedback.OtherHarmful },
}
renderComponent(answerWithMissingFeedback, extraMockState);
- const handleChange = jest.fn();
const dislikeButton = screen.getByLabelText('Dislike this response');
// Click dislike to open dialog
@@ -529,10 +516,6 @@ describe('Answer Component', () => {
tempMockCitation[0].filepath = '';
tempMockCitation[0].reindex_id = '';
- const answerWithMissingFeedback = {
- ...mockAnswerProps,
- CitationPanel: [...tempMockCitation]
- }
renderComponent();
diff --git a/src/frontend/src/components/Answer/Answer.tsx b/src/frontend/src/components/Answer/Answer.tsx
index dcf5574d0..2a3c290ed 100644
--- a/src/frontend/src/components/Answer/Answer.tsx
+++ b/src/frontend/src/components/Answer/Answer.tsx
@@ -39,7 +39,6 @@ export const Answer = ({ answer, onCitationClicked }: Props) => {
}
const [isRefAccordionOpen, { toggle: toggleIsRefAccordionOpen }] = useBoolean(false)
- const filePathTruncationLimit = 50
const parsedAnswer = useMemo(() => parseAnswer(answer), [answer])
const [chevronIsExpanded, setChevronIsExpanded] = useState(isRefAccordionOpen)
@@ -156,7 +155,7 @@ export const Answer = ({ answer, onCitationClicked }: Props) => {
const onLikeResponseClicked = async () => {
if (answer.message_id == undefined) return
- let newFeedbackState = feedbackState
+ let newFeedbackState: Feedback.Neutral | Feedback.Positive
// Set or unset the thumbs up state
if (feedbackState == Feedback.Positive) {
newFeedbackState = Feedback.Neutral
@@ -176,7 +175,7 @@ export const Answer = ({ answer, onCitationClicked }: Props) => {
const onDislikeResponseClicked = async () => {
if (answer.message_id == undefined) return
- let newFeedbackState = feedbackState
+ let newFeedbackState: Feedback.Neutral | Feedback.Negative
if (feedbackState === undefined || feedbackState === Feedback.Neutral || feedbackState === Feedback.Positive) {
newFeedbackState = Feedback.Negative
setFeedbackState(newFeedbackState)
diff --git a/src/frontend/src/components/ChatHistory/ChatHistoryListItem.tsx b/src/frontend/src/components/ChatHistory/ChatHistoryListItem.tsx
index d4cff2bf0..b14b50039 100644
--- a/src/frontend/src/components/ChatHistory/ChatHistoryListItem.tsx
+++ b/src/frontend/src/components/ChatHistory/ChatHistoryListItem.tsx
@@ -81,10 +81,6 @@ export const ChatHistoryListItemCell: React.FC = (
styles: { main: { maxWidth: 450 } }
}
- const tooltipStyles: Partial = {
- root: { display: 'inline-block', maxWidth: '80%' }
- };
-
if (!item) {
return null
}
diff --git a/src/frontend/src/components/ChatHistory/ChatHistoryPanel.test.tsx b/src/frontend/src/components/ChatHistory/ChatHistoryPanel.test.tsx
index a3b31c6c7..37fd7f27f 100644
--- a/src/frontend/src/components/ChatHistory/ChatHistoryPanel.test.tsx
+++ b/src/frontend/src/components/ChatHistory/ChatHistoryPanel.test.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import { render, fireEvent, screen, waitFor } from '@testing-library/react';
import { AppStateContext } from '../../state/AppProvider';
import { ChatHistoryPanel } from './ChatHistoryPanel';
-import { ChatHistoryLoadingState, ChatMessage, Conversation, CosmosDBStatus, Feedback, historyDeleteAll,historyList } from '../../api';
+import { ChatHistoryLoadingState, ChatMessage, Conversation, CosmosDBStatus, Feedback } from '../../api';
import * as api from '../../api';
import {defaultMockState} from '../../test/test.utils';
diff --git a/src/frontend/src/components/ChatHistory/chatHistoryListItem.test.tsx b/src/frontend/src/components/ChatHistory/chatHistoryListItem.test.tsx
index 7fe93195c..a7eccb4c9 100644
--- a/src/frontend/src/components/ChatHistory/chatHistoryListItem.test.tsx
+++ b/src/frontend/src/components/ChatHistory/chatHistoryListItem.test.tsx
@@ -1,10 +1,9 @@
-import { renderWithContext, screen, waitFor, fireEvent, act, findByText, render } from '../../test/test.utils'
+import { renderWithContext, screen, waitFor, fireEvent, act } from '../../test/test.utils'
import { ChatHistoryListItemCell, ChatHistoryListItemGroups } from './ChatHistoryListItem'
import { Conversation } from '../../api/models'
import { historyRename, historyDelete, historyList, historyRead } from '../../api'
-import React, { useEffect } from 'react'
+import React from 'react'
import userEvent from '@testing-library/user-event'
-import { AppStateContext } from '../../state/AppProvider'
// Mock API
jest.mock('../../api/api', () => ({
@@ -555,13 +554,6 @@ describe('ChatHistoryListItemCell', () => {
test('shows error when trying to rename to an existing title', async () => {
const existingTitle = 'Existing Chat Title'
- const conversationWithExistingTitle: Conversation = {
- id: '2',
- title: existingTitle,
- messages: [],
- date: new Date().toISOString()
- }
-
; (historyRename as jest.Mock).mockResolvedValueOnce({
ok: false,
json: async () => ({ message: 'Title already exists' })
diff --git a/src/frontend/src/components/DraftCards/TitleCard.test.tsx b/src/frontend/src/components/DraftCards/TitleCard.test.tsx
index 04ebb4425..ce4a2b73a 100644
--- a/src/frontend/src/components/DraftCards/TitleCard.test.tsx
+++ b/src/frontend/src/components/DraftCards/TitleCard.test.tsx
@@ -4,16 +4,6 @@ import { render, screen, fireEvent } from '@testing-library/react';
import TitleCard from './TitleCard';
import { AppStateContext } from '../../state/AppProvider';
-const contextValue = {
- state: {
- draftedDocumentTitle: null,
- isChatHistoryOpen: false,
- chatHistoryLoadingState: 'idle',
- isCosmosDBAvailable: true,
- chatHistory: [],
- },
- };
-
const mockDispatch = jest.fn();
const renderWithContext = (contextValue : any) => {
diff --git a/src/frontend/src/components/FeatureCard/FeatureCard.test.tsx b/src/frontend/src/components/FeatureCard/FeatureCard.test.tsx
index 75ac5ba37..d01da5f95 100644
--- a/src/frontend/src/components/FeatureCard/FeatureCard.test.tsx
+++ b/src/frontend/src/components/FeatureCard/FeatureCard.test.tsx
@@ -35,7 +35,7 @@ describe('FeatureCard', () => {
};
test('renders correctly with the provided props', () => {
- const { getByText, getByRole } = renderFeatureCard(props);
+ const { getByText } = renderFeatureCard(props);
// Check if title and description are rendered correctly
expect(getByText(props.title)).toBeInTheDocument();
@@ -108,7 +108,7 @@ describe('FeatureCard', () => {
// Mock the useNavigate hook to return our mock function
require('react-router-dom').useNavigate.mockReturnValue(mockNavigate);
- const { getByText, queryByText } = renderFeatureCard({
+ const { getByText } = renderFeatureCard({
icon: props.icon,
urlSuffix: props.urlSuffix,
title: "Feature Card",
diff --git a/src/frontend/src/components/QuestionInput/QuestionInput.test.tsx b/src/frontend/src/components/QuestionInput/QuestionInput.test.tsx
index e1d4e1e97..c2c26906f 100644
--- a/src/frontend/src/components/QuestionInput/QuestionInput.test.tsx
+++ b/src/frontend/src/components/QuestionInput/QuestionInput.test.tsx
@@ -1,6 +1,5 @@
import { render, fireEvent, screen } from '@testing-library/react'
import { QuestionInput } from './QuestionInput'
-import { SendRegular } from '@fluentui/react-icons'
// Mocking the Send SVG import
jest.mock('../../assets/Send.svg', () => 'mock-send-svg')
diff --git a/src/frontend/src/components/Sidebar/Sidebar.test.tsx b/src/frontend/src/components/Sidebar/Sidebar.test.tsx
index 7f4ff89bf..b9264ef6a 100644
--- a/src/frontend/src/components/Sidebar/Sidebar.test.tsx
+++ b/src/frontend/src/components/Sidebar/Sidebar.test.tsx
@@ -1,9 +1,9 @@
import React from 'react';
-import { render, screen,fireEvent,act } from '@testing-library/react';
+import { render, screen,fireEvent } from '@testing-library/react';
import { AppStateContext } from '../../state/AppProvider';
import Sidebar from './Sidebar';
import { ChatHistoryLoadingState } from '../../api/models';
-import { BrowserRouter as Router, useLocation ,useNavigate} from 'react-router-dom';
+import { BrowserRouter as Router, useLocation } from 'react-router-dom';
import { getUserInfo } from '../../api';
import {defaultMockState} from '../../test/test.utils';
@@ -187,7 +187,6 @@ describe('Sidebar', () => {
});
it('returns the correct view based on the current URL', () => {
- const mockUseLocation = jest.fn();
(useLocation as jest.Mock).mockReturnValue({ pathname: '/draft' });
renderSidebar();
diff --git a/src/frontend/src/components/Sidebar/Sidebar.tsx b/src/frontend/src/components/Sidebar/Sidebar.tsx
index 9bde2c9a1..6acc09a84 100644
--- a/src/frontend/src/components/Sidebar/Sidebar.tsx
+++ b/src/frontend/src/components/Sidebar/Sidebar.tsx
@@ -2,12 +2,8 @@ import React, { useEffect, useState, useContext } from 'react'
import { Stack, Text } from '@fluentui/react'
import {
Book28Regular,
- Book32Regular,
- BookRegular,
News28Regular,
- NewsRegular,
Notepad28Regular,
- Notepad32Regular
} from '@fluentui/react-icons'
import { Button, Avatar } from '@fluentui/react-components'
import styles from './Sidebar.module.css'
@@ -85,15 +81,7 @@ const Sidebar = (): JSX.Element => {
const navigate = useNavigate()
const location = useLocation()
const [name, setName] = useState('')
- useEffect(() => {
- if(appStateContext?.state.isRequestInitiated == true){
- NavigationButtonStates.Disabled
- }
- else{
- NavigationButtonStates.Active
- }
-})
-
+
useEffect(() => {
if (!appStateContext) {
throw new Error('useAppState must be used within a AppStateProvider')
diff --git a/src/frontend/src/constants/chatHistory.test.tsx b/src/frontend/src/constants/chatHistory.test.tsx
index e5cef1e8b..27e033620 100644
--- a/src/frontend/src/constants/chatHistory.test.tsx
+++ b/src/frontend/src/constants/chatHistory.test.tsx
@@ -1,5 +1,4 @@
import { chatHistorySampleData } from './chatHistory';
-import { Conversation } from '../api/models';
describe('chatHistorySampleData', () => {
it('should be an array of Conversation objects', () => {
diff --git a/src/frontend/src/helpers/helpers.ts b/src/frontend/src/helpers/helpers.ts
index 8816726e5..1ed90ed3a 100644
--- a/src/frontend/src/helpers/helpers.ts
+++ b/src/frontend/src/helpers/helpers.ts
@@ -1,4 +1,4 @@
-import { Conversation, ChatMessage, ToolMessageContent, Citation } from '../api/models'
+import { ChatMessage } from '../api/models'
// -------------Chat.tsx-------------
diff --git a/src/frontend/src/pages/chat/Chat.test.tsx b/src/frontend/src/pages/chat/Chat.test.tsx
index a4f2f7240..5355a816a 100644
--- a/src/frontend/src/pages/chat/Chat.test.tsx
+++ b/src/frontend/src/pages/chat/Chat.test.tsx
@@ -1,6 +1,6 @@
import { renderWithContext, screen, waitFor, fireEvent, act } from '../../test/test.utils'
import Chat from './Chat'
-import { ChatHistoryLoadingState,ChatType } from '../../api/models'
+import { ChatType } from '../../api/models'
import * as ReactRouterDom from 'react-router-dom';
import {
getUserInfo,
@@ -9,13 +9,11 @@ import {
historyClear,
ChatMessage,
Citation,
- historyUpdate,
- CosmosDBStatus
+ historyUpdate
} from '../../api'
import userEvent from '@testing-library/user-event'
-import { AIResponseContent, decodedConversationResponseWithCitations } from '../../../__mocks__/mockAPIData'
-import { CitationPanel } from './Components/CitationPanel'
+import { decodedConversationResponseWithCitations } from '../../../__mocks__/mockAPIData'
// import { BuildingCheckmarkRegular } from '@fluentui/react-icons';
@@ -108,8 +106,6 @@ jest.mock('../../components/ChatHistory/ChatHistoryPanel', () => ({
ChatHistoryPanel: jest.fn(() => ChatHistoryPanelMock
)
}))
-
-const mockDispatch = jest.fn()
const originalHostname = window.location.hostname
const mockState = {
@@ -316,8 +312,6 @@ const addToExistResponse = {
//-----ConversationAPI Response
-const response4 = {}
-
let originalFetch: typeof global.fetch
describe('Chat Component', () => {
@@ -567,7 +561,6 @@ describe('Chat Component', () => {
mockCallConversationApi.mockResolvedValueOnce({ ...mockResponse })
}
- const setIsVisible = jest.fn()
beforeEach(() => {
jest.clearAllMocks()
originalFetch = global.fetch
diff --git a/src/frontend/src/pages/chat/Chat.tsx b/src/frontend/src/pages/chat/Chat.tsx
index 185f2ed8c..a13b5b569 100644
--- a/src/frontend/src/pages/chat/Chat.tsx
+++ b/src/frontend/src/pages/chat/Chat.tsx
@@ -6,15 +6,13 @@ import {
Dialog,
DialogType,
Stack,
- Modal,
IStackTokens,
mergeStyleSets,
IModalStyles,
- PrimaryButton,
Spinner,
SpinnerSize
} from '@fluentui/react'
-import { SquareRegular, ShieldLockRegular, ErrorCircleRegular } from '@fluentui/react-icons'
+import { SquareRegular } from '@fluentui/react-icons'
import uuid from 'react-uuid'
import { isEmpty } from 'lodash'
@@ -26,7 +24,6 @@ import {
ConversationRequest,
conversationApi,
Citation,
- ToolMessageContent,
ChatResponse,
getUserInfo,
Conversation,
@@ -55,50 +52,10 @@ const enum messageStatus {
Done = 'Done'
}
-// Define stack tokens for spacing
-const stackTokens: IStackTokens = { childrenGap: 20 }
-
-// Define custom styles for the modal
-const modalStyles: IModalStyles = {
- main: {
- maxWidth: '80%',
- minHeight: '40%',
- padding: '20px',
- backgroundColor: '#f3f2f1',
- borderRadius: '8px',
- overflowY: 'hidden'
- },
- root: undefined,
- scrollableContent: {
- minWidth: '800px'
- },
- layer: undefined,
- keyboardMoveIconContainer: undefined,
- keyboardMoveIcon: undefined
-}
-
-// Define custom styles for the content inside the modal
-const contentStyles = mergeStyleSets({
- iframe: {
- width: '100%',
- height: '55vh',
- border: 'none'
- },
- closeButton: {
- marginTop: '20px',
- alignSelf: 'flex-end'
- }
-})
-
interface Props {
type?: ChatType
}
-
-const renderLink = (props: any) => {
- return ;
-};
-
const Chat = ({ type = ChatType.Browse }: Props) => {
const location = useLocation()
@@ -114,21 +71,18 @@ const Chat = ({ type = ChatType.Browse }: Props) => {
const abortFuncs = useRef([] as AbortController[])
const [showAuthMessage, setShowAuthMessage] = useState()
const [messages, setMessages] = useState([])
- const [jsonDraftDocument, setJSONDraftDocument] = useState('')
+ const [, setJSONDraftDocument] = useState('')
const [draftDocument, setDraftDocument] = useState()
const [processMessages, setProcessMessages] = useState(messageStatus.NotRunning)
const [clearingChat, setClearingChat] = useState(false)
const [hideErrorDialog, { toggle: toggleErrorDialog }] = useBoolean(true)
const [errorMsg, setErrorMsg] = useState()
- const [isModalOpen, setIsModalOpen] = useState(false)
- const [modalUrl, setModalUrl] = useState('');
- const [finalMessages, setFinalMessages] = useState([])
+ const [, setModalUrl] = useState('');
if (!appStateContext || !appStateContext.state) {
console.error("AppStateContext is undefined. Ensure AppProvider wraps this component.");
return null; // Prevents execution if context is missing
}
const [loadingState, setLoadingState] = useState(appStateContext.state.isLoading);
- const { currentChat } = appStateContext?.state;
const errorDialogContentProps = {
type: DialogType.close,
@@ -575,13 +529,7 @@ const Chat = ({ type = ChatType.Browse }: Props) => {
? resultConversation.messages.push(assistantMessage)
: resultConversation.messages.push(toolMessage, assistantMessage)
}
- if (!resultConversation) {
- setIsLoading(false)
- appStateContext?.dispatch({ type: 'GENERATE_ISLODING', payload: false })
- setShowLoadingMessage(false)
- abortFuncs.current = abortFuncs.current.filter(a => a !== abortController)
- return
- }
+
appStateContext?.dispatch({ type: 'UPDATE_CURRENT_CHAT', payload: resultConversation })
isEmpty(toolMessage)
? setMessages([...messages, assistantMessage])
@@ -644,13 +592,7 @@ const Chat = ({ type = ChatType.Browse }: Props) => {
}
resultConversation.messages.push(errorChatMsg)
}
- if (!resultConversation) {
- setIsLoading(false)
- appStateContext?.dispatch({ type: 'GENERATE_ISLODING', payload: false })
- setShowLoadingMessage(false)
- abortFuncs.current = abortFuncs.current.filter(a => a !== abortController)
- return
- }
+
appStateContext?.dispatch({ type: 'UPDATE_CURRENT_CHAT', payload: resultConversation })
setMessages([...messages, errorChatMsg])
} else {
@@ -810,12 +752,6 @@ const Chat = ({ type = ChatType.Browse }: Props) => {
const onShowCitation = (citation: Citation) => {
const url = citation.url
setModalUrl(url ?? '')
- setIsModalOpen(true)
- }
-
- const onCloseModal = () => {
- setIsModalOpen(false)
- setModalUrl('')
}
const onViewSource = (citation: Citation) => {
diff --git a/src/frontend/src/pages/chat/Components/AuthNotConfigure.test.tsx b/src/frontend/src/pages/chat/Components/AuthNotConfigure.test.tsx
index a47a1e4d3..fbb818bc0 100644
--- a/src/frontend/src/pages/chat/Components/AuthNotConfigure.test.tsx
+++ b/src/frontend/src/pages/chat/Components/AuthNotConfigure.test.tsx
@@ -2,7 +2,6 @@ import React from 'react'
import { render, screen } from '@testing-library/react'
import '@testing-library/jest-dom'
import { AuthNotConfigure } from './AuthNotConfigure'
-import styles from '../Chat.module.css'
// Mock the Fluent UI icons
jest.mock('@fluentui/react-icons', () => ({
diff --git a/src/frontend/src/pages/chat/Components/ChatMessageContainer.test.tsx b/src/frontend/src/pages/chat/Components/ChatMessageContainer.test.tsx
index ce4083322..35bfdb5e0 100644
--- a/src/frontend/src/pages/chat/Components/ChatMessageContainer.test.tsx
+++ b/src/frontend/src/pages/chat/Components/ChatMessageContainer.test.tsx
@@ -1,6 +1,6 @@
import { render, screen, fireEvent } from '@testing-library/react';
import { ChatMessageContainer } from './ChatMessageContainer';
-import { ChatMessage, Citation,ChatType } from '../../../api/models';
+import { ChatMessage, ChatType } from '../../../api/models';
import { Answer } from '../../../components/Answer';
jest.mock('../../../components/Answer', () => ({
@@ -74,7 +74,7 @@ describe('ChatMessageContainer', () => {
"date": "2024-11-07T09:37:30.581Z"
},
- ]
+ ];
it('renders user and assistant messages correctly', () => {
render(
@@ -199,6 +199,6 @@ describe('ChatMessageContainer', () => {
/>
);
expect(screen.getByText(/Generating template...this may take up to 30 seconds./)).toBeInTheDocument();
- expect(screen.getByText(/Generate promissory note with a proposed $100,000 for Washington State/)).toBeInTheDocument();
+ expect(screen.getByText(/Generate promissory note with a proposed \$100,000 for Washington State/)).toBeInTheDocument();
});
});
diff --git a/src/frontend/src/pages/chat/Components/ChatMessageContainer.tsx b/src/frontend/src/pages/chat/Components/ChatMessageContainer.tsx
index 5e38e4b48..0c3e2ae6d 100644
--- a/src/frontend/src/pages/chat/Components/ChatMessageContainer.tsx
+++ b/src/frontend/src/pages/chat/Components/ChatMessageContainer.tsx
@@ -1,4 +1,4 @@
-import { useRef, useState, useEffect, useContext, useLayoutEffect, forwardRef } from 'react';
+import { forwardRef } from 'react';
import styles from '../Chat.module.css';
import { Answer } from '../../../components/Answer';
import { parseCitationFromMessage, generateTemplateSections } from '../../../helpers/helpers';
diff --git a/src/frontend/src/pages/document/Document.tsx b/src/frontend/src/pages/document/Document.tsx
index ea49adbb6..a22d94733 100644
--- a/src/frontend/src/pages/document/Document.tsx
+++ b/src/frontend/src/pages/document/Document.tsx
@@ -11,7 +11,6 @@ interface DocumentData {
const Document = (): JSX.Element => {
const params = useParams();
const [document, setDocument] = useState(null);
- const [error, setError] = useState(null);
const [isLoading, setIsLoading] = useState(false); // Step 1
useEffect(() => {
diff --git a/src/frontend/src/pages/draft/Draft.test.tsx b/src/frontend/src/pages/draft/Draft.test.tsx
index abcd558f6..0c963b934 100644
--- a/src/frontend/src/pages/draft/Draft.test.tsx
+++ b/src/frontend/src/pages/draft/Draft.test.tsx
@@ -1,13 +1,10 @@
import { render, screen, fireEvent, act, waitFor } from '@testing-library/react'
-import { BrowserRouter } from 'react-router-dom'
import { AppStateContext } from '../../state/AppProvider'
import Draft from './Draft'
-import { Section } from '../../api/models'
import { saveAs } from 'file-saver'
-import { defaultMockState } from '../../test/test.utils';
import { MemoryRouter } from 'react-router-dom';
-import { Document, Packer, Paragraph, TextRun } from 'docx'
+import { Document} from 'docx'
// Mocks for third-party components and modules
diff --git a/src/frontend/src/pages/draft/Draft.tsx b/src/frontend/src/pages/draft/Draft.tsx
index a02fa3e14..da6ebfe01 100644
--- a/src/frontend/src/pages/draft/Draft.tsx
+++ b/src/frontend/src/pages/draft/Draft.tsx
@@ -1,6 +1,6 @@
import { useContext, useEffect, useMemo, useState } from 'react'
import styles from './Draft.module.css'
-import { useLocation, useNavigate } from 'react-router-dom'
+import { useNavigate } from 'react-router-dom'
import TitleCard from '../../components/DraftCards/TitleCard'
import SectionCard from '../../components/DraftCards/SectionCard'
import { Document, Packer, Paragraph, TextRun } from 'docx'
@@ -11,7 +11,6 @@ import { Section } from '../../api/models'
const Draft = (): JSX.Element => {
const appStateContext = useContext(AppStateContext)
- const location = useLocation()
const navigate = useNavigate()
// get draftedDocument from context
diff --git a/src/frontend/src/pages/landing/Landing.tsx b/src/frontend/src/pages/landing/Landing.tsx
index 2fcb5b450..44332762a 100644
--- a/src/frontend/src/pages/landing/Landing.tsx
+++ b/src/frontend/src/pages/landing/Landing.tsx
@@ -1,4 +1,4 @@
-import { useRef, useState, useEffect, useContext, useLayoutEffect } from 'react'
+import { useContext } from 'react'
import { Stack } from '@fluentui/react'
import styles from './Landing.module.css'
import Contoso from '../../assets/Contoso.svg'
diff --git a/src/frontend/src/state/AppProvider.tsx b/src/frontend/src/state/AppProvider.tsx
index 7189731c9..f0238bc40 100644
--- a/src/frontend/src/state/AppProvider.tsx
+++ b/src/frontend/src/state/AppProvider.tsx
@@ -10,8 +10,7 @@ import {
Feedback,
FrontendSettings,
frontendSettings,
- historyEnsure,
- historyList
+ historyEnsure
} from '../api'
import { appStateReducer } from './AppReducer'
diff --git a/src/frontend/src/state/AppReducer.tsx b/src/frontend/src/state/AppReducer.tsx
index 8e9ebd967..4a6712324 100644
--- a/src/frontend/src/state/AppReducer.tsx
+++ b/src/frontend/src/state/AppReducer.tsx
@@ -108,16 +108,16 @@ export const appStateReducer = (state: AppState, action: Action): AppState => {
case 'SET_IS_REQUEST_INITIATED' :
return {...state, isRequestInitiated : action.payload}
case 'ADD_FAILED_SECTION':
- var tempFailedSections = [...state.failedSections];
- const exists = tempFailedSections.some((item) => item.title === action.payload.title);
- if (!exists)
+ const tempFailedSections = [...state.failedSections];
+ const exists = tempFailedSections.some((item) => item.title === action.payload.title);
+ if (!exists) {
tempFailedSections.push(action.payload);
- return { ...state , failedSections : [...tempFailedSections] }
- case 'REMOVED_FAILED_SECTION' :
- var tempFailedSections = [...state.failedSections];
- tempFailedSections = state.failedSections.filter((item) => item.title !== action.payload.section.title);
- return { ...state , failedSections : [...tempFailedSections] }
- case 'UPDATE_SECTION_API_REQ_STATUS' :
+ }
+ return { ...state, failedSections: [...tempFailedSections] }
+ case 'REMOVED_FAILED_SECTION':
+ const filteredFailedSections = state.failedSections.filter((item) => item.title !== action.payload.section.title);
+ return { ...state, failedSections: filteredFailedSections }
+ case 'UPDATE_SECTION_API_REQ_STATUS':
return {...state, isFailedReqInitiated : action.payload}
case 'UPDATE_IS_LOADED_SECTIONS' :
diff --git a/src/frontend/src/test/test.utils.tsx b/src/frontend/src/test/test.utils.tsx
index 34f1291c4..b9bfb767c 100644
--- a/src/frontend/src/test/test.utils.tsx
+++ b/src/frontend/src/test/test.utils.tsx
@@ -2,7 +2,7 @@
import React from 'react';
import { render, RenderResult } from '@testing-library/react';
import { AppStateContext } from '../state/AppProvider';
-import { Conversation, ChatHistoryLoadingState } from '../api/models';
+import { ChatHistoryLoadingState } from '../api/models';
// Default mock state
export const defaultMockState = {
isChatHistoryOpen: true,
diff --git a/tests/e2e-test/pages/browsePage.py b/tests/e2e-test/pages/browsePage.py
index a88233db6..5de638429 100644
--- a/tests/e2e-test/pages/browsePage.py
+++ b/tests/e2e-test/pages/browsePage.py
@@ -10,7 +10,7 @@ class BrowsePage(BasePage):
CLOSE_BUTTON = "//button[.='Close']"
def __init__(self, page):
- self.page = page
+ super().__init__(page)
def enter_a_question(self, text):
# Type a question in the text area
diff --git a/tests/e2e-test/pages/draftPage.py b/tests/e2e-test/pages/draftPage.py
index ead577aec..b6e96bded 100644
--- a/tests/e2e-test/pages/draftPage.py
+++ b/tests/e2e-test/pages/draftPage.py
@@ -13,7 +13,7 @@ class DraftPage(BasePage):
invalid_response1 = "There was an issue fetching your data. Please try again."
def __init__(self, page):
- self.page = page
+ super().__init__(page)
def validate_draft_sections_loaded(self):
max_wait_time = 180 # seconds
diff --git a/tests/e2e-test/pages/generatePage.py b/tests/e2e-test/pages/generatePage.py
index 92a55d062..2fbccd42d 100644
--- a/tests/e2e-test/pages/generatePage.py
+++ b/tests/e2e-test/pages/generatePage.py
@@ -19,7 +19,7 @@ class GeneratePage(BasePage):
CHAT_HISTORY_CLOSE = "//i[@data-icon-name='Cancel']"
def __init__(self, page):
- self.page = page
+ super().__init__(page)
def enter_a_question(self, text):
# Type a question in the text area
diff --git a/tests/e2e-test/pages/homePage.py b/tests/e2e-test/pages/homePage.py
index 9bacc0934..bda0333d9 100644
--- a/tests/e2e-test/pages/homePage.py
+++ b/tests/e2e-test/pages/homePage.py
@@ -15,7 +15,7 @@ class HomePage(BasePage):
)
def __init__(self, page):
- self.page = page
+ super().__init__(page)
def click_browse_button(self):
# click on BROWSE