Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport main] Simplify RAG presets; add bulk API details #611

Merged
merged 1 commit into from
Feb 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@ export const BULK_API_DOCS_LINK =
'https://opensearch.org/docs/latest/api-reference/document-apis/bulk/';
export const SEARCH_PIPELINE_DOCS_LINK =
'https://opensearch.org/docs/latest/search-plugins/search-pipelines/using-search-pipeline/';
export const ML_RESPONSE_PROCESSOR_EXAMPLE_DOCS_LINK =
'https://opensearch.org/docs/latest/search-plugins/search-pipelines/ml-inference-search-response/#example-externally-hosted-text-embedding-model';

/**
* Text chunking algorithm constants
Expand Down
60 changes: 60 additions & 0 deletions public/general_components/results/ml_response.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { isEmpty } from 'lodash';
import {
EuiCode,
EuiCodeEditor,
EuiEmptyPrompt,
EuiLink,
EuiSpacer,
EuiText,
} from '@elastic/eui';
import {
customStringify,
ML_RESPONSE_PROCESSOR_EXAMPLE_DOCS_LINK,
} from '../../../common';

interface MLResponseProps {
mlResponse: {};
}

/**
* Small component to render the ML response within a raw search response.
*/
export function MLResponse(props: MLResponseProps) {
return (
<>
<EuiSpacer size="s" />
<EuiText size="s">
Showing results stored in <EuiCode>ext.ml_inference</EuiCode> from the
search response.{' '}
<EuiLink href={ML_RESPONSE_PROCESSOR_EXAMPLE_DOCS_LINK} target="_blank">
See an example
</EuiLink>
</EuiText>
<EuiSpacer size="m" />
{isEmpty(props.mlResponse) ? (
<EuiEmptyPrompt title={<h2>No response found</h2>} titleSize="s" />
) : (
<EuiCodeEditor
mode="json"
theme="textmate"
width="100%"
height="100%"
value={customStringify(props.mlResponse)}
readOnly={true}
setOptions={{
fontSize: '12px',
autoScrollEditorIntoView: true,
wrap: true,
}}
tabSize={2}
/>
)}
</>
);
}
16 changes: 16 additions & 0 deletions public/general_components/results/results.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

