mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
Feat: Add agent-log-list page (#9076)
### What problem does this PR solve? Fix: Add agent-log-list page And RAPTOR:Save directly after enabling, incomplete form submission #3221 ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
186
web/src/components/originui/time-range-picker.tsx
Normal file
186
web/src/components/originui/time-range-picker.tsx
Normal file
@ -0,0 +1,186 @@
|
||||
import {
|
||||
endOfMonth,
|
||||
endOfYear,
|
||||
format,
|
||||
startOfMonth,
|
||||
startOfYear,
|
||||
subDays,
|
||||
subMonths,
|
||||
subYears,
|
||||
} from 'date-fns';
|
||||
import { useEffect, useId, useState } from 'react';
|
||||
|
||||
import { Calendar, DateRange } from '@/components/originui/calendar';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from '@/components/ui/popover';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { CalendarIcon } from 'lucide-react';
|
||||
|
||||
const CalendarComp = ({
|
||||
selectDateRange,
|
||||
onSelect,
|
||||
...props
|
||||
}: ITimeRangePickerProps) => {
|
||||
const today = new Date();
|
||||
const yesterday = {
|
||||
from: subDays(today, 1),
|
||||
to: subDays(today, 1),
|
||||
};
|
||||
const last7Days = {
|
||||
from: subDays(today, 6),
|
||||
to: today,
|
||||
};
|
||||
const last30Days = {
|
||||
from: subDays(today, 29),
|
||||
to: today,
|
||||
};
|
||||
const monthToDate = {
|
||||
from: startOfMonth(today),
|
||||
to: today,
|
||||
};
|
||||
const lastMonth = {
|
||||
from: startOfMonth(subMonths(today, 1)),
|
||||
to: endOfMonth(subMonths(today, 1)),
|
||||
};
|
||||
const yearToDate = {
|
||||
from: startOfYear(today),
|
||||
to: today,
|
||||
};
|
||||
const lastYear = {
|
||||
from: startOfYear(subYears(today, 1)),
|
||||
to: endOfYear(subYears(today, 1)),
|
||||
};
|
||||
const dateRangeList = [
|
||||
{ key: 'yestday', value: yesterday },
|
||||
{ key: 'last7Days', value: last7Days },
|
||||
{ key: 'last30Days', value: last30Days },
|
||||
{ key: 'monthToDate', value: monthToDate },
|
||||
{ key: 'lastMonth', value: lastMonth },
|
||||
{ key: 'yearToDate', value: yearToDate },
|
||||
{ key: 'lastYear', value: lastYear },
|
||||
];
|
||||
const [month, setMonth] = useState(today);
|
||||
const [date, setDate] = useState<DateRange>(selectDateRange || last7Days);
|
||||
useEffect(() => {
|
||||
onSelect?.(date);
|
||||
}, [date, onSelect]);
|
||||
return (
|
||||
<div>
|
||||
<div className="rounded-md border">
|
||||
<div className="flex max-sm:flex-col">
|
||||
<div className="relative py-4 max-sm:order-1 max-sm:border-t sm:w-32">
|
||||
<div className="h-full sm:border-e">
|
||||
<div className="flex flex-col px-2 gap-2">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="w-full justify-start"
|
||||
onClick={() => {
|
||||
setDate({
|
||||
from: today,
|
||||
to: today,
|
||||
});
|
||||
setMonth(today);
|
||||
}}
|
||||
>
|
||||
Today
|
||||
</Button>
|
||||
{dateRangeList.map((dateRange) => (
|
||||
<Button
|
||||
key={dateRange.key}
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="w-full justify-start"
|
||||
onClick={() => {
|
||||
setDate(dateRange.value);
|
||||
setMonth(dateRange.value.to);
|
||||
}}
|
||||
>
|
||||
{dateRange.key}
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Calendar
|
||||
mode="range"
|
||||
selected={date}
|
||||
onSelect={(newDate) => {
|
||||
if (newDate) {
|
||||
setDate(newDate as DateRange);
|
||||
}
|
||||
}}
|
||||
month={month}
|
||||
onMonthChange={setMonth}
|
||||
className="p-2"
|
||||
{...props}
|
||||
// disabled={[
|
||||
// { after: today }, // Dates before today
|
||||
// ]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export type ITimeRangePickerProps = {
|
||||
onSelect: (e: DateRange) => void;
|
||||
selectDateRange: DateRange;
|
||||
className?: string;
|
||||
};
|
||||
const TimeRangePicker = ({
|
||||
onSelect,
|
||||
selectDateRange,
|
||||
...props
|
||||
}: ITimeRangePickerProps) => {
|
||||
const id = useId();
|
||||
const today = new Date();
|
||||
const [date, setDate] = useState<DateRange | undefined>(
|
||||
selectDateRange || { from: today, to: today },
|
||||
);
|
||||
const onChange = (e: DateRange | undefined) => {
|
||||
if (!e) return;
|
||||
setDate(e);
|
||||
onSelect?.(e);
|
||||
};
|
||||
return (
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<Button
|
||||
id={id}
|
||||
variant="outline"
|
||||
className="group bg-muted-foreground/10 hover:bg-muted-foreground/10 border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px]"
|
||||
>
|
||||
<span className={cn('truncate', !date && 'text-muted-foreground')}>
|
||||
{date?.from ? (
|
||||
date.to ? (
|
||||
<>
|
||||
{format(date.from, 'LLL dd, y')} -{' '}
|
||||
{format(date.to, 'LLL dd, y')}
|
||||
</>
|
||||
) : (
|
||||
format(date.from, 'LLL dd, y')
|
||||
)
|
||||
) : (
|
||||
'Pick a date range'
|
||||
)}
|
||||
</span>
|
||||
<CalendarIcon
|
||||
size={16}
|
||||
className="text-muted-foreground/80 group-hover:text-foreground shrink-0 transition-colors"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-2" align="start">
|
||||
<CalendarComp selectDateRange={date} onSelect={onChange} {...props} />
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
export default TimeRangePicker;
|
||||
@ -54,6 +54,13 @@ export const useNavigatePage = () => {
|
||||
[navigate],
|
||||
);
|
||||
|
||||
const navigateToAgentLogs = useCallback(
|
||||
(id: string) => () => {
|
||||
navigate(`${Routes.AgentLogPage}/${id}`);
|
||||
},
|
||||
[navigate],
|
||||
);
|
||||
|
||||
const navigateToAgentTemplates = useCallback(() => {
|
||||
navigate(Routes.AgentTemplates);
|
||||
}, [navigate]);
|
||||
@ -120,6 +127,7 @@ export const useNavigatePage = () => {
|
||||
navigateToChunk,
|
||||
navigateToAgents,
|
||||
navigateToAgent,
|
||||
navigateToAgentLogs,
|
||||
navigateToAgentTemplates,
|
||||
navigateToSearchList,
|
||||
navigateToSearch,
|
||||
|
||||
@ -1,13 +1,20 @@
|
||||
import { FileUploadProps } from '@/components/file-upload';
|
||||
import message from '@/components/ui/message';
|
||||
import { AgentGlobals } from '@/constants/agent';
|
||||
import { ITraceData } from '@/interfaces/database/agent';
|
||||
import {
|
||||
IAgentLogsRequest,
|
||||
IAgentLogsResponse,
|
||||
ITraceData,
|
||||
} from '@/interfaces/database/agent';
|
||||
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 { useGetSharedChatSearchParams } from '@/pages/chat/shared-hooks';
|
||||
import agentService, { fetchTrace } from '@/services/agent-service';
|
||||
import agentService, {
|
||||
fetchAgentLogsByCanvasId,
|
||||
fetchTrace,
|
||||
} from '@/services/agent-service';
|
||||
import api from '@/utils/api';
|
||||
import { buildMessageListWithUuid } from '@/utils/chat';
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
@ -558,3 +565,22 @@ export const useFetchAgentAvatar = (): {
|
||||
|
||||
return { data, loading, refetch };
|
||||
};
|
||||
|
||||
export const useFetchAgentLog = (searchParams: IAgentLogsRequest) => {
|
||||
const { id } = useParams();
|
||||
const { data, isFetching: loading } = useQuery<IAgentLogsResponse>({
|
||||
queryKey: ['fetchAgentLog', id, searchParams],
|
||||
initialData: {} as IAgentLogsResponse,
|
||||
gcTime: 0,
|
||||
queryFn: async () => {
|
||||
console.log('useFetchAgentLog', searchParams);
|
||||
const { data } = await fetchAgentLogsByCanvasId(id as string, {
|
||||
...searchParams,
|
||||
});
|
||||
|
||||
return data?.data ?? [];
|
||||
},
|
||||
});
|
||||
|
||||
return { data, loading };
|
||||
};
|
||||
|
||||
@ -229,3 +229,38 @@ export interface ITraceData {
|
||||
component_id: string;
|
||||
trace: Array<Record<string, any>>;
|
||||
}
|
||||
|
||||
export interface IAgentLogResponse {
|
||||
id: string;
|
||||
message: IAgentLogMessage[];
|
||||
update_date: string;
|
||||
create_date: string;
|
||||
update_time: number;
|
||||
create_time: number;
|
||||
round: number;
|
||||
thumb_up: number;
|
||||
errors: string;
|
||||
source: string;
|
||||
user_id: string;
|
||||
dsl: string;
|
||||
reference: IReference;
|
||||
}
|
||||
export interface IAgentLogsResponse {
|
||||
total: number;
|
||||
sessions: IAgentLogResponse[];
|
||||
}
|
||||
export interface IAgentLogsRequest {
|
||||
keywords?: string;
|
||||
to_date?: string | Date;
|
||||
from_date?: string | Date;
|
||||
orderby?: string;
|
||||
desc?: boolean;
|
||||
page?: number;
|
||||
page_size?: number;
|
||||
}
|
||||
|
||||
export interface IAgentLogMessage {
|
||||
content: string;
|
||||
role: 'user' | 'assistant';
|
||||
id: string;
|
||||
}
|
||||
|
||||
@ -25,7 +25,6 @@ import {
|
||||
CirclePlay,
|
||||
Download,
|
||||
History,
|
||||
Key,
|
||||
LaptopMinimalCheck,
|
||||
Logs,
|
||||
ScreenShare,
|
||||
@ -42,7 +41,6 @@ import {
|
||||
useGetBeginNodeDataInputs,
|
||||
useGetBeginNodeDataQueryIsSafe,
|
||||
} from './hooks/use-get-begin-query';
|
||||
import { useOpenDocument } from './hooks/use-open-document';
|
||||
import {
|
||||
useSaveGraph,
|
||||
useSaveGraphBeforeOpeningDebugDrawer,
|
||||
@ -73,7 +71,7 @@ export default function Agent() {
|
||||
const { t } = useTranslation();
|
||||
const { data: userInfo } = useFetchUserInfo();
|
||||
|
||||
const openDocument = useOpenDocument();
|
||||
// const openDocument = useOpenDocument();
|
||||
const {
|
||||
handleExportJson,
|
||||
handleImportJson,
|
||||
@ -100,7 +98,7 @@ export default function Agent() {
|
||||
|
||||
const { showEmbedModal, hideEmbedModal, embedVisible, beta } =
|
||||
useShowEmbedModal();
|
||||
|
||||
const { navigateToAgentLogs } = useNavigatePage();
|
||||
const isBeginNodeDataQuerySafe = useGetBeginNodeDataQueryIsSafe();
|
||||
|
||||
return (
|
||||
@ -135,7 +133,10 @@ export default function Agent() {
|
||||
<History />
|
||||
{t('flow.historyversion')}
|
||||
</Button>
|
||||
<Button variant={'secondary'}>
|
||||
<Button
|
||||
variant={'secondary'}
|
||||
onClick={navigateToAgentLogs(id as string)}
|
||||
>
|
||||
<Logs />
|
||||
{t('flow.log')}
|
||||
</Button>
|
||||
@ -147,11 +148,11 @@ export default function Agent() {
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<AgentDropdownMenuItem onClick={openDocument}>
|
||||
{/* <AgentDropdownMenuItem onClick={openDocument}>
|
||||
<Key />
|
||||
API
|
||||
</AgentDropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
</AgentDropdownMenuItem> */}
|
||||
{/* <DropdownMenuSeparator /> */}
|
||||
<AgentDropdownMenuItem onClick={handleImportJson}>
|
||||
<Download />
|
||||
{t('flow.import')}
|
||||
|
||||
319
web/src/pages/agents/agent-log-page.tsx
Normal file
319
web/src/pages/agents/agent-log-page.tsx
Normal file
@ -0,0 +1,319 @@
|
||||
import TimeRangePicker from '@/components/originui/time-range-picker';
|
||||
import { PageHeader } from '@/components/page-header';
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from '@/components/ui/breadcrumb';
|
||||
import { SearchInput } from '@/components/ui/input';
|
||||
import { RAGFlowPagination } from '@/components/ui/ragflow-pagination';
|
||||
import { Spin } from '@/components/ui/spin';
|
||||
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
|
||||
import { useFetchAgentLog } from '@/hooks/use-agent-request';
|
||||
import { IAgentLogResponse } from '@/interfaces/database/agent';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useParams } from 'umi';
|
||||
import { DateRange } from '../../components/originui/calendar/index';
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from '../../components/ui/table';
|
||||
import { useFetchDataOnMount } from '../agent/hooks/use-fetch-data';
|
||||
|
||||
const AgentLogPage: React.FC = () => {
|
||||
const { navigateToAgentList, navigateToAgent } = useNavigatePage();
|
||||
const { flowDetail: agentDetail } = useFetchDataOnMount();
|
||||
const { id: canvasId } = useParams();
|
||||
const today = new Date();
|
||||
const init = {
|
||||
keywords: '',
|
||||
from_date: today,
|
||||
to_date: today,
|
||||
orderby: 'create_time',
|
||||
desc: false,
|
||||
page: 1,
|
||||
page_size: 10,
|
||||
};
|
||||
const [searchParams, setSearchParams] = useState(init);
|
||||
const columns = [
|
||||
{
|
||||
title: 'ID',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
},
|
||||
{
|
||||
title: 'Title',
|
||||
dataIndex: 'title',
|
||||
key: 'title',
|
||||
render: (text, record: IAgentLogResponse) => (
|
||||
<span>
|
||||
{record?.message?.length ? record?.message[0]?.content : ''}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'State',
|
||||
dataIndex: 'state',
|
||||
key: 'state',
|
||||
render: (text, record: IAgentLogResponse) => (
|
||||
<div
|
||||
className="size-2 rounded-full"
|
||||
style={{ backgroundColor: record.errors ? 'red' : 'green' }}
|
||||
></div>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Number',
|
||||
dataIndex: 'round',
|
||||
key: 'round',
|
||||
},
|
||||
{
|
||||
title: 'Latest Date',
|
||||
dataIndex: 'update_date',
|
||||
key: 'update_date',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
title: 'Create Date',
|
||||
dataIndex: 'create_date',
|
||||
key: 'create_date',
|
||||
sortable: true,
|
||||
},
|
||||
];
|
||||
|
||||
const { data: logData, loading } = useFetchAgentLog(searchParams);
|
||||
const { sessions: data, total } = logData || {};
|
||||
const [currentDate, setCurrentDate] = useState<DateRange>({
|
||||
from: searchParams.from_date,
|
||||
to: searchParams.to_date,
|
||||
});
|
||||
const [keywords, setKeywords] = useState(searchParams.keywords);
|
||||
const handleDateRangeChange = ({
|
||||
from: startDate,
|
||||
to: endDate,
|
||||
}: DateRange) => {
|
||||
setCurrentDate({ from: startDate, to: endDate });
|
||||
};
|
||||
|
||||
const [pagination, setPagination] = useState<{
|
||||
current: number;
|
||||
pageSize: number;
|
||||
total: number;
|
||||
}>({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: total,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setPagination((pre) => {
|
||||
return {
|
||||
...pre,
|
||||
total: total,
|
||||
};
|
||||
});
|
||||
}, [total]);
|
||||
|
||||
const [sortConfig, setSortConfig] = useState<{
|
||||
orderby: string;
|
||||
desc: boolean;
|
||||
} | null>({ orderby: init.orderby, desc: init.desc ? true : false });
|
||||
|
||||
const handlePageChange = (current?: number, pageSize?: number) => {
|
||||
console.log('current', current, 'pageSize', pageSize);
|
||||
setPagination((pre) => {
|
||||
return {
|
||||
...pre,
|
||||
current: current ?? pre.current,
|
||||
pageSize: pageSize ?? pre.pageSize,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const handleSearch = () => {
|
||||
setSearchParams((pre) => {
|
||||
return {
|
||||
...pre,
|
||||
from_date: currentDate.from as Date,
|
||||
to_date: currentDate.to as Date,
|
||||
page: pagination.current,
|
||||
page_size: pagination.pageSize,
|
||||
orderby: sortConfig?.orderby || '',
|
||||
desc: sortConfig?.desc as boolean,
|
||||
keywords: keywords,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
handleSearch();
|
||||
}, [pagination.current, pagination.pageSize, sortConfig]);
|
||||
// handle sort
|
||||
const handleSort = (key: string) => {
|
||||
let desc = false;
|
||||
if (sortConfig && sortConfig.orderby === key) {
|
||||
desc = !sortConfig.desc;
|
||||
}
|
||||
setSortConfig({ orderby: key, desc });
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
setSearchParams(init);
|
||||
};
|
||||
return (
|
||||
<div className=" text-white">
|
||||
<PageHeader>
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink onClick={navigateToAgentList}>
|
||||
Agent
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink onClick={navigateToAgent(canvasId as string)}>
|
||||
{agentDetail.title}
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbPage>Log</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</PageHeader>
|
||||
<div className="p-4">
|
||||
<div className="flex justify-between items-center">
|
||||
<h1 className="text-2xl font-bold mb-4">Log</h1>
|
||||
|
||||
<div className="flex justify-end space-x-2 mb-4">
|
||||
<div className="flex items-center space-x-2">
|
||||
<span>ID/Title</span>
|
||||
<SearchInput
|
||||
value={keywords}
|
||||
onChange={(e) => {
|
||||
setKeywords(e.target.value);
|
||||
}}
|
||||
className="w-32"
|
||||
></SearchInput>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<span className="whitespace-nowrap">Latest Date</span>
|
||||
<TimeRangePicker
|
||||
onSelect={handleDateRangeChange}
|
||||
selectDateRange={{ from: currentDate.from, to: currentDate.to }}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="bg-foreground text-text-title-invert px-4 py-1 rounded"
|
||||
onClick={() => {
|
||||
setPagination({ ...pagination, current: 1 });
|
||||
handleSearch();
|
||||
}}
|
||||
>
|
||||
Search
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="bg-transparent text-foreground px-4 py-1 rounded border"
|
||||
onClick={() => handleReset()}
|
||||
>
|
||||
Reset
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="border rounded-md overflow-auto">
|
||||
{/* <div className="max-h-[500px] overflow-y-auto w-full"> */}
|
||||
<Table rootClassName="max-h-[calc(100vh-200px)]">
|
||||
<TableHeader className="sticky top-0 bg-background z-10 shadow-sm">
|
||||
<TableRow>
|
||||
{columns.map((column) => (
|
||||
<TableHead
|
||||
key={column.dataIndex}
|
||||
onClick={
|
||||
column.sortable
|
||||
? () => handleSort(column.dataIndex)
|
||||
: undefined
|
||||
}
|
||||
className={
|
||||
column.sortable ? 'cursor-pointer hover:bg-muted/50' : ''
|
||||
}
|
||||
>
|
||||
<div className="flex items-center">
|
||||
{column.title}
|
||||
{column.sortable &&
|
||||
sortConfig?.orderby === column.dataIndex && (
|
||||
<span className="ml-1">
|
||||
{sortConfig.desc ? '↓' : '↑'}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{loading && (
|
||||
<TableRow>
|
||||
<TableCell
|
||||
colSpan={columns.length}
|
||||
className="h-24 text-center"
|
||||
>
|
||||
<Spin size="large">
|
||||
<span className="sr-only">Loading...</span>
|
||||
</Spin>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
{!loading &&
|
||||
data?.map((item) => (
|
||||
<TableRow key={item.id}>
|
||||
{columns.map((column) => (
|
||||
<TableCell key={column.dataIndex}>
|
||||
{column.render
|
||||
? column.render(item[column.dataIndex], item)
|
||||
: item[column.dataIndex]}
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
))}
|
||||
{!loading && (!data || data.length === 0) && (
|
||||
<TableRow>
|
||||
<TableCell
|
||||
colSpan={columns.length}
|
||||
className="h-24 text-center"
|
||||
>
|
||||
No data
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
{/* </div> */}
|
||||
</div>
|
||||
<div className="flex justify-end mt-4 w-full">
|
||||
<div className="space-x-2">
|
||||
<RAGFlowPagination
|
||||
{...pagination}
|
||||
total={pagination.total}
|
||||
onChange={(page, pageSize) => {
|
||||
handlePageChange(page, pageSize);
|
||||
}}
|
||||
></RAGFlowPagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AgentLogPage;
|
||||
@ -88,13 +88,17 @@ export function ChunkMethodForm() {
|
||||
let beValid = await form.formControl.trigger();
|
||||
if (beValid) {
|
||||
// setSubmitLoading(true);
|
||||
let postData = form.formState.values;
|
||||
delete postData['avatar']; // has submitted in first form general
|
||||
|
||||
saveKnowledgeConfiguration({
|
||||
...postData,
|
||||
// let postData = form.formState.values;
|
||||
// console.log('submit form -->', form);
|
||||
// delete postData['avatar']; // has submitted in first form general
|
||||
form.handleSubmit(async (values) => {
|
||||
console.log('saveKnowledgeConfiguration: ', values);
|
||||
delete values['avatar'];
|
||||
await saveKnowledgeConfiguration({
|
||||
kb_id,
|
||||
...values,
|
||||
});
|
||||
})();
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
|
||||
@ -36,6 +36,7 @@ export enum Routes {
|
||||
Result = '/result',
|
||||
ResultView = `${Chunk}${Result}`,
|
||||
KnowledgeGraph = '/knowledge-graph',
|
||||
AgentLogPage = '/agent-log-page',
|
||||
}
|
||||
|
||||
const routes = [
|
||||
@ -244,6 +245,11 @@ const routes = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: `${Routes.AgentLogPage}/:id`,
|
||||
layout: false,
|
||||
component: `@/pages${Routes.Agents}${Routes.AgentLogPage}`,
|
||||
},
|
||||
{
|
||||
path: `${Routes.Agent}/:id`,
|
||||
layout: false,
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { IAgentLogsRequest } from '@/interfaces/database/agent';
|
||||
import api from '@/utils/api';
|
||||
import { registerNextServer } from '@/utils/register-server';
|
||||
import request from '@/utils/request';
|
||||
@ -22,6 +23,7 @@ const {
|
||||
fetchVersion,
|
||||
fetchCanvas,
|
||||
fetchAgentAvatar,
|
||||
fetchAgentLogs,
|
||||
} = api;
|
||||
|
||||
const methods = {
|
||||
@ -101,6 +103,10 @@ const methods = {
|
||||
url: fetchAgentAvatar,
|
||||
method: 'get',
|
||||
},
|
||||
fetchAgentLogs: {
|
||||
url: fetchAgentLogs,
|
||||
method: 'get',
|
||||
},
|
||||
} as const;
|
||||
|
||||
const agentService = registerNextServer<keyof typeof methods>(methods);
|
||||
@ -108,5 +114,11 @@ const agentService = registerNextServer<keyof typeof methods>(methods);
|
||||
export const fetchTrace = (data: { canvas_id: string; message_id: string }) => {
|
||||
return request.get(methods.trace.url, { params: data });
|
||||
};
|
||||
export const fetchAgentLogsByCanvasId = (
|
||||
canvasId: string,
|
||||
params: IAgentLogsRequest,
|
||||
) => {
|
||||
return request.get(methods.fetchAgentLogs.url(canvasId), { params: params });
|
||||
};
|
||||
|
||||
export default agentService;
|
||||
|
||||
@ -153,6 +153,8 @@ export default {
|
||||
fetchCanvas: (id: string) => `${api_host}/canvas/get/${id}`,
|
||||
fetchAgentAvatar: (id: string) => `${api_host}/canvas/getsse/${id}`,
|
||||
uploadAgentFile: (id?: string) => `${api_host}/canvas/upload/${id}`,
|
||||
fetchAgentLogs: (canvasId: string) =>
|
||||
`${api_host}/canvas/${canvasId}/sessions`,
|
||||
|
||||
// mcp server
|
||||
listMcpServer: `${api_host}/mcp_server/list`,
|
||||
|
||||
@ -32,3 +32,14 @@ export function formatPureDate(date: any) {
|
||||
}
|
||||
return dayjs(date).format('DD/MM/YYYY');
|
||||
}
|
||||
|
||||
export function formatStandardDate(date: any) {
|
||||
if (!date) {
|
||||
return '';
|
||||
}
|
||||
const parsedDate = dayjs(date);
|
||||
if (!parsedDate.isValid()) {
|
||||
return '';
|
||||
}
|
||||
return parsedDate.format('YYYY-MM-DD');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user