mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
### What problem does this PR solve? Feat: Allow chat to use meta data #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -53,14 +53,14 @@ export default defineConfig({
|
|||||||
|
|
||||||
memo.optimization.minimizer('terser').use(TerserPlugin); // Fixed the issue that the page displayed an error after packaging lexical with terser
|
memo.optimization.minimizer('terser').use(TerserPlugin); // Fixed the issue that the page displayed an error after packaging lexical with terser
|
||||||
|
|
||||||
memo.plugin('eslint').use(ESLintPlugin, [
|
// memo.plugin('eslint').use(ESLintPlugin, [
|
||||||
{
|
// {
|
||||||
extensions: ['js', 'ts', 'tsx'],
|
// extensions: ['js', 'ts', 'tsx'],
|
||||||
failOnError: true,
|
// failOnError: true,
|
||||||
exclude: ['**/node_modules/**', '**/mfsu**', '**/mfsu-virtual-entry**'],
|
// exclude: ['**/node_modules/**', '**/mfsu**', '**/mfsu-virtual-entry**'],
|
||||||
files: ['src/**/*.{js,ts,tsx}'],
|
// files: ['src/**/*.{js,ts,tsx}'],
|
||||||
},
|
// },
|
||||||
]);
|
// ]);
|
||||||
|
|
||||||
return memo;
|
return memo;
|
||||||
},
|
},
|
||||||
|
|||||||
@ -4,8 +4,8 @@ import isEqual from 'lodash/isEqual';
|
|||||||
import { ReactNode, useCallback, useEffect, useRef, useState } from 'react';
|
import { ReactNode, useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export const useSetModalState = () => {
|
export const useSetModalState = (initialVisible = false) => {
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(initialVisible);
|
||||||
|
|
||||||
const showModal = useCallback(() => {
|
const showModal = useCallback(() => {
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
|
|||||||
@ -28,6 +28,8 @@ export const enum KnowledgeApiAction {
|
|||||||
DeleteKnowledge = 'deleteKnowledge',
|
DeleteKnowledge = 'deleteKnowledge',
|
||||||
SaveKnowledge = 'saveKnowledge',
|
SaveKnowledge = 'saveKnowledge',
|
||||||
FetchKnowledgeDetail = 'fetchKnowledgeDetail',
|
FetchKnowledgeDetail = 'fetchKnowledgeDetail',
|
||||||
|
FetchKnowledgeGraph = 'fetchKnowledgeGraph',
|
||||||
|
FetchMetadata = 'fetchMetadata',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useKnowledgeBaseId = (): string => {
|
export const useKnowledgeBaseId = (): string => {
|
||||||
@ -263,7 +265,7 @@ export function useFetchKnowledgeGraph() {
|
|||||||
const knowledgeBaseId = useKnowledgeBaseId();
|
const knowledgeBaseId = useKnowledgeBaseId();
|
||||||
|
|
||||||
const { data, isFetching: loading } = useQuery<IKnowledgeGraph>({
|
const { data, isFetching: loading } = useQuery<IKnowledgeGraph>({
|
||||||
queryKey: ['fetchKnowledgeGraph', knowledgeBaseId],
|
queryKey: [KnowledgeApiAction.FetchKnowledgeGraph, knowledgeBaseId],
|
||||||
initialData: { graph: {}, mind_map: {} } as IKnowledgeGraph,
|
initialData: { graph: {}, mind_map: {} } as IKnowledgeGraph,
|
||||||
enabled: !!knowledgeBaseId,
|
enabled: !!knowledgeBaseId,
|
||||||
gcTime: 0,
|
gcTime: 0,
|
||||||
@ -275,3 +277,20 @@ export function useFetchKnowledgeGraph() {
|
|||||||
|
|
||||||
return { data, loading };
|
return { data, loading };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useFetchKnowledgeMetadata(kbIds: string[] = []) {
|
||||||
|
const { data, isFetching: loading } = useQuery<
|
||||||
|
Record<string, Record<string, string[]>>
|
||||||
|
>({
|
||||||
|
queryKey: [KnowledgeApiAction.FetchMetadata, kbIds],
|
||||||
|
initialData: {},
|
||||||
|
enabled: kbIds.length > 0,
|
||||||
|
gcTime: 0,
|
||||||
|
queryFn: async () => {
|
||||||
|
const { data } = await kbService.getMeta({ kb_ids: kbIds.join(',') });
|
||||||
|
return data?.data ?? {};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return { data, loading };
|
||||||
|
}
|
||||||
|
|||||||
@ -563,6 +563,9 @@ This auto-tagging feature enhances retrieval by adding another layer of domain-s
|
|||||||
crossLanguage: 'Cross-language search',
|
crossLanguage: 'Cross-language search',
|
||||||
crossLanguageTip: `Select one or more languages for cross‑language search. If no language is selected, the system searches with the original query.`,
|
crossLanguageTip: `Select one or more languages for cross‑language search. If no language is selected, the system searches with the original query.`,
|
||||||
createChat: 'Create chat',
|
createChat: 'Create chat',
|
||||||
|
metadata: 'Metadata',
|
||||||
|
metadataTip: 'Metadata',
|
||||||
|
conditions: 'Conditions',
|
||||||
},
|
},
|
||||||
setting: {
|
setting: {
|
||||||
profile: 'Profile',
|
profile: 'Profile',
|
||||||
|
|||||||
@ -8,10 +8,25 @@ import classNames from 'classnames';
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { ISegmentedContentProps } from '../interface';
|
import { ISegmentedContentProps } from '../interface';
|
||||||
|
|
||||||
|
import { DatasetMetadata } from '../constants';
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
|
import { MetadataFilterConditions } from './metadata-filter-conditions';
|
||||||
|
|
||||||
const emptyResponseField = ['prompt_config', 'empty_response'];
|
const emptyResponseField = ['prompt_config', 'empty_response'];
|
||||||
|
|
||||||
|
const MetadataOptions = Object.values(DatasetMetadata).map((x) => {
|
||||||
|
let value: DatasetMetadata | boolean = x;
|
||||||
|
if (x === DatasetMetadata.Disabled) {
|
||||||
|
value = false;
|
||||||
|
} else if (x === DatasetMetadata.Automatic) {
|
||||||
|
value = true;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
value,
|
||||||
|
label: x,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
const AssistantSetting = ({
|
const AssistantSetting = ({
|
||||||
show,
|
show,
|
||||||
form,
|
form,
|
||||||
@ -20,6 +35,11 @@ const AssistantSetting = ({
|
|||||||
const { t } = useTranslate('chat');
|
const { t } = useTranslate('chat');
|
||||||
const { data } = useFetchTenantInfo(true);
|
const { data } = useFetchTenantInfo(true);
|
||||||
|
|
||||||
|
const metadata = Form.useWatch(['meta_data_filter', 'auto'], form);
|
||||||
|
const kbIds = Form.useWatch(['kb_ids'], form);
|
||||||
|
|
||||||
|
const hasKnowledge = Array.isArray(kbIds) && kbIds.length > 0;
|
||||||
|
|
||||||
const handleChange = useCallback(() => {
|
const handleChange = useCallback(() => {
|
||||||
const kbIds = form.getFieldValue('kb_ids');
|
const kbIds = form.getFieldValue('kb_ids');
|
||||||
const emptyResponse = form.getFieldValue(emptyResponseField);
|
const emptyResponse = form.getFieldValue(emptyResponseField);
|
||||||
@ -153,6 +173,24 @@ const AssistantSetting = ({
|
|||||||
required={false}
|
required={false}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
></KnowledgeBaseItem>
|
></KnowledgeBaseItem>
|
||||||
|
{hasKnowledge && (
|
||||||
|
<Form.Item
|
||||||
|
label={t('metadata')}
|
||||||
|
name={['meta_data_filter', 'auto']}
|
||||||
|
tooltip={t('metadataTip')}
|
||||||
|
>
|
||||||
|
<Select options={MetadataOptions} />
|
||||||
|
</Form.Item>
|
||||||
|
)}
|
||||||
|
{hasKnowledge && metadata === DatasetMetadata.Manual && (
|
||||||
|
<Form.Item
|
||||||
|
label={t('conditions')}
|
||||||
|
tooltip={t('ttsTip')}
|
||||||
|
initialValue={false}
|
||||||
|
>
|
||||||
|
<MetadataFilterConditions kbIds={kbIds}></MetadataFilterConditions>
|
||||||
|
</Form.Item>
|
||||||
|
)}
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -0,0 +1,84 @@
|
|||||||
|
import { useFetchKnowledgeMetadata } from '@/hooks/use-knowledge-request';
|
||||||
|
import { SwitchOperatorOptions } from '@/pages/agent/constant';
|
||||||
|
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Dropdown,
|
||||||
|
Empty,
|
||||||
|
Form,
|
||||||
|
FormListOperation,
|
||||||
|
Input,
|
||||||
|
Select,
|
||||||
|
Space,
|
||||||
|
} from 'antd';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
export function MetadataFilterConditions({ kbIds }: { kbIds: string[] }) {
|
||||||
|
const metadata = useFetchKnowledgeMetadata(kbIds);
|
||||||
|
|
||||||
|
const renderItems = useCallback(
|
||||||
|
(add: FormListOperation['add']) => {
|
||||||
|
if (Object.keys(metadata.data).length === 0) {
|
||||||
|
return [{ key: 'noData', label: <Empty></Empty> }];
|
||||||
|
}
|
||||||
|
return Object.keys(metadata.data).map((key) => {
|
||||||
|
return {
|
||||||
|
key,
|
||||||
|
onClick: () => {
|
||||||
|
add({
|
||||||
|
key,
|
||||||
|
value: '',
|
||||||
|
op: SwitchOperatorOptions[0].value,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
label: key,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[metadata],
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<Form.List name={['meta_data_filter', 'manual']}>
|
||||||
|
{(fields, { add, remove }) => (
|
||||||
|
<>
|
||||||
|
{fields.map(({ key, name, ...restField }) => (
|
||||||
|
<Space
|
||||||
|
key={key}
|
||||||
|
style={{ display: 'flex', marginBottom: 8 }}
|
||||||
|
align="baseline"
|
||||||
|
>
|
||||||
|
<Form.Item
|
||||||
|
{...restField}
|
||||||
|
name={[name, 'key']}
|
||||||
|
rules={[{ required: true, message: 'Missing first name' }]}
|
||||||
|
>
|
||||||
|
<Input placeholder="First Name" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item {...restField} name={[name, 'op']} className="w-20">
|
||||||
|
<Select
|
||||||
|
options={SwitchOperatorOptions}
|
||||||
|
popupMatchSelectWidth={false}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
{...restField}
|
||||||
|
name={[name, 'value']}
|
||||||
|
rules={[{ required: true, message: 'Missing last name' }]}
|
||||||
|
>
|
||||||
|
<Input placeholder="Last Name" />
|
||||||
|
</Form.Item>
|
||||||
|
<MinusCircleOutlined onClick={() => remove(name)} />
|
||||||
|
</Space>
|
||||||
|
))}
|
||||||
|
<Form.Item>
|
||||||
|
<Dropdown trigger={['click']} menu={{ items: renderItems(add) }}>
|
||||||
|
<Button type="dashed" block icon={<PlusOutlined />}>
|
||||||
|
Add Condition
|
||||||
|
</Button>
|
||||||
|
</Dropdown>
|
||||||
|
</Form.Item>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Form.List>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1 +1,7 @@
|
|||||||
export const EmptyConversationId = 'empty';
|
export const EmptyConversationId = 'empty';
|
||||||
|
|
||||||
|
export enum DatasetMetadata {
|
||||||
|
Disabled = 'disabled',
|
||||||
|
Automatic = 'automatic',
|
||||||
|
Manual = 'manual',
|
||||||
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import { PanelRightClose } from 'lucide-react';
|
||||||
import { FormProvider, useForm } from 'react-hook-form';
|
import { FormProvider, useForm } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import ChatBasicSetting from './chat-basic-settings';
|
import ChatBasicSetting from './chat-basic-settings';
|
||||||
@ -7,7 +8,8 @@ import { ChatModelSettings } from './chat-model-settings';
|
|||||||
import { ChatPromptEngine } from './chat-prompt-engine';
|
import { ChatPromptEngine } from './chat-prompt-engine';
|
||||||
import { useChatSettingSchema } from './use-chat-setting-schema';
|
import { useChatSettingSchema } from './use-chat-setting-schema';
|
||||||
|
|
||||||
export function ChatSettings() {
|
type ChatSettingsProps = { switchSettingVisible(): void };
|
||||||
|
export function ChatSettings({ switchSettingVisible }: ChatSettingsProps) {
|
||||||
const formSchema = useChatSettingSchema();
|
const formSchema = useChatSettingSchema();
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
const form = useForm<z.infer<typeof formSchema>>({
|
||||||
@ -33,11 +35,18 @@ export function ChatSettings() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="py-6">
|
<section className="p-5 w-[400px] max-w-[20%]">
|
||||||
|
<div className="flex justify-between items-center text-base">
|
||||||
|
Chat Settings
|
||||||
|
<PanelRightClose
|
||||||
|
className="size-4 cursor-pointer"
|
||||||
|
onClick={switchSettingVisible}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<FormProvider {...form}>
|
<FormProvider {...form}>
|
||||||
<form
|
<form
|
||||||
onSubmit={form.handleSubmit(onSubmit)}
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
className="space-y-6 overflow-auto max-h-[88vh] pr-4"
|
className="space-y-6 overflow-auto max-h-[87vh] pr-4"
|
||||||
>
|
>
|
||||||
<ChatBasicSetting></ChatBasicSetting>
|
<ChatBasicSetting></ChatBasicSetting>
|
||||||
<ChatPromptEngine></ChatPromptEngine>
|
<ChatPromptEngine></ChatPromptEngine>
|
||||||
|
|||||||
@ -23,7 +23,7 @@ interface IProps {
|
|||||||
export function ChatBox({ controller }: IProps) {
|
export function ChatBox({ controller }: IProps) {
|
||||||
const {
|
const {
|
||||||
value,
|
value,
|
||||||
scrollRef,
|
// scrollRef,
|
||||||
messageContainerRef,
|
messageContainerRef,
|
||||||
sendLoading,
|
sendLoading,
|
||||||
derivedMessages,
|
derivedMessages,
|
||||||
@ -43,8 +43,8 @@ export function ChatBox({ controller }: IProps) {
|
|||||||
const sendDisabled = useSendButtonDisabled(value);
|
const sendDisabled = useSendButtonDisabled(value);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="border-x flex flex-col p-5 w-full">
|
<section className="border-x flex flex-col p-5 flex-1 min-w-0">
|
||||||
<div ref={messageContainerRef} className="flex-1 overflow-auto">
|
<div ref={messageContainerRef} className="flex-1 overflow-auto min-h-0">
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
{derivedMessages?.map((message, i) => {
|
{derivedMessages?.map((message, i) => {
|
||||||
return (
|
return (
|
||||||
@ -75,7 +75,7 @@ export function ChatBox({ controller }: IProps) {
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<div ref={scrollRef} />
|
{/* <div ref={scrollRef} /> */}
|
||||||
</div>
|
</div>
|
||||||
<NextMessageInput
|
<NextMessageInput
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
|||||||
@ -7,10 +7,12 @@ import {
|
|||||||
BreadcrumbPage,
|
BreadcrumbPage,
|
||||||
BreadcrumbSeparator,
|
BreadcrumbSeparator,
|
||||||
} from '@/components/ui/breadcrumb';
|
} from '@/components/ui/breadcrumb';
|
||||||
|
import { useSetModalState } from '@/hooks/common-hooks';
|
||||||
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
|
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
|
||||||
import { useFetchDialog } from '@/hooks/use-chat-request';
|
import { useFetchDialog } from '@/hooks/use-chat-request';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useHandleClickConversationCard } from '../hooks/use-click-card';
|
import { useHandleClickConversationCard } from '../hooks/use-click-card';
|
||||||
|
import { ChatSettings } from './app-settings/chat-settings';
|
||||||
import { ChatBox } from './chat-box';
|
import { ChatBox } from './chat-box';
|
||||||
import { Sessions } from './sessions';
|
import { Sessions } from './sessions';
|
||||||
|
|
||||||
@ -20,6 +22,8 @@ export default function Chat() {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { handleConversationCardClick, controller } =
|
const { handleConversationCardClick, controller } =
|
||||||
useHandleClickConversationCard();
|
useHandleClickConversationCard();
|
||||||
|
const { visible: settingVisible, switchVisible: switchSettingVisible } =
|
||||||
|
useSetModalState(true);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="h-full flex flex-col">
|
<section className="h-full flex flex-col">
|
||||||
@ -39,11 +43,19 @@ export default function Chat() {
|
|||||||
</Breadcrumb>
|
</Breadcrumb>
|
||||||
</PageHeader>
|
</PageHeader>
|
||||||
<div className="flex flex-1 min-h-0">
|
<div className="flex flex-1 min-h-0">
|
||||||
|
<div className="flex flex-1 min-w-0">
|
||||||
<Sessions
|
<Sessions
|
||||||
handleConversationCardClick={handleConversationCardClick}
|
handleConversationCardClick={handleConversationCardClick}
|
||||||
|
switchSettingVisible={switchSettingVisible}
|
||||||
></Sessions>
|
></Sessions>
|
||||||
<ChatBox controller={controller}></ChatBox>
|
<ChatBox controller={controller}></ChatBox>
|
||||||
</div>
|
</div>
|
||||||
|
{settingVisible && (
|
||||||
|
<ChatSettings
|
||||||
|
switchSettingVisible={switchSettingVisible}
|
||||||
|
></ChatSettings>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,21 +1,30 @@
|
|||||||
import { MoreButton } from '@/components/more-button';
|
import { MoreButton } from '@/components/more-button';
|
||||||
|
import { RAGFlowAvatar } from '@/components/ragflow-avatar';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Card, CardContent } from '@/components/ui/card';
|
import { Card, CardContent } from '@/components/ui/card';
|
||||||
import { useGetChatSearchParams } from '@/hooks/use-chat-request';
|
import { useSetModalState } from '@/hooks/common-hooks';
|
||||||
|
import {
|
||||||
|
useFetchDialog,
|
||||||
|
useGetChatSearchParams,
|
||||||
|
} from '@/hooks/use-chat-request';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { Plus } from 'lucide-react';
|
import { PanelLeftClose, PanelRightClose, Plus } from 'lucide-react';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useHandleClickConversationCard } from '../hooks/use-click-card';
|
import { useHandleClickConversationCard } from '../hooks/use-click-card';
|
||||||
import { useSelectDerivedConversationList } from '../hooks/use-select-conversation-list';
|
import { useSelectDerivedConversationList } from '../hooks/use-select-conversation-list';
|
||||||
import { ChatSettingSheet } from './app-settings/chat-settings-sheet';
|
|
||||||
|
|
||||||
type SessionProps = Pick<
|
type SessionProps = Pick<
|
||||||
ReturnType<typeof useHandleClickConversationCard>,
|
ReturnType<typeof useHandleClickConversationCard>,
|
||||||
'handleConversationCardClick'
|
'handleConversationCardClick'
|
||||||
>;
|
> & { switchSettingVisible(): void };
|
||||||
export function Sessions({ handleConversationCardClick }: SessionProps) {
|
export function Sessions({
|
||||||
|
handleConversationCardClick,
|
||||||
|
switchSettingVisible,
|
||||||
|
}: SessionProps) {
|
||||||
const { list: conversationList, addTemporaryConversation } =
|
const { list: conversationList, addTemporaryConversation } =
|
||||||
useSelectDerivedConversationList();
|
useSelectDerivedConversationList();
|
||||||
|
const { data } = useFetchDialog();
|
||||||
|
const { visible, switchVisible } = useSetModalState(true);
|
||||||
|
|
||||||
const handleCardClick = useCallback(
|
const handleCardClick = useCallback(
|
||||||
(conversationId: string, isNew: boolean) => () => {
|
(conversationId: string, isNew: boolean) => () => {
|
||||||
@ -26,9 +35,32 @@ export function Sessions({ handleConversationCardClick }: SessionProps) {
|
|||||||
|
|
||||||
const { conversationId } = useGetChatSearchParams();
|
const { conversationId } = useGetChatSearchParams();
|
||||||
|
|
||||||
|
if (!visible) {
|
||||||
|
return (
|
||||||
|
<PanelRightClose
|
||||||
|
className="cursor-pointer size-4 mt-8"
|
||||||
|
onClick={switchVisible}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="p-6 w-[400px] max-w-[20%] flex flex-col">
|
<section className="p-6 w-[400px] max-w-[20%] flex flex-col">
|
||||||
<div className="flex justify-between items-center mb-4">
|
<section className="flex items-center text-base justify-between gap-2">
|
||||||
|
<div className="flex gap-3 items-center min-w-0">
|
||||||
|
<RAGFlowAvatar
|
||||||
|
avatar={data.icon}
|
||||||
|
name={data.name}
|
||||||
|
className="size-8"
|
||||||
|
></RAGFlowAvatar>
|
||||||
|
<span className="flex-1 truncate">{data.name}</span>
|
||||||
|
</div>
|
||||||
|
<PanelLeftClose
|
||||||
|
className="cursor-pointer size-4"
|
||||||
|
onClick={switchVisible}
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
<div className="flex justify-between items-center mb-4 pt-10">
|
||||||
<span className="text-xl font-bold">Conversations</span>
|
<span className="text-xl font-bold">Conversations</span>
|
||||||
<Button variant={'ghost'} onClick={addTemporaryConversation}>
|
<Button variant={'ghost'} onClick={addTemporaryConversation}>
|
||||||
<Plus></Plus>
|
<Plus></Plus>
|
||||||
@ -51,9 +83,9 @@ export function Sessions({ handleConversationCardClick }: SessionProps) {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="py-2">
|
<div className="py-2">
|
||||||
<ChatSettingSheet>
|
<Button className="w-full" onClick={switchSettingVisible}>
|
||||||
<Button className="w-full">Chat Settings</Button>
|
Chat Settings
|
||||||
</ChatSettingSheet>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -37,6 +37,7 @@ const {
|
|||||||
upload_and_parse,
|
upload_and_parse,
|
||||||
listTagByKnowledgeIds,
|
listTagByKnowledgeIds,
|
||||||
setMeta,
|
setMeta,
|
||||||
|
getMeta,
|
||||||
} = api;
|
} = api;
|
||||||
|
|
||||||
const methods = {
|
const methods = {
|
||||||
@ -159,6 +160,10 @@ const methods = {
|
|||||||
url: api.get_dataset_filter,
|
url: api.get_dataset_filter,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
},
|
},
|
||||||
|
getMeta: {
|
||||||
|
url: getMeta,
|
||||||
|
method: 'get',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const kbService = registerServer<keyof typeof methods>(methods, request);
|
const kbService = registerServer<keyof typeof methods>(methods, request);
|
||||||
|
|||||||
@ -44,6 +44,7 @@ export default {
|
|||||||
get_kb_detail: `${api_host}/kb/detail`,
|
get_kb_detail: `${api_host}/kb/detail`,
|
||||||
getKnowledgeGraph: (knowledgeId: string) =>
|
getKnowledgeGraph: (knowledgeId: string) =>
|
||||||
`${api_host}/kb/${knowledgeId}/knowledge_graph`,
|
`${api_host}/kb/${knowledgeId}/knowledge_graph`,
|
||||||
|
getMeta: `${api_host}/kb/get_meta`,
|
||||||
|
|
||||||
// tags
|
// tags
|
||||||
listTag: (knowledgeId: string) => `${api_host}/kb/${knowledgeId}/tags`,
|
listTag: (knowledgeId: string) => `${api_host}/kb/${knowledgeId}/tags`,
|
||||||
|
|||||||
Reference in New Issue
Block a user