mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-02-03 17:15:08 +08:00
Compare commits
17 Commits
6e9691a419
...
9de3ecc4a8
| Author | SHA1 | Date | |
|---|---|---|---|
| 9de3ecc4a8 | |||
| c4a66204f0 | |||
| 3558a6c170 | |||
| 595fc4ccec | |||
| 3ad147d349 | |||
| d285d8cd97 | |||
| 5714895291 | |||
| a33936e8ff | |||
| 9f8161d13e | |||
| a599a0f4bf | |||
| 7498bc63a3 | |||
| 894bf995bb | |||
| 52dbacc506 | |||
| cbcbbc41af | |||
| 6044314811 | |||
| 5fb38ecc2a | |||
| 73db759558 |
@ -427,7 +427,7 @@ class Message(ComponentBase):
|
||||
logging.error(f"Error converting content to {self._param.output_format}: {e}")
|
||||
|
||||
async def _save_to_memory(self, content):
|
||||
if not self._param.memory_ids:
|
||||
if not hasattr(self._param, "memory_ids") or not self._param.memory_ids:
|
||||
return True, "No memory selected."
|
||||
|
||||
message_dict = {
|
||||
|
||||
@ -282,7 +282,11 @@ class Retrieval(ToolBase, ABC):
|
||||
self.set_output("formalized_content", self._param.empty_response)
|
||||
return
|
||||
|
||||
if self._param.kb_ids:
|
||||
if hasattr(self._param, "retrieval_from") and self._param.retrieval_from == "dataset":
|
||||
return await self._retrieve_kb(kwargs["query"])
|
||||
elif hasattr(self._param, "retrieval_from") and self._param.retrieval_from == "memory":
|
||||
return await self._retrieve_memory(kwargs["query"])
|
||||
elif self._param.kb_ids:
|
||||
return await self._retrieve_kb(kwargs["query"])
|
||||
elif hasattr(self._param, "memory_ids") and self._param.memory_ids:
|
||||
return await self._retrieve_memory(kwargs["query"])
|
||||
|
||||
@ -21,11 +21,12 @@ from api.db import TenantPermission
|
||||
from api.db.services.memory_service import MemoryService
|
||||
from api.db.services.user_service import UserTenantService
|
||||
from api.db.services.canvas_service import UserCanvasService
|
||||
from api.utils.api_utils import validate_request, get_request_json, get_error_argument_result, get_json_result, \
|
||||
not_allowed_parameters
|
||||
from api.db.joint_services.memory_message_service import get_memory_size_cache, judge_system_prompt_is_default
|
||||
from api.utils.api_utils import validate_request, get_request_json, get_error_argument_result, get_json_result
|
||||
from api.utils.memory_utils import format_ret_data_from_memory, get_memory_type_human
|
||||
from api.constants import MEMORY_NAME_LIMIT, MEMORY_SIZE_LIMIT
|
||||
from memory.services.messages import MessageService
|
||||
from memory.utils.prompt_util import PromptAssembler
|
||||
from common.constants import MemoryType, RetCode, ForgettingPolicy
|
||||
|
||||
|
||||
@ -68,7 +69,6 @@ async def create_memory():
|
||||
|
||||
@manager.route("/<memory_id>", methods=["PUT"]) # noqa: F821
|
||||
@login_required
|
||||
@not_allowed_parameters("id", "tenant_id", "memory_type", "storage_type", "embd_id")
|
||||
async def update_memory(memory_id):
|
||||
req = await get_request_json()
|
||||
update_dict = {}
|
||||
@ -88,6 +88,14 @@ async def update_memory(memory_id):
|
||||
update_dict["permissions"] = req["permissions"]
|
||||
if req.get("llm_id"):
|
||||
update_dict["llm_id"] = req["llm_id"]
|
||||
if req.get("embd_id"):
|
||||
update_dict["embd_id"] = req["embd_id"]
|
||||
if req.get("memory_type"):
|
||||
memory_type = set(req["memory_type"])
|
||||
invalid_type = memory_type - {e.name.lower() for e in MemoryType}
|
||||
if invalid_type:
|
||||
return get_error_argument_result(f"Memory type '{invalid_type}' is not supported.")
|
||||
update_dict["memory_type"] = list(memory_type)
|
||||
# check memory_size valid
|
||||
if req.get("memory_size"):
|
||||
if not 0 < int(req["memory_size"]) <= MEMORY_SIZE_LIMIT:
|
||||
@ -123,6 +131,15 @@ async def update_memory(memory_id):
|
||||
|
||||
if not to_update:
|
||||
return get_json_result(message=True, data=memory_dict)
|
||||
# check memory empty when update embd_id, memory_type
|
||||
memory_size = get_memory_size_cache(memory_id, current_memory.tenant_id)
|
||||
not_allowed_update = [f for f in ["embd_id", "memory_type"] if f in to_update and memory_size > 0]
|
||||
if not_allowed_update:
|
||||
return get_error_argument_result(f"Can't update {not_allowed_update} when memory isn't empty.")
|
||||
if "memory_type" in to_update:
|
||||
if "system_prompt" not in to_update and judge_system_prompt_is_default(current_memory.system_prompt, current_memory.memory_type):
|
||||
# update old default prompt, assemble a new one
|
||||
to_update["system_prompt"] = PromptAssembler.assemble_system_prompt({"memory_type": to_update["memory_type"]})
|
||||
|
||||
try:
|
||||
MemoryService.update_memory(current_memory.tenant_id, memory_id, to_update)
|
||||
|
||||
@ -1189,7 +1189,7 @@ class Memory(DataBaseModel):
|
||||
permissions = CharField(max_length=16, null=False, index=True, help_text="me|team", default="me")
|
||||
description = TextField(null=True, help_text="description")
|
||||
memory_size = IntegerField(default=5242880, null=False, index=False)
|
||||
forgetting_policy = CharField(max_length=32, null=False, default="fifo", index=False, help_text="lru|fifo")
|
||||
forgetting_policy = CharField(max_length=32, null=False, default="FIFO", index=False, help_text="LRU|FIFO")
|
||||
temperature = FloatField(default=0.5, index=False)
|
||||
system_prompt = TextField(null=True, help_text="system prompt", index=False)
|
||||
user_prompt = TextField(null=True, help_text="user prompt", index=False)
|
||||
|
||||
@ -96,7 +96,7 @@ async def save_to_memory(memory_id: str, message_dict: dict):
|
||||
current_memory_size = get_memory_size_cache(memory_id, tenant_id)
|
||||
if new_msg_size + current_memory_size > memory.memory_size:
|
||||
size_to_delete = current_memory_size + new_msg_size - memory.memory_size
|
||||
if memory.forgetting_policy == "fifo":
|
||||
if memory.forgetting_policy == "FIFO":
|
||||
message_ids_to_delete, delete_size = MessageService.pick_messages_to_delete_by_fifo(memory_id, tenant_id, size_to_delete)
|
||||
MessageService.delete_message({"message_id": message_ids_to_delete}, tenant_id, memory_id)
|
||||
decrease_memory_size_cache(memory_id, delete_size)
|
||||
@ -231,3 +231,8 @@ def init_memory_size_cache():
|
||||
memory_size = memory_size_map.get(memory.id, 0)
|
||||
set_memory_size_cache(memory.id, memory_size)
|
||||
logging.info("Memory size cache init done.")
|
||||
|
||||
|
||||
def judge_system_prompt_is_default(system_prompt: str, memory_type: int|list[str]):
|
||||
memory_type_list = memory_type if isinstance(memory_type, list) else get_memory_type_human(memory_type)
|
||||
return system_prompt == PromptAssembler.assemble_system_prompt({"memory_type": memory_type_list})
|
||||
|
||||
@ -117,6 +117,8 @@ class MemoryService(CommonService):
|
||||
if len(memory_name) > MEMORY_NAME_LIMIT:
|
||||
return False, f"Memory name {memory_name} exceeds limit of {MEMORY_NAME_LIMIT}."
|
||||
|
||||
timestamp = current_timestamp()
|
||||
format_time = get_format_time()
|
||||
# build create dict
|
||||
memory_info = {
|
||||
"id": get_uuid(),
|
||||
@ -126,10 +128,10 @@ class MemoryService(CommonService):
|
||||
"embd_id": embd_id,
|
||||
"llm_id": llm_id,
|
||||
"system_prompt": PromptAssembler.assemble_system_prompt({"memory_type": memory_type}),
|
||||
"create_time": current_timestamp(),
|
||||
"create_date": get_format_time(),
|
||||
"update_time": current_timestamp(),
|
||||
"update_date": get_format_time(),
|
||||
"create_time": timestamp,
|
||||
"create_date": format_time,
|
||||
"update_time": timestamp,
|
||||
"update_date": format_time,
|
||||
}
|
||||
obj = cls.model(**memory_info).save(force_insert=True)
|
||||
|
||||
@ -147,6 +149,8 @@ class MemoryService(CommonService):
|
||||
return 0
|
||||
if "temperature" in update_dict and isinstance(update_dict["temperature"], str):
|
||||
update_dict["temperature"] = float(update_dict["temperature"])
|
||||
if "memory_type" in update_dict and isinstance(update_dict["memory_type"], list):
|
||||
update_dict["memory_type"] = calculate_memory_type(update_dict["memory_type"])
|
||||
if "name" in update_dict:
|
||||
update_dict["name"] = duplicate_name(
|
||||
cls.query,
|
||||
|
||||
@ -171,7 +171,7 @@ class MemoryStorageType(StrEnum):
|
||||
|
||||
|
||||
class ForgettingPolicy(StrEnum):
|
||||
FIFO = "fifo"
|
||||
FIFO = "FIFO"
|
||||
|
||||
|
||||
# environment
|
||||
|
||||
@ -7,7 +7,7 @@ slug: /deploy_local_llm
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
Deploy and run local models using Ollama, Xinference, or other frameworks.
|
||||
Deploy and run local models using Ollama, Xinference, VLLM ,SGLANG or other frameworks.
|
||||
|
||||
---
|
||||
|
||||
@ -314,3 +314,41 @@ To enable IPEX-LLM accelerated Ollama in RAGFlow, you must also complete the con
|
||||
3. [Update System Model Settings](#6-update-system-model-settings)
|
||||
4. [Update Chat Configuration](#7-update-chat-configuration)
|
||||
|
||||
### 5. Deploy VLLM
|
||||
|
||||
ubuntu 22.04/24.04
|
||||
|
||||
```bash
|
||||
pip install vllm
|
||||
```
|
||||
### 5.1 RUN VLLM WITH BEST PRACTISE
|
||||
|
||||
```bash
|
||||
nohup vllm serve /data/Qwen3-8B --served-model-name Qwen3-8B-FP8 --dtype auto --port 1025 --gpu-memory-utilization 0.90 --tool-call-parser hermes --enable-auto-tool-choice > /var/log/vllm_startup1.log 2>&1 &
|
||||
```
|
||||
you can get log info
|
||||
```bash
|
||||
tail -f -n 100 /var/log/vllm_startup1.log
|
||||
```
|
||||
when see the follow ,it means vllm engine is ready for access
|
||||
```bash
|
||||
Starting vLLM API server 0 on http://0.0.0.0:1025
|
||||
Started server process [19177]
|
||||
Application startup complete.
|
||||
```
|
||||
### 5.2 INTERGRATEING RAGFLOW WITH VLLM CHAT/EM/RERANK LLM WITH WEBUI
|
||||
|
||||
setting->model providers->search->vllm->add ,configure as follow:<br>
|
||||
|
||||

|
||||
|
||||
select vllm chat model as default llm model as follow:<br>
|
||||

|
||||
### 5.3 chat with vllm chat model
|
||||
create chat->create conversations-chat as follow:<br>
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
26
web/package-lock.json
generated
26
web/package-lock.json
generated
@ -90,6 +90,7 @@
|
||||
"react-infinite-scroll-component": "^6.1.0",
|
||||
"react-markdown": "^9.0.1",
|
||||
"react-pdf-highlighter": "^6.1.0",
|
||||
"react-photo-view": "^1.2.7",
|
||||
"react-resizable-panels": "^3.0.6",
|
||||
"react-string-replace": "^1.1.1",
|
||||
"react-syntax-highlighter": "^15.5.0",
|
||||
@ -30404,6 +30405,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-photo-view": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmmirror.com/react-photo-view/-/react-photo-view-1.2.7.tgz",
|
||||
"integrity": "sha512-MfOWVPxuibncRLaycZUNxqYU8D9IA+rbGDDaq6GM8RIoGJal592hEJoRAyRSI7ZxyyJNJTLMUWWL3UIXHJJOpw==",
|
||||
"license": "Apache-2.0",
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-refresh": {
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmmirror.com/react-refresh/-/react-refresh-0.14.0.tgz",
|
||||
@ -36191,6 +36202,21 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/tinyglobby/node_modules/picomatch": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz",
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/tinyrainbow": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/tinyrainbow/-/tinyrainbow-2.0.0.tgz",
|
||||
|
||||
@ -103,6 +103,7 @@
|
||||
"react-infinite-scroll-component": "^6.1.0",
|
||||
"react-markdown": "^9.0.1",
|
||||
"react-pdf-highlighter": "^6.1.0",
|
||||
"react-photo-view": "^1.2.7",
|
||||
"react-resizable-panels": "^3.0.6",
|
||||
"react-string-replace": "^1.1.1",
|
||||
"react-syntax-highlighter": "^15.5.0",
|
||||
|
||||
@ -2,6 +2,7 @@ import { Toaster as Sonner } from '@/components/ui/sonner';
|
||||
import { Toaster } from '@/components/ui/toaster';
|
||||
import i18n from '@/locales/config';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { configResponsive } from 'ahooks';
|
||||
import { App, ConfigProvider, ConfigProviderProps, theme } from 'antd';
|
||||
import pt_BR from 'antd/lib/locale/pt_BR';
|
||||
import deDE from 'antd/locale/de_DE';
|
||||
@ -24,7 +25,7 @@ import { TooltipProvider } from './components/ui/tooltip';
|
||||
import { ThemeEnum } from './constants/common';
|
||||
import storage from './utils/authorization-util';
|
||||
|
||||
import { configResponsive } from 'ahooks';
|
||||
import 'react-photo-view/dist/react-photo-view.css';
|
||||
|
||||
configResponsive({
|
||||
sm: 640,
|
||||
|
||||
@ -91,13 +91,13 @@ export function ConfirmDeleteDialog({
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter className="px-5 flex items-center gap-2">
|
||||
<AlertDialogCancel onClick={onCancel}>
|
||||
{okButtonText || t('common.cancel')}
|
||||
{cancelButtonText || t('common.cancel')}
|
||||
</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
className="bg-state-error text-text-primary hover:text-text-primary hover:bg-state-error"
|
||||
onClick={onOk}
|
||||
>
|
||||
{cancelButtonText || t('common.delete')}
|
||||
{okButtonText || t('common.delete')}
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
|
||||
@ -7,8 +7,11 @@ import {
|
||||
CarouselPrevious,
|
||||
} from '@/components/ui/carousel';
|
||||
import { IReferenceChunk } from '@/interfaces/database/chat';
|
||||
import { api_host } from '@/utils/api';
|
||||
import { isPlainObject } from 'lodash';
|
||||
import { RotateCw, ZoomIn, ZoomOut } from 'lucide-react';
|
||||
import { useMemo } from 'react';
|
||||
import { PhotoProvider, PhotoView } from 'react-photo-view';
|
||||
import { extractNumbersFromMessageContent } from './utils';
|
||||
|
||||
type IProps = {
|
||||
@ -36,35 +39,60 @@ function ImageCarousel({ images }: { images: ImageItem[] }) {
|
||||
const buttonVisibilityClass = getButtonVisibilityClass(images.length);
|
||||
|
||||
return (
|
||||
<Carousel
|
||||
className="w-full"
|
||||
opts={{
|
||||
align: 'start',
|
||||
<PhotoProvider
|
||||
// className="[&_.PhotoView-Slider__toolbarIcon]:hidden"
|
||||
toolbarRender={({ rotate, onRotate, scale, onScale }) => {
|
||||
return (
|
||||
<>
|
||||
<RotateCw
|
||||
className="mr-4 cursor-pointer text-text-disabled hover:text-text-primary"
|
||||
onClick={() => onRotate(rotate + 90)}
|
||||
/>
|
||||
<ZoomIn
|
||||
className="mr-4 cursor-pointer text-text-disabled hover:text-text-primary"
|
||||
onClick={() => onScale(scale + 1)}
|
||||
/>
|
||||
<ZoomOut
|
||||
className="cursor-pointer text-text-disabled hover:text-text-primary"
|
||||
onClick={() => onScale(scale - 1)}
|
||||
/>
|
||||
{/* <X className="cursor-pointer text-text-disabled hover:text-text-primary" /> */}
|
||||
</>
|
||||
);
|
||||
}}
|
||||
>
|
||||
<CarouselContent>
|
||||
{images.map(({ id, index }) => (
|
||||
<CarouselItem
|
||||
key={index}
|
||||
className="
|
||||
basis-full
|
||||
@sm:basis-1/2
|
||||
@md:basis-1/3
|
||||
@lg:basis-1/4
|
||||
@2xl:basis-1/6
|
||||
"
|
||||
>
|
||||
<Image
|
||||
id={id}
|
||||
className="h-40 w-full"
|
||||
label={`Fig. ${(index + 1).toString()}`}
|
||||
/>
|
||||
</CarouselItem>
|
||||
))}
|
||||
</CarouselContent>
|
||||
<CarouselPrevious className={buttonVisibilityClass} />
|
||||
<CarouselNext className={buttonVisibilityClass} />
|
||||
</Carousel>
|
||||
<Carousel
|
||||
className="w-full"
|
||||
opts={{
|
||||
align: 'start',
|
||||
}}
|
||||
>
|
||||
<CarouselContent>
|
||||
{images.map(({ id, index }) => (
|
||||
<CarouselItem
|
||||
key={index}
|
||||
className="
|
||||
basis-full
|
||||
@sm:basis-1/2
|
||||
@md:basis-1/3
|
||||
@lg:basis-1/4
|
||||
@2xl:basis-1/6
|
||||
"
|
||||
>
|
||||
<PhotoView src={`${api_host}/document/image/${id}`}>
|
||||
<Image
|
||||
id={id}
|
||||
className="h-40 w-full"
|
||||
label={`Fig. ${(index + 1).toString()}`}
|
||||
/>
|
||||
</PhotoView>
|
||||
</CarouselItem>
|
||||
))}
|
||||
</CarouselContent>
|
||||
<CarouselPrevious className={buttonVisibilityClass} />
|
||||
<CarouselNext className={buttonVisibilityClass} />
|
||||
</Carousel>
|
||||
</PhotoProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { toast } from 'sonner';
|
||||
|
||||
const duration = { duration: 1500 };
|
||||
const duration = { duration: 2500 };
|
||||
|
||||
const message = {
|
||||
success: (msg: string) => {
|
||||
|
||||
@ -31,6 +31,7 @@ export interface ModalProps {
|
||||
cancelButtonClassName?: string;
|
||||
disabled?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
zIndex?: number;
|
||||
}
|
||||
export interface ModalType extends FC<ModalProps> {
|
||||
show: typeof modalIns.show;
|
||||
@ -63,6 +64,7 @@ const Modal: ModalType = ({
|
||||
cancelButtonClassName,
|
||||
disabled = false,
|
||||
style,
|
||||
zIndex = 50,
|
||||
}) => {
|
||||
const sizeClasses = {
|
||||
small: 'max-w-md',
|
||||
@ -172,6 +174,7 @@ const Modal: ModalType = ({
|
||||
<DialogPrimitive.Overlay
|
||||
className="fixed inset-0 z-[1000] bg-bg-card backdrop-blur-[1px] flex items-center justify-center p-4"
|
||||
onClick={() => maskClosable && onOpenChange?.(false)}
|
||||
style={{ zIndex: zIndex }}
|
||||
>
|
||||
<DialogPrimitive.Content
|
||||
className={cn(
|
||||
|
||||
@ -102,6 +102,7 @@ export const useShowDeleteConfirm = () => {
|
||||
style: {
|
||||
width: '450px',
|
||||
},
|
||||
zIndex: 1000,
|
||||
okButtonClassName:
|
||||
'bg-state-error text-white hover:bg-state-error hover:text-white',
|
||||
onOk: async () => {
|
||||
|
||||
@ -266,20 +266,19 @@ export const useRunDocument = () => {
|
||||
mutationFn: async ({
|
||||
documentIds,
|
||||
run,
|
||||
shouldDelete,
|
||||
option,
|
||||
}: {
|
||||
documentIds: string[];
|
||||
run: number;
|
||||
shouldDelete: boolean;
|
||||
option?: { delete: boolean; apply_kb: boolean };
|
||||
}) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: [DocumentApiAction.FetchDocumentList],
|
||||
});
|
||||
|
||||
const ret = await kbService.document_run({
|
||||
doc_ids: documentIds,
|
||||
run,
|
||||
delete: shouldDelete,
|
||||
...option,
|
||||
});
|
||||
const code = get(ret, 'data.code');
|
||||
if (code === 0) {
|
||||
|
||||
@ -79,7 +79,7 @@ export function Header() {
|
||||
{ path: Routes.Chats, name: t('header.chat'), icon: MessageSquareText },
|
||||
{ path: Routes.Searches, name: t('header.search'), icon: Search },
|
||||
{ path: Routes.Agents, name: t('header.flow'), icon: Cpu },
|
||||
{ path: Routes.Memories, name: t('header.Memories'), icon: Cpu },
|
||||
{ path: Routes.Memories, name: t('header.memories'), icon: Cpu },
|
||||
{ path: Routes.Files, name: t('header.fileManager'), icon: File },
|
||||
],
|
||||
[t],
|
||||
|
||||
@ -417,7 +417,7 @@ Prozedurales Gedächtnis: Erlernte Fähigkeiten, Gewohnheiten und automatisierte
|
||||
fileFilter: 'Dateifilter',
|
||||
setDefaultTip: '',
|
||||
setDefault: 'Als Standard festlegen',
|
||||
eidtLinkDataPipeline: 'Ingestion-Pipeline bearbeiten',
|
||||
editLinkDataPipeline: 'Ingestion-Pipeline bearbeiten',
|
||||
linkPipelineSetTip:
|
||||
'Verknüpfung der Ingestion-Pipeline mit diesem Datensatz verwalten',
|
||||
default: 'Standard',
|
||||
@ -900,7 +900,7 @@ Beispiel: general/v2/`,
|
||||
Beispiel: https://fsn1.your-objectstorage.com`,
|
||||
S3CompatibleAddressingStyleTip: `Erforderlich für S3-kompatible Storage Box. Geben Sie den S3-kompatiblen Adressierungsstil an.
|
||||
Beispiel: Virtual Hosted Style`,
|
||||
addDataSourceModalTital: 'Erstellen Sie Ihren {{name}} Connector',
|
||||
addDataSourceModalTitle: 'Erstellen Sie Ihren {{name}} Connector',
|
||||
deleteSourceModalTitle: 'Datenquelle löschen',
|
||||
deleteSourceModalContent: `
|
||||
<p>Sind Sie sicher, dass Sie diese Datenquellenverknüpfung löschen möchten?</p>`,
|
||||
@ -1357,12 +1357,12 @@ Beispiel: Virtual Hosted Style`,
|
||||
search: 'Suchen',
|
||||
communication: 'Kommunikation',
|
||||
developer: 'Entwickler',
|
||||
typeCommandOrsearch: 'Geben Sie einen Befehl ein oder suchen Sie...',
|
||||
typeCommandORsearch: 'Geben Sie einen Befehl ein oder suchen Sie...',
|
||||
builtIn: 'Eingebaut',
|
||||
ExceptionDefaultValue: 'Ausnahme-Standardwert',
|
||||
exceptionMethod: 'Ausnahmemethode',
|
||||
maxRounds: 'Maximale Reflexionsrunden',
|
||||
delayEfterError: 'Verzögerung nach Fehler',
|
||||
delayAfterError: 'Verzögerung nach Fehler',
|
||||
maxRetries: 'Maximale Wiederholungsrunden',
|
||||
advancedSettings: 'Erweiterte Einstellungen',
|
||||
addTools: 'Tools hinzufügen',
|
||||
@ -1882,7 +1882,7 @@ Beispiel: Virtual Hosted Style`,
|
||||
}`,
|
||||
datatype: 'MIME-Typ der HTTP-Anfrage',
|
||||
insertVariableTip: 'Eingabe / Variablen einfügen',
|
||||
historyversion: 'Versionsverlauf',
|
||||
historyVersion: 'Versionsverlauf',
|
||||
version: {
|
||||
created: 'Erstellt',
|
||||
details: 'Versionsdetails',
|
||||
|
||||
@ -99,7 +99,7 @@ export default {
|
||||
search: 'Search',
|
||||
welcome: 'Welcome to',
|
||||
dataset: 'Dataset',
|
||||
Memories: 'Memory',
|
||||
memories: 'Memory',
|
||||
},
|
||||
memories: {
|
||||
llmTooltip:
|
||||
@ -112,6 +112,10 @@ export default {
|
||||
Semantic Memory: General knowledge and facts about the user and world.
|
||||
Episodic Memory: Time-stamped records of specific events and experiences.
|
||||
Procedural Memory: Learned skills, habits, and automated procedures.`,
|
||||
raw: 'raw',
|
||||
semantic: 'semantic',
|
||||
episodic: 'episodic',
|
||||
procedural: 'procedural',
|
||||
editName: 'Edit name',
|
||||
memory: 'Memory',
|
||||
createMemory: 'Create memory',
|
||||
@ -125,8 +129,9 @@ Procedural Memory: Learned skills, habits, and automated procedures.`,
|
||||
},
|
||||
memory: {
|
||||
messages: {
|
||||
forgetMessageTip: 'Are you sure you want to forget?',
|
||||
messageDescription:
|
||||
'Memory retrieval is configured with Similarity threshold, Keyword similarity weight, and Top N from Advanced Settings.',
|
||||
'Memory extract is configured with Prompts and Temperature from Advanced Settings.',
|
||||
copied: 'Copied!',
|
||||
contentEmbed: 'Content embed',
|
||||
content: 'Content',
|
||||
@ -145,17 +150,17 @@ Procedural Memory: Learned skills, habits, and automated procedures.`,
|
||||
avatar: 'Avatar',
|
||||
description: 'Description',
|
||||
memorySize: 'Memory size',
|
||||
advancedSettings: 'Advanced Settings',
|
||||
advancedSettings: 'Advanced settings',
|
||||
permission: 'Permission',
|
||||
onlyMe: 'Only Me',
|
||||
onlyMe: 'Only me',
|
||||
team: 'Team',
|
||||
storageType: 'Storage Type',
|
||||
storageType: 'Storage type',
|
||||
storageTypePlaceholder: 'Please select storage type',
|
||||
forgetPolicy: 'Forget Policy',
|
||||
forgetPolicy: 'Forget policy',
|
||||
temperature: 'Temperature',
|
||||
systemPrompt: 'System Prompt',
|
||||
systemPrompt: 'System prompt',
|
||||
systemPromptPlaceholder: 'Please enter system prompt',
|
||||
userPrompt: 'User Prompt',
|
||||
userPrompt: 'User prompt',
|
||||
userPromptPlaceholder: 'Please enter user prompt',
|
||||
},
|
||||
sideBar: {
|
||||
@ -166,7 +171,7 @@ Procedural Memory: Learned skills, habits, and automated procedures.`,
|
||||
knowledgeList: {
|
||||
welcome: 'Welcome back',
|
||||
description: 'Which knowledge bases will you use today?',
|
||||
createKnowledgeBase: 'Create Dataset',
|
||||
createKnowledgeBase: 'Create dataset',
|
||||
name: 'Name',
|
||||
namePlaceholder: 'Please input name.',
|
||||
doc: 'Docs',
|
||||
@ -216,6 +221,10 @@ Procedural Memory: Learned skills, habits, and automated procedures.`,
|
||||
deleteSettingFieldWarn: `This field will be deleted; existing metadata won't be affected.`,
|
||||
deleteSettingValueWarn: `This value will be deleted; existing metadata won't be affected.`,
|
||||
},
|
||||
redoAll: 'Clear existing chunks',
|
||||
applyAutoMetadataSettings: 'Apply global auto-metadata settings',
|
||||
parseFileTip: 'Are you sure to parse?',
|
||||
parseFile: 'Parse file',
|
||||
emptyMetadata: 'No metadata',
|
||||
metadataField: 'Metadata field',
|
||||
systemAttribute: 'System attribute',
|
||||
@ -364,11 +373,11 @@ Procedural Memory: Learned skills, habits, and automated procedures.`,
|
||||
autoQuestions: 'Auto-question',
|
||||
autoQuestionsTip: `Automatically extract N questions for each chunk to increase their ranking for queries containing those questions. You can check or update the added questions for a chunk from the chunk list. This feature will not disrupt the chunking process if an error occurs, except that it may add an empty result to the original chunk. Be aware that extra tokens will be consumed by the indexing model specified in 'Configuration'. For details, see https://ragflow.io/docs/dev/autokeyword_autoquestion.`,
|
||||
redo: 'Do you want to clear the existing {{chunkNum}} chunks?',
|
||||
setMetaData: 'Set meta data',
|
||||
setMetaData: 'Set metadata',
|
||||
pleaseInputJson: 'Please enter JSON',
|
||||
documentMetaTips: `<p>The meta data is in Json format(it's not searchable). It will be added into prompt for LLM if any chunks of this document are included in the prompt.</p>
|
||||
documentMetaTips: `<p>The metadata is in Json format(it's not searchable). It will be added into prompt for LLM if any chunks of this document are included in the prompt.</p>
|
||||
<p>Examples:</p>
|
||||
<b>The meta data is:</b><br>
|
||||
<b>The metadata is:</b><br>
|
||||
<code>
|
||||
{
|
||||
"Author": "Alex Dowson",
|
||||
@ -401,14 +410,14 @@ Procedural Memory: Learned skills, habits, and automated procedures.`,
|
||||
imageTableContextWindowTip:
|
||||
'Captures N tokens of text above and below the image & table to provide richer background context.',
|
||||
autoMetadata: 'Auto metadata',
|
||||
mineruOptions: 'MinerU Options',
|
||||
mineruParseMethod: 'Parse Method',
|
||||
mineruOptions: 'MinerU options',
|
||||
mineruParseMethod: 'Parse method',
|
||||
mineruParseMethodTip:
|
||||
'Method for parsing PDF: auto (automatic detection), txt (text extraction), ocr (optical character recognition)',
|
||||
mineruFormulaEnable: 'Formula Recognition',
|
||||
mineruFormulaEnable: 'Formula recognition',
|
||||
mineruFormulaEnableTip:
|
||||
'Enable formula recognition. Note: This may not work correctly for Cyrillic documents.',
|
||||
mineruTableEnable: 'Table Recognition',
|
||||
mineruTableEnable: 'Table recognition',
|
||||
mineruTableEnableTip: 'Enable table recognition and extraction.',
|
||||
overlappedPercent: 'Overlapped percent(%)',
|
||||
generationScopeTip:
|
||||
@ -441,11 +450,11 @@ Procedural Memory: Learned skills, habits, and automated procedures.`,
|
||||
fileFilter: 'File filter',
|
||||
setDefaultTip: '',
|
||||
setDefault: 'Set as default',
|
||||
eidtLinkDataPipeline: 'Edit Ingestion pipeline',
|
||||
linkPipelineSetTip: 'Manage Ingestion pipeline linkage with this dataset',
|
||||
editLinkDataPipeline: 'Edit ingestion pipeline',
|
||||
linkPipelineSetTip: 'Manage ingestion pipeline linkage with this dataset',
|
||||
default: 'Default',
|
||||
dataPipeline: 'Ingestion pipeline',
|
||||
linkDataPipeline: 'Link Ingestion pipeline',
|
||||
linkDataPipeline: 'Link ingestion pipeline',
|
||||
enableAutoGenerate: 'Enable auto generate',
|
||||
teamPlaceholder: 'Please select a team.',
|
||||
dataFlowPlaceholder: 'Please select a pipeline.',
|
||||
@ -455,7 +464,7 @@ Procedural Memory: Learned skills, habits, and automated procedures.`,
|
||||
manualSetup: 'Choose pipeline',
|
||||
builtIn: 'Built-in',
|
||||
titleDescription:
|
||||
'Update your knowledge base configuration here, particularly the chunking method.',
|
||||
'Update your memory configuration here, particularly the LLM and prompts.',
|
||||
name: 'Knowledge base name',
|
||||
photo: 'Knowledge base photo',
|
||||
photoTip: 'You can upload a file with 4 MB',
|
||||
@ -756,8 +765,8 @@ This auto-tagging feature enhances retrieval by adding another layer of domain-s
|
||||
maxTokens: 'Max tokens',
|
||||
maxTokensMessage: 'Max tokens is required',
|
||||
maxTokensTip: `This sets the maximum length of the model's output, measured in the number of tokens (words or pieces of words). Defaults to 512. If disabled, you lift the maximum token limit, allowing the model to determine the number of tokens in its responses.`,
|
||||
maxTokensInvalidMessage: 'Please enter a valid number for Max Tokens.',
|
||||
maxTokensMinMessage: 'Max Tokens cannot be less than 0.',
|
||||
maxTokensInvalidMessage: 'Please enter a valid number for Max tokens.',
|
||||
maxTokensMinMessage: 'Max tokens cannot be less than 0.',
|
||||
quote: 'Show quote',
|
||||
quoteTip: 'Whether to display the original text as a reference.',
|
||||
selfRag: 'Self-RAG',
|
||||
@ -878,7 +887,7 @@ Example: general/v2/`,
|
||||
Example: https://fsn1.your-objectstorage.com`,
|
||||
S3CompatibleAddressingStyleTip: `Required for S3 compatible Storage Box. Specify the S3-compatible addressing style.
|
||||
Example: Virtual Hosted Style`,
|
||||
addDataSourceModalTital: 'Create your {{name}} connector',
|
||||
addDataSourceModalTitle: 'Create your {{name}} connector',
|
||||
deleteSourceModalTitle: 'Delete data source',
|
||||
deleteSourceModalContent: `
|
||||
<p>Are you sure you want to delete this data source link?</p>`,
|
||||
@ -970,10 +979,10 @@ Example: Virtual Hosted Style`,
|
||||
avatarTip: 'This will be displayed on your profile.',
|
||||
profileDescription: 'Update your photo and personal details here.',
|
||||
maxTokens: 'Max tokens',
|
||||
maxTokensMessage: 'Max Tokens is required',
|
||||
maxTokensMessage: 'Max tokens is required',
|
||||
maxTokensTip: `This sets the maximum length of the model's output, measured in the number of tokens (words or pieces of words). Defaults to 512. If disabled, you lift the maximum token limit, allowing the model to determine the number of tokens in its responses.`,
|
||||
maxTokensInvalidMessage: 'Please enter a valid number for Max Tokens.',
|
||||
maxTokensMinMessage: 'Max Tokens cannot be less than 0.',
|
||||
maxTokensInvalidMessage: 'Please enter a valid number for Max tokens.',
|
||||
maxTokensMinMessage: 'Max tokens cannot be less than 0.',
|
||||
password: 'Password',
|
||||
passwordDescription:
|
||||
'Please enter your current password to change your password.',
|
||||
@ -1322,12 +1331,12 @@ Example: Virtual Hosted Style`,
|
||||
search: 'Search',
|
||||
communication: 'Communication',
|
||||
developer: 'Developer',
|
||||
typeCommandOrsearch: 'Type a command or search...',
|
||||
typeCommandORsearch: 'Type a command or search...',
|
||||
builtIn: 'Built-in',
|
||||
ExceptionDefaultValue: 'Exception default value',
|
||||
exceptionMethod: 'Exception method',
|
||||
maxRounds: 'Max reflection rounds',
|
||||
delayEfterError: 'Delay after error',
|
||||
delayAfterError: 'Delay after error',
|
||||
maxRetries: 'Max retry rounds',
|
||||
advancedSettings: 'Advanced settings',
|
||||
addTools: 'Add tools',
|
||||
@ -1834,7 +1843,7 @@ This delimiter is used to split the input text into several text pieces echo of
|
||||
}`,
|
||||
datatype: 'MINE type of the HTTP request',
|
||||
insertVariableTip: `Enter / Insert variables`,
|
||||
historyversion: 'Version history',
|
||||
historyVersion: 'Version history',
|
||||
version: {
|
||||
created: 'Created',
|
||||
details: 'Version details',
|
||||
@ -2169,7 +2178,7 @@ Important structured information may include: names, dates, locations, events, k
|
||||
agentStatus: 'Agent status:',
|
||||
},
|
||||
saveToMemory: 'Save to memory',
|
||||
memory: 'Memory',
|
||||
retrievalFrom: 'Retrieval from',
|
||||
},
|
||||
llmTools: {
|
||||
bad_calculator: {
|
||||
@ -2247,7 +2256,7 @@ Important structured information may include: names, dates, locations, events, k
|
||||
dataflowParser: {
|
||||
result: 'Result',
|
||||
parseSummary: 'Parse summary',
|
||||
parseSummaryTip: 'Parser:deepdoc',
|
||||
parseSummaryTip: 'Parser:DeepDoc',
|
||||
parserMethod: 'Parser method',
|
||||
outputFormat: 'Output format',
|
||||
rerunFromCurrentStep: 'Rerun from current step',
|
||||
@ -2270,10 +2279,10 @@ Important structured information may include: names, dates, locations, events, k
|
||||
<p>To keep them, please click Rerun to re-run the current stage.</p> `,
|
||||
changeStepModalConfirmText: 'Switch Anyway',
|
||||
changeStepModalCancelText: 'Cancel',
|
||||
unlinkPipelineModalTitle: 'Unlink Ingestion pipeline',
|
||||
unlinkPipelineModalTitle: 'Unlink ingestion pipeline',
|
||||
unlinkPipelineModalConfirmText: 'Unlink',
|
||||
unlinkPipelineModalContent: `
|
||||
<p>Once unlinked, this Dataset will no longer be connected to the current Ingestion pipeline.</p>
|
||||
<p>Once unlinked, this Dataset will no longer be connected to the current ingestion pipeline.</p>
|
||||
<p>Files that are already being parsed will continue until completion</p>
|
||||
<p>Files that are not yet parsed will no longer be processed</p> <br/>
|
||||
<p>Are you sure you want to proceed?</p> `,
|
||||
@ -2284,7 +2293,7 @@ Important structured information may include: names, dates, locations, events, k
|
||||
},
|
||||
datasetOverview: {
|
||||
downloadTip: 'Files being downloaded from data sources. ',
|
||||
processingTip: 'Files being processed by Ingestion pipeline.',
|
||||
processingTip: 'Files being processed by ingestion pipeline.',
|
||||
totalFiles: 'Total files',
|
||||
downloading: 'Downloading',
|
||||
downloadSuccessTip: 'Total successful downloads',
|
||||
|
||||
@ -1191,7 +1191,7 @@ export default {
|
||||
}`,
|
||||
datatype: 'Type MIME de la requête HTTP',
|
||||
insertVariableTip: `Entrer / Insérer des variables`,
|
||||
historyversion: 'Historique des versions',
|
||||
historyVersion: 'Historique des versions',
|
||||
version: {
|
||||
created: 'Créé',
|
||||
details: 'Détails de la version',
|
||||
|
||||
@ -325,7 +325,7 @@ export default {
|
||||
fileFilter: 'Filtro file',
|
||||
setDefaultTip: '',
|
||||
setDefault: 'Imposta come predefinito',
|
||||
eidtLinkDataPipeline: 'Modifica pipeline di ingestione',
|
||||
editLinkDataPipeline: 'Modifica pipeline di ingestione',
|
||||
linkPipelineSetTip:
|
||||
'Gestisci il collegamento della pipeline di ingestione con questo dataset',
|
||||
default: 'Predefinito',
|
||||
|
||||
@ -311,7 +311,7 @@ export default {
|
||||
fileFilter: 'Фильтр файлов',
|
||||
setDefaultTip: '',
|
||||
setDefault: 'Установить по умолчанию',
|
||||
eidtLinkDataPipeline: 'Редактировать пайплайн обработки',
|
||||
editLinkDataPipeline: 'Редактировать пайплайн обработки',
|
||||
linkPipelineSetTip:
|
||||
'Управление связью пайплайна обработки с этим набором данных',
|
||||
default: 'По умолчанию',
|
||||
@ -722,7 +722,7 @@ export default {
|
||||
Пример: https://fsn1.your-objectstorage.com`,
|
||||
S3CompatibleAddressingStyleTip: `Требуется для S3 совместимого Storage Box. Укажите стиль адресации, совместимый с S3.
|
||||
Пример: Virtual Hosted Style`,
|
||||
addDataSourceModalTital: 'Создайте ваш коннектор {{name}}',
|
||||
addDataSourceModalTitle: 'Создайте ваш коннектор {{name}}',
|
||||
deleteSourceModalTitle: 'Удалить источник данных',
|
||||
deleteSourceModalContent: `
|
||||
<p>Вы уверены, что хотите удалить эту ссылку на источник данных?</p>`,
|
||||
@ -1133,12 +1133,12 @@ export default {
|
||||
search: 'Поиск',
|
||||
communication: 'Коммуникация',
|
||||
developer: 'Разработчик',
|
||||
typeCommandOrsearch: 'Введите команду или поиск...',
|
||||
typeCommandORsearch: 'Введите команду или поиск...',
|
||||
builtIn: 'Встроенный',
|
||||
ExceptionDefaultValue: 'Значение по умолчанию при исключении',
|
||||
exceptionMethod: 'Метод обработки исключений',
|
||||
maxRounds: 'Макс. раундов рефлексии',
|
||||
delayEfterError: 'Задержка после ошибки',
|
||||
delayAfterError: 'Задержка после ошибки',
|
||||
maxRetries: 'Макс. попыток повтора',
|
||||
advancedSettings: 'Расширенные настройки',
|
||||
addTools: 'Добавить инструменты',
|
||||
@ -1637,7 +1637,7 @@ export default {
|
||||
}`,
|
||||
datatype: 'MIME тип HTTP запроса',
|
||||
insertVariableTip: `Введите / Вставьте переменные`,
|
||||
historyversion: 'История версий',
|
||||
historyVersion: 'История версий',
|
||||
version: {
|
||||
created: 'Создано',
|
||||
details: 'Детали версии',
|
||||
|
||||
@ -93,17 +93,21 @@ export default {
|
||||
search: '搜索',
|
||||
welcome: '欢迎来到',
|
||||
dataset: '知识库',
|
||||
Memories: '记忆',
|
||||
memories: '记忆',
|
||||
},
|
||||
memories: {
|
||||
llmTooltip: '分析对话内容,提取关键信息,并生成结构化的记忆摘要。',
|
||||
embeddingModelTooltip:
|
||||
'将文本转换为数值向量,用于语义相似度搜索和记忆检索。',
|
||||
embeddingModelError: '记忆类型为必填项,且"原始"类型不可删除。',
|
||||
embeddingModelError: '记忆类型为必填项,且"row"类型不可删除。',
|
||||
memoryTypeTooltip: `原始: 用户与代理之间的原始对话内容(默认必需)。
|
||||
语义记忆: 关于用户和世界的通用知识和事实。
|
||||
情景记忆: 带时间戳的特定事件和经历记录。
|
||||
程序记忆: 学习的技能、习惯和自动化程序。`,
|
||||
raw: '原始',
|
||||
semantic: '语义',
|
||||
episodic: '情景',
|
||||
procedural: '程序',
|
||||
editName: '编辑名称',
|
||||
memory: '记忆',
|
||||
createMemory: '创建记忆',
|
||||
@ -117,8 +121,8 @@ export default {
|
||||
},
|
||||
memory: {
|
||||
messages: {
|
||||
messageDescription:
|
||||
'记忆检索已在高级设置中配置相似度阈值、关键词相似度权重和前N个结果。',
|
||||
forgetMessageTip: '确定遗忘吗?',
|
||||
messageDescription: '记忆提取使用高级设置中的提示词和温度值进行配置。',
|
||||
copied: '已复制!',
|
||||
contentEmbed: '内容嵌入',
|
||||
content: '内容',
|
||||
@ -201,6 +205,10 @@ export default {
|
||||
deleteSettingFieldWarn: `此字段将被删除;现有元数据不会受到影响。`,
|
||||
deleteSettingValueWarn: `此值将被删除;现有元数据不会受到影响。`,
|
||||
},
|
||||
redoAll: '清除现有分块',
|
||||
applyAutoMetadataSettings: '应用全局自动元数据设置',
|
||||
parseFileTip: '您确定要解析吗?',
|
||||
parseFile: '解析文件',
|
||||
emptyMetadata: '无元数据',
|
||||
localUpload: '本地上传',
|
||||
fileSize: '文件大小',
|
||||
@ -405,7 +413,7 @@ export default {
|
||||
fileFilter: '正则匹配表达式',
|
||||
setDefaultTip: '',
|
||||
setDefault: '设置默认',
|
||||
eidtLinkDataPipeline: '编辑pipeline',
|
||||
editLinkDataPipeline: '编辑pipeline',
|
||||
linkPipelineSetTip: '管理与此数据集的数据管道链接',
|
||||
default: '默认',
|
||||
dataPipeline: 'Ingestion pipeline',
|
||||
@ -418,7 +426,7 @@ export default {
|
||||
parseType: '解析方法',
|
||||
manualSetup: '选择pipeline',
|
||||
builtIn: '内置',
|
||||
titleDescription: '在这里更新您的知识库详细信息,尤其是切片方法。',
|
||||
titleDescription: '在这里更新您的记忆配置,特别是大语言模型和提示词。',
|
||||
name: '知识库名称',
|
||||
photo: '知识库图片',
|
||||
photoTip: '你可以上传4MB的文件',
|
||||
@ -820,7 +828,7 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
||||
'可选:指定空间键以限制同步到特定空间。留空则同步所有可访问的空间。多个空间请用逗号分隔(例如:DEV,DOCS,HR)',
|
||||
s3PrefixTip: `指定 S3 存储桶内的文件夹路径,用于读取文件。
|
||||
示例:general/v2/`,
|
||||
addDataSourceModalTital: '创建你的 {{name}} 链接',
|
||||
addDataSourceModalTitle: '创建你的 {{name}} 链接',
|
||||
deleteSourceModalTitle: '删除数据源链接',
|
||||
deleteSourceModalContent: `
|
||||
<p>您确定要删除此数据源链接吗?</p>`,
|
||||
@ -1202,14 +1210,14 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
||||
search: '搜索',
|
||||
communication: '通信',
|
||||
developer: '开发者',
|
||||
typeCommandOrsearch: '输入命令或或搜索...',
|
||||
typeCommandORsearch: '输入命令或或搜索...',
|
||||
builtIn: '内置',
|
||||
goto: '异常分支',
|
||||
comment: '默认值',
|
||||
ExceptionDefaultValue: '异常处理默认值',
|
||||
exceptionMethod: '异常处理方法',
|
||||
maxRounds: '最大反思轮数',
|
||||
delayEfterError: '错误后延迟',
|
||||
delayAfterError: '错误后延迟',
|
||||
maxRetries: '最大重试轮数',
|
||||
advancedSettings: '高级设置',
|
||||
addTools: '添加工具',
|
||||
@ -1246,7 +1254,7 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
||||
dialog: '对话',
|
||||
flow: '工作流',
|
||||
noMoreData: '没有更多数据了',
|
||||
historyversion: '历史版本',
|
||||
historyVersion: '历史版本',
|
||||
version: {
|
||||
details: '版本详情',
|
||||
download: '下载',
|
||||
@ -1970,7 +1978,7 @@ Tokenizer 会根据所选方式将内容存储为对应的数据结构。`,
|
||||
agentStatus: '智能体状态:',
|
||||
},
|
||||
saveToMemory: '保存到Memory',
|
||||
memory: 'Memory',
|
||||
retrievalFrom: '检索来源',
|
||||
},
|
||||
footer: {
|
||||
profile: 'All rights reserved @ React',
|
||||
|
||||
@ -1,13 +1,16 @@
|
||||
import { NodeCollapsible } from '@/components/collapse';
|
||||
import { RAGFlowAvatar } from '@/components/ragflow-avatar';
|
||||
import { useFetchKnowledgeList } from '@/hooks/use-knowledge-request';
|
||||
import { IRetrievalNode } from '@/interfaces/database/flow';
|
||||
import { useFetchAllMemoryList } from '@/hooks/use-memory-request';
|
||||
import { BaseNode } from '@/interfaces/database/flow';
|
||||
import { NodeProps, Position } from '@xyflow/react';
|
||||
import classNames from 'classnames';
|
||||
import { get } from 'lodash';
|
||||
import { memo } from 'react';
|
||||
import { NodeHandleId } from '../../constant';
|
||||
import { NodeHandleId, RetrievalFrom } from '../../constant';
|
||||
import { RetrievalFormSchemaType } from '../../form/retrieval-form/next';
|
||||
import { useGetVariableLabelOrTypeByValue } from '../../hooks/use-get-begin-query';
|
||||
import { LabelCard } from './card';
|
||||
import { CommonHandle, LeftEndHandle } from './handle';
|
||||
import styles from './index.less';
|
||||
import NodeHeader from './node-header';
|
||||
@ -19,12 +22,17 @@ function InnerRetrievalNode({
|
||||
data,
|
||||
isConnectable = true,
|
||||
selected,
|
||||
}: NodeProps<IRetrievalNode>) {
|
||||
}: NodeProps<BaseNode<RetrievalFormSchemaType>>) {
|
||||
const knowledgeBaseIds: string[] = get(data, 'form.kb_ids', []);
|
||||
const memoryIds: string[] = get(data, 'form.memory_ids', []);
|
||||
const { list: knowledgeList } = useFetchKnowledgeList(true);
|
||||
|
||||
const { getLabel } = useGetVariableLabelOrTypeByValue({ nodeId: id });
|
||||
|
||||
const isMemory = data.form?.retrieval_from === RetrievalFrom.Memory;
|
||||
|
||||
const memoryList = useFetchAllMemoryList();
|
||||
|
||||
return (
|
||||
<ToolBar selected={selected} id={id} label={data.label}>
|
||||
<NodeWrapper selected={selected} id={id}>
|
||||
@ -45,8 +53,22 @@ function InnerRetrievalNode({
|
||||
[styles.nodeHeader]: knowledgeBaseIds.length > 0,
|
||||
})}
|
||||
></NodeHeader>
|
||||
<NodeCollapsible items={knowledgeBaseIds}>
|
||||
<NodeCollapsible items={isMemory ? memoryIds : knowledgeBaseIds}>
|
||||
{(id) => {
|
||||
if (isMemory) {
|
||||
const item = memoryList.data?.find((y) => id === y.id);
|
||||
return (
|
||||
<LabelCard key={id} className="flex items-center gap-1.5">
|
||||
<RAGFlowAvatar
|
||||
className="size-6 rounded-lg"
|
||||
avatar={item?.avatar ?? ''}
|
||||
name={item ? item?.name : id}
|
||||
/>
|
||||
<span className="flex-1 truncate"> {item?.name}</span>
|
||||
</LabelCard>
|
||||
);
|
||||
}
|
||||
|
||||
const item = knowledgeList.find((y) => id === y.id);
|
||||
const label = getLabel(id);
|
||||
|
||||
|
||||
@ -79,6 +79,11 @@ export const DataOperationsOperatorOptions = [
|
||||
|
||||
export const SwitchElseTo = 'end_cpn_ids';
|
||||
|
||||
export enum RetrievalFrom {
|
||||
Dataset = 'dataset',
|
||||
Memory = 'memory',
|
||||
}
|
||||
|
||||
export const initialRetrievalValues = {
|
||||
query: AgentGlobalsSysQueryWithBrace,
|
||||
top_n: 8,
|
||||
@ -91,6 +96,7 @@ export const initialRetrievalValues = {
|
||||
use_kg: false,
|
||||
toc_enhance: false,
|
||||
cross_languages: [],
|
||||
retrieval_from: RetrievalFrom.Dataset,
|
||||
outputs: {
|
||||
formalized_content: {
|
||||
type: 'string',
|
||||
|
||||
@ -242,7 +242,7 @@ function AgentForm({ node }: INextOperatorForm) {
|
||||
name={`delay_after_error`}
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex-1">
|
||||
<FormLabel>{t('flow.delayEfterError')}</FormLabel>
|
||||
<FormLabel>{t('flow.delayAfterError')}</FormLabel>
|
||||
<FormControl>
|
||||
<NumberInput {...field} max={5} step={0.1}></NumberInput>
|
||||
</FormControl>
|
||||
|
||||
@ -115,7 +115,7 @@ export function ToolCommand({ value, onChange }: ToolCommandProps) {
|
||||
|
||||
return (
|
||||
<Command>
|
||||
<CommandInput placeholder={t('flow.typeCommandOrsearch')} />
|
||||
<CommandInput placeholder={t('flow.typeCommandORsearch')} />
|
||||
<CommandList>
|
||||
<CommandEmpty>No results found.</CommandEmpty>
|
||||
{Menus.map((x) => (
|
||||
|
||||
@ -20,14 +20,20 @@ import {
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from '@/components/ui/form';
|
||||
import { Radio } from '@/components/ui/radio';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
import { UseKnowledgeGraphFormField } from '@/components/use-knowledge-graph-item';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { memo, useMemo } from 'react';
|
||||
import { useForm, useFormContext } from 'react-hook-form';
|
||||
import {
|
||||
UseFormReturn,
|
||||
useForm,
|
||||
useFormContext,
|
||||
useWatch,
|
||||
} from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { z } from 'zod';
|
||||
import { initialRetrievalValues } from '../../constant';
|
||||
import { RetrievalFrom, initialRetrievalValues } from '../../constant';
|
||||
import { useWatchFormChange } from '../../hooks/use-watch-form-change';
|
||||
import { INextOperatorForm } from '../../interface';
|
||||
import { FormWrapper } from '../components/form-wrapper';
|
||||
@ -48,6 +54,7 @@ export const RetrievalPartialSchema = {
|
||||
toc_enhance: z.boolean(),
|
||||
...MetadataFilterSchema,
|
||||
memory_ids: z.array(z.string()).optional(),
|
||||
retrieval_from: z.string(),
|
||||
};
|
||||
|
||||
export const FormSchema = z.object({
|
||||
@ -55,6 +62,44 @@ export const FormSchema = z.object({
|
||||
...RetrievalPartialSchema,
|
||||
});
|
||||
|
||||
export type RetrievalFormSchemaType = z.infer<typeof FormSchema>;
|
||||
|
||||
export function MemoryDatasetForm() {
|
||||
const { t } = useTranslation();
|
||||
const form = useFormContext();
|
||||
const retrievalFrom = useWatch({
|
||||
control: form.control,
|
||||
name: 'retrieval_from',
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<RAGFlowFormItem name="retrieval_from" label={t('flow.retrievalFrom')}>
|
||||
<Radio.Group>
|
||||
<Radio value={RetrievalFrom.Dataset}>
|
||||
{t('knowledgeDetails.dataset')}
|
||||
</Radio>
|
||||
<Radio value={RetrievalFrom.Memory}>{t('header.memories')}</Radio>
|
||||
</Radio.Group>
|
||||
</RAGFlowFormItem>
|
||||
{retrievalFrom === RetrievalFrom.Memory ? (
|
||||
<MemoriesFormField label={t('header.memories')}></MemoriesFormField>
|
||||
) : (
|
||||
<KnowledgeBaseFormField showVariable></KnowledgeBaseFormField>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export function useHideKnowledgeGraphField(form: UseFormReturn<any>) {
|
||||
const retrievalFrom = useWatch({
|
||||
control: form.control,
|
||||
name: 'retrieval_from',
|
||||
});
|
||||
|
||||
return retrievalFrom === RetrievalFrom.Memory;
|
||||
}
|
||||
|
||||
export function EmptyResponseField() {
|
||||
const { t } = useTranslation();
|
||||
const form = useFormContext();
|
||||
@ -106,6 +151,8 @@ function RetrievalForm({ node }: INextOperatorForm) {
|
||||
resolver: zodResolver(FormSchema),
|
||||
});
|
||||
|
||||
const hideKnowledgeGraphField = useHideKnowledgeGraphField(form);
|
||||
|
||||
useWatchFormChange(node?.id, form);
|
||||
|
||||
return (
|
||||
@ -114,8 +161,7 @@ function RetrievalForm({ node }: INextOperatorForm) {
|
||||
<RAGFlowFormItem name="query" label={t('flow.query')}>
|
||||
<PromptEditor></PromptEditor>
|
||||
</RAGFlowFormItem>
|
||||
<KnowledgeBaseFormField showVariable></KnowledgeBaseFormField>
|
||||
<MemoriesFormField label={t('flow.memory')}></MemoriesFormField>
|
||||
<MemoryDatasetForm></MemoryDatasetForm>
|
||||
<Collapse title={<div>{t('flow.advancedSettings')}</div>}>
|
||||
<FormContainer>
|
||||
<SimilaritySliderFormField
|
||||
@ -123,12 +169,20 @@ function RetrievalForm({ node }: INextOperatorForm) {
|
||||
isTooltipShown
|
||||
></SimilaritySliderFormField>
|
||||
<TopNFormField></TopNFormField>
|
||||
<RerankFormFields></RerankFormFields>
|
||||
<MetadataFilter canReference></MetadataFilter>
|
||||
{hideKnowledgeGraphField || (
|
||||
<>
|
||||
<RerankFormFields></RerankFormFields>
|
||||
<MetadataFilter canReference></MetadataFilter>
|
||||
</>
|
||||
)}
|
||||
<EmptyResponseField></EmptyResponseField>
|
||||
<CrossLanguageFormField name="cross_languages"></CrossLanguageFormField>
|
||||
<UseKnowledgeGraphFormField name="use_kg"></UseKnowledgeGraphFormField>
|
||||
<TOCEnhanceFormField name="toc_enhance"></TOCEnhanceFormField>
|
||||
{hideKnowledgeGraphField || (
|
||||
<>
|
||||
<CrossLanguageFormField name="cross_languages"></CrossLanguageFormField>
|
||||
<UseKnowledgeGraphFormField name="use_kg"></UseKnowledgeGraphFormField>
|
||||
<TOCEnhanceFormField name="toc_enhance"></TOCEnhanceFormField>
|
||||
</>
|
||||
)}
|
||||
</FormContainer>
|
||||
</Collapse>
|
||||
<Output list={outputList}></Output>
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
import { Collapse } from '@/components/collapse';
|
||||
import { CrossLanguageFormField } from '@/components/cross-language-form-field';
|
||||
import { FormContainer } from '@/components/form-container';
|
||||
import { KnowledgeBaseFormField } from '@/components/knowledge-base-item';
|
||||
import { MemoriesFormField } from '@/components/memories-form-field';
|
||||
import { MetadataFilter } from '@/components/metadata-filter';
|
||||
import { RerankFormFields } from '@/components/rerank';
|
||||
import { SimilaritySliderFormField } from '@/components/similarity-slider';
|
||||
@ -18,7 +16,9 @@ import { DescriptionField } from '../../components/description-field';
|
||||
import { FormWrapper } from '../../components/form-wrapper';
|
||||
import {
|
||||
EmptyResponseField,
|
||||
MemoryDatasetForm,
|
||||
RetrievalPartialSchema,
|
||||
useHideKnowledgeGraphField,
|
||||
} from '../../retrieval-form/next';
|
||||
import { useValues } from '../use-values';
|
||||
import { useWatchFormChange } from '../use-watch-change';
|
||||
@ -36,14 +36,15 @@ const RetrievalForm = () => {
|
||||
resolver: zodResolver(FormSchema),
|
||||
});
|
||||
|
||||
const hideKnowledgeGraphField = useHideKnowledgeGraphField(form);
|
||||
|
||||
useWatchFormChange(form);
|
||||
|
||||
return (
|
||||
<Form {...form}>
|
||||
<FormWrapper>
|
||||
<DescriptionField></DescriptionField>
|
||||
<KnowledgeBaseFormField showVariable></KnowledgeBaseFormField>
|
||||
<MemoriesFormField label={t('flow.memory')}></MemoriesFormField>
|
||||
<MemoryDatasetForm></MemoryDatasetForm>
|
||||
<Collapse title={<div>{t('flow.advancedSettings')}</div>}>
|
||||
<FormContainer>
|
||||
<SimilaritySliderFormField
|
||||
@ -51,12 +52,21 @@ const RetrievalForm = () => {
|
||||
isTooltipShown
|
||||
></SimilaritySliderFormField>
|
||||
<TopNFormField></TopNFormField>
|
||||
<RerankFormFields></RerankFormFields>
|
||||
<MetadataFilter canReference></MetadataFilter>
|
||||
{hideKnowledgeGraphField || (
|
||||
<>
|
||||
<RerankFormFields></RerankFormFields>
|
||||
<MetadataFilter canReference></MetadataFilter>
|
||||
</>
|
||||
)}
|
||||
|
||||
<EmptyResponseField></EmptyResponseField>
|
||||
<CrossLanguageFormField name="cross_languages"></CrossLanguageFormField>
|
||||
<UseKnowledgeGraphFormField name="use_kg"></UseKnowledgeGraphFormField>
|
||||
<TOCEnhanceFormField name="toc_enhance"></TOCEnhanceFormField>
|
||||
{hideKnowledgeGraphField || (
|
||||
<>
|
||||
<CrossLanguageFormField name="cross_languages"></CrossLanguageFormField>
|
||||
<UseKnowledgeGraphFormField name="use_kg"></UseKnowledgeGraphFormField>
|
||||
<TOCEnhanceFormField name="toc_enhance"></TOCEnhanceFormField>
|
||||
</>
|
||||
)}
|
||||
</FormContainer>
|
||||
</Collapse>
|
||||
</FormWrapper>
|
||||
|
||||
@ -246,7 +246,7 @@ export default function Agent() {
|
||||
</Button>
|
||||
<Button variant={'secondary'} onClick={showVersionDialog}>
|
||||
<History />
|
||||
{t('flow.historyversion')}
|
||||
{t('flow.historyVersion')}
|
||||
</Button>
|
||||
{isPipeline || (
|
||||
<Button
|
||||
|
||||
@ -61,7 +61,7 @@ export function VersionDialog({
|
||||
<DialogContent className="max-w-[60vw]">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="text-base">
|
||||
{t('flow.historyversion')}
|
||||
{t('flow.historyVersion')}
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
<section className="flex gap-8 relative">
|
||||
|
||||
@ -52,7 +52,7 @@ const LinkDataPipelineModal = ({
|
||||
title={
|
||||
!isEdit
|
||||
? t('knowledgeConfiguration.linkDataPipeline')
|
||||
: t('knowledgeConfiguration.eidtLinkDataPipeline')
|
||||
: t('knowledgeConfiguration.editLinkDataPipeline')
|
||||
}
|
||||
open={open}
|
||||
onOpenChange={setOpen}
|
||||
|
||||
@ -23,6 +23,7 @@ import {
|
||||
import { ManageMetadataModal } from '../components/metedata/manage-modal';
|
||||
import { DatasetTable } from './dataset-table';
|
||||
import Generate from './generate-button/generate';
|
||||
import { ReparseDialog } from './reparse-dialog';
|
||||
import { useBulkOperateDataset } from './use-bulk-operate-dataset';
|
||||
import { useCreateEmptyDocument } from './use-create-empty-document';
|
||||
import { useSelectDatasetFilters } from './use-select-filters';
|
||||
@ -77,7 +78,12 @@ export default function Dataset() {
|
||||
const { rowSelection, rowSelectionIsEmpty, setRowSelection, selectedCount } =
|
||||
useRowSelection();
|
||||
|
||||
const { list } = useBulkOperateDataset({
|
||||
const {
|
||||
list,
|
||||
visible: reparseDialogVisible,
|
||||
hideModal: hideReparseDialogModal,
|
||||
handleRunClick: handleOperationIconClick,
|
||||
} = useBulkOperateDataset({
|
||||
documents,
|
||||
rowSelection,
|
||||
setRowSelection,
|
||||
@ -207,6 +213,16 @@ export default function Dataset() {
|
||||
otherData={metadataConfig.record}
|
||||
/>
|
||||
)}
|
||||
{reparseDialogVisible && (
|
||||
<ReparseDialog
|
||||
// hidden={isZeroChunk || isRunning}
|
||||
hidden={false}
|
||||
handleOperationIconClick={handleOperationIconClick}
|
||||
chunk_num={0}
|
||||
visible={reparseDialogVisible}
|
||||
hideModal={hideReparseDialogModal}
|
||||
></ReparseDialog>
|
||||
)}
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import { ConfirmDeleteDialog } from '@/components/confirm-delete-dialog';
|
||||
import { IconFontFill } from '@/components/icon-font';
|
||||
import {
|
||||
DropdownMenu,
|
||||
@ -19,6 +18,7 @@ import { useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { DocumentType, RunningStatus } from './constant';
|
||||
import { ParsingCard } from './parsing-card';
|
||||
import { ReparseDialog } from './reparse-dialog';
|
||||
import { UseChangeDocumentParserShowType } from './use-change-document-parser';
|
||||
import { useHandleRunDocumentByIds } from './use-run-document';
|
||||
import { UseSaveMetaShowType } from './use-save-meta';
|
||||
@ -63,15 +63,21 @@ export function ParsingStatusCell({
|
||||
} = record;
|
||||
const operationIcon = IconMap[run];
|
||||
const p = Number((progress * 100).toFixed(2));
|
||||
const { handleRunDocumentByIds } = useHandleRunDocumentByIds(id);
|
||||
const {
|
||||
handleRunDocumentByIds,
|
||||
visible: reparseDialogVisible,
|
||||
showModal: showReparseDialogModal,
|
||||
hideModal: hideReparseDialogModal,
|
||||
} = useHandleRunDocumentByIds(id);
|
||||
const isRunning = isParserRunning(run);
|
||||
const isZeroChunk = chunk_num === 0;
|
||||
|
||||
const handleOperationIconClick =
|
||||
(shouldDelete: boolean = false) =>
|
||||
() => {
|
||||
handleRunDocumentByIds(record.id, isRunning, shouldDelete);
|
||||
};
|
||||
const handleOperationIconClick = (option: {
|
||||
delete: boolean;
|
||||
apply_kb: boolean;
|
||||
}) => {
|
||||
handleRunDocumentByIds(record.id, isRunning, option);
|
||||
};
|
||||
|
||||
const handleShowChangeParserModal = useCallback(() => {
|
||||
showChangeParserModal(record);
|
||||
@ -129,23 +135,20 @@ export function ParsingStatusCell({
|
||||
<div className="flex items-center gap-3">
|
||||
<Separator orientation="vertical" className="h-2.5" />
|
||||
{!isParserRunning(run) && (
|
||||
<ConfirmDeleteDialog
|
||||
title={t(`knowledgeDetails.redo`, { chunkNum: chunk_num })}
|
||||
hidden={isZeroChunk || isRunning}
|
||||
onOk={handleOperationIconClick(true)}
|
||||
onCancel={handleOperationIconClick(false)}
|
||||
// <ReparseDialog
|
||||
// hidden={isZeroChunk || isRunning}
|
||||
// handleOperationIconClick={handleOperationIconClick}
|
||||
// chunk_num={chunk_num}
|
||||
// >
|
||||
<div
|
||||
className="cursor-pointer flex items-center gap-3"
|
||||
onClick={() => {
|
||||
showReparseDialogModal();
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="cursor-pointer flex items-center gap-3"
|
||||
onClick={
|
||||
isZeroChunk || isRunning
|
||||
? handleOperationIconClick(false)
|
||||
: () => {}
|
||||
}
|
||||
>
|
||||
{!isParserRunning(run) && operationIcon}
|
||||
</div>
|
||||
</ConfirmDeleteDialog>
|
||||
{!isParserRunning(run) && operationIcon}
|
||||
</div>
|
||||
// {/* </ReparseDialog> */}
|
||||
)}
|
||||
{isParserRunning(run) ? (
|
||||
<>
|
||||
@ -158,11 +161,14 @@ export function ParsingStatusCell({
|
||||
</div>
|
||||
<div
|
||||
className="cursor-pointer flex items-center gap-3"
|
||||
onClick={
|
||||
isZeroChunk || isRunning
|
||||
? handleOperationIconClick(false)
|
||||
: () => {}
|
||||
}
|
||||
onClick={() => {
|
||||
showReparseDialogModal();
|
||||
}}
|
||||
// onClick={
|
||||
// isZeroChunk || isRunning
|
||||
// ? handleOperationIconClick(false)
|
||||
// : () => {}
|
||||
// }
|
||||
>
|
||||
{operationIcon}
|
||||
</div>
|
||||
@ -175,6 +181,16 @@ export function ParsingStatusCell({
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{reparseDialogVisible && (
|
||||
<ReparseDialog
|
||||
// hidden={isZeroChunk || isRunning}
|
||||
hidden={false}
|
||||
handleOperationIconClick={handleOperationIconClick}
|
||||
chunk_num={chunk_num}
|
||||
visible={reparseDialogVisible}
|
||||
hideModal={hideReparseDialogModal}
|
||||
></ReparseDialog>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
154
web/src/pages/dataset/dataset/reparse-dialog.tsx
Normal file
154
web/src/pages/dataset/dataset/reparse-dialog.tsx
Normal file
@ -0,0 +1,154 @@
|
||||
import { ConfirmDeleteDialog } from '@/components/confirm-delete-dialog';
|
||||
import {
|
||||
DynamicForm,
|
||||
DynamicFormRef,
|
||||
FormFieldType,
|
||||
} from '@/components/dynamic-form';
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
import { DialogProps } from '@radix-ui/react-dialog';
|
||||
import { t } from 'i18next';
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
export const ReparseDialog = ({
|
||||
handleOperationIconClick,
|
||||
chunk_num,
|
||||
hidden = false,
|
||||
visible = true,
|
||||
hideModal,
|
||||
children,
|
||||
}: DialogProps & {
|
||||
chunk_num: number;
|
||||
handleOperationIconClick: (options: {
|
||||
delete: boolean;
|
||||
apply_kb: boolean;
|
||||
}) => void;
|
||||
visible: boolean;
|
||||
hideModal: () => void;
|
||||
hidden?: boolean;
|
||||
}) => {
|
||||
const [formInstance, setFormInstance] = useState<DynamicFormRef | null>(null);
|
||||
|
||||
const formCallbackRef = useCallback((node: DynamicFormRef | null) => {
|
||||
if (node) {
|
||||
setFormInstance(node);
|
||||
console.log('Form instance assigned:', node);
|
||||
} else {
|
||||
console.log('Form instance removed');
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleCancel = useCallback(() => {
|
||||
// handleOperationIconClick(false);
|
||||
hideModal?.();
|
||||
formInstance?.reset();
|
||||
}, [formInstance]);
|
||||
|
||||
const handleSave = useCallback(async () => {
|
||||
const instance = formInstance;
|
||||
if (!instance) {
|
||||
console.error('Form instance is null');
|
||||
return;
|
||||
}
|
||||
|
||||
const check = await instance.trigger();
|
||||
if (check) {
|
||||
instance.submit();
|
||||
const formValues = instance.getValues();
|
||||
console.log(formValues);
|
||||
handleOperationIconClick({
|
||||
delete: formValues.delete,
|
||||
apply_kb: formValues.apply_kb,
|
||||
});
|
||||
}
|
||||
}, [formInstance, handleOperationIconClick]);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (!hidden) {
|
||||
// const timer = setTimeout(() => {
|
||||
// if (!formInstance) {
|
||||
// console.warn(
|
||||
// 'Form ref is still null after component should be mounted',
|
||||
// );
|
||||
// } else {
|
||||
// console.log('Form ref is properly set');
|
||||
// }
|
||||
// }, 1000);
|
||||
|
||||
// return () => clearTimeout(timer);
|
||||
// }
|
||||
// }, [hidden, formInstance]);
|
||||
|
||||
return (
|
||||
<ConfirmDeleteDialog
|
||||
title={t(`knowledgeDetails.parseFile`)}
|
||||
onOk={() => handleSave()}
|
||||
onCancel={() => handleCancel()}
|
||||
hidden={hidden}
|
||||
open={visible}
|
||||
content={{
|
||||
title: t(`knowledgeDetails.parseFileTip`),
|
||||
node: (
|
||||
<div>
|
||||
<DynamicForm.Root
|
||||
onSubmit={(data) => {
|
||||
console.log('submit', data);
|
||||
}}
|
||||
ref={formCallbackRef}
|
||||
fields={[
|
||||
{
|
||||
name: 'delete',
|
||||
label: '',
|
||||
type: FormFieldType.Checkbox,
|
||||
render: (fieldProps) => (
|
||||
<div className="flex items-center text-text-secondary p-5 border border-border-button rounded-lg">
|
||||
<Checkbox
|
||||
{...fieldProps}
|
||||
onCheckedChange={(checked: boolean) => {
|
||||
fieldProps.onChange(checked);
|
||||
}}
|
||||
/>
|
||||
<span className="ml-2">
|
||||
{chunk_num > 0
|
||||
? t(`knowledgeDetails.redo`, { chunkNum: chunk_num })
|
||||
: t('knowledgeDetails.redoAll')}
|
||||
</span>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: 'apply_kb',
|
||||
label: '',
|
||||
type: FormFieldType.Checkbox,
|
||||
render: (fieldProps) => (
|
||||
<div className="flex items-center text-text-secondary p-5 border border-border-button rounded-lg">
|
||||
<Checkbox
|
||||
{...fieldProps}
|
||||
onCheckedChange={(checked: boolean) => {
|
||||
fieldProps.onChange(checked);
|
||||
}}
|
||||
/>
|
||||
<span className="ml-2">
|
||||
{t('knowledgeDetails.applyAutoMetadataSettings')}
|
||||
</span>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]}
|
||||
>
|
||||
{/* <DynamicForm.CancelButton
|
||||
handleCancel={() => handleOperationIconClick(false)}
|
||||
cancelText={t('common.cancel')}
|
||||
/>
|
||||
<DynamicForm.SavingButton
|
||||
buttonText={t('common.confirm')}
|
||||
submitFunc={handleSave}
|
||||
/> */}
|
||||
</DynamicForm.Root>
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
>
|
||||
{/* {children} */}
|
||||
</ConfirmDeleteDialog>
|
||||
);
|
||||
};
|
||||
@ -1,3 +1,4 @@
|
||||
import { useSetModalState } from '@/hooks/common-hooks';
|
||||
import {
|
||||
UseRowSelectionType,
|
||||
useSelectedIds,
|
||||
@ -30,9 +31,9 @@ export function useBulkOperateDataset({
|
||||
const { runDocumentByIds } = useRunDocument();
|
||||
const { setDocumentStatus } = useSetDocumentStatus();
|
||||
const { removeDocument } = useRemoveDocument();
|
||||
|
||||
const { visible, showModal, hideModal } = useSetModalState();
|
||||
const runDocument = useCallback(
|
||||
(run: number) => {
|
||||
async (run: number, option?: { delete: boolean; apply_kb: boolean }) => {
|
||||
const nonVirtualKeys = selectedRowKeys.filter(
|
||||
(x) =>
|
||||
!documents.some((y) => x === y.id && y.type === DocumentType.Virtual),
|
||||
@ -42,18 +43,22 @@ export function useBulkOperateDataset({
|
||||
toast.error(t('Please select a non-empty file list'));
|
||||
return;
|
||||
}
|
||||
runDocumentByIds({
|
||||
await runDocumentByIds({
|
||||
documentIds: nonVirtualKeys,
|
||||
run,
|
||||
shouldDelete: false,
|
||||
option,
|
||||
});
|
||||
hideModal();
|
||||
},
|
||||
[documents, runDocumentByIds, selectedRowKeys, t],
|
||||
[documents, runDocumentByIds, selectedRowKeys, hideModal, t],
|
||||
);
|
||||
|
||||
const handleRunClick = useCallback(() => {
|
||||
runDocument(1);
|
||||
}, [runDocument]);
|
||||
const handleRunClick = useCallback(
|
||||
(option: { delete: boolean; apply_kb: boolean }) => {
|
||||
runDocument(1, option);
|
||||
},
|
||||
[runDocument],
|
||||
);
|
||||
|
||||
const handleCancelClick = useCallback(() => {
|
||||
runDocument(2);
|
||||
@ -106,7 +111,7 @@ export function useBulkOperateDataset({
|
||||
id: 'run',
|
||||
label: t('knowledgeDetails.run'),
|
||||
icon: <Play />,
|
||||
onClick: handleRunClick,
|
||||
onClick: () => showModal(),
|
||||
},
|
||||
{
|
||||
id: 'cancel',
|
||||
@ -127,5 +132,5 @@ export function useBulkOperateDataset({
|
||||
},
|
||||
];
|
||||
|
||||
return { list };
|
||||
return { list, visible, hideModal, showModal, handleRunClick };
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { useSetModalState } from '@/hooks/common-hooks';
|
||||
import { useRunDocument } from '@/hooks/use-document-request';
|
||||
import { useState } from 'react';
|
||||
|
||||
@ -5,11 +6,11 @@ export const useHandleRunDocumentByIds = (id: string) => {
|
||||
const { runDocumentByIds, loading } = useRunDocument();
|
||||
const [currentId, setCurrentId] = useState<string>('');
|
||||
const isLoading = loading && currentId !== '' && currentId === id;
|
||||
|
||||
const { visible, showModal, hideModal } = useSetModalState();
|
||||
const handleRunDocumentByIds = async (
|
||||
documentId: string,
|
||||
isRunning: boolean,
|
||||
shouldDelete: boolean = false,
|
||||
option: { delete: boolean; apply_kb: boolean },
|
||||
) => {
|
||||
if (isLoading) {
|
||||
return;
|
||||
@ -19,16 +20,20 @@ export const useHandleRunDocumentByIds = (id: string) => {
|
||||
await runDocumentByIds({
|
||||
documentIds: [documentId],
|
||||
run: isRunning ? 2 : 1,
|
||||
shouldDelete,
|
||||
option,
|
||||
});
|
||||
setCurrentId('');
|
||||
} catch (error) {
|
||||
setCurrentId('');
|
||||
}
|
||||
hideModal();
|
||||
};
|
||||
|
||||
return {
|
||||
handleRunDocumentByIds,
|
||||
loading: isLoading,
|
||||
visible,
|
||||
showModal,
|
||||
hideModal,
|
||||
};
|
||||
};
|
||||
|
||||
@ -10,6 +10,12 @@ export enum MemoryType {
|
||||
Episodic = 'episodic',
|
||||
Procedural = 'procedural',
|
||||
}
|
||||
export const MemoryOptions = (t: TFunction) => [
|
||||
{ label: t('memories.raw'), value: MemoryType.Raw },
|
||||
{ label: t('memories.semantic'), value: MemoryType.Semantic },
|
||||
{ label: t('memories.episodic'), value: MemoryType.Episodic },
|
||||
{ label: t('memories.procedural'), value: MemoryType.Procedural },
|
||||
];
|
||||
export const createMemoryFields = (t: TFunction) =>
|
||||
[
|
||||
{
|
||||
@ -24,12 +30,7 @@ export const createMemoryFields = (t: TFunction) =>
|
||||
type: FormFieldType.MultiSelect,
|
||||
placeholder: t('memories.descriptionPlaceholder'),
|
||||
tooltip: t('memories.memoryTypeTooltip'),
|
||||
options: [
|
||||
{ label: 'Raw', value: MemoryType.Raw },
|
||||
{ label: 'Semantic', value: MemoryType.Semantic },
|
||||
{ label: 'Episodic', value: MemoryType.Episodic },
|
||||
{ label: 'Procedural', value: MemoryType.Procedural },
|
||||
],
|
||||
options: MemoryOptions(t),
|
||||
required: true,
|
||||
customValidate: (value) => {
|
||||
if (!value.includes(MemoryType.Raw) || !value.length) {
|
||||
|
||||
@ -16,7 +16,7 @@ export interface MemoryListParams {
|
||||
export type MemoryType = 'raw' | 'semantic' | 'episodic' | 'procedural';
|
||||
export type StorageType = 'table' | 'graph';
|
||||
export type Permissions = 'me' | 'team';
|
||||
export type ForgettingPolicy = 'fifo' | 'lru';
|
||||
export type ForgettingPolicy = 'FIFO' | 'LRU';
|
||||
export interface ICreateMemoryProps {
|
||||
name: string;
|
||||
memory_type: MemoryType[];
|
||||
|
||||
@ -39,7 +39,7 @@ export default function MemoryMessage() {
|
||||
messages={data?.messages?.message_list ?? []}
|
||||
pagination={pagination}
|
||||
setPagination={setPagination}
|
||||
total={data?.messages?.total ?? 0}
|
||||
total={data?.messages?.total_count ?? 0}
|
||||
// rowSelection={rowSelection}
|
||||
// setRowSelection={setRowSelection}
|
||||
// loading={loading}
|
||||
|
||||
@ -14,7 +14,7 @@ export interface IMessageInfo {
|
||||
}
|
||||
|
||||
export interface IMessageTableProps {
|
||||
messages: { message_list: Array<IMessageInfo>; total: number };
|
||||
messages: { message_list: Array<IMessageInfo>; total_count: number };
|
||||
storage_type: string;
|
||||
}
|
||||
|
||||
|
||||
@ -251,7 +251,9 @@ export function MemoryTable({
|
||||
title={t('memory.messages.forgetMessage')}
|
||||
open={showDeleteDialog}
|
||||
onOpenChange={setShowDeleteDialog}
|
||||
okButtonText={t('common.confirm')}
|
||||
content={{
|
||||
title: t('memory.messages.forgetMessageTip'),
|
||||
node: (
|
||||
<ConfirmDeleteDialogNode
|
||||
// avatar={{ avatar: selectedMessage.avatar, name: selectedMessage.name }}
|
||||
|
||||
@ -12,7 +12,7 @@ import { z } from 'zod';
|
||||
export const advancedSettingsFormSchema = {
|
||||
permissions: z.string().optional(),
|
||||
storage_type: z.enum(['table', 'graph']).optional(),
|
||||
forgetting_policy: z.enum(['lru', 'fifo']).optional(),
|
||||
forgetting_policy: z.enum(['LRU', 'FIFO']).optional(),
|
||||
temperature: z.number().optional(),
|
||||
system_prompt: z.string().optional(),
|
||||
user_prompt: z.string().optional(),
|
||||
@ -20,7 +20,7 @@ export const advancedSettingsFormSchema = {
|
||||
export const defaultAdvancedSettingsForm = {
|
||||
permissions: 'me',
|
||||
storage_type: 'table',
|
||||
forgetting_policy: 'fifo',
|
||||
forgetting_policy: 'FIFO',
|
||||
temperature: 0.7,
|
||||
system_prompt: '',
|
||||
user_prompt: '',
|
||||
@ -80,8 +80,8 @@ export const AdvancedSettingsForm = () => {
|
||||
horizontal: true,
|
||||
placeholder: t('memory.config.storageTypePlaceholder'),
|
||||
options: [
|
||||
{ label: 'table', value: 'table' },
|
||||
// { label: 'graph', value: 'graph' },
|
||||
{ label: 'Table', value: 'table' },
|
||||
// { label: 'Graph', value: 'graph' },
|
||||
],
|
||||
required: false,
|
||||
}}
|
||||
@ -94,8 +94,8 @@ export const AdvancedSettingsForm = () => {
|
||||
horizontal: true,
|
||||
// placeholder: t('memory.config.storageTypePlaceholder'),
|
||||
options: [
|
||||
// { label: 'lru', value: 'lru' },
|
||||
{ label: 'fifo', value: 'fifo' },
|
||||
// { label: 'LRU', value: 'LRU' },
|
||||
{ label: 'FIFO', value: 'fifo' },
|
||||
],
|
||||
required: false,
|
||||
}}
|
||||
@ -146,7 +146,7 @@ export const AdvancedSettingsForm = () => {
|
||||
field={{
|
||||
name: 'user_prompt',
|
||||
label: t('memory.config.userPrompt'),
|
||||
type: FormFieldType.Text,
|
||||
type: FormFieldType.Textarea,
|
||||
horizontal: true,
|
||||
placeholder: t('memory.config.userPromptPlaceholder'),
|
||||
required: false,
|
||||
|
||||
@ -15,9 +15,9 @@ export const useUpdateMemoryConfig = () => {
|
||||
try {
|
||||
const params = omit(data, [
|
||||
'id',
|
||||
'memory_type',
|
||||
'embd_id',
|
||||
'storage_type',
|
||||
// 'memory_type',
|
||||
// 'embd_id',
|
||||
// 'storage_type',
|
||||
]);
|
||||
res = await updateMemory({
|
||||
// ...memoryDataTemp,
|
||||
|
||||
@ -6,9 +6,9 @@ import { MainContainer } from '@/pages/dataset/dataset-setting/configuration-for
|
||||
import { TopTitle } from '@/pages/dataset/dataset-title';
|
||||
import { IMemory } from '@/pages/memories/interface';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { t } from 'i18next';
|
||||
import { useEffect } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { z } from 'zod';
|
||||
import { useFetchMemoryBaseConfiguration } from '../hooks/use-memory-setting';
|
||||
import {
|
||||
@ -24,14 +24,15 @@ import {
|
||||
memoryModelFormSchema,
|
||||
} from './memory-model-form';
|
||||
|
||||
const MemoryMessageSchema = z.object({
|
||||
id: z.string(),
|
||||
...basicInfoSchema,
|
||||
...memoryModelFormSchema,
|
||||
...advancedSettingsFormSchema,
|
||||
});
|
||||
// type MemoryMessageForm = z.infer<typeof MemoryMessageSchema>;
|
||||
export default function MemoryMessage() {
|
||||
const { t } = useTranslation();
|
||||
const MemoryMessageSchema = z.object({
|
||||
id: z.string(),
|
||||
...basicInfoSchema,
|
||||
...memoryModelFormSchema(t),
|
||||
...advancedSettingsFormSchema,
|
||||
});
|
||||
const form = useForm<IMemory>({
|
||||
resolver: zodResolver(MemoryMessageSchema),
|
||||
defaultValues: {
|
||||
@ -57,12 +58,13 @@ export default function MemoryMessage() {
|
||||
temperature: data?.temperature,
|
||||
system_prompt: data?.system_prompt || '',
|
||||
user_prompt: data?.user_prompt || '',
|
||||
forgetting_policy: data?.forgetting_policy || 'fifo',
|
||||
storage_type: data?.storage_type || 'table',
|
||||
forgetting_policy: data?.forgetting_policy || 'FIFO',
|
||||
storage_type: data?.storage_type || 'Table',
|
||||
permissions: data?.permissions || 'me',
|
||||
});
|
||||
}, [data, form]);
|
||||
const onSubmit = (data: IMemory) => {
|
||||
console.log('data', data);
|
||||
onMemoryRenameOk(data);
|
||||
};
|
||||
return (
|
||||
@ -74,7 +76,7 @@ export default function MemoryMessage() {
|
||||
<div className="flex gap-14 flex-1 min-h-0">
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(() => {})} className="space-y-6 ">
|
||||
<div className="w-[768px] h-[calc(100vh-300px)] pr-1 overflow-y-auto scrollbar-auto">
|
||||
<div className="w-[768px] h-[calc(100vh-300px)] pr-1 overflow-y-auto scrollbar-auto pb-4">
|
||||
<MainContainer className="text-text-secondary !space-y-10">
|
||||
<div className="text-base font-medium text-text-primary">
|
||||
{t('knowledgeConfiguration.baseInfo')}
|
||||
|
||||
@ -1,25 +1,36 @@
|
||||
import { FormFieldType, RenderField } from '@/components/dynamic-form';
|
||||
import { useModelOptions } from '@/components/llm-setting-items/llm-form-field';
|
||||
import { EmbeddingSelect } from '@/pages/dataset/dataset-setting/configuration/common-item';
|
||||
import { MemoryType } from '@/pages/memories/constants';
|
||||
import { MemoryOptions, MemoryType } from '@/pages/memories/constants';
|
||||
import { TFunction } from 'i18next';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { z } from 'zod';
|
||||
import { useFetchMemoryMessageList } from '../memory-message/hook';
|
||||
|
||||
export const memoryModelFormSchema = {
|
||||
export const memoryModelFormSchema = (t: TFunction) => ({
|
||||
embd_id: z.string(),
|
||||
llm_id: z.string(),
|
||||
memory_type: z.array(z.string()).optional(),
|
||||
memory_type: z.array(z.string()).superRefine((data, ctx) => {
|
||||
if (!data.includes(MemoryType.Raw) || !data.length) {
|
||||
ctx.addIssue({
|
||||
// path: ['memory_type'],
|
||||
message: t('memories.embeddingModelError'),
|
||||
code: 'custom',
|
||||
});
|
||||
}
|
||||
}),
|
||||
memory_size: z.number().optional(),
|
||||
};
|
||||
});
|
||||
export const defaultMemoryModelForm = {
|
||||
embd_id: '',
|
||||
llm_id: '',
|
||||
memory_type: [MemoryType.Raw],
|
||||
memory_type: [],
|
||||
memory_size: 0,
|
||||
};
|
||||
export const MemoryModelForm = () => {
|
||||
const { modelOptions } = useModelOptions();
|
||||
const { t } = useTranslation();
|
||||
const { data } = useFetchMemoryMessageList();
|
||||
return (
|
||||
<>
|
||||
<RenderField
|
||||
@ -33,7 +44,11 @@ export const MemoryModelForm = () => {
|
||||
type: FormFieldType.Custom,
|
||||
disabled: true,
|
||||
render: (field) => (
|
||||
<EmbeddingSelect field={field} isEdit={false} disabled={true} />
|
||||
<EmbeddingSelect
|
||||
field={field}
|
||||
isEdit={false}
|
||||
disabled={data?.messages?.total_count > 0}
|
||||
/>
|
||||
),
|
||||
|
||||
tooltip: t('memories.embeddingModelTooltip'),
|
||||
@ -47,6 +62,7 @@ export const MemoryModelForm = () => {
|
||||
required: true,
|
||||
horizontal: true,
|
||||
type: FormFieldType.Select,
|
||||
disabled: data?.messages?.total_count > 0,
|
||||
options: modelOptions as { value: string; label: string }[],
|
||||
tooltip: t('memories.llmTooltip'),
|
||||
}}
|
||||
@ -59,13 +75,14 @@ export const MemoryModelForm = () => {
|
||||
horizontal: true,
|
||||
placeholder: t('memories.memoryTypePlaceholder'),
|
||||
tooltip: t('memories.memoryTypeTooltip'),
|
||||
disabled: true,
|
||||
options: [
|
||||
{ label: 'Raw', value: 'raw' },
|
||||
{ label: 'Semantic', value: 'semantic' },
|
||||
{ label: 'Episodic', value: 'episodic' },
|
||||
{ label: 'Procedural', value: 'procedural' },
|
||||
],
|
||||
disabled: data?.messages?.total_count > 0,
|
||||
options: MemoryOptions(t),
|
||||
customValidate: (value) => {
|
||||
if (!value.includes(MemoryType.Raw) || !value.length) {
|
||||
return t('memories.embeddingModelError');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
required: true,
|
||||
}}
|
||||
/>
|
||||
|
||||
@ -42,7 +42,7 @@ const AddDataSourceModal = ({
|
||||
title={
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="size-6">{sourceData?.icon}</div>
|
||||
{t('setting.addDataSourceModalTital', { name: sourceData?.name })}
|
||||
{t('setting.addDataSourceModalTitle', { name: sourceData?.name })}
|
||||
</div>
|
||||
}
|
||||
open={visible || false}
|
||||
|
||||
@ -34,7 +34,7 @@ const methods = {
|
||||
} as const;
|
||||
const memoryService = registerNextServer<keyof typeof methods>(methods);
|
||||
export const updateMemoryById = (id: string, data: any) => {
|
||||
return request.put(updateMemorySetting(id), { data });
|
||||
return request.put(updateMemorySetting(id), { ...data });
|
||||
};
|
||||
export const getMemoryDetailById = (id: string, data: any) => {
|
||||
return request.get(getMemoryDetail(id), { params: data });
|
||||
|
||||
@ -239,7 +239,7 @@ export default {
|
||||
createMemory: `${api_host}/memories`,
|
||||
getMemoryList: `${api_host}/memories`,
|
||||
getMemoryConfig: (id: string) => `${api_host}/memories/${id}/config`,
|
||||
deleteMemory: (id: string) => `${api_host}/memory/rm/${id}`,
|
||||
deleteMemory: (id: string) => `${api_host}/memories/${id}`,
|
||||
getMemoryDetail: (id: string) => `${api_host}/memories/${id}`,
|
||||
updateMemorySetting: (id: string) => `${api_host}/memories/${id}`,
|
||||
deleteMemoryMessage: (data: { memory_id: string; message_id: string }) =>
|
||||
|
||||
Reference in New Issue
Block a user