diff --git a/api/controllers/common/fields.py b/api/controllers/common/fields.py index 79869916ed..3466eea1f6 100644 --- a/api/controllers/common/fields.py +++ b/api/controllers/common/fields.py @@ -1,5 +1,7 @@ from flask_restful import fields +from libs.helper import AppIconUrlField + parameters__system_parameters = { "image_file_size_limit": fields.Integer, "video_file_size_limit": fields.Integer, @@ -22,3 +24,20 @@ parameters_fields = { "file_upload": fields.Raw, "system_parameters": fields.Nested(parameters__system_parameters), } + +site_fields = { + "title": fields.String, + "chat_color_theme": fields.String, + "chat_color_theme_inverted": fields.Boolean, + "icon_type": fields.String, + "icon": fields.String, + "icon_background": fields.String, + "icon_url": AppIconUrlField, + "description": fields.String, + "copyright": fields.String, + "privacy_policy": fields.String, + "custom_disclaimer": fields.String, + "default_language": fields.String, + "show_workflow_steps": fields.Boolean, + "use_icon_as_answer_icon": fields.Boolean, +} diff --git a/api/controllers/service_api/__init__.py b/api/controllers/service_api/__init__.py index d97074e8b9..d964e27819 100644 --- a/api/controllers/service_api/__init__.py +++ b/api/controllers/service_api/__init__.py @@ -6,6 +6,6 @@ bp = Blueprint("service_api", __name__, url_prefix="/v1") api = ExternalApi(bp) from . import index -from .app import annotation, app, audio, completion, conversation, file, message, workflow +from .app import annotation, app, audio, completion, conversation, file, message, site, workflow from .dataset import dataset, document, hit_testing, metadata, segment, upload_file from .workspace import models diff --git a/api/controllers/service_api/app/site.py b/api/controllers/service_api/app/site.py new file mode 100644 index 0000000000..e752dfee30 --- /dev/null +++ b/api/controllers/service_api/app/site.py @@ -0,0 +1,30 @@ +from flask_restful import Resource, marshal_with +from werkzeug.exceptions import Forbidden + +from controllers.common import fields +from controllers.service_api import api +from controllers.service_api.wraps import validate_app_token +from extensions.ext_database import db +from models.account import TenantStatus +from models.model import App, Site + + +class AppSiteApi(Resource): + """Resource for app sites.""" + + @validate_app_token + @marshal_with(fields.site_fields) + def get(self, app_model: App): + """Retrieve app site info.""" + site = db.session.query(Site).filter(Site.app_id == app_model.id).first() + + if not site: + raise Forbidden() + + if app_model.tenant.status == TenantStatus.ARCHIVE: + raise Forbidden() + + return site + + +api.add_resource(AppSiteApi, "/site") diff --git a/api/core/workflow/nodes/code/code_node.py b/api/core/workflow/nodes/code/code_node.py index 3c34c5b4e7..804c05f9f4 100644 --- a/api/core/workflow/nodes/code/code_node.py +++ b/api/core/workflow/nodes/code/code_node.py @@ -127,7 +127,7 @@ class CodeNode(BaseNode[CodeNodeData]): depth: int = 1, ): if depth > dify_config.CODE_MAX_DEPTH: - raise DepthLimitError(f"Depth limit ${dify_config.CODE_MAX_DEPTH} reached, object too deep.") + raise DepthLimitError(f"Depth limit {dify_config.CODE_MAX_DEPTH} reached, object too deep.") transformed_result: dict[str, Any] = {} if output_schema is None: diff --git a/api/pyproject.toml b/api/pyproject.toml index 988c7f500b..18fe5db1a6 100644 --- a/api/pyproject.toml +++ b/api/pyproject.toml @@ -14,7 +14,7 @@ dependencies = [ "chardet~=5.1.0", "flask~=3.1.0", "flask-compress~=1.17", - "flask-cors~=4.0.0", + "flask-cors~=5.0.0", "flask-login~=0.6.3", "flask-migrate~=4.0.7", "flask-restful~=0.3.10", @@ -71,17 +71,16 @@ dependencies = [ "python-docx~=1.1.0", "python-dotenv==1.0.1", "pyyaml~=6.0.1", - "readabilipy==0.2.0", + "readabilipy~=0.3.0", "redis[hiredis]~=6.0.0", "resend~=2.9.0", - "sentry-sdk[flask]~=1.44.1", + "sentry-sdk[flask]~=2.28.0", "sqlalchemy~=2.0.29", "starlette==0.41.0", "tiktoken~=0.9.0", - "tokenizers~=0.15.0", - "transformers~=4.39.0", + "transformers~=4.51.0", "unstructured[docx,epub,md,ppt,pptx]~=0.16.1", - "weave~=0.51.34", + "weave~=0.51.0", "yarl~=1.18.3", "webvtt-py~=0.5.1", ] @@ -195,7 +194,7 @@ vdb = [ "tcvectordb~=1.6.4", "tidb-vector==0.0.9", "upstash-vector==0.6.0", - "volcengine-compat~=1.0.156", + "volcengine-compat~=1.0.0", "weaviate-client~=3.24.0", "xinference-client~=1.2.2", ] diff --git a/api/uv.lock b/api/uv.lock index c3eca17eb8..672755cb8a 100644 --- a/api/uv.lock +++ b/api/uv.lock @@ -1251,7 +1251,6 @@ dependencies = [ { name = "sqlalchemy" }, { name = "starlette" }, { name = "tiktoken" }, - { name = "tokenizers" }, { name = "transformers" }, { name = "unstructured", extra = ["docx", "epub", "md", "ppt", "pptx"] }, { name = "weave" }, @@ -1360,7 +1359,7 @@ requires-dist = [ { name = "chardet", specifier = "~=5.1.0" }, { name = "flask", specifier = "~=3.1.0" }, { name = "flask-compress", specifier = "~=1.17" }, - { name = "flask-cors", specifier = "~=4.0.0" }, + { name = "flask-cors", specifier = "~=5.0.0" }, { name = "flask-login", specifier = "~=0.6.3" }, { name = "flask-migrate", specifier = "~=4.0.7" }, { name = "flask-restful", specifier = "~=0.3.10" }, @@ -1415,17 +1414,16 @@ requires-dist = [ { name = "python-docx", specifier = "~=1.1.0" }, { name = "python-dotenv", specifier = "==1.0.1" }, { name = "pyyaml", specifier = "~=6.0.1" }, - { name = "readabilipy", specifier = "==0.2.0" }, + { name = "readabilipy", specifier = "~=0.3.0" }, { name = "redis", extras = ["hiredis"], specifier = "~=6.0.0" }, { name = "resend", specifier = "~=2.9.0" }, - { name = "sentry-sdk", extras = ["flask"], specifier = "~=1.44.1" }, + { name = "sentry-sdk", extras = ["flask"], specifier = "~=2.28.0" }, { name = "sqlalchemy", specifier = "~=2.0.29" }, { name = "starlette", specifier = "==0.41.0" }, { name = "tiktoken", specifier = "~=0.9.0" }, - { name = "tokenizers", specifier = "~=0.15.0" }, - { name = "transformers", specifier = "~=4.39.0" }, + { name = "transformers", specifier = "~=4.51.0" }, { name = "unstructured", extras = ["docx", "epub", "md", "ppt", "pptx"], specifier = "~=0.16.1" }, - { name = "weave", specifier = "~=0.51.34" }, + { name = "weave", specifier = "~=0.51.0" }, { name = "webvtt-py", specifier = "~=0.5.1" }, { name = "yarl", specifier = "~=1.18.3" }, ] @@ -1514,7 +1512,7 @@ vdb = [ { name = "tcvectordb", specifier = "~=1.6.4" }, { name = "tidb-vector", specifier = "==0.0.9" }, { name = "upstash-vector", specifier = "==0.6.0" }, - { name = "volcengine-compat", specifier = "~=1.0.156" }, + { name = "volcengine-compat", specifier = "~=1.0.0" }, { name = "weaviate-client", specifier = "~=3.24.0" }, { name = "xinference-client", specifier = "~=1.2.2" }, ] @@ -1732,14 +1730,15 @@ wheels = [ [[package]] name = "flask-cors" -version = "4.0.2" +version = "5.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "flask" }, + { name = "werkzeug" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1c/41/89ea5af8b9d647036237c528abb2fdf8bb10b23b3f750e8e2da07873b270/flask_cors-4.0.2.tar.gz", hash = "sha256:493b98e2d1e2f1a4720a7af25693ef2fe32fbafec09a2f72c59f3e475eda61d2", size = 30954 } +sdist = { url = "https://files.pythonhosted.org/packages/32/d8/667bd90d1ee41c96e938bafe81052494e70b7abd9498c4a0215c103b9667/flask_cors-5.0.1.tar.gz", hash = "sha256:6ccb38d16d6b72bbc156c1c3f192bc435bfcc3c2bc864b2df1eb9b2d97b2403c", size = 11643 } wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/60/e941089faf4f50f2e0231d7f7af69308616a37e99da3ec75df60b8809db7/Flask_Cors-4.0.2-py2.py3-none-any.whl", hash = "sha256:38364faf1a7a5d0a55bd1d2e2f83ee9e359039182f5e6a029557e1f56d92c09a", size = 14467 }, + { url = "https://files.pythonhosted.org/packages/85/61/4aea5fb55be1b6f95e604627dc6c50c47d693e39cab2ac086ee0155a0abd/flask_cors-5.0.1-py3-none-any.whl", hash = "sha256:fa5cb364ead54bbf401a26dbf03030c6b18fb2fcaf70408096a572b409586b0c", size = 11296 }, ] [[package]] @@ -2044,7 +2043,7 @@ wheels = [ [[package]] name = "google-cloud-bigquery" -version = "3.31.0" +version = "3.32.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "google-api-core", extra = ["grpc"] }, @@ -2055,9 +2054,9 @@ dependencies = [ { name = "python-dateutil" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/73/91/4c7274f4d5faf13ac000b06353deaf3579575bf0e4bbad07fa68b9f09ba9/google_cloud_bigquery-3.31.0.tar.gz", hash = "sha256:b89dc716dbe4abdb7a4f873f7050100287bc98514e0614c5d54cd6a8e9fb0991", size = 479961 } +sdist = { url = "https://files.pythonhosted.org/packages/9f/cf/174ea37f0410f0702c3582c09bae45d6f43c6eabe2858ab5fb2a4319e15f/google_cloud_bigquery-3.32.0.tar.gz", hash = "sha256:f1c53d73a6d255c8cd0ca7a0c077d95224217427a4b7dcf9913ea0298a2961e8", size = 487055 } wheels = [ - { url = "https://files.pythonhosted.org/packages/e8/bc/4cb8c61fc6dd817a4a390b745ec7b305f4578f547a16d09d54c8a790624b/google_cloud_bigquery-3.31.0-py3-none-any.whl", hash = "sha256:97f4a3219854ff01d6a3a57312feecb0b6e13062226b823f867e2d3619c4787b", size = 250099 }, + { url = "https://files.pythonhosted.org/packages/5e/c3/f3f6179f54e4b4ac2c6abaa8186054fd1d7d881676bb3caef9688e5fac3d/google_cloud_bigquery-3.32.0-py3-none-any.whl", hash = "sha256:ff38d21d70c4563d2473db288d2a9fe44f071d928bbad6d029ac9ba0b8a36b7a", size = 253121 }, ] [[package]] @@ -2346,17 +2345,17 @@ wheels = [ [[package]] name = "hf-xet" -version = "1.1.0" +version = "1.1.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/aa/2c/70009910fcbd204bde75842b60c1e47fe72edb0e978954cb8001735885c7/hf_xet-1.1.0.tar.gz", hash = "sha256:a7c2a4c2b6eee9ce0a1a367a82b60d95ba634420ef1c250addad7aa4af419cf4", size = 263996 } +sdist = { url = "https://files.pythonhosted.org/packages/3a/09/e2fc5ccd6f9828efbd9135d5aab70895fa6891752ce84c57026c48f3f33d/hf_xet-1.1.1.tar.gz", hash = "sha256:3e75d6e04c38c80115b640c025d68c3dc14d62f8b244011dfe547363674a1e87", size = 277864 } wheels = [ - { url = "https://files.pythonhosted.org/packages/dc/fd/0db331297e331f0f02005fd7ea666439bf15efd74f0dd62af02a43236a1b/hf_xet-1.1.0-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:0322c42551e275fcb7949c083a54a81b2898e50787c9aa74284fcb8d2c58c12c", size = 5069444 }, - { url = "https://files.pythonhosted.org/packages/b9/7d/4d7ae44219d3744ad55669cb90ef3d4ed9f5f8a4729fa635a6499491cb78/hf_xet-1.1.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:667153a0304ac2debf2af95a8ff7687186f885b493f4cd16344869af270cd110", size = 4881465 }, - { url = "https://files.pythonhosted.org/packages/83/9a/d40d2a57b132d609d8a4ccc29e59ed69749021610616749cabcda2532158/hf_xet-1.1.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:995eeffb119636ea617b96c7d7bf3c3f5ea8727fa57974574e25d700b8532d48", size = 53584225 }, - { url = "https://files.pythonhosted.org/packages/2e/01/d94553f91d85746e0862f24d239da88d10f5ce252b028565744e982432f4/hf_xet-1.1.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:3aee847da362393331f515c4010d0aaa1c2669acfcca1f4b28946d6949cc0086", size = 52043680 }, - { url = "https://files.pythonhosted.org/packages/29/89/1f31853bf378f0ceb3363c07fd8a12af9b904b1f8c21e65eb5c19397bc98/hf_xet-1.1.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:68c5813a6074aa36e12ef5983230e3b03148cce61e0fcdd294096493795565b4", size = 53072672 }, - { url = "https://files.pythonhosted.org/packages/b5/9f/5ecb92b18a4b2135a72a95dc08bcbeda9176f46642c745ee052420d2aea8/hf_xet-1.1.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4ee9222bf9274b1c198b88a929de0b5a49349c4962d89c5b3b2f0f7f47d9761c", size = 53521053 }, - { url = "https://files.pythonhosted.org/packages/53/d6/cb32842cbf1cf5a154b41fa918a2fd86003af9bca227a2397cd7f312a8a6/hf_xet-1.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:73153eab9abf3d6973b21e94a67ccba5d595c3e12feb8c0bf50be02964e7f126", size = 4204376 }, + { url = "https://files.pythonhosted.org/packages/97/f5/81194ea8e4a585d7d4d0f2ad1ca16e05a4b0c5a385bb2610a8e6da1d2c3d/hf_xet-1.1.1-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:e39a8513f0854656116c837d387d9a41e9d78430b1a181442f04c223cbc4e8f8", size = 5274857 }, + { url = "https://files.pythonhosted.org/packages/55/3c/36342b3fa247f2580821a4b183d38f36fb20e911a8307df625790e734359/hf_xet-1.1.1-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:c60cd67be384cb9e592fa6dfd29a10fddffa1feb2f3b31f53e980630d1ca0fd6", size = 5079657 }, + { url = "https://files.pythonhosted.org/packages/b0/c1/4f770cc7be79287905e13765d4a7e1949dce3483f90867f532ff56e7126b/hf_xet-1.1.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5efc6cf15930d9b0cef25c0444e00c2f55d9e09f856f26ed8c809fd5cd1aa044", size = 25506200 }, + { url = "https://files.pythonhosted.org/packages/94/69/1ec612f8e9e2ca27563adfca926cfb41bbe988e30d4cd6fc1e0c019e5570/hf_xet-1.1.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:504bbc8341edc2aa4b3c20c1fdda818554ab34e4175730f42e2a90436cbbe706", size = 24469080 }, + { url = "https://files.pythonhosted.org/packages/8d/96/9201773a0ebb982aa5936f19bdd04d404bc5d74e23f30bce6e857757998b/hf_xet-1.1.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:87d030157a21016c2cddf757a5fd6f1f364d86afef6e190e63a37dd4dc6f6c98", size = 25641374 }, + { url = "https://files.pythonhosted.org/packages/ba/14/10a4cf526070e774bdc7ce68202dc27a15751ddc22c6b47a5ecb6d8ea4ad/hf_xet-1.1.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6e9b640f0f002b3bea36739b30cf3133b3175c27a342b39315be9a9bdb0cec5b", size = 25425434 }, + { url = "https://files.pythonhosted.org/packages/bd/25/7015a82b3b165747ba85b0383e5d5278d268f3a30460f6d55849903cf272/hf_xet-1.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:215a4e95009a0b9795ca3cf33db4e8d1248139593d7e1185661cd19b062d2b82", size = 4391897 }, ] [[package]] @@ -3366,9 +3365,11 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7a/08/c008711d1b92ff1272f4fea0fbee57723171f161d42e5c680625535280af/onnxruntime-1.22.0-cp311-cp311-macosx_13_0_universal2.whl", hash = "sha256:8d6725c5b9a681d8fe72f2960c191a96c256367887d076b08466f52b4e0991df", size = 34282151 }, { url = "https://files.pythonhosted.org/packages/3e/8b/22989f6b59bc4ad1324f07a945c80b9ab825f0a581ad7a6064b93716d9b7/onnxruntime-1.22.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fef17d665a917866d1f68f09edc98223b9a27e6cb167dec69da4c66484ad12fd", size = 14446302 }, { url = "https://files.pythonhosted.org/packages/7a/d5/aa83d084d05bc8f6cf8b74b499c77431ffd6b7075c761ec48ec0c161a47f/onnxruntime-1.22.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b978aa63a9a22095479c38371a9b359d4c15173cbb164eaad5f2cd27d666aa65", size = 16393496 }, + { url = "https://files.pythonhosted.org/packages/89/a5/1c6c10322201566015183b52ef011dfa932f5dd1b278de8d75c3b948411d/onnxruntime-1.22.0-cp311-cp311-win_amd64.whl", hash = "sha256:03d3ef7fb11adf154149d6e767e21057e0e577b947dd3f66190b212528e1db31", size = 12691517 }, { url = "https://files.pythonhosted.org/packages/4d/de/9162872c6e502e9ac8c99a98a8738b2fab408123d11de55022ac4f92562a/onnxruntime-1.22.0-cp312-cp312-macosx_13_0_universal2.whl", hash = "sha256:f3c0380f53c1e72a41b3f4d6af2ccc01df2c17844072233442c3a7e74851ab97", size = 34298046 }, { url = "https://files.pythonhosted.org/packages/03/79/36f910cd9fc96b444b0e728bba14607016079786adf032dae61f7c63b4aa/onnxruntime-1.22.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8601128eaef79b636152aea76ae6981b7c9fc81a618f584c15d78d42b310f1c", size = 14443220 }, { url = "https://files.pythonhosted.org/packages/8c/60/16d219b8868cc8e8e51a68519873bdb9f5f24af080b62e917a13fff9989b/onnxruntime-1.22.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6964a975731afc19dc3418fad8d4e08c48920144ff590149429a5ebe0d15fb3c", size = 16406377 }, + { url = "https://files.pythonhosted.org/packages/36/b4/3f1c71ce1d3d21078a6a74c5483bfa2b07e41a8d2b8fb1e9993e6a26d8d3/onnxruntime-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:c0d534a43d1264d1273c2d4f00a5a588fa98d21117a3345b7104fa0bbcaadb9a", size = 12692233 }, ] [[package]] @@ -3691,7 +3692,7 @@ wheels = [ [[package]] name = "opik" -version = "1.3.5" +version = "1.3.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -3703,13 +3704,14 @@ dependencies = [ { name = "pydantic-settings" }, { name = "pytest" }, { name = "rich" }, + { name = "sentry-sdk" }, { name = "tenacity" }, { name = "tqdm" }, { name = "uuid6" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/df/64/99cb7cf300620b092f78d052487966b7c9132a191388e297396b670350ca/opik-1.3.5.tar.gz", hash = "sha256:943e4b636b70e5781f7a6f40b33fadda0935b57ecad0997f195ce909956b68d7", size = 169802 } +sdist = { url = "https://files.pythonhosted.org/packages/d8/16/b37208d6a77f3cc74750cff4e0970e6f596aef0f491a675a40aa879157e6/opik-1.3.6.tar.gz", hash = "sha256:25d6fa8b7aa1ef23d10d598040e539440912c12b765eabfc75c8780bbbfc8ad3", size = 177174 } wheels = [ - { url = "https://files.pythonhosted.org/packages/fb/be/670ff4b921d529320ccae7fe95751c171fe6ee4708d109b744f83309bec7/opik-1.3.5-py3-none-any.whl", hash = "sha256:c6a195b33851959b8e96ac78fe211b6157288eddc03fa8bfbd1ef53424b702dc", size = 330096 }, + { url = "https://files.pythonhosted.org/packages/d4/3f/e9d14a97f85d34505770b7c7715bd72bbfc40a778163818f0d3e871264bb/opik-1.3.6-py3-none-any.whl", hash = "sha256:888973c2a1276d68c9b3cf26d8078db8aa675d2c907edda328cdab4995a8e29b", size = 341630 }, ] [[package]] @@ -4776,7 +4778,7 @@ wheels = [ [[package]] name = "readabilipy" -version = "0.2.0" +version = "0.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "beautifulsoup4" }, @@ -4784,9 +4786,9 @@ dependencies = [ { name = "lxml" }, { name = "regex" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e0/ca/0c9e5afed873dd29f529f24bb3174d582f77e343acfa8c77a39745fa7073/readabilipy-0.2.0.tar.gz", hash = "sha256:098bf347b19f362042fb6c08864ad776588bf844ac2261fb230f7f9c250fdae5", size = 38948 } +sdist = { url = "https://files.pythonhosted.org/packages/b8/e4/260a202516886c2e0cc6e6ae96d1f491792d829098886d9529a2439fbe8e/readabilipy-0.3.0.tar.gz", hash = "sha256:e13313771216953935ac031db4234bdb9725413534bfb3c19dbd6caab0887ae0", size = 35491 } wheels = [ - { url = "https://files.pythonhosted.org/packages/39/42/11f5795b747841912a6f7bacab32ab1eaabc911a4e9949fbf8786121f4d3/readabilipy-0.2.0-py3-none-any.whl", hash = "sha256:0050853cd6ab012ac75bb4d8f06427feb7dc32054da65060da44654d049802d0", size = 4339504 }, + { url = "https://files.pythonhosted.org/packages/dd/46/8a640c6de1a6c6af971f858b2fb178ca5e1db91f223d8ba5f40efe1491e5/readabilipy-0.3.0-py3-none-any.whl", hash = "sha256:d106da0fad11d5fdfcde21f5c5385556bfa8ff0258483037d39ea6b1d6db3943", size = 22158 }, ] [[package]] @@ -5070,15 +5072,15 @@ wheels = [ [[package]] name = "sentry-sdk" -version = "1.44.1" +version = "2.28.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fd/72/85a8bc961d9160ac8c9f0a6d39dbdad21795d55c7b02a433bd0ffb75c037/sentry-sdk-1.44.1.tar.gz", hash = "sha256:24e6a53eeabffd2f95d952aa35ca52f0f4201d17f820ac9d3ff7244c665aaf68", size = 243446 } +sdist = { url = "https://files.pythonhosted.org/packages/5e/bb/6a41b2e0e9121bed4d2ec68d50568ab95c49f4744156a9bbb789c866c66d/sentry_sdk-2.28.0.tar.gz", hash = "sha256:14d2b73bc93afaf2a9412490329099e6217761cbab13b6ee8bc0e82927e1504e", size = 325052 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/f8/2038661bc32579d0c11191fc1093e49db590bfb6e63d501d7995fb798d62/sentry_sdk-1.44.1-py2.py3-none-any.whl", hash = "sha256:5f75eb91d8ab6037c754a87b8501cc581b2827e923682f593bed3539ce5b3999", size = 266105 }, + { url = "https://files.pythonhosted.org/packages/9b/4e/b1575833094c088dfdef63fbca794518860fcbc8002aadf51ebe8b6a387f/sentry_sdk-2.28.0-py2.py3-none-any.whl", hash = "sha256:51496e6cb3cb625b99c8e08907c67a9112360259b0ef08470e532c3ab184a232", size = 341693 }, ] [package.optional-dependencies] @@ -5424,37 +5426,27 @@ wheels = [ [[package]] name = "tokenizers" -version = "0.15.2" +version = "0.21.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "huggingface-hub" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c0/44/625db94e91c6196b6574359fa70bfe28e8eabf57a1b894f8f0ec69727fd1/tokenizers-0.15.2.tar.gz", hash = "sha256:e6e9c6e019dd5484be5beafc775ae6c925f4c69a3487040ed09b45e13df2cb91", size = 320256 } +sdist = { url = "https://files.pythonhosted.org/packages/92/76/5ac0c97f1117b91b7eb7323dcd61af80d72f790b4df71249a7850c195f30/tokenizers-0.21.1.tar.gz", hash = "sha256:a1bb04dc5b448985f86ecd4b05407f5a8d97cb2c0532199b2a302a604a0165ab", size = 343256 } wheels = [ - { url = "https://files.pythonhosted.org/packages/73/11/933d68d395f5486d935e1c15da80bc96bf3f48595652069d19e0e9894386/tokenizers-0.15.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:89cd1cb93e4b12ff39bb2d626ad77e35209de9309a71e4d3d4672667b4b256e7", size = 2578922 }, - { url = "https://files.pythonhosted.org/packages/5f/4f/a4c12cc058a899c1caaa1e689c3df9a698e20e891d4005aa6ec2174a9339/tokenizers-0.15.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cfed5c64e5be23d7ee0f0e98081a25c2a46b0b77ce99a4f0605b1ec43dd481fa", size = 2412317 }, - { url = "https://files.pythonhosted.org/packages/e9/13/b86ea87b7e3b4a2ca154220dc4eb19a56a3864ec03e9630d15d1bac10da1/tokenizers-0.15.2-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a907d76dcfda37023ba203ab4ceeb21bc5683436ebefbd895a0841fd52f6f6f2", size = 3643051 }, - { url = "https://files.pythonhosted.org/packages/0f/23/e4985657ea42ad432d6dc2100b2687e70a6bae730f1f8c52f81d9e6ccf3a/tokenizers-0.15.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20ea60479de6fc7b8ae756b4b097572372d7e4032e2521c1bbf3d90c90a99ff0", size = 3534327 }, - { url = "https://files.pythonhosted.org/packages/34/d5/e1ad46939d6de48d41bbd8b302f87ecde79847855210e75517a832b29490/tokenizers-0.15.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:48e2b9335be2bc0171df9281385c2ed06a15f5cf121c44094338306ab7b33f2c", size = 3398296 }, - { url = "https://files.pythonhosted.org/packages/e7/d1/4d319a035f819af3290ec5a09482ad659d9d2a0aea33890fb5720ce81841/tokenizers-0.15.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:112a1dd436d2cc06e6ffdc0b06d55ac019a35a63afd26475205cb4b1bf0bfbff", size = 3927353 }, - { url = "https://files.pythonhosted.org/packages/e5/39/facfca8e598126a0001d4295e6b1ee670d241aa6f4fcdd97016065b43c5d/tokenizers-0.15.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4620cca5c2817177ee8706f860364cc3a8845bc1e291aaf661fb899e5d1c45b0", size = 4030091 }, - { url = "https://files.pythonhosted.org/packages/15/0b/c09b2c0dc688c82adadaa0d5080983de3ce920f4a5cbadb7eaa5302ad251/tokenizers-0.15.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ccd73a82751c523b3fc31ff8194702e4af4db21dc20e55b30ecc2079c5d43cb7", size = 3577167 }, - { url = "https://files.pythonhosted.org/packages/07/3b/d8e60712e509a6f5d01bf0eb4470452b72277be4883656206d4ccd7e02de/tokenizers-0.15.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:107089f135b4ae7817affe6264f8c7a5c5b4fd9a90f9439ed495f54fcea56fb4", size = 9683503 }, - { url = "https://files.pythonhosted.org/packages/c0/61/1c26c8e54af9bab32743e0484601a60738f33797f91040da2a4104f07e70/tokenizers-0.15.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0ff110ecc57b7aa4a594396525a3451ad70988e517237fe91c540997c4e50e29", size = 9996038 }, - { url = "https://files.pythonhosted.org/packages/d1/54/451e96d8514b1afbef955f7420e1180e015c3f4eb085ad38189c0e83ee87/tokenizers-0.15.2-cp311-none-win32.whl", hash = "sha256:6d76f00f5c32da36c61f41c58346a4fa7f0a61be02f4301fd30ad59834977cc3", size = 2013591 }, - { url = "https://files.pythonhosted.org/packages/c1/02/40725eebedea8175918bd59ab80b2174d6ef3b3ef9ac8ec996e84c38d3ca/tokenizers-0.15.2-cp311-none-win_amd64.whl", hash = "sha256:cc90102ed17271cf0a1262babe5939e0134b3890345d11a19c3145184b706055", size = 2192797 }, - { url = "https://files.pythonhosted.org/packages/ae/ca/ea4b5aa70d4d26f2d05620c265b07b5a249157767c1673f5753b8bfc7db1/tokenizers-0.15.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f86593c18d2e6248e72fb91c77d413a815153b8ea4e31f7cd443bdf28e467670", size = 2574444 }, - { url = "https://files.pythonhosted.org/packages/f9/99/5a55a9b6e2db274c0969ad57d989d02efae90f9e558983a561c9b2b7ea1a/tokenizers-0.15.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0774bccc6608eca23eb9d620196687c8b2360624619623cf4ba9dc9bd53e8b51", size = 2411608 }, - { url = "https://files.pythonhosted.org/packages/82/cc/29bb3a25c06b90ce82bb20ef074011481de5c44413a1e1eb10cfd93080fb/tokenizers-0.15.2-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d0222c5b7c9b26c0b4822a82f6a7011de0a9d3060e1da176f66274b70f846b98", size = 3652367 }, - { url = "https://files.pythonhosted.org/packages/c0/ae/f6a974be9b2e1615f3de3cc9e4fc2897a86357400801c58143c67cbbad2e/tokenizers-0.15.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3835738be1de66624fff2f4f6f6684775da4e9c00bde053be7564cbf3545cc66", size = 3529509 }, - { url = "https://files.pythonhosted.org/packages/d6/42/340b91f675b494c4ecc0a256c5dd88b4003dbfde05afff90b970738fdfb4/tokenizers-0.15.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0143e7d9dcd811855c1ce1ab9bf5d96d29bf5e528fd6c7824d0465741e8c10fd", size = 3396516 }, - { url = "https://files.pythonhosted.org/packages/6f/b2/8a965abc17fff309eb06e98ce429a19a5e04f731a669a6113b9e182f8a79/tokenizers-0.15.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db35825f6d54215f6b6009a7ff3eedee0848c99a6271c870d2826fbbedf31a38", size = 3918811 }, - { url = "https://files.pythonhosted.org/packages/6c/16/dad7b4aa6e34a395aef7ae7b010d8b5ebefdf3df81510de53d7f17d2f0fc/tokenizers-0.15.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3f5e64b0389a2be47091d8cc53c87859783b837ea1a06edd9d8e04004df55a5c", size = 4025494 }, - { url = "https://files.pythonhosted.org/packages/f6/de/3707df0c1d7bf55e6a4dba724700353bfee8e292fdd8ccfe93416549124d/tokenizers-0.15.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e0480c452217edd35eca56fafe2029fb4d368b7c0475f8dfa3c5c9c400a7456", size = 3575314 }, - { url = "https://files.pythonhosted.org/packages/2e/dd/7b8da304d152bb46f13bc2ba5bd545480ab6ce39d94a53eef07f7624d235/tokenizers-0.15.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a33ab881c8fe70474980577e033d0bc9a27b7ab8272896e500708b212995d834", size = 9682779 }, - { url = "https://files.pythonhosted.org/packages/07/aa/66e8a81e07a791ca6ee9d74ee6de1ffbcd3985149f13aeb530bd409baba0/tokenizers-0.15.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a308a607ca9de2c64c1b9ba79ec9a403969715a1b8ba5f998a676826f1a7039d", size = 9995614 }, - { url = "https://files.pythonhosted.org/packages/bf/e1/aed3bc98785c54bd26bf6dd3d2f54cc00de33e8b1f922a23131372eedec8/tokenizers-0.15.2-cp312-none-win32.whl", hash = "sha256:b8fcfa81bcb9447df582c5bc96a031e6df4da2a774b8080d4f02c0c16b42be0b", size = 2011030 }, - { url = "https://files.pythonhosted.org/packages/c9/ea/5800f4941a713b2feed955b6a256aacc1ca68a6699916d2668622c075d38/tokenizers-0.15.2-cp312-none-win_amd64.whl", hash = "sha256:38d7ab43c6825abfc0b661d95f39c7f8af2449364f01d331f3b51c94dcff7221", size = 2180523 }, + { url = "https://files.pythonhosted.org/packages/a5/1f/328aee25f9115bf04262e8b4e5a2050b7b7cf44b59c74e982db7270c7f30/tokenizers-0.21.1-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:e78e413e9e668ad790a29456e677d9d3aa50a9ad311a40905d6861ba7692cf41", size = 2780767 }, + { url = "https://files.pythonhosted.org/packages/ae/1a/4526797f3719b0287853f12c5ad563a9be09d446c44ac784cdd7c50f76ab/tokenizers-0.21.1-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:cd51cd0a91ecc801633829fcd1fda9cf8682ed3477c6243b9a095539de4aecf3", size = 2650555 }, + { url = "https://files.pythonhosted.org/packages/4d/7a/a209b29f971a9fdc1da86f917fe4524564924db50d13f0724feed37b2a4d/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28da6b72d4fb14ee200a1bd386ff74ade8992d7f725f2bde2c495a9a98cf4d9f", size = 2937541 }, + { url = "https://files.pythonhosted.org/packages/3c/1e/b788b50ffc6191e0b1fc2b0d49df8cff16fe415302e5ceb89f619d12c5bc/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:34d8cfde551c9916cb92014e040806122295a6800914bab5865deb85623931cf", size = 2819058 }, + { url = "https://files.pythonhosted.org/packages/36/aa/3626dfa09a0ecc5b57a8c58eeaeb7dd7ca9a37ad9dd681edab5acd55764c/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aaa852d23e125b73d283c98f007e06d4595732104b65402f46e8ef24b588d9f8", size = 3133278 }, + { url = "https://files.pythonhosted.org/packages/a4/4d/8fbc203838b3d26269f944a89459d94c858f5b3f9a9b6ee9728cdcf69161/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a21a15d5c8e603331b8a59548bbe113564136dc0f5ad8306dd5033459a226da0", size = 3144253 }, + { url = "https://files.pythonhosted.org/packages/d8/1b/2bd062adeb7c7511b847b32e356024980c0ffcf35f28947792c2d8ad2288/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2fdbd4c067c60a0ac7eca14b6bd18a5bebace54eb757c706b47ea93204f7a37c", size = 3398225 }, + { url = "https://files.pythonhosted.org/packages/8a/63/38be071b0c8e06840bc6046991636bcb30c27f6bb1e670f4f4bc87cf49cc/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dd9a0061e403546f7377df940e866c3e678d7d4e9643d0461ea442b4f89e61a", size = 3038874 }, + { url = "https://files.pythonhosted.org/packages/ec/83/afa94193c09246417c23a3c75a8a0a96bf44ab5630a3015538d0c316dd4b/tokenizers-0.21.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:db9484aeb2e200c43b915a1a0150ea885e35f357a5a8fabf7373af333dcc8dbf", size = 9014448 }, + { url = "https://files.pythonhosted.org/packages/ae/b3/0e1a37d4f84c0f014d43701c11eb8072704f6efe8d8fc2dcdb79c47d76de/tokenizers-0.21.1-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:ed248ab5279e601a30a4d67bdb897ecbe955a50f1e7bb62bd99f07dd11c2f5b6", size = 8937877 }, + { url = "https://files.pythonhosted.org/packages/ac/33/ff08f50e6d615eb180a4a328c65907feb6ded0b8f990ec923969759dc379/tokenizers-0.21.1-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:9ac78b12e541d4ce67b4dfd970e44c060a2147b9b2a21f509566d556a509c67d", size = 9186645 }, + { url = "https://files.pythonhosted.org/packages/5f/aa/8ae85f69a9f6012c6f8011c6f4aa1c96154c816e9eea2e1b758601157833/tokenizers-0.21.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e5a69c1a4496b81a5ee5d2c1f3f7fbdf95e90a0196101b0ee89ed9956b8a168f", size = 9384380 }, + { url = "https://files.pythonhosted.org/packages/e8/5b/a5d98c89f747455e8b7a9504910c865d5e51da55e825a7ae641fb5ff0a58/tokenizers-0.21.1-cp39-abi3-win32.whl", hash = "sha256:1039a3a5734944e09de1d48761ade94e00d0fa760c0e0551151d4dd851ba63e3", size = 2239506 }, + { url = "https://files.pythonhosted.org/packages/e6/b6/072a8e053ae600dcc2ac0da81a23548e3b523301a442a6ca900e92ac35be/tokenizers-0.21.1-cp39-abi3-win_amd64.whl", hash = "sha256:0f0dcbcc9f6e13e675a66d7a5f2f225a736745ce484c1a4e07476a89ccdad382", size = 2435481 }, ] [[package]] @@ -5522,7 +5514,7 @@ wheels = [ [[package]] name = "transformers" -version = "4.39.3" +version = "4.51.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "filelock" }, @@ -5536,9 +5528,9 @@ dependencies = [ { name = "tokenizers" }, { name = "tqdm" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/11/a9/a8ece5f26d59d76f55117580e138f992075623623672c920c42ad5e26f85/transformers-4.39.3.tar.gz", hash = "sha256:2586e5ff4150f122716fc40f5530e92871befc051848fbe82600969c535b762d", size = 7610890 } +sdist = { url = "https://files.pythonhosted.org/packages/f1/11/7414d5bc07690002ce4d7553602107bf969af85144bbd02830f9fb471236/transformers-4.51.3.tar.gz", hash = "sha256:e292fcab3990c6defe6328f0f7d2004283ca81a7a07b2de9a46d67fd81ea1409", size = 8941266 } wheels = [ - { url = "https://files.pythonhosted.org/packages/15/fc/7b6dd7e1adc0a6407b845ed4be1999e98b6917d0694e57316d140cc85484/transformers-4.39.3-py3-none-any.whl", hash = "sha256:7838034a12cca3168247f9d2d1dba6724c9de3ae0f73a108258c6b8fc5912601", size = 8803702 }, + { url = "https://files.pythonhosted.org/packages/a9/b6/5257d04ae327b44db31f15cce39e6020cc986333c715660b1315a9724d82/transformers-4.51.3-py3-none-any.whl", hash = "sha256:fd3279633ceb2b777013234bbf0b4f5c2d23c4626b05497691f00cfda55e8a83", size = 10383940 }, ] [[package]] @@ -5908,14 +5900,14 @@ wheels = [ [[package]] name = "types-tqdm" -version = "4.67.0.20250417" +version = "4.67.0.20250513" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "types-requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4a/54/1ce092a682af4b2995a3708a8830dc15502927f3586064d9ea3738a562d1/types_tqdm-4.67.0.20250417.tar.gz", hash = "sha256:bfcc4099d8d48df54e53f3ea64708cbcc1d1c4039ca7619594189da8c03c7be2", size = 17179 } +sdist = { url = "https://files.pythonhosted.org/packages/d4/74/a77b5179e3543853c51ce786b300cd253934477c81aab4d786dff9894724/types_tqdm-4.67.0.20250513.tar.gz", hash = "sha256:907028c8d0a8fc20072132cd0cee72a3b6c72abf32f5ff914a7749e7d13b351e", size = 17207 } wheels = [ - { url = "https://files.pythonhosted.org/packages/18/48/320971ed192f4ac207305a75fa8366efb1b6a90a24db0513f492668d87c0/types_tqdm-4.67.0.20250417-py3-none-any.whl", hash = "sha256:d43fc9a295be1f94083c744a09099c033c4dea293ff9a07bab9f34bfbffaaf80", size = 24057 }, + { url = "https://files.pythonhosted.org/packages/6a/7b/996a534691afd516f60fa3ad3f4101b38f7222fff6c1b12f508a4c817695/types_tqdm-4.67.0.20250513-py3-none-any.whl", hash = "sha256:73d2bdac28bab49235d8660aece6c415636a0fb406f7a24b39737dfc6bf6a5dd", size = 24060 }, ] [[package]] @@ -6220,7 +6212,7 @@ wheels = [ [[package]] name = "wandb" -version = "0.18.3" +version = "0.19.11" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -6229,23 +6221,26 @@ dependencies = [ { name = "platformdirs" }, { name = "protobuf" }, { name = "psutil" }, + { name = "pydantic" }, { name = "pyyaml" }, { name = "requests" }, { name = "sentry-sdk" }, { name = "setproctitle" }, { name = "setuptools" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cc/57/8a61979c40a7a0a5206ef3369ed474326135bf292f172019f35dca97a235/wandb-0.18.3.tar.gz", hash = "sha256:eb2574cea72bc908c6ce1b37edf7a889619e6e06e1b4714eecfe0662ded43c06", size = 8686381 } +sdist = { url = "https://files.pythonhosted.org/packages/39/98/0ff2925a21b998d4b84731429f4554ca3d9b5cad42c09c075e7306c3aca0/wandb-0.19.11.tar.gz", hash = "sha256:3f50a27dfadbb25946a513ffe856c0e8e538b5626ef207aa50b00c3b0356bff8", size = 39511477 } wheels = [ - { url = "https://files.pythonhosted.org/packages/1c/4a/6fa1d584ecd69cea5b9943ec5cfa36276cbd567efa8709135a7e4ab89cfb/wandb-0.18.3-py3-none-any.whl", hash = "sha256:7da64f7da0ff7572439de10bfd45534e8811e71e78ac2ccc3b818f1c0f3a9aef", size = 5015658 }, - { url = "https://files.pythonhosted.org/packages/59/8f/deef595ca67833ea5aceb5da5fc10759a5e8f8bce85b17761b1614fa2ba9/wandb-0.18.3-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:6674d8a5c40c79065b9c7eb765136756d5ebc9457a5f9abc820a660fb23f8b67", size = 10081571 }, - { url = "https://files.pythonhosted.org/packages/06/85/b55642d095407369dd7ad1d8ea1e7f410d60fcdb6c29bcc9afb1e5522d51/wandb-0.18.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:741f566e409a2684d3047e4cc25e8e914d78196b901190937b24b6abb8b052e5", size = 10008319 }, - { url = "https://files.pythonhosted.org/packages/b4/53/5387afaab29876e669973b3bb5bda829e3c10e509caef59f614bf20c0106/wandb-0.18.3-py3-none-macosx_11_0_x86_64.whl", hash = "sha256:8be5e877570b693001c52dcc2089e48e6a4dcbf15f3adf5c9349f95148b59d58", size = 10250633 }, - { url = "https://files.pythonhosted.org/packages/bd/79/2fa554283afa7259e296313160164947daf52e0d42b04d6ecf9c5af01e15/wandb-0.18.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d788852bd4739fa18de3918f309c3a955b5cef3247fae1c40df3a63af637e1a0", size = 12339454 }, - { url = "https://files.pythonhosted.org/packages/86/a6/11eaa16c96469b4d6fc0fb3271e70d5bbe2c3a93c15fc677de9a1aa4374a/wandb-0.18.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab81424eb207d78239a8d69c90521a70074fb81e3709055484e43c76fe44dc08", size = 12970950 }, - { url = "https://files.pythonhosted.org/packages/13/dd/ccaa5a51e2557368300eec9e362b5688151e45a052e33017633baa3011a9/wandb-0.18.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:2c91315b8b62423eae18577d66a4b4bb8e4341a7d5c849cb2963e3b3dff0bf6d", size = 13038220 }, - { url = "https://files.pythonhosted.org/packages/bc/6f/fabbf2161078556384ef48f3db89182773010cdd14900986004e702b85f5/wandb-0.18.3-py3-none-win32.whl", hash = "sha256:92a647dab783938ec87776a9fae8a13e72e6dad939c53e357cdea9d2570f0ad8", size = 12573298 }, - { url = "https://files.pythonhosted.org/packages/d8/7b/e94b46d620d26b2e1f486f2746febdcb6579be20f361355b40263ddd8262/wandb-0.18.3-py3-none-win_amd64.whl", hash = "sha256:29cac2cfa3124241fed22cfedc9a52e1500275ee9bbb0b428ce4bf63c4723bf0", size = 12573303 }, + { url = "https://files.pythonhosted.org/packages/4f/2c/f8bab58c73fdde4442f1baffd9ea5d1bb3113906a97a27e8d9ab72db7a69/wandb-0.19.11-py3-none-any.whl", hash = "sha256:ff3bf050ba25ebae7aedc9a775ffab90c28068832edfe5458423f488c2558f82", size = 6481327 }, + { url = "https://files.pythonhosted.org/packages/45/4a/34b364280f690f4c6d7660f528fba9f13bdecabc4c869d266a4632cf836e/wandb-0.19.11-py3-none-macosx_10_14_x86_64.whl", hash = "sha256:0823fd9aa6343f40c04e01959997ca8c6d6adf1bd81c8d45261fa4915f1c6b67", size = 20555751 }, + { url = "https://files.pythonhosted.org/packages/d8/e6/a27868fdb83a60df37b9d15e52c3353dd88d74442f27ae48cf765c6b9554/wandb-0.19.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c758ef5439599d9023db5b3cf1698477055d82f9fae48af2779f63f1d289167c", size = 20377587 }, + { url = "https://files.pythonhosted.org/packages/21/f7/d5cf5b58c2b3015364c7b2b6af6a440cbeda4103b67332e1e64b30f6252d/wandb-0.19.11-py3-none-macosx_11_0_x86_64.whl", hash = "sha256:de2dfd4911e7691735e271654c735e7b90cdee9d29a3796fbf06e9e92d48f3d7", size = 20985041 }, + { url = "https://files.pythonhosted.org/packages/68/06/8b827f16a0b8f18002d2fffa7c5a7fd447946e0d0c68aeec0dd7eb18cdd3/wandb-0.19.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfff738850770d26b13f8f3fe400a6456f1e39e87f3f29d5aa241b249476df95", size = 20017696 }, + { url = "https://files.pythonhosted.org/packages/f9/31/eeb2878b26566c04c3e9b8b20b3ec3c54a2be50535088d36a37c008e07a3/wandb-0.19.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8ff673007448df11cc69379ae0df28ead866800dc1ec7bc151b402db0bbcf40", size = 21425857 }, + { url = "https://files.pythonhosted.org/packages/10/30/08988360678ae78334bb16625c28260fcaba49f500b89f8766807cb74d71/wandb-0.19.11-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:858bc5023fa1b3285d89d15f62be78afdb28301064daa49ea3f4ebde5dcedad2", size = 20023145 }, + { url = "https://files.pythonhosted.org/packages/c8/e9/a639c42c8ca517c4d25e8970d64d0c5a9bd35b784faed5f47d9cca3dcd12/wandb-0.19.11-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:90e4b57649896acb16c3dd41b3093df1a169c2f1d94ff15d76af86b8a60dcdac", size = 21504842 }, + { url = "https://files.pythonhosted.org/packages/44/74/dbe9277dd935b77dd16939cdf15357766fec0813a6e336cf5f1d07eb016e/wandb-0.19.11-py3-none-win32.whl", hash = "sha256:38dea43c7926d8800405a73b80b9adfe81eb315fc6f2ac6885c77eb966634421", size = 20767584 }, + { url = "https://files.pythonhosted.org/packages/36/d5/215cac3edec5c5ac6e7231beb9d22466d5d4e4a132fa3a1d044f7d682c15/wandb-0.19.11-py3-none-win_amd64.whl", hash = "sha256:73402003c56ddc2198878492ab2bff55bb49bce5587eae5960e737d27c0c48f7", size = 20767588 }, ] [[package]] diff --git a/dev/start-api b/dev/start-api new file mode 100755 index 0000000000..0b50ad0d0a --- /dev/null +++ b/dev/start-api @@ -0,0 +1,10 @@ +#!/bin/bash + +set -x + +SCRIPT_DIR="$(dirname "$(realpath "$0")")" +cd "$SCRIPT_DIR/.." + + +uv --directory api run \ + flask run --host 0.0.0.0 --port=5001 --debug diff --git a/dev/start-worker b/dev/start-worker new file mode 100755 index 0000000000..7007b265e0 --- /dev/null +++ b/dev/start-worker @@ -0,0 +1,11 @@ +#!/bin/bash + +set -x + +SCRIPT_DIR="$(dirname "$(realpath "$0")")" +cd "$SCRIPT_DIR/.." + + +uv --directory api run \ + celery -A app.celery worker \ + -P gevent -c 1 --loglevel INFO -Q dataset,generation,mail,ops_trace,app_deletion diff --git a/web/app/components/base/chat/chat/question.tsx b/web/app/components/base/chat/chat/question.tsx index 3f7f2e837f..8fc49d1978 100644 --- a/web/app/components/base/chat/chat/question.tsx +++ b/web/app/components/base/chat/chat/question.tsx @@ -5,6 +5,8 @@ import type { import { memo, useCallback, + useEffect, + useRef, useState, } from 'react' import type { ChatItem } from '../types' @@ -52,6 +54,8 @@ const Question: FC = ({ const [isEditing, setIsEditing] = useState(false) const [editedContent, setEditedContent] = useState(content) + const [contentWidth, setContentWidth] = useState(0) + const contentRef = useRef(null) const handleEdit = useCallback(() => { setIsEditing(true) @@ -75,14 +79,31 @@ const Question: FC = ({ item.nextSibling && switchSibling?.(item.nextSibling) }, [switchSibling, item.prevSibling, item.nextSibling]) + const getContentWidth = () => { + if (contentRef.current) + setContentWidth(contentRef.current?.clientWidth) + } + + useEffect(() => { + if (!contentRef.current) + return + const resizeObserver = new ResizeObserver(() => { + getContentWidth() + }) + resizeObserver.observe(contentRef.current) + return () => { + resizeObserver.disconnect() + } + }, []) + return ( -
-
+
+
-
+
{ copy(content) Toast.notify({ type: 'success', message: t('common.actionMsg.copySuccessfully') }) @@ -95,6 +116,7 @@ const Question: FC = ({
diff --git a/web/app/components/base/premium-badge/index.css b/web/app/components/base/premium-badge/index.css index 7957e402b1..b160ba7e2c 100644 --- a/web/app/components/base/premium-badge/index.css +++ b/web/app/components/base/premium-badge/index.css @@ -2,47 +2,55 @@ @layer components { .premium-badge { - @apply inline-flex justify-center items-center rounded-md border box-border border-white/95 text-white + @apply shrink-0 relative inline-flex justify-center items-center rounded-md box-border border border-transparent text-white shadow-xs hover:shadow-lg bg-origin-border overflow-hidden; + background-clip: padding-box, border-box; + } + .allowHover { + @apply cursor-pointer; } /* m is for the regular button */ .premium-badge-m { - @apply border shadow-lg !p-1 h-6 w-auto + @apply !p-1 h-6 w-auto } .premium-badge-s { - @apply border-[0.5px] shadow-xs !px-1 !py-[3px] h-[18px] w-auto + @apply border-[0.5px] !px-1 !py-[3px] h-[18px] w-auto } .premium-badge-blue { - @apply bg-gradient-to-r from-[#5289ffe6] to-[#155aefe6] bg-util-colors-blue-blue-200 + @apply bg-util-colors-blue-blue-200; + background-image: linear-gradient(90deg, #5289ffe6 0%, #155aefe6 100%), linear-gradient(135deg, var(--color-premium-badge-border-highlight-color) 0%, #155aef 100%); + } + .premium-badge-blue.allowHover:hover { + @apply bg-util-colors-blue-blue-300; + background-image: linear-gradient(90deg, #296dffe6 0%, #004aebe6 100%), linear-gradient(135deg, var(--color-premium-badge-border-highlight-color) 0%, #00329e 100%); } .premium-badge-indigo { - @apply bg-gradient-to-r from-[#8098f9e6] to-[#444ce7e6] bg-util-colors-indigo-indigo-200 + @apply bg-util-colors-indigo-indigo-200; + background-image: linear-gradient(90deg, #8098f9e6 0%, #444ce7e6 100%), linear-gradient(135deg, var(--color-premium-badge-border-highlight-color) 0%, #6172f3 100%); + } + .premium-badge-indigo.allowHover:hover { + @apply bg-util-colors-indigo-indigo-300; + background-image: linear-gradient(90deg, #6172f3e6 0%, #2d31a6e6 100%), linear-gradient(135deg, var(--color-premium-badge-border-highlight-color) 0%, #2d31a6 100%); } .premium-badge-gray { - @apply bg-gradient-to-r from-[#98a2b2e6] to-[#676f83e6] bg-util-colors-gray-gray-200 + @apply bg-util-colors-gray-gray-200; + background-image: linear-gradient(90deg, #98a2b2e6 0%, #676f83e6 100%), linear-gradient(135deg, var(--color-premium-badge-border-highlight-color) 0%, #676f83 100%); + } + .premium-badge-gray.allowHover:hover { + @apply bg-util-colors-gray-gray-300; + background-image: linear-gradient(90deg, #676f83e6 0%, #354052e6 100%), linear-gradient(135deg, var(--color-premium-badge-border-highlight-color) 0%, #354052 100%); } .premium-badge-orange { - @apply bg-gradient-to-r from-[#ff692ee6] to-[#e04f16e6] bg-util-colors-orange-orange-200 + @apply bg-util-colors-orange-orange-200; + background-image: linear-gradient(90deg, #ff692ee6 0%, #e04f16e6 100%), linear-gradient(135deg, var(--color-premium-badge-border-highlight-color) 0%, #e62e05 100%); } - - .premium-badge-blue.allowHover:hover { - @apply bg-gradient-to-r from-[#296dffe6] to-[#004aebe6] bg-util-colors-blue-blue-300 cursor-pointer - } - - .premium-badge-indigo.allowHover:hover { - @apply bg-gradient-to-r from-[#6172f3e6] to-[#2d31a6e6] bg-util-colors-indigo-indigo-300 cursor-pointer - } - - .premium-badge-gray.allowHover:hover { - @apply bg-gradient-to-r from-[#676f83e6] to-[#354052e6] bg-util-colors-gray-gray-300 cursor-pointer - } - .premium-badge-orange.allowHover:hover { - @apply bg-gradient-to-r from-[#ff4405e6] to-[#b93815e6] bg-util-colors-orange-orange-300 cursor-pointer + @apply bg-util-colors-orange-orange-300; + background-image: linear-gradient(90deg, #ff4405e6 0%, #b93815e6 100%), linear-gradient(135deg, var(--color-premium-badge-border-highlight-color) 0%, #e62e05 100%); } } diff --git a/web/app/components/base/premium-badge/index.tsx b/web/app/components/base/premium-badge/index.tsx index b97dd5daf8..ce162d7565 100644 --- a/web/app/components/base/premium-badge/index.tsx +++ b/web/app/components/base/premium-badge/index.tsx @@ -61,13 +61,9 @@ const PremiumBadge: React.FC = ({ {children}
) diff --git a/web/app/components/develop/template/template.en.mdx b/web/app/components/develop/template/template.en.mdx index 43dc226107..8212e800f7 100755 --- a/web/app/components/develop/template/template.en.mdx +++ b/web/app/components/develop/template/template.en.mdx @@ -647,3 +647,62 @@ The text generation application offers non-session support and is ideal for tran +--- + + + + + Used to get the WebApp settings of the application. + ### Response + - `title` (string) WebApp name + - `chat_color_theme` (string) Chat color theme, in hex format + - `chat_color_theme_inverted` (bool) Whether the chat color theme is inverted + - `icon_type` (string) Icon type, `emoji` - emoji, `image` - picture + - `icon` (string) Icon. If it's `emoji` type, it's an emoji symbol; if it's `image` type, it's an image URL. + - `icon_background` (string) Background color in hex format + - `icon_url` (string) Icon URL + - `description` (string) Description + - `copyright` (string) Copyright information + - `privacy_policy` (string) Privacy policy link + - `custom_disclaimer` (string) Custom disclaimer + - `default_language` (string) Default language + - `show_workflow_steps` (bool) Whether to show workflow details + - `use_icon_as_answer_icon` (bool) Whether to replace 🤖 in chat with the WebApp icon + + + + ```bash {{ title: 'cURL' }} + curl -X GET '${props.appDetail.api_base_url}/site' \ + -H 'Authorization: Bearer {api_key}' + ``` + + + + + ```json {{ title: 'Response' }} + { + "title": "My App", + "chat_color_theme": "#ff4a4a", + "chat_color_theme_inverted": false, + "icon_type": "emoji", + "icon": "😄", + "icon_background": "#FFEAD5", + "icon_url": null, + "description": "This is my app.", + "copyright": "all rights reserved", + "privacy_policy": "", + "custom_disclaimer": "All generated by AI", + "default_language": "en-US", + "show_workflow_steps": false, + "use_icon_as_answer_icon": false, + } + ``` + + + +___ diff --git a/web/app/components/develop/template/template.ja.mdx b/web/app/components/develop/template/template.ja.mdx index 2c676e392f..5061792caf 100755 --- a/web/app/components/develop/template/template.ja.mdx +++ b/web/app/components/develop/template/template.ja.mdx @@ -645,3 +645,62 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from +--- + + + + + アプリのWebApp設定を取得するために使用します。 + ### レスポンス + - `title` (string) WebApp名 + - `chat_color_theme` (string) チャットの色テーマ、16進数形式 + - `chat_color_theme_inverted` (bool) チャットの色テーマを反転するかどうか + - `icon_type` (string) アイコンタイプ、`emoji`-絵文字、`image`-画像 + - `icon` (string) アイコン。`emoji`タイプの場合は絵文字、`image`タイプの場合は画像URL + - `icon_background` (string) 16進数形式の背景色 + - `icon_url` (string) アイコンのURL + - `description` (string) 説明 + - `copyright` (string) 著作権情報 + - `privacy_policy` (string) プライバシーポリシーのリンク + - `custom_disclaimer` (string) カスタム免責事項 + - `default_language` (string) デフォルト言語 + - `show_workflow_steps` (bool) ワークフローの詳細を表示するかどうか + - `use_icon_as_answer_icon` (bool) WebAppのアイコンをチャット内の🤖に置き換えるかどうか + + + + ```bash {{ title: 'cURL' }} + curl -X GET '${props.appDetail.api_base_url}/site' \ + -H 'Authorization: Bearer {api_key}' + ``` + + + + + ```json {{ title: 'Response' }} + { + "title": "My App", + "chat_color_theme": "#ff4a4a", + "chat_color_theme_inverted": false, + "icon_type": "emoji", + "icon": "😄", + "icon_background": "#FFEAD5", + "icon_url": null, + "description": "This is my app.", + "copyright": "all rights reserved", + "privacy_policy": "", + "custom_disclaimer": "All generated by AI", + "default_language": "en-US", + "show_workflow_steps": false, + "use_icon_as_answer_icon": false, + } + ``` + + + +___ diff --git a/web/app/components/develop/template/template.zh.mdx b/web/app/components/develop/template/template.zh.mdx index da9aa43204..df83684c06 100755 --- a/web/app/components/develop/template/template.zh.mdx +++ b/web/app/components/develop/template/template.zh.mdx @@ -507,7 +507,6 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx' - --- --- + + + + 用于获取应用的 WebApp 设置 + ### Response + - `title` (string) WebApp 名称 + - `chat_color_theme` (string) 聊天颜色主题, hex 格式 + - `chat_color_theme_inverted` (bool) 聊天颜色主题是否反转 + - `icon_type` (string) 图标类型, `emoji`-表情, `image`-图片 + - `icon` (string) 图标, 如果是 `emoji` 类型, 则是 emoji 表情符号, 如果是 `image` 类型, 则是图片 URL + - `icon_background` (string) hex 格式的背景色 + - `icon_url` (string) 图标 URL + - `description` (string) 描述 + - `copyright` (string) 版权信息 + - `privacy_policy` (string) 隐私政策链接 + - `custom_disclaimer` (string) 自定义免责声明 + - `default_language` (string) 默认语言 + - `show_workflow_steps` (bool) 是否显示工作流详情 + - `use_icon_as_answer_icon` (bool) 是否使用 WebApp 图标替换聊天中的 🤖 + + + + ```bash {{ title: 'cURL' }} + curl -X GET '${props.appDetail.api_base_url}/site' \ + -H 'Authorization: Bearer {api_key}' + ``` + + + + + ```json {{ title: 'Response' }} + { + "title": "My App", + "chat_color_theme": "#ff4a4a", + "chat_color_theme_inverted": false, + "icon_type": "emoji", + "icon": "😄", + "icon_background": "#FFEAD5", + "icon_url": null, + "description": "This is my app.", + "copyright": "all rights reserved", + "privacy_policy": "", + "custom_disclaimer": "All generated by AI", + "default_language": "en-US", + "show_workflow_steps": false, + "use_icon_as_answer_icon": false, + } + ``` + + + +___ + --- + + + + Used to get the WebApp settings of the application. + ### Response + - `title` (string) WebApp name + - `chat_color_theme` (string) Chat color theme, in hex format + - `chat_color_theme_inverted` (bool) Whether the chat color theme is inverted + - `icon_type` (string) Icon type, `emoji` - emoji, `image` - picture + - `icon` (string) Icon. If it's `emoji` type, it's an emoji symbol; if it's `image` type, it's an image URL + - `icon_background` (string) Background color in hex format + - `icon_url` (string) Icon URL + - `description` (string) Description + - `copyright` (string) Copyright information + - `privacy_policy` (string) Privacy policy link + - `custom_disclaimer` (string) Custom disclaimer + - `default_language` (string) Default language + - `show_workflow_steps` (bool) Whether to show workflow details + - `use_icon_as_answer_icon` (bool) Whether to replace 🤖 in chat with the WebApp icon + + + + ```bash {{ title: 'cURL' }} + curl -X GET '${props.appDetail.api_base_url}/site' \ + -H 'Authorization: Bearer {api_key}' + ``` + + + + + ```json {{ title: 'Response' }} + { + "title": "My App", + "chat_color_theme": "#ff4a4a", + "chat_color_theme_inverted": false, + "icon_type": "emoji", + "icon": "😄", + "icon_background": "#FFEAD5", + "icon_url": null, + "description": "This is my app.", + "copyright": "all rights reserved", + "privacy_policy": "", + "custom_disclaimer": "All generated by AI", + "default_language": "en-US", + "show_workflow_steps": false, + "use_icon_as_answer_icon": false, + } + ``` + + + +___ + + +--- + + + + + アプリのWebApp設定を取得するために使用します。 + ### 応答 + - `title` (string) WebApp名 + - `chat_color_theme` (string) チャットの色テーマ、16進数形式 + - `chat_color_theme_inverted` (bool) チャットの色テーマを反転するかどうか + - `icon_type` (string) アイコンタイプ、`emoji`-絵文字、`image`-画像 + - `icon` (string) アイコン。`emoji`タイプの場合は絵文字、`image`タイプの場合は画像URL + - `icon_background` (string) 16進数形式の背景色 + - `icon_url` (string) アイコンのURL + - `description` (string) 説明 + - `copyright` (string) 著作権情報 + - `privacy_policy` (string) プライバシーポリシーのリンク + - `custom_disclaimer` (string) カスタム免責事項 + - `default_language` (string) デフォルト言語 + - `show_workflow_steps` (bool) ワークフローの詳細を表示するかどうか + - `use_icon_as_answer_icon` (bool) WebAppのアイコンをチャット内の🤖に置き換えるかどうか + + + + ```bash {{ title: 'cURL' }} + curl -X GET '${props.appDetail.api_base_url}/site' \ + -H 'Authorization: Bearer {api_key}' + ``` + + + + + ```json {{ title: 'Response' }} + { + "title": "My App", + "chat_color_theme": "#ff4a4a", + "chat_color_theme_inverted": false, + "icon_type": "emoji", + "icon": "😄", + "icon_background": "#FFEAD5", + "icon_url": null, + "description": "This is my app.", + "copyright": "all rights reserved", + "privacy_policy": "", + "custom_disclaimer": "All generated by AI", + "default_language": "en-US", + "show_workflow_steps": false, + "use_icon_as_answer_icon": false, + } + ``` + + + +___ diff --git a/web/app/components/develop/template/template_advanced_chat.zh.mdx b/web/app/components/develop/template/template_advanced_chat.zh.mdx index f8d5934974..9077f5492f 100755 --- a/web/app/components/develop/template/template_advanced_chat.zh.mdx +++ b/web/app/components/develop/template/template_advanced_chat.zh.mdx @@ -1329,7 +1329,63 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx' --- ---- + + + + 用于获取应用的 WebApp 设置 + ### Response + - `title` (string) WebApp 名称 + - `chat_color_theme` (string) 聊天颜色主题, hex 格式 + - `chat_color_theme_inverted` (bool) 聊天颜色主题是否反转 + - `icon_type` (string) 图标类型, `emoji`-表情, `image`-图片 + - `icon` (string) 图标, 如果是 `emoji` 类型, 则是 emoji 表情符号, 如果是 `image` 类型, 则是图片 URL + - `icon_background` (string) hex 格式的背景色 + - `icon_url` (string) 图标 URL + - `description` (string) 描述 + - `copyright` (string) 版权信息 + - `privacy_policy` (string) 隐私政策链接 + - `custom_disclaimer` (string) 自定义免责声明 + - `default_language` (string) 默认语言 + - `show_workflow_steps` (bool) 是否显示工作流详情 + - `use_icon_as_answer_icon` (bool) 是否使用 WebApp 图标替换聊天中的 🤖 + + + + ```bash {{ title: 'cURL' }} + curl -X GET '${props.appDetail.api_base_url}/site' \ + -H 'Authorization: Bearer {api_key}' + ``` + + + + + ```json {{ title: 'Response' }} + { + "title": "My App", + "chat_color_theme": "#ff4a4a", + "chat_color_theme_inverted": false, + "icon_type": "emoji", + "icon": "😄", + "icon_background": "#FFEAD5", + "icon_url": null, + "description": "This is my app.", + "copyright": "all rights reserved", + "privacy_policy": "", + "custom_disclaimer": "All generated by AI", + "default_language": "en-US", + "show_workflow_steps": false, + "use_icon_as_answer_icon": false, + } + ``` + + + +___ --- + + + + Used to get the WebApp settings of the application. + ### Response + - `title` (string) WebApp name + - `chat_color_theme` (string) Chat color theme, in hex format + - `chat_color_theme_inverted` (bool) Whether the chat color theme is inverted + - `icon_type` (string) Icon type, `emoji` - emoji, `image` - picture + - `icon` (string) Icon. If it's `emoji` type, it's an emoji symbol; if it's `image` type, it's an image URL + - `icon_background` (string) Background color in hex format + - `icon_url` (string) Icon URL + - `description` (string) Description + - `copyright` (string) Copyright information + - `privacy_policy` (string) Privacy policy link + - `custom_disclaimer` (string) Custom disclaimer + - `default_language` (string) Default language + - `show_workflow_steps` (bool) Whether to show workflow details + - `use_icon_as_answer_icon` (bool) Whether to replace 🤖 in chat with the WebApp icon + + + + ```bash {{ title: 'cURL' }} + curl -X GET '${props.appDetail.api_base_url}/site' \ + -H 'Authorization: Bearer {api_key}' + ``` + + + + + ```json {{ title: 'Response' }} + { + "title": "My App", + "chat_color_theme": "#ff4a4a", + "chat_color_theme_inverted": false, + "icon_type": "emoji", + "icon": "😄", + "icon_background": "#FFEAD5", + "icon_url": null, + "description": "This is my app.", + "copyright": "all rights reserved", + "privacy_policy": "", + "custom_disclaimer": "All generated by AI", + "default_language": "en-US", + "show_workflow_steps": false, + "use_icon_as_answer_icon": false, + } + ``` + + + +___ + + +--- + + + + + アプリのWebApp設定を取得するために使用します。 + ### 応答 + - `title` (string) WebApp名 + - `chat_color_theme` (string) チャットの色テーマ、16進数形式 + - `chat_color_theme_inverted` (bool) チャットの色テーマを反転するかどうか + - `icon_type` (string) アイコンタイプ、`emoji`-絵文字、`image`-画像 + - `icon` (string) アイコン。`emoji`タイプの場合は絵文字、`image`タイプの場合は画像URL + - `icon_background` (string) 16進数形式の背景色 + - `icon_url` (string) アイコンのURL + - `description` (string) 説明 + - `copyright` (string) 著作権情報 + - `privacy_policy` (string) プライバシーポリシーのリンク + - `custom_disclaimer` (string) カスタム免責事項 + - `default_language` (string) デフォルト言語 + - `show_workflow_steps` (bool) ワークフローの詳細を表示するかどうか + - `use_icon_as_answer_icon` (bool) WebAppのアイコンをチャット内の🤖に置き換えるかどうか + + + + ```bash {{ title: 'cURL' }} + curl -X GET '${props.appDetail.api_base_url}/site' \ + -H 'Authorization: Bearer {api_key}' + ``` + + + + + ```json {{ title: 'Response' }} + { + "title": "My App", + "chat_color_theme": "#ff4a4a", + "chat_color_theme_inverted": false, + "icon_type": "emoji", + "icon": "😄", + "icon_background": "#FFEAD5", + "icon_url": null, + "description": "This is my app.", + "copyright": "all rights reserved", + "privacy_policy": "", + "custom_disclaimer": "All generated by AI", + "default_language": "en-US", + "show_workflow_steps": false, + "use_icon_as_answer_icon": false, + } + ``` + + + +___ diff --git a/web/app/components/develop/template/template_chat.zh.mdx b/web/app/components/develop/template/template_chat.zh.mdx index 99c9876546..866170027f 100644 --- a/web/app/components/develop/template/template_chat.zh.mdx +++ b/web/app/components/develop/template/template_chat.zh.mdx @@ -1332,3 +1332,63 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx' + +--- + + + + + 用于获取应用的 WebApp 设置 + ### Response + - `title` (string) WebApp 名称 + - `chat_color_theme` (string) 聊天颜色主题, hex 格式 + - `chat_color_theme_inverted` (bool) 聊天颜色主题是否反转 + - `icon_type` (string) 图标类型, `emoji`-表情, `image`-图片 + - `icon` (string) 图标, 如果是 `emoji` 类型, 则是 emoji 表情符号, 如果是 `image` 类型, 则是图片 URL + - `icon_background` (string) hex 格式的背景色 + - `icon_url` (string) 图标 URL + - `description` (string) 描述 + - `copyright` (string) 版权信息 + - `privacy_policy` (string) 隐私政策链接 + - `custom_disclaimer` (string) 自定义免责声明 + - `default_language` (string) 默认语言 + - `show_workflow_steps` (bool) 是否显示工作流详情 + - `use_icon_as_answer_icon` (bool) 是否使用 WebApp 图标替换聊天中的 🤖 + + + + ```bash {{ title: 'cURL' }} + curl -X GET '${props.appDetail.api_base_url}/site' \ + -H 'Authorization: Bearer {api_key}' + ``` + + + + + ```json {{ title: 'Response' }} + { + "title": "My App", + "chat_color_theme": "#ff4a4a", + "chat_color_theme_inverted": false, + "icon_type": "emoji", + "icon": "😄", + "icon_background": "#FFEAD5", + "icon_url": null, + "description": "This is my app.", + "copyright": "all rights reserved", + "privacy_policy": "", + "custom_disclaimer": "All generated by AI", + "default_language": "en-US", + "show_workflow_steps": false, + "use_icon_as_answer_icon": false, + } + ``` + + + +___ diff --git a/web/app/components/develop/template/template_workflow.en.mdx b/web/app/components/develop/template/template_workflow.en.mdx index 556b306a64..2afcedc88c 100644 --- a/web/app/components/develop/template/template_workflow.en.mdx +++ b/web/app/components/develop/template/template_workflow.en.mdx @@ -737,3 +737,56 @@ Workflow applications offers non-session support and is ideal for translation, a +--- + + + + + Used to get the WebApp settings of the application. + ### Response + - `title` (string) WebApp name + - `icon_type` (string) Icon type, `emoji` - emoji, `image` - picture + - `icon` (string) Icon. If it's `emoji` type, it's an emoji symbol; if it's `image` type, it's an image URL. + - `icon_background` (string) Background color in hex format + - `icon_url` (string) Icon URL + - `description` (string) Description + - `copyright` (string) Copyright information + - `privacy_policy` (string) Privacy policy link + - `custom_disclaimer` (string) Custom disclaimer + - `default_language` (string) Default language + - `show_workflow_steps` (bool) Whether to show workflow details + + + + ```bash {{ title: 'cURL' }} + curl -X GET '${props.appDetail.api_base_url}/site' \ + -H 'Authorization: Bearer {api_key}' + ``` + + + + + ```json {{ title: 'Response' }} + { + "title": "My App", + "icon_type": "emoji", + "icon": "😄", + "icon_background": "#FFEAD5", + "icon_url": null, + "description": "This is my app.", + "copyright": "all rights reserved", + "privacy_policy": "", + "custom_disclaimer": "All generated by AI", + "default_language": "en-US", + "show_workflow_steps": false, + } + ``` + + + +___ diff --git a/web/app/components/develop/template/template_workflow.ja.mdx b/web/app/components/develop/template/template_workflow.ja.mdx index 3f33be58b9..b6afea9bc4 100644 --- a/web/app/components/develop/template/template_workflow.ja.mdx +++ b/web/app/components/develop/template/template_workflow.ja.mdx @@ -740,3 +740,57 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from +——— + + + + + アプリのWebApp設定を取得するために使用します。 + ### 応答 + - `title` (string) WebApp名 + - `icon_type` (string) アイコンタイプ、`emoji`-絵文字、`image`-画像 + - `icon` (string) アイコン。`emoji`タイプの場合は絵文字、`image`タイプの場合は画像URL + - `icon_background` (string) 16進数形式の背景色 + - `icon_url` (string) アイコンのURL + - `description` (string) 説明 + - `copyright` (string) 著作権情報 + - `privacy_policy` (string) プライバシーポリシーのリンク + - `custom_disclaimer` (string) カスタム免責事項 + - `default_language` (string) デフォルト言語 + - `show_workflow_steps` (bool) ワークフローの詳細を表示するかどうか + + + + ```bash {{ title: 'cURL' }} + curl -X GET '${props.appDetail.api_base_url}/site' \ + -H 'Authorization: Bearer {api_key}' + ``` + + + + + ```json {{ title: 'Response' }} + { + "title": "My App", + "icon_type": "emoji", + "icon": "😄", + "icon_background": "#FFEAD5", + "icon_url": null, + "description": "This is my app.", + "copyright": "all rights reserved", + "privacy_policy": "", + "custom_disclaimer": "All generated by AI", + "default_language": "en-US", + "show_workflow_steps": false, + } + ``` + + + +___ + diff --git a/web/app/components/develop/template/template_workflow.zh.mdx b/web/app/components/develop/template/template_workflow.zh.mdx index b032407ee9..e78b309e05 100644 --- a/web/app/components/develop/template/template_workflow.zh.mdx +++ b/web/app/components/develop/template/template_workflow.zh.mdx @@ -727,3 +727,57 @@ Workflow 应用无会话支持,适合用于翻译/文章写作/总结 AI 等 + +--- + + + + + 用于获取应用的 WebApp 设置 + ### Response + - `title` (string) WebApp 名称 + - `icon_type` (string) 图标类型, `emoji`-表情, `image`-图片 + - `icon` (string) 图标, 如果是 `emoji` 类型, 则是 emoji 表情符号, 如果是 `image` 类型, 则是图片 URL + - `icon_background` (string) hex 格式的背景色 + - `icon_url` (string) 图标 URL + - `description` (string) 描述 + - `copyright` (string) 版权信息 + - `privacy_policy` (string) 隐私政策链接 + - `custom_disclaimer` (string) 自定义免责声明 + - `default_language` (string) 默认语言 + - `show_workflow_steps` (bool) 是否显示工作流详情 + + + + ```bash {{ title: 'cURL' }} + curl -X GET '${props.appDetail.api_base_url}/site' \ + -H 'Authorization: Bearer {api_key}' + ``` + + + + + ```json {{ title: 'Response' }} + { + "title": "My App", + "icon_type": "emoji", + "icon": "😄", + "icon_background": "#FFEAD5", + "icon_url": null, + "description": "This is my app.", + "copyright": "all rights reserved", + "privacy_policy": "", + "custom_disclaimer": "All generated by AI", + "default_language": "en-US", + "show_workflow_steps": false, + } + ``` + + + +___ diff --git a/web/app/components/header/account-setting/model-provider-page/install-from-marketplace.tsx b/web/app/components/header/account-setting/model-provider-page/install-from-marketplace.tsx index 38f35d6fb4..818007a26f 100644 --- a/web/app/components/header/account-setting/model-provider-page/install-from-marketplace.tsx +++ b/web/app/components/header/account-setting/model-provider-page/install-from-marketplace.tsx @@ -1,4 +1,5 @@ import { useCallback, useState } from 'react' +import { useTheme } from 'next-themes' import { useTranslation } from 'react-i18next' import Link from 'next/link' import { @@ -29,6 +30,7 @@ const InstallFromMarketplace = ({ searchText, }: InstallFromMarketplaceProps) => { const { t } = useTranslation() + const { theme } = useTheme() const [collapse, setCollapse] = useState(false) const locale = getLocaleOnClient() const { @@ -53,7 +55,7 @@ const InstallFromMarketplace = ({
{t('common.modelProvider.discoverMore')} - + {t('plugin.marketplace.difyMarketplace')} diff --git a/web/app/components/plugins/marketplace/list/card-wrapper.tsx b/web/app/components/plugins/marketplace/list/card-wrapper.tsx index 75c9aae3d5..27511559d9 100644 --- a/web/app/components/plugins/marketplace/list/card-wrapper.tsx +++ b/web/app/components/plugins/marketplace/list/card-wrapper.tsx @@ -1,4 +1,5 @@ 'use client' +import { useTheme } from 'next-themes' import { RiArrowRightUpLine } from '@remixicon/react' import { getPluginLinkInMarketplace } from '../utils' import Card from '@/app/components/plugins/card' @@ -22,6 +23,7 @@ const CardWrapper = ({ locale, }: CardWrapperProps) => { const { t } = useMixedTranslation(locale) + const { theme } = useTheme() const [isShowInstallFromMarketplace, { setTrue: showInstallFromMarketplace, setFalse: hideInstallFromMarketplace, @@ -54,7 +56,7 @@ const CardWrapper = ({ > {t('plugin.detailPanel.operation.install')} - +
) } + { + node.varErrorMessage?.map((errorMessage: string) => ( +
+
+ + {errorMessage} +
+
+ )) + }
)) diff --git a/web/app/components/workflow/hooks/use-checklist.ts b/web/app/components/workflow/hooks/use-checklist.ts index c1b0189b8b..4b0fcca192 100644 --- a/web/app/components/workflow/hooks/use-checklist.ts +++ b/web/app/components/workflow/hooks/use-checklist.ts @@ -15,6 +15,7 @@ import { useStore } from '../store' import { getToolCheckParams, getValidTreeNodes, + transformStartNodeVariables, } from '../utils' import { CUSTOM_NODE, @@ -45,6 +46,9 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => { const { data: strategyProviders } = useStrategyProviders() const datasetsDetail = useDatasetsDetailStore(s => s.datasetsDetail) + const chatVarList = useStore(s => s.conversationVariables) + const environmentVariables = useStore(s => s.environmentVariables) + const getCheckData = useCallback((data: CommonNodeType<{}>) => { let checkData = data if (data.type === BlockEnum.KnowledgeRetrieval) { @@ -64,7 +68,10 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => { const needWarningNodes = useMemo(() => { const list = [] - const { validNodes } = getValidTreeNodes(nodes.filter(node => node.type === CUSTOM_NODE), edges) + const { validNodes } = getValidTreeNodes(nodes.filter(node => node.type === CUSTOM_NODE), edges, true) + + const allVariablesMap = transformStartNodeVariables(chatVarList, environmentVariables) + const errMessageMap = new Map() for (let i = 0; i < nodes.length; i++) { const node = nodes[i] @@ -110,8 +117,32 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => { toolIcon, unConnected: !validNodes.find(n => n.id === node.id), errorMessage, + varErrorMessage: [], }) } + errMessageMap.set(node.id, list[list.length - 1]) + if (nodesExtraData[node.data.type as BlockEnum].checkVarValid) { + const { errorMessage: varErrorMessages } = nodesExtraData[node.data.type as BlockEnum].checkVarValid(node.data, { ...allVariablesMap, ...node._parentOutputVarMap }, t) + + if (varErrorMessages?.length) { + const errMessage = errMessageMap.get(node.id) + if (errMessage) { + errMessage.varErrorMessage = varErrorMessages + } + else { + list.push({ + id: node.id, + type: node.data.type, + title: node.data.title, + toolIcon, + unConnected: !validNodes.find(n => n.id === node.id), + errorMessage: '', + varErrorMessage: varErrorMessages, + }) + errMessageMap.set(node.id, list[list.length - 1]) + } + } + } } } @@ -133,8 +164,13 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => { }) } + for (let i = 0; i < validNodes.length; i++) { + const node = validNodes[i] + delete node._parentOutputVarMap + } + return list - }, [nodes, edges, isChatMode, buildInTools, customTools, workflowTools, language, nodesExtraData, t, strategyProviders, getCheckData]) + }, [nodes, edges, isChatMode, buildInTools, customTools, workflowTools, language, nodesExtraData, t, strategyProviders, getCheckData, chatVarList, environmentVariables]) return needWarningNodes } @@ -153,6 +189,9 @@ export const useChecklistBeforePublish = () => { const updateDatasetsDetail = useDatasetsDetailStore(s => s.updateDatasetsDetail) const updateTime = useRef(0) + const chatVarList = useStore(s => s.conversationVariables) + const environmentVariables = useStore(s => s.environmentVariables) + const getCheckData = useCallback((data: CommonNodeType<{}>, datasets: DataSet[]) => { let checkData = data if (data.type === BlockEnum.KnowledgeRetrieval) { @@ -183,12 +222,15 @@ export const useChecklistBeforePublish = () => { const { validNodes, maxDepth, - } = getValidTreeNodes(nodes.filter(node => node.type === CUSTOM_NODE), edges) + } = getValidTreeNodes(nodes.filter(node => node.type === CUSTOM_NODE), edges, true) if (maxDepth > MAX_TREE_DEPTH) { notify({ type: 'error', message: t('workflow.common.maxTreeDepth', { depth: MAX_TREE_DEPTH }) }) return false } + + const allVariablesMap = transformStartNodeVariables(chatVarList, environmentVariables) + // Before publish, we need to fetch datasets detail, in case of the settings of datasets have been changed const knowledgeRetrievalNodes = nodes.filter(node => node.data.type === BlockEnum.KnowledgeRetrieval) const allDatasetIds = knowledgeRetrievalNodes.reduce((acc, node) => { @@ -239,6 +281,14 @@ export const useChecklistBeforePublish = () => { notify({ type: 'error', message: `[${node.data.title}] ${t('workflow.common.needConnectTip')}` }) return false } + + if (nodesExtraData[node.data.type as BlockEnum].checkVarValid) { + const { errorMessage: varErrorMessage } = nodesExtraData[node.data.type as BlockEnum].checkVarValid(node.data, { ...allVariablesMap, ...node._parentOutputVarMap }, t) + if (varErrorMessage?.length) { + notify({ type: 'error', message: `[${node.data.title}] ${varErrorMessage[0]}` }) + return false + } + } } if (isChatMode && !nodes.find(node => node.data.type === BlockEnum.Answer)) { @@ -252,7 +302,7 @@ export const useChecklistBeforePublish = () => { } return true - }, [store, isChatMode, notify, t, buildInTools, customTools, workflowTools, language, nodesExtraData, strategyProviders, updateDatasetsDetail, getCheckData]) + }, [store, isChatMode, notify, t, buildInTools, customTools, workflowTools, language, nodesExtraData, strategyProviders, updateDatasetsDetail, getCheckData, chatVarList, environmentVariables]) return { handleCheckBeforePublish, diff --git a/web/app/components/workflow/nodes/_base/components/variable/utils.ts b/web/app/components/workflow/nodes/_base/components/variable/utils.ts index f804cf6902..751d438d68 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/utils.ts +++ b/web/app/components/workflow/nodes/_base/components/variable/utils.ts @@ -164,7 +164,7 @@ const findExceptVarInObject = (obj: any, filterVar: (payload: Var, selector: Val return res } -const formatItem = ( +export const formatItem = ( item: any, isChatMode: boolean, filterVar: (payload: Var, selector: ValueSelector) => boolean, diff --git a/web/app/components/workflow/nodes/answer/default.ts b/web/app/components/workflow/nodes/answer/default.ts index 4ff6e49d7e..5dff505007 100644 --- a/web/app/components/workflow/nodes/answer/default.ts +++ b/web/app/components/workflow/nodes/answer/default.ts @@ -1,5 +1,6 @@ import { BlockEnum } from '../../types' -import type { NodeDefault } from '../../types' +import type { NodeDefault, Var } from '../../types' +import { getNotExistVariablesByText } from '../../utils/workflow' import type { AnswerNodeType } from './types' import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks' @@ -31,6 +32,19 @@ const nodeDefault: NodeDefault = { errorMessage: errorMessages, } }, + checkVarValid(payload: AnswerNodeType, varMap: Record, t: any) { + const errorMessageArr = [] + + const answer_warnings = getNotExistVariablesByText(payload.answer || '', varMap) + if (answer_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.answer.answer')} ${t('workflow.common.referenceVar')}${answer_warnings.join('、')}${t('workflow.common.noExist')}`) + + return { + isValid: true, + warning_vars: [...answer_warnings], + errorMessage: errorMessageArr, + } + }, } export default nodeDefault diff --git a/web/app/components/workflow/nodes/assigner/default.ts b/web/app/components/workflow/nodes/assigner/default.ts index 6341305576..32dac73b36 100644 --- a/web/app/components/workflow/nodes/assigner/default.ts +++ b/web/app/components/workflow/nodes/assigner/default.ts @@ -1,5 +1,6 @@ import { BlockEnum } from '../../types' -import type { NodeDefault } from '../../types' +import type { NodeDefault, Var } from '../../types' +import { getNotExistVariablesByArray } from '../../utils/workflow' import { type AssignerNodeType, WriteMode } from './types' import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks' const i18nPrefix = 'workflow.errorMsg' @@ -47,6 +48,23 @@ const nodeDefault: NodeDefault = { errorMessage: errorMessages, } }, + + checkVarValid(payload: AssignerNodeType, varMap: Record, t: any) { + const errorMessageArr: string[] = [] + const variables_warnings = getNotExistVariablesByArray(payload.items.map(item => item.variable_selector ?? []) ?? [], varMap) + if (variables_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.assigner.assignedVariable')} ${t('workflow.common.referenceVar')}${variables_warnings.join('、')}${t('workflow.common.noExist')}`) + + const value_warnings = getNotExistVariablesByArray(payload.items.map(item => item.value ?? []) ?? [], varMap) + if (value_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.assigner.setVariable')} ${t('workflow.common.referenceVar')}${value_warnings.join('、')}${t('workflow.common.noExist')}`) + + return { + isValid: true, + warning_vars: [...variables_warnings, ...value_warnings], + errorMessage: errorMessageArr, + } + }, } export default nodeDefault diff --git a/web/app/components/workflow/nodes/code/default.ts b/web/app/components/workflow/nodes/code/default.ts index 5f90c18716..320cac59b4 100644 --- a/web/app/components/workflow/nodes/code/default.ts +++ b/web/app/components/workflow/nodes/code/default.ts @@ -1,5 +1,6 @@ import { BlockEnum } from '../../types' -import type { NodeDefault } from '../../types' +import type { NodeDefault, Var } from '../../types' +import { getNotExistVariablesByArray } from '../../utils/workflow' import { CodeLanguage, type CodeNodeType } from './types' import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks' @@ -37,7 +38,20 @@ const nodeDefault: NodeDefault = { errorMessage: errorMessages, } }, + checkVarValid(payload: CodeNodeType, varMap: Record, t: any) { + const errorMessageArr = [] + const variables_selector = payload.variables.map(v => v.value_selector) + const variables_selector_warnings = getNotExistVariablesByArray(variables_selector, varMap) + if (variables_selector_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.code.inputVars')} ${t('workflow.common.referenceVar')}${variables_selector_warnings.join('、')}${t('workflow.common.noExist')}`) + + return { + isValid: true, + warning_vars: variables_selector_warnings, + errorMessage: errorMessageArr, + } + }, } export default nodeDefault diff --git a/web/app/components/workflow/nodes/document-extractor/default.ts b/web/app/components/workflow/nodes/document-extractor/default.ts index e141844d19..57eb58b168 100644 --- a/web/app/components/workflow/nodes/document-extractor/default.ts +++ b/web/app/components/workflow/nodes/document-extractor/default.ts @@ -1,5 +1,6 @@ import { BlockEnum } from '../../types' -import type { NodeDefault } from '../../types' +import type { NodeDefault, Var } from '../../types' +import { getNotExistVariablesByArray } from '../../utils/workflow' import type { DocExtractorNodeType } from './types' import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks' const i18nPrefix = 'workflow.errorMsg' @@ -31,6 +32,19 @@ const nodeDefault: NodeDefault = { errorMessage: errorMessages, } }, + checkVarValid(payload: DocExtractorNodeType, varMap: Record, t: any) { + const errorMessageArr: string[] = [] + + const variables_warnings = getNotExistVariablesByArray([payload.variable_selector], varMap) + if (variables_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.docExtractor.inputVar')} ${t('workflow.common.referenceVar')}${variables_warnings.join('、')}${t('workflow.common.noExist')}`) + + return { + isValid: true, + warning_vars: variables_warnings, + errorMessage: errorMessageArr, + } + }, } export default nodeDefault diff --git a/web/app/components/workflow/nodes/http/default.ts b/web/app/components/workflow/nodes/http/default.ts index 1bd584eeb9..1c027a3fec 100644 --- a/web/app/components/workflow/nodes/http/default.ts +++ b/web/app/components/workflow/nodes/http/default.ts @@ -1,5 +1,6 @@ import { BlockEnum } from '../../types' -import type { NodeDefault } from '../../types' +import type { NodeDefault, Var } from '../../types' +import { getNotExistVariablesByArray, getNotExistVariablesByText } from '../../utils/workflow' import { AuthorizationType, BodyType, Method } from './types' import type { BodyPayload, HttpNodeType } from './types' import { @@ -50,8 +51,8 @@ const nodeDefault: NodeDefault = { errorMessages = t('workflow.errorMsg.fieldRequired', { field: t('workflow.nodes.http.api') }) if (!errorMessages - && payload.body.type === BodyType.binary - && ((!(payload.body.data as BodyPayload)[0]?.file) || (payload.body.data as BodyPayload)[0]?.file?.length === 0) + && payload.body.type === BodyType.binary + && ((!(payload.body.data as BodyPayload)[0]?.file) || (payload.body.data as BodyPayload)[0]?.file?.length === 0) ) errorMessages = t('workflow.errorMsg.fieldRequired', { field: t('workflow.nodes.http.binaryFileVariable') }) @@ -60,6 +61,53 @@ const nodeDefault: NodeDefault = { errorMessage: errorMessages, } }, + checkVarValid(payload: HttpNodeType, varMap: Record, t: any) { + const errorMessageArr: string[] = [] + const url_warnings = getNotExistVariablesByText(payload.url, varMap) + if (url_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.http.api')} ${t('workflow.common.referenceVar')}${url_warnings.join('、')}${t('workflow.common.noExist')}`) + + const headers_warnings = getNotExistVariablesByText(payload.headers, varMap) + if (headers_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.http.headers')} ${t('workflow.common.referenceVar')}${headers_warnings.join('、')}${t('workflow.common.noExist')}`) + + const params_warnings = getNotExistVariablesByText(payload.params, varMap) + if (params_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.http.params')} ${t('workflow.common.referenceVar')}${params_warnings.join('、')}${t('workflow.common.noExist')}`) + + const body_warnings: string[] = [] + + if ([BodyType.binary].includes(payload.body.type)) { + const body_data = payload.body.data as BodyPayload + body_data.forEach((item) => { + const key_warnings = getNotExistVariablesByText(item.key || '', varMap) + if (key_warnings.length) + body_warnings.push(...key_warnings) + const warnings = getNotExistVariablesByArray([item.file || []], varMap) + if (warnings.length) + body_warnings.push(...warnings) + }) + } + else { + const body_data = payload.body.data as BodyPayload + body_data.forEach((item) => { + const key_warnings = getNotExistVariablesByText(item.key || '', varMap) + if (key_warnings.length) + body_warnings.push(...key_warnings) + const value_warnings = getNotExistVariablesByText(item.value || '', varMap) + if (value_warnings.length) + body_warnings.push(...value_warnings) + }) + } + if (body_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.http.body')} ${t('workflow.common.referenceVar')}${body_warnings.join('、')}${t('workflow.common.noExist')}`) + + return { + isValid: true, + warning_vars: [...url_warnings, ...headers_warnings, ...params_warnings, ...body_warnings], + errorMessage: errorMessageArr, + } + }, } export default nodeDefault diff --git a/web/app/components/workflow/nodes/if-else/default.ts b/web/app/components/workflow/nodes/if-else/default.ts index 1be80592e5..53c139b4c0 100644 --- a/web/app/components/workflow/nodes/if-else/default.ts +++ b/web/app/components/workflow/nodes/if-else/default.ts @@ -1,4 +1,6 @@ +import type { Var } from '../../types' import { BlockEnum, type NodeDefault } from '../../types' +import { getNotExistVariablesByArray, getNotExistVariablesByText } from '../../utils/workflow' import { type IfElseNodeType, LogicalOperator } from './types' import { isEmptyRelatedOperator } from './utils' import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks' @@ -75,6 +77,41 @@ const nodeDefault: NodeDefault = { errorMessage: errorMessages, } }, + checkVarValid(payload: IfElseNodeType, varMap: Record, t: any) { + const errorMessageArr = [] + + const condition_variable_selector_warnings: string[] = [] + const condition_value_warnings: string[] = [] + payload.cases.forEach((caseItem) => { + caseItem.conditions.forEach((condition) => { + if (!condition.variable_selector) + return + const selector_warnings = getNotExistVariablesByArray([condition.variable_selector], varMap) + if (selector_warnings.length) + condition_variable_selector_warnings.push(...selector_warnings) + const value_warnings = Array.isArray(condition.value) ? getNotExistVariablesByArray([condition.value], varMap) : getNotExistVariablesByText(condition.value, varMap) + if (value_warnings.length) + condition_value_warnings.push(...value_warnings) + condition.sub_variable_condition?.conditions.forEach((subCondition) => { + const sub_variable_value_warnings = Array.isArray(subCondition.value) ? getNotExistVariablesByArray([subCondition.value], varMap) : getNotExistVariablesByText(subCondition.value, varMap) + if (sub_variable_value_warnings.length) + condition_value_warnings.push(...sub_variable_value_warnings) + }) + }) + }) + + if (condition_variable_selector_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.ifElse.condition')} ${t('workflow.common.referenceVar')}${condition_variable_selector_warnings.join('、')}${t('workflow.common.noExist')}`) + + if (condition_value_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.ifElse.enterValue')} ${t('workflow.common.referenceVar')}${condition_value_warnings.join('、')}${t('workflow.common.noExist')}`) + + return { + isValid: true, + warning_vars: condition_variable_selector_warnings, + errorMessage: errorMessageArr, + } + }, } export default nodeDefault diff --git a/web/app/components/workflow/nodes/iteration/default.ts b/web/app/components/workflow/nodes/iteration/default.ts index 0ef8382abe..392c64137e 100644 --- a/web/app/components/workflow/nodes/iteration/default.ts +++ b/web/app/components/workflow/nodes/iteration/default.ts @@ -1,5 +1,6 @@ import { BlockEnum, ErrorHandleMode } from '../../types' -import type { NodeDefault } from '../../types' +import type { NodeDefault, Var } from '../../types' +import { getNotExistVariablesByArray } from '../../utils/workflow' import type { IterationNodeType } from './types' import { ALL_CHAT_AVAILABLE_BLOCKS, @@ -58,6 +59,19 @@ const nodeDefault: NodeDefault = { errorMessage: errorMessages, } }, + checkVarValid(payload: IterationNodeType, varMap: Record, t: any) { + const errorMessageArr: string[] = [] + + const iterator_selector_warnings = getNotExistVariablesByArray([payload.iterator_selector], varMap) + if (iterator_selector_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.iteration.input')} ${t('workflow.common.referenceVar')}${iterator_selector_warnings.join('、')}${t('workflow.common.noExist')}`) + + return { + isValid: true, + warning_vars: iterator_selector_warnings, + errorMessage: errorMessageArr, + } + }, } export default nodeDefault diff --git a/web/app/components/workflow/nodes/knowledge-retrieval/default.ts b/web/app/components/workflow/nodes/knowledge-retrieval/default.ts index 09da8dd789..955e30d90f 100644 --- a/web/app/components/workflow/nodes/knowledge-retrieval/default.ts +++ b/web/app/components/workflow/nodes/knowledge-retrieval/default.ts @@ -1,5 +1,6 @@ import { BlockEnum } from '../../types' -import type { NodeDefault } from '../../types' +import type { NodeDefault, Var } from '../../types' +import { getNotExistVariablesByArray } from '../../utils/workflow' import type { KnowledgeRetrievalNodeType } from './types' import { checkoutRerankModelConfigedInRetrievalSettings } from './utils' import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks' @@ -52,6 +53,19 @@ const nodeDefault: NodeDefault = { errorMessage: errorMessages, } }, + checkVarValid(payload: KnowledgeRetrievalNodeType, varMap: Record, t: any) { + const errorMessageArr = [] + + const query_variable_selector_warnings = getNotExistVariablesByArray([payload.query_variable_selector], varMap) + if (query_variable_selector_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.knowledgeRetrieval.queryVariable')} ${t('workflow.common.referenceVar')}${query_variable_selector_warnings.join('、')}${t('workflow.common.noExist')}`) + + return { + isValid: true, + warning_vars: [...query_variable_selector_warnings], + errorMessage: errorMessageArr, + } + }, } export default nodeDefault diff --git a/web/app/components/workflow/nodes/list-operator/default.ts b/web/app/components/workflow/nodes/list-operator/default.ts index 0256cb8673..c2d15edc58 100644 --- a/web/app/components/workflow/nodes/list-operator/default.ts +++ b/web/app/components/workflow/nodes/list-operator/default.ts @@ -1,5 +1,6 @@ import { BlockEnum, VarType } from '../../types' -import type { NodeDefault } from '../../types' +import type { NodeDefault, Var } from '../../types' +import { getNotExistVariablesByArray } from '../../utils/workflow' import { comparisonOperatorNotRequireValue } from '../if-else/utils' import { type ListFilterNodeType, OrderBy } from './types' import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks' @@ -60,6 +61,18 @@ const nodeDefault: NodeDefault = { errorMessage: errorMessages, } }, + checkVarValid(payload: ListFilterNodeType, varMap: Record, t: any) { + const errorMessageArr = [] + + const variable_warnings = getNotExistVariablesByArray([payload.variable], varMap) + if (variable_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.listFilter.inputVar')} ${t('workflow.common.referenceVar')}${variable_warnings.join('、')}${t('workflow.common.noExist')}`) + return { + isValid: true, + warning_vars: variable_warnings, + errorMessage: errorMessageArr, + } + }, } export default nodeDefault diff --git a/web/app/components/workflow/nodes/list-operator/panel.tsx b/web/app/components/workflow/nodes/list-operator/panel.tsx index a09839f04f..d93a79397d 100644 --- a/web/app/components/workflow/nodes/list-operator/panel.tsx +++ b/web/app/components/workflow/nodes/list-operator/panel.tsx @@ -97,16 +97,14 @@ const Panel: FC> = ({ {inputs.extract_by?.enabled ? (
- {hasSubVariable && ( -
- -
- )} +
+ +
) : null} diff --git a/web/app/components/workflow/nodes/llm/default.ts b/web/app/components/workflow/nodes/llm/default.ts index 92377f74b8..5625c85480 100644 --- a/web/app/components/workflow/nodes/llm/default.ts +++ b/web/app/components/workflow/nodes/llm/default.ts @@ -1,5 +1,7 @@ -import { BlockEnum, EditionType } from '../../types' +import type { Var } from '../../types' +import { BlockEnum, EditionType, VarType } from '../../types' import { type NodeDefault, type PromptItem, PromptRole } from '../../types' +import { getNotExistVariablesByArray, getNotExistVariablesByText } from '../../utils/workflow' import type { LLMNodeType } from './types' import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks' @@ -86,6 +88,37 @@ const nodeDefault: NodeDefault = { errorMessage: errorMessages, } }, + checkVarValid(payload: LLMNodeType, varMap: Record, t: any) { + const errorMessageArr = [] + const prompt_templates_warnings: string[] = [] + if (payload.context?.enabled && payload.context?.variable_selector?.length) { + const context_variable_selector_warnings = getNotExistVariablesByArray([payload.context.variable_selector], varMap) + if (context_variable_selector_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.llm.context')} ${t('workflow.common.referenceVar')}${context_variable_selector_warnings.join('、')}${t('workflow.common.noExist')}`) + } + const prompt_templates = Array.isArray(payload.prompt_template) ? payload.prompt_template : [payload.prompt_template] as PromptItem[] + prompt_templates.forEach((v) => { + prompt_templates_warnings.push(...getNotExistVariablesByText(v.text, { context: { variable: 'context', type: VarType.string }, ...varMap })) + }) + if (prompt_templates_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.llm.prompt')} ${t('workflow.common.referenceVar')}${prompt_templates_warnings.join('、')}${t('workflow.common.noExist')}`) + + const memory_query_prompt_template_warnings = getNotExistVariablesByText(payload.memory?.query_prompt_template || '', varMap) + if (memory_query_prompt_template_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.common.memories.title')}USER ${t('workflow.common.referenceVar')}${memory_query_prompt_template_warnings.join('、')}${t('workflow.common.noExist')}`) + + if (payload.vision?.enabled && payload.vision?.configs?.variable_selector?.length) { + const vision_variable_selector_warnings = getNotExistVariablesByArray([payload.vision.configs.variable_selector], varMap) + if (vision_variable_selector_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.llm.vision')} ${t('workflow.common.referenceVar')}${vision_variable_selector_warnings.join('、')}${t('workflow.common.noExist')}`) + } + + return { + isValid: true, + warning_vars: [...prompt_templates_warnings, ...memory_query_prompt_template_warnings], + errorMessage: errorMessageArr, + } + }, } export default nodeDefault diff --git a/web/app/components/workflow/nodes/parameter-extractor/default.ts b/web/app/components/workflow/nodes/parameter-extractor/default.ts index 0e3b707d30..5ab5384502 100644 --- a/web/app/components/workflow/nodes/parameter-extractor/default.ts +++ b/web/app/components/workflow/nodes/parameter-extractor/default.ts @@ -1,5 +1,6 @@ import { BlockEnum } from '../../types' -import type { NodeDefault } from '../../types' +import type { NodeDefault, Var } from '../../types' +import { getNotExistVariablesByArray, getNotExistVariablesByText } from '../../utils/workflow' import { type ParameterExtractorNodeType, ReasoningModeType } from './types' import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks' const i18nPrefix = 'workflow' @@ -64,6 +65,30 @@ const nodeDefault: NodeDefault = { errorMessage: errorMessages, } }, + checkVarValid(payload: ParameterExtractorNodeType, varMap: Record, t: any) { + const errorMessageArr: string[] = [] + + const variables_warnings = getNotExistVariablesByArray([payload.query], varMap) + if (variables_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.parameterExtractor.inputVar')} ${t('workflow.common.referenceVar')}${variables_warnings.join('、')}${t('workflow.common.noExist')}`) + + let vision_variable_warnings: string[] = [] + if (payload.vision?.configs?.variable_selector?.length) { + vision_variable_warnings = getNotExistVariablesByArray([payload.vision.configs.variable_selector], varMap) + if (vision_variable_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.llm.vision')} ${t('workflow.common.referenceVar')}${vision_variable_warnings.join('、')}${t('workflow.common.noExist')}`) + } + + const instruction_warnings = getNotExistVariablesByText(payload.instruction, varMap) + if (instruction_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.parameterExtractor.instruction')} ${t('workflow.common.referenceVar')}${instruction_warnings.join('、')}${t('workflow.common.noExist')}`) + + return { + isValid: true, + warning_vars: [...variables_warnings, ...vision_variable_warnings, ...instruction_warnings], + errorMessage: errorMessageArr, + } + }, } export default nodeDefault diff --git a/web/app/components/workflow/nodes/question-classifier/default.ts b/web/app/components/workflow/nodes/question-classifier/default.ts index 2729c53f29..70410a5f18 100644 --- a/web/app/components/workflow/nodes/question-classifier/default.ts +++ b/web/app/components/workflow/nodes/question-classifier/default.ts @@ -1,5 +1,6 @@ -import type { NodeDefault } from '../../types' +import type { NodeDefault, Var } from '../../types' import { BlockEnum } from '../../types' +import { getNotExistVariablesByArray, getNotExistVariablesByText } from '../../utils/workflow' import type { QuestionClassifierNodeType } from './types' import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks' @@ -71,6 +72,30 @@ const nodeDefault: NodeDefault = { errorMessage: errorMessages, } }, + checkVarValid(payload: QuestionClassifierNodeType, varMap: Record, t: any) { + const errorMessageArr = [] + + const query_variable_selector_warnings = getNotExistVariablesByArray([payload.query_variable_selector], varMap) + if (query_variable_selector_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.questionClassifiers.inputVars')} ${t('workflow.common.referenceVar')}${query_variable_selector_warnings.join('、')}${t('workflow.common.noExist')}`) + + let vision_variable_selector_warnings: string[] = [] + if (payload.vision?.configs?.variable_selector?.length) { + vision_variable_selector_warnings = getNotExistVariablesByArray([payload.vision?.configs?.variable_selector], varMap) + if (vision_variable_selector_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.llm.vision')} ${t('workflow.common.referenceVar')}${vision_variable_selector_warnings.join('、')}${t('workflow.common.noExist')}`) + } + + const instruction_warnings: string[] = getNotExistVariablesByText(payload.instruction, varMap) + if (instruction_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.questionClassifiers.advancedSetting')}-${t('workflow.nodes.questionClassifiers.instruction')} ${t('workflow.common.referenceVar')}${instruction_warnings.join('、')}${t('workflow.common.noExist')}`) + + return { + isValid: true, + warning_vars: [...query_variable_selector_warnings, ...vision_variable_selector_warnings, ...instruction_warnings], + errorMessage: errorMessageArr, + } + }, } export default nodeDefault diff --git a/web/app/components/workflow/nodes/template-transform/default.ts b/web/app/components/workflow/nodes/template-transform/default.ts index c698680342..25e5d7f961 100644 --- a/web/app/components/workflow/nodes/template-transform/default.ts +++ b/web/app/components/workflow/nodes/template-transform/default.ts @@ -1,5 +1,6 @@ import { BlockEnum } from '../../types' -import type { NodeDefault } from '../../types' +import type { NodeDefault, Var } from '../../types' +import { getNotExistVariablesByArray } from '../../utils/workflow' import type { TemplateTransformNodeType } from './types' import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks' const i18nPrefix = 'workflow.errorMsg' @@ -33,6 +34,19 @@ const nodeDefault: NodeDefault = { errorMessage: errorMessages, } }, + checkVarValid(payload: TemplateTransformNodeType, varMap: Record, t: any) { + const errorMessageArr = [] + + const variables_selector = payload.variables.map(v => v.value_selector) + const variables_selector_warnings = getNotExistVariablesByArray(variables_selector, varMap) + if (variables_selector_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.templateTransform.inputVars')} ${t('workflow.common.referenceVar')}${variables_selector_warnings.join('、')}${t('workflow.common.noExist')}`) + + return { + isValid: true, + errorMessage: errorMessageArr, + } + }, } export default nodeDefault diff --git a/web/app/components/workflow/nodes/tool/default.ts b/web/app/components/workflow/nodes/tool/default.ts index f245929684..782c575c8e 100644 --- a/web/app/components/workflow/nodes/tool/default.ts +++ b/web/app/components/workflow/nodes/tool/default.ts @@ -1,8 +1,9 @@ import { BlockEnum } from '../../types' -import type { NodeDefault } from '../../types' +import type { NodeDefault, Var } from '../../types' import type { ToolNodeType } from './types' import { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types' import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks' +import { getNotExistVariablesByArray, getNotExistVariablesByText } from '../../utils/workflow' const i18nPrefix = 'workflow.errorMsg' @@ -63,6 +64,35 @@ const nodeDefault: NodeDefault = { errorMessage: errorMessages, } }, + checkVarValid(payload: ToolNodeType, varMap: Record, t: any) { + const errorMessageArr = [] + const tool_parametersMap = payload.tool_parameters + const tool_parameters_array = Object.values(tool_parametersMap) + const tool_parameters_warnings: string[] = [] + tool_parameters_array?.forEach((item) => { + if (!item.value) + return + if (Array.isArray(item.value)) { + const warnings = getNotExistVariablesByArray([item.value], varMap) + if (warnings.length) + tool_parameters_warnings.push(...warnings) + return + } + if (typeof item.value === 'string') { + const warnings = getNotExistVariablesByText(item.value, varMap) + if (warnings.length) + tool_parameters_warnings.push(...warnings) + } + }) + if (tool_parameters_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.tool.inputVars')} ${t('workflow.common.referenceVar')}${tool_parameters_warnings.join('、')}${t('workflow.common.noExist')}`) + + return { + isValid: true, + warning_vars: tool_parameters_warnings, + errorMessage: errorMessageArr, + } + }, } export default nodeDefault diff --git a/web/app/components/workflow/nodes/variable-assigner/default.ts b/web/app/components/workflow/nodes/variable-assigner/default.ts index 60c7c27969..8482406602 100644 --- a/web/app/components/workflow/nodes/variable-assigner/default.ts +++ b/web/app/components/workflow/nodes/variable-assigner/default.ts @@ -1,5 +1,7 @@ +import type { Var } from '../../types' import { type NodeDefault, VarType } from '../../types' import { BlockEnum } from '../../types' +import { getNotExistVariablesByArray } from '../../utils/workflow' import type { VariableAssignerNodeType } from './types' import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/blocks' @@ -54,6 +56,18 @@ const nodeDefault: NodeDefault = { errorMessage: errorMessages, } }, + checkVarValid(payload: VariableAssignerNodeType, varMap: Record, t: any) { + const errorMessageArr: string[] = [] + const variables_warnings = getNotExistVariablesByArray(payload.variables ?? [], varMap) + if (variables_warnings.length) + errorMessageArr.push(`${t('workflow.nodes.variableAssigner.title')} ${t('workflow.common.referenceVar')}${variables_warnings.join('、')}${t('workflow.common.noExist')}`) + + return { + isValid: true, + warning_vars: variables_warnings, + errorMessage: errorMessageArr, + } + }, } export default nodeDefault diff --git a/web/app/components/workflow/types.ts b/web/app/components/workflow/types.ts index 884bdfbd10..1e6186924e 100644 --- a/web/app/components/workflow/types.ts +++ b/web/app/components/workflow/types.ts @@ -297,6 +297,7 @@ export type NodeDefault = { getAvailablePrevNodes: (isChatMode: boolean) => BlockEnum[] getAvailableNextNodes: (isChatMode: boolean) => BlockEnum[] checkValid: (payload: T, t: any, moreDataForCheckValid?: any) => { isValid: boolean; errorMessage?: string } + checkVarValid?: (payload: T, varMap: Record, t: any,) => { isValid: boolean; errorMessage?: string[] } } export type OnSelectBlock = (type: BlockEnum, toolDefaultValue?: ToolDefaultValue) => void diff --git a/web/app/components/workflow/utils/workflow-init.spec.ts b/web/app/components/workflow/utils/workflow-init.spec.ts index 8b7bdfaa92..d96e54a76a 100644 --- a/web/app/components/workflow/utils/workflow-init.spec.ts +++ b/web/app/components/workflow/utils/workflow-init.spec.ts @@ -5,6 +5,18 @@ import type { } from '@/app/components/workflow/types' import { CUSTOM_ITERATION_START_NODE } from '@/app/components/workflow/nodes/iteration-start/constants' +jest.mock('ky', () => ({ + __esModule: true, + default: { + create: jest.fn(), + }, +})) + +jest.mock('lodash-es/groupBy', () => ({ + __esModule: true, + default: jest.fn(), +})) + describe('preprocessNodesAndEdges', () => { it('process nodes without iteration node or loop node should return origin nodes and edges.', () => { const nodes = [ diff --git a/web/app/components/workflow/utils/workflow.ts b/web/app/components/workflow/utils/workflow.ts index 88c31f09b5..739908646a 100644 --- a/web/app/components/workflow/utils/workflow.ts +++ b/web/app/components/workflow/utils/workflow.ts @@ -10,14 +10,20 @@ import { uniqBy, } from 'lodash-es' import type { + ConversationVariable, Edge, + EnvironmentVariable, Node, + Var, } from '../types' import { BlockEnum, } from '../types' import type { IterationNodeType } from '../nodes/iteration/types' import type { LoopNodeType } from '../nodes/loop/types' +import { VAR_REGEX_TEXT } from '@/config' +import { formatItem } from '../nodes/_base/components/variable/utils' +import type { StructuredOutput } from '../nodes/llm/types' export const canRunBySingle = (nodeType: BlockEnum) => { return nodeType === BlockEnum.LLM @@ -86,7 +92,17 @@ export const getNodesConnectedSourceOrTargetHandleIdsMap = (changes: ConnectedSo return nodesConnectedSourceOrTargetHandleIdsMap } -export const getValidTreeNodes = (nodes: Node[], edges: Edge[]) => { +function getParentOutputVarMap(item: Var, path: string, varMap: Record) { + if (!item.children || (Array.isArray(item.children) && !item.children.length) || ((item.children as StructuredOutput).schema)) + return + (item.children as Var[]).forEach((child) => { + const newPath = `${path}.${child.variable}` + varMap[newPath] = child + getParentOutputVarMap(child, newPath, varMap) + }) +} + +export const getValidTreeNodes = (nodes: Node[], edges: Edge[], isCollectVar?: boolean) => { const startNode = nodes.find(node => node.data.type === BlockEnum.Start) if (!startNode) { @@ -109,6 +125,19 @@ export const getValidTreeNodes = (nodes: Node[], edges: Edge[]) => { outgoers.forEach((outgoer) => { list.push(outgoer) + if (isCollectVar) { + const nodeObj = formatItem(root, false, () => true) + const varMap = {} as Record + nodeObj.vars.forEach((item) => { + if (item.variable.startsWith('sys.')) + return + const newPath = `${nodeObj.nodeId}.${item.variable}` + varMap[newPath] = item + getParentOutputVarMap(item, newPath, varMap) + }) + outgoer._parentOutputVarMap = { ...(root._parentOutputVarMap ?? {}), ...varMap } + } + if (outgoer.data.type === BlockEnum.Iteration) list.push(...nodes.filter(node => node.parentId === outgoer.id)) if (outgoer.data.type === BlockEnum.Loop) @@ -327,3 +356,48 @@ export const getParallelInfo = (nodes: Node[], edges: Edge[], parentNodeId?: str export const hasErrorHandleNode = (nodeType?: BlockEnum) => { return nodeType === BlockEnum.LLM || nodeType === BlockEnum.Tool || nodeType === BlockEnum.HttpRequest || nodeType === BlockEnum.Code } + +export const transformStartNodeVariables = (chatVarList: ConversationVariable[], environmentVariables: EnvironmentVariable[]) => { + const variablesMap: Record = {} + chatVarList.forEach((variable) => { + variablesMap[`conversation.${variable.name}`] = variable + }) + environmentVariables.forEach((variable) => { + variablesMap[`env.${variable.name}`] = variable + }) + return variablesMap +} + +export const getNotExistVariablesByText = (text: string, varMap: Record) => { + const var_warnings: string[] = [] + text?.replace(VAR_REGEX_TEXT, (str, id_name) => { + if (id_name.startsWith('sys.')) + return str + if (varMap[id_name]) + return str + const arr = id_name.split('.') + arr.shift() + var_warnings.push(arr.join('.')) + return str + }) + return var_warnings +} + +export const getNotExistVariablesByArray = (array: string[][], varMap: Record) => { + if (!array.length) + return [] + const var_warnings: string[] = [] + array.forEach((item) => { + if (!item.length) + return + if (['sys'].includes(item[0])) + return + const var_warning = varMap[item.join('.')] + if (var_warning) + return + const arr = [...item] + arr.shift() + var_warnings.push(arr.join('.')) + }) + return var_warnings +} diff --git a/web/config/index.ts b/web/config/index.ts index 4d308807c5..4ddf30c2e4 100644 --- a/web/config/index.ts +++ b/web/config/index.ts @@ -282,6 +282,8 @@ Thought: {{agent_scratchpad}} export const VAR_REGEX = /\{\{(#[a-zA-Z0-9_-]{1,50}(\.[a-zA-Z_]\w{0,29}){1,10}#)\}\}/gi +export const VAR_REGEX_TEXT = /\{\{#([a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)*)#\}\}/gi + export const resetReg = () => VAR_REGEX.lastIndex = 0 export let textGenerationTimeoutMs = 60000 diff --git a/web/i18n/en-US/workflow.ts b/web/i18n/en-US/workflow.ts index f7121a7a8a..009cfd4326 100644 --- a/web/i18n/en-US/workflow.ts +++ b/web/i18n/en-US/workflow.ts @@ -113,6 +113,8 @@ const translation = { addFailureBranch: 'Add Fail Branch', loadMore: 'Load More', noHistory: 'No History', + referenceVar: 'Reference Variable', + noExist: 'No such variable', }, env: { envPanelTitle: 'Environment Variables', @@ -596,6 +598,7 @@ const translation = { selectVariable: 'Select variable...', addSubVariable: 'Sub Variable', select: 'Select', + condition: 'Condition', }, variableAssigner: { title: 'Assign variables', diff --git a/web/i18n/ja-JP/workflow.ts b/web/i18n/ja-JP/workflow.ts index 5fc9a81875..46a20efa26 100644 --- a/web/i18n/ja-JP/workflow.ts +++ b/web/i18n/ja-JP/workflow.ts @@ -113,6 +113,8 @@ const translation = { addFailureBranch: '失敗ブランチを追加', loadMore: 'さらに読み込む', noHistory: '履歴がありません', + referenceVar: '参照変数', + noExist: '存在しません', }, env: { envPanelTitle: '環境変数', @@ -596,6 +598,7 @@ const translation = { }, select: '選ぶ', addSubVariable: 'サブ変数', + condition: '条件', }, variableAssigner: { title: '変数を代入する', diff --git a/web/i18n/zh-Hans/workflow.ts b/web/i18n/zh-Hans/workflow.ts index ab77e0ef8d..74b948837e 100644 --- a/web/i18n/zh-Hans/workflow.ts +++ b/web/i18n/zh-Hans/workflow.ts @@ -113,6 +113,8 @@ const translation = { openInExplore: '在“探索”中打开', loadMore: '加载更多', noHistory: '没有历史版本', + referenceVar: '引用变量', + noExist: '不存在', }, env: { envPanelTitle: '环境变量', @@ -597,6 +599,7 @@ const translation = { selectVariable: '选择变量', addSubVariable: '添加子变量', select: '选择', + condition: '条件', }, variableAssigner: { title: '变量赋值', diff --git a/web/themes/manual-dark.css b/web/themes/manual-dark.css index ce9f7b8190..881f9d2c47 100644 --- a/web/themes/manual-dark.css +++ b/web/themes/manual-dark.css @@ -1,64 +1,65 @@ html[data-theme="dark"] { - --color-premium-yearly-tip-text-background: linear-gradient(91deg, #FDB022 2.18%, #F79009 108.79%); - --color-premium-badge-background: linear-gradient(95deg, rgba(103, 111, 131, 0.90) 0%, rgba(73, 84, 100, 0.90) 105.58%), var(--util-colors-gray-gray-200, #18222F); - --color-premium-text-background: linear-gradient(92deg, rgba(249, 250, 251, 0.95) 0%, rgba(233, 235, 240, 0.95) 97.78%); - --color-price-enterprise-background: linear-gradient(180deg, rgba(185, 211, 234, 0.00) 0%, rgba(180, 209, 234, 0.92) 100%); - --color-grid-mask-background: linear-gradient(0deg, rgba(0, 0, 0, 0.00) 0%, rgba(24, 24, 25, 0.1) 62.25%, rgba(24, 24, 25, 0.10) 100%); - --color-chatbot-bg: linear-gradient(180deg, - rgba(34, 34, 37, 0.9) 0%, - rgba(29, 29, 32, 0.9) 90.48%); - --color-chat-bubble-bg: linear-gradient(180deg, - rgba(200, 206, 218, 0.08) 0%, - rgba(200, 206, 218, 0.02) 100%); - --color-chat-input-mask: linear-gradient(180deg, - rgba(24, 24, 27, 0.04) 0%, - rgba(24, 24, 27, 0.60) 100%); - --color-workflow-process-bg: linear-gradient(90deg, - rgba(24, 24, 27, 0.25) 0%, - rgba(24, 24, 27, 0.04) 100%); - --color-workflow-run-failed-bg: linear-gradient(98deg, - rgba(240, 68, 56, 0.12) 0%, - rgba(0, 0, 0, 0) 26.01%); - --color-workflow-batch-failed-bg: linear-gradient(92deg, - rgba(240, 68, 56, 0.3) 0%, - rgba(0, 0, 0, 0) 100%); - --color-marketplace-divider-bg: linear-gradient(90deg, - rgba(200, 206, 218, 0.14) 0%, - rgba(0, 0, 0, 0) 100%); - --color-marketplace-plugin-empty: linear-gradient(180deg, - rgba(0, 0, 0, 0) 0%, - #222225 100%); - --color-toast-success-bg: linear-gradient(92deg, - rgba(23, 178, 106, 0.3) 0%, - rgba(0, 0, 0, 0) 100%); - --color-toast-warning-bg: linear-gradient(92deg, - rgba(247, 144, 9, 0.3) 0%, - rgba(0, 0, 0, 0) 100%); - --color-toast-error-bg: linear-gradient(92deg, - rgba(240, 68, 56, 0.3) 0%, - rgba(0, 0, 0, 0) 100%); - --color-toast-info-bg: linear-gradient(92deg, - rgba(11, 165, 236, 0.3) 0%); - --color-account-teams-bg: linear-gradient(271deg, - rgba(34, 34, 37, 0.9) -0.1%, - rgba(29, 29, 32, 0.9) 98.26%); - --color-app-detail-bg: linear-gradient(169deg, - #1D1D20 1.18%, - #222225 99.52%); - --color-app-detail-overlay-bg: linear-gradient(270deg, - rgba(0, 0, 0, 0.00) 0%, - rgba(24, 24, 27, 0.02) 8%, - rgba(24, 24, 27, 0.54) 100%); - --color-dataset-chunk-process-success-bg: linear-gradient(92deg, rgba(23, 178, 106, 0.30) 0%, rgba(0, 0, 0, 0.00) 100%); - --color-dataset-chunk-process-error-bg: linear-gradient(92deg, rgba(240, 68, 56, 0.30) 0%, rgba(0, 0, 0, 0.00) 100%); - --color-dataset-chunk-detail-card-hover-bg: linear-gradient(180deg, #1D1D20 0%, #222225 100%); - --color-dataset-child-chunk-expand-btn-bg: linear-gradient(90deg, rgba(24, 24, 27, 0.25) 0%, rgba(24, 24, 27, 0.04) 100%); - --color-dataset-option-card-blue-gradient: linear-gradient(90deg, #24252E 0%, #1E1E21 100%); - --color-dataset-option-card-purple-gradient: linear-gradient(90deg, #25242E 0%, #1E1E21 100%); - --color-dataset-option-card-orange-gradient: linear-gradient(90deg, #2B2322 0%, #1E1E21 100%); - --color-dataset-chunk-list-mask-bg: linear-gradient(180deg, rgba(34, 34, 37, 0.00) 0%, #222225 100%); - --mask-top2bottom-gray-50-to-transparent: linear-gradient(180deg, - rgba(24, 24, 27, 0.08) 0%, - rgba(0, 0, 0, 0) 100%); - --color-line-divider-bg: linear-gradient(90deg, rgba(200, 206, 218, 0.14) 0%, rgba(0, 0, 0, 0) 100%, ); + --color-premium-yearly-tip-text-background: linear-gradient(91deg, #FDB022 2.18%, #F79009 108.79%); + --color-premium-badge-background: linear-gradient(95deg, rgba(103, 111, 131, 0.90) 0%, rgba(73, 84, 100, 0.90) 105.58%), var(--util-colors-gray-gray-200, #18222F); + --color-premium-text-background: linear-gradient(92deg, rgba(249, 250, 251, 0.95) 0%, rgba(233, 235, 240, 0.95) 97.78%); + --color-premium-badge-border-highlight-color: #ffffff33; + --color-price-enterprise-background: linear-gradient(180deg, rgba(185, 211, 234, 0.00) 0%, rgba(180, 209, 234, 0.92) 100%); + --color-grid-mask-background: linear-gradient(0deg, rgba(0, 0, 0, 0.00) 0%, rgba(24, 24, 25, 0.1) 62.25%, rgba(24, 24, 25, 0.10) 100%); + --color-chatbot-bg: linear-gradient(180deg, + rgba(34, 34, 37, 0.9) 0%, + rgba(29, 29, 32, 0.9) 90.48%); + --color-chat-bubble-bg: linear-gradient(180deg, + rgba(200, 206, 218, 0.08) 0%, + rgba(200, 206, 218, 0.02) 100%); + --color-chat-input-mask: linear-gradient(180deg, + rgba(24, 24, 27, 0.04) 0%, + rgba(24, 24, 27, 0.60) 100%); + --color-workflow-process-bg: linear-gradient(90deg, + rgba(24, 24, 27, 0.25) 0%, + rgba(24, 24, 27, 0.04) 100%); + --color-workflow-run-failed-bg: linear-gradient(98deg, + rgba(240, 68, 56, 0.12) 0%, + rgba(0, 0, 0, 0) 26.01%); + --color-workflow-batch-failed-bg: linear-gradient(92deg, + rgba(240, 68, 56, 0.3) 0%, + rgba(0, 0, 0, 0) 100%); + --color-marketplace-divider-bg: linear-gradient(90deg, + rgba(200, 206, 218, 0.14) 0%, + rgba(0, 0, 0, 0) 100%); + --color-marketplace-plugin-empty: linear-gradient(180deg, + rgba(0, 0, 0, 0) 0%, + #222225 100%); + --color-toast-success-bg: linear-gradient(92deg, + rgba(23, 178, 106, 0.3) 0%, + rgba(0, 0, 0, 0) 100%); + --color-toast-warning-bg: linear-gradient(92deg, + rgba(247, 144, 9, 0.3) 0%, + rgba(0, 0, 0, 0) 100%); + --color-toast-error-bg: linear-gradient(92deg, + rgba(240, 68, 56, 0.3) 0%, + rgba(0, 0, 0, 0) 100%); + --color-toast-info-bg: linear-gradient(92deg, + rgba(11, 165, 236, 0.3) 0%); + --color-account-teams-bg: linear-gradient(271deg, + rgba(34, 34, 37, 0.9) -0.1%, + rgba(29, 29, 32, 0.9) 98.26%); + --color-app-detail-bg: linear-gradient(169deg, + #1D1D20 1.18%, + #222225 99.52%); + --color-app-detail-overlay-bg: linear-gradient(270deg, + rgba(0, 0, 0, 0.00) 0%, + rgba(24, 24, 27, 0.02) 8%, + rgba(24, 24, 27, 0.54) 100%); + --color-dataset-chunk-process-success-bg: linear-gradient(92deg, rgba(23, 178, 106, 0.30) 0%, rgba(0, 0, 0, 0.00) 100%); + --color-dataset-chunk-process-error-bg: linear-gradient(92deg, rgba(240, 68, 56, 0.30) 0%, rgba(0, 0, 0, 0.00) 100%); + --color-dataset-chunk-detail-card-hover-bg: linear-gradient(180deg, #1D1D20 0%, #222225 100%); + --color-dataset-child-chunk-expand-btn-bg: linear-gradient(90deg, rgba(24, 24, 27, 0.25) 0%, rgba(24, 24, 27, 0.04) 100%); + --color-dataset-option-card-blue-gradient: linear-gradient(90deg, #24252E 0%, #1E1E21 100%); + --color-dataset-option-card-purple-gradient: linear-gradient(90deg, #25242E 0%, #1E1E21 100%); + --color-dataset-option-card-orange-gradient: linear-gradient(90deg, #2B2322 0%, #1E1E21 100%); + --color-dataset-chunk-list-mask-bg: linear-gradient(180deg, rgba(34, 34, 37, 0.00) 0%, #222225 100%); + --mask-top2bottom-gray-50-to-transparent: linear-gradient(180deg, + rgba(24, 24, 27, 0.08) 0%, + rgba(0, 0, 0, 0) 100%); + --color-line-divider-bg: linear-gradient(90deg, rgba(200, 206, 218, 0.14) 0%, rgba(0, 0, 0, 0) 100%); } diff --git a/web/themes/manual-light.css b/web/themes/manual-light.css index 2f15578339..ab6f14423f 100644 --- a/web/themes/manual-light.css +++ b/web/themes/manual-light.css @@ -1,64 +1,65 @@ html[data-theme="light"] { - --color-premium-yearly-tip-text-background: linear-gradient(91deg, #F79009 2.18%, #DC6803 108.79%); - --color-premium-badge-background: linear-gradient(95deg, rgba(152, 162, 178, 0.90) 0%, rgba(103, 111, 131, 0.90) 105.58%); - --color-premium-text-background: linear-gradient(92deg, rgba(252, 252, 253, 0.95) 0%, rgba(242, 244, 247, 0.95) 97.78%); - --color-price-enterprise-background: linear-gradient(180deg, rgba(185, 211, 234, 0.00) 0%, rgba(180, 209, 234, 0.92) 100%); - --color-grid-mask-background: linear-gradient(0deg, #FFF 0%, rgba(217, 217, 217, 0.10) 62.25%, rgba(217, 217, 217, 0.10) 100%); - --color-chatbot-bg: linear-gradient(180deg, - rgba(249, 250, 251, 0.9) 0%, - rgba(242, 244, 247, 0.9) 90.48%); - --color-chat-bubble-bg: linear-gradient(180deg, - #fff 0%, - rgba(255, 255, 255, 0.6) 100%); - --color-chat-input-mask: linear-gradient(180deg, - rgba(255, 255, 255, 0.01) 0%, - #F2F4F7 100%); - --color-workflow-process-bg: linear-gradient(90deg, - rgba(200, 206, 218, 0.2) 0%, - rgba(200, 206, 218, 0.04) 100%); - --color-workflow-run-failed-bg: linear-gradient(98deg, - rgba(240, 68, 56, 0.10) 0%, - rgba(255, 255, 255, 0) 26.01%); - --color-workflow-batch-failed-bg: linear-gradient(92deg, - rgba(240, 68, 56, 0.25) 0%, - rgba(255, 255, 255, 0) 100%); - --color-marketplace-divider-bg: linear-gradient(90deg, - rgba(16, 24, 40, 0.08) 0%, - rgba(255, 255, 255, 0) 100%); - --color-marketplace-plugin-empty: linear-gradient(180deg, - rgba(255, 255, 255, 0) 0%, - #fcfcfd 100%); - --color-toast-success-bg: linear-gradient(92deg, - rgba(23, 178, 106, 0.25) 0%, - rgba(255, 255, 255, 0) 100%); - --color-toast-warning-bg: linear-gradient(92deg, - rgba(247, 144, 9, 0.25) 0%, - rgba(255, 255, 255, 0) 100%); - --color-toast-error-bg: linear-gradient(92deg, - rgba(240, 68, 56, 0.25) 0%, - rgba(255, 255, 255, 0) 100%); - --color-toast-info-bg: linear-gradient(92deg, - rgba(11, 165, 236, 0.25) 0%); - --color-account-teams-bg: linear-gradient(271deg, - rgba(249, 250, 251, 0.9) -0.1%, - rgba(242, 244, 247, 0.9) 98.26%); - --color-app-detail-bg: linear-gradient(169deg, - #F2F4F7 1.18%, - #F9FAFB 99.52%); - --color-app-detail-overlay-bg: linear-gradient(270deg, - rgba(0, 0, 0, 0.00) 0%, - rgba(16, 24, 40, 0.01) 8%, - rgba(16, 24, 40, 0.18) 100%); - --color-dataset-chunk-process-success-bg: linear-gradient(92deg, rgba(23, 178, 106, 0.25) 0%, rgba(255, 255, 255, 0.00) 100%); - --color-dataset-chunk-process-error-bg: linear-gradient(92deg, rgba(240, 68, 56, 0.25) 0%, rgba(255, 255, 255, 0.00) 100%); - --color-dataset-chunk-detail-card-hover-bg: linear-gradient(180deg, #F2F4F7 0%, #F9FAFB 100%); - --color-dataset-child-chunk-expand-btn-bg: linear-gradient(90deg, rgba(200, 206, 218, 0.20) 0%, rgba(200, 206, 218, 0.04) 100%); - --color-dataset-option-card-blue-gradient: linear-gradient(90deg, #F2F4F7 0%, #F9FAFB 100%); - --color-dataset-option-card-purple-gradient: linear-gradient(90deg, #F0EEFA 0%, #F9FAFB 100%); - --color-dataset-option-card-orange-gradient: linear-gradient(90deg, #F8F2EE 0%, #F9FAFB 100%); - --color-dataset-chunk-list-mask-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.00) 0%, #FCFCFD 100%); - --mask-top2bottom-gray-50-to-transparent: linear-gradient(180deg, - rgba(200, 206, 218, 0.2) 0%, - rgba(255, 255, 255, 0) 100%); - --color-line-divider-bg: linear-gradient(90deg, rgba(16, 24, 40, 0.08) 0%, rgba(255, 255, 255, 0) 100%); + --color-premium-yearly-tip-text-background: linear-gradient(91deg, #F79009 2.18%, #DC6803 108.79%); + --color-premium-badge-background: linear-gradient(95deg, rgba(152, 162, 178, 0.90) 0%, rgba(103, 111, 131, 0.90) 105.58%); + --color-premium-text-background: linear-gradient(92deg, rgba(252, 252, 253, 0.95) 0%, rgba(242, 244, 247, 0.95) 97.78%); + --color-premium-badge-border-highlight-color: #fffffff2; + --color-price-enterprise-background: linear-gradient(180deg, rgba(185, 211, 234, 0.00) 0%, rgba(180, 209, 234, 0.92) 100%); + --color-grid-mask-background: linear-gradient(0deg, #FFF 0%, rgba(217, 217, 217, 0.10) 62.25%, rgba(217, 217, 217, 0.10) 100%); + --color-chatbot-bg: linear-gradient(180deg, + rgba(249, 250, 251, 0.9) 0%, + rgba(242, 244, 247, 0.9) 90.48%); + --color-chat-bubble-bg: linear-gradient(180deg, + #fff 0%, + rgba(255, 255, 255, 0.6) 100%); + --color-chat-input-mask: linear-gradient(180deg, + rgba(255, 255, 255, 0.01) 0%, + #F2F4F7 100%); + --color-workflow-process-bg: linear-gradient(90deg, + rgba(200, 206, 218, 0.2) 0%, + rgba(200, 206, 218, 0.04) 100%); + --color-workflow-run-failed-bg: linear-gradient(98deg, + rgba(240, 68, 56, 0.10) 0%, + rgba(255, 255, 255, 0) 26.01%); + --color-workflow-batch-failed-bg: linear-gradient(92deg, + rgba(240, 68, 56, 0.25) 0%, + rgba(255, 255, 255, 0) 100%); + --color-marketplace-divider-bg: linear-gradient(90deg, + rgba(16, 24, 40, 0.08) 0%, + rgba(255, 255, 255, 0) 100%); + --color-marketplace-plugin-empty: linear-gradient(180deg, + rgba(255, 255, 255, 0) 0%, + #fcfcfd 100%); + --color-toast-success-bg: linear-gradient(92deg, + rgba(23, 178, 106, 0.25) 0%, + rgba(255, 255, 255, 0) 100%); + --color-toast-warning-bg: linear-gradient(92deg, + rgba(247, 144, 9, 0.25) 0%, + rgba(255, 255, 255, 0) 100%); + --color-toast-error-bg: linear-gradient(92deg, + rgba(240, 68, 56, 0.25) 0%, + rgba(255, 255, 255, 0) 100%); + --color-toast-info-bg: linear-gradient(92deg, + rgba(11, 165, 236, 0.25) 0%); + --color-account-teams-bg: linear-gradient(271deg, + rgba(249, 250, 251, 0.9) -0.1%, + rgba(242, 244, 247, 0.9) 98.26%); + --color-app-detail-bg: linear-gradient(169deg, + #F2F4F7 1.18%, + #F9FAFB 99.52%); + --color-app-detail-overlay-bg: linear-gradient(270deg, + rgba(0, 0, 0, 0.00) 0%, + rgba(16, 24, 40, 0.01) 8%, + rgba(16, 24, 40, 0.18) 100%); + --color-dataset-chunk-process-success-bg: linear-gradient(92deg, rgba(23, 178, 106, 0.25) 0%, rgba(255, 255, 255, 0.00) 100%); + --color-dataset-chunk-process-error-bg: linear-gradient(92deg, rgba(240, 68, 56, 0.25) 0%, rgba(255, 255, 255, 0.00) 100%); + --color-dataset-chunk-detail-card-hover-bg: linear-gradient(180deg, #F2F4F7 0%, #F9FAFB 100%); + --color-dataset-child-chunk-expand-btn-bg: linear-gradient(90deg, rgba(200, 206, 218, 0.20) 0%, rgba(200, 206, 218, 0.04) 100%); + --color-dataset-option-card-blue-gradient: linear-gradient(90deg, #F2F4F7 0%, #F9FAFB 100%); + --color-dataset-option-card-purple-gradient: linear-gradient(90deg, #F0EEFA 0%, #F9FAFB 100%); + --color-dataset-option-card-orange-gradient: linear-gradient(90deg, #F8F2EE 0%, #F9FAFB 100%); + --color-dataset-chunk-list-mask-bg: linear-gradient(180deg, rgba(255, 255, 255, 0.00) 0%, #FCFCFD 100%); + --mask-top2bottom-gray-50-to-transparent: linear-gradient(180deg, + rgba(200, 206, 218, 0.2) 0%, + rgba(255, 255, 255, 0) 100%); + --color-line-divider-bg: linear-gradient(90deg, rgba(16, 24, 40, 0.08) 0%, rgba(255, 255, 255, 0) 100%); }