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