Browse Source

Feat: Make the agent dialog window exposed to the outside world fill in the begin form #3221 (#9124)

### What problem does this PR solve?
Feat: Make the agent dialog window exposed to the outside world fill in
the begin form #3221

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
tags/v0.20.0
balibabu 3 months ago
parent
commit
6a170b2f6e
No account linked to committer's email address

+ 1
- 1
web/src/components/llm-select/llm-label.tsx View File

@@ -20,7 +20,7 @@ const LLMLabel = ({ value }: IProps) => {
height={20}
size={'small'}
/>
{llmName}
<span className="flex-1 truncate"> {llmName}</span>
</div>
);
};

+ 1
- 0
web/src/components/message-input/next.tsx View File

@@ -143,6 +143,7 @@ export function NextMessageInput({
size="icon"
variant="ghost"
className="size-7 rounded-sm"
disabled={isUploading || sendLoading}
>
<Paperclip className="size-3.5" />
<span className="sr-only">Attach file</span>

+ 27
- 0
web/src/hooks/use-agent-request.ts View File

@@ -10,6 +10,7 @@ import { DSL, IFlow, IFlowTemplate } from '@/interfaces/database/flow';
import { IDebugSingleRequestBody } from '@/interfaces/request/agent';
import i18n from '@/locales/config';
import { BeginId } from '@/pages/agent/constant';
import { BeginQuery } from '@/pages/agent/interface';
import { useGetSharedChatSearchParams } from '@/pages/chat/shared-hooks';
import agentService, {
fetchAgentLogsByCanvasId,
@@ -46,6 +47,7 @@ export const enum AgentApiAction {
FetchVersionList = 'fetchVersionList',
FetchVersion = 'fetchVersion',
FetchAgentAvatar = 'fetchAgentAvatar',
FetchExternalAgentInputs = 'fetchExternalAgentInputs',
}

export const EmptyDsl = {
@@ -584,3 +586,28 @@ export const useFetchAgentLog = (searchParams: IAgentLogsRequest) => {

return { data, loading };
};

export const useFetchExternalAgentInputs = () => {
const { sharedId } = useGetSharedChatSearchParams();

const {
data,
isFetching: loading,
refetch,
} = useQuery<Record<string, BeginQuery>>({
queryKey: [AgentApiAction.FetchExternalAgentInputs],
initialData: {} as Record<string, BeginQuery>,
refetchOnReconnect: false,
refetchOnMount: false,
refetchOnWindowFocus: false,
gcTime: 0,
enabled: !!sharedId,
queryFn: async () => {
const { data } = await agentService.fetchExternalAgentInputs(sharedId!);

return data?.data ?? {};
},
});

return { data, loading, refetch };
};

+ 7
- 3
web/src/pages/agent/chat/use-send-agent-message.ts View File

@@ -176,6 +176,7 @@ export function useSetUploadResponseData() {
export const useSendAgentMessage = (
url?: string,
addEventList?: (data: IEventList, messageId: string) => void,
beginParams?: any[],
) => {
const { id: agentId } = useParams();
const { handleInputChange, value, setValue } = useHandleMessageInputChange();
@@ -226,7 +227,9 @@ export const useSendAgentMessage = (

params.query = message.content;
// params.message_id = message.id;
params.inputs = transferInputsArrayToObject(query); // begin operator inputs
params.inputs = transferInputsArrayToObject(
beginParams ? beginParams : query,
); // begin operator inputs

params.files = uploadResponseList;

@@ -248,13 +251,14 @@ export const useSendAgentMessage = (
},
[
agentId,
sessionId,
send,
clearUploadResponseList,
inputs,
beginParams,
uploadResponseList,
sessionId,
setValue,
removeLatestMessage,
clearUploadResponseList,
],
);


+ 10
- 0
web/src/pages/agent/constant.tsx View File

@@ -487,6 +487,16 @@ export const initialExeSqlValues = {
port: 3306,
password: '',
max_records: 1024,
outputs: {
formalized_content: {
value: '',
type: 'string',
},
json: {
value: [],
type: 'Array<Object>',
},
},
};

export const initialSwitchValues = {

+ 7
- 0
web/src/pages/agent/form/exesql-form/index.tsx View File

@@ -20,10 +20,14 @@ import { useFormValues } from '../../hooks/use-form-values';
import { useWatchFormChange } from '../../hooks/use-watch-form-change';
import { INextOperatorForm } from '../../interface';
import { ExeSQLOptions } from '../../options';
import { buildOutputList } from '../../utils/build-output-list';
import { FormWrapper } from '../components/form-wrapper';
import { Output } from '../components/output';
import { QueryVariable } from '../components/query-variable';
import { FormSchema, useSubmitForm } from './use-submit-form';

const outputList = buildOutputList(initialExeSqlValues.outputs);

export function ExeSQLFormWidgets({ loading }: { loading: boolean }) {
const form = useFormContext();
const { t } = useTranslate('flow');
@@ -153,6 +157,9 @@ function ExeSQLForm({ node }: INextOperatorForm) {
<QueryVariable name="sql"></QueryVariable>
<ExeSQLFormWidgets loading={loading}></ExeSQLFormWidgets>
</FormWrapper>
<div className="p-5">
<Output list={outputList}></Output>
</div>
</Form>
);
}

+ 2
- 14
web/src/pages/agent/index.tsx View File

@@ -18,7 +18,6 @@ import {
import { SharedFrom } from '@/constants/chat';
import { useSetModalState } from '@/hooks/common-hooks';
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
import { useFetchUserInfo } from '@/hooks/user-setting-hooks';
import { ReactFlowProvider } from '@xyflow/react';
import {
ChevronDown,
@@ -37,10 +36,7 @@ import AgentCanvas from './canvas';
import EmbedDialog from './embed-dialog';
import { useHandleExportOrImportJsonFile } from './hooks/use-export-json';
import { useFetchDataOnMount } from './hooks/use-fetch-data';
import {
useGetBeginNodeDataInputs,
useGetBeginNodeDataQueryIsSafe,
} from './hooks/use-get-begin-query';
import { useGetBeginNodeDataInputs } from './hooks/use-get-begin-query';
import {
useSaveGraph,
useSaveGraphBeforeOpeningDebugDrawer,
@@ -69,7 +65,6 @@ export default function Agent() {
showModal: showChatDrawer,
} = useSetModalState();
const { t } = useTranslation();
const { data: userInfo } = useFetchUserInfo();

// const openDocument = useOpenDocument();
const {
@@ -99,7 +94,6 @@ export default function Agent() {
const { showEmbedModal, hideEmbedModal, embedVisible, beta } =
useShowEmbedModal();
const { navigateToAgentLogs } = useNavigatePage();
const isBeginNodeDataQuerySafe = useGetBeginNodeDataQueryIsSafe();

return (
<section className="h-full">
@@ -165,13 +159,7 @@ export default function Agent() {
{location.hostname !== 'demo.ragflow.io' && (
<>
<DropdownMenuSeparator />
<AgentDropdownMenuItem
onClick={showEmbedModal}
disabled={
!isBeginNodeDataQuerySafe ||
userInfo.nickname !== agentDetail.nickname
}
>
<AgentDropdownMenuItem onClick={showEmbedModal}>
<ScreenShare />
{t('common.embedIntoSite')}
</AgentDropdownMenuItem>

+ 23
- 1
web/src/pages/next-chats/hooks/use-send-shared-message.ts View File

@@ -1,7 +1,9 @@
import { SharedFrom } from '@/constants/chat';
import { useSetModalState } from '@/hooks/common-hooks';
import { IEventList } from '@/hooks/use-send-message';
import { useSendAgentMessage } from '@/pages/agent/chat/use-send-agent-message';
import trim from 'lodash/trim';
import { useCallback, useState } from 'react';
import { useSearchParams } from 'umi';

export const useSendButtonDisabled = (value: string) => {
@@ -34,10 +36,30 @@ export const useSendNextSharedMessage = (
const { from, sharedId: conversationId } = useGetSharedChatSearchParams();
const url = `/api/v1/${from === SharedFrom.Agent ? 'agentbots' : 'chatbots'}/${conversationId}/completions`;

const ret = useSendAgentMessage(url, addEventList);
const [params, setParams] = useState<any[]>([]);

const {
visible: parameterDialogVisible,
hideModal: hideParameterDialog,
showModal: showParameterDialog,
} = useSetModalState();

const ret = useSendAgentMessage(url, addEventList, params);

const ok = useCallback(
(params: any[]) => {
setParams(params);
hideParameterDialog();
},
[hideParameterDialog],
);

return {
...ret,
hasError: false,
parameterDialogVisible,
hideParameterDialog,
showParameterDialog,
ok,
};
};

+ 22
- 13
web/src/pages/next-chats/share/index.tsx View File

@@ -3,10 +3,9 @@ import { NextMessageInput } from '@/components/message-input/next';
import MessageItem from '@/components/next-message-item';
import PdfDrawer from '@/components/pdf-drawer';
import { useClickDrawer } from '@/components/pdf-drawer/hooks';
import { MessageType, SharedFrom } from '@/constants/chat';
import { useFetchNextConversationSSE } from '@/hooks/chat-hooks';
import { MessageType } from '@/constants/chat';
import {
useFetchAgentAvatar,
useFetchExternalAgentInputs,
useUploadCanvasFileWithProgress,
} from '@/hooks/use-agent-request';
import { cn } from '@/lib/utils';
@@ -14,11 +13,13 @@ import i18n from '@/locales/config';
import { useCacheChatLog } from '@/pages/agent/hooks/use-cache-chat-log';
import { useSendButtonDisabled } from '@/pages/chat/hooks';
import { buildMessageUuidWithRole } from '@/utils/chat';
import React, { forwardRef, useCallback, useMemo } from 'react';
import { isEmpty } from 'lodash';
import React, { forwardRef, useCallback } from 'react';
import {
useGetSharedChatSearchParams,
useSendNextSharedMessage,
} from '../hooks/use-send-shared-message';
import { ParameterDialog } from './parameter-dialog';

const ChatContainer = () => {
const {
@@ -48,8 +49,13 @@ const ChatContainer = () => {
stopOutputMessage,
findReferenceByMessageId,
appendUploadResponseList,
parameterDialogVisible,
hideParameterDialog,
showParameterDialog,
ok,
} = useSendNextSharedMessage(addEventList);

const { data } = useFetchExternalAgentInputs();
const sendDisabled = useSendButtonDisabled(value);

// useEffect(() => {
@@ -64,12 +70,6 @@ const ChatContainer = () => {
// }
// }, [derivedMessages, setCurrentMessageId]);

const useFetchAvatar = useMemo(() => {
return from === SharedFrom.Agent
? useFetchAgentAvatar
: useFetchNextConversationSSE;
}, [from]);

const handleUploadFile: NonNullable<FileUploadProps['onUpload']> =
useCallback(
async (files, options) => {
@@ -84,12 +84,16 @@ const ChatContainer = () => {
i18n.changeLanguage(locale);
}
}, [locale, visibleAvatar]);
const { data: avatarData } = useFetchAvatar();

React.useEffect(() => {
if (!isEmpty(data)) {
showParameterDialog();
}
}, [data, showParameterDialog]);

if (!conversationId) {
return <div>empty</div>;
}

return (
<section className="h-[100vh] flex justify-center items-center">
<div className=" w-[80vw]">
@@ -108,7 +112,6 @@ const ChatContainer = () => {
}
setCurrentMessageId={setCurrentMessageId}
key={buildMessageUuidWithRole(message)}
avatarDialog={avatarData.avatar}
item={message}
nickname="You"
reference={findReferenceByMessageId(message.id)}
@@ -156,6 +159,12 @@ const ChatContainer = () => {
chunk={selectedChunk}
></PdfDrawer>
)}
{parameterDialogVisible && (
<ParameterDialog
hideModal={hideParameterDialog}
ok={ok}
></ParameterDialog>
)}
</section>
);
};

+ 33
- 0
web/src/pages/next-chats/share/parameter-dialog.tsx View File

@@ -0,0 +1,33 @@
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { useFetchExternalAgentInputs } from '@/hooks/use-agent-request';
import { IModalProps } from '@/interfaces/common';
import DebugContent from '@/pages/agent/debug-content';
import { buildBeginInputListFromObject } from '@/pages/agent/form/begin-form/utils';

interface IProps extends IModalProps<any> {
ok(parameters: any[]): void;
}
export function ParameterDialog({ hideModal, ok }: IProps) {
const { data } = useFetchExternalAgentInputs();

return (
<Dialog open onOpenChange={hideModal}>
<DialogContent>
<DialogHeader>
<DialogTitle>Parameter</DialogTitle>
</DialogHeader>
<DebugContent
parameters={buildBeginInputListFromObject(data)}
ok={ok}
isNext={false}
btnText={'Submit'}
></DebugContent>
</DialogContent>
</Dialog>
);
}

+ 5
- 0
web/src/services/agent-service.ts View File

@@ -24,6 +24,7 @@ const {
fetchCanvas,
fetchAgentAvatar,
fetchAgentLogs,
fetchExternalAgentInputs,
} = api;

const methods = {
@@ -107,6 +108,10 @@ const methods = {
url: fetchAgentLogs,
method: 'get',
},
fetchExternalAgentInputs: {
url: fetchExternalAgentInputs,
method: 'get',
},
} as const;

const agentService = registerNextServer<keyof typeof methods>(methods);

+ 3
- 0
web/src/utils/api.ts View File

@@ -1,4 +1,5 @@
let api_host = `/v1`;
const ExternalApi = `/api`;

export { api_host };

@@ -155,6 +156,8 @@ export default {
uploadAgentFile: (id?: string) => `${api_host}/canvas/upload/${id}`,
fetchAgentLogs: (canvasId: string) =>
`${api_host}/canvas/${canvasId}/sessions`,
fetchExternalAgentInputs: (canvasId: string) =>
`${ExternalApi}${api_host}/agentbots/${canvasId}/inputs`,

// mcp server
listMcpServer: `${api_host}/mcp_server/list`,

Loading…
Cancel
Save