Skip to content

Commit

Permalink
set defaults and display output schema based on fullresponsepath (#382)…
Browse files Browse the repository at this point in the history
… (#384)

Signed-off-by: Tyler Ohlsen <[email protected]>
(cherry picked from commit 68a152d)

Co-authored-by: Tyler Ohlsen <[email protected]>
  • Loading branch information
opensearch-trigger-bot[bot] and ohltyler committed Sep 17, 2024
1 parent 65872fb commit d328240
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 16 deletions.
14 changes: 8 additions & 6 deletions common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,11 @@ export const QUERY_PRESETS = [
/**
* MISCELLANEOUS
*/
export enum PROCESSOR_CONTEXT {
INGEST = 'ingest',
SEARCH_REQUEST = 'search_request',
SEARCH_RESPONSE = 'search_response',
}
export const START_FROM_SCRATCH_WORKFLOW_NAME = 'Start From Scratch';
export const DEFAULT_NEW_WORKFLOW_NAME = 'new_workflow';
export const DEFAULT_NEW_WORKFLOW_DESCRIPTION = 'My new workflow';
Expand All @@ -434,9 +439,6 @@ export const MAX_JSON_STRING_LENGTH = 10000;
export const MAX_WORKFLOW_NAME_TO_DISPLAY = 40;
export const WORKFLOW_NAME_REGEXP = RegExp('^[a-zA-Z0-9_-]*$');
export const EMPTY_MAP_ENTRY = { key: '', value: '' } as MapEntry;

export enum PROCESSOR_CONTEXT {
INGEST = 'ingest',
SEARCH_REQUEST = 'search_request',
SEARCH_RESPONSE = 'search_response',
}
export const MODEL_OUTPUT_SCHEMA_NESTED_PATH =
'output.properties.inference_results.items.properties.output.items.properties.dataAsMap.properties';
export const MODEL_OUTPUT_SCHEMA_FULL_PATH = 'output.properties';
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ export function MLProcessorInputs(props: MLProcessorInputsProps) {
) as IConfigField;
const outputMapFieldPath = `${props.baseConfigPath}.${props.config.id}.${outputMapField.id}`;
const outputMapValue = getIn(values, outputMapFieldPath);
const fullResponsePath = getIn(
values,
`${props.baseConfigPath}.${props.config.id}.full_response_path`
);

// preview availability states
// if there are preceding search request processors, we cannot fetch and display the interim transformed query.
Expand Down Expand Up @@ -228,6 +232,7 @@ export function MLProcessorInputs(props: MLProcessorInputsProps) {
<OutputTransformModal
uiConfig={props.uiConfig}
config={props.config}
baseConfigPath={props.baseConfigPath}
context={props.context}
outputMapField={outputMapField}
outputMapFieldPath={outputMapFieldPath}
Expand Down Expand Up @@ -345,7 +350,11 @@ export function MLProcessorInputs(props: MLProcessorInputsProps) {
: 'New document field'
}
valuePlaceholder="Model output field"
valueOptions={parseModelOutputs(modelInterface)}
valueOptions={
fullResponsePath
? undefined
: parseModelOutputs(modelInterface, false)
}
/>
<EuiSpacer size="s" />
{inputMapValue.length !== outputMapValue.length &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import {
EuiSmallButton,
EuiSpacer,
EuiText,
EuiPopover,
EuiSmallButtonEmpty,
EuiPopoverTitle,
EuiCodeBlock,
} from '@elastic/eui';
import {
IConfigField,
Expand Down Expand Up @@ -50,11 +54,16 @@ import {
} from '../../../../store';
import { getCore } from '../../../../services';
import { MapArrayField } from '../input_fields';
import { getDataSourceId, parseModelOutputs } from '../../../../utils/utils';
import {
getDataSourceId,
parseModelOutputs,
parseModelOutputsObj,
} from '../../../../utils/utils';

interface OutputTransformModalProps {
uiConfig: WorkflowConfig;
config: IProcessorConfig;
baseConfigPath: string;
context: PROCESSOR_CONTEXT;
outputMapField: IConfigField;
outputMapFieldPath: string;
Expand All @@ -77,8 +86,15 @@ export function OutputTransformModal(props: OutputTransformModalProps) {
const [sourceOutput, setSourceOutput] = useState<string>('[]');
const [transformedOutput, setTransformedOutput] = useState<string>('{}');

// get the current output map
// get some current values
const map = getIn(values, props.outputMapFieldPath) as MapArrayFormValue;
const fullResponsePath = getIn(
values,
`${props.baseConfigPath}.${props.config.id}.full_response_path`
);

// popover state containing the model interface details, if applicable
const [popoverOpen, setPopoverOpen] = useState<boolean>(false);

// selected transform state
const transformOptions = map.map((_, idx) => ({
Expand Down Expand Up @@ -123,7 +139,44 @@ export function OutputTransformModal(props: OutputTransformModalProps) {
Fetch some sample output data and see how it is transformed.
</EuiText>
<EuiSpacer size="s" />
<EuiText>Source output</EuiText>
<EuiFlexGroup direction="row" justifyContent="spaceBetween">
<EuiFlexItem>
<EuiText>Source output</EuiText>
</EuiFlexItem>
{!isEmpty(
parseModelOutputsObj(props.modelInterface, fullResponsePath)
) && (
<EuiFlexItem grow={false}>
<EuiPopover
isOpen={popoverOpen}
closePopover={() => setPopoverOpen(false)}
button={
<EuiSmallButtonEmpty
onClick={() => setPopoverOpen(!popoverOpen)}
>
View output schema
</EuiSmallButtonEmpty>
}
>
<EuiPopoverTitle>
The JSON Schema defining the model's expected output
</EuiPopoverTitle>
<EuiCodeBlock
language="json"
fontSize="m"
isCopyable={false}
>
{customStringify(
parseModelOutputsObj(
props.modelInterface,
fullResponsePath
)
)}
</EuiCodeBlock>
</EuiPopover>
</EuiFlexItem>
)}
</EuiFlexGroup>
<EuiSmallButton
style={{ width: '100px' }}
isLoading={isFetching}
Expand Down Expand Up @@ -277,7 +330,11 @@ export function OutputTransformModal(props: OutputTransformModalProps) {
helpLink={ML_INFERENCE_DOCS_LINK}
keyPlaceholder="Document field"
valuePlaceholder="Model output field"
valueOptions={parseModelOutputs(props.modelInterface)}
valueOptions={
fullResponsePath
? undefined
: parseModelOutputs(props.modelInterface, false)
}
// If the map we are adding is the first one, populate the selected option to index 0
onMapAdd={(curArray) => {
if (isEmpty(curArray)) {
Expand Down
37 changes: 32 additions & 5 deletions public/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import jsonpath from 'jsonpath';
import { escape, get } from 'lodash';
import {
JSONPATH_ROOT_SELECTOR,
MODEL_OUTPUT_SCHEMA_FULL_PATH,
MODEL_OUTPUT_SCHEMA_NESTED_PATH,
MapFormValue,
ModelInputFormField,
ModelInterface,
Expand All @@ -18,10 +20,13 @@ import {
WORKFLOW_RESOURCE_TYPE,
WORKFLOW_STEP_TYPE,
Workflow,
customStringify,
} from '../../common';
import { getCore, getDataSourceEnabled } from '../services';
import { MDSQueryParams, ModelInputMap } from '../../common/interfaces';
import {
MDSQueryParams,
ModelInputMap,
ModelOutputMap,
} from '../../common/interfaces';
import queryString from 'query-string';
import { useLocation } from 'react-router-dom';
import * as pluginManifest from '../../opensearch_dashboards.json';
Expand Down Expand Up @@ -221,11 +226,19 @@ export function parseModelInputsObj(
) as ModelInputMap;
}

// Derive the collection of model outputs from the model interface JSONSchema into a form-ready list
// Derive the collection of model outputs from the model interface JSONSchema into a form-ready list.
// Expose the full path or nested path depending on fullResponsePath
export function parseModelOutputs(
modelInterface: ModelInterface | undefined
modelInterface: ModelInterface | undefined,
fullResponsePath: boolean = false
): ModelOutputFormField[] {
const modelOutputsObj = get(modelInterface, 'output.properties', {}) as {
const modelOutputsObj = get(
modelInterface,
fullResponsePath
? MODEL_OUTPUT_SCHEMA_FULL_PATH
: MODEL_OUTPUT_SCHEMA_NESTED_PATH,
{}
) as {
[key: string]: ModelOutput;
};
return Object.keys(modelOutputsObj).map(
Expand All @@ -237,6 +250,20 @@ export function parseModelOutputs(
);
}

// Derive the collection of model outputs as an obj.
// Expose the full path or nested path depending on fullResponsePath
export function parseModelOutputsObj(
modelInterface: ModelInterface | undefined,
fullResponsePath: boolean = false
): ModelOutputMap {
return get(
modelInterface,
fullResponsePath
? MODEL_OUTPUT_SCHEMA_FULL_PATH
: MODEL_OUTPUT_SCHEMA_NESTED_PATH,
{}
) as ModelOutputMap;
}
export const getDataSourceFromURL = (location: {
search: string;
}): MDSQueryParams => {
Expand Down

0 comments on commit d328240

Please sign in to comment.