mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-02-05 18:15:06 +08:00
Compare commits
4 Commits
1c38f4cefb
...
e8cb1d8fc4
| Author | SHA1 | Date | |
|---|---|---|---|
| e8cb1d8fc4 | |||
| 4e86ee4ff9 | |||
| c99034f717 | |||
| 86b254d214 |
@ -52,9 +52,16 @@ It consists of a server-side Service and a command-line client (CLI), both imple
|
|||||||
```
|
```
|
||||||
3. Launch the CLI client:
|
3. Launch the CLI client:
|
||||||
```bash
|
```bash
|
||||||
ragflow-cli -h 0.0.0.0 -p 9381
|
ragflow-cli -h 127.0.0.1 -p 9381
|
||||||
```
|
```
|
||||||
Enter superuser's password to login. Default password is `admin`.
|
You will be prompted to enter the superuser's password to log in.
|
||||||
|
The default password is admin.
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
- -h: RAGFlow admin server host address
|
||||||
|
|
||||||
|
- -p: RAGFlow admin server port
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License
|
# limitations under the License
|
||||||
#
|
#
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
import re
|
import re
|
||||||
@ -234,54 +235,63 @@ def get_all_parent_folders():
|
|||||||
return server_error_response(e)
|
return server_error_response(e)
|
||||||
|
|
||||||
|
|
||||||
@manager.route('/rm', methods=['POST']) # noqa: F821
|
@manager.route("/rm", methods=["POST"]) # noqa: F821
|
||||||
@login_required
|
@login_required
|
||||||
@validate_request("file_ids")
|
@validate_request("file_ids")
|
||||||
def rm():
|
def rm():
|
||||||
req = request.json
|
req = request.json
|
||||||
file_ids = req["file_ids"]
|
file_ids = req["file_ids"]
|
||||||
|
|
||||||
|
def _delete_single_file(file):
|
||||||
|
try:
|
||||||
|
if file.location:
|
||||||
|
STORAGE_IMPL.rm(file.parent_id, file.location)
|
||||||
|
except Exception:
|
||||||
|
logging.exception(f"Fail to remove object: {file.parent_id}/{file.location}")
|
||||||
|
|
||||||
|
informs = File2DocumentService.get_by_file_id(file.id)
|
||||||
|
for inform in informs:
|
||||||
|
doc_id = inform.document_id
|
||||||
|
e, doc = DocumentService.get_by_id(doc_id)
|
||||||
|
if e and doc:
|
||||||
|
tenant_id = DocumentService.get_tenant_id(doc_id)
|
||||||
|
if tenant_id:
|
||||||
|
DocumentService.remove_document(doc, tenant_id)
|
||||||
|
File2DocumentService.delete_by_file_id(file.id)
|
||||||
|
|
||||||
|
FileService.delete(file)
|
||||||
|
|
||||||
|
def _delete_folder_recursive(folder, tenant_id):
|
||||||
|
sub_files = FileService.list_all_files_by_parent_id(folder.id)
|
||||||
|
for sub_file in sub_files:
|
||||||
|
if sub_file.type == FileType.FOLDER.value:
|
||||||
|
_delete_folder_recursive(sub_file, tenant_id)
|
||||||
|
else:
|
||||||
|
_delete_single_file(sub_file)
|
||||||
|
|
||||||
|
FileService.delete(folder)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
for file_id in file_ids:
|
for file_id in file_ids:
|
||||||
e, file = FileService.get_by_id(file_id)
|
e, file = FileService.get_by_id(file_id)
|
||||||
if not e:
|
if not e or not file:
|
||||||
return get_data_error_result(message="File or Folder not found!")
|
return get_data_error_result(message="File or Folder not found!")
|
||||||
if not file.tenant_id:
|
if not file.tenant_id:
|
||||||
return get_data_error_result(message="Tenant not found!")
|
return get_data_error_result(message="Tenant not found!")
|
||||||
if not check_file_team_permission(file, current_user.id):
|
if not check_file_team_permission(file, current_user.id):
|
||||||
return get_json_result(data=False, message='No authorization.', code=settings.RetCode.AUTHENTICATION_ERROR)
|
return get_json_result(data=False, message="No authorization.", code=settings.RetCode.AUTHENTICATION_ERROR)
|
||||||
|
|
||||||
if file.source_type == FileSource.KNOWLEDGEBASE:
|
if file.source_type == FileSource.KNOWLEDGEBASE:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if file.type == FileType.FOLDER.value:
|
if file.type == FileType.FOLDER.value:
|
||||||
file_id_list = FileService.get_all_innermost_file_ids(file_id, [])
|
_delete_folder_recursive(file, current_user.id)
|
||||||
for inner_file_id in file_id_list:
|
continue
|
||||||
e, file = FileService.get_by_id(inner_file_id)
|
|
||||||
if not e:
|
|
||||||
return get_data_error_result(message="File not found!")
|
|
||||||
STORAGE_IMPL.rm(file.parent_id, file.location)
|
|
||||||
FileService.delete_folder_by_pf_id(current_user.id, file_id)
|
|
||||||
else:
|
|
||||||
STORAGE_IMPL.rm(file.parent_id, file.location)
|
|
||||||
if not FileService.delete(file):
|
|
||||||
return get_data_error_result(
|
|
||||||
message="Database error (File removal)!")
|
|
||||||
|
|
||||||
# delete file2document
|
_delete_single_file(file)
|
||||||
informs = File2DocumentService.get_by_file_id(file_id)
|
|
||||||
for inform in informs:
|
|
||||||
doc_id = inform.document_id
|
|
||||||
e, doc = DocumentService.get_by_id(doc_id)
|
|
||||||
if not e:
|
|
||||||
return get_data_error_result(message="Document not found!")
|
|
||||||
tenant_id = DocumentService.get_tenant_id(doc_id)
|
|
||||||
if not tenant_id:
|
|
||||||
return get_data_error_result(message="Tenant not found!")
|
|
||||||
if not DocumentService.remove_document(doc, tenant_id):
|
|
||||||
return get_data_error_result(
|
|
||||||
message="Database error (Document removal)!")
|
|
||||||
File2DocumentService.delete_by_file_id(file_id)
|
|
||||||
|
|
||||||
return get_json_result(data=True)
|
return get_json_result(data=True)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return server_error_response(e)
|
return server_error_response(e)
|
||||||
|
|
||||||
@ -355,31 +365,89 @@ def get(file_id):
|
|||||||
return server_error_response(e)
|
return server_error_response(e)
|
||||||
|
|
||||||
|
|
||||||
@manager.route('/mv', methods=['POST']) # noqa: F821
|
@manager.route("/mv", methods=["POST"]) # noqa: F821
|
||||||
@login_required
|
@login_required
|
||||||
@validate_request("src_file_ids", "dest_file_id")
|
@validate_request("src_file_ids", "dest_file_id")
|
||||||
def move():
|
def move():
|
||||||
req = request.json
|
req = request.json
|
||||||
try:
|
try:
|
||||||
file_ids = req["src_file_ids"]
|
file_ids = req["src_file_ids"]
|
||||||
parent_id = req["dest_file_id"]
|
dest_parent_id = req["dest_file_id"]
|
||||||
|
|
||||||
|
ok, dest_folder = FileService.get_by_id(dest_parent_id)
|
||||||
|
if not ok or not dest_folder:
|
||||||
|
return get_data_error_result(message="Parent Folder not found!")
|
||||||
|
|
||||||
files = FileService.get_by_ids(file_ids)
|
files = FileService.get_by_ids(file_ids)
|
||||||
files_dict = {}
|
if not files:
|
||||||
for file in files:
|
return get_data_error_result(message="Source files not found!")
|
||||||
files_dict[file.id] = file
|
|
||||||
|
files_dict = {f.id: f for f in files}
|
||||||
|
|
||||||
for file_id in file_ids:
|
for file_id in file_ids:
|
||||||
file = files_dict[file_id]
|
file = files_dict.get(file_id)
|
||||||
if not file:
|
if not file:
|
||||||
return get_data_error_result(message="File or Folder not found!")
|
return get_data_error_result(message="File or Folder not found!")
|
||||||
if not file.tenant_id:
|
if not file.tenant_id:
|
||||||
return get_data_error_result(message="Tenant not found!")
|
return get_data_error_result(message="Tenant not found!")
|
||||||
if not check_file_team_permission(file, current_user.id):
|
if not check_file_team_permission(file, current_user.id):
|
||||||
return get_json_result(data=False, message='No authorization.', code=settings.RetCode.AUTHENTICATION_ERROR)
|
return get_json_result(
|
||||||
fe, _ = FileService.get_by_id(parent_id)
|
data=False,
|
||||||
if not fe:
|
message="No authorization.",
|
||||||
return get_data_error_result(message="Parent Folder not found!")
|
code=settings.RetCode.AUTHENTICATION_ERROR,
|
||||||
FileService.move_file(file_ids, parent_id)
|
)
|
||||||
|
|
||||||
|
def _move_entry_recursive(source_file_entry, dest_folder):
|
||||||
|
if source_file_entry.type == FileType.FOLDER.value:
|
||||||
|
existing_folder = FileService.query(name=source_file_entry.name, parent_id=dest_folder.id)
|
||||||
|
if existing_folder:
|
||||||
|
new_folder = existing_folder[0]
|
||||||
|
else:
|
||||||
|
new_folder = FileService.insert(
|
||||||
|
{
|
||||||
|
"id": get_uuid(),
|
||||||
|
"parent_id": dest_folder.id,
|
||||||
|
"tenant_id": source_file_entry.tenant_id,
|
||||||
|
"created_by": current_user.id,
|
||||||
|
"name": source_file_entry.name,
|
||||||
|
"location": "",
|
||||||
|
"size": 0,
|
||||||
|
"type": FileType.FOLDER.value,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
sub_files = FileService.list_all_files_by_parent_id(source_file_entry.id)
|
||||||
|
for sub_file in sub_files:
|
||||||
|
_move_entry_recursive(sub_file, new_folder)
|
||||||
|
|
||||||
|
FileService.delete_by_id(source_file_entry.id)
|
||||||
|
return
|
||||||
|
|
||||||
|
old_parent_id = source_file_entry.parent_id
|
||||||
|
old_location = source_file_entry.location
|
||||||
|
filename = source_file_entry.name
|
||||||
|
|
||||||
|
new_location = filename
|
||||||
|
while STORAGE_IMPL.obj_exist(dest_folder.id, new_location):
|
||||||
|
new_location += "_"
|
||||||
|
|
||||||
|
try:
|
||||||
|
STORAGE_IMPL.move(old_parent_id, old_location, dest_folder.id, new_location)
|
||||||
|
except Exception as storage_err:
|
||||||
|
raise RuntimeError(f"Move file failed at storage layer: {str(storage_err)}")
|
||||||
|
|
||||||
|
FileService.update_by_id(
|
||||||
|
source_file_entry.id,
|
||||||
|
{
|
||||||
|
"parent_id": dest_folder.id,
|
||||||
|
"location": new_location,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
_move_entry_recursive(file, dest_folder)
|
||||||
|
|
||||||
return get_json_result(data=True)
|
return get_json_result(data=True)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return server_error_response(e)
|
return server_error_response(e)
|
||||||
|
|||||||
@ -194,6 +194,9 @@ def add_llm():
|
|||||||
elif factory == "Azure-OpenAI":
|
elif factory == "Azure-OpenAI":
|
||||||
api_key = apikey_json(["api_key", "api_version"])
|
api_key = apikey_json(["api_key", "api_version"])
|
||||||
|
|
||||||
|
elif factory == "OpenRouter":
|
||||||
|
api_key = apikey_json(["api_key", "provider_order"])
|
||||||
|
|
||||||
llm = {
|
llm = {
|
||||||
"tenant_id": current_user.id,
|
"tenant_id": current_user.id,
|
||||||
"llm_factory": factory,
|
"llm_factory": factory,
|
||||||
|
|||||||
@ -476,6 +476,16 @@ class FileService(CommonService):
|
|||||||
|
|
||||||
return err, files
|
return err, files
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
@DB.connection_context()
|
||||||
|
def list_all_files_by_parent_id(cls, parent_id):
|
||||||
|
try:
|
||||||
|
files = cls.model.select().where((cls.model.parent_id == parent_id) & (cls.model.id != parent_id))
|
||||||
|
return list(files)
|
||||||
|
except Exception:
|
||||||
|
logging.exception("list_by_parent_id failed")
|
||||||
|
raise RuntimeError("Database error (list_by_parent_id)!")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def parse_docs(file_objs, user_id):
|
def parse_docs(file_objs, user_id):
|
||||||
exe = ThreadPoolExecutor(max_workers=12)
|
exe = ThreadPoolExecutor(max_workers=12)
|
||||||
|
|||||||
@ -52,10 +52,17 @@ The Admin CLI and Admin Service form a client-server architectural suite for RAG
|
|||||||
3. Launch the CLI client:
|
3. Launch the CLI client:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ragflow-cli -h 0.0.0.0 -p 9381
|
ragflow-cli -h 127.0.0.1 -p 9381
|
||||||
```
|
```
|
||||||
|
|
||||||
Enter superuser's password to login. Default password is `admin`.
|
You will be prompted to enter the superuser's password to log in.
|
||||||
|
The default password is admin.
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
- -h: RAGFlow admin server host address
|
||||||
|
|
||||||
|
- -p: RAGFlow admin server port
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1425,6 +1425,9 @@ class LiteLLMBase(ABC):
|
|||||||
self.bedrock_ak = json.loads(key).get("bedrock_ak", "")
|
self.bedrock_ak = json.loads(key).get("bedrock_ak", "")
|
||||||
self.bedrock_sk = json.loads(key).get("bedrock_sk", "")
|
self.bedrock_sk = json.loads(key).get("bedrock_sk", "")
|
||||||
self.bedrock_region = json.loads(key).get("bedrock_region", "")
|
self.bedrock_region = json.loads(key).get("bedrock_region", "")
|
||||||
|
elif self.provider == SupportedLiteLLMProvider.OpenRouter:
|
||||||
|
self.api_key = json.loads(key).get("api_key", "")
|
||||||
|
self.provider_order = json.loads(key).get("provider_order", "")
|
||||||
|
|
||||||
def _get_delay(self):
|
def _get_delay(self):
|
||||||
"""Calculate retry delay time"""
|
"""Calculate retry delay time"""
|
||||||
@ -1469,7 +1472,6 @@ class LiteLLMBase(ABC):
|
|||||||
timeout=self.timeout,
|
timeout=self.timeout,
|
||||||
)
|
)
|
||||||
# response = self.client.chat.completions.create(model=self.model_name, messages=history, **gen_conf, **kwargs)
|
# response = self.client.chat.completions.create(model=self.model_name, messages=history, **gen_conf, **kwargs)
|
||||||
|
|
||||||
if any([not response.choices, not response.choices[0].message, not response.choices[0].message.content]):
|
if any([not response.choices, not response.choices[0].message, not response.choices[0].message.content]):
|
||||||
return "", 0
|
return "", 0
|
||||||
ans = response.choices[0].message.content.strip()
|
ans = response.choices[0].message.content.strip()
|
||||||
@ -1620,6 +1622,24 @@ class LiteLLMBase(ABC):
|
|||||||
"aws_region_name": self.bedrock_region,
|
"aws_region_name": self.bedrock_region,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if self.provider == SupportedLiteLLMProvider.OpenRouter:
|
||||||
|
if self.provider_order:
|
||||||
|
def _to_order_list(x):
|
||||||
|
if x is None:
|
||||||
|
return []
|
||||||
|
if isinstance(x, str):
|
||||||
|
return [s.strip() for s in x.split(",") if s.strip()]
|
||||||
|
if isinstance(x, (list, tuple)):
|
||||||
|
return [str(s).strip() for s in x if str(s).strip()]
|
||||||
|
return []
|
||||||
|
extra_body = {}
|
||||||
|
provider_cfg = {}
|
||||||
|
provider_order = _to_order_list(self.provider_order)
|
||||||
|
provider_cfg["order"] = provider_order
|
||||||
|
provider_cfg["allow_fallbacks"] = False
|
||||||
|
extra_body["provider"] = provider_cfg
|
||||||
|
completion_args.update({"extra_body": extra_body})
|
||||||
return completion_args
|
return completion_args
|
||||||
|
|
||||||
def chat_with_tools(self, system: str, history: list, gen_conf: dict = {}):
|
def chat_with_tools(self, system: str, history: list, gen_conf: dict = {}):
|
||||||
|
|||||||
@ -38,6 +38,7 @@ class Base(ABC):
|
|||||||
self.is_tools = False
|
self.is_tools = False
|
||||||
self.tools = []
|
self.tools = []
|
||||||
self.toolcall_sessions = {}
|
self.toolcall_sessions = {}
|
||||||
|
self.extra_body = None
|
||||||
|
|
||||||
def describe(self, image):
|
def describe(self, image):
|
||||||
raise NotImplementedError("Please implement encode method!")
|
raise NotImplementedError("Please implement encode method!")
|
||||||
@ -77,7 +78,8 @@ class Base(ABC):
|
|||||||
try:
|
try:
|
||||||
response = self.client.chat.completions.create(
|
response = self.client.chat.completions.create(
|
||||||
model=self.model_name,
|
model=self.model_name,
|
||||||
messages=self._form_history(system, history, images)
|
messages=self._form_history(system, history, images),
|
||||||
|
extra_body=self.extra_body,
|
||||||
)
|
)
|
||||||
return response.choices[0].message.content.strip(), response.usage.total_tokens
|
return response.choices[0].message.content.strip(), response.usage.total_tokens
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -90,7 +92,8 @@ class Base(ABC):
|
|||||||
response = self.client.chat.completions.create(
|
response = self.client.chat.completions.create(
|
||||||
model=self.model_name,
|
model=self.model_name,
|
||||||
messages=self._form_history(system, history, images),
|
messages=self._form_history(system, history, images),
|
||||||
stream=True
|
stream=True,
|
||||||
|
extra_body=self.extra_body,
|
||||||
)
|
)
|
||||||
for resp in response:
|
for resp in response:
|
||||||
if not resp.choices[0].delta.content:
|
if not resp.choices[0].delta.content:
|
||||||
@ -177,6 +180,7 @@ class GptV4(Base):
|
|||||||
res = self.client.chat.completions.create(
|
res = self.client.chat.completions.create(
|
||||||
model=self.model_name,
|
model=self.model_name,
|
||||||
messages=self.prompt(b64),
|
messages=self.prompt(b64),
|
||||||
|
extra_body=self.extra_body,
|
||||||
)
|
)
|
||||||
return res.choices[0].message.content.strip(), total_token_count_from_response(res)
|
return res.choices[0].message.content.strip(), total_token_count_from_response(res)
|
||||||
|
|
||||||
@ -185,6 +189,7 @@ class GptV4(Base):
|
|||||||
res = self.client.chat.completions.create(
|
res = self.client.chat.completions.create(
|
||||||
model=self.model_name,
|
model=self.model_name,
|
||||||
messages=self.vision_llm_prompt(b64, prompt),
|
messages=self.vision_llm_prompt(b64, prompt),
|
||||||
|
extra_body=self.extra_body,
|
||||||
)
|
)
|
||||||
return res.choices[0].message.content.strip(),total_token_count_from_response(res)
|
return res.choices[0].message.content.strip(),total_token_count_from_response(res)
|
||||||
|
|
||||||
@ -327,10 +332,27 @@ class OpenRouterCV(GptV4):
|
|||||||
):
|
):
|
||||||
if not base_url:
|
if not base_url:
|
||||||
base_url = "https://openrouter.ai/api/v1"
|
base_url = "https://openrouter.ai/api/v1"
|
||||||
self.client = OpenAI(api_key=key, base_url=base_url)
|
api_key = json.loads(key).get("api_key", "")
|
||||||
|
self.client = OpenAI(api_key=api_key, base_url=base_url)
|
||||||
self.model_name = model_name
|
self.model_name = model_name
|
||||||
self.lang = lang
|
self.lang = lang
|
||||||
Base.__init__(self, **kwargs)
|
Base.__init__(self, **kwargs)
|
||||||
|
provider_order = json.loads(key).get("provider_order", "")
|
||||||
|
self.extra_body = {}
|
||||||
|
if provider_order:
|
||||||
|
def _to_order_list(x):
|
||||||
|
if x is None:
|
||||||
|
return []
|
||||||
|
if isinstance(x, str):
|
||||||
|
return [s.strip() for s in x.split(",") if s.strip()]
|
||||||
|
if isinstance(x, (list, tuple)):
|
||||||
|
return [str(s).strip() for s in x if str(s).strip()]
|
||||||
|
return []
|
||||||
|
provider_cfg = {}
|
||||||
|
provider_order = _to_order_list(provider_order)
|
||||||
|
provider_cfg["order"] = provider_order
|
||||||
|
provider_cfg["allow_fallbacks"] = False
|
||||||
|
self.extra_body["provider"] = provider_cfg
|
||||||
|
|
||||||
|
|
||||||
class LocalAICV(GptV4):
|
class LocalAICV(GptV4):
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
from minio import Minio
|
from minio import Minio
|
||||||
|
from minio.commonconfig import CopySource
|
||||||
from minio.error import S3Error
|
from minio.error import S3Error
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from rag import settings
|
from rag import settings
|
||||||
@ -141,3 +142,36 @@ class RAGFlowMinio:
|
|||||||
except Exception:
|
except Exception:
|
||||||
logging.exception(f"Fail to remove bucket {bucket}")
|
logging.exception(f"Fail to remove bucket {bucket}")
|
||||||
|
|
||||||
|
def copy(self, src_bucket, src_path, dest_bucket, dest_path):
|
||||||
|
try:
|
||||||
|
if not self.conn.bucket_exists(dest_bucket):
|
||||||
|
self.conn.make_bucket(dest_bucket)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.conn.stat_object(src_bucket, src_path)
|
||||||
|
except Exception as e:
|
||||||
|
logging.exception(f"Source object not found: {src_bucket}/{src_path}, {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
self.conn.copy_object(
|
||||||
|
dest_bucket,
|
||||||
|
dest_path,
|
||||||
|
CopySource(src_bucket, src_path),
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
logging.exception(f"Fail to copy {src_bucket}/{src_path} -> {dest_bucket}/{dest_path}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def move(self, src_bucket, src_path, dest_bucket, dest_path):
|
||||||
|
try:
|
||||||
|
if self.copy(src_bucket, src_path, dest_bucket, dest_path):
|
||||||
|
self.rm(src_bucket, src_path)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logging.error(f"Copy failed, move aborted: {src_bucket}/{src_path}")
|
||||||
|
return False
|
||||||
|
except Exception:
|
||||||
|
logging.exception(f"Fail to move {src_bucket}/{src_path} -> {dest_bucket}/{dest_path}")
|
||||||
|
return False
|
||||||
|
|||||||
143
web/package-lock.json
generated
143
web/package-lock.json
generated
@ -49,7 +49,7 @@
|
|||||||
"@xyflow/react": "^12.3.6",
|
"@xyflow/react": "^12.3.6",
|
||||||
"ahooks": "^3.7.10",
|
"ahooks": "^3.7.10",
|
||||||
"antd": "^5.12.7",
|
"antd": "^5.12.7",
|
||||||
"axios": "^1.6.3",
|
"axios": "^1.12.0",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"classnames": "^2.5.1",
|
"classnames": "^2.5.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
@ -13551,12 +13551,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "1.7.2",
|
"version": "1.12.0",
|
||||||
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.7.2.tgz",
|
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.12.0.tgz",
|
||||||
"integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
|
"integrity": "sha512-oXTDccv8PcfjZmPGlWsPSwtOJCZ/b6W5jAMCNcfwJbCzDckwG0jrYJFaWH1yvivfCXjVzV/SPDEhMB3Q+DSurg==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"follow-redirects": "^1.15.6",
|
"follow-redirects": "^1.15.6",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.4",
|
||||||
"proxy-from-env": "^1.1.0"
|
"proxy-from-env": "^1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -14181,6 +14182,19 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/call-bind-apply-helpers": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"function-bind": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/call-me-maybe": {
|
"node_modules/call-me-maybe": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmmirror.com/call-me-maybe/-/call-me-maybe-1.0.2.tgz",
|
"resolved": "https://registry.npmmirror.com/call-me-maybe/-/call-me-maybe-1.0.2.tgz",
|
||||||
@ -16795,6 +16809,20 @@
|
|||||||
"underscore": "^1.13.1"
|
"underscore": "^1.13.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dunder-proto": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind-apply-helpers": "^1.0.1",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"gopd": "^1.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/duplexer": {
|
"node_modules/duplexer": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmmirror.com/duplexer/-/duplexer-0.1.2.tgz",
|
"resolved": "https://registry.npmmirror.com/duplexer/-/duplexer-0.1.2.tgz",
|
||||||
@ -17364,12 +17392,10 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/es-define-property": {
|
"node_modules/es-define-property": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||||
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
|
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||||
"dependencies": {
|
"license": "MIT",
|
||||||
"get-intrinsic": "^1.2.4"
|
|
||||||
},
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
@ -17426,9 +17452,10 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/es-object-atoms": {
|
"node_modules/es-object-atoms": {
|
||||||
"version": "1.0.0",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
||||||
"integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==",
|
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"es-errors": "^1.3.0"
|
"es-errors": "^1.3.0"
|
||||||
},
|
},
|
||||||
@ -17437,13 +17464,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/es-set-tostringtag": {
|
"node_modules/es-set-tostringtag": {
|
||||||
"version": "2.0.3",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz",
|
"resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
|
||||||
"integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==",
|
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"get-intrinsic": "^1.2.4",
|
"es-errors": "^1.3.0",
|
||||||
|
"get-intrinsic": "^1.2.6",
|
||||||
"has-tostringtag": "^1.0.2",
|
"has-tostringtag": "^1.0.2",
|
||||||
"hasown": "^2.0.1"
|
"hasown": "^2.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
@ -19233,12 +19262,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/form-data": {
|
"node_modules/form-data": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.4",
|
||||||
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.4.tgz",
|
||||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"asynckit": "^0.4.0",
|
"asynckit": "^0.4.0",
|
||||||
"combined-stream": "^1.0.8",
|
"combined-stream": "^1.0.8",
|
||||||
|
"es-set-tostringtag": "^2.1.0",
|
||||||
|
"hasown": "^2.0.2",
|
||||||
"mime-types": "^2.1.12"
|
"mime-types": "^2.1.12"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -19398,18 +19430,27 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/get-intrinsic": {
|
"node_modules/get-intrinsic": {
|
||||||
"version": "1.2.4",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"call-bind-apply-helpers": "^1.0.2",
|
||||||
|
"es-define-property": "^1.0.1",
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
|
"es-object-atoms": "^1.1.1",
|
||||||
"function-bind": "^1.1.2",
|
"function-bind": "^1.1.2",
|
||||||
"has-proto": "^1.0.1",
|
"get-proto": "^1.0.1",
|
||||||
"has-symbols": "^1.0.3",
|
"gopd": "^1.2.0",
|
||||||
"hasown": "^2.0.0"
|
"has-symbols": "^1.1.0",
|
||||||
|
"hasown": "^2.0.2",
|
||||||
|
"math-intrinsics": "^1.1.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/get-nonce": {
|
"node_modules/get-nonce": {
|
||||||
@ -19428,6 +19469,19 @@
|
|||||||
"node": ">=8.0.0"
|
"node": ">=8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/get-proto": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"dunder-proto": "^1.0.1",
|
||||||
|
"es-object-atoms": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/get-stdin": {
|
"node_modules/get-stdin": {
|
||||||
"version": "9.0.0",
|
"version": "9.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/get-stdin/-/get-stdin-9.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/get-stdin/-/get-stdin-9.0.0.tgz",
|
||||||
@ -19609,11 +19663,15 @@
|
|||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/gopd": {
|
"node_modules/gopd": {
|
||||||
"version": "1.0.1",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.0.1.tgz",
|
"resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
|
||||||
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
|
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||||
"dependencies": {
|
"license": "MIT",
|
||||||
"get-intrinsic": "^1.1.3"
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/graceful-fs": {
|
"node_modules/graceful-fs": {
|
||||||
@ -19746,11 +19804,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/has-symbols": {
|
"node_modules/has-symbols": {
|
||||||
"version": "1.0.3",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz",
|
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
|
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/has-tostringtag": {
|
"node_modules/has-tostringtag": {
|
||||||
@ -25234,6 +25296,15 @@
|
|||||||
"resolved": "https://registry.npmmirror.com/markdown-table/-/markdown-table-3.0.3.tgz",
|
"resolved": "https://registry.npmmirror.com/markdown-table/-/markdown-table-3.0.3.tgz",
|
||||||
"integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw=="
|
"integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/math-intrinsics": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/mathml-tag-names": {
|
"node_modules/mathml-tag-names": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmmirror.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz",
|
"resolved": "https://registry.npmmirror.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz",
|
||||||
|
|||||||
@ -62,7 +62,7 @@
|
|||||||
"@xyflow/react": "^12.3.6",
|
"@xyflow/react": "^12.3.6",
|
||||||
"ahooks": "^3.7.10",
|
"ahooks": "^3.7.10",
|
||||||
"antd": "^5.12.7",
|
"antd": "^5.12.7",
|
||||||
"axios": "^1.6.3",
|
"axios": "^1.12.0",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"classnames": "^2.5.1",
|
"classnames": "^2.5.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
|||||||
@ -15,7 +15,10 @@ import {
|
|||||||
import omit from 'lodash/omit';
|
import omit from 'lodash/omit';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
type FieldType = IAddLlmRequestBody & { vision: boolean };
|
type FieldType = IAddLlmRequestBody & {
|
||||||
|
vision: boolean;
|
||||||
|
provider_order?: string;
|
||||||
|
};
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
@ -128,6 +131,10 @@ const OllamaModal = ({
|
|||||||
{ value: 'speech2text', label: 'sequence2text' },
|
{ value: 'speech2text', label: 'sequence2text' },
|
||||||
{ value: 'tts', label: 'tts' },
|
{ value: 'tts', label: 'tts' },
|
||||||
],
|
],
|
||||||
|
[LLMFactory.OpenRouter]: [
|
||||||
|
{ value: 'chat', label: 'chat' },
|
||||||
|
{ value: 'image2text', label: 'image2text' },
|
||||||
|
],
|
||||||
Default: [
|
Default: [
|
||||||
{ value: 'chat', label: 'chat' },
|
{ value: 'chat', label: 'chat' },
|
||||||
{ value: 'embedding', label: 'embedding' },
|
{ value: 'embedding', label: 'embedding' },
|
||||||
@ -233,6 +240,16 @@ const OllamaModal = ({
|
|||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
{llmFactory === LLMFactory.OpenRouter && (
|
||||||
|
<Form.Item<FieldType>
|
||||||
|
label="Provider Order"
|
||||||
|
name="provider_order"
|
||||||
|
tooltip="Comma-separated provider list, e.g. Groq,Fireworks"
|
||||||
|
rules={[]}
|
||||||
|
>
|
||||||
|
<Input placeholder="Groq,Fireworks" onKeyDown={handleKeyDown} />
|
||||||
|
</Form.Item>
|
||||||
|
)}
|
||||||
|
|
||||||
<Form.Item noStyle dependencies={['model_type']}>
|
<Form.Item noStyle dependencies={['model_type']}>
|
||||||
{({ getFieldValue }) =>
|
{({ getFieldValue }) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user