Feat: Show webhook schema dialog.
This commit is contained in:
parent
137de4849d
commit
266edf1a5f
8 changed files with 177 additions and 47 deletions
|
|
@ -42,9 +42,9 @@ import { FormWrapper } from '../components/form-wrapper';
|
||||||
import { Output } from '../components/output';
|
import { Output } from '../components/output';
|
||||||
import { PromptEditor } from '../components/prompt-editor';
|
import { PromptEditor } from '../components/prompt-editor';
|
||||||
import { QueryVariable } from '../components/query-variable';
|
import { QueryVariable } from '../components/query-variable';
|
||||||
|
import { SchemaDialog } from '../components/schema-dialog';
|
||||||
|
import { SchemaPanel } from '../components/schema-panel';
|
||||||
import { AgentTools, Agents } from './agent-tools';
|
import { AgentTools, Agents } from './agent-tools';
|
||||||
import { StructuredOutputDialog } from './structured-output-dialog';
|
|
||||||
import { StructuredOutputPanel } from './structured-output-panel';
|
|
||||||
import { useBuildPromptExtraPromptOptions } from './use-build-prompt-options';
|
import { useBuildPromptExtraPromptOptions } from './use-build-prompt-options';
|
||||||
import {
|
import {
|
||||||
useHandleShowStructuredOutput,
|
useHandleShowStructuredOutput,
|
||||||
|
|
@ -327,19 +327,17 @@ function AgentForm({ node }: INextOperatorForm) {
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<StructuredOutputPanel
|
<SchemaPanel value={structuredOutput}></SchemaPanel>
|
||||||
value={structuredOutput}
|
|
||||||
></StructuredOutputPanel>
|
|
||||||
</section>
|
</section>
|
||||||
)}
|
)}
|
||||||
</FormWrapper>
|
</FormWrapper>
|
||||||
</Form>
|
</Form>
|
||||||
{structuredOutputDialogVisible && (
|
{structuredOutputDialogVisible && (
|
||||||
<StructuredOutputDialog
|
<SchemaDialog
|
||||||
hideModal={hideStructuredOutputDialog}
|
hideModal={hideStructuredOutputDialog}
|
||||||
onOk={handleStructuredOutputDialogOk}
|
onOk={handleStructuredOutputDialogOk}
|
||||||
initialValues={structuredOutput}
|
initialValues={structuredOutput}
|
||||||
></StructuredOutputDialog>
|
></SchemaDialog>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import { INextOperatorForm } from '../../interface';
|
||||||
import { ParameterDialog } from './parameter-dialog';
|
import { ParameterDialog } from './parameter-dialog';
|
||||||
import { QueryTable } from './query-table';
|
import { QueryTable } from './query-table';
|
||||||
import { useEditQueryRecord } from './use-edit-query';
|
import { useEditQueryRecord } from './use-edit-query';
|
||||||
|
import { useHandleModeChange } from './use-handle-mode-change';
|
||||||
import { useValues } from './use-values';
|
import { useValues } from './use-values';
|
||||||
import { useWatchFormChange } from './use-watch-change';
|
import { useWatchFormChange } from './use-watch-change';
|
||||||
import { WebHook } from './webhook';
|
import { WebHook } from './webhook';
|
||||||
|
|
@ -98,6 +99,8 @@ function BeginForm({ node }: INextOperatorForm) {
|
||||||
|
|
||||||
const previousModeRef = useRef(mode);
|
const previousModeRef = useRef(mode);
|
||||||
|
|
||||||
|
const { handleModeChange } = useHandleModeChange(form);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
previousModeRef.current === AgentDialogueMode.Task &&
|
previousModeRef.current === AgentDialogueMode.Task &&
|
||||||
|
|
@ -137,6 +140,10 @@ function BeginForm({ node }: INextOperatorForm) {
|
||||||
placeholder={t('common.pleaseSelect')}
|
placeholder={t('common.pleaseSelect')}
|
||||||
options={ModeOptions}
|
options={ModeOptions}
|
||||||
{...field}
|
{...field}
|
||||||
|
onChange={(val) => {
|
||||||
|
handleModeChange(val);
|
||||||
|
field.onChange(val);
|
||||||
|
}}
|
||||||
></RAGFlowSelect>
|
></RAGFlowSelect>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
|
|
@ -185,44 +192,48 @@ function BeginForm({ node }: INextOperatorForm) {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{mode === AgentDialogueMode.Webhook && <WebHook></WebHook>}
|
{mode === AgentDialogueMode.Webhook && <WebHook></WebHook>}
|
||||||
{/* Create a hidden field to make Form instance record this */}
|
{mode !== AgentDialogueMode.Webhook && (
|
||||||
<FormField
|
<>
|
||||||
control={form.control}
|
{/* Create a hidden field to make Form instance record this */}
|
||||||
name={'inputs'}
|
<FormField
|
||||||
render={() => <div></div>}
|
control={form.control}
|
||||||
/>
|
name={'inputs'}
|
||||||
<Collapse
|
render={() => <div></div>}
|
||||||
title={
|
/>
|
||||||
<div>
|
<Collapse
|
||||||
{t('flow.input')}
|
title={
|
||||||
<FormTooltip tooltip={t('flow.beginInputTip')}></FormTooltip>
|
<div>
|
||||||
</div>
|
{t('flow.input')}
|
||||||
}
|
<FormTooltip tooltip={t('flow.beginInputTip')}></FormTooltip>
|
||||||
rightContent={
|
</div>
|
||||||
<Button
|
}
|
||||||
variant={'ghost'}
|
rightContent={
|
||||||
onClick={(e) => {
|
<Button
|
||||||
e.preventDefault();
|
variant={'ghost'}
|
||||||
showModal();
|
onClick={(e) => {
|
||||||
}}
|
e.preventDefault();
|
||||||
|
showModal();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Plus />
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Plus />
|
<QueryTable
|
||||||
</Button>
|
data={inputs}
|
||||||
}
|
showModal={showModal}
|
||||||
>
|
deleteRecord={handleDeleteRecord}
|
||||||
<QueryTable
|
></QueryTable>
|
||||||
data={inputs}
|
</Collapse>
|
||||||
showModal={showModal}
|
{visible && (
|
||||||
deleteRecord={handleDeleteRecord}
|
<ParameterDialog
|
||||||
></QueryTable>
|
hideModal={hideModal}
|
||||||
</Collapse>
|
initialValue={currentRecord}
|
||||||
{visible && (
|
otherThanCurrentQuery={otherThanCurrentQuery}
|
||||||
<ParameterDialog
|
submit={ok}
|
||||||
hideModal={hideModal}
|
></ParameterDialog>
|
||||||
initialValue={currentRecord}
|
)}
|
||||||
otherThanCurrentQuery={otherThanCurrentQuery}
|
</>
|
||||||
submit={ok}
|
|
||||||
></ParameterDialog>
|
|
||||||
)}
|
)}
|
||||||
</Form>
|
</Form>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
import { UseFormReturn } from 'react-hook-form';
|
||||||
|
import { AgentDialogueMode } from '../../constant';
|
||||||
|
|
||||||
|
// const WebhookSchema = {
|
||||||
|
// query: {
|
||||||
|
// type: 'object',
|
||||||
|
// required: [],
|
||||||
|
// properties: {
|
||||||
|
// // debug: { type: 'boolean' },
|
||||||
|
// // event: { type: 'string' },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
|
||||||
|
// headers: {
|
||||||
|
// type: 'object',
|
||||||
|
// required: [],
|
||||||
|
// properties: {
|
||||||
|
// // 'X-Trace-ID': { type: 'string' },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
|
||||||
|
// body: {
|
||||||
|
// type: 'object',
|
||||||
|
// required: [],
|
||||||
|
// properties: {
|
||||||
|
// id: { type: 'string' },
|
||||||
|
// payload: { type: 'object' },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// };
|
||||||
|
|
||||||
|
const schema = {
|
||||||
|
properties: {
|
||||||
|
query: {
|
||||||
|
type: 'object',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
headers: {
|
||||||
|
type: 'object',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
type: 'object',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export function useHandleModeChange(form: UseFormReturn<any>) {
|
||||||
|
const handleModeChange = useCallback(
|
||||||
|
(mode: AgentDialogueMode) => {
|
||||||
|
if (mode === AgentDialogueMode.Webhook) {
|
||||||
|
form.setValue('schema', schema, { shouldDirty: true });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[form],
|
||||||
|
);
|
||||||
|
return { handleModeChange };
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { JSONSchema } from '@/components/jsonjoy-builder';
|
||||||
|
import { useSetModalState } from '@/hooks/common-hooks';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
import { UseFormReturn } from 'react-hook-form';
|
||||||
|
|
||||||
|
export function useShowSchemaDialog(form: UseFormReturn<any>) {
|
||||||
|
const {
|
||||||
|
visible: schemaDialogVisible,
|
||||||
|
showModal: showSchemaDialog,
|
||||||
|
hideModal: hideSchemaDialog,
|
||||||
|
} = useSetModalState();
|
||||||
|
|
||||||
|
const handleSchemaDialogOk = useCallback(
|
||||||
|
(values: JSONSchema) => {
|
||||||
|
// Sync data to canvas
|
||||||
|
form.setValue('schema', values);
|
||||||
|
hideSchemaDialog();
|
||||||
|
},
|
||||||
|
[form, hideSchemaDialog],
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
schemaDialogVisible,
|
||||||
|
showSchemaDialog,
|
||||||
|
hideSchemaDialog,
|
||||||
|
handleSchemaDialogOk,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -23,6 +23,7 @@ export function useWatchFormChange(id?: string, form?: UseFormReturn) {
|
||||||
const nextValues = {
|
const nextValues = {
|
||||||
...values,
|
...values,
|
||||||
inputs: transferInputsArrayToObject(values.inputs),
|
inputs: transferInputsArrayToObject(values.inputs),
|
||||||
|
outputs: values.schema,
|
||||||
};
|
};
|
||||||
|
|
||||||
updateNodeForm(id, nextValues);
|
updateNodeForm(id, nextValues);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { SelectWithSearch } from '@/components/originui/select-with-search';
|
import { SelectWithSearch } from '@/components/originui/select-with-search';
|
||||||
import { RAGFlowFormItem } from '@/components/ragflow-form';
|
import { RAGFlowFormItem } from '@/components/ragflow-form';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
import { Separator } from '@/components/ui/separator';
|
import { Separator } from '@/components/ui/separator';
|
||||||
import { Textarea } from '@/components/ui/textarea';
|
import { Textarea } from '@/components/ui/textarea';
|
||||||
|
|
@ -13,6 +14,9 @@ import {
|
||||||
WebhookSecurityAuthType,
|
WebhookSecurityAuthType,
|
||||||
} from '../../../constant';
|
} from '../../../constant';
|
||||||
import { DynamicStringForm } from '../../components/dynamic-string-form';
|
import { DynamicStringForm } from '../../components/dynamic-string-form';
|
||||||
|
import { SchemaDialog } from '../../components/schema-dialog';
|
||||||
|
import { SchemaPanel } from '../../components/schema-panel';
|
||||||
|
import { useShowSchemaDialog } from '../use-show-schema-dialog';
|
||||||
import { Auth } from './auth';
|
import { Auth } from './auth';
|
||||||
import { WebhookResponse } from './response';
|
import { WebhookResponse } from './response';
|
||||||
|
|
||||||
|
|
@ -27,6 +31,15 @@ export function WebHook() {
|
||||||
name: 'execution_mode',
|
name: 'execution_mode',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
showSchemaDialog,
|
||||||
|
schemaDialogVisible,
|
||||||
|
hideSchemaDialog,
|
||||||
|
handleSchemaDialogOk,
|
||||||
|
} = useShowSchemaDialog(form);
|
||||||
|
|
||||||
|
const schema = form.getValues('schema');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<RAGFlowFormItem name="methods" label={t('flow.webhook.methods')}>
|
<RAGFlowFormItem name="methods" label={t('flow.webhook.methods')}>
|
||||||
|
|
@ -76,7 +89,11 @@ export function WebHook() {
|
||||||
label={t('flow.webhook.ipWhitelist')}
|
label={t('flow.webhook.ipWhitelist')}
|
||||||
></DynamicStringForm>
|
></DynamicStringForm>
|
||||||
</>
|
</>
|
||||||
<RAGFlowFormItem name="schema" label={t('flow.webhook.schema')}>
|
<RAGFlowFormItem
|
||||||
|
name="schema"
|
||||||
|
label={t('flow.webhook.schema')}
|
||||||
|
className="hidden"
|
||||||
|
>
|
||||||
<Textarea></Textarea>
|
<Textarea></Textarea>
|
||||||
</RAGFlowFormItem>
|
</RAGFlowFormItem>
|
||||||
<RAGFlowFormItem
|
<RAGFlowFormItem
|
||||||
|
|
@ -90,6 +107,21 @@ export function WebHook() {
|
||||||
{executionMode === WebhookExecutionMode.Immediately && (
|
{executionMode === WebhookExecutionMode.Immediately && (
|
||||||
<WebhookResponse></WebhookResponse>
|
<WebhookResponse></WebhookResponse>
|
||||||
)}
|
)}
|
||||||
|
<Separator></Separator>
|
||||||
|
<section className="flex justify-between items-center">
|
||||||
|
Schema
|
||||||
|
<Button variant={'ghost'} onClick={showSchemaDialog}>
|
||||||
|
{t('flow.structuredOutput.configuration')}
|
||||||
|
</Button>
|
||||||
|
</section>
|
||||||
|
<SchemaPanel value={schema}></SchemaPanel>
|
||||||
|
{schemaDialogVisible && (
|
||||||
|
<SchemaDialog
|
||||||
|
initialValues={schema}
|
||||||
|
hideModal={hideSchemaDialog}
|
||||||
|
onOk={handleSchemaDialogOk}
|
||||||
|
></SchemaDialog>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import { IModalProps } from '@/interfaces/common';
|
||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export function StructuredOutputDialog({
|
export function SchemaDialog({
|
||||||
hideModal,
|
hideModal,
|
||||||
onOk,
|
onOk,
|
||||||
initialValues,
|
initialValues,
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { JSONSchema, JsonSchemaVisualizer } from '@/components/jsonjoy-builder';
|
import { JSONSchema, JsonSchemaVisualizer } from '@/components/jsonjoy-builder';
|
||||||
|
|
||||||
export function StructuredOutputPanel({ value }: { value: JSONSchema }) {
|
export function SchemaPanel({ value }: { value: JSONSchema }) {
|
||||||
return (
|
return (
|
||||||
<section className="h-48">
|
<section className="h-48">
|
||||||
<JsonSchemaVisualizer
|
<JsonSchemaVisualizer
|
||||||
Loading…
Add table
Reference in a new issue