mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-19 12:06:42 +08:00
### What problem does this PR solve? Feat: Display the data flow log on the far right. #9869 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -1599,6 +1599,9 @@ This delimiter is used to split the input text into several text pieces echo of
|
|||||||
serverType: 'Server Type',
|
serverType: 'Server Type',
|
||||||
addMCP: 'Add MCP',
|
addMCP: 'Add MCP',
|
||||||
editMCP: 'Edit MCP',
|
editMCP: 'Edit MCP',
|
||||||
|
toolsAvailable: 'tools available',
|
||||||
|
mcpServers: 'MCP Servers',
|
||||||
|
customizeTheListOfMcpServers: 'Customize the list of MCP servers',
|
||||||
},
|
},
|
||||||
search: {
|
search: {
|
||||||
searchApps: 'Search Apps',
|
searchApps: 'Search Apps',
|
||||||
@ -1695,6 +1698,7 @@ This delimiter is used to split the input text into several text pieces echo of
|
|||||||
filenameEmbdWeight: 'Filename embd weight',
|
filenameEmbdWeight: 'Filename embd weight',
|
||||||
begin: 'File',
|
begin: 'File',
|
||||||
parserMethod: 'Parser method',
|
parserMethod: 'Parser method',
|
||||||
|
exportJson: 'Export JSON',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1510,6 +1510,17 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
|||||||
okText: '确认',
|
okText: '确认',
|
||||||
cancelText: '取消',
|
cancelText: '取消',
|
||||||
},
|
},
|
||||||
|
mcp: {
|
||||||
|
export: '导出',
|
||||||
|
import: '导入',
|
||||||
|
url: 'URL',
|
||||||
|
serverType: '服务器类型',
|
||||||
|
addMCP: '添加 MCP',
|
||||||
|
editMCP: '编辑 MCP',
|
||||||
|
toolsAvailable: '可用的工具',
|
||||||
|
mcpServers: 'MCP 服务器',
|
||||||
|
customizeTheListOfMcpServers: '自定义 MCP 服务器列表',
|
||||||
|
},
|
||||||
search: {
|
search: {
|
||||||
searchApps: '搜索',
|
searchApps: '搜索',
|
||||||
createSearch: '创建查询',
|
createSearch: '创建查询',
|
||||||
@ -1605,6 +1616,7 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
|||||||
filenameEmbdWeight: '文件名嵌入权重',
|
filenameEmbdWeight: '文件名嵌入权重',
|
||||||
begin: '文件',
|
begin: '文件',
|
||||||
parserMethod: '解析方法',
|
parserMethod: '解析方法',
|
||||||
|
exportJson: '导出 JSON',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -153,7 +153,11 @@ function DataFlowCanvas({ drawerVisible, hideDrawer }: IProps) {
|
|||||||
hideModal: hideLogSheet,
|
hideModal: hideLogSheet,
|
||||||
} = useSetModalState();
|
} = useSetModalState();
|
||||||
|
|
||||||
const { run, loading: running, messageId } = useRunDataflow(showLogSheet!);
|
const {
|
||||||
|
run,
|
||||||
|
loading: running,
|
||||||
|
messageId,
|
||||||
|
} = useRunDataflow(showLogSheet!, hideRunOrChatDrawer);
|
||||||
|
|
||||||
const onConnect = (connection: Connection) => {
|
const onConnect = (connection: Connection) => {
|
||||||
originalOnConnect(connection);
|
originalOnConnect(connection);
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { useFetchAgent } from '@/hooks/use-agent-request';
|
||||||
import { ITraceData } from '@/interfaces/database/agent';
|
import { ITraceData } from '@/interfaces/database/agent';
|
||||||
import { downloadJsonFile } from '@/utils/file-util';
|
import { downloadJsonFile } from '@/utils/file-util';
|
||||||
import { get, isEmpty } from 'lodash';
|
import { get, isEmpty } from 'lodash';
|
||||||
@ -22,12 +23,14 @@ export function isEndOutputEmpty(list?: ITraceData[]) {
|
|||||||
return isEmpty(findEndOutput(list));
|
return isEmpty(findEndOutput(list));
|
||||||
}
|
}
|
||||||
export function useDownloadOutput(data?: ITraceData[]) {
|
export function useDownloadOutput(data?: ITraceData[]) {
|
||||||
|
const { data: agent } = useFetchAgent();
|
||||||
|
|
||||||
const handleDownloadJson = useCallback(() => {
|
const handleDownloadJson = useCallback(() => {
|
||||||
const output = findEndOutput(data);
|
const output = findEndOutput(data);
|
||||||
if (!isEndOutputEmpty(data)) {
|
if (!isEndOutputEmpty(data)) {
|
||||||
downloadJsonFile(output, `output.json`);
|
downloadJsonFile(output, `${agent.title}.json`);
|
||||||
}
|
}
|
||||||
}, [data]);
|
}, [agent.title, data]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
handleDownloadJson,
|
handleDownloadJson,
|
||||||
|
|||||||
@ -5,7 +5,10 @@ import { useCallback, useState } from 'react';
|
|||||||
import { useParams } from 'umi';
|
import { useParams } from 'umi';
|
||||||
import { useSaveGraphBeforeOpeningDebugDrawer } from './use-save-graph';
|
import { useSaveGraphBeforeOpeningDebugDrawer } from './use-save-graph';
|
||||||
|
|
||||||
export function useRunDataflow(showLogSheet: () => void) {
|
export function useRunDataflow(
|
||||||
|
showLogSheet: () => void,
|
||||||
|
hideRunOrChatDrawer: () => void,
|
||||||
|
) {
|
||||||
const { send } = useSendMessageBySSE(api.runCanvas);
|
const { send } = useSendMessageBySSE(api.runCanvas);
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const [messageId, setMessageId] = useState();
|
const [messageId, setMessageId] = useState();
|
||||||
@ -26,6 +29,7 @@ export function useRunDataflow(showLogSheet: () => void) {
|
|||||||
|
|
||||||
if (res && res?.response.status === 200 && get(res, 'data.code') === 0) {
|
if (res && res?.response.status === 200 && get(res, 'data.code') === 0) {
|
||||||
// fetch canvas
|
// fetch canvas
|
||||||
|
hideRunOrChatDrawer();
|
||||||
|
|
||||||
const msgId = get(res, 'data.data.message_id');
|
const msgId = get(res, 'data.data.message_id');
|
||||||
if (msgId) {
|
if (msgId) {
|
||||||
@ -35,7 +39,7 @@ export function useRunDataflow(showLogSheet: () => void) {
|
|||||||
return msgId;
|
return msgId;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[id, saveGraph, send],
|
[hideRunOrChatDrawer, id, saveGraph, send],
|
||||||
);
|
);
|
||||||
|
|
||||||
return { run, loading: loading, messageId };
|
return { run, loading: loading, messageId };
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import { IModalProps } from '@/interfaces/common';
|
|||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { NotebookText, SquareArrowOutUpRight } from 'lucide-react';
|
import { NotebookText, SquareArrowOutUpRight } from 'lucide-react';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
import 'react18-json-view/src/style.css';
|
import 'react18-json-view/src/style.css';
|
||||||
import {
|
import {
|
||||||
isEndOutputEmpty,
|
isEndOutputEmpty,
|
||||||
@ -20,6 +21,7 @@ import { DataflowTimeline } from './dataflow-timeline';
|
|||||||
type LogSheetProps = IModalProps<any> & { messageId?: string };
|
type LogSheetProps = IModalProps<any> & { messageId?: string };
|
||||||
|
|
||||||
export function LogSheet({ hideModal, messageId }: LogSheetProps) {
|
export function LogSheet({ hideModal, messageId }: LogSheetProps) {
|
||||||
|
const { t } = useTranslation();
|
||||||
const { setMessageId, data } = useFetchMessageTrace(false);
|
const { setMessageId, data } = useFetchMessageTrace(false);
|
||||||
|
|
||||||
const { handleDownloadJson } = useDownloadOutput(data);
|
const { handleDownloadJson } = useDownloadOutput(data);
|
||||||
@ -32,7 +34,7 @@ export function LogSheet({ hideModal, messageId }: LogSheetProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Sheet open onOpenChange={hideModal} modal={false}>
|
<Sheet open onOpenChange={hideModal} modal={false}>
|
||||||
<SheetContent className={cn('top-20 right-[620px]')}>
|
<SheetContent className={cn('top-20')}>
|
||||||
<SheetHeader>
|
<SheetHeader>
|
||||||
<SheetTitle className="flex items-center gap-1">
|
<SheetTitle className="flex items-center gap-1">
|
||||||
<NotebookText className="size-4" />
|
<NotebookText className="size-4" />
|
||||||
@ -46,7 +48,7 @@ export function LogSheet({ hideModal, messageId }: LogSheetProps) {
|
|||||||
className="w-full mt-8"
|
className="w-full mt-8"
|
||||||
>
|
>
|
||||||
<SquareArrowOutUpRight />
|
<SquareArrowOutUpRight />
|
||||||
Export JSON
|
{t('dataflow.exportJson')}
|
||||||
</Button>
|
</Button>
|
||||||
</section>
|
</section>
|
||||||
</SheetContent>
|
</SheetContent>
|
||||||
|
|||||||
@ -122,7 +122,11 @@ export function EditMcpDialog({
|
|||||||
setFieldChanged={setFieldChanged}
|
setFieldChanged={setFieldChanged}
|
||||||
></EditMcpForm>
|
></EditMcpForm>
|
||||||
<Collapse
|
<Collapse
|
||||||
title={<div>{nextTools?.length || 0} tools available</div>}
|
title={
|
||||||
|
<div>
|
||||||
|
{nextTools?.length || 0} {t('mcp.toolsAvailable')}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
open={collapseOpen}
|
open={collapseOpen}
|
||||||
onOpenChange={setCollapseOpen}
|
onOpenChange={setCollapseOpen}
|
||||||
rightContent={
|
rightContent={
|
||||||
|
|||||||
@ -33,10 +33,10 @@ export default function McpServer() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="p-4 w-full">
|
<section className="p-4 w-full">
|
||||||
<div className="text-text-primary text-2xl">MCP Servers</div>
|
<div className="text-text-primary text-2xl">{t('mcp.mcpServers')}</div>
|
||||||
<section className="flex items-center justify-between pb-5">
|
<section className="flex items-center justify-between pb-5">
|
||||||
<div className="text-text-secondary">
|
<div className="text-text-secondary">
|
||||||
Customize the list of MCP servers
|
{t('mcp.customizeTheListOfMcpServers')}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-5">
|
<div className="flex gap-5">
|
||||||
<SearchInput
|
<SearchInput
|
||||||
|
|||||||
Reference in New Issue
Block a user