Merge branch 'fix/update-default-github-star' into deploy/dev
This commit is contained in:
commit
a981bdc8e9
@ -325,8 +325,8 @@ class DatasetInitApi(Resource):
|
|||||||
@cloud_edition_billing_resource_check("vector_space")
|
@cloud_edition_billing_resource_check("vector_space")
|
||||||
@cloud_edition_billing_rate_limit_check("knowledge")
|
@cloud_edition_billing_rate_limit_check("knowledge")
|
||||||
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, dataset_operator, 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()
|
||||||
@ -704,8 +704,8 @@ class DocumentProcessingApi(DocumentResource):
|
|||||||
document_id = str(document_id)
|
document_id = str(document_id)
|
||||||
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, dataset_operator, 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":
|
||||||
@ -769,8 +769,8 @@ class DocumentMetadataApi(DocumentResource):
|
|||||||
doc_type = req_data.get("doc_type")
|
doc_type = req_data.get("doc_type")
|
||||||
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, dataset_operator, 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:
|
||||||
|
|||||||
@ -123,8 +123,8 @@ class DatasetDocumentSegmentListApi(Resource):
|
|||||||
raise NotFound("Document not found.")
|
raise NotFound("Document not found.")
|
||||||
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, owner, dataset_operator, 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)
|
||||||
@ -151,8 +151,8 @@ class DatasetDocumentSegmentApi(Resource):
|
|||||||
raise NotFound("Document not found.")
|
raise NotFound("Document not found.")
|
||||||
# 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, dataset_operator, or editor
|
||||||
if not current_user.is_editor:
|
if not current_user.is_dataset_editor:
|
||||||
raise Forbidden()
|
raise Forbidden()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -206,7 +206,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":
|
||||||
@ -281,8 +281,8 @@ class DatasetDocumentSegmentUpdateApi(Resource):
|
|||||||
).first()
|
).first()
|
||||||
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, dataset_operator, 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)
|
||||||
@ -325,8 +325,8 @@ class DatasetDocumentSegmentUpdateApi(Resource):
|
|||||||
).first()
|
).first()
|
||||||
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, owner, dataset_operator, 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)
|
||||||
@ -428,7 +428,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":
|
||||||
@ -528,8 +528,8 @@ class ChildChunkAddApi(Resource):
|
|||||||
).first()
|
).first()
|
||||||
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, dataset_operator, 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)
|
||||||
@ -579,8 +579,8 @@ class ChildChunkUpdateApi(Resource):
|
|||||||
).first()
|
).first()
|
||||||
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, owner, dataset_operator, 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)
|
||||||
@ -624,8 +624,8 @@ class ChildChunkUpdateApi(Resource):
|
|||||||
).first()
|
).first()
|
||||||
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, owner, dataset_operator, 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)
|
||||||
|
|||||||
@ -10,7 +10,7 @@ from controllers.service_api.app.error import NotChatAppError
|
|||||||
from controllers.service_api.wraps import FetchUserArg, WhereisUserArg, validate_app_token
|
from controllers.service_api.wraps import FetchUserArg, WhereisUserArg, validate_app_token
|
||||||
from core.app.entities.app_invoke_entities import InvokeFrom
|
from core.app.entities.app_invoke_entities import InvokeFrom
|
||||||
from fields.conversation_fields import message_file_fields
|
from fields.conversation_fields import message_file_fields
|
||||||
from fields.message_fields import feedback_fields, retriever_resource_fields
|
from fields.message_fields import agent_thought_fields, feedback_fields, retriever_resource_fields
|
||||||
from fields.raws import FilesContainedField
|
from fields.raws import FilesContainedField
|
||||||
from libs.helper import TimestampField, uuid_value
|
from libs.helper import TimestampField, uuid_value
|
||||||
from models.model import App, AppMode, EndUser
|
from models.model import App, AppMode, EndUser
|
||||||
@ -19,20 +19,6 @@ from services.message_service import MessageService
|
|||||||
|
|
||||||
|
|
||||||
class MessageListApi(Resource):
|
class MessageListApi(Resource):
|
||||||
agent_thought_fields = {
|
|
||||||
"id": fields.String,
|
|
||||||
"chain_id": fields.String,
|
|
||||||
"message_id": fields.String,
|
|
||||||
"position": fields.Integer,
|
|
||||||
"thought": fields.String,
|
|
||||||
"tool": fields.String,
|
|
||||||
"tool_labels": fields.Raw,
|
|
||||||
"tool_input": fields.String,
|
|
||||||
"created_at": TimestampField,
|
|
||||||
"observation": fields.String,
|
|
||||||
"message_files": fields.List(fields.Nested(message_file_fields)),
|
|
||||||
}
|
|
||||||
|
|
||||||
message_fields = {
|
message_fields = {
|
||||||
"id": fields.String,
|
"id": fields.String,
|
||||||
"conversation_id": fields.String,
|
"conversation_id": fields.String,
|
||||||
|
|||||||
@ -80,7 +80,7 @@ class AIModel(BaseModel):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif isinstance(invoke_error, InvokeError):
|
elif isinstance(invoke_error, InvokeError):
|
||||||
return invoke_error(description=f"[{self.provider_name}] {invoke_error.description}, {str(error)}")
|
return InvokeError(description=f"[{self.provider_name}] {invoke_error.description}, {str(error)}")
|
||||||
else:
|
else:
|
||||||
return error
|
return error
|
||||||
|
|
||||||
|
|||||||
@ -57,11 +57,19 @@ class StreamProcessor(ABC):
|
|||||||
|
|
||||||
# The branch_identify parameter is added to ensure that
|
# The branch_identify parameter is added to ensure that
|
||||||
# only nodes in the correct logical branch are included.
|
# only nodes in the correct logical branch are included.
|
||||||
|
reachable_node_ids.append(edge.target_node_id)
|
||||||
ids = self._fetch_node_ids_in_reachable_branch(edge.target_node_id, run_result.edge_source_handle)
|
ids = self._fetch_node_ids_in_reachable_branch(edge.target_node_id, run_result.edge_source_handle)
|
||||||
reachable_node_ids.extend(ids)
|
reachable_node_ids.extend(ids)
|
||||||
else:
|
else:
|
||||||
|
# if the condition edge in parallel, and the target node is not in parallel, we should not remove it
|
||||||
|
# Issues: #13626
|
||||||
|
if (
|
||||||
|
finished_node_id in self.graph.node_parallel_mapping
|
||||||
|
and edge.target_node_id not in self.graph.parallel_mapping
|
||||||
|
):
|
||||||
|
continue
|
||||||
unreachable_first_node_ids.append(edge.target_node_id)
|
unreachable_first_node_ids.append(edge.target_node_id)
|
||||||
|
unreachable_first_node_ids = list(set(unreachable_first_node_ids) - set(reachable_node_ids))
|
||||||
for node_id in unreachable_first_node_ids:
|
for node_id in unreachable_first_node_ids:
|
||||||
self._remove_node_ids_in_unreachable_branch(node_id, reachable_node_ids)
|
self._remove_node_ids_in_unreachable_branch(node_id, reachable_node_ids)
|
||||||
|
|
||||||
|
|||||||
@ -71,15 +71,8 @@ class OpenDALStorage(BaseStorage):
|
|||||||
logger.debug(f"file {filename} downloaded to {target_filepath}")
|
logger.debug(f"file {filename} downloaded to {target_filepath}")
|
||||||
|
|
||||||
def exists(self, filename: str) -> bool:
|
def exists(self, filename: str) -> bool:
|
||||||
# FIXME this is a workaround for opendal python-binding do not have a exists method and no better
|
res: bool = self.op.exists(path=filename)
|
||||||
# error handler here when opendal python-binding has a exists method, we should use it
|
return res
|
||||||
# more https://github.com/apache/opendal/blob/main/bindings/python/src/operator.rs
|
|
||||||
try:
|
|
||||||
res: bool = self.op.stat(path=filename).mode.is_file()
|
|
||||||
logger.debug(f"file {filename} checked")
|
|
||||||
return res
|
|
||||||
except Exception:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def delete(self, filename: str):
|
def delete(self, filename: str):
|
||||||
if self.exists(filename):
|
if self.exists(filename):
|
||||||
|
|||||||
@ -5,7 +5,6 @@ from .account import (
|
|||||||
InvitationCode,
|
InvitationCode,
|
||||||
Tenant,
|
Tenant,
|
||||||
TenantAccountJoin,
|
TenantAccountJoin,
|
||||||
TenantAccountJoinRole,
|
|
||||||
TenantAccountRole,
|
TenantAccountRole,
|
||||||
TenantStatus,
|
TenantStatus,
|
||||||
)
|
)
|
||||||
@ -156,7 +155,6 @@ __all__ = [
|
|||||||
"TagBinding",
|
"TagBinding",
|
||||||
"Tenant",
|
"Tenant",
|
||||||
"TenantAccountJoin",
|
"TenantAccountJoin",
|
||||||
"TenantAccountJoinRole",
|
|
||||||
"TenantAccountRole",
|
"TenantAccountRole",
|
||||||
"TenantDefaultModel",
|
"TenantDefaultModel",
|
||||||
"TenantPreferredModelProvider",
|
"TenantPreferredModelProvider",
|
||||||
|
|||||||
@ -220,13 +220,6 @@ class Tenant(db.Model): # type: ignore[name-defined]
|
|||||||
self.custom_config = json.dumps(value)
|
self.custom_config = json.dumps(value)
|
||||||
|
|
||||||
|
|
||||||
class TenantAccountJoinRole(enum.Enum):
|
|
||||||
OWNER = "owner"
|
|
||||||
ADMIN = "admin"
|
|
||||||
NORMAL = "normal"
|
|
||||||
DATASET_OPERATOR = "dataset_operator"
|
|
||||||
|
|
||||||
|
|
||||||
class TenantAccountJoin(db.Model): # type: ignore[name-defined]
|
class TenantAccountJoin(db.Model): # type: ignore[name-defined]
|
||||||
__tablename__ = "tenant_account_joins"
|
__tablename__ = "tenant_account_joins"
|
||||||
__table_args__ = (
|
__table_args__ = (
|
||||||
|
|||||||
2
api/poetry.lock
generated
2
api/poetry.lock
generated
@ -9922,4 +9922,4 @@ cffi = ["cffi (>=1.11)"]
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.1"
|
lock-version = "2.1"
|
||||||
python-versions = ">=3.11,<3.13"
|
python-versions = ">=3.11,<3.13"
|
||||||
content-hash = "b22f8a8e798de0ca992b6fce0296081e90732dd30a00dbc3b3db24158dc857e9"
|
content-hash = "13cbc3af42af0b3013c4a63024c372886ed88080579b1e2e5083e3dd191d080d"
|
||||||
|
|||||||
@ -105,7 +105,7 @@ bce-python-sdk = "~0.9.23"
|
|||||||
cos-python-sdk-v5 = "1.9.30"
|
cos-python-sdk-v5 = "1.9.30"
|
||||||
esdk-obs-python = "3.24.6.1"
|
esdk-obs-python = "3.24.6.1"
|
||||||
google-cloud-storage = "2.16.0"
|
google-cloud-storage = "2.16.0"
|
||||||
opendal = "~0.45.12"
|
opendal = "~0.45.16"
|
||||||
oss2 = "2.18.5"
|
oss2 = "2.18.5"
|
||||||
supabase = "~2.8.1"
|
supabase = "~2.8.1"
|
||||||
tos = "~2.7.1"
|
tos = "~2.7.1"
|
||||||
|
|||||||
@ -28,7 +28,6 @@ from models.account import (
|
|||||||
AccountStatus,
|
AccountStatus,
|
||||||
Tenant,
|
Tenant,
|
||||||
TenantAccountJoin,
|
TenantAccountJoin,
|
||||||
TenantAccountJoinRole,
|
|
||||||
TenantAccountRole,
|
TenantAccountRole,
|
||||||
TenantStatus,
|
TenantStatus,
|
||||||
)
|
)
|
||||||
@ -625,8 +624,8 @@ class TenantService:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def create_tenant_member(tenant: Tenant, account: Account, role: str = "normal") -> TenantAccountJoin:
|
def create_tenant_member(tenant: Tenant, account: Account, role: str = "normal") -> TenantAccountJoin:
|
||||||
"""Create tenant member"""
|
"""Create tenant member"""
|
||||||
if role == TenantAccountJoinRole.OWNER.value:
|
if role == TenantAccountRole.OWNER.value:
|
||||||
if TenantService.has_roles(tenant, [TenantAccountJoinRole.OWNER]):
|
if TenantService.has_roles(tenant, [TenantAccountRole.OWNER]):
|
||||||
logging.error(f"Tenant {tenant.id} has already an owner.")
|
logging.error(f"Tenant {tenant.id} has already an owner.")
|
||||||
raise Exception("Tenant already has an owner.")
|
raise Exception("Tenant already has an owner.")
|
||||||
|
|
||||||
@ -734,10 +733,10 @@ class TenantService:
|
|||||||
return updated_accounts
|
return updated_accounts
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def has_roles(tenant: Tenant, roles: list[TenantAccountJoinRole]) -> bool:
|
def has_roles(tenant: Tenant, roles: list[TenantAccountRole]) -> bool:
|
||||||
"""Check if user has any of the given roles for a tenant"""
|
"""Check if user has any of the given roles for a tenant"""
|
||||||
if not all(isinstance(role, TenantAccountJoinRole) for role in roles):
|
if not all(isinstance(role, TenantAccountRole) for role in roles):
|
||||||
raise ValueError("all roles must be TenantAccountJoinRole")
|
raise ValueError("all roles must be TenantAccountRole")
|
||||||
|
|
||||||
return (
|
return (
|
||||||
db.session.query(TenantAccountJoin)
|
db.session.query(TenantAccountJoin)
|
||||||
@ -749,7 +748,7 @@ class TenantService:
|
|||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_user_role(account: Account, tenant: Tenant) -> Optional[TenantAccountJoinRole]:
|
def get_user_role(account: Account, tenant: Tenant) -> Optional[TenantAccountRole]:
|
||||||
"""Get the role of the current account for a given tenant"""
|
"""Get the role of the current account for a given tenant"""
|
||||||
join = (
|
join = (
|
||||||
db.session.query(TenantAccountJoin)
|
db.session.query(TenantAccountJoin)
|
||||||
|
|||||||
@ -2,7 +2,7 @@ from flask_login import current_user # type: ignore
|
|||||||
|
|
||||||
from configs import dify_config
|
from configs import dify_config
|
||||||
from extensions.ext_database import db
|
from extensions.ext_database import db
|
||||||
from models.account import Tenant, TenantAccountJoin, TenantAccountJoinRole
|
from models.account import Tenant, TenantAccountJoin, TenantAccountRole
|
||||||
from services.account_service import TenantService
|
from services.account_service import TenantService
|
||||||
from services.feature_service import FeatureService
|
from services.feature_service import FeatureService
|
||||||
|
|
||||||
@ -18,7 +18,6 @@ class WorkspaceService:
|
|||||||
"plan": tenant.plan,
|
"plan": tenant.plan,
|
||||||
"status": tenant.status,
|
"status": tenant.status,
|
||||||
"created_at": tenant.created_at,
|
"created_at": tenant.created_at,
|
||||||
"in_trail": True,
|
|
||||||
"trial_end_reason": None,
|
"trial_end_reason": None,
|
||||||
"role": "normal",
|
"role": "normal",
|
||||||
}
|
}
|
||||||
@ -34,9 +33,7 @@ class WorkspaceService:
|
|||||||
|
|
||||||
can_replace_logo = FeatureService.get_features(tenant_info["id"]).can_replace_logo
|
can_replace_logo = FeatureService.get_features(tenant_info["id"]).can_replace_logo
|
||||||
|
|
||||||
if can_replace_logo and TenantService.has_roles(
|
if can_replace_logo and TenantService.has_roles(tenant, [TenantAccountRole.OWNER, TenantAccountRole.ADMIN]):
|
||||||
tenant, [TenantAccountJoinRole.OWNER, TenantAccountJoinRole.ADMIN]
|
|
||||||
):
|
|
||||||
base_url = dify_config.FILES_URL
|
base_url = dify_config.FILES_URL
|
||||||
replace_webapp_logo = (
|
replace_webapp_logo = (
|
||||||
f"{base_url}/files/workspaces/{tenant.id}/webapp-logo"
|
f"{base_url}/files/workspaces/{tenant.id}/webapp-logo"
|
||||||
|
|||||||
@ -723,6 +723,9 @@ SSRF_PROXY_HTTPS_URL=http://ssrf_proxy:3128
|
|||||||
# Maximum loop count in the workflow
|
# Maximum loop count in the workflow
|
||||||
LOOP_NODE_MAX_COUNT=100
|
LOOP_NODE_MAX_COUNT=100
|
||||||
|
|
||||||
|
# The maximum number of tools that can be used in the agent.
|
||||||
|
MAX_TOOLS_NUM=10
|
||||||
|
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
# Environment Variables for web Service
|
# Environment Variables for web Service
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
|
|||||||
@ -68,6 +68,7 @@ services:
|
|||||||
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-}
|
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-}
|
||||||
PM2_INSTANCES: ${PM2_INSTANCES:-2}
|
PM2_INSTANCES: ${PM2_INSTANCES:-2}
|
||||||
LOOP_NODE_MAX_COUNT: ${LOOP_NODE_MAX_COUNT:-100}
|
LOOP_NODE_MAX_COUNT: ${LOOP_NODE_MAX_COUNT:-100}
|
||||||
|
MAX_TOOLS_NUM: ${MAX_TOOLS_NUM:-10}
|
||||||
|
|
||||||
# The postgres database.
|
# The postgres database.
|
||||||
db:
|
db:
|
||||||
|
|||||||
@ -311,6 +311,7 @@ x-shared-env: &shared-api-worker-env
|
|||||||
SSRF_PROXY_HTTP_URL: ${SSRF_PROXY_HTTP_URL:-http://ssrf_proxy:3128}
|
SSRF_PROXY_HTTP_URL: ${SSRF_PROXY_HTTP_URL:-http://ssrf_proxy:3128}
|
||||||
SSRF_PROXY_HTTPS_URL: ${SSRF_PROXY_HTTPS_URL:-http://ssrf_proxy:3128}
|
SSRF_PROXY_HTTPS_URL: ${SSRF_PROXY_HTTPS_URL:-http://ssrf_proxy:3128}
|
||||||
LOOP_NODE_MAX_COUNT: ${LOOP_NODE_MAX_COUNT:-100}
|
LOOP_NODE_MAX_COUNT: ${LOOP_NODE_MAX_COUNT:-100}
|
||||||
|
MAX_TOOLS_NUM: ${MAX_TOOLS_NUM:-10}
|
||||||
TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000}
|
TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000}
|
||||||
PGUSER: ${PGUSER:-${DB_USERNAME}}
|
PGUSER: ${PGUSER:-${DB_USERNAME}}
|
||||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-${DB_PASSWORD}}
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-${DB_PASSWORD}}
|
||||||
@ -486,6 +487,7 @@ services:
|
|||||||
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-}
|
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-}
|
||||||
PM2_INSTANCES: ${PM2_INSTANCES:-2}
|
PM2_INSTANCES: ${PM2_INSTANCES:-2}
|
||||||
LOOP_NODE_MAX_COUNT: ${LOOP_NODE_MAX_COUNT:-100}
|
LOOP_NODE_MAX_COUNT: ${LOOP_NODE_MAX_COUNT:-100}
|
||||||
|
MAX_TOOLS_NUM: ${MAX_TOOLS_NUM:-10}
|
||||||
|
|
||||||
# The postgres database.
|
# The postgres database.
|
||||||
db:
|
db:
|
||||||
|
|||||||
@ -40,3 +40,6 @@ NEXT_PUBLIC_INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH=4000
|
|||||||
|
|
||||||
# Maximum loop count in the workflow
|
# Maximum loop count in the workflow
|
||||||
NEXT_PUBLIC_LOOP_NODE_MAX_COUNT=100
|
NEXT_PUBLIC_LOOP_NODE_MAX_COUNT=100
|
||||||
|
|
||||||
|
# Maximum number of tools in the agent/workflow
|
||||||
|
NEXT_PUBLIC_MAX_TOOLS_NUM=10
|
||||||
@ -1,8 +1,9 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import React, { useState } from 'react'
|
import React, { useEffect, useRef, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { RiCloseLine } from '@remixicon/react'
|
import { RiCloseLine } from '@remixicon/react'
|
||||||
|
import { useClickAway } from 'ahooks'
|
||||||
import ItemPanel from './item-panel'
|
import ItemPanel from './item-panel'
|
||||||
import Button from '@/app/components/base/button'
|
import Button from '@/app/components/base/button'
|
||||||
import { CuteRobot } from '@/app/components/base/icons/src/vender/solid/communication'
|
import { CuteRobot } from '@/app/components/base/icons/src/vender/solid/communication'
|
||||||
@ -31,6 +32,18 @@ const AgentSetting: FC<Props> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const [tempPayload, setTempPayload] = useState(payload)
|
const [tempPayload, setTempPayload] = useState(payload)
|
||||||
|
const ref = useRef(null)
|
||||||
|
const [mounted, setMounted] = useState(false)
|
||||||
|
|
||||||
|
useClickAway(() => {
|
||||||
|
if (mounted)
|
||||||
|
onCancel()
|
||||||
|
}, ref)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setMounted(true)
|
||||||
|
}, [])
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
onSave(tempPayload)
|
onSave(tempPayload)
|
||||||
}
|
}
|
||||||
@ -42,6 +55,7 @@ const AgentSetting: FC<Props> = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
ref={ref}
|
||||||
className='w-[640px] flex flex-col h-full overflow-hidden bg-components-panel-bg border-[0.5px] border-components-panel-border rounded-xl shadow-xl'
|
className='w-[640px] flex flex-col h-full overflow-hidden bg-components-panel-bg border-[0.5px] border-components-panel-border rounded-xl shadow-xl'
|
||||||
>
|
>
|
||||||
<div className='shrink-0 flex justify-between items-center pl-6 pr-5 h-14 border-b border-divider-regular'>
|
<div className='shrink-0 flex justify-between items-center pl-6 pr-5 h-14 border-b border-divider-regular'>
|
||||||
|
|||||||
@ -641,7 +641,7 @@ Chat applications support session persistence, allowing previous chat history to
|
|||||||
"tool_input": "{\"dalle2\": {\"prompt\": \"cat\"}}",
|
"tool_input": "{\"dalle2\": {\"prompt\": \"cat\"}}",
|
||||||
"created_at": 1705988186,
|
"created_at": 1705988186,
|
||||||
"observation": "image has been created and sent to user already, you should tell user to check it now.",
|
"observation": "image has been created and sent to user already, you should tell user to check it now.",
|
||||||
"message_files": [
|
"files": [
|
||||||
"976990d2-5294-47e6-8f14-7356ba9d2d76"
|
"976990d2-5294-47e6-8f14-7356ba9d2d76"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -655,7 +655,7 @@ Chat applications support session persistence, allowing previous chat history to
|
|||||||
"tool_input": "",
|
"tool_input": "",
|
||||||
"created_at": 1705988199,
|
"created_at": 1705988199,
|
||||||
"observation": "",
|
"observation": "",
|
||||||
"message_files": []
|
"files": []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -641,7 +641,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
|
|||||||
"tool_input": "{\"dalle2\": {\"prompt\": \"cat\"}}",
|
"tool_input": "{\"dalle2\": {\"prompt\": \"cat\"}}",
|
||||||
"created_at": 1705988186,
|
"created_at": 1705988186,
|
||||||
"observation": "画像はすでに作成され、ユーザーに送信されました。今すぐユーザーに確認するように伝えてください。",
|
"observation": "画像はすでに作成され、ユーザーに送信されました。今すぐユーザーに確認するように伝えてください。",
|
||||||
"message_files": [
|
"files": [
|
||||||
"976990d2-5294-47e6-8f14-7356ba9d2d76"
|
"976990d2-5294-47e6-8f14-7356ba9d2d76"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -655,7 +655,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
|
|||||||
"tool_input": "",
|
"tool_input": "",
|
||||||
"created_at": 1705988199,
|
"created_at": 1705988199,
|
||||||
"observation": "",
|
"observation": "",
|
||||||
"message_files": []
|
"files": []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -657,7 +657,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
|
|||||||
"tool_input": "{\"dalle2\": {\"prompt\": \"cat\"}}",
|
"tool_input": "{\"dalle2\": {\"prompt\": \"cat\"}}",
|
||||||
"created_at": 1705988186,
|
"created_at": 1705988186,
|
||||||
"observation": "image has been created and sent to user already, you should tell user to check it now.",
|
"observation": "image has been created and sent to user already, you should tell user to check it now.",
|
||||||
"message_files": [
|
"files": [
|
||||||
"976990d2-5294-47e6-8f14-7356ba9d2d76"
|
"976990d2-5294-47e6-8f14-7356ba9d2d76"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -671,7 +671,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
|
|||||||
"tool_input": "",
|
"tool_input": "",
|
||||||
"created_at": 1705988199,
|
"created_at": 1705988199,
|
||||||
"observation": "",
|
"observation": "",
|
||||||
"message_files": []
|
"files": []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const GithubStar: FC<{ className: string }> = (props) => {
|
|||||||
queryKey: ['github-star'],
|
queryKey: ['github-star'],
|
||||||
queryFn: getStar,
|
queryFn: getStar,
|
||||||
enabled: process.env.NODE_ENV !== 'development',
|
enabled: process.env.NODE_ENV !== 'development',
|
||||||
initialData: { stargazers_count: 6000 },
|
initialData: { stargazers_count: 81204 },
|
||||||
})
|
})
|
||||||
if (isFetching)
|
if (isFetching)
|
||||||
return null
|
return null
|
||||||
|
|||||||
@ -28,9 +28,6 @@ const nodeDefault: NodeDefault<LoopNodeType> = {
|
|||||||
checkValid(payload: LoopNodeType, t: any) {
|
checkValid(payload: LoopNodeType, t: any) {
|
||||||
let errorMessages = ''
|
let errorMessages = ''
|
||||||
|
|
||||||
if (!errorMessages && (!payload.break_conditions || payload.break_conditions.length === 0))
|
|
||||||
errorMessages = t(`${i18nPrefix}.fieldRequired`, { field: t('workflow.nodes.loop.breakCondition') })
|
|
||||||
|
|
||||||
payload.break_conditions!.forEach((condition) => {
|
payload.break_conditions!.forEach((condition) => {
|
||||||
if (!errorMessages && (!condition.variable_selector || condition.variable_selector.length === 0))
|
if (!errorMessages && (!condition.variable_selector || condition.variable_selector.length === 0))
|
||||||
errorMessages = t(`${i18nPrefix}.fieldRequired`, { field: t(`${i18nPrefix}.fields.variable`) })
|
errorMessages = t(`${i18nPrefix}.fieldRequired`, { field: t(`${i18nPrefix}.fields.variable`) })
|
||||||
|
|||||||
@ -55,6 +55,7 @@ const Panel: FC<NodePanelProps<LoopNodeType>> = ({
|
|||||||
<div>
|
<div>
|
||||||
<Field
|
<Field
|
||||||
title={<div className='pl-3'>{t(`${i18nPrefix}.breakCondition`)}</div>}
|
title={<div className='pl-3'>{t(`${i18nPrefix}.breakCondition`)}</div>}
|
||||||
|
tooltip={t(`${i18nPrefix}.breakConditionTip`)}
|
||||||
>
|
>
|
||||||
<ConditionWrap
|
<ConditionWrap
|
||||||
nodeId={id}
|
nodeId={id}
|
||||||
|
|||||||
@ -17,12 +17,14 @@ import { getOperators } from './utils'
|
|||||||
import { LogicalOperator } from './types'
|
import { LogicalOperator } from './types'
|
||||||
import type { HandleAddCondition, HandleAddSubVariableCondition, HandleRemoveCondition, HandleToggleConditionLogicalOperator, HandleToggleSubVariableConditionLogicalOperator, HandleUpdateCondition, HandleUpdateSubVariableCondition, LoopNodeType } from './types'
|
import type { HandleAddCondition, HandleAddSubVariableCondition, HandleRemoveCondition, HandleToggleConditionLogicalOperator, HandleToggleSubVariableConditionLogicalOperator, HandleUpdateCondition, HandleUpdateSubVariableCondition, LoopNodeType } from './types'
|
||||||
import useIsVarFileAttribute from './use-is-var-file-attribute'
|
import useIsVarFileAttribute from './use-is-var-file-attribute'
|
||||||
|
import { useStore } from '@/app/components/workflow/store'
|
||||||
|
|
||||||
const DELIMITER = '@@@@@'
|
const DELIMITER = '@@@@@'
|
||||||
const useConfig = (id: string, payload: LoopNodeType) => {
|
const useConfig = (id: string, payload: LoopNodeType) => {
|
||||||
const { nodesReadOnly: readOnly } = useNodesReadOnly()
|
const { nodesReadOnly: readOnly } = useNodesReadOnly()
|
||||||
const { isNodeInLoop } = useIsNodeInLoop(id)
|
const { isNodeInLoop } = useIsNodeInLoop(id)
|
||||||
const isChatMode = useIsChatMode()
|
const isChatMode = useIsChatMode()
|
||||||
|
const conversationVariables = useStore(s => s.conversationVariables)
|
||||||
|
|
||||||
const { inputs, setInputs } = useNodeCrud<LoopNodeType>(id, payload)
|
const { inputs, setInputs } = useNodeCrud<LoopNodeType>(id, payload)
|
||||||
|
|
||||||
@ -35,7 +37,7 @@ const useConfig = (id: string, payload: LoopNodeType) => {
|
|||||||
const beforeNodes = getBeforeNodesInSameBranch(id)
|
const beforeNodes = getBeforeNodesInSameBranch(id)
|
||||||
const loopChildrenNodes = getLoopNodeChildren(id)
|
const loopChildrenNodes = getLoopNodeChildren(id)
|
||||||
const canChooseVarNodes = [...beforeNodes, ...loopChildrenNodes]
|
const canChooseVarNodes = [...beforeNodes, ...loopChildrenNodes]
|
||||||
const childrenNodeVars = toNodeOutputVars(loopChildrenNodes, isChatMode)
|
const childrenNodeVars = toNodeOutputVars(loopChildrenNodes, isChatMode, undefined, [], conversationVariables)
|
||||||
|
|
||||||
// single run
|
// single run
|
||||||
const loopInputKey = `${id}.input_selector`
|
const loopInputKey = `${id}.input_selector`
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import React, { useEffect } from 'react'
|
import React, { useCallback, useEffect } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { useDebounceFn } from 'ahooks'
|
||||||
|
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { useRouter } from 'next/navigation'
|
import { useRouter } from 'next/navigation'
|
||||||
@ -39,7 +40,7 @@ const InstallForm = () => {
|
|||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
formState: { errors },
|
formState: { errors, isSubmitting },
|
||||||
} = useForm<AccountFormValues>({
|
} = useForm<AccountFormValues>({
|
||||||
resolver: zodResolver(accountFormSchema),
|
resolver: zodResolver(accountFormSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
@ -59,9 +60,22 @@ const InstallForm = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleSetting = async () => {
|
const handleSetting = async () => {
|
||||||
|
if (isSubmitting) return
|
||||||
handleSubmit(onSubmit)()
|
handleSubmit(onSubmit)()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { run: debouncedHandleKeyDown } = useDebounceFn(
|
||||||
|
(e: React.KeyboardEvent) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
e.preventDefault()
|
||||||
|
handleSetting()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ wait: 200 },
|
||||||
|
)
|
||||||
|
|
||||||
|
const handleKeyDown = useCallback(debouncedHandleKeyDown, [debouncedHandleKeyDown])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchSetupStatus().then((res: SetupStatusResponse) => {
|
fetchSetupStatus().then((res: SetupStatusResponse) => {
|
||||||
if (res.step === 'finished') {
|
if (res.step === 'finished') {
|
||||||
@ -90,7 +104,7 @@ const InstallForm = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="grow mt-8 sm:mx-auto sm:w-full sm:max-w-md">
|
<div className="grow mt-8 sm:mx-auto sm:w-full sm:max-w-md">
|
||||||
<div className="bg-white ">
|
<div className="bg-white ">
|
||||||
<form onSubmit={handleSubmit(onSubmit)}>
|
<form onSubmit={handleSubmit(onSubmit)} onKeyDown={handleKeyDown}>
|
||||||
<div className='mb-5'>
|
<div className='mb-5'>
|
||||||
<label htmlFor="email" className="my-2 flex items-center justify-between text-sm font-medium text-gray-900">
|
<label htmlFor="email" className="my-2 flex items-center justify-between text-sm font-medium text-gray-900">
|
||||||
{t('login.email')}
|
{t('login.email')}
|
||||||
@ -99,7 +113,7 @@ const InstallForm = () => {
|
|||||||
<input
|
<input
|
||||||
{...register('email')}
|
{...register('email')}
|
||||||
placeholder={t('login.emailPlaceholder') || ''}
|
placeholder={t('login.emailPlaceholder') || ''}
|
||||||
className={'appearance-none block w-full rounded-lg pl-[14px] px-3 py-2 border border-gray-200 hover:border-gray-300 hover:shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 placeholder-gray-400 caret-primary-600 sm:text-sm'}
|
className={'appearance-none block w-full rounded-lg pl-[14px] px-3 py-2 border border-gray-200 hover:border-gray-300 hover:shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 placeholder:text-gray-400 caret-primary-600 sm:text-sm'}
|
||||||
/>
|
/>
|
||||||
{errors.email && <span className='text-red-400 text-sm'>{t(`${errors.email?.message}`)}</span>}
|
{errors.email && <span className='text-red-400 text-sm'>{t(`${errors.email?.message}`)}</span>}
|
||||||
</div>
|
</div>
|
||||||
@ -114,7 +128,7 @@ const InstallForm = () => {
|
|||||||
<input
|
<input
|
||||||
{...register('name')}
|
{...register('name')}
|
||||||
placeholder={t('login.namePlaceholder') || ''}
|
placeholder={t('login.namePlaceholder') || ''}
|
||||||
className={'appearance-none block w-full rounded-lg pl-[14px] px-3 py-2 border border-gray-200 hover:border-gray-300 hover:shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 placeholder-gray-400 caret-primary-600 sm:text-sm pr-10'}
|
className={'appearance-none block w-full rounded-lg pl-[14px] px-3 py-2 border border-gray-200 hover:border-gray-300 hover:shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 placeholder:text-gray-400 caret-primary-600 sm:text-sm pr-10'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{errors.name && <span className='text-red-400 text-sm'>{t(`${errors.name.message}`)}</span>}
|
{errors.name && <span className='text-red-400 text-sm'>{t(`${errors.name.message}`)}</span>}
|
||||||
@ -129,7 +143,7 @@ const InstallForm = () => {
|
|||||||
{...register('password')}
|
{...register('password')}
|
||||||
type={showPassword ? 'text' : 'password'}
|
type={showPassword ? 'text' : 'password'}
|
||||||
placeholder={t('login.passwordPlaceholder') || ''}
|
placeholder={t('login.passwordPlaceholder') || ''}
|
||||||
className={'appearance-none block w-full rounded-lg pl-[14px] px-3 py-2 border border-gray-200 hover:border-gray-300 hover:shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 placeholder-gray-400 caret-primary-600 sm:text-sm pr-10'}
|
className={'appearance-none block w-full rounded-lg pl-[14px] px-3 py-2 border border-gray-200 hover:border-gray-300 hover:shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 placeholder:text-gray-400 caret-primary-600 sm:text-sm pr-10'}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="absolute inset-y-0 right-0 flex items-center pr-3">
|
<div className="absolute inset-y-0 right-0 flex items-center pr-3">
|
||||||
|
|||||||
@ -47,6 +47,7 @@ const LocaleLayout = ({
|
|||||||
data-public-maintenance-notice={process.env.NEXT_PUBLIC_MAINTENANCE_NOTICE}
|
data-public-maintenance-notice={process.env.NEXT_PUBLIC_MAINTENANCE_NOTICE}
|
||||||
data-public-site-about={process.env.NEXT_PUBLIC_SITE_ABOUT}
|
data-public-site-about={process.env.NEXT_PUBLIC_SITE_ABOUT}
|
||||||
data-public-text-generation-timeout-ms={process.env.NEXT_PUBLIC_TEXT_GENERATION_TIMEOUT_MS}
|
data-public-text-generation-timeout-ms={process.env.NEXT_PUBLIC_TEXT_GENERATION_TIMEOUT_MS}
|
||||||
|
data-public-max-tools-num={process.env.NEXT_PUBLIC_MAX_TOOLS_NUM}
|
||||||
data-public-top-k-max-value={process.env.NEXT_PUBLIC_TOP_K_MAX_VALUE}
|
data-public-top-k-max-value={process.env.NEXT_PUBLIC_TOP_K_MAX_VALUE}
|
||||||
data-public-indexing-max-segmentation-tokens-length={process.env.NEXT_PUBLIC_INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH}
|
data-public-indexing-max-segmentation-tokens-length={process.env.NEXT_PUBLIC_INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH}
|
||||||
data-public-loop-node-max-count={process.env.NEXT_PUBLIC_LOOP_NODE_MAX_COUNT}
|
data-public-loop-node-max-count={process.env.NEXT_PUBLIC_LOOP_NODE_MAX_COUNT}
|
||||||
|
|||||||
@ -162,7 +162,14 @@ export const ANNOTATION_DEFAULT = {
|
|||||||
score_threshold: 0.9,
|
score_threshold: 0.9,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MAX_TOOLS_NUM = 10
|
export let maxToolsNum = 10
|
||||||
|
|
||||||
|
if (process.env.NEXT_PUBLIC_MAX_TOOLS_NUM && process.env.NEXT_PUBLIC_MAX_TOOLS_NUM !== '')
|
||||||
|
maxToolsNum = Number.parseInt(process.env.NEXT_PUBLIC_MAX_TOOLS_NUM)
|
||||||
|
else if (globalThis.document?.body?.getAttribute('data-public-max-tools-num') && globalThis.document.body.getAttribute('data-public-max-tools-num') !== '')
|
||||||
|
maxToolsNum = Number.parseInt(globalThis.document.body.getAttribute('data-public-max-tools-num') as string)
|
||||||
|
|
||||||
|
export const MAX_TOOLS_NUM = maxToolsNum
|
||||||
|
|
||||||
export const DEFAULT_AGENT_SETTING = {
|
export const DEFAULT_AGENT_SETTING = {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
|||||||
@ -49,7 +49,6 @@ const initialWorkspaceInfo: ICurrentWorkspace = {
|
|||||||
created_at: 0,
|
created_at: 0,
|
||||||
role: 'normal',
|
role: 'normal',
|
||||||
providers: [],
|
providers: [],
|
||||||
in_trail: true,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const AppContext = createContext<AppContextValue>({
|
const AppContext = createContext<AppContextValue>({
|
||||||
|
|||||||
@ -703,6 +703,7 @@ const translation = {
|
|||||||
loop_other: '{{count}} Loops',
|
loop_other: '{{count}} Loops',
|
||||||
currentLoop: 'Current Loop',
|
currentLoop: 'Current Loop',
|
||||||
breakCondition: 'Loop Termination Condition',
|
breakCondition: 'Loop Termination Condition',
|
||||||
|
breakConditionTip: 'Only variables within loops with termination conditions and conversation variables can be referenced.',
|
||||||
loopMaxCount: 'Maximum Loop Count',
|
loopMaxCount: 'Maximum Loop Count',
|
||||||
loopMaxCountError: 'Please enter a valid maximum loop count, ranging from 1 to {{maxCount}}',
|
loopMaxCountError: 'Please enter a valid maximum loop count, ranging from 1 to {{maxCount}}',
|
||||||
errorResponseMethod: 'Error Response Method',
|
errorResponseMethod: 'Error Response Method',
|
||||||
|
|||||||
@ -704,6 +704,7 @@ const translation = {
|
|||||||
loop_other: '{{count}} 个循环',
|
loop_other: '{{count}} 个循环',
|
||||||
currentLoop: '当前循环',
|
currentLoop: '当前循环',
|
||||||
breakCondition: '循环终止条件',
|
breakCondition: '循环终止条件',
|
||||||
|
breakConditionTip: '支持引用终止条件循环内的变量和会话变量。',
|
||||||
loopMaxCount: '最大循环次数',
|
loopMaxCount: '最大循环次数',
|
||||||
loopMaxCountError: '请输入正确的 最大循环次数,范围为 1 到 {{maxCount}}',
|
loopMaxCountError: '请输入正确的 最大循环次数,范围为 1 到 {{maxCount}}',
|
||||||
errorResponseMethod: '错误响应方法',
|
errorResponseMethod: '错误响应方法',
|
||||||
|
|||||||
@ -1,23 +1,23 @@
|
|||||||
import type { I18nText } from '@/i18n/language'
|
import type { I18nText } from '@/i18n/language'
|
||||||
|
|
||||||
export interface CommonResponse {
|
export type CommonResponse = {
|
||||||
result: 'success' | 'fail'
|
result: 'success' | 'fail'
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OauthResponse {
|
export type OauthResponse = {
|
||||||
redirect_url: string
|
redirect_url: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SetupStatusResponse {
|
export type SetupStatusResponse = {
|
||||||
step: 'finished' | 'not_started'
|
step: 'finished' | 'not_started'
|
||||||
setup_at?: Date
|
setup_at?: Date
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface InitValidateStatusResponse {
|
export type InitValidateStatusResponse = {
|
||||||
status: 'finished' | 'not_started'
|
status: 'finished' | 'not_started'
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UserProfileResponse {
|
export type UserProfileResponse = {
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
email: string
|
email: string
|
||||||
@ -33,13 +33,13 @@ export interface UserProfileResponse {
|
|||||||
created_at?: string
|
created_at?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UserProfileOriginResponse {
|
export type UserProfileOriginResponse = {
|
||||||
json: () => Promise<UserProfileResponse>
|
json: () => Promise<UserProfileResponse>
|
||||||
bodyUsed: boolean
|
bodyUsed: boolean
|
||||||
headers: any
|
headers: any
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LangGeniusVersionResponse {
|
export type LangGeniusVersionResponse = {
|
||||||
current_version: string
|
current_version: string
|
||||||
latest_version: string
|
latest_version: string
|
||||||
version: string
|
version: string
|
||||||
@ -49,7 +49,7 @@ export interface LangGeniusVersionResponse {
|
|||||||
current_env: string
|
current_env: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TenantInfoResponse {
|
export type TenantInfoResponse = {
|
||||||
name: string
|
name: string
|
||||||
created_at: string
|
created_at: string
|
||||||
providers: Array<{
|
providers: Array<{
|
||||||
@ -80,14 +80,14 @@ export enum ProviderName {
|
|||||||
Tongyi = 'tongyi',
|
Tongyi = 'tongyi',
|
||||||
ChatGLM = 'chatglm',
|
ChatGLM = 'chatglm',
|
||||||
}
|
}
|
||||||
export interface ProviderAzureToken {
|
export type ProviderAzureToken = {
|
||||||
openai_api_base?: string
|
openai_api_base?: string
|
||||||
openai_api_key?: string
|
openai_api_key?: string
|
||||||
}
|
}
|
||||||
export interface ProviderAnthropicToken {
|
export type ProviderAnthropicToken = {
|
||||||
anthropic_api_key?: string
|
anthropic_api_key?: string
|
||||||
}
|
}
|
||||||
export interface ProviderTokenType {
|
export type ProviderTokenType = {
|
||||||
[ProviderName.OPENAI]: string
|
[ProviderName.OPENAI]: string
|
||||||
[ProviderName.AZURE_OPENAI]: ProviderAzureToken
|
[ProviderName.AZURE_OPENAI]: ProviderAzureToken
|
||||||
[ProviderName.ANTHROPIC]: ProviderAnthropicToken
|
[ProviderName.ANTHROPIC]: ProviderAnthropicToken
|
||||||
@ -110,14 +110,14 @@ export type ProviderHosted = Provider & {
|
|||||||
quota_used: number
|
quota_used: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AccountIntegrate {
|
export type AccountIntegrate = {
|
||||||
provider: 'google' | 'github'
|
provider: 'google' | 'github'
|
||||||
created_at: number
|
created_at: number
|
||||||
is_bound: boolean
|
is_bound: boolean
|
||||||
link: string
|
link: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IWorkspace {
|
export type IWorkspace = {
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
plan: string
|
plan: string
|
||||||
@ -129,7 +129,6 @@ export interface IWorkspace {
|
|||||||
export type ICurrentWorkspace = Omit<IWorkspace, 'current'> & {
|
export type ICurrentWorkspace = Omit<IWorkspace, 'current'> & {
|
||||||
role: 'owner' | 'admin' | 'editor' | 'dataset_operator' | 'normal'
|
role: 'owner' | 'admin' | 'editor' | 'dataset_operator' | 'normal'
|
||||||
providers: Provider[]
|
providers: Provider[]
|
||||||
in_trail: boolean
|
|
||||||
trial_end_reason?: string
|
trial_end_reason?: string
|
||||||
custom_config?: {
|
custom_config?: {
|
||||||
remove_webapp_brand?: boolean
|
remove_webapp_brand?: boolean
|
||||||
@ -137,7 +136,7 @@ export type ICurrentWorkspace = Omit<IWorkspace, 'current'> & {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DataSourceNotionPage {
|
export type DataSourceNotionPage = {
|
||||||
page_icon: null | {
|
page_icon: null | {
|
||||||
type: string | null
|
type: string | null
|
||||||
url: string | null
|
url: string | null
|
||||||
@ -156,7 +155,7 @@ export type NotionPage = DataSourceNotionPage & {
|
|||||||
|
|
||||||
export type DataSourceNotionPageMap = Record<string, DataSourceNotionPage & { workspace_id: string }>
|
export type DataSourceNotionPageMap = Record<string, DataSourceNotionPage & { workspace_id: string }>
|
||||||
|
|
||||||
export interface DataSourceNotionWorkspace {
|
export type DataSourceNotionWorkspace = {
|
||||||
workspace_name: string
|
workspace_name: string
|
||||||
workspace_id: string
|
workspace_id: string
|
||||||
workspace_icon: string | null
|
workspace_icon: string | null
|
||||||
@ -166,7 +165,7 @@ export interface DataSourceNotionWorkspace {
|
|||||||
|
|
||||||
export type DataSourceNotionWorkspaceMap = Record<string, DataSourceNotionWorkspace>
|
export type DataSourceNotionWorkspaceMap = Record<string, DataSourceNotionWorkspace>
|
||||||
|
|
||||||
export interface DataSourceNotion {
|
export type DataSourceNotion = {
|
||||||
id: string
|
id: string
|
||||||
provider: string
|
provider: string
|
||||||
is_bound: boolean
|
is_bound: boolean
|
||||||
@ -181,12 +180,12 @@ export enum DataSourceProvider {
|
|||||||
jinaReader = 'jinareader',
|
jinaReader = 'jinareader',
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FirecrawlConfig {
|
export type FirecrawlConfig = {
|
||||||
api_key: string
|
api_key: string
|
||||||
base_url: string
|
base_url: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DataSourceItem {
|
export type DataSourceItem = {
|
||||||
id: string
|
id: string
|
||||||
category: DataSourceCategory
|
category: DataSourceCategory
|
||||||
provider: DataSourceProvider
|
provider: DataSourceProvider
|
||||||
@ -195,15 +194,15 @@ export interface DataSourceItem {
|
|||||||
updated_at: number
|
updated_at: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DataSources {
|
export type DataSources = {
|
||||||
sources: DataSourceItem[]
|
sources: DataSourceItem[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GithubRepo {
|
export type GithubRepo = {
|
||||||
stargazers_count: number
|
stargazers_count: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PluginProvider {
|
export type PluginProvider = {
|
||||||
tool_name: string
|
tool_name: string
|
||||||
is_enabled: boolean
|
is_enabled: boolean
|
||||||
credentials: {
|
credentials: {
|
||||||
@ -211,7 +210,7 @@ export interface PluginProvider {
|
|||||||
} | null
|
} | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FileUploadConfigResponse {
|
export type FileUploadConfigResponse = {
|
||||||
batch_count_limit: number
|
batch_count_limit: number
|
||||||
image_file_size_limit?: number | string // default is 10MB
|
image_file_size_limit?: number | string // default is 10MB
|
||||||
file_size_limit: number // default is 15MB
|
file_size_limit: number // default is 15MB
|
||||||
@ -234,14 +233,14 @@ export type InvitationResponse = CommonResponse & {
|
|||||||
invitation_results: InvitationResult[]
|
invitation_results: InvitationResult[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ApiBasedExtension {
|
export type ApiBasedExtension = {
|
||||||
id?: string
|
id?: string
|
||||||
name?: string
|
name?: string
|
||||||
api_endpoint?: string
|
api_endpoint?: string
|
||||||
api_key?: string
|
api_key?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CodeBasedExtensionForm {
|
export type CodeBasedExtensionForm = {
|
||||||
type: string
|
type: string
|
||||||
label: I18nText
|
label: I18nText
|
||||||
variable: string
|
variable: string
|
||||||
@ -252,17 +251,17 @@ export interface CodeBasedExtensionForm {
|
|||||||
max_length?: number
|
max_length?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CodeBasedExtensionItem {
|
export type CodeBasedExtensionItem = {
|
||||||
name: string
|
name: string
|
||||||
label: any
|
label: any
|
||||||
form_schema: CodeBasedExtensionForm[]
|
form_schema: CodeBasedExtensionForm[]
|
||||||
}
|
}
|
||||||
export interface CodeBasedExtension {
|
export type CodeBasedExtension = {
|
||||||
module: string
|
module: string
|
||||||
data: CodeBasedExtensionItem[]
|
data: CodeBasedExtensionItem[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ExternalDataTool {
|
export type ExternalDataTool = {
|
||||||
type?: string
|
type?: string
|
||||||
label?: string
|
label?: string
|
||||||
icon?: string
|
icon?: string
|
||||||
@ -274,7 +273,7 @@ export interface ExternalDataTool {
|
|||||||
} & Partial<Record<string, any>>
|
} & Partial<Record<string, any>>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ModerateResponse {
|
export type ModerateResponse = {
|
||||||
flagged: boolean
|
flagged: boolean
|
||||||
text: string
|
text: string
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user