Skip to content

Commit

Permalink
Simplify RAG presets; add bulk API details (#610) (#611)
Browse files Browse the repository at this point in the history
* Add new ml response tab



* Add bulk API content



---------


(cherry picked from commit ee7ec89)

Signed-off-by: Tyler Ohlsen <ohltyler@amazon.com>
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
1 parent 5d13c93 commit 37788e7
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 10 deletions.
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
5 changes: 3 additions & 2 deletions public/pages/workflows/new_workflow/quick_configure_modal.tsx
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

0 comments on commit 37788e7

Please sign in to comment.