mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-09-19 20:24:32 +02:00
Match any/all keywords in Standard Answers (#2443)
* migration: add column "match_any_keywords" to StandardAnswer * Implement any/all keyword matching for standard answers * Add match_any_keywords to non-searchable fields * Remove stray print * Simplify Slack messages for any and all cases --------- Co-authored-by: danswer-trial <danswer-trial@danswer-trials-MacBook-Pro.local>
This commit is contained in:
@@ -9,15 +9,25 @@ import * as Yup from "yup";
|
||||
import {
|
||||
createStandardAnswer,
|
||||
createStandardAnswerCategory,
|
||||
StandardAnswerCreationRequest,
|
||||
updateStandardAnswer,
|
||||
} from "./lib";
|
||||
import {
|
||||
TextFormField,
|
||||
MarkdownFormField,
|
||||
BooleanFormField,
|
||||
SelectorFormField,
|
||||
} from "@/components/admin/connectors/Field";
|
||||
import MultiSelectDropdown from "@/components/MultiSelectDropdown";
|
||||
|
||||
function mapKeywordSelectToMatchAny(keywordSelect: "any" | "all"): boolean {
|
||||
return keywordSelect == "any";
|
||||
}
|
||||
|
||||
function mapMatchAnyToKeywordSelect(matchAny: boolean): "any" | "all" {
|
||||
return matchAny ? "any" : "all";
|
||||
}
|
||||
|
||||
export const StandardAnswerCreationForm = ({
|
||||
standardAnswerCategories,
|
||||
existingStandardAnswer,
|
||||
@@ -45,6 +55,11 @@ export const StandardAnswerCreationForm = ({
|
||||
matchRegex: existingStandardAnswer
|
||||
? existingStandardAnswer.match_regex
|
||||
: false,
|
||||
matchAnyKeywords: existingStandardAnswer
|
||||
? mapMatchAnyToKeywordSelect(
|
||||
existingStandardAnswer.match_any_keywords
|
||||
)
|
||||
: "all",
|
||||
}}
|
||||
validationSchema={Yup.object().shape({
|
||||
keyword: Yup.string()
|
||||
@@ -59,8 +74,11 @@ export const StandardAnswerCreationForm = ({
|
||||
onSubmit={async (values, formikHelpers) => {
|
||||
formikHelpers.setSubmitting(true);
|
||||
|
||||
const cleanedValues = {
|
||||
const cleanedValues: StandardAnswerCreationRequest = {
|
||||
...values,
|
||||
matchAnyKeywords: mapKeywordSelectToMatchAny(
|
||||
values.matchAnyKeywords
|
||||
),
|
||||
categories: values.categories.map((category) => category.id),
|
||||
};
|
||||
|
||||
@@ -98,11 +116,19 @@ export const StandardAnswerCreationForm = ({
|
||||
tooltip="Triggers if the question matches this regex pattern (using Python `re.search()`)"
|
||||
placeholder="(?:it|support)\s*ticket"
|
||||
/>
|
||||
) : values.matchAnyKeywords == "any" ? (
|
||||
<TextFormField
|
||||
name="keyword"
|
||||
label="Any of these keywords, separated by spaces"
|
||||
tooltip="A question must match these keywords in order to trigger the answer."
|
||||
placeholder="ticket problem issue"
|
||||
autoCompleteDisabled={true}
|
||||
/>
|
||||
) : (
|
||||
<TextFormField
|
||||
name="keyword"
|
||||
label="Keywords"
|
||||
tooltip="Triggers if the question contains all of these keywords, in any order."
|
||||
label="All of these keywords, in any order, separated by spaces"
|
||||
tooltip="A question must match these keywords in order to trigger the answer."
|
||||
placeholder="it ticket"
|
||||
autoCompleteDisabled={true}
|
||||
/>
|
||||
@@ -113,6 +139,27 @@ export const StandardAnswerCreationForm = ({
|
||||
label="Match regex"
|
||||
name="matchRegex"
|
||||
/>
|
||||
{values.matchRegex ? null : (
|
||||
<SelectorFormField
|
||||
defaultValue={`all`}
|
||||
label="Keyword detection strategy"
|
||||
subtext="Choose whether to require the user's question to contain any or all of the keywords above to show this answer."
|
||||
name="matchAnyKeywords"
|
||||
options={[
|
||||
{
|
||||
name: "All keywords",
|
||||
value: "all",
|
||||
},
|
||||
{
|
||||
name: "Any keywords",
|
||||
value: "any",
|
||||
},
|
||||
]}
|
||||
onSelect={(selected) => {
|
||||
setFieldValue("matchAnyKeywords", selected);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<div className="w-full">
|
||||
<MarkdownFormField
|
||||
name="answer"
|
||||
|
@@ -7,6 +7,7 @@ export interface StandardAnswerCreationRequest {
|
||||
answer: string;
|
||||
categories: number[];
|
||||
matchRegex: boolean;
|
||||
matchAnyKeywords: boolean;
|
||||
}
|
||||
|
||||
const buildRequestBodyFromStandardAnswerCategoryCreationRequest = (
|
||||
@@ -50,6 +51,7 @@ const buildRequestBodyFromStandardAnswerCreationRequest = (
|
||||
answer: request.answer,
|
||||
categories: request.categories,
|
||||
match_regex: request.matchRegex,
|
||||
match_any_keywords: request.matchAnyKeywords,
|
||||
});
|
||||
};
|
||||
|
||||
|
@@ -171,8 +171,14 @@ const StandardAnswersTable = ({
|
||||
];
|
||||
|
||||
const filteredStandardAnswers = standardAnswers.filter((standardAnswer) => {
|
||||
const { answer, id, categories, match_regex, ...fieldsToSearch } =
|
||||
standardAnswer;
|
||||
const {
|
||||
answer,
|
||||
id,
|
||||
categories,
|
||||
match_regex,
|
||||
match_any_keywords,
|
||||
...fieldsToSearch
|
||||
} = standardAnswer;
|
||||
const cleanedQuery = query.toLowerCase();
|
||||
const searchMatch = Object.values(fieldsToSearch).some((value) => {
|
||||
return value.toLowerCase().includes(cleanedQuery);
|
||||
|
@@ -162,6 +162,7 @@ export interface StandardAnswer {
|
||||
keyword: string;
|
||||
answer: string;
|
||||
match_regex: boolean;
|
||||
match_any_keywords: boolean;
|
||||
categories: StandardAnswerCategory[];
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user