diff --git a/app/frontend/src/components/Settings/Settings.module.css b/app/frontend/src/components/Settings/Settings.module.css
new file mode 100644
index 0000000000..1d512e58e2
--- /dev/null
+++ b/app/frontend/src/components/Settings/Settings.module.css
@@ -0,0 +1,3 @@
+.settingsSeparator {
+ margin-top: 0.75rem;
+}
diff --git a/app/frontend/src/components/Settings/Settings.tsx b/app/frontend/src/components/Settings/Settings.tsx
new file mode 100644
index 0000000000..de404297ab
--- /dev/null
+++ b/app/frontend/src/components/Settings/Settings.tsx
@@ -0,0 +1,316 @@
+import { useId } from "@fluentui/react-hooks";
+import { useTranslation } from "react-i18next";
+import { TextField, ITextFieldProps, Checkbox, ICheckboxProps, Dropdown, IDropdownProps, IDropdownOption } from "@fluentui/react";
+import { HelpCallout } from "../HelpCallout";
+import { GPT4VSettings } from "../GPT4VSettings";
+import { VectorSettings } from "../VectorSettings";
+import { RetrievalMode, VectorFieldOptions, GPT4VInput } from "../../api";
+import styles from "./Settings.module.css";
+
+// Add type for onRenderLabel
+type RenderLabelType = ITextFieldProps | IDropdownProps | ICheckboxProps;
+
+export interface SettingsProps {
+ promptTemplate: string;
+ temperature: number;
+ retrieveCount: number;
+ seed: number | null;
+ minimumSearchScore: number;
+ minimumRerankerScore: number;
+ useSemanticRanker: boolean;
+ useSemanticCaptions: boolean;
+ excludeCategory: string;
+ includeCategory: string;
+ retrievalMode: RetrievalMode;
+ useGPT4V: boolean;
+ gpt4vInput: GPT4VInput;
+ vectorFieldList: VectorFieldOptions[];
+ showSemanticRankerOption: boolean;
+ showGPT4VOptions: boolean;
+ showVectorOption: boolean;
+ useOidSecurityFilter: boolean;
+ useGroupsSecurityFilter: boolean;
+ useLogin: boolean;
+ loggedIn: boolean;
+ requireAccessControl: boolean;
+ className?: string;
+ onChange: (field: string, value: any) => void;
+ shouldStream?: boolean; // Only used in Chat
+ useSuggestFollowupQuestions?: boolean; // Only used in Chat
+ promptTemplatePrefix?: string;
+ promptTemplateSuffix?: string;
+ showSuggestFollowupQuestions?: boolean;
+}
+
+export const Settings = ({
+ promptTemplate,
+ temperature,
+ retrieveCount,
+ seed,
+ minimumSearchScore,
+ minimumRerankerScore,
+ useSemanticRanker,
+ useSemanticCaptions,
+ excludeCategory,
+ includeCategory,
+ retrievalMode,
+ useGPT4V,
+ gpt4vInput,
+ vectorFieldList,
+ showSemanticRankerOption,
+ showGPT4VOptions,
+ showVectorOption,
+ useOidSecurityFilter,
+ useGroupsSecurityFilter,
+ useLogin,
+ loggedIn,
+ requireAccessControl,
+ className,
+ onChange,
+ shouldStream,
+ useSuggestFollowupQuestions,
+ promptTemplatePrefix,
+ promptTemplateSuffix,
+ showSuggestFollowupQuestions
+}: SettingsProps) => {
+ const { t } = useTranslation();
+
+ // Form field IDs
+ const promptTemplateId = useId("promptTemplate");
+ const promptTemplateFieldId = useId("promptTemplateField");
+ const temperatureId = useId("temperature");
+ const temperatureFieldId = useId("temperatureField");
+ const seedId = useId("seed");
+ const seedFieldId = useId("seedField");
+ const searchScoreId = useId("searchScore");
+ const searchScoreFieldId = useId("searchScoreField");
+ const rerankerScoreId = useId("rerankerScore");
+ const rerankerScoreFieldId = useId("rerankerScoreField");
+ const retrieveCountId = useId("retrieveCount");
+ const retrieveCountFieldId = useId("retrieveCountField");
+ const includeCategoryId = useId("includeCategory");
+ const includeCategoryFieldId = useId("includeCategoryField");
+ const excludeCategoryId = useId("excludeCategory");
+ const excludeCategoryFieldId = useId("excludeCategoryField");
+ const semanticRankerId = useId("semanticRanker");
+ const semanticRankerFieldId = useId("semanticRankerField");
+ const semanticCaptionsId = useId("semanticCaptions");
+ const semanticCaptionsFieldId = useId("semanticCaptionsField");
+ const useOidSecurityFilterId = useId("useOidSecurityFilter");
+ const useOidSecurityFilterFieldId = useId("useOidSecurityFilterField");
+ const useGroupsSecurityFilterId = useId("useGroupsSecurityFilter");
+ const useGroupsSecurityFilterFieldId = useId("useGroupsSecurityFilterField");
+ const shouldStreamId = useId("shouldStream");
+ const shouldStreamFieldId = useId("shouldStreamField");
+ const suggestFollowupQuestionsId = useId("suggestFollowupQuestions");
+ const suggestFollowupQuestionsFieldId = useId("suggestFollowupQuestionsField");
+
+ const renderLabel = (props: RenderLabelType | undefined, labelId: string, fieldId: string, helpText: string) => (
+
+ );
+
+ return (
+
+ onChange("promptTemplate", val || "")}
+ aria-labelledby={promptTemplateId}
+ onRenderLabel={props => renderLabel(props, promptTemplateId, promptTemplateFieldId, t("helpTexts.promptTemplate"))}
+ />
+
+ onChange("temperature", parseFloat(val || "0"))}
+ aria-labelledby={temperatureId}
+ onRenderLabel={props => renderLabel(props, temperatureId, temperatureFieldId, t("helpTexts.temperature"))}
+ />
+
+ onChange("seed", val ? parseInt(val) : null)}
+ aria-labelledby={seedId}
+ onRenderLabel={props => renderLabel(props, seedId, seedFieldId, t("helpTexts.seed"))}
+ />
+
+ onChange("minimumSearchScore", parseFloat(val || "0"))}
+ aria-labelledby={searchScoreId}
+ onRenderLabel={props => renderLabel(props, searchScoreId, searchScoreFieldId, t("helpTexts.searchScore"))}
+ />
+
+ {showSemanticRankerOption && (
+ onChange("minimumRerankerScore", parseFloat(val || "0"))}
+ aria-labelledby={rerankerScoreId}
+ onRenderLabel={props => renderLabel(props, rerankerScoreId, rerankerScoreFieldId, t("helpTexts.rerankerScore"))}
+ />
+ )}
+
+ onChange("retrieveCount", parseInt(val || "3"))}
+ aria-labelledby={retrieveCountId}
+ onRenderLabel={props => renderLabel(props, retrieveCountId, retrieveCountFieldId, t("helpTexts.retrieveNumber"))}
+ />
+
+ , option?: IDropdownOption) => onChange("includeCategory", option?.key || "")}
+ aria-labelledby={includeCategoryId}
+ options={[
+ { key: "", text: t("labels.includeCategoryOptions.all") }
+ // { key: "example", text: "Example Category" } // Add more categories as needed
+ ]}
+ onRenderLabel={props => renderLabel(props, includeCategoryId, includeCategoryFieldId, t("helpTexts.includeCategory"))}
+ />
+
+ onChange("excludeCategory", val || "")}
+ aria-labelledby={excludeCategoryId}
+ onRenderLabel={props => renderLabel(props, excludeCategoryId, excludeCategoryFieldId, t("helpTexts.excludeCategory"))}
+ />
+
+ {showSemanticRankerOption && (
+ <>
+ onChange("useSemanticRanker", !!checked)}
+ aria-labelledby={semanticRankerId}
+ onRenderLabel={props => renderLabel(props, semanticRankerId, semanticRankerFieldId, t("helpTexts.useSemanticReranker"))}
+ />
+
+ onChange("useSemanticCaptions", !!checked)}
+ disabled={!useSemanticRanker}
+ aria-labelledby={semanticCaptionsId}
+ onRenderLabel={props => renderLabel(props, semanticCaptionsId, semanticCaptionsFieldId, t("helpTexts.useSemanticCaptions"))}
+ />
+ >
+ )}
+
+ {useLogin && (
+ <>
+ onChange("useOidSecurityFilter", !!checked)}
+ aria-labelledby={useOidSecurityFilterId}
+ onRenderLabel={props => renderLabel(props, useOidSecurityFilterId, useOidSecurityFilterFieldId, t("helpTexts.useOidSecurityFilter"))}
+ />
+ onChange("useGroupsSecurityFilter", !!checked)}
+ aria-labelledby={useGroupsSecurityFilterId}
+ onRenderLabel={props =>
+ renderLabel(props, useGroupsSecurityFilterId, useGroupsSecurityFilterFieldId, t("helpTexts.useGroupsSecurityFilter"))
+ }
+ />
+ >
+ )}
+
+ {showGPT4VOptions && (
+ onChange("useGPT4V", val)}
+ updateGPT4VInputs={val => onChange("gpt4vInput", val)}
+ />
+ )}
+
+ {showVectorOption && (
+ onChange("vectorFieldList", val)}
+ updateRetrievalMode={val => onChange("retrievalMode", val)}
+ />
+ )}
+
+ {/* Streaming checkbox for Chat */}
+ {shouldStream !== undefined && (
+ onChange("shouldStream", !!checked)}
+ aria-labelledby={shouldStreamId}
+ onRenderLabel={props => renderLabel(props, shouldStreamId, shouldStreamFieldId, t("helpTexts.streamChat"))}
+ />
+ )}
+
+ {/* Followup questions checkbox for Chat */}
+ {showSuggestFollowupQuestions && (
+ onChange("useSuggestFollowupQuestions", !!checked)}
+ aria-labelledby={suggestFollowupQuestionsId}
+ onRenderLabel={props =>
+ renderLabel(props, suggestFollowupQuestionsId, suggestFollowupQuestionsFieldId, t("helpTexts.suggestFollowupQuestions"))
+ }
+ />
+ )}
+
+ );
+};
diff --git a/app/frontend/src/pages/ask/Ask.tsx b/app/frontend/src/pages/ask/Ask.tsx
index d336a4566c..35137afb3d 100644
--- a/app/frontend/src/pages/ask/Ask.tsx
+++ b/app/frontend/src/pages/ask/Ask.tsx
@@ -1,19 +1,7 @@
import { useContext, useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { Helmet } from "react-helmet-async";
-import {
- Checkbox,
- Panel,
- DefaultButton,
- Spinner,
- TextField,
- ICheckboxProps,
- ITextFieldProps,
- Dropdown,
- IDropdownOption,
- IDropdownProps
-} from "@fluentui/react";
-import { useId } from "@fluentui/react-hooks";
+import { Panel, DefaultButton, Spinner } from "@fluentui/react";
import styles from "./Ask.module.css";
@@ -22,13 +10,10 @@ import { Answer, AnswerError } from "../../components/Answer";
import { QuestionInput } from "../../components/QuestionInput";
import { ExampleList } from "../../components/Example";
import { AnalysisPanel, AnalysisPanelTabs } from "../../components/AnalysisPanel";
-import { HelpCallout } from "../../components/HelpCallout";
import { SettingsButton } from "../../components/SettingsButton/SettingsButton";
-import { useLogin, getToken, requireAccessControl, checkLoggedIn } from "../../authConfig";
-import { VectorSettings } from "../../components/VectorSettings";
-import { GPT4VSettings } from "../../components/GPT4VSettings";
+import { useLogin, getToken, requireAccessControl } from "../../authConfig";
import { UploadFile } from "../../components/UploadFile";
-
+import { Settings } from "../../components/Settings/Settings";
import { useMsal } from "@azure/msal-react";
import { TokenClaimsDisplay } from "../../components/TokenClaimsDisplay";
import { LoginContext } from "../../loginContext";
@@ -163,43 +148,63 @@ export function Component(): JSX.Element {
}
};
- const onPromptTemplateChange = (_ev?: React.FormEvent, newValue?: string) => {
- setPromptTemplate(newValue || "");
- };
-
- const onTemperatureChange = (_ev?: React.SyntheticEvent, newValue?: string) => {
- setTemperature(parseFloat(newValue || "0"));
- };
-
- const onSeedChange = (_ev?: React.SyntheticEvent, newValue?: string) => {
- setSeed(parseInt(newValue || ""));
- };
-
- const onMinimumSearchScoreChange = (_ev?: React.SyntheticEvent, newValue?: string) => {
- setMinimumSearchScore(parseFloat(newValue || "0"));
- };
-
- const onMinimumRerankerScoreChange = (_ev?: React.SyntheticEvent, newValue?: string) => {
- setMinimumRerankerScore(parseFloat(newValue || "0"));
- };
- const onRetrieveCountChange = (_ev?: React.SyntheticEvent, newValue?: string) => {
- setRetrieveCount(parseInt(newValue || "3"));
- };
-
- const onUseSemanticRankerChange = (_ev?: React.FormEvent, checked?: boolean) => {
- setUseSemanticRanker(!!checked);
- };
-
- const onUseSemanticCaptionsChange = (_ev?: React.FormEvent, checked?: boolean) => {
- setUseSemanticCaptions(!!checked);
- };
-
- const onIncludeCategoryChanged = (_ev?: React.FormEvent, option?: IDropdownOption) => {
- setIncludeCategory((option?.key as string) || "");
- };
-
- const onExcludeCategoryChanged = (_ev?: React.FormEvent, newValue?: string) => {
- setExcludeCategory(newValue || "");
+ const handleSettingsChange = (field: string, value: any) => {
+ switch (field) {
+ case "promptTemplate":
+ setPromptTemplate(value);
+ break;
+ case "promptTemplatePrefix":
+ setPromptTemplatePrefix(value);
+ break;
+ case "promptTemplateSuffix":
+ setPromptTemplateSuffix(value);
+ break;
+ case "temperature":
+ setTemperature(value);
+ break;
+ case "seed":
+ setSeed(value);
+ break;
+ case "minimumRerankerScore":
+ setMinimumRerankerScore(value);
+ break;
+ case "minimumSearchScore":
+ setMinimumSearchScore(value);
+ break;
+ case "retrieveCount":
+ setRetrieveCount(value);
+ break;
+ case "useSemanticRanker":
+ setUseSemanticRanker(value);
+ break;
+ case "useSemanticCaptions":
+ setUseSemanticCaptions(value);
+ break;
+ case "excludeCategory":
+ setExcludeCategory(value);
+ break;
+ case "includeCategory":
+ setIncludeCategory(value);
+ break;
+ case "useOidSecurityFilter":
+ setUseOidSecurityFilter(value);
+ break;
+ case "useGroupsSecurityFilter":
+ setUseGroupsSecurityFilter(value);
+ break;
+ case "useGPT4V":
+ setUseGPT4V(value);
+ break;
+ case "gpt4vInput":
+ setGPT4VInput(value);
+ break;
+ case "vectorFieldList":
+ setVectorFieldList(value);
+ break;
+ case "retrievalMode":
+ setRetrievalMode(value);
+ break;
+ }
};
const onExampleClicked = (example: string) => {
@@ -232,31 +237,6 @@ export function Component(): JSX.Element {
setUseGroupsSecurityFilter(!!checked);
};
- // IDs for form labels and their associated callouts
- const promptTemplateId = useId("promptTemplate");
- const promptTemplateFieldId = useId("promptTemplateField");
- const temperatureId = useId("temperature");
- const temperatureFieldId = useId("temperatureField");
- const seedId = useId("seed");
- const seedFieldId = useId("seedField");
- const searchScoreId = useId("searchScore");
- const searchScoreFieldId = useId("searchScoreField");
- const rerankerScoreId = useId("rerankerScore");
- const rerankerScoreFieldId = useId("rerankerScoreField");
- const retrieveCountId = useId("retrieveCount");
- const retrieveCountFieldId = useId("retrieveCountField");
- const includeCategoryId = useId("includeCategory");
- const includeCategoryFieldId = useId("includeCategoryField");
- const excludeCategoryId = useId("excludeCategory");
- const excludeCategoryFieldId = useId("excludeCategoryField");
- const semanticRankerId = useId("semanticRanker");
- const semanticRankerFieldId = useId("semanticRankerField");
- const semanticCaptionsId = useId("semanticCaptions");
- const semanticCaptionsFieldId = useId("semanticCaptionsField");
- const useOidSecurityFilterId = useId("useOidSecurityFilter");
- const useOidSecurityFilterFieldId = useId("useOidSecurityFilterField");
- const useGroupsSecurityFilterId = useId("useGroupsSecurityFilter");
- const useGroupsSecurityFilterFieldId = useId("useGroupsSecurityFilterField");
const { t, i18n } = useTranslation();
return (
@@ -330,234 +310,33 @@ export function Component(): JSX.Element {
onRenderFooterContent={() => setIsConfigPanelOpen(false)}>{t("labels.closeButton")}}
isFooterAtBottom={true}
>
- (
-
- )}
+
-
- (
-
- )}
- />
-
- (
-
- )}
- />
-
- (
-
- )}
- />
-
- {showSemanticRankerOption && (
- (
-
- )}
- />
- )}
-
- (
-
- )}
- />
-
- (
-
- )}
- />
-
- (
-
- )}
- />
-
- {showSemanticRankerOption && (
- <>
- (
-
- )}
- />
-
- (
-
- )}
- />
- >
- )}
-
- {showGPT4VOptions && (
- {
- setUseGPT4V(useGPT4V);
- }}
- updateGPT4VInputs={inputs => setGPT4VInput(inputs)}
- />
- )}
-
- {showVectorOption && (
- setVectorFieldList(options)}
- updateRetrievalMode={(retrievalMode: RetrievalMode) => setRetrievalMode(retrievalMode)}
- />
- )}
-
- {useLogin && (
- <>
- (
-
- )}
- />
- (
-
- )}
- />
- >
- )}
{useLogin && }
diff --git a/app/frontend/src/pages/chat/Chat.tsx b/app/frontend/src/pages/chat/Chat.tsx
index a68f47b9b0..1fa09ec511 100644
--- a/app/frontend/src/pages/chat/Chat.tsx
+++ b/app/frontend/src/pages/chat/Chat.tsx
@@ -1,9 +1,8 @@
import { useRef, useState, useEffect, useContext } from "react";
import { useTranslation } from "react-i18next";
import { Helmet } from "react-helmet-async";
-import { Checkbox, Panel, DefaultButton, TextField, ITextFieldProps, ICheckboxProps, Dropdown, IDropdownOption, IDropdownProps } from "@fluentui/react";
+import { Panel, DefaultButton } from "@fluentui/react";
import { SparkleFilled } from "@fluentui/react-icons";
-import { useId } from "@fluentui/react-hooks";
import readNDJSONStream from "ndjson-readablestream";
import styles from "./Chat.module.css";
@@ -24,7 +23,6 @@ import { Answer, AnswerError, AnswerLoading } from "../../components/Answer";
import { QuestionInput } from "../../components/QuestionInput";
import { ExampleList } from "../../components/Example";
import { UserChatMessage } from "../../components/UserChatMessage";
-import { HelpCallout } from "../../components/HelpCallout";
import { AnalysisPanel, AnalysisPanelTabs } from "../../components/AnalysisPanel";
import { HistoryPanel } from "../../components/HistoryPanel";
import { HistoryProviderOptions, useHistoryManager } from "../../components/HistoryProviders";
@@ -33,12 +31,11 @@ import { SettingsButton } from "../../components/SettingsButton";
import { ClearChatButton } from "../../components/ClearChatButton";
import { UploadFile } from "../../components/UploadFile";
import { useLogin, getToken, requireAccessControl } from "../../authConfig";
-import { VectorSettings } from "../../components/VectorSettings";
import { useMsal } from "@azure/msal-react";
import { TokenClaimsDisplay } from "../../components/TokenClaimsDisplay";
-import { GPT4VSettings } from "../../components/GPT4VSettings";
import { LoginContext } from "../../loginContext";
import { LanguagePicker } from "../../i18n/LanguagePicker";
+import { Settings } from "../../components/Settings/Settings";
const Chat = () => {
const [isConfigPanelOpen, setIsConfigPanelOpen] = useState(false);
@@ -257,60 +254,63 @@ const Chat = () => {
getConfig();
}, []);
- const onPromptTemplateChange = (_ev?: React.FormEvent, newValue?: string) => {
- setPromptTemplate(newValue || "");
- };
-
- const onTemperatureChange = (_ev?: React.SyntheticEvent, newValue?: string) => {
- setTemperature(parseFloat(newValue || "0"));
- };
-
- const onSeedChange = (_ev?: React.SyntheticEvent, newValue?: string) => {
- setSeed(parseInt(newValue || ""));
- };
-
- const onMinimumSearchScoreChange = (_ev?: React.SyntheticEvent, newValue?: string) => {
- setMinimumSearchScore(parseFloat(newValue || "0"));
- };
-
- const onMinimumRerankerScoreChange = (_ev?: React.SyntheticEvent, newValue?: string) => {
- setMinimumRerankerScore(parseFloat(newValue || "0"));
- };
-
- const onRetrieveCountChange = (_ev?: React.SyntheticEvent, newValue?: string) => {
- setRetrieveCount(parseInt(newValue || "3"));
- };
-
- const onUseSemanticRankerChange = (_ev?: React.FormEvent, checked?: boolean) => {
- setUseSemanticRanker(!!checked);
- };
-
- const onUseSemanticCaptionsChange = (_ev?: React.FormEvent, checked?: boolean) => {
- setUseSemanticCaptions(!!checked);
- };
-
- const onShouldStreamChange = (_ev?: React.FormEvent, checked?: boolean) => {
- setShouldStream(!!checked);
- };
-
- const onIncludeCategoryChanged = (_ev?: React.FormEvent, option?: IDropdownOption) => {
- setIncludeCategory((option?.key as string) || "");
- };
-
- const onExcludeCategoryChanged = (_ev?: React.FormEvent, newValue?: string) => {
- setExcludeCategory(newValue || "");
- };
-
- const onUseSuggestFollowupQuestionsChange = (_ev?: React.FormEvent, checked?: boolean) => {
- setUseSuggestFollowupQuestions(!!checked);
- };
-
- const onUseOidSecurityFilterChange = (_ev?: React.FormEvent, checked?: boolean) => {
- setUseOidSecurityFilter(!!checked);
- };
-
- const onUseGroupsSecurityFilterChange = (_ev?: React.FormEvent, checked?: boolean) => {
- setUseGroupsSecurityFilter(!!checked);
+ const handleSettingsChange = (field: string, value: any) => {
+ switch (field) {
+ case "promptTemplate":
+ setPromptTemplate(value);
+ break;
+ case "temperature":
+ setTemperature(value);
+ break;
+ case "seed":
+ setSeed(value);
+ break;
+ case "minimumRerankerScore":
+ setMinimumRerankerScore(value);
+ break;
+ case "minimumSearchScore":
+ setMinimumSearchScore(value);
+ break;
+ case "retrieveCount":
+ setRetrieveCount(value);
+ break;
+ case "useSemanticRanker":
+ setUseSemanticRanker(value);
+ break;
+ case "useSemanticCaptions":
+ setUseSemanticCaptions(value);
+ break;
+ case "excludeCategory":
+ setExcludeCategory(value);
+ break;
+ case "includeCategory":
+ setIncludeCategory(value);
+ break;
+ case "useOidSecurityFilter":
+ setUseOidSecurityFilter(value);
+ break;
+ case "useGroupsSecurityFilter":
+ setUseGroupsSecurityFilter(value);
+ break;
+ case "shouldStream":
+ setShouldStream(value);
+ break;
+ case "useSuggestFollowupQuestions":
+ setUseSuggestFollowupQuestions(value);
+ break;
+ case "useGPT4V":
+ setUseGPT4V(value);
+ break;
+ case "gpt4vInput":
+ setGPT4VInput(value);
+ break;
+ case "vectorFieldList":
+ setVectorFieldList(value);
+ break;
+ case "retrievalMode":
+ setRetrievalMode(value);
+ break;
+ }
};
const onExampleClicked = (example: string) => {
@@ -338,35 +338,6 @@ const Chat = () => {
setSelectedAnswer(index);
};
- // IDs for form labels and their associated callouts
- const promptTemplateId = useId("promptTemplate");
- const promptTemplateFieldId = useId("promptTemplateField");
- const temperatureId = useId("temperature");
- const temperatureFieldId = useId("temperatureField");
- const seedId = useId("seed");
- const seedFieldId = useId("seedField");
- const searchScoreId = useId("searchScore");
- const searchScoreFieldId = useId("searchScoreField");
- const rerankerScoreId = useId("rerankerScore");
- const rerankerScoreFieldId = useId("rerankerScoreField");
- const retrieveCountId = useId("retrieveCount");
- const retrieveCountFieldId = useId("retrieveCountField");
- const includeCategoryId = useId("includeCategory");
- const includeCategoryFieldId = useId("includeCategoryField");
- const excludeCategoryId = useId("excludeCategory");
- const excludeCategoryFieldId = useId("excludeCategoryField");
- const semanticRankerId = useId("semanticRanker");
- const semanticRankerFieldId = useId("semanticRankerField");
- const semanticCaptionsId = useId("semanticCaptions");
- const semanticCaptionsFieldId = useId("semanticCaptionsField");
- const suggestFollowupQuestionsId = useId("suggestFollowupQuestions");
- const suggestFollowupQuestionsFieldId = useId("suggestFollowupQuestionsField");
- const useOidSecurityFilterId = useId("useOidSecurityFilter");
- const useOidSecurityFilterFieldId = useId("useOidSecurityFilterField");
- const useGroupsSecurityFilterId = useId("useGroupsSecurityFilter");
- const useGroupsSecurityFilterFieldId = useId("useGroupsSecurityFilterField");
- const shouldStreamId = useId("shouldStream");
- const shouldStreamFieldId = useId("shouldStreamField");
const { t, i18n } = useTranslation();
return (
@@ -509,280 +480,34 @@ const Chat = () => {
onRenderFooterContent={() => setIsConfigPanelOpen(false)}>{t("labels.closeButton")}}
isFooterAtBottom={true}
>
- (
-
- )}
- />
-
- (
-
- )}
+
-
- (
-
- )}
- />
-
- (
-
- )}
- />
-
- {showSemanticRankerOption && (
- (
-
- )}
- />
- )}
-
- (
-
- )}
- />
-
- (
-
- )}
- />
-
- (
-
- )}
- />
-
- {showSemanticRankerOption && (
- <>
- (
-
- )}
- />
-
- (
-
- )}
- />
- >
- )}
-
- (
-
- )}
- />
-
- {showGPT4VOptions && (
- {
- setUseGPT4V(useGPT4V);
- }}
- updateGPT4VInputs={inputs => setGPT4VInput(inputs)}
- />
- )}
-
- {showVectorOption && (
- setVectorFieldList(options)}
- updateRetrievalMode={(retrievalMode: RetrievalMode) => setRetrievalMode(retrievalMode)}
- />
- )}
-
- {useLogin && (
- <>
- (
-
- )}
- />
- (
-
- )}
- />
- >
- )}
-
- (
-
- )}
- />
-
{useLogin && }
diff --git a/docs/data_ingestion.md b/docs/data_ingestion.md
index 1d317b6345..1837018154 100644
--- a/docs/data_ingestion.md
+++ b/docs/data_ingestion.md
@@ -57,7 +57,7 @@ If needed, you can modify the chunking algorithm in `scripts/prepdocslib/textspl
To enhance search functionality, categorize data during the ingestion process with the `--category` argument, for example `scripts/prepdocs.ps1 --category ExampleCategoryName`. This argument specifies the category to which the data belongs, enabling you to filter search results based on these categories.
-After running the script with the desired category, ensure these categories are added to the 'Include Category' dropdown list. This can be found in the developer settings of [`Chat.tsx`](../app/frontend/src/pages/chat/Chat.tsx) and [`Ask.tsx`](../app/frontend/src/pages/ask/Ask.tsx). The default option for this dropdown is "All". By including specific categories, you can refine your search results more effectively.
+After running the script with the desired category, ensure these categories are added to the 'Include Category' dropdown list. This can be found in the developer settings in [`Settings.tsx`](/app/frontend/src/components/settings/Settings.tsx). The default option for this dropdown is "All". By including specific categories, you can refine your search results more effectively.
### Indexing additional documents
diff --git a/tests/e2e.py b/tests/e2e.py
index b176d6f6d0..de3f458ac9 100644
--- a/tests/e2e.py
+++ b/tests/e2e.py
@@ -145,12 +145,17 @@ def test_chat_customization(page: Page, live_server_url: str):
# Set up a mock route to the /chat endpoint
def handle(route: Route):
overrides = route.request.post_data_json["context"]["overrides"]
+ assert overrides["temperature"] == 0.5
+ assert overrides["seed"] == 123
+ assert overrides["minimum_search_score"] == 0.5
+ assert overrides["minimum_reranker_score"] == 0.5
assert overrides["retrieval_mode"] == "vectors"
assert overrides["semantic_ranker"] is False
assert overrides["semantic_captions"] is True
assert overrides["top"] == 1
assert overrides["prompt_template"] == "You are a cat and only talk about tuna."
assert overrides["exclude_category"] == "dogs"
+ assert overrides["suggest_followup_questions"] is True
assert overrides["use_oid_security_filter"] is False
assert overrides["use_groups_security_filter"] is False
@@ -170,12 +175,23 @@ def handle(route: Route):
page.get_by_role("button", name="Developer settings").click()
page.get_by_label("Override prompt template").click()
page.get_by_label("Override prompt template").fill("You are a cat and only talk about tuna.")
+ page.get_by_label("Temperature").click()
+ page.get_by_label("Temperature").fill("0.5")
+ page.get_by_label("Seed").click()
+ page.get_by_label("Seed").fill("123")
+ page.get_by_label("Minimum search score").click()
+ page.get_by_label("Minimum search score").fill("0.5")
+ page.get_by_label("Minimum reranker score").click()
+ page.get_by_label("Minimum reranker score").fill("0.5")
page.get_by_label("Retrieve this many search results:").click()
page.get_by_label("Retrieve this many search results:").fill("1")
+ page.get_by_label("Include category").click()
+ page.get_by_role("option", name="All", exact=True).click()
page.get_by_label("Exclude category").click()
page.get_by_label("Exclude category").fill("dogs")
page.get_by_text("Use semantic captions").click()
page.get_by_text("Use semantic ranker for retrieval").click()
+ page.get_by_text("Suggest follow-up questions").click()
page.get_by_text("Vectors + Text (Hybrid)").click()
page.get_by_role("option", name="Vectors", exact=True).click()
page.get_by_text("Stream chat completion responses").click()