mirror of
https://github.com/langgenius/dify.git
synced 2026-01-06 06:26:00 +00:00
Compare commits
1 Commits
0.15.5
...
fix/datase
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4fc91d526e |
5
.github/workflows/build-push.yml
vendored
5
.github/workflows/build-push.yml
vendored
@@ -5,8 +5,9 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- "main"
|
- "main"
|
||||||
- "deploy/dev"
|
- "deploy/dev"
|
||||||
tags:
|
- "fix/dataset-admin"
|
||||||
- "*"
|
release:
|
||||||
|
types: [published]
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: build-push-${{ github.head_ref || github.run_id }}
|
group: build-push-${{ github.head_ref || github.run_id }}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ class PackagingInfo(BaseSettings):
|
|||||||
|
|
||||||
CURRENT_VERSION: str = Field(
|
CURRENT_VERSION: str = Field(
|
||||||
description="Dify version",
|
description="Dify version",
|
||||||
default="0.15.5",
|
default="0.15.3",
|
||||||
)
|
)
|
||||||
|
|
||||||
COMMIT_SHA: str = Field(
|
COMMIT_SHA: str = Field(
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ class DatasetInitApi(Resource):
|
|||||||
@cloud_edition_billing_resource_check("vector_space")
|
@cloud_edition_billing_resource_check("vector_space")
|
||||||
def post(self):
|
def post(self):
|
||||||
# The role of the current user in the ta table must be admin, owner, or editor
|
# The role of the current user in the ta table must be admin, owner, or editor
|
||||||
if not current_user.is_editor:
|
if not current_user.is_dataset_editor:
|
||||||
raise Forbidden()
|
raise Forbidden()
|
||||||
|
|
||||||
parser = reqparse.RequestParser()
|
parser = reqparse.RequestParser()
|
||||||
@@ -684,7 +684,7 @@ class DocumentProcessingApi(DocumentResource):
|
|||||||
document = self.get_document(dataset_id, document_id)
|
document = self.get_document(dataset_id, document_id)
|
||||||
|
|
||||||
# The role of the current user in the ta table must be admin, owner, or editor
|
# The role of the current user in the ta table must be admin, owner, or editor
|
||||||
if not current_user.is_editor:
|
if not current_user.is_dataset_editor:
|
||||||
raise Forbidden()
|
raise Forbidden()
|
||||||
|
|
||||||
if action == "pause":
|
if action == "pause":
|
||||||
@@ -748,7 +748,7 @@ class DocumentMetadataApi(DocumentResource):
|
|||||||
doc_metadata = req_data.get("doc_metadata")
|
doc_metadata = req_data.get("doc_metadata")
|
||||||
|
|
||||||
# The role of the current user in the ta table must be admin, owner, or editor
|
# The role of the current user in the ta table must be admin, owner, or editor
|
||||||
if not current_user.is_editor:
|
if not current_user.is_dataset_editor:
|
||||||
raise Forbidden()
|
raise Forbidden()
|
||||||
|
|
||||||
if doc_type is None or doc_metadata is None:
|
if doc_type is None or doc_metadata is None:
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ class DatasetDocumentSegmentListApi(Resource):
|
|||||||
segment_ids = request.args.getlist("segment_id")
|
segment_ids = request.args.getlist("segment_id")
|
||||||
|
|
||||||
# The role of the current user in the ta table must be admin or owner
|
# The role of the current user in the ta table must be admin or owner
|
||||||
if not current_user.is_editor:
|
if not current_user.is_dataset_editor:
|
||||||
raise Forbidden()
|
raise Forbidden()
|
||||||
try:
|
try:
|
||||||
DatasetService.check_dataset_permission(dataset, current_user)
|
DatasetService.check_dataset_permission(dataset, current_user)
|
||||||
@@ -149,7 +149,7 @@ class DatasetDocumentSegmentApi(Resource):
|
|||||||
# check user's model setting
|
# check user's model setting
|
||||||
DatasetService.check_dataset_model_setting(dataset)
|
DatasetService.check_dataset_model_setting(dataset)
|
||||||
# The role of the current user in the ta table must be admin, owner, or editor
|
# The role of the current user in the ta table must be admin, owner, or editor
|
||||||
if not current_user.is_editor:
|
if not current_user.is_dataset_editor:
|
||||||
raise Forbidden()
|
raise Forbidden()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -202,7 +202,7 @@ class DatasetDocumentSegmentAddApi(Resource):
|
|||||||
document = DocumentService.get_document(dataset_id, document_id)
|
document = DocumentService.get_document(dataset_id, document_id)
|
||||||
if not document:
|
if not document:
|
||||||
raise NotFound("Document not found.")
|
raise NotFound("Document not found.")
|
||||||
if not current_user.is_editor:
|
if not current_user.is_dataset_editor:
|
||||||
raise Forbidden()
|
raise Forbidden()
|
||||||
# check embedding model setting
|
# check embedding model setting
|
||||||
if dataset.indexing_technique == "high_quality":
|
if dataset.indexing_technique == "high_quality":
|
||||||
@@ -277,7 +277,7 @@ class DatasetDocumentSegmentUpdateApi(Resource):
|
|||||||
if not segment:
|
if not segment:
|
||||||
raise NotFound("Segment not found.")
|
raise NotFound("Segment not found.")
|
||||||
# The role of the current user in the ta table must be admin, owner, or editor
|
# The role of the current user in the ta table must be admin, owner, or editor
|
||||||
if not current_user.is_editor:
|
if not current_user.is_dataset_editor:
|
||||||
raise Forbidden()
|
raise Forbidden()
|
||||||
try:
|
try:
|
||||||
DatasetService.check_dataset_permission(dataset, current_user)
|
DatasetService.check_dataset_permission(dataset, current_user)
|
||||||
@@ -320,7 +320,7 @@ class DatasetDocumentSegmentUpdateApi(Resource):
|
|||||||
if not segment:
|
if not segment:
|
||||||
raise NotFound("Segment not found.")
|
raise NotFound("Segment not found.")
|
||||||
# The role of the current user in the ta table must be admin or owner
|
# The role of the current user in the ta table must be admin or owner
|
||||||
if not current_user.is_editor:
|
if not current_user.is_dataset_editor:
|
||||||
raise Forbidden()
|
raise Forbidden()
|
||||||
try:
|
try:
|
||||||
DatasetService.check_dataset_permission(dataset, current_user)
|
DatasetService.check_dataset_permission(dataset, current_user)
|
||||||
@@ -420,7 +420,7 @@ class ChildChunkAddApi(Resource):
|
|||||||
).first()
|
).first()
|
||||||
if not segment:
|
if not segment:
|
||||||
raise NotFound("Segment not found.")
|
raise NotFound("Segment not found.")
|
||||||
if not current_user.is_editor:
|
if not current_user.is_dataset_editor:
|
||||||
raise Forbidden()
|
raise Forbidden()
|
||||||
# check embedding model setting
|
# check embedding model setting
|
||||||
if dataset.indexing_technique == "high_quality":
|
if dataset.indexing_technique == "high_quality":
|
||||||
@@ -520,7 +520,7 @@ class ChildChunkAddApi(Resource):
|
|||||||
if not segment:
|
if not segment:
|
||||||
raise NotFound("Segment not found.")
|
raise NotFound("Segment not found.")
|
||||||
# The role of the current user in the ta table must be admin, owner, or editor
|
# The role of the current user in the ta table must be admin, owner, or editor
|
||||||
if not current_user.is_editor:
|
if not current_user.is_dataset_editor:
|
||||||
raise Forbidden()
|
raise Forbidden()
|
||||||
try:
|
try:
|
||||||
DatasetService.check_dataset_permission(dataset, current_user)
|
DatasetService.check_dataset_permission(dataset, current_user)
|
||||||
@@ -570,7 +570,7 @@ class ChildChunkUpdateApi(Resource):
|
|||||||
if not child_chunk:
|
if not child_chunk:
|
||||||
raise NotFound("Child chunk not found.")
|
raise NotFound("Child chunk not found.")
|
||||||
# The role of the current user in the ta table must be admin or owner
|
# The role of the current user in the ta table must be admin or owner
|
||||||
if not current_user.is_editor:
|
if not current_user.is_dataset_editor:
|
||||||
raise Forbidden()
|
raise Forbidden()
|
||||||
try:
|
try:
|
||||||
DatasetService.check_dataset_permission(dataset, current_user)
|
DatasetService.check_dataset_permission(dataset, current_user)
|
||||||
@@ -614,7 +614,7 @@ class ChildChunkUpdateApi(Resource):
|
|||||||
if not child_chunk:
|
if not child_chunk:
|
||||||
raise NotFound("Child chunk not found.")
|
raise NotFound("Child chunk not found.")
|
||||||
# The role of the current user in the ta table must be admin or owner
|
# The role of the current user in the ta table must be admin or owner
|
||||||
if not current_user.is_editor:
|
if not current_user.is_dataset_editor:
|
||||||
raise Forbidden()
|
raise Forbidden()
|
||||||
try:
|
try:
|
||||||
DatasetService.check_dataset_permission(dataset, current_user)
|
DatasetService.check_dataset_permission(dataset, current_user)
|
||||||
|
|||||||
@@ -77,4 +77,5 @@
|
|||||||
- onebot
|
- onebot
|
||||||
- regex
|
- regex
|
||||||
- trello
|
- trello
|
||||||
|
- vanna
|
||||||
- fal
|
- fal
|
||||||
|
|||||||
BIN
api/core/tools/provider/builtin/vanna/_assets/icon.png
Normal file
BIN
api/core/tools/provider/builtin/vanna/_assets/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.5 KiB |
134
api/core/tools/provider/builtin/vanna/tools/vanna.py
Normal file
134
api/core/tools/provider/builtin/vanna/tools/vanna.py
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
from typing import Any, Union
|
||||||
|
|
||||||
|
from vanna.remote import VannaDefault # type: ignore
|
||||||
|
|
||||||
|
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||||
|
from core.tools.errors import ToolProviderCredentialValidationError
|
||||||
|
from core.tools.tool.builtin_tool import BuiltinTool
|
||||||
|
|
||||||
|
|
||||||
|
class VannaTool(BuiltinTool):
|
||||||
|
def _invoke(
|
||||||
|
self, user_id: str, tool_parameters: dict[str, Any]
|
||||||
|
) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
|
||||||
|
"""
|
||||||
|
invoke tools
|
||||||
|
"""
|
||||||
|
# Ensure runtime and credentials
|
||||||
|
if not self.runtime or not self.runtime.credentials:
|
||||||
|
raise ToolProviderCredentialValidationError("Tool runtime or credentials are missing")
|
||||||
|
api_key = self.runtime.credentials.get("api_key", None)
|
||||||
|
if not api_key:
|
||||||
|
raise ToolProviderCredentialValidationError("Please input api key")
|
||||||
|
|
||||||
|
model = tool_parameters.get("model", "")
|
||||||
|
if not model:
|
||||||
|
return self.create_text_message("Please input RAG model")
|
||||||
|
|
||||||
|
prompt = tool_parameters.get("prompt", "")
|
||||||
|
if not prompt:
|
||||||
|
return self.create_text_message("Please input prompt")
|
||||||
|
|
||||||
|
url = tool_parameters.get("url", "")
|
||||||
|
if not url:
|
||||||
|
return self.create_text_message("Please input URL/Host/DSN")
|
||||||
|
|
||||||
|
db_name = tool_parameters.get("db_name", "")
|
||||||
|
username = tool_parameters.get("username", "")
|
||||||
|
password = tool_parameters.get("password", "")
|
||||||
|
port = tool_parameters.get("port", 0)
|
||||||
|
|
||||||
|
base_url = self.runtime.credentials.get("base_url", None)
|
||||||
|
vn = VannaDefault(model=model, api_key=api_key, config={"endpoint": base_url})
|
||||||
|
|
||||||
|
db_type = tool_parameters.get("db_type", "")
|
||||||
|
if db_type in {"Postgres", "MySQL", "Hive", "ClickHouse"}:
|
||||||
|
if not db_name:
|
||||||
|
return self.create_text_message("Please input database name")
|
||||||
|
if not username:
|
||||||
|
return self.create_text_message("Please input username")
|
||||||
|
if port < 1:
|
||||||
|
return self.create_text_message("Please input port")
|
||||||
|
|
||||||
|
schema_sql = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS"
|
||||||
|
match db_type:
|
||||||
|
case "SQLite":
|
||||||
|
schema_sql = "SELECT type, sql FROM sqlite_master WHERE sql is not null"
|
||||||
|
vn.connect_to_sqlite(url)
|
||||||
|
case "Postgres":
|
||||||
|
vn.connect_to_postgres(host=url, dbname=db_name, user=username, password=password, port=port)
|
||||||
|
case "DuckDB":
|
||||||
|
vn.connect_to_duckdb(url=url)
|
||||||
|
case "SQLServer":
|
||||||
|
vn.connect_to_mssql(url)
|
||||||
|
case "MySQL":
|
||||||
|
vn.connect_to_mysql(host=url, dbname=db_name, user=username, password=password, port=port)
|
||||||
|
case "Oracle":
|
||||||
|
vn.connect_to_oracle(user=username, password=password, dsn=url)
|
||||||
|
case "Hive":
|
||||||
|
vn.connect_to_hive(host=url, dbname=db_name, user=username, password=password, port=port)
|
||||||
|
case "ClickHouse":
|
||||||
|
vn.connect_to_clickhouse(host=url, dbname=db_name, user=username, password=password, port=port)
|
||||||
|
|
||||||
|
enable_training = tool_parameters.get("enable_training", False)
|
||||||
|
reset_training_data = tool_parameters.get("reset_training_data", False)
|
||||||
|
if enable_training:
|
||||||
|
if reset_training_data:
|
||||||
|
existing_training_data = vn.get_training_data()
|
||||||
|
if len(existing_training_data) > 0:
|
||||||
|
for _, training_data in existing_training_data.iterrows():
|
||||||
|
vn.remove_training_data(training_data["id"])
|
||||||
|
|
||||||
|
ddl = tool_parameters.get("ddl", "")
|
||||||
|
question = tool_parameters.get("question", "")
|
||||||
|
sql = tool_parameters.get("sql", "")
|
||||||
|
memos = tool_parameters.get("memos", "")
|
||||||
|
training_metadata = tool_parameters.get("training_metadata", False)
|
||||||
|
|
||||||
|
if training_metadata:
|
||||||
|
if db_type == "SQLite":
|
||||||
|
df_ddl = vn.run_sql(schema_sql)
|
||||||
|
for ddl in df_ddl["sql"].to_list():
|
||||||
|
vn.train(ddl=ddl)
|
||||||
|
else:
|
||||||
|
df_information_schema = vn.run_sql(schema_sql)
|
||||||
|
plan = vn.get_training_plan_generic(df_information_schema)
|
||||||
|
vn.train(plan=plan)
|
||||||
|
|
||||||
|
if ddl:
|
||||||
|
vn.train(ddl=ddl)
|
||||||
|
|
||||||
|
if sql:
|
||||||
|
if question:
|
||||||
|
vn.train(question=question, sql=sql)
|
||||||
|
else:
|
||||||
|
vn.train(sql=sql)
|
||||||
|
if memos:
|
||||||
|
vn.train(documentation=memos)
|
||||||
|
|
||||||
|
#########################################################################################
|
||||||
|
# Due to CVE-2024-5565, we have to disable the chart generation feature
|
||||||
|
# The Vanna library uses a prompt function to present the user with visualized results,
|
||||||
|
# it is possible to alter the prompt using prompt injection and run arbitrary Python code
|
||||||
|
# instead of the intended visualization code.
|
||||||
|
# Specifically - allowing external input to the library’s “ask” method
|
||||||
|
# with "visualize" set to True (default behavior) leads to remote code execution.
|
||||||
|
# Affected versions: <= 0.5.5
|
||||||
|
#########################################################################################
|
||||||
|
allow_llm_to_see_data = tool_parameters.get("allow_llm_to_see_data", False)
|
||||||
|
res = vn.ask(
|
||||||
|
prompt, print_results=False, auto_train=True, visualize=False, allow_llm_to_see_data=allow_llm_to_see_data
|
||||||
|
)
|
||||||
|
|
||||||
|
result = []
|
||||||
|
|
||||||
|
if res is not None:
|
||||||
|
result.append(self.create_text_message(res[0]))
|
||||||
|
if len(res) > 1 and res[1] is not None:
|
||||||
|
result.append(self.create_text_message(res[1].to_markdown()))
|
||||||
|
if len(res) > 2 and res[2] is not None:
|
||||||
|
result.append(
|
||||||
|
self.create_blob_message(blob=res[2].to_image(format="svg"), meta={"mime_type": "image/svg+xml"})
|
||||||
|
)
|
||||||
|
|
||||||
|
return result
|
||||||
213
api/core/tools/provider/builtin/vanna/tools/vanna.yaml
Normal file
213
api/core/tools/provider/builtin/vanna/tools/vanna.yaml
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
identity:
|
||||||
|
name: vanna
|
||||||
|
author: QCTC
|
||||||
|
label:
|
||||||
|
en_US: Vanna.AI
|
||||||
|
zh_Hans: Vanna.AI
|
||||||
|
description:
|
||||||
|
human:
|
||||||
|
en_US: The fastest way to get actionable insights from your database just by asking questions.
|
||||||
|
zh_Hans: 一个基于大模型和RAG的Text2SQL工具。
|
||||||
|
llm: A tool for converting text to SQL.
|
||||||
|
parameters:
|
||||||
|
- name: prompt
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
label:
|
||||||
|
en_US: Prompt
|
||||||
|
zh_Hans: 提示词
|
||||||
|
pt_BR: Prompt
|
||||||
|
human_description:
|
||||||
|
en_US: used for generating SQL
|
||||||
|
zh_Hans: 用于生成SQL
|
||||||
|
llm_description: key words for generating SQL
|
||||||
|
form: llm
|
||||||
|
- name: model
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
label:
|
||||||
|
en_US: RAG Model
|
||||||
|
zh_Hans: RAG模型
|
||||||
|
human_description:
|
||||||
|
en_US: RAG Model for your database DDL
|
||||||
|
zh_Hans: 存储数据库训练数据的RAG模型
|
||||||
|
llm_description: RAG Model for generating SQL
|
||||||
|
form: llm
|
||||||
|
- name: db_type
|
||||||
|
type: select
|
||||||
|
required: true
|
||||||
|
options:
|
||||||
|
- value: SQLite
|
||||||
|
label:
|
||||||
|
en_US: SQLite
|
||||||
|
zh_Hans: SQLite
|
||||||
|
- value: Postgres
|
||||||
|
label:
|
||||||
|
en_US: Postgres
|
||||||
|
zh_Hans: Postgres
|
||||||
|
- value: DuckDB
|
||||||
|
label:
|
||||||
|
en_US: DuckDB
|
||||||
|
zh_Hans: DuckDB
|
||||||
|
- value: SQLServer
|
||||||
|
label:
|
||||||
|
en_US: Microsoft SQL Server
|
||||||
|
zh_Hans: 微软 SQL Server
|
||||||
|
- value: MySQL
|
||||||
|
label:
|
||||||
|
en_US: MySQL
|
||||||
|
zh_Hans: MySQL
|
||||||
|
- value: Oracle
|
||||||
|
label:
|
||||||
|
en_US: Oracle
|
||||||
|
zh_Hans: Oracle
|
||||||
|
- value: Hive
|
||||||
|
label:
|
||||||
|
en_US: Hive
|
||||||
|
zh_Hans: Hive
|
||||||
|
- value: ClickHouse
|
||||||
|
label:
|
||||||
|
en_US: ClickHouse
|
||||||
|
zh_Hans: ClickHouse
|
||||||
|
default: SQLite
|
||||||
|
label:
|
||||||
|
en_US: DB Type
|
||||||
|
zh_Hans: 数据库类型
|
||||||
|
human_description:
|
||||||
|
en_US: Database type.
|
||||||
|
zh_Hans: 选择要链接的数据库类型。
|
||||||
|
form: form
|
||||||
|
- name: url
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
label:
|
||||||
|
en_US: URL/Host/DSN
|
||||||
|
zh_Hans: URL/Host/DSN
|
||||||
|
human_description:
|
||||||
|
en_US: Please input depending on DB type, visit https://vanna.ai/docs/ for more specification
|
||||||
|
zh_Hans: 请根据数据库类型,填入对应值,详情参考https://vanna.ai/docs/
|
||||||
|
form: form
|
||||||
|
- name: db_name
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
label:
|
||||||
|
en_US: DB name
|
||||||
|
zh_Hans: 数据库名
|
||||||
|
human_description:
|
||||||
|
en_US: Database name
|
||||||
|
zh_Hans: 数据库名
|
||||||
|
form: form
|
||||||
|
- name: username
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
label:
|
||||||
|
en_US: Username
|
||||||
|
zh_Hans: 用户名
|
||||||
|
human_description:
|
||||||
|
en_US: Username
|
||||||
|
zh_Hans: 用户名
|
||||||
|
form: form
|
||||||
|
- name: password
|
||||||
|
type: secret-input
|
||||||
|
required: false
|
||||||
|
label:
|
||||||
|
en_US: Password
|
||||||
|
zh_Hans: 密码
|
||||||
|
human_description:
|
||||||
|
en_US: Password
|
||||||
|
zh_Hans: 密码
|
||||||
|
form: form
|
||||||
|
- name: port
|
||||||
|
type: number
|
||||||
|
required: false
|
||||||
|
label:
|
||||||
|
en_US: Port
|
||||||
|
zh_Hans: 端口
|
||||||
|
human_description:
|
||||||
|
en_US: Port
|
||||||
|
zh_Hans: 端口
|
||||||
|
form: form
|
||||||
|
- name: ddl
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
label:
|
||||||
|
en_US: Training DDL
|
||||||
|
zh_Hans: 训练DDL
|
||||||
|
human_description:
|
||||||
|
en_US: DDL statements for training data
|
||||||
|
zh_Hans: 用于训练RAG Model的建表语句
|
||||||
|
form: llm
|
||||||
|
- name: question
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
label:
|
||||||
|
en_US: Training Question
|
||||||
|
zh_Hans: 训练问题
|
||||||
|
human_description:
|
||||||
|
en_US: Question-SQL Pairs
|
||||||
|
zh_Hans: Question-SQL中的问题
|
||||||
|
form: llm
|
||||||
|
- name: sql
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
label:
|
||||||
|
en_US: Training SQL
|
||||||
|
zh_Hans: 训练SQL
|
||||||
|
human_description:
|
||||||
|
en_US: SQL queries to your training data
|
||||||
|
zh_Hans: 用于训练RAG Model的SQL语句
|
||||||
|
form: llm
|
||||||
|
- name: memos
|
||||||
|
type: string
|
||||||
|
required: false
|
||||||
|
label:
|
||||||
|
en_US: Training Memos
|
||||||
|
zh_Hans: 训练说明
|
||||||
|
human_description:
|
||||||
|
en_US: Sometimes you may want to add documentation about your business terminology or definitions
|
||||||
|
zh_Hans: 添加更多关于数据库的业务说明
|
||||||
|
form: llm
|
||||||
|
- name: enable_training
|
||||||
|
type: boolean
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
label:
|
||||||
|
en_US: Training Data
|
||||||
|
zh_Hans: 训练数据
|
||||||
|
human_description:
|
||||||
|
en_US: You only need to train once. Do not train again unless you want to add more training data
|
||||||
|
zh_Hans: 训练数据无更新时,训练一次即可
|
||||||
|
form: form
|
||||||
|
- name: reset_training_data
|
||||||
|
type: boolean
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
label:
|
||||||
|
en_US: Reset Training Data
|
||||||
|
zh_Hans: 重置训练数据
|
||||||
|
human_description:
|
||||||
|
en_US: Remove all training data in the current RAG Model
|
||||||
|
zh_Hans: 删除当前RAG Model中的所有训练数据
|
||||||
|
form: form
|
||||||
|
- name: training_metadata
|
||||||
|
type: boolean
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
label:
|
||||||
|
en_US: Training Metadata
|
||||||
|
zh_Hans: 训练元数据
|
||||||
|
human_description:
|
||||||
|
en_US: If enabled, it will attempt to train on the metadata of that database
|
||||||
|
zh_Hans: 是否自动从数据库获取元数据来训练
|
||||||
|
form: form
|
||||||
|
- name: allow_llm_to_see_data
|
||||||
|
type: boolean
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
label:
|
||||||
|
en_US: Whether to allow the LLM to see the data
|
||||||
|
zh_Hans: 是否允许LLM查看数据
|
||||||
|
human_description:
|
||||||
|
en_US: Whether to allow the LLM to see the data
|
||||||
|
zh_Hans: 是否允许LLM查看数据
|
||||||
|
form: form
|
||||||
46
api/core/tools/provider/builtin/vanna/vanna.py
Normal file
46
api/core/tools/provider/builtin/vanna/vanna.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import re
|
||||||
|
from typing import Any
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
from core.tools.errors import ToolProviderCredentialValidationError
|
||||||
|
from core.tools.provider.builtin.vanna.tools.vanna import VannaTool
|
||||||
|
from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController
|
||||||
|
|
||||||
|
|
||||||
|
class VannaProvider(BuiltinToolProviderController):
|
||||||
|
def _get_protocol_and_main_domain(self, url):
|
||||||
|
parsed_url = urlparse(url)
|
||||||
|
protocol = parsed_url.scheme
|
||||||
|
hostname = parsed_url.hostname
|
||||||
|
port = f":{parsed_url.port}" if parsed_url.port else ""
|
||||||
|
|
||||||
|
# Check if the hostname is an IP address
|
||||||
|
is_ip = re.match(r"^\d{1,3}(\.\d{1,3}){3}$", hostname) is not None
|
||||||
|
|
||||||
|
# Return the full hostname (with port if present) for IP addresses, otherwise return the main domain
|
||||||
|
main_domain = f"{hostname}{port}" if is_ip else ".".join(hostname.split(".")[-2:]) + port
|
||||||
|
return f"{protocol}://{main_domain}"
|
||||||
|
|
||||||
|
def _validate_credentials(self, credentials: dict[str, Any]) -> None:
|
||||||
|
base_url = credentials.get("base_url")
|
||||||
|
if not base_url:
|
||||||
|
base_url = "https://ask.vanna.ai/rpc"
|
||||||
|
else:
|
||||||
|
base_url = base_url.removesuffix("/")
|
||||||
|
credentials["base_url"] = base_url
|
||||||
|
try:
|
||||||
|
VannaTool().fork_tool_runtime(
|
||||||
|
runtime={
|
||||||
|
"credentials": credentials,
|
||||||
|
}
|
||||||
|
).invoke(
|
||||||
|
user_id="",
|
||||||
|
tool_parameters={
|
||||||
|
"model": "chinook",
|
||||||
|
"db_type": "SQLite",
|
||||||
|
"url": f"{self._get_protocol_and_main_domain(credentials['base_url'])}/Chinook.sqlite",
|
||||||
|
"query": "What are the top 10 customers by sales?",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
raise ToolProviderCredentialValidationError(str(e))
|
||||||
35
api/core/tools/provider/builtin/vanna/vanna.yaml
Normal file
35
api/core/tools/provider/builtin/vanna/vanna.yaml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
identity:
|
||||||
|
author: QCTC
|
||||||
|
name: vanna
|
||||||
|
label:
|
||||||
|
en_US: Vanna.AI
|
||||||
|
zh_Hans: Vanna.AI
|
||||||
|
description:
|
||||||
|
en_US: The fastest way to get actionable insights from your database just by asking questions.
|
||||||
|
zh_Hans: 一个基于大模型和RAG的Text2SQL工具。
|
||||||
|
icon: icon.png
|
||||||
|
tags:
|
||||||
|
- utilities
|
||||||
|
- productivity
|
||||||
|
credentials_for_provider:
|
||||||
|
api_key:
|
||||||
|
type: secret-input
|
||||||
|
required: true
|
||||||
|
label:
|
||||||
|
en_US: API key
|
||||||
|
zh_Hans: API key
|
||||||
|
placeholder:
|
||||||
|
en_US: Please input your API key
|
||||||
|
zh_Hans: 请输入你的 API key
|
||||||
|
pt_BR: Please input your API key
|
||||||
|
help:
|
||||||
|
en_US: Get your API key from Vanna.AI
|
||||||
|
zh_Hans: 从 Vanna.AI 获取你的 API key
|
||||||
|
url: https://vanna.ai/account/profile
|
||||||
|
base_url:
|
||||||
|
type: text-input
|
||||||
|
required: false
|
||||||
|
label:
|
||||||
|
en_US: Vanna.AI Endpoint Base URL
|
||||||
|
placeholder:
|
||||||
|
en_US: https://ask.vanna.ai/rpc
|
||||||
@@ -195,7 +195,7 @@ class CodeNode(BaseNode[CodeNodeData]):
|
|||||||
if output_config.type == "object":
|
if output_config.type == "object":
|
||||||
# check if output is object
|
# check if output is object
|
||||||
if not isinstance(result.get(output_name), dict):
|
if not isinstance(result.get(output_name), dict):
|
||||||
if isinstance(result.get(output_name), type(None)):
|
if result.get(output_name) is None:
|
||||||
transformed_result[output_name] = None
|
transformed_result[output_name] = None
|
||||||
else:
|
else:
|
||||||
raise OutputValidationError(
|
raise OutputValidationError(
|
||||||
@@ -223,7 +223,7 @@ class CodeNode(BaseNode[CodeNodeData]):
|
|||||||
elif output_config.type == "array[number]":
|
elif output_config.type == "array[number]":
|
||||||
# check if array of number available
|
# check if array of number available
|
||||||
if not isinstance(result[output_name], list):
|
if not isinstance(result[output_name], list):
|
||||||
if isinstance(result[output_name], type(None)):
|
if result[output_name] is None:
|
||||||
transformed_result[output_name] = None
|
transformed_result[output_name] = None
|
||||||
else:
|
else:
|
||||||
raise OutputValidationError(
|
raise OutputValidationError(
|
||||||
@@ -244,7 +244,7 @@ class CodeNode(BaseNode[CodeNodeData]):
|
|||||||
elif output_config.type == "array[string]":
|
elif output_config.type == "array[string]":
|
||||||
# check if array of string available
|
# check if array of string available
|
||||||
if not isinstance(result[output_name], list):
|
if not isinstance(result[output_name], list):
|
||||||
if isinstance(result[output_name], type(None)):
|
if result[output_name] is None:
|
||||||
transformed_result[output_name] = None
|
transformed_result[output_name] = None
|
||||||
else:
|
else:
|
||||||
raise OutputValidationError(
|
raise OutputValidationError(
|
||||||
@@ -265,7 +265,7 @@ class CodeNode(BaseNode[CodeNodeData]):
|
|||||||
elif output_config.type == "array[object]":
|
elif output_config.type == "array[object]":
|
||||||
# check if array of object available
|
# check if array of object available
|
||||||
if not isinstance(result[output_name], list):
|
if not isinstance(result[output_name], list):
|
||||||
if isinstance(result[output_name], type(None)):
|
if result[output_name] is None:
|
||||||
transformed_result[output_name] = None
|
transformed_result[output_name] = None
|
||||||
else:
|
else:
|
||||||
raise OutputValidationError(
|
raise OutputValidationError(
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ x-shared-env: &shared-api-worker-env
|
|||||||
services:
|
services:
|
||||||
# API service
|
# API service
|
||||||
api:
|
api:
|
||||||
image: langgenius/dify-api:0.15.5
|
image: langgenius/dify-api:0.15.3
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
# Use the shared environment variables.
|
# Use the shared environment variables.
|
||||||
@@ -25,7 +25,7 @@ services:
|
|||||||
# worker service
|
# worker service
|
||||||
# The Celery worker for processing the queue.
|
# The Celery worker for processing the queue.
|
||||||
worker:
|
worker:
|
||||||
image: langgenius/dify-api:0.15.5
|
image: langgenius/dify-api:0.15.3
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
# Use the shared environment variables.
|
# Use the shared environment variables.
|
||||||
@@ -47,7 +47,7 @@ services:
|
|||||||
|
|
||||||
# Frontend web application.
|
# Frontend web application.
|
||||||
web:
|
web:
|
||||||
image: langgenius/dify-web:0.15.5
|
image: langgenius/dify-web:0.15.3
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
CONSOLE_API_URL: ${CONSOLE_API_URL:-}
|
CONSOLE_API_URL: ${CONSOLE_API_URL:-}
|
||||||
@@ -98,7 +98,7 @@ services:
|
|||||||
|
|
||||||
# The DifySandbox
|
# The DifySandbox
|
||||||
sandbox:
|
sandbox:
|
||||||
image: langgenius/dify-sandbox:0.2.11
|
image: langgenius/dify-sandbox:0.2.10
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
# The DifySandbox configurations
|
# The DifySandbox configurations
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ services:
|
|||||||
|
|
||||||
# The DifySandbox
|
# The DifySandbox
|
||||||
sandbox:
|
sandbox:
|
||||||
image: langgenius/dify-sandbox:0.2.11
|
image: langgenius/dify-sandbox:0.2.10
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
# The DifySandbox configurations
|
# The DifySandbox configurations
|
||||||
|
|||||||
@@ -393,7 +393,7 @@ x-shared-env: &shared-api-worker-env
|
|||||||
services:
|
services:
|
||||||
# API service
|
# API service
|
||||||
api:
|
api:
|
||||||
image: langgenius/dify-api:0.15.5
|
image: langgenius/dify-api:0.15.3
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
# Use the shared environment variables.
|
# Use the shared environment variables.
|
||||||
@@ -416,7 +416,7 @@ services:
|
|||||||
# worker service
|
# worker service
|
||||||
# The Celery worker for processing the queue.
|
# The Celery worker for processing the queue.
|
||||||
worker:
|
worker:
|
||||||
image: langgenius/dify-api:0.15.5
|
image: langgenius/dify-api:0.15.3
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
# Use the shared environment variables.
|
# Use the shared environment variables.
|
||||||
@@ -438,7 +438,7 @@ services:
|
|||||||
|
|
||||||
# Frontend web application.
|
# Frontend web application.
|
||||||
web:
|
web:
|
||||||
image: langgenius/dify-web:0.15.5
|
image: langgenius/dify-web:0.15.3
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
CONSOLE_API_URL: ${CONSOLE_API_URL:-}
|
CONSOLE_API_URL: ${CONSOLE_API_URL:-}
|
||||||
@@ -489,7 +489,7 @@ services:
|
|||||||
|
|
||||||
# The DifySandbox
|
# The DifySandbox
|
||||||
sandbox:
|
sandbox:
|
||||||
image: langgenius/dify-sandbox:0.2.11
|
image: langgenius/dify-sandbox:0.2.10
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
# The DifySandbox configurations
|
# The DifySandbox configurations
|
||||||
|
|||||||
@@ -312,7 +312,7 @@ function AppPreview({ mode }: { mode: AppMode }) {
|
|||||||
'chat': {
|
'chat': {
|
||||||
title: t('app.types.chatbot'),
|
title: t('app.types.chatbot'),
|
||||||
description: t('app.newApp.chatbotUserDescription'),
|
description: t('app.newApp.chatbotUserDescription'),
|
||||||
link: 'https://docs.dify.ai/guides/application-orchestrate#application_type',
|
link: 'https://docs.dify.ai/guides/application-orchestrate/conversation-application?fallback=true',
|
||||||
},
|
},
|
||||||
'advanced-chat': {
|
'advanced-chat': {
|
||||||
title: t('app.types.advanced'),
|
title: t('app.types.advanced'),
|
||||||
|
|||||||
@@ -11,12 +11,10 @@ import { useLocalStorageState } from 'ahooks'
|
|||||||
import produce from 'immer'
|
import produce from 'immer'
|
||||||
import type {
|
import type {
|
||||||
ChatConfig,
|
ChatConfig,
|
||||||
ChatItem,
|
|
||||||
Feedback,
|
Feedback,
|
||||||
} from '../types'
|
} from '../types'
|
||||||
import { CONVERSATION_ID_INFO } from '../constants'
|
import { CONVERSATION_ID_INFO } from '../constants'
|
||||||
import { buildChatItemTree, getProcessedInputsFromUrlParams } from '../utils'
|
import { getPrevChatList, getProcessedInputsFromUrlParams } from '../utils'
|
||||||
import { getProcessedFilesFromResponse } from '../../file-uploader/utils'
|
|
||||||
import {
|
import {
|
||||||
fetchAppInfo,
|
fetchAppInfo,
|
||||||
fetchAppMeta,
|
fetchAppMeta,
|
||||||
@@ -34,33 +32,6 @@ import { useToastContext } from '@/app/components/base/toast'
|
|||||||
import { changeLanguage } from '@/i18n/i18next-config'
|
import { changeLanguage } from '@/i18n/i18next-config'
|
||||||
import { InputVarType } from '@/app/components/workflow/types'
|
import { InputVarType } from '@/app/components/workflow/types'
|
||||||
import { TransferMethod } from '@/types/app'
|
import { TransferMethod } from '@/types/app'
|
||||||
import { addFileInfos, sortAgentSorts } from '@/app/components/tools/utils'
|
|
||||||
|
|
||||||
function getFormattedChatList(messages: any[]) {
|
|
||||||
const newChatList: ChatItem[] = []
|
|
||||||
messages.forEach((item) => {
|
|
||||||
const questionFiles = item.message_files?.filter((file: any) => file.belongs_to === 'user') || []
|
|
||||||
newChatList.push({
|
|
||||||
id: `question-${item.id}`,
|
|
||||||
content: item.query,
|
|
||||||
isAnswer: false,
|
|
||||||
message_files: getProcessedFilesFromResponse(questionFiles.map((item: any) => ({ ...item, related_id: item.id }))),
|
|
||||||
parentMessageId: item.parent_message_id || undefined,
|
|
||||||
})
|
|
||||||
const answerFiles = item.message_files?.filter((file: any) => file.belongs_to === 'assistant') || []
|
|
||||||
newChatList.push({
|
|
||||||
id: item.id,
|
|
||||||
content: item.answer,
|
|
||||||
agent_thoughts: addFileInfos(item.agent_thoughts ? sortAgentSorts(item.agent_thoughts) : item.agent_thoughts, item.message_files),
|
|
||||||
feedback: item.feedback,
|
|
||||||
isAnswer: true,
|
|
||||||
citation: item.retriever_resources,
|
|
||||||
message_files: getProcessedFilesFromResponse(answerFiles.map((item: any) => ({ ...item, related_id: item.id }))),
|
|
||||||
parentMessageId: `question-${item.id}`,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
return newChatList
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useEmbeddedChatbot = () => {
|
export const useEmbeddedChatbot = () => {
|
||||||
const isInstalledApp = false
|
const isInstalledApp = false
|
||||||
@@ -106,7 +77,7 @@ export const useEmbeddedChatbot = () => {
|
|||||||
|
|
||||||
const appPrevChatList = useMemo(
|
const appPrevChatList = useMemo(
|
||||||
() => (currentConversationId && appChatListData?.data.length)
|
() => (currentConversationId && appChatListData?.data.length)
|
||||||
? buildChatItemTree(getFormattedChatList(appChatListData.data))
|
? getPrevChatList(appChatListData.data)
|
||||||
: [],
|
: [],
|
||||||
[appChatListData, currentConversationId],
|
[appChatListData, currentConversationId],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import SyntaxHighlighter from 'react-syntax-highlighter'
|
|||||||
import { atelierHeathLight } from 'react-syntax-highlighter/dist/esm/styles/hljs'
|
import { atelierHeathLight } from 'react-syntax-highlighter/dist/esm/styles/hljs'
|
||||||
import { Component, memo, useMemo, useRef, useState } from 'react'
|
import { Component, memo, useMemo, useRef, useState } from 'react'
|
||||||
import type { CodeComponent } from 'react-markdown/lib/ast-to-react'
|
import type { CodeComponent } from 'react-markdown/lib/ast-to-react'
|
||||||
import SVGRenderer from './svg-gallery'
|
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
import CopyBtn from '@/app/components/base/copy-btn'
|
import CopyBtn from '@/app/components/base/copy-btn'
|
||||||
import SVGBtn from '@/app/components/base/svg'
|
import SVGBtn from '@/app/components/base/svg'
|
||||||
@@ -19,7 +18,7 @@ import ImageGallery from '@/app/components/base/image-gallery'
|
|||||||
import { useChatContext } from '@/app/components/base/chat/chat/context'
|
import { useChatContext } from '@/app/components/base/chat/chat/context'
|
||||||
import VideoGallery from '@/app/components/base/video-gallery'
|
import VideoGallery from '@/app/components/base/video-gallery'
|
||||||
import AudioGallery from '@/app/components/base/audio-gallery'
|
import AudioGallery from '@/app/components/base/audio-gallery'
|
||||||
// import SVGRenderer from '@/app/components/base/svg-gallery'
|
import SVGRenderer from '@/app/components/base/svg-gallery'
|
||||||
import MarkdownButton from '@/app/components/base/markdown-blocks/button'
|
import MarkdownButton from '@/app/components/base/markdown-blocks/button'
|
||||||
import MarkdownForm from '@/app/components/base/markdown-blocks/form'
|
import MarkdownForm from '@/app/components/base/markdown-blocks/form'
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { useEffect, useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import { SVG } from '@svgdotjs/svg.js'
|
import { SVG } from '@svgdotjs/svg.js'
|
||||||
import DOMPurify from 'dompurify'
|
|
||||||
import ImagePreview from '@/app/components/base/image-uploader/image-preview'
|
import ImagePreview from '@/app/components/base/image-uploader/image-preview'
|
||||||
|
|
||||||
export const SVGRenderer = ({ content }: { content: string }) => {
|
export const SVGRenderer = ({ content }: { content: string }) => {
|
||||||
@@ -45,7 +44,7 @@ export const SVGRenderer = ({ content }: { content: string }) => {
|
|||||||
|
|
||||||
svgRef.current.style.width = `${Math.min(originalWidth, 298)}px`
|
svgRef.current.style.width = `${Math.min(originalWidth, 298)}px`
|
||||||
|
|
||||||
const rootElement = draw.svg(DOMPurify.sanitize(content))
|
const rootElement = draw.svg(content)
|
||||||
|
|
||||||
rootElement.click(() => {
|
rootElement.click(() => {
|
||||||
setImagePreview(svgToDataURL(svgElement as Element))
|
setImagePreview(svgToDataURL(svgElement as Element))
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "dify-web",
|
"name": "dify-web",
|
||||||
"version": "0.15.5",
|
"version": "0.15.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.17.0"
|
"node": ">=18.17.0"
|
||||||
@@ -51,7 +51,6 @@
|
|||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"decimal.js": "^10.4.3",
|
"decimal.js": "^10.4.3",
|
||||||
"dompurify": "^3.2.4",
|
|
||||||
"echarts": "^5.5.1",
|
"echarts": "^5.5.1",
|
||||||
"echarts-for-react": "^3.0.2",
|
"echarts-for-react": "^3.0.2",
|
||||||
"elkjs": "^0.9.3",
|
"elkjs": "^0.9.3",
|
||||||
@@ -71,7 +70,7 @@
|
|||||||
"mermaid": "11.4.1",
|
"mermaid": "11.4.1",
|
||||||
"mime": "^4.0.4",
|
"mime": "^4.0.4",
|
||||||
"negotiator": "^0.6.3",
|
"negotiator": "^0.6.3",
|
||||||
"next": "^14.2.25",
|
"next": "^14.2.10",
|
||||||
"pinyin-pro": "^3.23.0",
|
"pinyin-pro": "^3.23.0",
|
||||||
"qrcode.react": "^3.1.0",
|
"qrcode.react": "^3.1.0",
|
||||||
"qs": "^6.11.1",
|
"qs": "^6.11.1",
|
||||||
|
|||||||
115
web/yarn.lock
115
web/yarn.lock
@@ -2066,10 +2066,10 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@monaco-editor/loader" "^1.4.0"
|
"@monaco-editor/loader" "^1.4.0"
|
||||||
|
|
||||||
"@next/env@14.2.25":
|
"@next/env@14.2.17":
|
||||||
version "14.2.25"
|
version "14.2.17"
|
||||||
resolved "https://registry.yarnpkg.com/@next/env/-/env-14.2.25.tgz#936d10b967e103e49a4bcea1e97292d5605278dd"
|
resolved "https://registry.npmjs.org/@next/env/-/env-14.2.17.tgz"
|
||||||
integrity sha512-JnzQ2cExDeG7FxJwqAksZ3aqVJrHjFwZQAEJ9gQZSoEhIow7SNoKZzju/AwQ+PLIR4NY8V0rhcVozx/2izDO0w==
|
integrity sha512-MCgO7VHxXo8sYR/0z+sk9fGyJJU636JyRmkjc7ZJY8Hurl8df35qG5hoAh5KMs75FLjhlEo9bb2LGe89Y/scDA==
|
||||||
|
|
||||||
"@next/eslint-plugin-next@14.0.4":
|
"@next/eslint-plugin-next@14.0.4":
|
||||||
version "14.0.4"
|
version "14.0.4"
|
||||||
@@ -2085,50 +2085,50 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
source-map "^0.7.0"
|
source-map "^0.7.0"
|
||||||
|
|
||||||
"@next/swc-darwin-arm64@14.2.25":
|
"@next/swc-darwin-arm64@14.2.17":
|
||||||
version "14.2.25"
|
version "14.2.17"
|
||||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.25.tgz#7bcccfda0c0ff045c45fbe34c491b7368e373e3d"
|
resolved "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.17.tgz"
|
||||||
integrity sha512-09clWInF1YRd6le00vt750s3m7SEYNehz9C4PUcSu3bAdCTpjIV4aTYQZ25Ehrr83VR1rZeqtKUPWSI7GfuKZQ==
|
integrity sha512-WiOf5nElPknrhRMTipXYTJcUz7+8IAjOYw3vXzj3BYRcVY0hRHKWgTgQ5439EvzQyHEko77XK+yN9x9OJ0oOog==
|
||||||
|
|
||||||
"@next/swc-darwin-x64@14.2.25":
|
"@next/swc-darwin-x64@14.2.17":
|
||||||
version "14.2.25"
|
version "14.2.17"
|
||||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.25.tgz#b489e209d7b405260b73f69a38186ed150fb7a08"
|
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.17.tgz#e29a17ef28d97c347c7d021f391e13b6c8e4c813"
|
||||||
integrity sha512-V+iYM/QR+aYeJl3/FWWU/7Ix4b07ovsQ5IbkwgUK29pTHmq+5UxeDr7/dphvtXEq5pLB/PucfcBNh9KZ8vWbug==
|
integrity sha512-29y425wYnL17cvtxrDQWC3CkXe/oRrdt8ie61S03VrpwpPRI0XsnTvtKO06XCisK4alaMnZlf8riwZIbJTaSHQ==
|
||||||
|
|
||||||
"@next/swc-linux-arm64-gnu@14.2.25":
|
"@next/swc-linux-arm64-gnu@14.2.17":
|
||||||
version "14.2.25"
|
version "14.2.17"
|
||||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.25.tgz#ba064fabfdce0190d9859493d8232fffa84ef2e2"
|
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.17.tgz#10e99c7aa60cc33f8b7633e045f74be9a43e7b0c"
|
||||||
integrity sha512-LFnV2899PJZAIEHQ4IMmZIgL0FBieh5keMnriMY1cK7ompR+JUd24xeTtKkcaw8QmxmEdhoE5Mu9dPSuDBgtTg==
|
integrity sha512-SSHLZls3ZwNEHsc+d0ynKS+7Af0Nr8+KTUBAy9pm6xz9SHkJ/TeuEg6W3cbbcMSh6j4ITvrjv3Oi8n27VR+IPw==
|
||||||
|
|
||||||
"@next/swc-linux-arm64-musl@14.2.25":
|
"@next/swc-linux-arm64-musl@14.2.17":
|
||||||
version "14.2.25"
|
version "14.2.17"
|
||||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.25.tgz#bf0018267e4e0fbfa1524750321f8cae855144a3"
|
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.17.tgz#9a5bb809d3c6aef96c409959aedae28b4e5db53d"
|
||||||
integrity sha512-QC5y5PPTmtqFExcKWKYgUNkHeHE/z3lUsu83di488nyP0ZzQ3Yse2G6TCxz6nNsQwgAx1BehAJTZez+UQxzLfw==
|
integrity sha512-VFge37us5LNPatB4F7iYeuGs9Dprqe4ZkW7lOEJM91r+Wf8EIdViWHLpIwfdDXinvCdLl6b4VyLpEBwpkctJHA==
|
||||||
|
|
||||||
"@next/swc-linux-x64-gnu@14.2.25":
|
"@next/swc-linux-x64-gnu@14.2.17":
|
||||||
version "14.2.25"
|
version "14.2.17"
|
||||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.25.tgz#64f5a6016a7148297ee80542e0fd788418a32472"
|
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.17.tgz#64e0ce01870e6dc45ae48f676d7cce82aedcdc62"
|
||||||
integrity sha512-y6/ML4b9eQ2D/56wqatTJN5/JR8/xdObU2Fb1RBidnrr450HLCKr6IJZbPqbv7NXmje61UyxjF5kvSajvjye5w==
|
integrity sha512-aaQlpxUVb9RZ41adlTYVQ3xvYEfBPUC8+6rDgmQ/0l7SvK8S1YNJzPmDPX6a4t0jLtIoNk7j+nroS/pB4nx7vQ==
|
||||||
|
|
||||||
"@next/swc-linux-x64-musl@14.2.25":
|
"@next/swc-linux-x64-musl@14.2.17":
|
||||||
version "14.2.25"
|
version "14.2.17"
|
||||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.25.tgz#58dc636d7c55828478159546f7b95ab1e902301c"
|
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.17.tgz#93114164b6ccfc533908193ab9065f0c3970abc3"
|
||||||
integrity sha512-sPX0TSXHGUOZFvv96GoBXpB3w4emMqKeMgemrSxI7A6l55VBJp/RKYLwZIB9JxSqYPApqiREaIIap+wWq0RU8w==
|
integrity sha512-HSyEiFaEY3ay5iATDqEup5WAfrhMATNJm8dYx3ZxL+e9eKv10XKZCwtZByDoLST7CyBmyDz+OFJL1wigyXeaoA==
|
||||||
|
|
||||||
"@next/swc-win32-arm64-msvc@14.2.25":
|
"@next/swc-win32-arm64-msvc@14.2.17":
|
||||||
version "14.2.25"
|
version "14.2.17"
|
||||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.25.tgz#93562d447c799bded1e89c1a62d5195a2a8c6c0d"
|
resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.17.tgz#4b99dea02178c112e5c33c742f9ff2a49b3b2939"
|
||||||
integrity sha512-ReO9S5hkA1DU2cFCsGoOEp7WJkhFzNbU/3VUF6XxNGUCQChyug6hZdYL/istQgfT/GWE6PNIg9cm784OI4ddxQ==
|
integrity sha512-h5qM9Btqv87eYH8ArrnLoAHLyi79oPTP2vlGNSg4CDvUiXgi7l0+5KuEGp5pJoMhjuv9ChRdm7mRlUUACeBt4w==
|
||||||
|
|
||||||
"@next/swc-win32-ia32-msvc@14.2.25":
|
"@next/swc-win32-ia32-msvc@14.2.17":
|
||||||
version "14.2.25"
|
version "14.2.17"
|
||||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.25.tgz#ad85a33466be1f41d083211ea21adc0d2c6e6554"
|
resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.17.tgz#f1c23955405a259b6d45c65f918575b01bcf0106"
|
||||||
integrity sha512-DZ/gc0o9neuCDyD5IumyTGHVun2dCox5TfPQI/BJTYwpSNYM3CZDI4i6TOdjeq1JMo+Ug4kPSMuZdwsycwFbAw==
|
integrity sha512-BD/G++GKSLexQjdyoEUgyo5nClU7er5rK0sE+HlEqnldJSm96CIr/+YOTT063LVTT/dUOeQsNgp5DXr86/K7/A==
|
||||||
|
|
||||||
"@next/swc-win32-x64-msvc@14.2.25":
|
"@next/swc-win32-x64-msvc@14.2.17":
|
||||||
version "14.2.25"
|
version "14.2.17"
|
||||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.25.tgz#3969c66609e683ec63a6a9f320a855f7be686a08"
|
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.17.tgz#44f5a4fcd8df1396a8d4326510ca2d92fb809cb3"
|
||||||
integrity sha512-KSznmS6eFjQ9RJ1nEc66kJvtGIL1iZMYmGEXsZPh2YtnLtqrgdVvKXJY2ScjjoFnG6nGLyPFR0UiEvDwVah4Tw==
|
integrity sha512-vkQfN1+4V4KqDibkW2q0sJ6CxQuXq5l2ma3z0BRcfIqkAMZiiW67T9yCpwqJKP68QghBtPEFjPAlaqe38O6frw==
|
||||||
|
|
||||||
"@nodelib/fs.scandir@2.1.5":
|
"@nodelib/fs.scandir@2.1.5":
|
||||||
version "2.1.5"
|
version "2.1.5"
|
||||||
@@ -5864,13 +5864,6 @@ dompurify@^3.2.1:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
"@types/trusted-types" "^2.0.7"
|
"@types/trusted-types" "^2.0.7"
|
||||||
|
|
||||||
dompurify@^3.2.4:
|
|
||||||
version "3.2.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.2.4.tgz#af5a5a11407524431456cf18836c55d13441cd8e"
|
|
||||||
integrity sha512-ysFSFEDVduQpyhzAob/kkuJjf5zWkZD8/A9ywSp1byueyuCfHamrCBa14/Oc2iiB0e51B+NpxSl5gmzn+Ms/mg==
|
|
||||||
optionalDependencies:
|
|
||||||
"@types/trusted-types" "^2.0.7"
|
|
||||||
|
|
||||||
domutils@^2.5.2, domutils@^2.8.0:
|
domutils@^2.5.2, domutils@^2.8.0:
|
||||||
version "2.8.0"
|
version "2.8.0"
|
||||||
resolved "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz"
|
resolved "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz"
|
||||||
@@ -9918,12 +9911,12 @@ neo-async@^2.6.2:
|
|||||||
resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz"
|
resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz"
|
||||||
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
|
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
|
||||||
|
|
||||||
next@^14.2.25:
|
next@^14.2.10:
|
||||||
version "14.2.25"
|
version "14.2.17"
|
||||||
resolved "https://registry.yarnpkg.com/next/-/next-14.2.25.tgz#0657551fde6a97f697cf9870e9ccbdaa465c6008"
|
resolved "https://registry.npmjs.org/next/-/next-14.2.17.tgz"
|
||||||
integrity sha512-N5M7xMc4wSb4IkPvEV5X2BRRXUmhVHNyaXwEM86+voXthSZz8ZiRyQW4p9mwAoAPIm6OzuVZtn7idgEJeAJN3Q==
|
integrity sha512-hNo/Zy701DDO3nzKkPmsLRlDfNCtb1OJxFUvjGEl04u7SFa3zwC6hqsOUzMajcaEOEV8ey1GjvByvrg0Qr5AiQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@next/env" "14.2.25"
|
"@next/env" "14.2.17"
|
||||||
"@swc/helpers" "0.5.5"
|
"@swc/helpers" "0.5.5"
|
||||||
busboy "1.6.0"
|
busboy "1.6.0"
|
||||||
caniuse-lite "^1.0.30001579"
|
caniuse-lite "^1.0.30001579"
|
||||||
@@ -9931,15 +9924,15 @@ next@^14.2.25:
|
|||||||
postcss "8.4.31"
|
postcss "8.4.31"
|
||||||
styled-jsx "5.1.1"
|
styled-jsx "5.1.1"
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
"@next/swc-darwin-arm64" "14.2.25"
|
"@next/swc-darwin-arm64" "14.2.17"
|
||||||
"@next/swc-darwin-x64" "14.2.25"
|
"@next/swc-darwin-x64" "14.2.17"
|
||||||
"@next/swc-linux-arm64-gnu" "14.2.25"
|
"@next/swc-linux-arm64-gnu" "14.2.17"
|
||||||
"@next/swc-linux-arm64-musl" "14.2.25"
|
"@next/swc-linux-arm64-musl" "14.2.17"
|
||||||
"@next/swc-linux-x64-gnu" "14.2.25"
|
"@next/swc-linux-x64-gnu" "14.2.17"
|
||||||
"@next/swc-linux-x64-musl" "14.2.25"
|
"@next/swc-linux-x64-musl" "14.2.17"
|
||||||
"@next/swc-win32-arm64-msvc" "14.2.25"
|
"@next/swc-win32-arm64-msvc" "14.2.17"
|
||||||
"@next/swc-win32-ia32-msvc" "14.2.25"
|
"@next/swc-win32-ia32-msvc" "14.2.17"
|
||||||
"@next/swc-win32-x64-msvc" "14.2.25"
|
"@next/swc-win32-x64-msvc" "14.2.17"
|
||||||
|
|
||||||
no-case@^3.0.4:
|
no-case@^3.0.4:
|
||||||
version "3.0.4"
|
version "3.0.4"
|
||||||
|
|||||||
Reference in New Issue
Block a user