Skip to content

Commit

Permalink
Onboard basic sentiment analysis with defaults (#350)
Browse files Browse the repository at this point in the history
Signed-off-by: Tyler Ohlsen <[email protected]>
  • Loading branch information
ohltyler authored Sep 9, 2024
1 parent 3e35af2 commit 9b644de
Show file tree
Hide file tree
Showing 8 changed files with 267 additions and 167 deletions.
19 changes: 17 additions & 2 deletions common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export enum WORKFLOW_TYPE {
SEMANTIC_SEARCH = 'Semantic search',
MULTIMODAL_SEARCH = 'Multimodal search',
HYBRID_SEARCH = 'Hybrid search',
SENTIMENT_ANALYSIS = 'Sentiment analysis',
CUSTOM = 'Custom',
UNKNOWN = 'Unknown',
}
Expand Down Expand Up @@ -181,9 +182,14 @@ export const SHARED_OPTIONAL_FIELDS = ['max_chunk_limit', 'description', 'tag'];
/**
* QUERY PRESETS
*/
export const DEFAULT_TEXT_FIELD = 'my_text';
export const DEFAULT_VECTOR_FIELD = 'my_embedding';
export const DEFAULT_IMAGE_FIELD = 'my_image';
export const DEFAULT_LABEL_FIELD = 'label';
export const VECTOR_FIELD_PATTERN = `{{vector_field}}`;
export const TEXT_FIELD_PATTERN = `{{text_field}}`;
export const IMAGE_FIELD_PATTERN = `{{image_field}}`;
export const LABEL_FIELD_PATTERN = `{{label_field}}`;
export const QUERY_TEXT_PATTERN = `{{query_text}}`;
export const QUERY_IMAGE_PATTERN = `{{query_image}}`;
export const MODEL_ID_PATTERN = `{{model_id}}`;
Expand All @@ -198,7 +204,7 @@ export const FETCH_ALL_QUERY = {
},
size: 1000,
};
export const TERM_QUERY = {
export const TERM_QUERY_TEXT = {
query: {
term: {
[TEXT_FIELD_PATTERN]: {
Expand All @@ -207,6 +213,15 @@ export const TERM_QUERY = {
},
},
};
export const TERM_QUERY_LABEL = {
query: {
term: {
[LABEL_FIELD_PATTERN]: {
value: QUERY_TEXT_PATTERN,
},
},
},
};
export const KNN_QUERY = {
_source: {
excludes: [VECTOR_FIELD_PATTERN],
Expand Down Expand Up @@ -353,7 +368,7 @@ export const QUERY_PRESETS = [
},
{
name: 'Term',
query: customStringify(TERM_QUERY),
query: customStringify(TERM_QUERY_TEXT),
},
{
name: 'Basic k-NN',
Expand Down
3 changes: 2 additions & 1 deletion common/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -483,10 +483,11 @@ export type QueryPreset = {
};

export type QuickConfigureFields = {
embeddingModelId?: string;
modelId?: string;
vectorField?: string;
textField?: string;
imageField?: string;
labelField?: string;
embeddingLength?: number;
};

Expand Down
166 changes: 107 additions & 59 deletions public/pages/workflows/new_workflow/quick_configure_inputs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ import {
} from '@elastic/eui';
import {
COHERE_DIMENSIONS,
DEFAULT_IMAGE_FIELD,
DEFAULT_LABEL_FIELD,
DEFAULT_TEXT_FIELD,
DEFAULT_VECTOR_FIELD,
MODEL_STATE,
Model,
OPENAI_DIMENSIONS,
Expand All @@ -30,10 +34,6 @@ interface QuickConfigureInputsProps {
setFields(fields: QuickConfigureFields): void;
}

const DEFAULT_TEXT_FIELD = 'my_text';
const DEFAULT_VECTOR_FIELD = 'my_embedding';
const DEFAULT_IMAGE_FIELD = 'my_image';

// Dynamic component to allow optional input configuration fields for different use cases.
// Hooks back to the parent component with such field values
export function QuickConfigureInputs(props: QuickConfigureInputsProps) {
Expand All @@ -60,26 +60,38 @@ export function QuickConfigureInputs(props: QuickConfigureInputsProps) {
// defaults for the field values for certain workflow types
useEffect(() => {
let defaultFieldValues = {} as QuickConfigureFields;
if (
props.workflowType === WORKFLOW_TYPE.SEMANTIC_SEARCH ||
props.workflowType === WORKFLOW_TYPE.MULTIMODAL_SEARCH ||
props.workflowType === WORKFLOW_TYPE.HYBRID_SEARCH
) {
defaultFieldValues = {
textField: DEFAULT_TEXT_FIELD,
vectorField: DEFAULT_VECTOR_FIELD,
};
}
if (props.workflowType === WORKFLOW_TYPE.MULTIMODAL_SEARCH) {
defaultFieldValues = {
...defaultFieldValues,
imageField: DEFAULT_IMAGE_FIELD,
};
switch (props.workflowType) {
case WORKFLOW_TYPE.SEMANTIC_SEARCH:
case WORKFLOW_TYPE.HYBRID_SEARCH: {
defaultFieldValues = {
textField: DEFAULT_TEXT_FIELD,
vectorField: DEFAULT_VECTOR_FIELD,
};
break;
}
case WORKFLOW_TYPE.MULTIMODAL_SEARCH: {
defaultFieldValues = {
textField: DEFAULT_TEXT_FIELD,
vectorField: DEFAULT_VECTOR_FIELD,
imageField: DEFAULT_IMAGE_FIELD,
};
break;
}
case WORKFLOW_TYPE.SENTIMENT_ANALYSIS: {
defaultFieldValues = {
textField: DEFAULT_TEXT_FIELD,
labelField: DEFAULT_LABEL_FIELD,
};
break;
}
case WORKFLOW_TYPE.CUSTOM:
default:
break;
}
if (deployedModels.length > 0) {
defaultFieldValues = {
...defaultFieldValues,
embeddingModelId: deployedModels[0].id,
modelId: deployedModels[0].id,
};
}
setFieldValues(defaultFieldValues);
Expand All @@ -93,7 +105,7 @@ export function QuickConfigureInputs(props: QuickConfigureInputsProps) {
// Try to pre-fill the dimensions based on the chosen model
useEffect(() => {
const selectedModel = deployedModels.find(
(model) => model.id === fieldValues.embeddingModelId
(model) => model.id === fieldValues.modelId
);
if (selectedModel?.connectorId !== undefined) {
const connector = connectors[selectedModel.connectorId];
Expand Down Expand Up @@ -127,13 +139,14 @@ export function QuickConfigureInputs(props: QuickConfigureInputsProps) {
}
}
}
}, [fieldValues.embeddingModelId, deployedModels, connectors]);
}, [fieldValues.modelId, deployedModels, connectors]);

return (
<>
{(props.workflowType === WORKFLOW_TYPE.SEMANTIC_SEARCH ||
props.workflowType === WORKFLOW_TYPE.MULTIMODAL_SEARCH ||
props.workflowType === WORKFLOW_TYPE.HYBRID_SEARCH) && (
props.workflowType === WORKFLOW_TYPE.HYBRID_SEARCH ||
props.workflowType === WORKFLOW_TYPE.SENTIMENT_ANALYSIS) && (
<>
<EuiSpacer size="m" />
<EuiAccordion
Expand All @@ -143,9 +156,17 @@ export function QuickConfigureInputs(props: QuickConfigureInputsProps) {
>
<EuiSpacer size="m" />
<EuiCompressedFormRow
label={'Embedding model'}
label={
props.workflowType === WORKFLOW_TYPE.SENTIMENT_ANALYSIS
? 'Model'
: 'Embedding model'
}
isInvalid={false}
helpText="The model to generate embeddings"
helpText={
props.workflowType === WORKFLOW_TYPE.SENTIMENT_ANALYSIS
? 'The sentiment analysis model'
: 'The model to generate embeddings'
}
>
<EuiCompressedSuperSelect
options={deployedModels.map(
Expand All @@ -171,11 +192,11 @@ export function QuickConfigureInputs(props: QuickConfigureInputsProps) {
disabled: false,
} as EuiSuperSelectOption<string>)
)}
valueOfSelected={fieldValues?.embeddingModelId || ''}
valueOfSelected={fieldValues?.modelId || ''}
onChange={(option: string) => {
setFieldValues({
...fieldValues,
embeddingModelId: option,
modelId: option,
});
}}
isInvalid={false}
Expand All @@ -185,7 +206,11 @@ export function QuickConfigureInputs(props: QuickConfigureInputsProps) {
<EuiCompressedFormRow
label={'Text field'}
isInvalid={false}
helpText="The name of the text document field to be embedded"
helpText={`The name of the text document field to be ${
props.workflowType === WORKFLOW_TYPE.SENTIMENT_ANALYSIS
? 'analyzed'
: 'embedded'
}`}
>
<EuiCompressedFieldText
value={fieldValues?.textField || ''}
Expand Down Expand Up @@ -218,37 +243,60 @@ export function QuickConfigureInputs(props: QuickConfigureInputsProps) {
<EuiSpacer size="s" />
</>
)}
<EuiCompressedFormRow
label={'Vector field'}
isInvalid={false}
helpText="The name of the document field containing the vector embedding"
>
<EuiCompressedFieldText
value={fieldValues?.vectorField || ''}
onChange={(e) => {
setFieldValues({
...fieldValues,
vectorField: e.target.value,
});
}}
/>
</EuiCompressedFormRow>
<EuiSpacer size="s" />
<EuiCompressedFormRow
label={'Embedding length'}
isInvalid={false}
helpText="The length / dimension of the generated vector embeddings. Autofilled values may be inaccurate."
>
<EuiCompressedFieldNumber
value={fieldValues?.embeddingLength || ''}
onChange={(e) => {
setFieldValues({
...fieldValues,
embeddingLength: Number(e.target.value),
});
}}
/>
</EuiCompressedFormRow>
{(props.workflowType === WORKFLOW_TYPE.SEMANTIC_SEARCH ||
props.workflowType === WORKFLOW_TYPE.MULTIMODAL_SEARCH ||
props.workflowType === WORKFLOW_TYPE.HYBRID_SEARCH) && (
<>
<EuiCompressedFormRow
label={'Vector field'}
isInvalid={false}
helpText="The name of the document field containing the vector embedding"
>
<EuiCompressedFieldText
value={fieldValues?.vectorField || ''}
onChange={(e) => {
setFieldValues({
...fieldValues,
vectorField: e.target.value,
});
}}
/>
</EuiCompressedFormRow>
<EuiSpacer size="s" />
<EuiCompressedFormRow
label={'Embedding length'}
isInvalid={false}
helpText="The length / dimension of the generated vector embeddings. Autofilled values may be inaccurate."
>
<EuiCompressedFieldNumber
value={fieldValues?.embeddingLength || ''}
onChange={(e) => {
setFieldValues({
...fieldValues,
embeddingLength: Number(e.target.value),
});
}}
/>
</EuiCompressedFormRow>
</>
)}
{props.workflowType === WORKFLOW_TYPE.SENTIMENT_ANALYSIS && (
<EuiCompressedFormRow
label={'Label field'}
isInvalid={false}
helpText="The name of the document field containing the sentiment label"
>
<EuiCompressedFieldText
value={fieldValues?.labelField || ''}
onChange={(e) => {
setFieldValues({
...fieldValues,
labelField: e.target.value,
});
}}
/>
</EuiCompressedFormRow>
)}
</EuiAccordion>
</>
)}
Expand Down
Loading

0 comments on commit 9b644de

Please sign in to comment.