From ed3ec58fbdd1a670a8899dfc7978efa70f2987f9 Mon Sep 17 00:00:00 2001 From: Tyler Ohlsen Date: Fri, 13 Sep 2024 16:36:51 -0700 Subject: [PATCH] Add toggle-able prompt template transformation in input transform Signed-off-by: Tyler Ohlsen --- public/configs/ml_processor.ts | 8 +- .../collapse_processor.ts | 2 + .../normalization_processor.ts | 2 + .../workflow_detail/tools/ingest/ingest.tsx | 1 + .../workflow_detail/tools/query/query.tsx | 1 + .../input_fields/json_field.tsx | 1 + .../input_transform_modal.tsx | 114 ++++++++++++++++++ .../processor_inputs/ml_processor_inputs.tsx | 1 + .../output_transform_modal.tsx | 2 + .../workflow_detail/workspace/workspace.tsx | 1 + 10 files changed, 129 insertions(+), 4 deletions(-) diff --git a/public/configs/ml_processor.ts b/public/configs/ml_processor.ts index bbfac637..623981ae 100644 --- a/public/configs/ml_processor.ts +++ b/public/configs/ml_processor.ts @@ -30,10 +30,6 @@ export abstract class MLProcessor extends Processor { }, ]; this.optionalFields = [ - { - id: 'description', - type: 'string', - }, { id: 'model_config', type: 'json', @@ -62,6 +58,10 @@ export abstract class MLProcessor extends Processor { id: 'tag', type: 'string', }, + { + id: 'description', + type: 'string', + }, ]; } } diff --git a/public/configs/search_response_processors/collapse_processor.ts b/public/configs/search_response_processors/collapse_processor.ts index be0decb9..ea63fcd8 100644 --- a/public/configs/search_response_processors/collapse_processor.ts +++ b/public/configs/search_response_processors/collapse_processor.ts @@ -5,6 +5,7 @@ import { PROCESSOR_TYPE } from '../../../common'; import { Processor } from '../processor'; +import { generateId } from '../../utils'; /** * The collapse processor config. Used in search flows. @@ -12,6 +13,7 @@ import { Processor } from '../processor'; export class CollapseProcessor extends Processor { constructor() { super(); + this.id = generateId('collapse_processor'); this.type = PROCESSOR_TYPE.COLLAPSE; this.name = 'Collapse Processor'; this.fields = [ diff --git a/public/configs/search_response_processors/normalization_processor.ts b/public/configs/search_response_processors/normalization_processor.ts index c56cb1a7..9ec1dc0d 100644 --- a/public/configs/search_response_processors/normalization_processor.ts +++ b/public/configs/search_response_processors/normalization_processor.ts @@ -5,6 +5,7 @@ import { PROCESSOR_TYPE } from '../../../common'; import { Processor } from '../processor'; +import { generateId } from '../../utils'; /** * The normalization processor config. Used in search flows. @@ -12,6 +13,7 @@ import { Processor } from '../processor'; export class NormalizationProcessor extends Processor { constructor() { super(); + this.id = generateId('normalization_processor'); this.type = PROCESSOR_TYPE.NORMALIZATION; this.name = 'Normalization Processor'; this.fields = []; diff --git a/public/pages/workflow_detail/tools/ingest/ingest.tsx b/public/pages/workflow_detail/tools/ingest/ingest.tsx index d4097b16..cdae1df0 100644 --- a/public/pages/workflow_detail/tools/ingest/ingest.tsx +++ b/public/pages/workflow_detail/tools/ingest/ingest.tsx @@ -29,6 +29,7 @@ export function Ingest(props: IngestProps) { setOptions={{ fontSize: '12px', autoScrollEditorIntoView: true, + wrap: true, }} tabSize={2} /> diff --git a/public/pages/workflow_detail/tools/query/query.tsx b/public/pages/workflow_detail/tools/query/query.tsx index 85e81a7c..752c0dde 100644 --- a/public/pages/workflow_detail/tools/query/query.tsx +++ b/public/pages/workflow_detail/tools/query/query.tsx @@ -29,6 +29,7 @@ export function Query(props: QueryProps) { setOptions={{ fontSize: '12px', autoScrollEditorIntoView: true, + wrap: true, }} tabSize={2} /> diff --git a/public/pages/workflow_detail/workflow_inputs/input_fields/json_field.tsx b/public/pages/workflow_detail/workflow_inputs/input_fields/json_field.tsx index e5423f53..ca49bd97 100644 --- a/public/pages/workflow_detail/workflow_inputs/input_fields/json_field.tsx +++ b/public/pages/workflow_detail/workflow_inputs/input_fields/json_field.tsx @@ -99,6 +99,7 @@ export function JsonField(props: JsonFieldProps) { highlightActiveLine: !props.readOnly, highlightSelectedWord: !props.readOnly, highlightGutterLine: !props.readOnly, + wrap: true, }} aria-label="Code Editor" tabSize={2} diff --git a/public/pages/workflow_detail/workflow_inputs/processor_inputs/input_transform_modal.tsx b/public/pages/workflow_detail/workflow_inputs/processor_inputs/input_transform_modal.tsx index 76901f96..c580037e 100644 --- a/public/pages/workflow_detail/workflow_inputs/processor_inputs/input_transform_modal.tsx +++ b/public/pages/workflow_detail/workflow_inputs/processor_inputs/input_transform_modal.tsx @@ -26,6 +26,7 @@ import { EuiCodeBlock, EuiPopoverTitle, EuiIconTip, + EuiSwitch, } from '@elastic/eui'; import { IConfigField, @@ -64,6 +65,7 @@ import { MapArrayField } from '../input_fields'; interface InputTransformModalProps { uiConfig: WorkflowConfig; config: IProcessorConfig; + baseConfigPath: string; context: PROCESSOR_CONTEXT; inputMapField: IConfigField; inputMapFieldPath: string; @@ -84,6 +86,14 @@ export function InputTransformModal(props: InputTransformModalProps) { const dataSourceId = getDataSourceId(); const { values } = useFormikContext(); + // various prompt states + const [viewPromptDetails, setViewPromptDetails] = useState(false); + const [viewTransformedPrompt, setViewTransformedPrompt] = useState( + false + ); + const [originalPrompt, setOriginalPrompt] = useState(''); + const [transformedPrompt, setTransformedPrompt] = useState(''); + // fetching input data state const [isFetching, setIsFetching] = useState(false); @@ -146,6 +156,32 @@ export function InputTransformModal(props: InputTransformModalProps) { } }, [transformedOutput]); + // hook to set the prompt if found in the model config + useEffect(() => { + const modelConfigString = getIn( + values, + `${props.baseConfigPath}.${props.config.id}.model_config` + ); + try { + const prompt = JSON.parse(modelConfigString)?.prompt; + if (!isEmpty(prompt)) { + setOriginalPrompt(prompt); + } + } catch {} + }, [ + getIn(values, `${props.baseConfigPath}.${props.config.id}.model_config`), + ]); + + // hook to set the transformed prompt, if a valid prompt found, and + // valid parameters set + useEffect(() => { + if (!isEmpty(originalPrompt)) { + setTransformedPrompt( + injectValuesIntoPrompt(originalPrompt, JSON.parse(transformedOutput)) + ); + } + }, [originalPrompt, transformedOutput]); + return ( @@ -303,6 +339,7 @@ export function InputTransformModal(props: InputTransformModalProps) { showLineNumbers: false, showGutter: false, showPrintMargin: false, + wrap: true, }} tabSize={2} /> @@ -425,11 +462,64 @@ export function InputTransformModal(props: InputTransformModalProps) { showLineNumbers: false, showGutter: false, showPrintMargin: false, + wrap: true, }} tabSize={2} /> + {!isEmpty(originalPrompt) && ( + + <> + + + Transformed prompt + + + setViewPromptDetails(!viewPromptDetails)} + /> + + + {viewPromptDetails && ( + <> + + + setViewTransformedPrompt(!viewTransformedPrompt) + } + /> + + + + )} + + + )} @@ -440,3 +530,27 @@ export function InputTransformModal(props: InputTransformModalProps) { ); } + +function injectValuesIntoPrompt( + promptString: string, + parameters: { [key: string]: string } +): string { + let finalPromptString = promptString; + // replace any parameter placeholders in the prompt with any values found in the + // parameters obj. + // we do 2 checks - one for the regular prompt, and one with "toString()" appended. + // this is required for parameters that have values as a list, for example. + Object.keys(parameters).forEach((parameterKey) => { + const parameterValue = parameters[parameterKey]; + const regex = new RegExp(`\\$\\{parameters.${parameterKey}\\}`, 'g'); + const regexWithToString = new RegExp( + `\\$\\{parameters.${parameterKey}.toString\\(\\)\\}`, + 'g' + ); + finalPromptString = finalPromptString + .replace(regex, parameterValue) + .replace(regexWithToString, parameterValue); + }); + + return finalPromptString; +} diff --git a/public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs.tsx b/public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs.tsx index bc6fa033..6f1b53ad 100644 --- a/public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs.tsx +++ b/public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs.tsx @@ -209,6 +209,7 @@ export function MLProcessorInputs(props: MLProcessorInputsProps) { @@ -322,6 +323,7 @@ export function OutputTransformModal(props: OutputTransformModalProps) { showLineNumbers: false, showGutter: false, showPrintMargin: false, + wrap: true, }} tabSize={2} /> diff --git a/public/pages/workflow_detail/workspace/workspace.tsx b/public/pages/workflow_detail/workspace/workspace.tsx index 9581ad22..5c618722 100644 --- a/public/pages/workflow_detail/workspace/workspace.tsx +++ b/public/pages/workflow_detail/workspace/workspace.tsx @@ -214,6 +214,7 @@ export function Workspace(props: WorkspaceProps) { setOptions={{ fontSize: '12px', autoScrollEditorIntoView: true, + wrap: true, }} tabSize={2} />