diff --git a/README.md b/README.md index efb37d6083..ef654ced1e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![cover-v5-optimized](https://github.com/langgenius/dify/assets/13230914/f9e19af5-61ba-4119-b926-d10c4c06ebab) +![cover-v5-optimized](./images/GitHub_README_if.png)

📌 Introducing Dify Workflow File Upload: Recreate Google NotebookLM Podcast @@ -87,8 +87,6 @@ Please refer to our [FAQ](https://docs.dify.ai/getting-started/install-self-host **1. Workflow**: Build and test powerful AI workflows on a visual canvas, leveraging all the following features and beyond. -https://github.com/langgenius/dify/assets/13230914/356df23e-1604-483d-80a6-9517ece318aa - **2. Comprehensive model support**: Seamless integration with hundreds of proprietary / open-source LLMs from dozens of inference providers and self-hosted solutions, covering GPT, Mistral, Llama3, and any OpenAI API-compatible models. A full list of supported model providers can be found [here](https://docs.dify.ai/getting-started/readme/model-providers). diff --git a/README_AR.md b/README_AR.md index 4f93802fda..1310a9d802 100644 --- a/README_AR.md +++ b/README_AR.md @@ -1,4 +1,4 @@ -![cover-v5-optimized](https://github.com/langgenius/dify/assets/13230914/f9e19af5-61ba-4119-b926-d10c4c06ebab) +![cover-v5-optimized](./images/GitHub_README_if.png)

Dify Cloud · @@ -54,8 +54,6 @@ **1. سير العمل**: قم ببناء واختبار سير عمل الذكاء الاصطناعي القوي على قماش بصري، مستفيدًا من جميع الميزات التالية وأكثر. - - **2. الدعم الشامل للنماذج**: تكامل سلس مع مئات من LLMs الخاصة / مفتوحة المصدر من عشرات من موفري التحليل والحلول المستضافة ذاتيًا، مما يغطي GPT و Mistral و Llama3 وأي نماذج متوافقة مع واجهة OpenAI API. يمكن العثور على قائمة كاملة بمزودي النموذج المدعومين [هنا](https://docs.dify.ai/getting-started/readme/model-providers). ![providers-v5](https://github.com/langgenius/dify/assets/13230914/5a17bdbe-097a-4100-8363-40255b70f6e3) diff --git a/README_BN.md b/README_BN.md index 7599fae9ff..be1f8cc72e 100644 --- a/README_BN.md +++ b/README_BN.md @@ -1,4 +1,4 @@ -![cover-v5-optimized](https://github.com/langgenius/dify/assets/13230914/f9e19af5-61ba-4119-b926-d10c4c06ebab) +![cover-v5-optimized](./images/GitHub_README_if.png)

📌 ডিফাই ওয়ার্কফ্লো ফাইল আপলোড পরিচিতি: গুগল নোটবুক-এলএম পডকাস্ট পুনর্নির্মাণ @@ -84,8 +84,6 @@ docker compose up -d **১. ওয়ার্কফ্লো**: ভিজ্যুয়াল ক্যানভাসে AI ওয়ার্কফ্লো তৈরি এবং পরীক্ষা করুন, নিম্নলিখিত সব ফিচার এবং তার বাইরেও আরও অনেক কিছু ব্যবহার করে। - - **২. মডেল সাপোর্ট**: GPT, Mistral, Llama3, এবং যেকোনো OpenAI API-সামঞ্জস্যপূর্ণ মডেলসহ, কয়েক ডজন ইনফারেন্স প্রদানকারী এবং সেল্ফ-হোস্টেড সমাধান থেকে শুরু করে প্রোপ্রাইটরি/ওপেন-সোর্স LLM-এর সাথে সহজে ইন্টিগ্রেশন। সমর্থিত মডেল প্রদানকারীদের একটি সম্পূর্ণ তালিকা পাওয়া যাবে [এখানে](https://docs.dify.ai/getting-started/readme/model-providers)। diff --git a/README_CN.md b/README_CN.md index 973629f459..1d4d51e856 100644 --- a/README_CN.md +++ b/README_CN.md @@ -1,4 +1,4 @@ -![cover-v5-optimized](https://github.com/langgenius/dify/assets/13230914/f9e19af5-61ba-4119-b926-d10c4c06ebab) +![cover-v5-optimized](./images/GitHub_README_if.png)

Dify 云服务 · @@ -61,11 +61,6 @@ Dify 是一个开源的 LLM 应用开发平台。其直观的界面结合了 AI **1. 工作流**: 在画布上构建和测试功能强大的 AI 工作流程,利用以下所有功能以及更多功能。 - - https://github.com/langgenius/dify/assets/13230914/356df23e-1604-483d-80a6-9517ece318aa - - - **2. 全面的模型支持**: 与数百种专有/开源 LLMs 以及数十种推理提供商和自托管解决方案无缝集成,涵盖 GPT、Mistral、Llama3 以及任何与 OpenAI API 兼容的模型。完整的支持模型提供商列表可在[此处](https://docs.dify.ai/getting-started/readme/model-providers)找到。 diff --git a/README_DE.md b/README_DE.md index 738c0e3b67..7cc2710fde 100644 --- a/README_DE.md +++ b/README_DE.md @@ -1,4 +1,4 @@ -![cover-v5-optimized](https://github.com/langgenius/dify/assets/13230914/f9e19af5-61ba-4119-b926-d10c4c06ebab) +![cover-v5-optimized](./images/GitHub_README_if.png)

📌 Einführung in Dify Workflow File Upload: Google NotebookLM Podcast nachbilden @@ -83,11 +83,6 @@ Bitte beachten Sie unsere [FAQ](https://docs.dify.ai/getting-started/install-sel **1. Workflow**: Erstellen und testen Sie leistungsstarke KI-Workflows auf einer visuellen Oberfläche, wobei Sie alle der folgenden Funktionen und darüber hinaus nutzen können. - - https://github.com/langgenius/dify/assets/13230914/356df23e-1604-483d-80a6-9517ece318aa - - - **2. Umfassende Modellunterstützung**: Nahtlose Integration mit Hunderten von proprietären und Open-Source-LLMs von Dutzenden Inferenzanbietern und selbstgehosteten Lösungen, die GPT, Mistral, Llama3 und alle mit der OpenAI API kompatiblen Modelle abdecken. Eine vollständige Liste der unterstützten Modellanbieter finden Sie [hier](https://docs.dify.ai/getting-started/readme/model-providers). diff --git a/README_ES.md b/README_ES.md index 212268b73d..12f2ce8c11 100644 --- a/README_ES.md +++ b/README_ES.md @@ -1,4 +1,4 @@ -![cover-v5-optimized](https://github.com/langgenius/dify/assets/13230914/f9e19af5-61ba-4119-b926-d10c4c06ebab) +![cover-v5-optimized](./images/GitHub_README_if.png)

Dify Cloud · @@ -59,11 +59,6 @@ Dify es una plataforma de desarrollo de aplicaciones de LLM de código abierto. **1. Flujo de trabajo**: Construye y prueba potentes flujos de trabajo de IA en un lienzo visual, aprovechando todas las siguientes características y más. - - https://github.com/langgenius/dify/assets/13230914/356df23e-1604-483d-80a6-9517ece318aa - - - **2. Soporte de modelos completo**: Integración perfecta con cientos de LLMs propietarios / de código abierto de docenas de proveedores de inferencia y soluciones auto-alojadas, que cubren GPT, Mistral, Llama3 y cualquier modelo compatible con la API de OpenAI. Se puede encontrar una lista completa de proveedores de modelos admitidos [aquí](https://docs.dify.ai/getting-started/readme/model-providers). diff --git a/README_FR.md b/README_FR.md index 89eea7d058..b106615b31 100644 --- a/README_FR.md +++ b/README_FR.md @@ -1,4 +1,4 @@ -![cover-v5-optimized](https://github.com/langgenius/dify/assets/13230914/f9e19af5-61ba-4119-b926-d10c4c06ebab) +![cover-v5-optimized](./images/GitHub_README_if.png)

Dify Cloud · @@ -59,11 +59,6 @@ Dify est une plateforme de développement d'applications LLM open source. Son in **1. Flux de travail** : Construisez et testez des flux de travail d'IA puissants sur un canevas visuel, en utilisant toutes les fonctionnalités suivantes et plus encore. - - https://github.com/langgenius/dify/assets/13230914/356df23e-1604-483d-80a6-9517ece318aa - - - **2. Prise en charge complète des modèles** : Intégration transparente avec des centaines de LLM propriétaires / open source provenant de dizaines de fournisseurs d'inférence et de solutions auto-hébergées, couvrant GPT, Mistral, Llama3, et tous les modèles compatibles avec l'API OpenAI. Une liste complète des fournisseurs de modèles pris en charge se trouve [ici](https://docs.dify.ai/getting-started/readme/model-providers). diff --git a/README_JA.md b/README_JA.md index adca219753..be5d8644e0 100644 --- a/README_JA.md +++ b/README_JA.md @@ -1,4 +1,4 @@ -![cover-v5-optimized](https://github.com/langgenius/dify/assets/13230914/f9e19af5-61ba-4119-b926-d10c4c06ebab) +![cover-v5-optimized](./images/GitHub_README_if.png)

Dify Cloud · @@ -60,11 +60,6 @@ DifyはオープンソースのLLMアプリケーション開発プラットフ **1. ワークフロー**: 強力なAIワークフローをビジュアルキャンバス上で構築し、テストできます。すべての機能、および以下の機能を使用できます。 - - https://github.com/langgenius/dify/assets/13230914/356df23e-1604-483d-80a6-9517ece318aa - - - **2. 総合的なモデルサポート**: 数百ものプロプライエタリ/オープンソースのLLMと、数十もの推論プロバイダーおよびセルフホスティングソリューションとのシームレスな統合を提供します。GPT、Mistral、Llama3、OpenAI APIと互換性のあるすべてのモデルを統合されています。サポートされているモデルプロバイダーの完全なリストは[こちら](https://docs.dify.ai/getting-started/readme/model-providers)をご覧ください。 diff --git a/README_KL.md b/README_KL.md index 17e6c9d509..3ebd756929 100644 --- a/README_KL.md +++ b/README_KL.md @@ -1,4 +1,4 @@ -![cover-v5-optimized](https://github.com/langgenius/dify/assets/13230914/f9e19af5-61ba-4119-b926-d10c4c06ebab) +![cover-v5-optimized](./images/GitHub_README_if.png)

Dify Cloud · @@ -59,11 +59,6 @@ Dify is an open-source LLM app development platform. Its intuitive interface com **1. Workflow**: Build and test powerful AI workflows on a visual canvas, leveraging all the following features and beyond. - - https://github.com/langgenius/dify/assets/13230914/356df23e-1604-483d-80a6-9517ece318aa - - - **2. Comprehensive model support**: Seamless integration with hundreds of proprietary / open-source LLMs from dozens of inference providers and self-hosted solutions, covering GPT, Mistral, Llama3, and any OpenAI API-compatible models. A full list of supported model providers can be found [here](https://docs.dify.ai/getting-started/readme/model-providers). diff --git a/README_KR.md b/README_KR.md index d44723f9b6..ecbe2f6b74 100644 --- a/README_KR.md +++ b/README_KR.md @@ -1,4 +1,4 @@ -![cover-v5-optimized](https://github.com/langgenius/dify/assets/13230914/f9e19af5-61ba-4119-b926-d10c4c06ebab) +![cover-v5-optimized](./images/GitHub_README_if.png)

Dify 클라우드 · @@ -54,11 +54,6 @@ **1. 워크플로우**: 다음 기능들을 비롯한 다양한 기능을 활용하여 시각적 캔버스에서 강력한 AI 워크플로우를 구축하고 테스트하세요. - - https://github.com/langgenius/dify/assets/13230914/356df23e-1604-483d-80a6-9517ece318aa - - - **2. 포괄적인 모델 지원:**: 수십 개의 추론 제공업체와 자체 호스팅 솔루션에서 제공하는 수백 개의 독점 및 오픈 소스 LLM과 원활하게 통합되며, GPT, Mistral, Llama3 및 모든 OpenAI API 호환 모델을 포함합니다. 지원되는 모델 제공업체의 전체 목록은 [여기](https://docs.dify.ai/getting-started/readme/model-providers)에서 확인할 수 있습니다. diff --git a/README_PT.md b/README_PT.md index 9dc2207279..157772d528 100644 --- a/README_PT.md +++ b/README_PT.md @@ -1,5 +1,4 @@ -![cover-v5-optimized](https://github.com/langgenius/dify/assets/13230914/f9e19af5-61ba-4119-b926-d10c4c06ebab) - +![cover-v5-optimized](./images/GitHub_README_if.png)

📌 Introduzindo o Dify Workflow com Upload de Arquivo: Recrie o Podcast Google NotebookLM

@@ -59,11 +58,6 @@ Dify é uma plataforma de desenvolvimento de aplicativos LLM de código aberto. **1. Workflow**: Construa e teste workflows poderosos de IA em uma interface visual, aproveitando todos os recursos a seguir e muito mais. - - https://github.com/langgenius/dify/assets/13230914/356df23e-1604-483d-80a6-9517ece318aa - - - **2. Suporte abrangente a modelos**: Integração perfeita com centenas de LLMs proprietários e de código aberto de diversas provedoras e soluções auto-hospedadas, abrangendo GPT, Mistral, Llama3 e qualquer modelo compatível com a API da OpenAI. A lista completa de provedores suportados pode ser encontrada [aqui](https://docs.dify.ai/getting-started/readme/model-providers). diff --git a/README_SI.md b/README_SI.md index 9a38b558b4..45aec75dcd 100644 --- a/README_SI.md +++ b/README_SI.md @@ -1,4 +1,4 @@ -![cover-v5-optimized](https://github.com/langgenius/dify/assets/13230914/f9e19af5-61ba-4119-b926-d10c4c06ebab) +![cover-v5-optimized](./images/GitHub_README_if.png)

📌 Predstavljamo nalaganje datotek Dify Workflow: znova ustvarite Google NotebookLM Podcast @@ -81,11 +81,6 @@ Prosimo, glejte naša pogosta vprašanja [FAQ](https://docs.dify.ai/getting-star **1. Potek dela**: Zgradite in preizkusite zmogljive poteke dela AI na vizualnem platnu, pri čemer izkoristite vse naslednje funkcije in več. - - https://github.com/langgenius/dify/assets/13230914/356df23e-1604-483d-80a6-9517ece318aa - - - **2. Celovita podpora za modele**: Brezhibna integracija s stotinami lastniških/odprtokodnih LLM-jev ducatov ponudnikov sklepanja in samostojnih rešitev, ki pokrivajo GPT, Mistral, Llama3 in vse modele, združljive z API-jem OpenAI. Celoten seznam podprtih ponudnikov modelov najdete [tukaj](https://docs.dify.ai/getting-started/readme/model-providers). diff --git a/README_TR.md b/README_TR.md index ab2853a019..94ab6ee338 100644 --- a/README_TR.md +++ b/README_TR.md @@ -1,4 +1,4 @@ -![cover-v5-optimized](https://github.com/langgenius/dify/assets/13230914/f9e19af5-61ba-4119-b926-d10c4c06ebab) +![cover-v5-optimized](./images/GitHub_README_if.png)

Dify Bulut · @@ -55,11 +55,6 @@ Dify, açık kaynaklı bir LLM uygulama geliştirme platformudur. Sezgisel aray **1. Workflow**: Görsel bir arayüz üzerinde güçlü AI iş akışları oluşturun ve test edin, aşağıdaki tüm özellikleri ve daha fazlasını kullanarak. - - https://github.com/langgenius/dify/assets/13230914/356df23e-1604-483d-80a6-9517ece318aa - - - **2. Kapsamlı model desteği**: Çok sayıda çıkarım sağlayıcısı ve kendi kendine barındırılan çözümlerden yüzlerce özel / açık kaynaklı LLM ile sorunsuz entegrasyon sağlar. GPT, Mistral, Llama3 ve OpenAI API uyumlu tüm modelleri kapsar. Desteklenen model sağlayıcılarının tam listesine [buradan](https://docs.dify.ai/getting-started/readme/model-providers) ulaşabilirsiniz. diff --git a/README_TW.md b/README_TW.md index 8263a22b64..c252292e44 100644 --- a/README_TW.md +++ b/README_TW.md @@ -1,4 +1,4 @@ -![cover-v5-optimized](https://github.com/langgenius/dify/assets/13230914/f9e19af5-61ba-4119-b926-d10c4c06ebab) +![cover-v5-optimized](./images/GitHub_README_if.png)

📌 介紹 Dify 工作流程檔案上傳功能:重現 Google NotebookLM Podcast @@ -86,8 +86,6 @@ docker compose up -d **1. 工作流程**: 在視覺化畫布上建立和測試強大的 AI 工作流程,利用以下所有功能及更多。 -https://github.com/langgenius/dify/assets/13230914/356df23e-1604-483d-80a6-9517ece318aa - **2. 全面的模型支援**: 無縫整合來自數十個推理提供商和自託管解決方案的數百個專有/開源 LLM,涵蓋 GPT、Mistral、Llama3 和任何與 OpenAI API 兼容的模型。您可以在[此處](https://docs.dify.ai/getting-started/readme/model-providers)找到支援的模型提供商完整列表。 diff --git a/README_VI.md b/README_VI.md index 852ed7aaa0..4e1e05cbf3 100644 --- a/README_VI.md +++ b/README_VI.md @@ -1,4 +1,4 @@ -![cover-v5-optimized](https://github.com/langgenius/dify/assets/13230914/f9e19af5-61ba-4119-b926-d10c4c06ebab) +![cover-v5-optimized](./images/GitHub_README_if.png)

Dify Cloud · @@ -55,11 +55,6 @@ Dify là một nền tảng phát triển ứng dụng LLM mã nguồn mở. Gia **1. Quy trình làm việc**: Xây dựng và kiểm tra các quy trình làm việc AI mạnh mẽ trên một canvas trực quan, tận dụng tất cả các tính năng sau đây và hơn thế nữa. - - https://github.com/langgenius/dify/assets/13230914/356df23e-1604-483d-80a6-9517ece318aa - - - **2. Hỗ trợ mô hình toàn diện**: Tích hợp liền mạch với hàng trăm mô hình LLM độc quyền / mã nguồn mở từ hàng chục nhà cung cấp suy luận và giải pháp tự lưu trữ, bao gồm GPT, Mistral, Llama3, và bất kỳ mô hình tương thích API OpenAI nào. Danh sách đầy đủ các nhà cung cấp mô hình được hỗ trợ có thể được tìm thấy [tại đây](https://docs.dify.ai/getting-started/readme/model-providers). diff --git a/api/configs/packaging/__init__.py b/api/configs/packaging/__init__.py index c7960e1356..de13018f37 100644 --- a/api/configs/packaging/__init__.py +++ b/api/configs/packaging/__init__.py @@ -9,7 +9,7 @@ class PackagingInfo(BaseSettings): CURRENT_VERSION: str = Field( description="Dify version", - default="1.3.1", + default="1.4.0", ) COMMIT_SHA: str = Field( diff --git a/api/services/app_dsl_service.py b/api/services/app_dsl_service.py index a2775fe6ad..d2875180d8 100644 --- a/api/services/app_dsl_service.py +++ b/api/services/app_dsl_service.py @@ -40,7 +40,7 @@ IMPORT_INFO_REDIS_KEY_PREFIX = "app_import_info:" CHECK_DEPENDENCIES_REDIS_KEY_PREFIX = "app_check_dependencies:" IMPORT_INFO_REDIS_EXPIRY = 10 * 60 # 10 minutes DSL_MAX_SIZE = 10 * 1024 * 1024 # 10MB -CURRENT_DSL_VERSION = "0.2.0" +CURRENT_DSL_VERSION = "0.3.0" class ImportMode(StrEnum): diff --git a/api/templates/clean_document_job_mail_template-US.html b/api/templates/clean_document_job_mail_template-US.html index 0f7ddc62a9..2d8f78b46a 100644 --- a/api/templates/clean_document_job_mail_template-US.html +++ b/api/templates/clean_document_job_mail_template-US.html @@ -69,7 +69,7 @@

- Dify Logo + Dify Logo
diff --git a/api/templates/delete_account_code_email_template_en-US.html b/api/templates/delete_account_code_email_template_en-US.html index eca3dedf72..f7f720513c 100644 --- a/api/templates/delete_account_code_email_template_en-US.html +++ b/api/templates/delete_account_code_email_template_en-US.html @@ -99,7 +99,7 @@
- Dify Logo + Dify Logo

Dify.AI Account Deletion and Verification

We received a request to delete your Dify account. To ensure the security of your account and diff --git a/api/templates/delete_account_success_template_en-US.html b/api/templates/delete_account_success_template_en-US.html index b96eee1172..5e149c3b8a 100644 --- a/api/templates/delete_account_success_template_en-US.html +++ b/api/templates/delete_account_success_template_en-US.html @@ -88,7 +88,7 @@

- Dify Logo + Dify Logo

Your Dify.AI Account Has Been Successfully Deleted

We're writing to confirm that your Dify.AI account has been successfully deleted as per your request. Your diff --git a/api/templates/email_code_login_mail_template_en-US.html b/api/templates/email_code_login_mail_template_en-US.html index 066818d10c..72d679dbf1 100644 --- a/api/templates/email_code_login_mail_template_en-US.html +++ b/api/templates/email_code_login_mail_template_en-US.html @@ -61,7 +61,7 @@

- Dify Logo + Dify Logo

Your login code for Dify

Copy and paste this code, this code will only be valid for the next 5 minutes.

diff --git a/api/templates/email_code_login_mail_template_zh-CN.html b/api/templates/email_code_login_mail_template_zh-CN.html index 0c2b63a1f1..69c2d38eb6 100644 --- a/api/templates/email_code_login_mail_template_zh-CN.html +++ b/api/templates/email_code_login_mail_template_zh-CN.html @@ -61,7 +61,7 @@
- Dify Logo + Dify Logo

Dify 的登录验证码

复制并粘贴此验证码,注意验证码仅在接下来的 5 分钟内有效。

diff --git a/api/templates/invite_member_mail_template_en-US.html b/api/templates/invite_member_mail_template_en-US.html index e8bf7f5a52..fb5167f17e 100644 --- a/api/templates/invite_member_mail_template_en-US.html +++ b/api/templates/invite_member_mail_template_en-US.html @@ -54,7 +54,7 @@
- Dify Logo + Dify Logo

Dear {{ to }},

diff --git a/api/templates/invite_member_mail_template_zh-CN.html b/api/templates/invite_member_mail_template_zh-CN.html index ccd9cdbaad..b9d6619fa4 100644 --- a/api/templates/invite_member_mail_template_zh-CN.html +++ b/api/templates/invite_member_mail_template_zh-CN.html @@ -54,7 +54,7 @@
- Dify Logo + Dify Logo

尊敬的 {{ to }},

diff --git a/api/templates/reset_password_mail_template_en-US.html b/api/templates/reset_password_mail_template_en-US.html index d598fd191c..9372bb0c41 100644 --- a/api/templates/reset_password_mail_template_en-US.html +++ b/api/templates/reset_password_mail_template_en-US.html @@ -61,7 +61,7 @@
- Dify Logo + Dify Logo

Set your Dify password

Copy and paste this code, this code will only be valid for the next 5 minutes.

diff --git a/api/templates/reset_password_mail_template_zh-CN.html b/api/templates/reset_password_mail_template_zh-CN.html index 342c9057a7..c08de6cc5d 100644 --- a/api/templates/reset_password_mail_template_zh-CN.html +++ b/api/templates/reset_password_mail_template_zh-CN.html @@ -61,7 +61,7 @@
- Dify Logo + Dify Logo

设置您的 Dify 账户密码

复制并粘贴此验证码,注意验证码仅在接下来的 5 分钟内有效。

diff --git a/docker/.env.example b/docker/.env.example index 37738a5065..f461be5a4a 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -478,7 +478,7 @@ ANALYTICDB_PORT=5432 ANALYTICDB_MIN_CONNECTION=1 ANALYTICDB_MAX_CONNECTION=5 -# TiDB vector configurations, only available when VECTOR_STORE is `tidb` +# TiDB vector configurations, only available when VECTOR_STORE is `tidb_vector` TIDB_VECTOR_HOST=tidb TIDB_VECTOR_PORT=4000 TIDB_VECTOR_USER= diff --git a/docker/docker-compose-template.yaml b/docker/docker-compose-template.yaml index 487d358b24..65fbd007e2 100644 --- a/docker/docker-compose-template.yaml +++ b/docker/docker-compose-template.yaml @@ -2,7 +2,7 @@ x-shared-env: &shared-api-worker-env services: # API service api: - image: langgenius/dify-api:1.3.1 + image: langgenius/dify-api:1.4.0 restart: always environment: # Use the shared environment variables. @@ -31,7 +31,7 @@ services: # worker service # The Celery worker for processing the queue. worker: - image: langgenius/dify-api:1.3.1 + image: langgenius/dify-api:1.4.0 restart: always environment: # Use the shared environment variables. @@ -57,7 +57,7 @@ services: # Frontend web application. web: - image: langgenius/dify-web:1.3.1 + image: langgenius/dify-web:1.4.0 restart: always environment: CONSOLE_API_URL: ${CONSOLE_API_URL:-} @@ -118,7 +118,7 @@ services: # The DifySandbox sandbox: - image: langgenius/dify-sandbox:0.2.11 + image: langgenius/dify-sandbox:0.2.12 restart: always environment: # The DifySandbox configurations @@ -142,7 +142,7 @@ services: # plugin daemon plugin_daemon: - image: langgenius/dify-plugin-daemon:0.0.9-local + image: langgenius/dify-plugin-daemon:0.0.10-local restart: always environment: # Use the shared environment variables. diff --git a/docker/docker-compose.middleware.yaml b/docker/docker-compose.middleware.yaml index 498390b708..4f39e801f5 100644 --- a/docker/docker-compose.middleware.yaml +++ b/docker/docker-compose.middleware.yaml @@ -45,7 +45,7 @@ services: # The DifySandbox sandbox: - image: langgenius/dify-sandbox:0.2.11 + image: langgenius/dify-sandbox:0.2.12 restart: always env_file: - ./middleware.env @@ -71,7 +71,7 @@ services: # plugin daemon plugin_daemon: - image: langgenius/dify-plugin-daemon:0.0.9-local + image: langgenius/dify-plugin-daemon:0.0.10-local restart: always env_file: - ./middleware.env diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index 1b9ae75c51..bfdfa701e3 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -492,7 +492,7 @@ x-shared-env: &shared-api-worker-env services: # API service api: - image: langgenius/dify-api:1.3.1 + image: langgenius/dify-api:1.4.0 restart: always environment: # Use the shared environment variables. @@ -521,7 +521,7 @@ services: # worker service # The Celery worker for processing the queue. worker: - image: langgenius/dify-api:1.3.1 + image: langgenius/dify-api:1.4.0 restart: always environment: # Use the shared environment variables. @@ -547,7 +547,7 @@ services: # Frontend web application. web: - image: langgenius/dify-web:1.3.1 + image: langgenius/dify-web:1.4.0 restart: always environment: CONSOLE_API_URL: ${CONSOLE_API_URL:-} @@ -608,7 +608,7 @@ services: # The DifySandbox sandbox: - image: langgenius/dify-sandbox:0.2.11 + image: langgenius/dify-sandbox:0.2.12 restart: always environment: # The DifySandbox configurations @@ -632,7 +632,7 @@ services: # plugin daemon plugin_daemon: - image: langgenius/dify-plugin-daemon:0.0.9-local + image: langgenius/dify-plugin-daemon:0.0.10-local restart: always environment: # Use the shared environment variables. diff --git a/images/GitHub_README_cover.png b/images/GitHub_README_cover.png deleted file mode 100644 index 0e21be2177..0000000000 Binary files a/images/GitHub_README_cover.png and /dev/null differ diff --git a/images/GitHub_README_if.png b/images/GitHub_README_if.png new file mode 100644 index 0000000000..6d7bb9e54b Binary files /dev/null and b/images/GitHub_README_if.png differ diff --git a/images/demo.png b/images/demo.png deleted file mode 100644 index ad0cbe0fb5..0000000000 Binary files a/images/demo.png and /dev/null differ diff --git a/images/describe.png b/images/describe.png new file mode 100644 index 0000000000..747739dc2c Binary files /dev/null and b/images/describe.png differ diff --git a/web/app/components/app/configuration/dataset-config/card-item/item.tsx b/web/app/components/app/configuration/dataset-config/card-item/item.tsx index 65ad2ca941..4feba8b01e 100644 --- a/web/app/components/app/configuration/dataset-config/card-item/item.tsx +++ b/web/app/components/app/configuration/dataset-config/card-item/item.tsx @@ -12,6 +12,7 @@ import { DataSourceType } from '@/models/datasets' import FileIcon from '@/app/components/base/file-icon' import { Folder } from '@/app/components/base/icons/src/vender/solid/files' import { Globe06 } from '@/app/components/base/icons/src/vender/solid/mapsAndTravel' +import ActionButton, { ActionButtonState } from '@/app/components/base/action-button' import Drawer from '@/app/components/base/drawer' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import Badge from '@/app/components/base/badge' @@ -47,56 +48,66 @@ const Item: FC = ({ const [isDeleting, setIsDeleting] = useState(false) return ( -
- { - config.data_source_type === DataSourceType.FILE && ( -
- -
- ) - } - { - config.data_source_type === DataSourceType.NOTION && ( -
- -
- ) - } - { - config.data_source_type === DataSourceType.WEB && ( -
- -
- ) - } -
-
-
{config.name}
- {config.provider === 'external' - ? - : } -
-
-
+
+
{ - editable &&
setShowSettingsModal(true)} - > - -
+ config.data_source_type === DataSourceType.FILE && ( +
+ +
+ ) } -
+ +
+ ) + } + { + config.data_source_type === DataSourceType.WEB && ( +
+ +
+ ) + } +
{config.name}
+
+
+ { + editable && { + e.stopPropagation() + setShowSettingsModal(true) + }} + > + + + } + onRemove(config.id)} - onMouseOver={() => setIsDeleting(true)} + state={isDeleting ? ActionButtonState.Destructive : ActionButtonState.Default} + onMouseEnter={() => setIsDeleting(true)} onMouseLeave={() => setIsDeleting(false)} > - -
+ +
+ { + config.indexing_technique && + } + { + config.provider === 'external' && + } setShowSettingsModal(false)} footer={null} mask={isMobile} panelClassName='mt-16 mx-2 sm:mr-2 mb-3 !p-0 !max-w-[640px] rounded-xl'> { ))}
{/* mask */} -
+
- - + +
diff --git a/web/app/components/workflow/header/checklist.tsx b/web/app/components/workflow/header/checklist.tsx index 374726cbeb..9da16c59c6 100644 --- a/web/app/components/workflow/header/checklist.tsx +++ b/web/app/components/workflow/header/checklist.tsx @@ -140,16 +140,6 @@ const WorkflowChecklist = ({
) } - { - 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 47eeef73b2..9aebd935a5 100644 --- a/web/app/components/workflow/hooks/use-checklist.ts +++ b/web/app/components/workflow/hooks/use-checklist.ts @@ -15,7 +15,6 @@ import { useStore } from '../store' import { getToolCheckParams, getValidTreeNodes, - transformStartNodeVariables, } from '../utils' import { CUSTOM_NODE, @@ -46,9 +45,6 @@ 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) { @@ -68,10 +64,7 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => { const needWarningNodes = useMemo(() => { const list = [] - const { validNodes } = getValidTreeNodes(nodes.filter(node => node.type === CUSTOM_NODE), edges, true) - - const allVariablesMap = transformStartNodeVariables(chatVarList, environmentVariables) - const errMessageMap = new Map() + const { validNodes } = getValidTreeNodes(nodes.filter(node => node.type === CUSTOM_NODE), edges) for (let i = 0; i < nodes.length; i++) { const node = nodes[i] @@ -117,32 +110,8 @@ 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]) - } - } - } } } @@ -164,13 +133,8 @@ 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, chatVarList, environmentVariables]) + }, [nodes, edges, isChatMode, buildInTools, customTools, workflowTools, language, nodesExtraData, t, strategyProviders, getCheckData]) return needWarningNodes } @@ -189,9 +153,6 @@ 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) { @@ -222,15 +183,12 @@ export const useChecklistBeforePublish = () => { const { validNodes, maxDepth, - } = getValidTreeNodes(nodes.filter(node => node.type === CUSTOM_NODE), edges, true) + } = getValidTreeNodes(nodes.filter(node => node.type === CUSTOM_NODE), edges) 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) => { @@ -281,14 +239,6 @@ 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)) { @@ -302,7 +252,7 @@ export const useChecklistBeforePublish = () => { } return true - }, [store, isChatMode, notify, t, buildInTools, customTools, workflowTools, language, nodesExtraData, strategyProviders, updateDatasetsDetail, getCheckData, chatVarList, environmentVariables]) + }, [store, isChatMode, notify, t, buildInTools, customTools, workflowTools, language, nodesExtraData, strategyProviders, updateDatasetsDetail, getCheckData]) 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 443329a924..428c204dd3 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 } -export const formatItem = ( +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 bb159aba2b..d3cb2c6741 100644 --- a/web/app/components/workflow/nodes/answer/default.ts +++ b/web/app/components/workflow/nodes/answer/default.ts @@ -1,5 +1,4 @@ -import type { NodeDefault, Var } from '../../types' -import { getNotExistVariablesByText } from '../../utils/workflow' +import type { NodeDefault } from '../../types' import type { AnswerNodeType } from './types' import { genNodeMetaData } from '@/app/components/workflow/utils' import { BlockEnum } from '@/app/components/workflow/types' @@ -25,19 +24,6 @@ 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 082757003a..453221ff31 100644 --- a/web/app/components/workflow/nodes/assigner/default.ts +++ b/web/app/components/workflow/nodes/assigner/default.ts @@ -1,5 +1,4 @@ -import type { NodeDefault, Var } from '../../types' -import { getNotExistVariablesByArray } from '../../utils/workflow' +import type { NodeDefault } from '../../types' import { type AssignerNodeType, WriteMode } from './types' import { genNodeMetaData } from '@/app/components/workflow/utils' import { BlockEnum } from '@/app/components/workflow/types' @@ -46,24 +45,6 @@ const nodeDefault: NodeDefault = { errorMessage: errorMessages, } }, - - checkVarValid(payload: AssignerNodeType, varMap: Record, t: any) { - const errorMessageArr: string[] = [] - const items = payload.items ?? [] - const variables_warnings = getNotExistVariablesByArray(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(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 5d27512095..7cf40db63f 100644 --- a/web/app/components/workflow/nodes/code/default.ts +++ b/web/app/components/workflow/nodes/code/default.ts @@ -1,5 +1,4 @@ -import type { NodeDefault, Var } from '../../types' -import { getNotExistVariablesByArray } from '../../utils/workflow' +import type { NodeDefault } from '../../types' import { CodeLanguage, type CodeNodeType } from './types' import { genNodeMetaData } from '@/app/components/workflow/utils' import { BlockEnum } from '@/app/components/workflow/types' @@ -35,20 +34,7 @@ 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 c28411cd63..77a847b5fd 100644 --- a/web/app/components/workflow/nodes/document-extractor/default.ts +++ b/web/app/components/workflow/nodes/document-extractor/default.ts @@ -1,5 +1,4 @@ -import type { NodeDefault, Var } from '../../types' -import { getNotExistVariablesByArray } from '../../utils/workflow' +import type { NodeDefault } from '../../types' import type { DocExtractorNodeType } from './types' import { genNodeMetaData } from '@/app/components/workflow/utils' import { BlockEnum } from '@/app/components/workflow/types' @@ -30,19 +29,6 @@ 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 279a114c43..0ba0671590 100644 --- a/web/app/components/workflow/nodes/http/default.ts +++ b/web/app/components/workflow/nodes/http/default.ts @@ -1,5 +1,4 @@ -import type { NodeDefault, Var } from '../../types' -import { getNotExistVariablesByArray, getNotExistVariablesByText } from '../../utils/workflow' +import type { NodeDefault } from '../../types' import { AuthorizationType, BodyType, Method } from './types' import type { BodyPayload, HttpNodeType } from './types' import { genNodeMetaData } from '@/app/components/workflow/utils' @@ -45,8 +44,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') }) @@ -55,53 +54,6 @@ 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 7a77188644..4ef3bef4a2 100644 --- a/web/app/components/workflow/nodes/if-else/default.ts +++ b/web/app/components/workflow/nodes/if-else/default.ts @@ -1,6 +1,4 @@ -import type { Var } from '../../types' import type { NodeDefault } from '../../types' -import { getNotExistVariablesByArray, getNotExistVariablesByText } from '../../utils/workflow' import { type IfElseNodeType, LogicalOperator } from './types' import { isEmptyRelatedOperator } from './utils' import { genNodeMetaData } from '@/app/components/workflow/utils' @@ -76,41 +74,6 @@ 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 8ef4615b55..3c348a4fe0 100644 --- a/web/app/components/workflow/nodes/iteration/default.ts +++ b/web/app/components/workflow/nodes/iteration/default.ts @@ -1,6 +1,5 @@ import { BlockEnum, ErrorHandleMode } from '../../types' -import type { NodeDefault, Var } from '../../types' -import { getNotExistVariablesByArray } from '../../utils/workflow' +import type { NodeDefault } from '../../types' import type { IterationNodeType } from './types' import { genNodeMetaData } from '@/app/components/workflow/utils' import { BlockClassificationEnum } from '@/app/components/workflow/block-selector/types' @@ -49,19 +48,6 @@ 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/components/dataset-item.tsx b/web/app/components/workflow/nodes/knowledge-retrieval/components/dataset-item.tsx index 35555083b1..bee387d549 100644 --- a/web/app/components/workflow/nodes/knowledge-retrieval/components/dataset-item.tsx +++ b/web/app/components/workflow/nodes/knowledge-retrieval/components/dataset-item.tsx @@ -55,7 +55,7 @@ const DatasetItem: FC = ({ }, [onRemove]) return ( -
= { 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 0dc67c14d1..08e664db15 100644 --- a/web/app/components/workflow/nodes/list-operator/default.ts +++ b/web/app/components/workflow/nodes/list-operator/default.ts @@ -1,6 +1,5 @@ import { BlockEnum, VarType } from '../../types' -import type { NodeDefault, Var } from '../../types' -import { getNotExistVariablesByArray } from '../../utils/workflow' +import type { NodeDefault } from '../../types' import { comparisonOperatorNotRequireValue } from '../if-else/utils' import { type ListFilterNodeType, OrderBy } from './types' import { genNodeMetaData } from '@/app/components/workflow/utils' @@ -58,18 +57,6 @@ 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/llm/default.ts b/web/app/components/workflow/nodes/llm/default.ts index 100d03591e..9b01c3bb68 100644 --- a/web/app/components/workflow/nodes/llm/default.ts +++ b/web/app/components/workflow/nodes/llm/default.ts @@ -1,7 +1,5 @@ -import type { Var } from '../../types' -import { BlockEnum, EditionType, VarType } from '../../types' +import { BlockEnum, EditionType } from '../../types' import { type NodeDefault, type PromptItem, PromptRole } from '../../types' -import { getNotExistVariablesByArray, getNotExistVariablesByText } from '../../utils/workflow' import type { LLMNodeType } from './types' import { genNodeMetaData } from '@/app/components/workflow/utils' @@ -83,37 +81,6 @@ 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 9560fe7b79..a65306249d 100644 --- a/web/app/components/workflow/nodes/parameter-extractor/default.ts +++ b/web/app/components/workflow/nodes/parameter-extractor/default.ts @@ -1,5 +1,4 @@ -import type { NodeDefault, Var } from '../../types' -import { getNotExistVariablesByArray, getNotExistVariablesByText } from '../../utils/workflow' +import type { NodeDefault } from '../../types' import { type ParameterExtractorNodeType, ReasoningModeType } from './types' import { genNodeMetaData } from '@/app/components/workflow/utils' import { BlockEnum } from '@/app/components/workflow/types' @@ -62,30 +61,6 @@ 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 b3ed63c73d..d34c854916 100644 --- a/web/app/components/workflow/nodes/question-classifier/default.ts +++ b/web/app/components/workflow/nodes/question-classifier/default.ts @@ -1,5 +1,4 @@ -import type { NodeDefault, Var } from '../../types' -import { getNotExistVariablesByArray, getNotExistVariablesByText } from '../../utils/workflow' +import type { NodeDefault } from '../../types' import type { QuestionClassifierNodeType } from './types' import { genNodeMetaData } from '@/app/components/workflow/utils' import { BlockEnum } from '@/app/components/workflow/types' @@ -69,30 +68,6 @@ 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 1617613432..1a3c092c0b 100644 --- a/web/app/components/workflow/nodes/template-transform/default.ts +++ b/web/app/components/workflow/nodes/template-transform/default.ts @@ -1,5 +1,4 @@ -import type { NodeDefault, Var } from '../../types' -import { getNotExistVariablesByArray } from '../../utils/workflow' +import type { NodeDefault } from '../../types' import type { TemplateTransformNodeType } from './types' import { genNodeMetaData } from '@/app/components/workflow/utils' import { BlockEnum } from '@/app/components/workflow/types' @@ -33,19 +32,6 @@ 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 26669f63c8..0677cc2e09 100644 --- a/web/app/components/workflow/nodes/tool/default.ts +++ b/web/app/components/workflow/nodes/tool/default.ts @@ -1,9 +1,8 @@ import { genNodeMetaData } from '@/app/components/workflow/utils' import { BlockEnum } from '@/app/components/workflow/types' -import type { NodeDefault, Var } from '../../types' +import type { NodeDefault } from '../../types' import type { ToolNodeType } from './types' import { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types' -import { getNotExistVariablesByArray, getNotExistVariablesByText } from '../../utils/workflow' const i18nPrefix = 'workflow.errorMsg' @@ -60,35 +59,6 @@ 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 9b4c1c2f5d..825bad5b9c 100644 --- a/web/app/components/workflow/nodes/variable-assigner/default.ts +++ b/web/app/components/workflow/nodes/variable-assigner/default.ts @@ -1,6 +1,4 @@ -import type { Var } from '../../types' import { type NodeDefault, VarType } from '../../types' -import { getNotExistVariablesByArray } from '../../utils/workflow' import type { VariableAssignerNodeType } from './types' import { genNodeMetaData } from '@/app/components/workflow/utils' import { BlockEnum } from '@/app/components/workflow/types' @@ -53,18 +51,6 @@ 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 8a4f0a8266..d100cceafa 100644 --- a/web/app/components/workflow/types.ts +++ b/web/app/components/workflow/types.ts @@ -303,7 +303,6 @@ export type NodeDefault = { } defaultValue: Partial 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 d96e54a76a..8b7bdfaa92 100644 --- a/web/app/components/workflow/utils/workflow-init.spec.ts +++ b/web/app/components/workflow/utils/workflow-init.spec.ts @@ -5,18 +5,6 @@ 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 739908646a..88c31f09b5 100644 --- a/web/app/components/workflow/utils/workflow.ts +++ b/web/app/components/workflow/utils/workflow.ts @@ -10,20 +10,14 @@ 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 @@ -92,17 +86,7 @@ export const getNodesConnectedSourceOrTargetHandleIdsMap = (changes: ConnectedSo return nodesConnectedSourceOrTargetHandleIdsMap } -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) => { +export const getValidTreeNodes = (nodes: Node[], edges: Edge[]) => { const startNode = nodes.find(node => node.data.type === BlockEnum.Start) if (!startNode) { @@ -125,19 +109,6 @@ export const getValidTreeNodes = (nodes: Node[], edges: Edge[], isCollectVar?: b 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) @@ -356,48 +327,3 @@ 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 4ddf30c2e4..4d308807c5 100644 --- a/web/config/index.ts +++ b/web/config/index.ts @@ -282,8 +282,6 @@ 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 d8d64967b1..7189f2e08b 100644 --- a/web/i18n/en-US/workflow.ts +++ b/web/i18n/en-US/workflow.ts @@ -113,8 +113,6 @@ const translation = { addFailureBranch: 'Add Fail Branch', loadMore: 'Load More', noHistory: 'No History', - referenceVar: 'Reference Variable', - noExist: 'No such variable', }, env: { envPanelTitle: 'Environment Variables', @@ -601,7 +599,6 @@ 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 10d76f50a8..066a5581d7 100644 --- a/web/i18n/ja-JP/workflow.ts +++ b/web/i18n/ja-JP/workflow.ts @@ -113,8 +113,6 @@ const translation = { addFailureBranch: '失敗ブランチを追加', loadMore: 'さらに読み込む', noHistory: '履歴がありません', - referenceVar: '参照変数', - noExist: '存在しません', }, env: { envPanelTitle: '環境変数', @@ -600,7 +598,6 @@ const translation = { }, select: '選ぶ', addSubVariable: 'サブ変数', - condition: '条件', }, variableAssigner: { title: '変数を代入する', diff --git a/web/i18n/zh-Hans/workflow.ts b/web/i18n/zh-Hans/workflow.ts index 3faac9b6fb..29f58d01a2 100644 --- a/web/i18n/zh-Hans/workflow.ts +++ b/web/i18n/zh-Hans/workflow.ts @@ -113,8 +113,6 @@ const translation = { openInExplore: '在“探索”中打开', loadMore: '加载更多', noHistory: '没有历史版本', - referenceVar: '引用变量', - noExist: '不存在', }, env: { envPanelTitle: '环境变量', @@ -602,7 +600,6 @@ const translation = { selectVariable: '选择变量', addSubVariable: '添加子变量', select: '选择', - condition: '条件', }, variableAssigner: { title: '变量赋值', diff --git a/web/package.json b/web/package.json index 6bf4236ad2..3da5b54921 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "dify-web", - "version": "1.3.1", + "version": "1.4.0", "private": true, "engines": { "node": ">=v22.11.0"