import React, { useState } from 'react';
import { get } from 'lodash';
import {
EuiPanel,
EuiFlexGroup,
Expand All @@ -13,6 +14,7 @@ import {
import { SearchResponse } from '../../../common';
import { ResultsTable } from './results_table';
import { ResultsJSON } from './results_json';
import { MLResponse } from './ml_response';

interface ResultsProps {
response: SearchResponse;
Expand All @@ -21,6 +23,7 @@ interface ResultsProps {
enum VIEW {
HITS_TABLE = 'hits_table',
RAW_JSON = 'raw_json',
ML_RESPONSE = 'ml_response',
}

/**
Expand Down Expand Up @@ -55,6 +58,10 @@ export function Results(props: ResultsProps) {
id: VIEW.RAW_JSON,
label: 'Raw JSON',
},
{
id: VIEW.ML_RESPONSE,
label: 'ML response',
},
]}
idSelected={selectedView}
onChange={(id) => setSelectedView(id as VIEW)}
Expand All @@ -69,9 +76,18 @@ export function Results(props: ResultsProps) {
{selectedView === VIEW.RAW_JSON && (
<ResultsJSON response={props.response} />
)}
{selectedView === VIEW.ML_RESPONSE && (
<MLResponse
mlResponse={getMLResponseFromSearchResponse(props.response)}
/>
)}
</>
</EuiFlexItem>
</EuiFlexGroup>
</EuiPanel>
);
}

function getMLResponseFromSearchResponse(searchResponse: SearchResponse): {} {
return get(searchResponse, 'ext.ml_inference', {});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import {
EuiText,
EuiFlexGroup,
EuiFlexItem,
EuiLink,
EuiCodeBlock,
EuiPopoverTitle,
} from '@elastic/eui';
import { BULK_API_DOCS_LINK } from '../../../../../common';

interface BulkPopoverContentProps {
indexName: string;
}

/**
* A basic component containing details about the bulk API and link to documentation.
* Provides a partially-complete example, dynamically populated based on an index name.
*/
export function BulkPopoverContent(props: BulkPopoverContentProps) {
return (
<EuiFlexItem style={{ width: '40vw' }}>
<EuiPopoverTitle>Ingest additional data</EuiPopoverTitle>
<EuiFlexGroup direction="column">
<EuiFlexItem grow={false}>
<EuiText>
You can ingest additional bulk data into the same index using the
Bulk API.{' '}
<EuiLink href={BULK_API_DOCS_LINK} target="_blank">
Learn more
</EuiLink>
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiCodeBlock fontSize="m" isCopyable={true}>
{`POST ${props.indexName}/_bulk
{ "index": { "_index": "${props.indexName}", "_id": //YOUR DOC ID// } }
{ //INSERT YOUR DOCUMENTS// }`}
</EuiCodeBlock>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
EuiCodeBlock,
EuiSmallButtonEmpty,
EuiEmptyPrompt,
EuiPopover,
} from '@elastic/eui';
import {
MapEntry,
Expand All @@ -25,6 +26,7 @@ import {
toFormattedDate,
} from '../../../../../common';
import { SourceDataModal } from './source_data_modal';
import { BulkPopoverContent } from './bulk_popover_content';

interface SourceDataProps {
workflow: Workflow | undefined;
Expand Down Expand Up @@ -54,6 +56,9 @@ export function SourceData(props: SourceDataProps) {
// edit modal state
const [isEditModalOpen, setIsEditModalOpen] = useState<boolean>(false);

// bulk API popover state
const [bulkPopoverOpen, setBulkPopoverOpen] = useState<boolean>(false);

// hook to listen when the docs form value changes.
useEffect(() => {
if (values?.ingest?.docs) {
Expand Down Expand Up @@ -133,11 +138,49 @@ export function SourceData(props: SourceDataProps) {
</EuiFlexGroup>
</EuiFlexItem>
{props.lastIngested !== undefined && (
<EuiFlexItem grow={false}>
<EuiText size="s" color="subdued">
{`Last ingested: ${toFormattedDate(props.lastIngested)}`}
</EuiText>
</EuiFlexItem>
<>
<EuiFlexItem grow={false}>
<EuiText size="s">
{`Last ingested: ${toFormattedDate(props.lastIngested)}`}
</EuiText>
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexGroup
direction="row"
gutterSize="none"
justifyContent="flexStart"
style={{ marginTop: '-8px' }}
>
<EuiFlexItem grow={false}>
<EuiText size="s">
Ingest additional data with the bulk API.
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiPopover
isOpen={bulkPopoverOpen}
initialFocus={false}
anchorPosition="downCenter"
closePopover={() => setBulkPopoverOpen(false)}
button={
<EuiSmallButtonEmpty
style={{ marginTop: '-4px' }}
onClick={() => {
setBulkPopoverOpen(!bulkPopoverOpen);
}}
>
Learn more
</EuiSmallButtonEmpty>
}
>
<BulkPopoverContent
indexName={getIn(values, 'ingest.index.name')}
/>
</EuiPopover>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</>
)}
{docsPopulated ? (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -741,7 +741,8 @@ function updateRAGSearchResponseProcessors(
llmInterface: ModelInterface | undefined
): WorkflowConfig {
config.search.enrichResponse.processors.forEach((processor, idx) => {
// prefill ML inference
// prefill ML inference. By default, store the inference results
// under the `ext.ml_inference` response body.
if (processor.type === PROCESSOR_TYPE.ML) {
config.search.enrichResponse.processors[idx].fields.forEach((field) => {
if (field.id === 'model' && fields.llmId) {
Expand Down Expand Up @@ -784,7 +785,7 @@ function updateRAGSearchResponseProcessors(
...outputMap[0],
value: {
transformType: TRANSFORM_TYPE.FIELD,
value: fields.llmResponseField,
value: `ext.ml_inference.${fields.llmResponseField}`,
},
};
} else {
Expand Down
3 changes: 0 additions & 3 deletions public/pages/workflows/new_workflow/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
*/

import {
CollapseProcessor,
MLIngestProcessor,
MLSearchRequestProcessor,
MLSearchResponseProcessor,
Expand Down Expand Up @@ -253,7 +252,6 @@ export function fetchRAGMetadata(version: string): UIState {
baseState.config.search.request.value = customStringify(FETCH_ALL_QUERY);
baseState.config.search.enrichResponse.processors = [
new MLSearchResponseProcessor().toObj(),
new CollapseProcessor().toObj(),
];
return baseState;
}
Expand All @@ -278,7 +276,6 @@ export function fetchVectorSearchWithRAGMetadata(version: string): UIState {
];
baseState.config.search.enrichResponse.processors = [
new MLSearchResponseProcessor().toObj(),
new CollapseProcessor().toObj(),
];
return baseState;
}
Expand Down
Loading