diff --git a/.github/workflows/api-tests.yml b/.github/workflows/api-tests.yml
index 7c632f8a34..b1cf41a226 100644
--- a/.github/workflows/api-tests.yml
+++ b/.github/workflows/api-tests.yml
@@ -39,7 +39,7 @@ jobs:
api/pyproject.toml
api/poetry.lock
- - name: Poetry check
+ - name: Check Poetry lockfile
run: |
poetry check -C api --lock
poetry show -C api
@@ -47,6 +47,9 @@ jobs:
- name: Install dependencies
run: poetry install -C api --with dev
+ - name: Check dependencies in pyproject.toml
+ run: poetry run -C api bash dev/pytest/pytest_artifacts.sh
+
- name: Run Unit tests
run: poetry run -C api bash dev/pytest/pytest_unit_tests.sh
diff --git a/README.md b/README.md
index 1c49c415fe..ac4a4e5839 100644
--- a/README.md
+++ b/README.md
@@ -196,10 +196,14 @@ If you'd like to configure a highly-available setup, there are community-contrib
#### Using Terraform for Deployment
+Deploy Dify to Cloud Platform with a single click using [terraform](https://www.terraform.io/)
+
##### Azure Global
-Deploy Dify to Azure with a single click using [terraform](https://www.terraform.io/).
- [Azure Terraform by @nikawang](https://github.com/nikawang/dify-azure-terraform)
+##### Google Cloud
+- [Google Cloud Terraform by @sotazum](https://github.com/DeNA/dify-google-cloud-terraform)
+
## Contributing
For those who'd like to contribute code, see our [Contribution Guide](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md).
diff --git a/README_AR.md b/README_AR.md
index 10d572cc49..42dbd9edff 100644
--- a/README_AR.md
+++ b/README_AR.md
@@ -179,10 +179,13 @@ docker compose up -d
#### استخدام Terraform للتوزيع
+انشر Dify إلى منصة السحابة بنقرة واحدة باستخدام [terraform](https://www.terraform.io/)
+
##### Azure Global
-استخدم [terraform](https://www.terraform.io/) لنشر Dify على Azure بنقرة واحدة.
- [Azure Terraform بواسطة @nikawang](https://github.com/nikawang/dify-azure-terraform)
+##### Google Cloud
+- [Google Cloud Terraform بواسطة @sotazum](https://github.com/DeNA/dify-google-cloud-terraform)
## المساهمة
diff --git a/README_CN.md b/README_CN.md
index 32551fcc31..afeca3147b 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -202,10 +202,14 @@ docker compose up -d
#### 使用 Terraform 部署
+使用 [terraform](https://www.terraform.io/) 一键将 Dify 部署到云平台
+
##### Azure Global
-使用 [terraform](https://www.terraform.io/) 一键部署 Dify 到 Azure。
- [Azure Terraform by @nikawang](https://github.com/nikawang/dify-azure-terraform)
+##### Google Cloud
+- [Google Cloud Terraform by @sotazum](https://github.com/DeNA/dify-google-cloud-terraform)
+
## Star History
[](https://star-history.com/#langgenius/dify&Date)
diff --git a/README_ES.md b/README_ES.md
index 2ae044b328..a6296aa93d 100644
--- a/README_ES.md
+++ b/README_ES.md
@@ -204,10 +204,13 @@ Si desea configurar una configuración de alta disponibilidad, la comunidad prop
#### Uso de Terraform para el despliegue
+Despliega Dify en una plataforma en la nube con un solo clic utilizando [terraform](https://www.terraform.io/)
+
##### Azure Global
-Utiliza [terraform](https://www.terraform.io/) para desplegar Dify en Azure con un solo clic.
- [Azure Terraform por @nikawang](https://github.com/nikawang/dify-azure-terraform)
+##### Google Cloud
+- [Google Cloud Terraform por @sotazum](https://github.com/DeNA/dify-google-cloud-terraform)
## Contribuir
diff --git a/README_FR.md b/README_FR.md
index 681d596749..da8b7baa3e 100644
--- a/README_FR.md
+++ b/README_FR.md
@@ -202,10 +202,13 @@ Si vous souhaitez configurer une configuration haute disponibilité, la communau
#### Utilisation de Terraform pour le déploiement
+Déployez Dify sur une plateforme cloud en un clic en utilisant [terraform](https://www.terraform.io/)
+
##### Azure Global
-Utilisez [terraform](https://www.terraform.io/) pour déployer Dify sur Azure en un clic.
- [Azure Terraform par @nikawang](https://github.com/nikawang/dify-azure-terraform)
+##### Google Cloud
+- [Google Cloud Terraform par @sotazum](https://github.com/DeNA/dify-google-cloud-terraform)
## Contribuer
diff --git a/README_JA.md b/README_JA.md
index e6a8621e7b..8c6076362b 100644
--- a/README_JA.md
+++ b/README_JA.md
@@ -68,7 +68,7 @@ DifyはオープンソースのLLMアプリケーション開発プラットフ
プロンプトの作成、モデルパフォーマンスの比較が行え、チャットベースのアプリに音声合成などの機能も追加できます。
**4. RAGパイプライン**:
- ドキュメントの取り込みから検索までをカバーする広範なRAG機能ができます。ほかにもPDF、PPT、その他の一般的なドキュメントフォーマットからのテキスト抽出のサーポイントも提供します。
+ ドキュメントの取り込みから検索までをカバーする広範なRAG機能ができます。ほかにもPDF、PPT、その他の一般的なドキュメントフォーマットからのテキスト抽出のサポートも提供します。
**5. エージェント機能**:
LLM Function CallingやReActに基づくエージェントの定義が可能で、AIエージェント用のプリビルトまたはカスタムツールを追加できます。Difyには、Google検索、DALL·E、Stable Diffusion、WolframAlphaなどのAIエージェント用の50以上の組み込みツールが提供します。
@@ -201,10 +201,13 @@ docker compose up -d
#### Terraformを使用したデプロイ
-##### Azure Global
-[terraform](https://www.terraform.io/) を使用して、AzureにDifyをワンクリックでデプロイします。
-- [nikawangのAzure Terraform](https://github.com/nikawang/dify-azure-terraform)
+[terraform](https://www.terraform.io/) を使用して、ワンクリックでDifyをクラウドプラットフォームにデプロイします
+##### Azure Global
+- [@nikawangによるAzure Terraform](https://github.com/nikawang/dify-azure-terraform)
+
+##### Google Cloud
+- [@sotazumによるGoogle Cloud Terraform](https://github.com/DeNA/dify-google-cloud-terraform)
## 貢献
diff --git a/README_KL.md b/README_KL.md
index 04620d42bb..ce2f78570b 100644
--- a/README_KL.md
+++ b/README_KL.md
@@ -202,10 +202,13 @@ If you'd like to configure a highly-available setup, there are community-contrib
#### Terraform atorlugu pilersitsineq
-##### Azure Global
-Atoruk [terraform](https://www.terraform.io/) Dify-mik Azure-mut ataatsikkut ikkussuilluarlugu.
-- [Azure Terraform atorlugu @nikawang](https://github.com/nikawang/dify-azure-terraform)
+wa'logh nIqHom neH ghun deployment toy'wI' [terraform](https://www.terraform.io/) lo'laH.
+##### Azure Global
+- [Azure Terraform mung @nikawang](https://github.com/nikawang/dify-azure-terraform)
+
+##### Google Cloud
+- [Google Cloud Terraform qachlot @sotazum](https://github.com/DeNA/dify-google-cloud-terraform)
## Contributing
diff --git a/README_KR.md b/README_KR.md
index a5f3bc68d0..87409bfb8c 100644
--- a/README_KR.md
+++ b/README_KR.md
@@ -39,7 +39,6 @@
-
@@ -195,10 +194,14 @@ Dify를 Kubernetes에 배포하고 프리미엄 스케일링 설정을 구성했
#### Terraform을 사용한 배포
+[terraform](https://www.terraform.io/)을 사용하여 단 한 번의 클릭으로 Dify를 클라우드 플랫폼에 배포하십시오
+
##### Azure Global
-[terraform](https://www.terraform.io/)을 사용하여 Azure에 Dify를 원클릭으로 배포하세요.
- [nikawang의 Azure Terraform](https://github.com/nikawang/dify-azure-terraform)
+##### Google Cloud
+- [sotazum의 Google Cloud Terraform](https://github.com/DeNA/dify-google-cloud-terraform)
+
## 기여
코드에 기여하고 싶은 분들은 [기여 가이드](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md)를 참조하세요.
diff --git a/README_TR.md b/README_TR.md
index 54b6db3f82..08080a8c7b 100644
--- a/README_TR.md
+++ b/README_TR.md
@@ -200,9 +200,13 @@ Yüksek kullanılabilirliğe sahip bir kurulum yapılandırmak isterseniz, Dify'
#### Dağıtım için Terraform Kullanımı
+Dify'ı bulut platformuna tek tıklamayla dağıtın [terraform](https://www.terraform.io/) kullanarak
+
##### Azure Global
-[Terraform](https://www.terraform.io/) kullanarak Dify'ı Azure'a tek tıklamayla dağıtın.
-- [@nikawang tarafından Azure Terraform](https://github.com/nikawang/dify-azure-terraform)
+- [Azure Terraform tarafından @nikawang](https://github.com/nikawang/dify-azure-terraform)
+
+##### Google Cloud
+- [Google Cloud Terraform tarafından @sotazum](https://github.com/DeNA/dify-google-cloud-terraform)
## Katkıda Bulunma
diff --git a/README_VI.md b/README_VI.md
index 6d4035eceb..d67f024c79 100644
--- a/README_VI.md
+++ b/README_VI.md
@@ -196,10 +196,14 @@ Nếu bạn muốn cấu hình một cài đặt có độ sẵn sàng cao, có
#### Sử dụng Terraform để Triển khai
+Triển khai Dify lên nền tảng đám mây với một cú nhấp chuột bằng cách sử dụng [terraform](https://www.terraform.io/)
+
##### Azure Global
-Triển khai Dify lên Azure chỉ với một cú nhấp chuột bằng cách sử dụng [terraform](https://www.terraform.io/).
- [Azure Terraform bởi @nikawang](https://github.com/nikawang/dify-azure-terraform)
+##### Google Cloud
+- [Google Cloud Terraform bởi @sotazum](https://github.com/DeNA/dify-google-cloud-terraform)
+
## Đóng góp
Đối với những người muốn đóng góp mã, xem [Hướng dẫn Đóng góp](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) của chúng tôi.
diff --git a/api/.env.example b/api/.env.example
index 7e5c636ff8..71f0e5db8f 100644
--- a/api/.env.example
+++ b/api/.env.example
@@ -39,7 +39,7 @@ DB_DATABASE=dify
# Storage configuration
# use for store upload files, private keys...
-# storage type: local, s3, azure-blob, google-storage, tencent-cos, huawei-obs, volcengine-tos
+# storage type: local, s3, azure-blob, google-storage, tencent-cos, huawei-obs, volcengine-tos, baidu-obs
STORAGE_TYPE=local
STORAGE_LOCAL_PATH=storage
S3_USE_AWS_MANAGED_IAM=false
@@ -79,6 +79,12 @@ HUAWEI_OBS_SECRET_KEY=your-secret-key
HUAWEI_OBS_ACCESS_KEY=your-access-key
HUAWEI_OBS_SERVER=your-server-url
+# Baidu OBS Storage Configuration
+BAIDU_OBS_BUCKET_NAME=your-bucket-name
+BAIDU_OBS_SECRET_KEY=your-secret-key
+BAIDU_OBS_ACCESS_KEY=your-access-key
+BAIDU_OBS_ENDPOINT=your-server-url
+
# OCI Storage configuration
OCI_ENDPOINT=your-endpoint
OCI_BUCKET_NAME=your-bucket-name
@@ -265,6 +271,9 @@ HTTP_REQUEST_MAX_WRITE_TIMEOUT=600
HTTP_REQUEST_NODE_MAX_BINARY_SIZE=10485760
HTTP_REQUEST_NODE_MAX_TEXT_SIZE=1048576
+# Respect X-* headers to redirect clients
+RESPECT_XFORWARD_HEADERS_ENABLED=false
+
# Log file path
LOG_FILE=
diff --git a/api/app.py b/api/app.py
index 1b58beee15..a251ef5f0f 100644
--- a/api/app.py
+++ b/api/app.py
@@ -26,7 +26,7 @@ from commands import register_commands
from configs import dify_config
# DO NOT REMOVE BELOW
-from events import event_handlers
+from events import event_handlers # noqa: F401
from extensions import (
ext_celery,
ext_code_based_extension,
@@ -36,6 +36,7 @@ from extensions import (
ext_login,
ext_mail,
ext_migrate,
+ ext_proxy_fix,
ext_redis,
ext_sentry,
ext_storage,
@@ -45,7 +46,7 @@ from extensions.ext_login import login_manager
from libs.passport import PassportService
# TODO: Find a way to avoid importing models here
-from models import account, dataset, model, source, task, tool, tools, web
+from models import account, dataset, model, source, task, tool, tools, web # noqa: F401
from services.account_service import AccountService
# DO NOT REMOVE ABOVE
@@ -156,6 +157,7 @@ def initialize_extensions(app):
ext_mail.init_app(app)
ext_hosting_provider.init_app(app)
ext_sentry.init_app(app)
+ ext_proxy_fix.init_app(app)
# Flask-Login configuration
@@ -181,10 +183,10 @@ def load_user_from_request(request_from_flask_login):
decoded = PassportService().verify(auth_token)
user_id = decoded.get("user_id")
- account = AccountService.load_logged_in_account(account_id=user_id, token=auth_token)
- if account:
- contexts.tenant_id.set(account.current_tenant_id)
- return account
+ logged_in_account = AccountService.load_logged_in_account(account_id=user_id, token=auth_token)
+ if logged_in_account:
+ contexts.tenant_id.set(logged_in_account.current_tenant_id)
+ return logged_in_account
@login_manager.unauthorized_handler
diff --git a/api/configs/feature/__init__.py b/api/configs/feature/__init__.py
index 9218d529cc..93dbc1367f 100644
--- a/api/configs/feature/__init__.py
+++ b/api/configs/feature/__init__.py
@@ -247,6 +247,12 @@ class HttpConfig(BaseSettings):
default=None,
)
+ RESPECT_XFORWARD_HEADERS_ENABLED: bool = Field(
+ description="Enable or disable the X-Forwarded-For Proxy Fix middleware from Werkzeug"
+ " to respect X-* headers to redirect clients",
+ default=False,
+ )
+
class InnerAPIConfig(BaseSettings):
"""
diff --git a/api/configs/middleware/__init__.py b/api/configs/middleware/__init__.py
index 6ad216c191..8626236856 100644
--- a/api/configs/middleware/__init__.py
+++ b/api/configs/middleware/__init__.py
@@ -8,6 +8,7 @@ from configs.middleware.cache.redis_config import RedisConfig
from configs.middleware.storage.aliyun_oss_storage_config import AliyunOSSStorageConfig
from configs.middleware.storage.amazon_s3_storage_config import S3StorageConfig
from configs.middleware.storage.azure_blob_storage_config import AzureBlobStorageConfig
+from configs.middleware.storage.baidu_obs_storage_config import BaiduOBSStorageConfig
from configs.middleware.storage.google_cloud_storage_config import GoogleCloudStorageConfig
from configs.middleware.storage.huawei_obs_storage_config import HuaweiCloudOBSStorageConfig
from configs.middleware.storage.oci_storage_config import OCIStorageConfig
@@ -200,12 +201,13 @@ class MiddlewareConfig(
StorageConfig,
AliyunOSSStorageConfig,
AzureBlobStorageConfig,
+ BaiduOBSStorageConfig,
GoogleCloudStorageConfig,
- TencentCloudCOSStorageConfig,
HuaweiCloudOBSStorageConfig,
- VolcengineTOSStorageConfig,
- S3StorageConfig,
OCIStorageConfig,
+ S3StorageConfig,
+ TencentCloudCOSStorageConfig,
+ VolcengineTOSStorageConfig,
# configs of vdb and vdb providers
VectorStoreConfig,
AnalyticdbConfig,
diff --git a/api/configs/middleware/storage/baidu_obs_storage_config.py b/api/configs/middleware/storage/baidu_obs_storage_config.py
new file mode 100644
index 0000000000..c511628a15
--- /dev/null
+++ b/api/configs/middleware/storage/baidu_obs_storage_config.py
@@ -0,0 +1,29 @@
+from typing import Optional
+
+from pydantic import BaseModel, Field
+
+
+class BaiduOBSStorageConfig(BaseModel):
+ """
+ Configuration settings for Baidu Object Storage Service (OBS)
+ """
+
+ BAIDU_OBS_BUCKET_NAME: Optional[str] = Field(
+ description="Name of the Baidu OBS bucket to store and retrieve objects (e.g., 'my-obs-bucket')",
+ default=None,
+ )
+
+ BAIDU_OBS_ACCESS_KEY: Optional[str] = Field(
+ description="Access Key ID for authenticating with Baidu OBS",
+ default=None,
+ )
+
+ BAIDU_OBS_SECRET_KEY: Optional[str] = Field(
+ description="Secret Access Key for authenticating with Baidu OBS",
+ default=None,
+ )
+
+ BAIDU_OBS_ENDPOINT: Optional[str] = Field(
+ description="URL of the Baidu OSS endpoint for your chosen region (e.g., 'https://.bj.bcebos.com')",
+ default=None,
+ )
diff --git a/api/configs/packaging/__init__.py b/api/configs/packaging/__init__.py
index c752660122..c311a989b4 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="0.8.3",
+ default="0.9.1",
)
COMMIT_SHA: str = Field(
diff --git a/api/controllers/console/app/conversation.py b/api/controllers/console/app/conversation.py
index df7bd352af..c1e16b3b9b 100644
--- a/api/controllers/console/app/conversation.py
+++ b/api/controllers/console/app/conversation.py
@@ -188,6 +188,7 @@ class ChatConversationApi(Resource):
subquery.c.from_end_user_session_id.ilike(keyword_filter),
),
)
+ .group_by(Conversation.id)
)
account = current_user
diff --git a/api/controllers/files/error.py b/api/controllers/files/error.py
new file mode 100644
index 0000000000..a7ce4cd6f7
--- /dev/null
+++ b/api/controllers/files/error.py
@@ -0,0 +1,7 @@
+from libs.exception import BaseHTTPException
+
+
+class UnsupportedFileTypeError(BaseHTTPException):
+ error_code = "unsupported_file_type"
+ description = "File type not allowed."
+ code = 415
diff --git a/api/controllers/files/image_preview.py b/api/controllers/files/image_preview.py
index 2432285d93..a56c1c332d 100644
--- a/api/controllers/files/image_preview.py
+++ b/api/controllers/files/image_preview.py
@@ -4,7 +4,7 @@ from werkzeug.exceptions import NotFound
import services
from controllers.files import api
-from libs.exception import BaseHTTPException
+from controllers.files.error import UnsupportedFileTypeError
from services.account_service import TenantService
from services.file_service import FileService
@@ -50,9 +50,3 @@ class WorkspaceWebappLogoApi(Resource):
api.add_resource(ImagePreviewApi, "/files//image-preview")
api.add_resource(WorkspaceWebappLogoApi, "/files/workspaces//webapp-logo")
-
-
-class UnsupportedFileTypeError(BaseHTTPException):
- error_code = "unsupported_file_type"
- description = "File type not allowed."
- code = 415
diff --git a/api/controllers/files/tool_files.py b/api/controllers/files/tool_files.py
index 38ac0815da..406cd42214 100644
--- a/api/controllers/files/tool_files.py
+++ b/api/controllers/files/tool_files.py
@@ -3,8 +3,8 @@ from flask_restful import Resource, reqparse
from werkzeug.exceptions import Forbidden, NotFound
from controllers.files import api
+from controllers.files.error import UnsupportedFileTypeError
from core.tools.tool_file_manager import ToolFileManager
-from libs.exception import BaseHTTPException
class ToolFilePreviewApi(Resource):
@@ -43,9 +43,3 @@ class ToolFilePreviewApi(Resource):
api.add_resource(ToolFilePreviewApi, "/files/tools/.")
-
-
-class UnsupportedFileTypeError(BaseHTTPException):
- error_code = "unsupported_file_type"
- description = "File type not allowed."
- code = 415
diff --git a/api/controllers/service_api/app/completion.py b/api/controllers/service_api/app/completion.py
index 8d8e356c4c..5c3601cf23 100644
--- a/api/controllers/service_api/app/completion.py
+++ b/api/controllers/service_api/app/completion.py
@@ -4,6 +4,7 @@ from flask_restful import Resource, reqparse
from werkzeug.exceptions import InternalServerError, NotFound
import services
+from constants import UUID_NIL
from controllers.service_api import api
from controllers.service_api.app.error import (
AppUnavailableError,
@@ -107,6 +108,7 @@ class ChatApi(Resource):
parser.add_argument("conversation_id", type=uuid_value, location="json")
parser.add_argument("retriever_from", type=str, required=False, default="dev", location="json")
parser.add_argument("auto_generate_name", type=bool, required=False, default=True, location="json")
+ parser.add_argument("parent_message_id", type=uuid_value, required=False, default=UUID_NIL, location="json")
args = parser.parse_args()
diff --git a/api/core/agent/cot_agent_runner.py b/api/core/agent/cot_agent_runner.py
index ebe04bf260..d98ba5a3fa 100644
--- a/api/core/agent/cot_agent_runner.py
+++ b/api/core/agent/cot_agent_runner.py
@@ -369,7 +369,7 @@ class CotAgentRunner(BaseAgentRunner, ABC):
return message
def _organize_historic_prompt_messages(
- self, current_session_messages: list[PromptMessage] = None
+ self, current_session_messages: Optional[list[PromptMessage]] = None
) -> list[PromptMessage]:
"""
organize historic prompt messages
diff --git a/api/core/agent/cot_chat_agent_runner.py b/api/core/agent/cot_chat_agent_runner.py
index bdec6b7ed1..5e16373fff 100644
--- a/api/core/agent/cot_chat_agent_runner.py
+++ b/api/core/agent/cot_chat_agent_runner.py
@@ -27,7 +27,7 @@ class CotChatAgentRunner(CotAgentRunner):
return SystemPromptMessage(content=system_prompt)
- def _organize_user_query(self, query, prompt_messages: list[PromptMessage] = None) -> list[PromptMessage]:
+ def _organize_user_query(self, query, prompt_messages: list[PromptMessage]) -> list[PromptMessage]:
"""
Organize user query
"""
diff --git a/api/core/agent/cot_completion_agent_runner.py b/api/core/agent/cot_completion_agent_runner.py
index 9dab956f9a..0563090537 100644
--- a/api/core/agent/cot_completion_agent_runner.py
+++ b/api/core/agent/cot_completion_agent_runner.py
@@ -1,4 +1,5 @@
import json
+from typing import Optional
from core.agent.cot_agent_runner import CotAgentRunner
from core.model_runtime.entities.message_entities import AssistantPromptMessage, PromptMessage, UserPromptMessage
@@ -21,7 +22,7 @@ class CotCompletionAgentRunner(CotAgentRunner):
return system_prompt
- def _organize_historic_prompt(self, current_session_messages: list[PromptMessage] = None) -> str:
+ def _organize_historic_prompt(self, current_session_messages: Optional[list[PromptMessage]] = None) -> str:
"""
Organize historic prompt
"""
diff --git a/api/core/agent/fc_agent_runner.py b/api/core/agent/fc_agent_runner.py
index 13164e0bfc..7b22025582 100644
--- a/api/core/agent/fc_agent_runner.py
+++ b/api/core/agent/fc_agent_runner.py
@@ -2,7 +2,7 @@ import json
import logging
from collections.abc import Generator
from copy import deepcopy
-from typing import Any, Union
+from typing import Any, Optional, Union
from core.agent.base_agent_runner import BaseAgentRunner
from core.app.apps.base_app_queue_manager import PublishFrom
@@ -370,7 +370,7 @@ class FunctionCallAgentRunner(BaseAgentRunner):
return tool_calls
def _init_system_message(
- self, prompt_template: str, prompt_messages: list[PromptMessage] = None
+ self, prompt_template: str, prompt_messages: Optional[list[PromptMessage]] = None
) -> list[PromptMessage]:
"""
Initialize system message
@@ -385,7 +385,7 @@ class FunctionCallAgentRunner(BaseAgentRunner):
return prompt_messages
- def _organize_user_query(self, query, prompt_messages: list[PromptMessage] = None) -> list[PromptMessage]:
+ def _organize_user_query(self, query, prompt_messages: list[PromptMessage]) -> list[PromptMessage]:
"""
Organize user query
"""
diff --git a/api/core/agent/output_parser/cot_output_parser.py b/api/core/agent/output_parser/cot_output_parser.py
index d04e38777a..99876b2f5e 100644
--- a/api/core/agent/output_parser/cot_output_parser.py
+++ b/api/core/agent/output_parser/cot_output_parser.py
@@ -14,7 +14,7 @@ class CotAgentOutputParser:
) -> Generator[Union[str, AgentScratchpadUnit.Action], None, None]:
def parse_action(json_str):
try:
- action = json.loads(json_str)
+ action = json.loads(json_str, strict=False)
action_name = None
action_input = None
diff --git a/api/core/callback_handler/agent_tool_callback_handler.py b/api/core/callback_handler/agent_tool_callback_handler.py
index 99e992fd89..d826edf6a0 100644
--- a/api/core/callback_handler/agent_tool_callback_handler.py
+++ b/api/core/callback_handler/agent_tool_callback_handler.py
@@ -1,9 +1,9 @@
-import os
from collections.abc import Mapping, Sequence
from typing import Any, Optional, TextIO, Union
from pydantic import BaseModel
+from configs import dify_config
from core.ops.entities.trace_entity import TraceTaskName
from core.ops.ops_trace_manager import TraceQueueManager, TraceTask
from core.tools.entities.tool_entities import ToolInvokeMessage
@@ -50,7 +50,8 @@ class DifyAgentCallbackHandler(BaseModel):
tool_inputs: Mapping[str, Any],
) -> None:
"""Do nothing."""
- print_text("\n[on_tool_start] ToolCall:" + tool_name + "\n" + str(tool_inputs) + "\n", color=self.color)
+ if dify_config.DEBUG:
+ print_text("\n[on_tool_start] ToolCall:" + tool_name + "\n" + str(tool_inputs) + "\n", color=self.color)
def on_tool_end(
self,
@@ -62,11 +63,12 @@ class DifyAgentCallbackHandler(BaseModel):
trace_manager: Optional[TraceQueueManager] = None,
) -> None:
"""If not the final action, print out observation."""
- print_text("\n[on_tool_end]\n", color=self.color)
- print_text("Tool: " + tool_name + "\n", color=self.color)
- print_text("Inputs: " + str(tool_inputs) + "\n", color=self.color)
- print_text("Outputs: " + str(tool_outputs)[:1000] + "\n", color=self.color)
- print_text("\n")
+ if dify_config.DEBUG:
+ print_text("\n[on_tool_end]\n", color=self.color)
+ print_text("Tool: " + tool_name + "\n", color=self.color)
+ print_text("Inputs: " + str(tool_inputs) + "\n", color=self.color)
+ print_text("Outputs: " + str(tool_outputs)[:1000] + "\n", color=self.color)
+ print_text("\n")
if trace_manager:
trace_manager.add_trace_task(
@@ -82,30 +84,33 @@ class DifyAgentCallbackHandler(BaseModel):
def on_tool_error(self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any) -> None:
"""Do nothing."""
- print_text("\n[on_tool_error] Error: " + str(error) + "\n", color="red")
+ if dify_config.DEBUG:
+ print_text("\n[on_tool_error] Error: " + str(error) + "\n", color="red")
def on_agent_start(self, thought: str) -> None:
"""Run on agent start."""
- if thought:
- print_text(
- "\n[on_agent_start] \nCurrent Loop: " + str(self.current_loop) + "\nThought: " + thought + "\n",
- color=self.color,
- )
- else:
- print_text("\n[on_agent_start] \nCurrent Loop: " + str(self.current_loop) + "\n", color=self.color)
+ if dify_config.DEBUG:
+ if thought:
+ print_text(
+ "\n[on_agent_start] \nCurrent Loop: " + str(self.current_loop) + "\nThought: " + thought + "\n",
+ color=self.color,
+ )
+ else:
+ print_text("\n[on_agent_start] \nCurrent Loop: " + str(self.current_loop) + "\n", color=self.color)
def on_agent_finish(self, color: Optional[str] = None, **kwargs: Any) -> None:
"""Run on agent end."""
- print_text("\n[on_agent_finish]\n Loop: " + str(self.current_loop) + "\n", color=self.color)
+ if dify_config.DEBUG:
+ print_text("\n[on_agent_finish]\n Loop: " + str(self.current_loop) + "\n", color=self.color)
self.current_loop += 1
@property
def ignore_agent(self) -> bool:
"""Whether to ignore agent callbacks."""
- return not os.environ.get("DEBUG") or os.environ.get("DEBUG").lower() != "true"
+ return not dify_config.DEBUG
@property
def ignore_chat_model(self) -> bool:
"""Whether to ignore chat model callbacks."""
- return not os.environ.get("DEBUG") or os.environ.get("DEBUG").lower() != "true"
+ return not dify_config.DEBUG
diff --git a/api/core/callback_handler/index_tool_callback_handler.py b/api/core/callback_handler/index_tool_callback_handler.py
index 23dc092895..1481578630 100644
--- a/api/core/callback_handler/index_tool_callback_handler.py
+++ b/api/core/callback_handler/index_tool_callback_handler.py
@@ -44,7 +44,6 @@ class DatasetIndexToolCallbackHandler:
DocumentSegment.index_node_id == document.metadata["doc_id"]
)
- # if 'dataset_id' in document.metadata:
if "dataset_id" in document.metadata:
query = query.filter(DocumentSegment.dataset_id == document.metadata["dataset_id"])
diff --git a/api/core/file/message_file_parser.py b/api/core/file/message_file_parser.py
index 83059b216e..641686bd7c 100644
--- a/api/core/file/message_file_parser.py
+++ b/api/core/file/message_file_parser.py
@@ -198,16 +198,34 @@ class MessageFileParser:
if "amazonaws.com" not in parsed_url.netloc:
return False
query_params = parse_qs(parsed_url.query)
- required_params = ["Signature", "Expires"]
- for param in required_params:
- if param not in query_params:
+
+ def check_presign_v2(query_params):
+ required_params = ["Signature", "Expires"]
+ for param in required_params:
+ if param not in query_params:
+ return False
+ if not query_params["Expires"][0].isdigit():
return False
- if not query_params["Expires"][0].isdigit():
- return False
- signature = query_params["Signature"][0]
- if not re.match(r"^[A-Za-z0-9+/]+={0,2}$", signature):
- return False
- return True
+ signature = query_params["Signature"][0]
+ if not re.match(r"^[A-Za-z0-9+/]+={0,2}$", signature):
+ return False
+
+ return True
+
+ def check_presign_v4(query_params):
+ required_params = ["X-Amz-Signature", "X-Amz-Expires"]
+ for param in required_params:
+ if param not in query_params:
+ return False
+ if not query_params["X-Amz-Expires"][0].isdigit():
+ return False
+ signature = query_params["X-Amz-Signature"][0]
+ if not re.match(r"^[A-Za-z0-9+/]+={0,2}$", signature):
+ return False
+
+ return True
+
+ return check_presign_v4(query_params) or check_presign_v2(query_params)
except Exception:
return False
diff --git a/api/core/indexing_runner.py b/api/core/indexing_runner.py
index af20df41b1..8df26172b7 100644
--- a/api/core/indexing_runner.py
+++ b/api/core/indexing_runner.py
@@ -211,9 +211,9 @@ class IndexingRunner:
tenant_id: str,
extract_settings: list[ExtractSetting],
tmp_processing_rule: dict,
- doc_form: str = None,
+ doc_form: Optional[str] = None,
doc_language: str = "English",
- dataset_id: str = None,
+ dataset_id: Optional[str] = None,
indexing_technique: str = "economy",
) -> dict:
"""
diff --git a/api/core/model_runtime/model_providers/anthropic/llm/llm.py b/api/core/model_runtime/model_providers/anthropic/llm/llm.py
index 46e1b415b8..3a5a42ba05 100644
--- a/api/core/model_runtime/model_providers/anthropic/llm/llm.py
+++ b/api/core/model_runtime/model_providers/anthropic/llm/llm.py
@@ -169,7 +169,7 @@ class AnthropicLargeLanguageModel(LargeLanguageModel):
stop: Optional[list[str]] = None,
stream: bool = True,
user: Optional[str] = None,
- callbacks: list[Callback] = None,
+ callbacks: Optional[list[Callback]] = None,
) -> Union[LLMResult, Generator]:
"""
Code block mode wrapper for invoking large language model
diff --git a/api/core/model_runtime/model_providers/azure_openai/_constant.py b/api/core/model_runtime/model_providers/azure_openai/_constant.py
index 0dada70cc5..baa5421396 100644
--- a/api/core/model_runtime/model_providers/azure_openai/_constant.py
+++ b/api/core/model_runtime/model_providers/azure_openai/_constant.py
@@ -1081,8 +1081,81 @@ LLM_BASE_MODELS = [
),
),
),
+ AzureBaseModel(
+ base_model_name="o1-preview",
+ entity=AIModelEntity(
+ model="fake-deployment-name",
+ label=I18nObject(
+ en_US="fake-deployment-name-label",
+ ),
+ model_type=ModelType.LLM,
+ features=[
+ ModelFeature.AGENT_THOUGHT,
+ ],
+ fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
+ model_properties={
+ ModelPropertyKey.MODE: LLMMode.CHAT.value,
+ ModelPropertyKey.CONTEXT_SIZE: 128000,
+ },
+ parameter_rules=[
+ ParameterRule(
+ name="response_format",
+ label=I18nObject(zh_Hans="回复格式", en_US="response_format"),
+ type="string",
+ help=I18nObject(
+ zh_Hans="指定模型必须输出的格式", en_US="specifying the format that the model must output"
+ ),
+ required=False,
+ options=["text", "json_object"],
+ ),
+ _get_max_tokens(default=512, min_val=1, max_val=32768),
+ ],
+ pricing=PriceConfig(
+ input=15.00,
+ output=60.00,
+ unit=0.000001,
+ currency="USD",
+ ),
+ ),
+ ),
+ AzureBaseModel(
+ base_model_name="o1-mini",
+ entity=AIModelEntity(
+ model="fake-deployment-name",
+ label=I18nObject(
+ en_US="fake-deployment-name-label",
+ ),
+ model_type=ModelType.LLM,
+ features=[
+ ModelFeature.AGENT_THOUGHT,
+ ],
+ fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
+ model_properties={
+ ModelPropertyKey.MODE: LLMMode.CHAT.value,
+ ModelPropertyKey.CONTEXT_SIZE: 128000,
+ },
+ parameter_rules=[
+ ParameterRule(
+ name="response_format",
+ label=I18nObject(zh_Hans="回复格式", en_US="response_format"),
+ type="string",
+ help=I18nObject(
+ zh_Hans="指定模型必须输出的格式", en_US="specifying the format that the model must output"
+ ),
+ required=False,
+ options=["text", "json_object"],
+ ),
+ _get_max_tokens(default=512, min_val=1, max_val=65536),
+ ],
+ pricing=PriceConfig(
+ input=3.00,
+ output=12.00,
+ unit=0.000001,
+ currency="USD",
+ ),
+ ),
+ ),
]
-
EMBEDDING_BASE_MODELS = [
AzureBaseModel(
base_model_name="text-embedding-ada-002",
diff --git a/api/core/model_runtime/model_providers/azure_openai/azure_openai.yaml b/api/core/model_runtime/model_providers/azure_openai/azure_openai.yaml
index 867f9fec42..cb87bfdf6b 100644
--- a/api/core/model_runtime/model_providers/azure_openai/azure_openai.yaml
+++ b/api/core/model_runtime/model_providers/azure_openai/azure_openai.yaml
@@ -120,6 +120,18 @@ model_credential_schema:
show_on:
- variable: __model_type
value: llm
+ - label:
+ en_US: o1-mini
+ value: o1-mini
+ show_on:
+ - variable: __model_type
+ value: llm
+ - label:
+ en_US: o1-preview
+ value: o1-preview
+ show_on:
+ - variable: __model_type
+ value: llm
- label:
en_US: gpt-4o-mini
value: gpt-4o-mini
diff --git a/api/core/model_runtime/model_providers/azure_openai/llm/llm.py b/api/core/model_runtime/model_providers/azure_openai/llm/llm.py
index f0033ea051..f63c80e58e 100644
--- a/api/core/model_runtime/model_providers/azure_openai/llm/llm.py
+++ b/api/core/model_runtime/model_providers/azure_openai/llm/llm.py
@@ -312,20 +312,118 @@ class AzureOpenAILargeLanguageModel(_CommonAzureOpenAI, LargeLanguageModel):
if user:
extra_model_kwargs["user"] = user
- # chat model
- messages = [self._convert_prompt_message_to_dict(m) for m in prompt_messages]
- response = client.chat.completions.create(
- messages=messages,
- model=model,
- stream=stream,
- **model_parameters,
- **extra_model_kwargs,
+ # clear illegal prompt messages
+ prompt_messages = self._clear_illegal_prompt_messages(model, prompt_messages)
+
+ block_as_stream = False
+ if model.startswith("o1"):
+ if stream:
+ block_as_stream = True
+ stream = False
+
+ if "stream_options" in extra_model_kwargs:
+ del extra_model_kwargs["stream_options"]
+
+ if "stop" in extra_model_kwargs:
+ del extra_model_kwargs["stop"]
+
+ # chat model
+ response = client.chat.completions.create(
+ messages=[self._convert_prompt_message_to_dict(m) for m in prompt_messages],
+ model=model,
+ stream=stream,
+ **model_parameters,
+ **extra_model_kwargs,
+ )
+
+ if stream:
+ return self._handle_chat_generate_stream_response(model, credentials, response, prompt_messages, tools)
+
+ block_result = self._handle_chat_generate_response(model, credentials, response, prompt_messages, tools)
+
+ if block_as_stream:
+ return self._handle_chat_block_as_stream_response(block_result, prompt_messages, stop)
+
+ return block_result
+
+ def _handle_chat_block_as_stream_response(
+ self,
+ block_result: LLMResult,
+ prompt_messages: list[PromptMessage],
+ stop: Optional[list[str]] = None,
+ ) -> Generator[LLMResultChunk, None, None]:
+ """
+ Handle llm chat response
+
+ :param model: model name
+ :param credentials: credentials
+ :param response: response
+ :param prompt_messages: prompt messages
+ :param tools: tools for tool calling
+ :param stop: stop words
+ :return: llm response chunk generator
+ """
+ text = block_result.message.content
+ text = cast(str, text)
+
+ if stop:
+ text = self.enforce_stop_tokens(text, stop)
+
+ yield LLMResultChunk(
+ model=block_result.model,
+ prompt_messages=prompt_messages,
+ system_fingerprint=block_result.system_fingerprint,
+ delta=LLMResultChunkDelta(
+ index=0,
+ message=AssistantPromptMessage(content=text),
+ finish_reason="stop",
+ usage=block_result.usage,
+ ),
)
- if stream:
- return self._handle_chat_generate_stream_response(model, credentials, response, prompt_messages, tools)
+ def _clear_illegal_prompt_messages(self, model: str, prompt_messages: list[PromptMessage]) -> list[PromptMessage]:
+ """
+ Clear illegal prompt messages for OpenAI API
- return self._handle_chat_generate_response(model, credentials, response, prompt_messages, tools)
+ :param model: model name
+ :param prompt_messages: prompt messages
+ :return: cleaned prompt messages
+ """
+ checklist = ["gpt-4-turbo", "gpt-4-turbo-2024-04-09"]
+
+ if model in checklist:
+ # count how many user messages are there
+ user_message_count = len([m for m in prompt_messages if isinstance(m, UserPromptMessage)])
+ if user_message_count > 1:
+ for prompt_message in prompt_messages:
+ if isinstance(prompt_message, UserPromptMessage):
+ if isinstance(prompt_message.content, list):
+ prompt_message.content = "\n".join(
+ [
+ item.data
+ if item.type == PromptMessageContentType.TEXT
+ else "[IMAGE]"
+ if item.type == PromptMessageContentType.IMAGE
+ else ""
+ for item in prompt_message.content
+ ]
+ )
+
+ if model.startswith("o1"):
+ system_message_count = len([m for m in prompt_messages if isinstance(m, SystemPromptMessage)])
+ if system_message_count > 0:
+ new_prompt_messages = []
+ for prompt_message in prompt_messages:
+ if isinstance(prompt_message, SystemPromptMessage):
+ prompt_message = UserPromptMessage(
+ content=prompt_message.content,
+ name=prompt_message.name,
+ )
+
+ new_prompt_messages.append(prompt_message)
+ prompt_messages = new_prompt_messages
+
+ return prompt_messages
def _handle_chat_generate_response(
self,
@@ -560,7 +658,7 @@ class AzureOpenAILargeLanguageModel(_CommonAzureOpenAI, LargeLanguageModel):
tokens_per_message = 4
# if there's a name, the role is omitted
tokens_per_name = -1
- elif model.startswith("gpt-35-turbo") or model.startswith("gpt-4"):
+ elif model.startswith("gpt-35-turbo") or model.startswith("gpt-4") or model.startswith("o1"):
tokens_per_message = 3
tokens_per_name = 1
else:
diff --git a/api/core/model_runtime/model_providers/bedrock/bedrock.yaml b/api/core/model_runtime/model_providers/bedrock/bedrock.yaml
index c540ee23b3..952f968b9d 100644
--- a/api/core/model_runtime/model_providers/bedrock/bedrock.yaml
+++ b/api/core/model_runtime/model_providers/bedrock/bedrock.yaml
@@ -50,34 +50,62 @@ provider_credential_schema:
label:
en_US: US East (N. Virginia)
zh_Hans: 美国东部 (弗吉尼亚北部)
+ - value: us-east-2
+ label:
+ en_US: US East (Ohio)
+ zh_Hans: 美国东部 (弗吉尼亚北部)
- value: us-west-2
label:
en_US: US West (Oregon)
zh_Hans: 美国西部 (俄勒冈州)
+ - value: ap-south-1
+ label:
+ en_US: Asia Pacific (Mumbai)
+ zh_Hans: 亚太地区(孟买)
- value: ap-southeast-1
label:
en_US: Asia Pacific (Singapore)
zh_Hans: 亚太地区 (新加坡)
- - value: ap-northeast-1
- label:
- en_US: Asia Pacific (Tokyo)
- zh_Hans: 亚太地区 (东京)
- - value: eu-central-1
- label:
- en_US: Europe (Frankfurt)
- zh_Hans: 欧洲 (法兰克福)
- - value: eu-west-2
- label:
- en_US: Eu west London (London)
- zh_Hans: 欧洲西部 (伦敦)
- - value: us-gov-west-1
- label:
- en_US: AWS GovCloud (US-West)
- zh_Hans: AWS GovCloud (US-West)
- value: ap-southeast-2
label:
en_US: Asia Pacific (Sydney)
zh_Hans: 亚太地区 (悉尼)
+ - value: ap-northeast-1
+ label:
+ en_US: Asia Pacific (Tokyo)
+ zh_Hans: 亚太地区 (东京)
+ - value: ap-northeast-2
+ label:
+ en_US: Asia Pacific (Seoul)
+ zh_Hans: 亚太地区(首尔)
+ - value: ca-central-1
+ label:
+ en_US: Canada (Central)
+ zh_Hans: 加拿大(中部)
+ - value: eu-central-1
+ label:
+ en_US: Europe (Frankfurt)
+ zh_Hans: 欧洲 (法兰克福)
+ - value: eu-west-1
+ label:
+ en_US: Europe (Ireland)
+ zh_Hans: 欧洲(爱尔兰)
+ - value: eu-west-2
+ label:
+ en_US: Europe (London)
+ zh_Hans: 欧洲西部 (伦敦)
+ - value: eu-west-3
+ label:
+ en_US: Europe (Paris)
+ zh_Hans: 欧洲(巴黎)
+ - value: sa-east-1
+ label:
+ en_US: South America (São Paulo)
+ zh_Hans: 南美洲(圣保罗)
+ - value: us-gov-west-1
+ label:
+ en_US: AWS GovCloud (US-West)
+ zh_Hans: AWS GovCloud (US-West)
- variable: model_for_validation
required: false
label:
diff --git a/api/core/model_runtime/model_providers/bedrock/llm/llm.py b/api/core/model_runtime/model_providers/bedrock/llm/llm.py
index d1961784f2..ff0403ee47 100644
--- a/api/core/model_runtime/model_providers/bedrock/llm/llm.py
+++ b/api/core/model_runtime/model_providers/bedrock/llm/llm.py
@@ -92,7 +92,7 @@ class BedrockLargeLanguageModel(LargeLanguageModel):
stop: Optional[list[str]] = None,
stream: bool = True,
user: Optional[str] = None,
- callbacks: list[Callback] = None,
+ callbacks: Optional[list[Callback]] = None,
) -> Union[LLMResult, Generator]:
"""
Code block mode wrapper for invoking large language model
diff --git a/api/core/model_runtime/model_providers/fireworks/llm/llm.py b/api/core/model_runtime/model_providers/fireworks/llm/llm.py
index 2dcf1adba6..24aad9c4d3 100644
--- a/api/core/model_runtime/model_providers/fireworks/llm/llm.py
+++ b/api/core/model_runtime/model_providers/fireworks/llm/llm.py
@@ -511,7 +511,7 @@ class FireworksLargeLanguageModel(_CommonFireworks, LargeLanguageModel):
model: str,
messages: list[PromptMessage],
tools: Optional[list[PromptMessageTool]] = None,
- credentials: dict = None,
+ credentials: Optional[dict] = None,
) -> int:
"""
Approximate num tokens with GPT2 tokenizer.
diff --git a/api/core/model_runtime/model_providers/google/llm/_position.yaml b/api/core/model_runtime/model_providers/google/llm/_position.yaml
new file mode 100644
index 0000000000..63b9ca3a29
--- /dev/null
+++ b/api/core/model_runtime/model_providers/google/llm/_position.yaml
@@ -0,0 +1,15 @@
+- gemini-1.5-pro
+- gemini-1.5-pro-latest
+- gemini-1.5-pro-001
+- gemini-1.5-pro-002
+- gemini-1.5-pro-exp-0801
+- gemini-1.5-pro-exp-0827
+- gemini-1.5-flash
+- gemini-1.5-flash-latest
+- gemini-1.5-flash-001
+- gemini-1.5-flash-002
+- gemini-1.5-flash-exp-0827
+- gemini-1.5-flash-8b-exp-0827
+- gemini-1.5-flash-8b-exp-0924
+- gemini-pro
+- gemini-pro-vision
diff --git a/api/core/model_runtime/model_providers/groq/llm/_position.yaml b/api/core/model_runtime/model_providers/groq/llm/_position.yaml
index be115ca920..0613b19f87 100644
--- a/api/core/model_runtime/model_providers/groq/llm/_position.yaml
+++ b/api/core/model_runtime/model_providers/groq/llm/_position.yaml
@@ -5,3 +5,4 @@
- llama3-8b-8192
- mixtral-8x7b-32768
- llama2-70b-4096
+- llama-guard-3-8b
diff --git a/api/core/model_runtime/model_providers/groq/llm/llama-guard-3-8b.yaml b/api/core/model_runtime/model_providers/groq/llm/llama-guard-3-8b.yaml
new file mode 100644
index 0000000000..03779ccc66
--- /dev/null
+++ b/api/core/model_runtime/model_providers/groq/llm/llama-guard-3-8b.yaml
@@ -0,0 +1,25 @@
+model: llama-guard-3-8b
+label:
+ zh_Hans: Llama-Guard-3-8B
+ en_US: Llama-Guard-3-8B
+model_type: llm
+features:
+ - agent-thought
+model_properties:
+ mode: chat
+ context_size: 8192
+parameter_rules:
+ - name: temperature
+ use_template: temperature
+ - name: top_p
+ use_template: top_p
+ - name: max_tokens
+ use_template: max_tokens
+ default: 512
+ min: 1
+ max: 8192
+pricing:
+ input: '0.20'
+ output: '0.20'
+ unit: '0.000001'
+ currency: USD
diff --git a/api/core/model_runtime/model_providers/openai/llm/llm.py b/api/core/model_runtime/model_providers/openai/llm/llm.py
index d42fce528a..1ac3837ad3 100644
--- a/api/core/model_runtime/model_providers/openai/llm/llm.py
+++ b/api/core/model_runtime/model_providers/openai/llm/llm.py
@@ -111,7 +111,7 @@ class OpenAILargeLanguageModel(_CommonOpenAI, LargeLanguageModel):
stop: Optional[list[str]] = None,
stream: bool = True,
user: Optional[str] = None,
- callbacks: list[Callback] = None,
+ callbacks: Optional[list[Callback]] = None,
) -> Union[LLMResult, Generator]:
"""
Code block mode wrapper for invoking large language model
diff --git a/api/core/model_runtime/model_providers/openai/speech2text/speech2text.py b/api/core/model_runtime/model_providers/openai/speech2text/speech2text.py
index 18f97e45f3..0d54d2ea9a 100644
--- a/api/core/model_runtime/model_providers/openai/speech2text/speech2text.py
+++ b/api/core/model_runtime/model_providers/openai/speech2text/speech2text.py
@@ -2,6 +2,8 @@ from typing import IO, Optional
from openai import OpenAI
+from core.model_runtime.entities.common_entities import I18nObject
+from core.model_runtime.entities.model_entities import AIModelEntity, FetchFrom, ModelType
from core.model_runtime.errors.validate import CredentialsValidateFailedError
from core.model_runtime.model_providers.__base.speech2text_model import Speech2TextModel
from core.model_runtime.model_providers.openai._common import _CommonOpenAI
@@ -58,3 +60,18 @@ class OpenAISpeech2TextModel(_CommonOpenAI, Speech2TextModel):
response = client.audio.transcriptions.create(model=model, file=file)
return response.text
+
+ def get_customizable_model_schema(self, model: str, credentials: dict) -> AIModelEntity | None:
+ """
+ used to define customizable model schema
+ """
+ entity = AIModelEntity(
+ model=model,
+ label=I18nObject(en_US=model),
+ fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
+ model_type=ModelType.SPEECH2TEXT,
+ model_properties={},
+ parameter_rules=[],
+ )
+
+ return entity
diff --git a/api/core/model_runtime/model_providers/openai_api_compatible/llm/llm.py b/api/core/model_runtime/model_providers/openai_api_compatible/llm/llm.py
index c2ffe653c8..356ac56b1e 100644
--- a/api/core/model_runtime/model_providers/openai_api_compatible/llm/llm.py
+++ b/api/core/model_runtime/model_providers/openai_api_compatible/llm/llm.py
@@ -688,7 +688,7 @@ class OAIAPICompatLargeLanguageModel(_CommonOaiApiCompat, LargeLanguageModel):
model: str,
messages: list[PromptMessage],
tools: Optional[list[PromptMessageTool]] = None,
- credentials: dict = None,
+ credentials: Optional[dict] = None,
) -> int:
"""
Approximate num tokens with GPT2 tokenizer.
diff --git a/api/core/model_runtime/model_providers/openai_api_compatible/speech2text/speech2text.py b/api/core/model_runtime/model_providers/openai_api_compatible/speech2text/speech2text.py
index 405096578c..cef77cc941 100644
--- a/api/core/model_runtime/model_providers/openai_api_compatible/speech2text/speech2text.py
+++ b/api/core/model_runtime/model_providers/openai_api_compatible/speech2text/speech2text.py
@@ -3,6 +3,8 @@ from urllib.parse import urljoin
import requests
+from core.model_runtime.entities.common_entities import I18nObject
+from core.model_runtime.entities.model_entities import AIModelEntity, FetchFrom, ModelType
from core.model_runtime.errors.invoke import InvokeBadRequestError
from core.model_runtime.errors.validate import CredentialsValidateFailedError
from core.model_runtime.model_providers.__base.speech2text_model import Speech2TextModel
@@ -59,3 +61,18 @@ class OAICompatSpeech2TextModel(_CommonOaiApiCompat, Speech2TextModel):
self._invoke(model, credentials, audio_file)
except Exception as ex:
raise CredentialsValidateFailedError(str(ex))
+
+ def get_customizable_model_schema(self, model: str, credentials: dict) -> AIModelEntity | None:
+ """
+ used to define customizable model schema
+ """
+ entity = AIModelEntity(
+ model=model,
+ label=I18nObject(en_US=model),
+ fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
+ model_type=ModelType.SPEECH2TEXT,
+ model_properties={},
+ parameter_rules=[],
+ )
+
+ return entity
diff --git a/api/core/model_runtime/model_providers/openrouter/llm/_position.yaml b/api/core/model_runtime/model_providers/openrouter/llm/_position.yaml
index d9497b76b8..5a25c84c34 100644
--- a/api/core/model_runtime/model_providers/openrouter/llm/_position.yaml
+++ b/api/core/model_runtime/model_providers/openrouter/llm/_position.yaml
@@ -14,6 +14,10 @@
- google/gemini-pro
- cohere/command-r-plus
- cohere/command-r
+- meta-llama/llama-3.2-1b-instruct
+- meta-llama/llama-3.2-3b-instruct
+- meta-llama/llama-3.2-11b-vision-instruct
+- meta-llama/llama-3.2-90b-vision-instruct
- meta-llama/llama-3.1-405b-instruct
- meta-llama/llama-3.1-70b-instruct
- meta-llama/llama-3.1-8b-instruct
@@ -22,6 +26,7 @@
- mistralai/mixtral-8x22b-instruct
- mistralai/mixtral-8x7b-instruct
- mistralai/mistral-7b-instruct
+- qwen/qwen-2.5-72b-instruct
- qwen/qwen-2-72b-instruct
- deepseek/deepseek-chat
- deepseek/deepseek-coder
diff --git a/api/core/model_runtime/model_providers/openrouter/llm/claude-3-5-sonnet.yaml b/api/core/model_runtime/model_providers/openrouter/llm/claude-3-5-sonnet.yaml
index 40558854e2..e829048e55 100644
--- a/api/core/model_runtime/model_providers/openrouter/llm/claude-3-5-sonnet.yaml
+++ b/api/core/model_runtime/model_providers/openrouter/llm/claude-3-5-sonnet.yaml
@@ -27,9 +27,9 @@ parameter_rules:
- name: max_tokens
use_template: max_tokens
required: true
- default: 4096
+ default: 8192
min: 1
- max: 4096
+ max: 8192
- name: response_format
use_template: response_format
pricing:
diff --git a/api/core/model_runtime/model_providers/openrouter/llm/llama-3.2-11b-vision-instruct.yaml b/api/core/model_runtime/model_providers/openrouter/llm/llama-3.2-11b-vision-instruct.yaml
new file mode 100644
index 0000000000..235156997f
--- /dev/null
+++ b/api/core/model_runtime/model_providers/openrouter/llm/llama-3.2-11b-vision-instruct.yaml
@@ -0,0 +1,45 @@
+model: meta-llama/llama-3.2-11b-vision-instruct
+label:
+ zh_Hans: llama-3.2-11b-vision-instruct
+ en_US: llama-3.2-11b-vision-instruct
+model_type: llm
+features:
+ - agent-thought
+model_properties:
+ mode: chat
+ context_size: 131072
+parameter_rules:
+ - name: temperature
+ use_template: temperature
+ - name: top_p
+ use_template: top_p
+ - name: top_k
+ label:
+ zh_Hans: 取样数量
+ en_US: Top k
+ type: int
+ help:
+ zh_Hans: 仅从每个后续标记的前 K 个选项中采样。
+ en_US: Only sample from the top K options for each subsequent token.
+ - name: max_tokens
+ use_template: max_tokens
+ - name: context_length_exceeded_behavior
+ default: None
+ label:
+ zh_Hans: 上下文长度超出行为
+ en_US: Context Length Exceeded Behavior
+ help:
+ zh_Hans: 上下文长度超出行为
+ en_US: Context Length Exceeded Behavior
+ type: string
+ options:
+ - None
+ - truncate
+ - error
+ - name: response_format
+ use_template: response_format
+pricing:
+ input: '0.055'
+ output: '0.055'
+ unit: '0.000001'
+ currency: USD
diff --git a/api/core/model_runtime/model_providers/openrouter/llm/llama-3.2-1b-instruct.yaml b/api/core/model_runtime/model_providers/openrouter/llm/llama-3.2-1b-instruct.yaml
new file mode 100644
index 0000000000..657ef16835
--- /dev/null
+++ b/api/core/model_runtime/model_providers/openrouter/llm/llama-3.2-1b-instruct.yaml
@@ -0,0 +1,45 @@
+model: meta-llama/llama-3.2-1b-instruct
+label:
+ zh_Hans: llama-3.2-1b-instruct
+ en_US: llama-3.2-1b-instruct
+model_type: llm
+features:
+ - agent-thought
+model_properties:
+ mode: chat
+ context_size: 131072
+parameter_rules:
+ - name: temperature
+ use_template: temperature
+ - name: top_p
+ use_template: top_p
+ - name: top_k
+ label:
+ zh_Hans: 取样数量
+ en_US: Top k
+ type: int
+ help:
+ zh_Hans: 仅从每个后续标记的前 K 个选项中采样。
+ en_US: Only sample from the top K options for each subsequent token.
+ - name: max_tokens
+ use_template: max_tokens
+ - name: context_length_exceeded_behavior
+ default: None
+ label:
+ zh_Hans: 上下文长度超出行为
+ en_US: Context Length Exceeded Behavior
+ help:
+ zh_Hans: 上下文长度超出行为
+ en_US: Context Length Exceeded Behavior
+ type: string
+ options:
+ - None
+ - truncate
+ - error
+ - name: response_format
+ use_template: response_format
+pricing:
+ input: '0.01'
+ output: '0.02'
+ unit: '0.000001'
+ currency: USD
diff --git a/api/core/model_runtime/model_providers/openrouter/llm/llama-3.2-3b-instruct.yaml b/api/core/model_runtime/model_providers/openrouter/llm/llama-3.2-3b-instruct.yaml
new file mode 100644
index 0000000000..7f6e24e591
--- /dev/null
+++ b/api/core/model_runtime/model_providers/openrouter/llm/llama-3.2-3b-instruct.yaml
@@ -0,0 +1,45 @@
+model: meta-llama/llama-3.2-3b-instruct
+label:
+ zh_Hans: llama-3.2-3b-instruct
+ en_US: llama-3.2-3b-instruct
+model_type: llm
+features:
+ - agent-thought
+model_properties:
+ mode: chat
+ context_size: 131072
+parameter_rules:
+ - name: temperature
+ use_template: temperature
+ - name: top_p
+ use_template: top_p
+ - name: top_k
+ label:
+ zh_Hans: 取样数量
+ en_US: Top k
+ type: int
+ help:
+ zh_Hans: 仅从每个后续标记的前 K 个选项中采样。
+ en_US: Only sample from the top K options for each subsequent token.
+ - name: max_tokens
+ use_template: max_tokens
+ - name: context_length_exceeded_behavior
+ default: None
+ label:
+ zh_Hans: 上下文长度超出行为
+ en_US: Context Length Exceeded Behavior
+ help:
+ zh_Hans: 上下文长度超出行为
+ en_US: Context Length Exceeded Behavior
+ type: string
+ options:
+ - None
+ - truncate
+ - error
+ - name: response_format
+ use_template: response_format
+pricing:
+ input: '0.03'
+ output: '0.05'
+ unit: '0.000001'
+ currency: USD
diff --git a/api/core/model_runtime/model_providers/openrouter/llm/llama-3.2-90b-vision-instruct.yaml b/api/core/model_runtime/model_providers/openrouter/llm/llama-3.2-90b-vision-instruct.yaml
new file mode 100644
index 0000000000..5d597f00a2
--- /dev/null
+++ b/api/core/model_runtime/model_providers/openrouter/llm/llama-3.2-90b-vision-instruct.yaml
@@ -0,0 +1,45 @@
+model: meta-llama/llama-3.2-90b-vision-instruct
+label:
+ zh_Hans: llama-3.2-90b-vision-instruct
+ en_US: llama-3.2-90b-vision-instruct
+model_type: llm
+features:
+ - agent-thought
+model_properties:
+ mode: chat
+ context_size: 131072
+parameter_rules:
+ - name: temperature
+ use_template: temperature
+ - name: top_p
+ use_template: top_p
+ - name: top_k
+ label:
+ zh_Hans: 取样数量
+ en_US: Top k
+ type: int
+ help:
+ zh_Hans: 仅从每个后续标记的前 K 个选项中采样。
+ en_US: Only sample from the top K options for each subsequent token.
+ - name: max_tokens
+ use_template: max_tokens
+ - name: context_length_exceeded_behavior
+ default: None
+ label:
+ zh_Hans: 上下文长度超出行为
+ en_US: Context Length Exceeded Behavior
+ help:
+ zh_Hans: 上下文长度超出行为
+ en_US: Context Length Exceeded Behavior
+ type: string
+ options:
+ - None
+ - truncate
+ - error
+ - name: response_format
+ use_template: response_format
+pricing:
+ input: '0.35'
+ output: '0.4'
+ unit: '0.000001'
+ currency: USD
diff --git a/api/core/model_runtime/model_providers/openrouter/llm/qwen2.5-72b-instruct.yaml b/api/core/model_runtime/model_providers/openrouter/llm/qwen2.5-72b-instruct.yaml
new file mode 100644
index 0000000000..f141a40a00
--- /dev/null
+++ b/api/core/model_runtime/model_providers/openrouter/llm/qwen2.5-72b-instruct.yaml
@@ -0,0 +1,30 @@
+model: qwen/qwen-2.5-72b-instruct
+label:
+ en_US: qwen-2.5-72b-instruct
+model_type: llm
+features:
+ - agent-thought
+model_properties:
+ mode: chat
+ context_size: 131072
+parameter_rules:
+ - name: temperature
+ use_template: temperature
+ - name: max_tokens
+ use_template: max_tokens
+ type: int
+ default: 512
+ min: 1
+ max: 8192
+ help:
+ zh_Hans: 指定生成结果长度的上限。如果生成结果截断,可以调大该参数。
+ en_US: Specifies the upper limit on the length of generated results. If the generated results are truncated, you can increase this parameter.
+ - name: top_p
+ use_template: top_p
+ - name: frequency_penalty
+ use_template: frequency_penalty
+pricing:
+ input: "0.35"
+ output: "0.4"
+ unit: "0.000001"
+ currency: USD
diff --git a/api/core/model_runtime/model_providers/sagemaker/tts/tts.py b/api/core/model_runtime/model_providers/sagemaker/tts/tts.py
index a22bd6dd6e..9652e1d650 100644
--- a/api/core/model_runtime/model_providers/sagemaker/tts/tts.py
+++ b/api/core/model_runtime/model_providers/sagemaker/tts/tts.py
@@ -77,7 +77,7 @@ class SageMakerText2SpeechModel(TTSModel):
"""
pass
- def _detect_lang_code(self, content: str, map_dict: dict = None):
+ def _detect_lang_code(self, content: str, map_dict: Optional[dict] = None):
map_dict = {"zh": "<|zh|>", "en": "<|en|>", "ja": "<|jp|>", "zh-TW": "<|yue|>", "ko": "<|ko|>"}
response = self.comprehend_client.detect_dominant_language(Text=content)
diff --git a/api/core/model_runtime/model_providers/voyage/rerank/_position.yaml b/api/core/model_runtime/model_providers/voyage/rerank/_position.yaml
new file mode 100644
index 0000000000..32afefbe04
--- /dev/null
+++ b/api/core/model_runtime/model_providers/voyage/rerank/_position.yaml
@@ -0,0 +1,4 @@
+- rerank-2
+- rerank-lite-2
+- rerank-1
+- rerank-lite-1
diff --git a/api/core/model_runtime/model_providers/voyage/rerank/rerank-2.yaml b/api/core/model_runtime/model_providers/voyage/rerank/rerank-2.yaml
new file mode 100644
index 0000000000..b760d3c418
--- /dev/null
+++ b/api/core/model_runtime/model_providers/voyage/rerank/rerank-2.yaml
@@ -0,0 +1,4 @@
+model: rerank-2
+model_type: rerank
+model_properties:
+ context_size: 16000
diff --git a/api/core/model_runtime/model_providers/voyage/rerank/rerank-lite-2.yaml b/api/core/model_runtime/model_providers/voyage/rerank/rerank-lite-2.yaml
new file mode 100644
index 0000000000..b6fa37a25b
--- /dev/null
+++ b/api/core/model_runtime/model_providers/voyage/rerank/rerank-lite-2.yaml
@@ -0,0 +1,4 @@
+model: rerank-lite-2
+model_type: rerank
+model_properties:
+ context_size: 8000
diff --git a/api/core/model_runtime/model_providers/voyage/text_embedding/_position.yaml b/api/core/model_runtime/model_providers/voyage/text_embedding/_position.yaml
new file mode 100644
index 0000000000..595663990f
--- /dev/null
+++ b/api/core/model_runtime/model_providers/voyage/text_embedding/_position.yaml
@@ -0,0 +1,6 @@
+- voyage-3
+- voyage-3-lite
+- voyage-finance-2
+- voyage-multilingual-2
+- voyage-law-2
+- voyage-code-2
diff --git a/api/core/model_runtime/model_providers/voyage/text_embedding/voyage-code-2.yaml b/api/core/model_runtime/model_providers/voyage/text_embedding/voyage-code-2.yaml
new file mode 100644
index 0000000000..693669c82c
--- /dev/null
+++ b/api/core/model_runtime/model_providers/voyage/text_embedding/voyage-code-2.yaml
@@ -0,0 +1,8 @@
+model: voyage-code-2
+model_type: text-embedding
+model_properties:
+ context_size: 16000
+pricing:
+ input: '0.00012'
+ unit: '0.001'
+ currency: USD
diff --git a/api/core/model_runtime/model_providers/voyage/text_embedding/voyage-finance-2.yaml b/api/core/model_runtime/model_providers/voyage/text_embedding/voyage-finance-2.yaml
new file mode 100644
index 0000000000..555e11002a
--- /dev/null
+++ b/api/core/model_runtime/model_providers/voyage/text_embedding/voyage-finance-2.yaml
@@ -0,0 +1,8 @@
+model: voyage-finance-2
+model_type: text-embedding
+model_properties:
+ context_size: 32000
+pricing:
+ input: '0.00012'
+ unit: '0.001'
+ currency: USD
diff --git a/api/core/model_runtime/model_providers/voyage/text_embedding/voyage-law-2.yaml b/api/core/model_runtime/model_providers/voyage/text_embedding/voyage-law-2.yaml
new file mode 100644
index 0000000000..032693286f
--- /dev/null
+++ b/api/core/model_runtime/model_providers/voyage/text_embedding/voyage-law-2.yaml
@@ -0,0 +1,8 @@
+model: voyage-law-2
+model_type: text-embedding
+model_properties:
+ context_size: 16000
+pricing:
+ input: '0.00012'
+ unit: '0.001'
+ currency: USD
diff --git a/api/core/model_runtime/model_providers/voyage/text_embedding/voyage-multilingual-2.yaml b/api/core/model_runtime/model_providers/voyage/text_embedding/voyage-multilingual-2.yaml
new file mode 100644
index 0000000000..9ecf4d5009
--- /dev/null
+++ b/api/core/model_runtime/model_providers/voyage/text_embedding/voyage-multilingual-2.yaml
@@ -0,0 +1,8 @@
+model: voyage-multilingual-2
+model_type: text-embedding
+model_properties:
+ context_size: 32000
+pricing:
+ input: '0.00012'
+ unit: '0.001'
+ currency: USD
diff --git a/api/core/model_runtime/model_providers/wenxin/llm/llm.py b/api/core/model_runtime/model_providers/wenxin/llm/llm.py
index f7c160b6b4..952cbb33f4 100644
--- a/api/core/model_runtime/model_providers/wenxin/llm/llm.py
+++ b/api/core/model_runtime/model_providers/wenxin/llm/llm.py
@@ -64,7 +64,7 @@ class ErnieBotLargeLanguageModel(LargeLanguageModel):
stop: Optional[list[str]] = None,
stream: bool = True,
user: Optional[str] = None,
- callbacks: list[Callback] = None,
+ callbacks: Optional[list[Callback]] = None,
) -> Union[LLMResult, Generator]:
"""
Code block mode wrapper for invoking large language model
diff --git a/api/core/model_runtime/model_providers/zhipuai/llm/llm.py b/api/core/model_runtime/model_providers/zhipuai/llm/llm.py
index ea331701ab..e0c4980523 100644
--- a/api/core/model_runtime/model_providers/zhipuai/llm/llm.py
+++ b/api/core/model_runtime/model_providers/zhipuai/llm/llm.py
@@ -223,6 +223,16 @@ class ZhipuAILargeLanguageModel(_CommonZhipuaiAI, LargeLanguageModel):
else:
new_prompt_messages.append(copy_prompt_message)
+ # zhipuai moved web_search param to tools
+ if "web_search" in model_parameters:
+ enable_web_search = model_parameters.get("web_search")
+ model_parameters.pop("web_search")
+ web_search_params = {"type": "web_search", "web_search": {"enable": enable_web_search}}
+ if "tools" in model_parameters:
+ model_parameters["tools"].append(web_search_params)
+ else:
+ model_parameters["tools"] = [web_search_params]
+
if model in {"glm-4v", "glm-4v-plus"}:
params = self._construct_glm_4v_parameter(model, new_prompt_messages, model_parameters)
else:
diff --git a/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/api_resource/assistant/assistant.py b/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/api_resource/assistant/assistant.py
index f772340a82..c29b057498 100644
--- a/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/api_resource/assistant/assistant.py
+++ b/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/api_resource/assistant/assistant.py
@@ -41,8 +41,8 @@ class Assistant(BaseAPI):
conversation_id: Optional[str] = None,
attachments: Optional[list[assistant_create_params.AssistantAttachments]] = None,
metadata: dict | None = None,
- request_id: str = None,
- user_id: str = None,
+ request_id: Optional[str] = None,
+ user_id: Optional[str] = None,
extra_headers: Headers | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
@@ -72,9 +72,9 @@ class Assistant(BaseAPI):
def query_support(
self,
*,
- assistant_id_list: list[str] = None,
- request_id: str = None,
- user_id: str = None,
+ assistant_id_list: Optional[list[str]] = None,
+ request_id: Optional[str] = None,
+ user_id: Optional[str] = None,
extra_headers: Headers | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
@@ -99,8 +99,8 @@ class Assistant(BaseAPI):
page: int = 1,
page_size: int = 10,
*,
- request_id: str = None,
- user_id: str = None,
+ request_id: Optional[str] = None,
+ user_id: Optional[str] = None,
extra_headers: Headers | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
diff --git a/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/api_resource/files.py b/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/api_resource/files.py
index ba9de75b7e..c723f6f66e 100644
--- a/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/api_resource/files.py
+++ b/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/api_resource/files.py
@@ -1,7 +1,7 @@
from __future__ import annotations
from collections.abc import Mapping
-from typing import TYPE_CHECKING, Literal, cast
+from typing import TYPE_CHECKING, Literal, Optional, cast
import httpx
@@ -34,11 +34,11 @@ class Files(BaseAPI):
def create(
self,
*,
- file: FileTypes = None,
- upload_detail: list[UploadDetail] = None,
+ file: Optional[FileTypes] = None,
+ upload_detail: Optional[list[UploadDetail]] = None,
purpose: Literal["fine-tune", "retrieval", "batch"],
- knowledge_id: str = None,
- sentence_size: int = None,
+ knowledge_id: Optional[str] = None,
+ sentence_size: Optional[int] = None,
extra_headers: Headers | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
diff --git a/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/api_resource/knowledge/document/document.py b/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/api_resource/knowledge/document/document.py
index 2c4066d893..492c49da66 100644
--- a/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/api_resource/knowledge/document/document.py
+++ b/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/api_resource/knowledge/document/document.py
@@ -34,12 +34,12 @@ class Document(BaseAPI):
def create(
self,
*,
- file: FileTypes = None,
+ file: Optional[FileTypes] = None,
custom_separator: Optional[list[str]] = None,
- upload_detail: list[UploadDetail] = None,
+ upload_detail: Optional[list[UploadDetail]] = None,
purpose: Literal["retrieval"],
- knowledge_id: str = None,
- sentence_size: int = None,
+ knowledge_id: Optional[str] = None,
+ sentence_size: Optional[int] = None,
extra_headers: Headers | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
diff --git a/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/api_resource/videos/videos.py b/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/api_resource/videos/videos.py
index f1f1c08036..71c8316602 100644
--- a/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/api_resource/videos/videos.py
+++ b/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/api_resource/videos/videos.py
@@ -31,11 +31,11 @@ class Videos(BaseAPI):
self,
model: str,
*,
- prompt: str = None,
- image_url: str = None,
+ prompt: Optional[str] = None,
+ image_url: Optional[str] = None,
sensitive_word_check: Optional[SensitiveWordCheckRequest] | NotGiven = NOT_GIVEN,
- request_id: str = None,
- user_id: str = None,
+ request_id: Optional[str] = None,
+ user_id: Optional[str] = None,
extra_headers: Headers | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
diff --git a/api/core/ops/langfuse_trace/langfuse_trace.py b/api/core/ops/langfuse_trace/langfuse_trace.py
index 6aefbec9aa..171e34f8cb 100644
--- a/api/core/ops/langfuse_trace/langfuse_trace.py
+++ b/api/core/ops/langfuse_trace/langfuse_trace.py
@@ -159,6 +159,16 @@ class LangFuseDataTrace(BaseTraceInstance):
"status": status,
}
)
+ process_data = json.loads(node_execution.process_data) if node_execution.process_data else {}
+ model_provider = process_data.get("model_provider", None)
+ model_name = process_data.get("model_name", None)
+ if model_provider is not None and model_name is not None:
+ metadata.update(
+ {
+ "model_provider": model_provider,
+ "model_name": model_name,
+ }
+ )
# add span
if trace_info.message_id:
@@ -191,7 +201,6 @@ class LangFuseDataTrace(BaseTraceInstance):
self.add_span(langfuse_span_data=span_data)
- process_data = json.loads(node_execution.process_data) if node_execution.process_data else {}
if process_data and process_data.get("model_mode") == "chat":
total_token = metadata.get("total_tokens", 0)
# add generation
diff --git a/api/core/rag/datasource/vdb/relyt/relyt_vector.py b/api/core/rag/datasource/vdb/relyt/relyt_vector.py
index f47f75718a..254956970f 100644
--- a/api/core/rag/datasource/vdb/relyt/relyt_vector.py
+++ b/api/core/rag/datasource/vdb/relyt/relyt_vector.py
@@ -162,7 +162,7 @@ class RelytVector(BaseVector):
else:
return None
- def delete_by_uuids(self, ids: list[str] = None):
+ def delete_by_uuids(self, ids: Optional[list[str]] = None):
"""Delete by vector IDs.
Args:
diff --git a/api/core/rag/datasource/vdb/vector_factory.py b/api/core/rag/datasource/vdb/vector_factory.py
index ca90233b7f..943b23870c 100644
--- a/api/core/rag/datasource/vdb/vector_factory.py
+++ b/api/core/rag/datasource/vdb/vector_factory.py
@@ -1,5 +1,5 @@
from abc import ABC, abstractmethod
-from typing import Any
+from typing import Any, Optional
from configs import dify_config
from core.embedding.cached_embedding import CacheEmbedding
@@ -25,7 +25,7 @@ class AbstractVectorFactory(ABC):
class Vector:
- def __init__(self, dataset: Dataset, attributes: list = None):
+ def __init__(self, dataset: Dataset, attributes: Optional[list] = None):
if attributes is None:
attributes = ["doc_id", "dataset_id", "document_id", "doc_hash"]
self._dataset = dataset
@@ -106,7 +106,7 @@ class Vector:
case _:
raise ValueError(f"Vector store {vector_type} is not supported.")
- def create(self, texts: list = None, **kwargs):
+ def create(self, texts: Optional[list] = None, **kwargs):
if texts:
embeddings = self._embeddings.embed_documents([document.page_content for document in texts])
self._vector_processor.create(texts=texts, embeddings=embeddings, **kwargs)
diff --git a/api/core/rag/extractor/extract_processor.py b/api/core/rag/extractor/extract_processor.py
index 9048138511..706a42b735 100644
--- a/api/core/rag/extractor/extract_processor.py
+++ b/api/core/rag/extractor/extract_processor.py
@@ -1,7 +1,7 @@
import re
import tempfile
from pathlib import Path
-from typing import Union
+from typing import Optional, Union
from urllib.parse import unquote
from configs import dify_config
@@ -84,7 +84,7 @@ class ExtractProcessor:
@classmethod
def extract(
- cls, extract_setting: ExtractSetting, is_automatic: bool = False, file_path: str = None
+ cls, extract_setting: ExtractSetting, is_automatic: bool = False, file_path: Optional[str] = None
) -> list[Document]:
if extract_setting.datasource_type == DatasourceType.FILE.value:
with tempfile.TemporaryDirectory() as temp_dir:
diff --git a/api/core/rag/extractor/unstructured/unstructured_epub_extractor.py b/api/core/rag/extractor/unstructured/unstructured_epub_extractor.py
index fa50fa76b2..a41ed3a558 100644
--- a/api/core/rag/extractor/unstructured/unstructured_epub_extractor.py
+++ b/api/core/rag/extractor/unstructured/unstructured_epub_extractor.py
@@ -1,4 +1,5 @@
import logging
+from typing import Optional
from core.rag.extractor.extractor_base import BaseExtractor
from core.rag.models.document import Document
@@ -17,7 +18,7 @@ class UnstructuredEpubExtractor(BaseExtractor):
def __init__(
self,
file_path: str,
- api_url: str = None,
+ api_url: Optional[str] = None,
):
"""Initialize with file path."""
self._file_path = file_path
diff --git a/api/core/tools/entities/tool_entities.py b/api/core/tools/entities/tool_entities.py
index 02b8b35be7..9962b559fa 100644
--- a/api/core/tools/entities/tool_entities.py
+++ b/api/core/tools/entities/tool_entities.py
@@ -341,7 +341,7 @@ class ToolRuntimeVariablePool(BaseModel):
self.pool.append(variable)
- def set_file(self, tool_name: str, value: str, name: str = None) -> None:
+ def set_file(self, tool_name: str, value: str, name: Optional[str] = None) -> None:
"""
set an image variable
diff --git a/api/core/tools/provider/_position.yaml b/api/core/tools/provider/_position.yaml
index e0a8e7511e..6bab9a09d8 100644
--- a/api/core/tools/provider/_position.yaml
+++ b/api/core/tools/provider/_position.yaml
@@ -5,31 +5,41 @@
- searchapi
- serper
- searxng
+- websearch
+- tavily
+- stackexchange
+- pubmed
+- arxiv
+- aws
+- nominatim
+- devdocs
+- spider
+- firecrawl
+- brave
+- crossref
+- jina
+- webscraper
- dalle
- azuredalle
- stability
-- wikipedia
-- nominatim
-- yahoo
-- alphavantage
-- arxiv
-- pubmed
- stablediffusion
-- webscraper
-- jina
-- aippt
-- youtube
-- code
-- wolframalpha
-- maths
-- github
-- chart
-- time
-- vectorizer
+- cogview
+- comfyui
+- getimgai
+- siliconflow
+- spark
+- stepfun
+- xinference
+- alphavantage
+- yahoo
+- openweather
- gaode
-- wecom
-- qrcode
+- aippt
+- chart
+- youtube
+- did
- dingtalk
+- discord
- feishu
- feishu_base
- feishu_document
@@ -39,4 +49,24 @@
- feishu_calendar
- feishu_spreadsheet
- slack
+- twilio
+- wecom
+- wikipedia
+- code
+- wolframalpha
+- maths
+- github
+- gitlab
+- time
+- vectorizer
+- qrcode
- tianditu
+- google_translate
+- hap
+- json_process
+- judge0ce
+- novitaai
+- onebot
+- regex
+- trello
+- vanna
diff --git a/api/core/tools/provider/builtin/aws/tools/sagemaker_tts.py b/api/core/tools/provider/builtin/aws/tools/sagemaker_tts.py
index bceeaab745..1fafe09b4d 100644
--- a/api/core/tools/provider/builtin/aws/tools/sagemaker_tts.py
+++ b/api/core/tools/provider/builtin/aws/tools/sagemaker_tts.py
@@ -1,6 +1,6 @@
import json
from enum import Enum
-from typing import Any, Union
+from typing import Any, Optional, Union
import boto3
@@ -21,7 +21,7 @@ class SageMakerTTSTool(BuiltinTool):
s3_client: Any = None
comprehend_client: Any = None
- def _detect_lang_code(self, content: str, map_dict: dict = None):
+ def _detect_lang_code(self, content: str, map_dict: Optional[dict] = None):
map_dict = {"zh": "<|zh|>", "en": "<|en|>", "ja": "<|jp|>", "zh-TW": "<|yue|>", "ko": "<|ko|>"}
response = self.comprehend_client.detect_dominant_language(Text=content)
diff --git a/api/core/tools/provider/builtin/discord/_assets/icon.svg b/api/core/tools/provider/builtin/discord/_assets/icon.svg
new file mode 100644
index 0000000000..177a0591f9
--- /dev/null
+++ b/api/core/tools/provider/builtin/discord/_assets/icon.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/api/core/tools/provider/builtin/discord/discord.py b/api/core/tools/provider/builtin/discord/discord.py
new file mode 100644
index 0000000000..c94824b591
--- /dev/null
+++ b/api/core/tools/provider/builtin/discord/discord.py
@@ -0,0 +1,9 @@
+from typing import Any
+
+from core.tools.provider.builtin.discord.tools.discord_webhook import DiscordWebhookTool
+from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController
+
+
+class DiscordProvider(BuiltinToolProviderController):
+ def _validate_credentials(self, credentials: dict[str, Any]) -> None:
+ DiscordWebhookTool()
diff --git a/api/core/tools/provider/builtin/discord/discord.yaml b/api/core/tools/provider/builtin/discord/discord.yaml
new file mode 100644
index 0000000000..18b249b522
--- /dev/null
+++ b/api/core/tools/provider/builtin/discord/discord.yaml
@@ -0,0 +1,16 @@
+identity:
+ author: Ice Yao
+ name: discord
+ label:
+ en_US: Discord
+ zh_Hans: Discord
+ pt_BR: Discord
+ description:
+ en_US: Discord Webhook
+ zh_Hans: Discord Webhook
+ pt_BR: Discord Webhook
+ icon: icon.svg
+ tags:
+ - social
+ - productivity
+credentials_for_provider:
diff --git a/api/core/tools/provider/builtin/discord/tools/discord_webhook.py b/api/core/tools/provider/builtin/discord/tools/discord_webhook.py
new file mode 100644
index 0000000000..7fdf791aba
--- /dev/null
+++ b/api/core/tools/provider/builtin/discord/tools/discord_webhook.py
@@ -0,0 +1,49 @@
+from typing import Any, Union
+
+import httpx
+
+from core.tools.entities.tool_entities import ToolInvokeMessage
+from core.tools.tool.builtin_tool import BuiltinTool
+
+
+class DiscordWebhookTool(BuiltinTool):
+ def _invoke(
+ self, user_id: str, tool_parameters: dict[str, Any]
+ ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
+ """
+ Incoming Webhooks
+ API Document:
+ https://discord.com/developers/docs/resources/webhook#execute-webhook
+ """
+
+ content = tool_parameters.get("content", "")
+ if not content:
+ return self.create_text_message("Invalid parameter content")
+
+ webhook_url = tool_parameters.get("webhook_url", "")
+
+ if not webhook_url.startswith("https://discord.com/api/webhooks/"):
+ return self.create_text_message(
+ f"Invalid parameter webhook_url ${webhook_url}, \
+ not a valid Discord webhook URL"
+ )
+
+ headers = {
+ "Content-Type": "application/json",
+ }
+ params = {}
+ payload = {
+ "content": content,
+ }
+
+ try:
+ res = httpx.post(webhook_url, headers=headers, params=params, json=payload)
+ if res.is_success:
+ return self.create_text_message("Text message was sent successfully")
+ else:
+ return self.create_text_message(
+ f"Failed to send the text message, \
+ status code: {res.status_code}, response: {res.text}"
+ )
+ except Exception as e:
+ return self.create_text_message("Failed to send message through webhook. {}".format(e))
diff --git a/api/core/tools/provider/builtin/discord/tools/discord_webhook.yaml b/api/core/tools/provider/builtin/discord/tools/discord_webhook.yaml
new file mode 100644
index 0000000000..bb3fa43f24
--- /dev/null
+++ b/api/core/tools/provider/builtin/discord/tools/discord_webhook.yaml
@@ -0,0 +1,40 @@
+identity:
+ name: discord_webhook
+ author: Ice Yao
+ label:
+ en_US: Incoming Webhook to send message
+ zh_Hans: 通过入站Webhook发送消息
+ pt_BR: Incoming Webhook to send message
+ icon: icon.svg
+description:
+ human:
+ en_US: Sending a message on Discord via the Incoming Webhook
+ zh_Hans: 通过入站Webhook在Discord上发送消息
+ pt_BR: Sending a message on Discord via the Incoming Webhook
+ llm: A tool for sending messages to a chat on Discord.
+parameters:
+ - name: webhook_url
+ type: string
+ required: true
+ label:
+ en_US: Discord Incoming Webhook url
+ zh_Hans: Discord入站Webhook的url
+ pt_BR: Discord Incoming Webhook url
+ human_description:
+ en_US: Discord Incoming Webhook url
+ zh_Hans: Discord入站Webhook的url
+ pt_BR: Discord Incoming Webhook url
+ form: form
+ - name: content
+ type: string
+ required: true
+ label:
+ en_US: content
+ zh_Hans: 消息内容
+ pt_BR: content
+ human_description:
+ en_US: Content to sent to the channel or person.
+ zh_Hans: 消息内容文本
+ pt_BR: Content to sent to the channel or person.
+ llm_description: Content of the message
+ form: llm
diff --git a/api/core/tools/provider/builtin/searchapi/tools/google.yaml b/api/core/tools/provider/builtin/searchapi/tools/google.yaml
index b69a0e1d3e..0dc1b66724 100644
--- a/api/core/tools/provider/builtin/searchapi/tools/google.yaml
+++ b/api/core/tools/provider/builtin/searchapi/tools/google.yaml
@@ -65,206 +65,1206 @@ parameters:
form: form
default: US
options:
+ - value: AF
+ label:
+ en_US: Afghanistan
+ zh_Hans: 阿富汗
+ pt_BR: Afeganistão
+ - value: AL
+ label:
+ en_US: Albania
+ zh_Hans: 阿尔巴尼亚
+ pt_BR: Albânia
+ - value: DZ
+ label:
+ en_US: Algeria
+ zh_Hans: 阿尔及利亚
+ pt_BR: Argélia
+ - value: AS
+ label:
+ en_US: American Samoa
+ zh_Hans: 美属萨摩亚
+ pt_BR: Samoa Americana
+ - value: AD
+ label:
+ en_US: Andorra
+ zh_Hans: 安道尔
+ pt_BR: Andorra
+ - value: AO
+ label:
+ en_US: Angola
+ zh_Hans: 安哥拉
+ pt_BR: Angola
+ - value: AI
+ label:
+ en_US: Anguilla
+ zh_Hans: 安圭拉
+ pt_BR: Anguilla
+ - value: AQ
+ label:
+ en_US: Antarctica
+ zh_Hans: 南极洲
+ pt_BR: Antártica
+ - value: AG
+ label:
+ en_US: Antigua and Barbuda
+ zh_Hans: 安提瓜和巴布达
+ pt_BR: Antígua e Barbuda
- value: AR
label:
en_US: Argentina
zh_Hans: 阿根廷
pt_BR: Argentina
+ - value: AM
+ label:
+ en_US: Armenia
+ zh_Hans: 亚美尼亚
+ pt_BR: Armênia
+ - value: AW
+ label:
+ en_US: Aruba
+ zh_Hans: 阿鲁巴
+ pt_BR: Aruba
- value: AU
label:
en_US: Australia
zh_Hans: 澳大利亚
- pt_BR: Australia
+ pt_BR: Austrália
- value: AT
label:
en_US: Austria
zh_Hans: 奥地利
- pt_BR: Austria
+ pt_BR: Áustria
+ - value: AZ
+ label:
+ en_US: Azerbaijan
+ zh_Hans: 阿塞拜疆
+ pt_BR: Azerbaijão
+ - value: BS
+ label:
+ en_US: Bahamas
+ zh_Hans: 巴哈马
+ pt_BR: Bahamas
+ - value: BH
+ label:
+ en_US: Bahrain
+ zh_Hans: 巴林
+ pt_BR: Bahrein
+ - value: BD
+ label:
+ en_US: Bangladesh
+ zh_Hans: 孟加拉国
+ pt_BR: Bangladesh
+ - value: BB
+ label:
+ en_US: Barbados
+ zh_Hans: 巴巴多斯
+ pt_BR: Barbados
+ - value: BY
+ label:
+ en_US: Belarus
+ zh_Hans: 白俄罗斯
+ pt_BR: Bielorrússia
- value: BE
label:
en_US: Belgium
zh_Hans: 比利时
- pt_BR: Belgium
+ pt_BR: Bélgica
+ - value: BZ
+ label:
+ en_US: Belize
+ zh_Hans: 伯利兹
+ pt_BR: Belize
+ - value: BJ
+ label:
+ en_US: Benin
+ zh_Hans: 贝宁
+ pt_BR: Benim
+ - value: BM
+ label:
+ en_US: Bermuda
+ zh_Hans: 百慕大
+ pt_BR: Bermudas
+ - value: BT
+ label:
+ en_US: Bhutan
+ zh_Hans: 不丹
+ pt_BR: Butão
+ - value: BO
+ label:
+ en_US: Bolivia
+ zh_Hans: 玻利维亚
+ pt_BR: Bolívia
+ - value: BA
+ label:
+ en_US: Bosnia and Herzegovina
+ zh_Hans: 波斯尼亚和黑塞哥维那
+ pt_BR: Bósnia e Herzegovina
+ - value: BW
+ label:
+ en_US: Botswana
+ zh_Hans: 博茨瓦纳
+ pt_BR: Botsuana
+ - value: BV
+ label:
+ en_US: Bouvet Island
+ zh_Hans: 布韦岛
+ pt_BR: Ilha Bouvet
- value: BR
label:
en_US: Brazil
zh_Hans: 巴西
- pt_BR: Brazil
+ pt_BR: Brasil
+ - value: IO
+ label:
+ en_US: British Indian Ocean Territory
+ zh_Hans: 英属印度洋领地
+ pt_BR: Território Britânico do Oceano Índico
+ - value: BN
+ label:
+ en_US: Brunei Darussalam
+ zh_Hans: 文莱
+ pt_BR: Brunei Darussalam
+ - value: BG
+ label:
+ en_US: Bulgaria
+ zh_Hans: 保加利亚
+ pt_BR: Bulgária
+ - value: BF
+ label:
+ en_US: Burkina Faso
+ zh_Hans: 布基纳法索
+ pt_BR: Burkina Faso
+ - value: BI
+ label:
+ en_US: Burundi
+ zh_Hans: 布隆迪
+ pt_BR: Burundi
+ - value: KH
+ label:
+ en_US: Cambodia
+ zh_Hans: 柬埔寨
+ pt_BR: Camboja
+ - value: CM
+ label:
+ en_US: Cameroon
+ zh_Hans: 喀麦隆
+ pt_BR: Camarões
- value: CA
label:
en_US: Canada
zh_Hans: 加拿大
- pt_BR: Canada
+ pt_BR: Canadá
+ - value: CV
+ label:
+ en_US: Cape Verde
+ zh_Hans: 佛得角
+ pt_BR: Cabo Verde
+ - value: KY
+ label:
+ en_US: Cayman Islands
+ zh_Hans: 开曼群岛
+ pt_BR: Ilhas Cayman
+ - value: CF
+ label:
+ en_US: Central African Republic
+ zh_Hans: 中非共和国
+ pt_BR: República Centro-Africana
+ - value: TD
+ label:
+ en_US: Chad
+ zh_Hans: 乍得
+ pt_BR: Chade
- value: CL
label:
en_US: Chile
zh_Hans: 智利
pt_BR: Chile
- - value: CO
- label:
- en_US: Colombia
- zh_Hans: 哥伦比亚
- pt_BR: Colombia
- value: CN
label:
en_US: China
zh_Hans: 中国
pt_BR: China
+ - value: CX
+ label:
+ en_US: Christmas Island
+ zh_Hans: 圣诞岛
+ pt_BR: Ilha do Natal
+ - value: CC
+ label:
+ en_US: Cocos (Keeling) Islands
+ zh_Hans: 科科斯(基林)群岛
+ pt_BR: Ilhas Cocos (Keeling)
+ - value: CO
+ label:
+ en_US: Colombia
+ zh_Hans: 哥伦比亚
+ pt_BR: Colômbia
+ - value: KM
+ label:
+ en_US: Comoros
+ zh_Hans: 科摩罗
+ pt_BR: Comores
+ - value: CG
+ label:
+ en_US: Congo
+ zh_Hans: 刚果
+ pt_BR: Congo
+ - value: CD
+ label:
+ en_US: Congo, the Democratic Republic of the
+ zh_Hans: 刚果民主共和国
+ pt_BR: Congo, República Democrática do
+ - value: CK
+ label:
+ en_US: Cook Islands
+ zh_Hans: 库克群岛
+ pt_BR: Ilhas Cook
+ - value: CR
+ label:
+ en_US: Costa Rica
+ zh_Hans: 哥斯达黎加
+ pt_BR: Costa Rica
+ - value: CI
+ label:
+ en_US: Cote D'ivoire
+ zh_Hans: 科特迪瓦
+ pt_BR: Costa do Marfim
+ - value: HR
+ label:
+ en_US: Croatia
+ zh_Hans: 克罗地亚
+ pt_BR: Croácia
+ - value: CU
+ label:
+ en_US: Cuba
+ zh_Hans: 古巴
+ pt_BR: Cuba
+ - value: CY
+ label:
+ en_US: Cyprus
+ zh_Hans: 塞浦路斯
+ pt_BR: Chipre
- value: CZ
label:
en_US: Czech Republic
zh_Hans: 捷克共和国
- pt_BR: Czech Republic
+ pt_BR: República Tcheca
- value: DK
label:
en_US: Denmark
zh_Hans: 丹麦
- pt_BR: Denmark
+ pt_BR: Dinamarca
+ - value: DJ
+ label:
+ en_US: Djibouti
+ zh_Hans: 吉布提
+ pt_BR: Djibuti
+ - value: DM
+ label:
+ en_US: Dominica
+ zh_Hans: 多米尼克
+ pt_BR: Dominica
+ - value: DO
+ label:
+ en_US: Dominican Republic
+ zh_Hans: 多米尼加共和国
+ pt_BR: República Dominicana
+ - value: EC
+ label:
+ en_US: Ecuador
+ zh_Hans: 厄瓜多尔
+ pt_BR: Equador
+ - value: EG
+ label:
+ en_US: Egypt
+ zh_Hans: 埃及
+ pt_BR: Egito
+ - value: SV
+ label:
+ en_US: El Salvador
+ zh_Hans: 萨尔瓦多
+ pt_BR: El Salvador
+ - value: GQ
+ label:
+ en_US: Equatorial Guinea
+ zh_Hans: 赤道几内亚
+ pt_BR: Guiné Equatorial
+ - value: ER
+ label:
+ en_US: Eritrea
+ zh_Hans: 厄立特里亚
+ pt_BR: Eritreia
+ - value: EE
+ label:
+ en_US: Estonia
+ zh_Hans: 爱沙尼亚
+ pt_BR: Estônia
+ - value: ET
+ label:
+ en_US: Ethiopia
+ zh_Hans: 埃塞俄比亚
+ pt_BR: Etiópia
+ - value: FK
+ label:
+ en_US: Falkland Islands (Malvinas)
+ zh_Hans: 福克兰群岛(马尔维纳斯)
+ pt_BR: Ilhas Falkland (Malvinas)
+ - value: FO
+ label:
+ en_US: Faroe Islands
+ zh_Hans: 法罗群岛
+ pt_BR: Ilhas Faroe
+ - value: FJ
+ label:
+ en_US: Fiji
+ zh_Hans: 斐济
+ pt_BR: Fiji
- value: FI
label:
en_US: Finland
zh_Hans: 芬兰
- pt_BR: Finland
+ pt_BR: Finlândia
- value: FR
label:
en_US: France
zh_Hans: 法国
- pt_BR: France
+ pt_BR: França
+ - value: GF
+ label:
+ en_US: French Guiana
+ zh_Hans: 法属圭亚那
+ pt_BR: Guiana Francesa
+ - value: PF
+ label:
+ en_US: French Polynesia
+ zh_Hans: 法属波利尼西亚
+ pt_BR: Polinésia Francesa
+ - value: TF
+ label:
+ en_US: French Southern Territories
+ zh_Hans: 法属南部领地
+ pt_BR: Territórios Franceses do Sul
+ - value: GA
+ label:
+ en_US: Gabon
+ zh_Hans: 加蓬
+ pt_BR: Gabão
+ - value: GM
+ label:
+ en_US: Gambia
+ zh_Hans: 冈比亚
+ pt_BR: Gâmbia
+ - value: GE
+ label:
+ en_US: Georgia
+ zh_Hans: 格鲁吉亚
+ pt_BR: Geórgia
- value: DE
label:
en_US: Germany
zh_Hans: 德国
- pt_BR: Germany
+ pt_BR: Alemanha
+ - value: GH
+ label:
+ en_US: Ghana
+ zh_Hans: 加纳
+ pt_BR: Gana
+ - value: GI
+ label:
+ en_US: Gibraltar
+ zh_Hans: 直布罗陀
+ pt_BR: Gibraltar
+ - value: GR
+ label:
+ en_US: Greece
+ zh_Hans: 希腊
+ pt_BR: Grécia
+ - value: GL
+ label:
+ en_US: Greenland
+ zh_Hans: 格陵兰
+ pt_BR: Groenlândia
+ - value: GD
+ label:
+ en_US: Grenada
+ zh_Hans: 格林纳达
+ pt_BR: Granada
+ - value: GP
+ label:
+ en_US: Guadeloupe
+ zh_Hans: 瓜德罗普
+ pt_BR: Guadalupe
+ - value: GU
+ label:
+ en_US: Guam
+ zh_Hans: 关岛
+ pt_BR: Guam
+ - value: GT
+ label:
+ en_US: Guatemala
+ zh_Hans: 危地马拉
+ pt_BR: Guatemala
+ - value: GN
+ label:
+ en_US: Guinea
+ zh_Hans: 几内亚
+ pt_BR: Guiné
+ - value: GW
+ label:
+ en_US: Guinea-Bissau
+ zh_Hans: 几内亚比绍
+ pt_BR: Guiné-Bissau
+ - value: GY
+ label:
+ en_US: Guyana
+ zh_Hans: 圭亚那
+ pt_BR: Guiana
+ - value: HT
+ label:
+ en_US: Haiti
+ zh_Hans: 海地
+ pt_BR: Haiti
+ - value: HM
+ label:
+ en_US: Heard Island and McDonald Islands
+ zh_Hans: 赫德岛和麦克唐纳群岛
+ pt_BR: Ilha Heard e Ilhas McDonald
+ - value: VA
+ label:
+ en_US: Holy See (Vatican City State)
+ zh_Hans: 教廷(梵蒂冈城国)
+ pt_BR: Santa Sé (Estado da Cidade do Vaticano)
+ - value: HN
+ label:
+ en_US: Honduras
+ zh_Hans: 洪都拉斯
+ pt_BR: Honduras
- value: HK
label:
en_US: Hong Kong
zh_Hans: 香港
pt_BR: Hong Kong
+ - value: HU
+ label:
+ en_US: Hungary
+ zh_Hans: 匈牙利
+ pt_BR: Hungria
+ - value: IS
+ label:
+ en_US: Iceland
+ zh_Hans: 冰岛
+ pt_BR: Islândia
- value: IN
label:
en_US: India
zh_Hans: 印度
- pt_BR: India
+ pt_BR: Índia
- value: ID
label:
en_US: Indonesia
zh_Hans: 印度尼西亚
- pt_BR: Indonesia
+ pt_BR: Indonésia
+ - value: IR
+ label:
+ en_US: Iran, Islamic Republic of
+ zh_Hans: 伊朗
+ pt_BR: Irã
+ - value: IQ
+ label:
+ en_US: Iraq
+ zh_Hans: 伊拉克
+ pt_BR: Iraque
+ - value: IE
+ label:
+ en_US: Ireland
+ zh_Hans: 爱尔兰
+ pt_BR: Irlanda
+ - value: IL
+ label:
+ en_US: Israel
+ zh_Hans: 以色列
+ pt_BR: Israel
- value: IT
label:
en_US: Italy
zh_Hans: 意大利
- pt_BR: Italy
+ pt_BR: Itália
+ - value: JM
+ label:
+ en_US: Jamaica
+ zh_Hans: 牙买加
+ pt_BR: Jamaica
- value: JP
label:
en_US: Japan
zh_Hans: 日本
- pt_BR: Japan
+ pt_BR: Japão
+ - value: JO
+ label:
+ en_US: Jordan
+ zh_Hans: 约旦
+ pt_BR: Jordânia
+ - value: KZ
+ label:
+ en_US: Kazakhstan
+ zh_Hans: 哈萨克斯坦
+ pt_BR: Cazaquistão
+ - value: KE
+ label:
+ en_US: Kenya
+ zh_Hans: 肯尼亚
+ pt_BR: Quênia
+ - value: KI
+ label:
+ en_US: Kiribati
+ zh_Hans: 基里巴斯
+ pt_BR: Kiribati
+ - value: KP
+ label:
+ en_US: Korea, Democratic People's Republic of
+ zh_Hans: 朝鲜
+ pt_BR: Coreia, República Democrática Popular da
- value: KR
label:
- en_US: Korea
+ en_US: Korea, Republic of
zh_Hans: 韩国
- pt_BR: Korea
+ pt_BR: Coreia, República da
+ - value: KW
+ label:
+ en_US: Kuwait
+ zh_Hans: 科威特
+ pt_BR: Kuwait
+ - value: KG
+ label:
+ en_US: Kyrgyzstan
+ zh_Hans: 吉尔吉斯斯坦
+ pt_BR: Quirguistão
+ - value: LA
+ label:
+ en_US: Lao People's Democratic Republic
+ zh_Hans: 老挝
+ pt_BR: República Democrática Popular do Laos
+ - value: LV
+ label:
+ en_US: Latvia
+ zh_Hans: 拉脱维亚
+ pt_BR: Letônia
+ - value: LB
+ label:
+ en_US: Lebanon
+ zh_Hans: 黎巴嫩
+ pt_BR: Líbano
+ - value: LS
+ label:
+ en_US: Lesotho
+ zh_Hans: 莱索托
+ pt_BR: Lesoto
+ - value: LR
+ label:
+ en_US: Liberia
+ zh_Hans: 利比里亚
+ pt_BR: Libéria
+ - value: LY
+ label:
+ en_US: Libyan Arab Jamahiriya
+ zh_Hans: 利比亚
+ pt_BR: Líbia
+ - value: LI
+ label:
+ en_US: Liechtenstein
+ zh_Hans: 列支敦士登
+ pt_BR: Liechtenstein
+ - value: LT
+ label:
+ en_US: Lithuania
+ zh_Hans: 立陶宛
+ pt_BR: Lituânia
+ - value: LU
+ label:
+ en_US: Luxembourg
+ zh_Hans: 卢森堡
+ pt_BR: Luxemburgo
+ - value: MO
+ label:
+ en_US: Macao
+ zh_Hans: 澳门
+ pt_BR: Macau
+ - value: MK
+ label:
+ en_US: Macedonia, the Former Yugosalv Republic of
+ zh_Hans: 前南斯拉夫马其顿共和国
+ pt_BR: Macedônia, Ex-República Iugoslava da
+ - value: MG
+ label:
+ en_US: Madagascar
+ zh_Hans: 马达加斯加
+ pt_BR: Madagascar
+ - value: MW
+ label:
+ en_US: Malawi
+ zh_Hans: 马拉维
+ pt_BR: Malaui
- value: MY
label:
en_US: Malaysia
zh_Hans: 马来西亚
- pt_BR: Malaysia
+ pt_BR: Malásia
+ - value: MV
+ label:
+ en_US: Maldives
+ zh_Hans: 马尔代夫
+ pt_BR: Maldivas
+ - value: ML
+ label:
+ en_US: Mali
+ zh_Hans: 马里
+ pt_BR: Mali
+ - value: MT
+ label:
+ en_US: Malta
+ zh_Hans: 马耳他
+ pt_BR: Malta
+ - value: MH
+ label:
+ en_US: Marshall Islands
+ zh_Hans: 马绍尔群岛
+ pt_BR: Ilhas Marshall
+ - value: MQ
+ label:
+ en_US: Martinique
+ zh_Hans: 马提尼克
+ pt_BR: Martinica
+ - value: MR
+ label:
+ en_US: Mauritania
+ zh_Hans: 毛里塔尼亚
+ pt_BR: Mauritânia
+ - value: MU
+ label:
+ en_US: Mauritius
+ zh_Hans: 毛里求斯
+ pt_BR: Maurício
+ - value: YT
+ label:
+ en_US: Mayotte
+ zh_Hans: 马约特
+ pt_BR: Mayotte
- value: MX
label:
en_US: Mexico
zh_Hans: 墨西哥
- pt_BR: Mexico
+ pt_BR: México
+ - value: FM
+ label:
+ en_US: Micronesia, Federated States of
+ zh_Hans: 密克罗尼西亚联邦
+ pt_BR: Micronésia, Estados Federados da
+ - value: MD
+ label:
+ en_US: Moldova, Republic of
+ zh_Hans: 摩尔多瓦共和国
+ pt_BR: Moldávia, República da
+ - value: MC
+ label:
+ en_US: Monaco
+ zh_Hans: 摩纳哥
+ pt_BR: Mônaco
+ - value: MN
+ label:
+ en_US: Mongolia
+ zh_Hans: 蒙古
+ pt_BR: Mongólia
+ - value: MS
+ label:
+ en_US: Montserrat
+ zh_Hans: 蒙特塞拉特
+ pt_BR: Montserrat
+ - value: MA
+ label:
+ en_US: Morocco
+ zh_Hans: 摩洛哥
+ pt_BR: Marrocos
+ - value: MZ
+ label:
+ en_US: Mozambique
+ zh_Hans: 莫桑比克
+ pt_BR: Moçambique
+ - value: MM
+ label:
+ en_US: Myanmar
+ zh_Hans: 缅甸
+ pt_BR: Mianmar
+ - value: NA
+ label:
+ en_US: Namibia
+ zh_Hans: 纳米比亚
+ pt_BR: Namíbia
+ - value: NR
+ label:
+ en_US: Nauru
+ zh_Hans: 瑙鲁
+ pt_BR: Nauru
+ - value: NP
+ label:
+ en_US: Nepal
+ zh_Hans: 尼泊尔
+ pt_BR: Nepal
- value: NL
label:
en_US: Netherlands
zh_Hans: 荷兰
- pt_BR: Netherlands
+ pt_BR: Países Baixos
+ - value: AN
+ label:
+ en_US: Netherlands Antilles
+ zh_Hans: 荷属安的列斯
+ pt_BR: Antilhas Holandesas
+ - value: NC
+ label:
+ en_US: New Caledonia
+ zh_Hans: 新喀里多尼亚
+ pt_BR: Nova Caledônia
- value: NZ
label:
en_US: New Zealand
zh_Hans: 新西兰
- pt_BR: New Zealand
- - value: 'NO'
+ pt_BR: Nova Zelândia
+ - value: NI
+ label:
+ en_US: Nicaragua
+ zh_Hans: 尼加拉瓜
+ pt_BR: Nicarágua
+ - value: NE
+ label:
+ en_US: Niger
+ zh_Hans: 尼日尔
+ pt_BR: Níger
+ - value: NG
+ label:
+ en_US: Nigeria
+ zh_Hans: 尼日利亚
+ pt_BR: Nigéria
+ - value: NU
+ label:
+ en_US: Niue
+ zh_Hans: 纽埃
+ pt_BR: Niue
+ - value: NF
+ label:
+ en_US: Norfolk Island
+ zh_Hans: 诺福克岛
+ pt_BR: Ilha Norfolk
+ - value: MP
+ label:
+ en_US: Northern Mariana Islands
+ zh_Hans: 北马里亚纳群岛
+ pt_BR: Ilhas Marianas do Norte
+ - value: "NO"
label:
en_US: Norway
zh_Hans: 挪威
- pt_BR: Norway
+ pt_BR: Noruega
+ - value: OM
+ label:
+ en_US: Oman
+ zh_Hans: 阿曼
+ pt_BR: Omã
+ - value: PK
+ label:
+ en_US: Pakistan
+ zh_Hans: 巴基斯坦
+ pt_BR: Paquistão
+ - value: PW
+ label:
+ en_US: Palau
+ zh_Hans: 帕劳
+ pt_BR: Palau
+ - value: PS
+ label:
+ en_US: Palestinian Territory, Occupied
+ zh_Hans: 巴勒斯坦领土
+ pt_BR: Palestina, Território Ocupado
+ - value: PA
+ label:
+ en_US: Panama
+ zh_Hans: 巴拿马
+ pt_BR: Panamá
+ - value: PG
+ label:
+ en_US: Papua New Guinea
+ zh_Hans: 巴布亚新几内亚
+ pt_BR: Papua Nova Guiné
+ - value: PY
+ label:
+ en_US: Paraguay
+ zh_Hans: 巴拉圭
+ pt_BR: Paraguai
+ - value: PE
+ label:
+ en_US: Peru
+ zh_Hans: 秘鲁
+ pt_BR: Peru
- value: PH
label:
en_US: Philippines
zh_Hans: 菲律宾
- pt_BR: Philippines
+ pt_BR: Filipinas
+ - value: PN
+ label:
+ en_US: Pitcairn
+ zh_Hans: 皮特凯恩岛
+ pt_BR: Pitcairn
- value: PL
label:
en_US: Poland
zh_Hans: 波兰
- pt_BR: Poland
+ pt_BR: Polônia
- value: PT
label:
en_US: Portugal
zh_Hans: 葡萄牙
pt_BR: Portugal
+ - value: PR
+ label:
+ en_US: Puerto Rico
+ zh_Hans: 波多黎各
+ pt_BR: Porto Rico
+ - value: QA
+ label:
+ en_US: Qatar
+ zh_Hans: 卡塔尔
+ pt_BR: Catar
+ - value: RE
+ label:
+ en_US: Reunion
+ zh_Hans: 留尼旺
+ pt_BR: Reunião
+ - value: RO
+ label:
+ en_US: Romania
+ zh_Hans: 罗马尼亚
+ pt_BR: Romênia
- value: RU
label:
- en_US: Russia
- zh_Hans: 俄罗斯
- pt_BR: Russia
+ en_US: Russian Federation
+ zh_Hans: 俄罗斯联邦
+ pt_BR: Rússia
+ - value: RW
+ label:
+ en_US: Rwanda
+ zh_Hans: 卢旺达
+ pt_BR: Ruanda
+ - value: SH
+ label:
+ en_US: Saint Helena
+ zh_Hans: 圣赫勒拿
+ pt_BR: Santa Helena
+ - value: KN
+ label:
+ en_US: Saint Kitts and Nevis
+ zh_Hans: 圣基茨和尼维斯
+ pt_BR: São Cristóvão e Nevis
+ - value: LC
+ label:
+ en_US: Saint Lucia
+ zh_Hans: 圣卢西亚
+ pt_BR: Santa Lúcia
+ - value: PM
+ label:
+ en_US: Saint Pierre and Miquelon
+ zh_Hans: 圣皮埃尔和密克隆
+ pt_BR: São Pedro e Miquelon
+ - value: VC
+ label:
+ en_US: Saint Vincent and the Grenadines
+ zh_Hans: 圣文森特和格林纳丁斯
+ pt_BR: São Vicente e Granadinas
+ - value: WS
+ label:
+ en_US: Samoa
+ zh_Hans: 萨摩亚
+ pt_BR: Samoa
+ - value: SM
+ label:
+ en_US: San Marino
+ zh_Hans: 圣马力诺
+ pt_BR: San Marino
+ - value: ST
+ label:
+ en_US: Sao Tome and Principe
+ zh_Hans: 圣多美和普林西比
+ pt_BR: São Tomé e Príncipe
- value: SA
label:
en_US: Saudi Arabia
zh_Hans: 沙特阿拉伯
- pt_BR: Saudi Arabia
+ pt_BR: Arábia Saudita
+ - value: SN
+ label:
+ en_US: Senegal
+ zh_Hans: 塞内加尔
+ pt_BR: Senegal
+ - value: RS
+ label:
+ en_US: Serbia and Montenegro
+ zh_Hans: 塞尔维亚和黑山
+ pt_BR: Sérvia e Montenegro
+ - value: SC
+ label:
+ en_US: Seychelles
+ zh_Hans: 塞舌尔
+ pt_BR: Seicheles
+ - value: SL
+ label:
+ en_US: Sierra Leone
+ zh_Hans: 塞拉利昂
+ pt_BR: Serra Leoa
- value: SG
label:
en_US: Singapore
zh_Hans: 新加坡
- pt_BR: Singapore
+ pt_BR: Singapura
+ - value: SK
+ label:
+ en_US: Slovakia
+ zh_Hans: 斯洛伐克
+ pt_BR: Eslováquia
+ - value: SI
+ label:
+ en_US: Slovenia
+ zh_Hans: 斯洛文尼亚
+ pt_BR: Eslovênia
+ - value: SB
+ label:
+ en_US: Solomon Islands
+ zh_Hans: 所罗门群岛
+ pt_BR: Ilhas Salomão
+ - value: SO
+ label:
+ en_US: Somalia
+ zh_Hans: 索马里
+ pt_BR: Somália
- value: ZA
label:
en_US: South Africa
zh_Hans: 南非
- pt_BR: South Africa
+ pt_BR: África do Sul
+ - value: GS
+ label:
+ en_US: South Georgia and the South Sandwich Islands
+ zh_Hans: 南乔治亚和南桑威奇群岛
+ pt_BR: Geórgia do Sul e Ilhas Sandwich do Sul
- value: ES
label:
en_US: Spain
zh_Hans: 西班牙
- pt_BR: Spain
+ pt_BR: Espanha
+ - value: LK
+ label:
+ en_US: Sri Lanka
+ zh_Hans: 斯里兰卡
+ pt_BR: Sri Lanka
+ - value: SD
+ label:
+ en_US: Sudan
+ zh_Hans: 苏丹
+ pt_BR: Sudão
+ - value: SR
+ label:
+ en_US: Suriname
+ zh_Hans: 苏里南
+ pt_BR: Suriname
+ - value: SJ
+ label:
+ en_US: Svalbard and Jan Mayen
+ zh_Hans: 斯瓦尔巴特和扬马延岛
+ pt_BR: Svalbard e Jan Mayen
+ - value: SZ
+ label:
+ en_US: Swaziland
+ zh_Hans: 斯威士兰
+ pt_BR: Essuatíni
- value: SE
label:
en_US: Sweden
zh_Hans: 瑞典
- pt_BR: Sweden
+ pt_BR: Suécia
- value: CH
label:
en_US: Switzerland
zh_Hans: 瑞士
- pt_BR: Switzerland
+ pt_BR: Suíça
+ - value: SY
+ label:
+ en_US: Syrian Arab Republic
+ zh_Hans: 叙利亚
+ pt_BR: Síria
- value: TW
label:
- en_US: Taiwan
+ en_US: Taiwan, Province of China
zh_Hans: 台湾
pt_BR: Taiwan
+ - value: TJ
+ label:
+ en_US: Tajikistan
+ zh_Hans: 塔吉克斯坦
+ pt_BR: Tajiquistão
+ - value: TZ
+ label:
+ en_US: Tanzania, United Republic of
+ zh_Hans: 坦桑尼亚联合共和国
+ pt_BR: Tanzânia
- value: TH
label:
en_US: Thailand
zh_Hans: 泰国
- pt_BR: Thailand
+ pt_BR: Tailândia
+ - value: TL
+ label:
+ en_US: Timor-Leste
+ zh_Hans: 东帝汶
+ pt_BR: Timor-Leste
+ - value: TG
+ label:
+ en_US: Togo
+ zh_Hans: 多哥
+ pt_BR: Togo
+ - value: TK
+ label:
+ en_US: Tokelau
+ zh_Hans: 托克劳
+ pt_BR: Toquelau
+ - value: TO
+ label:
+ en_US: Tonga
+ zh_Hans: 汤加
+ pt_BR: Tonga
+ - value: TT
+ label:
+ en_US: Trinidad and Tobago
+ zh_Hans: 特立尼达和多巴哥
+ pt_BR: Trindade e Tobago
+ - value: TN
+ label:
+ en_US: Tunisia
+ zh_Hans: 突尼斯
+ pt_BR: Tunísia
- value: TR
label:
en_US: Turkey
zh_Hans: 土耳其
- pt_BR: Turkey
+ pt_BR: Turquia
+ - value: TM
+ label:
+ en_US: Turkmenistan
+ zh_Hans: 土库曼斯坦
+ pt_BR: Turcomenistão
+ - value: TC
+ label:
+ en_US: Turks and Caicos Islands
+ zh_Hans: 特克斯和凯科斯群岛
+ pt_BR: Ilhas Turks e Caicos
+ - value: TV
+ label:
+ en_US: Tuvalu
+ zh_Hans: 图瓦卢
+ pt_BR: Tuvalu
+ - value: UG
+ label:
+ en_US: Uganda
+ zh_Hans: 乌干达
+ pt_BR: Uganda
+ - value: UA
+ label:
+ en_US: Ukraine
+ zh_Hans: 乌克兰
+ pt_BR: Ucrânia
+ - value: AE
+ label:
+ en_US: United Arab Emirates
+ zh_Hans: 阿联酋
+ pt_BR: Emirados Árabes Unidos
+ - value: UK
+ label:
+ en_US: United Kingdom
+ zh_Hans: 英国
+ pt_BR: Reino Unido
- value: GB
label:
en_US: United Kingdom
zh_Hans: 英国
- pt_BR: United Kingdom
+ pt_BR: Reino Unido
- value: US
label:
en_US: United States
zh_Hans: 美国
- pt_BR: United States
+ pt_BR: Estados Unidos
+ - value: UM
+ label:
+ en_US: United States Minor Outlying Islands
+ zh_Hans: 美国本土外小岛屿
+ pt_BR: Ilhas Menores Distantes dos Estados Unidos
+ - value: UY
+ label:
+ en_US: Uruguay
+ zh_Hans: 乌拉圭
+ pt_BR: Uruguai
+ - value: UZ
+ label:
+ en_US: Uzbekistan
+ zh_Hans: 乌兹别克斯坦
+ pt_BR: Uzbequistão
+ - value: VU
+ label:
+ en_US: Vanuatu
+ zh_Hans: 瓦努阿图
+ pt_BR: Vanuatu
+ - value: VE
+ label:
+ en_US: Venezuela
+ zh_Hans: 委内瑞拉
+ pt_BR: Venezuela
+ - value: VN
+ label:
+ en_US: Viet Nam
+ zh_Hans: 越南
+ pt_BR: Vietnã
+ - value: VG
+ label:
+ en_US: Virgin Islands, British
+ zh_Hans: 英属维尔京群岛
+ pt_BR: Ilhas Virgens Britânicas
+ - value: VI
+ label:
+ en_US: Virgin Islands, U.S.
+ zh_Hans: 美属维尔京群岛
+ pt_BR: Ilhas Virgens dos EUA
+ - value: WF
+ label:
+ en_US: Wallis and Futuna
+ zh_Hans: 瓦利斯和富图纳群岛
+ pt_BR: Wallis e Futuna
+ - value: EH
+ label:
+ en_US: Western Sahara
+ zh_Hans: 西撒哈拉
+ pt_BR: Saara Ocidental
+ - value: YE
+ label:
+ en_US: Yemen
+ zh_Hans: 也门
+ pt_BR: Iémen
+ - value: ZM
+ label:
+ en_US: Zambia
+ zh_Hans: 赞比亚
+ pt_BR: Zâmbia
+ - value: ZW
+ label:
+ en_US: Zimbabwe
+ zh_Hans: 津巴布韦
+ pt_BR: Zimbábue
- name: hl
type: select
label:
@@ -277,18 +1277,94 @@ parameters:
default: en
form: form
options:
+ - value: af
+ label:
+ en_US: Afrikaans
+ zh_Hans: 南非语
+ - value: ak
+ label:
+ en_US: Akan
+ zh_Hans: 阿坎语
+ - value: sq
+ label:
+ en_US: Albanian
+ zh_Hans: 阿尔巴尼亚语
+ - value: ws
+ label:
+ en_US: Samoa
+ zh_Hans: 萨摩亚语
+ - value: am
+ label:
+ en_US: Amharic
+ zh_Hans: 阿姆哈拉语
- value: ar
label:
en_US: Arabic
zh_Hans: 阿拉伯语
+ - value: hy
+ label:
+ en_US: Armenian
+ zh_Hans: 亚美尼亚语
+ - value: az
+ label:
+ en_US: Azerbaijani
+ zh_Hans: 阿塞拜疆语
+ - value: eu
+ label:
+ en_US: Basque
+ zh_Hans: 巴斯克语
+ - value: be
+ label:
+ en_US: Belarusian
+ zh_Hans: 白俄罗斯语
+ - value: bem
+ label:
+ en_US: Bemba
+ zh_Hans: 班巴语
+ - value: bn
+ label:
+ en_US: Bengali
+ zh_Hans: 孟加拉语
+ - value: bh
+ label:
+ en_US: Bihari
+ zh_Hans: 比哈尔语
+ - value: xx-bork
+ label:
+ en_US: Bork, bork, bork!
+ zh_Hans: 博克语
+ - value: bs
+ label:
+ en_US: Bosnian
+ zh_Hans: 波斯尼亚语
+ - value: br
+ label:
+ en_US: Breton
+ zh_Hans: 布列塔尼语
- value: bg
label:
en_US: Bulgarian
zh_Hans: 保加利亚语
+ - value: bt
+ label:
+ en_US: Bhutanese
+ zh_Hans: 不丹语
+ - value: km
+ label:
+ en_US: Cambodian
+ zh_Hans: 高棉语
- value: ca
label:
en_US: Catalan
zh_Hans: 加泰罗尼亚语
+ - value: chr
+ label:
+ en_US: Cherokee
+ zh_Hans: 切罗基语
+ - value: ny
+ label:
+ en_US: Chichewa
+ zh_Hans: 齐切瓦语
- value: zh-cn
label:
en_US: Chinese (Simplified)
@@ -297,6 +1373,14 @@ parameters:
label:
en_US: Chinese (Traditional)
zh_Hans: 中文(繁体)
+ - value: co
+ label:
+ en_US: Corsican
+ zh_Hans: 科西嘉语
+ - value: hr
+ label:
+ en_US: Croatian
+ zh_Hans: 克罗地亚语
- value: cs
label:
en_US: Czech
@@ -309,14 +1393,34 @@ parameters:
label:
en_US: Dutch
zh_Hans: 荷兰语
+ - value: xx-elmer
+ label:
+ en_US: Elmer Fudd
+ zh_Hans: 艾尔默福德语
- value: en
label:
en_US: English
zh_Hans: 英语
+ - value: eo
+ label:
+ en_US: Esperanto
+ zh_Hans: 世界语
- value: et
label:
en_US: Estonian
zh_Hans: 爱沙尼亚语
+ - value: ee
+ label:
+ en_US: Ewe
+ zh_Hans: 埃维语
+ - value: fo
+ label:
+ en_US: Faroese
+ zh_Hans: 法罗语
+ - value: tl
+ label:
+ en_US: Filipino
+ zh_Hans: 菲律宾语
- value: fi
label:
en_US: Finnish
@@ -325,6 +1429,22 @@ parameters:
label:
en_US: French
zh_Hans: 法语
+ - value: fy
+ label:
+ en_US: Frisian
+ zh_Hans: 弗里西亚语
+ - value: gaa
+ label:
+ en_US: Ga
+ zh_Hans: 加语
+ - value: gl
+ label:
+ en_US: Galician
+ zh_Hans: 加利西亚语
+ - value: ka
+ label:
+ en_US: Georgian
+ zh_Hans: 格鲁吉亚语
- value: de
label:
en_US: German
@@ -333,6 +1453,34 @@ parameters:
label:
en_US: Greek
zh_Hans: 希腊语
+ - value: kl
+ label:
+ en_US: Greenlandic
+ zh_Hans: 格陵兰语
+ - value: gn
+ label:
+ en_US: Guarani
+ zh_Hans: 瓜拉尼语
+ - value: gu
+ label:
+ en_US: Gujarati
+ zh_Hans: 古吉拉特语
+ - value: xx-hacker
+ label:
+ en_US: Hacker
+ zh_Hans: 黑客语
+ - value: ht
+ label:
+ en_US: Haitian Creole
+ zh_Hans: 海地克里奥尔语
+ - value: ha
+ label:
+ en_US: Hausa
+ zh_Hans: 豪萨语
+ - value: haw
+ label:
+ en_US: Hawaiian
+ zh_Hans: 夏威夷语
- value: iw
label:
en_US: Hebrew
@@ -345,10 +1493,26 @@ parameters:
label:
en_US: Hungarian
zh_Hans: 匈牙利语
+ - value: is
+ label:
+ en_US: Icelandic
+ zh_Hans: 冰岛语
+ - value: ig
+ label:
+ en_US: Igbo
+ zh_Hans: 伊博语
- value: id
label:
en_US: Indonesian
zh_Hans: 印尼语
+ - value: ia
+ label:
+ en_US: Interlingua
+ zh_Hans: 国际语
+ - value: ga
+ label:
+ en_US: Irish
+ zh_Hans: 爱尔兰语
- value: it
label:
en_US: Italian
@@ -357,22 +1521,94 @@ parameters:
label:
en_US: Japanese
zh_Hans: 日语
+ - value: jw
+ label:
+ en_US: Javanese
+ zh_Hans: 爪哇语
- value: kn
label:
en_US: Kannada
zh_Hans: 卡纳达语
+ - value: kk
+ label:
+ en_US: Kazakh
+ zh_Hans: 哈萨克语
+ - value: rw
+ label:
+ en_US: Kinyarwanda
+ zh_Hans: 基尼亚卢旺达语
+ - value: rn
+ label:
+ en_US: Kirundi
+ zh_Hans: 基隆迪语
+ - value: xx-klingon
+ label:
+ en_US: Klingon
+ zh_Hans: 克林贡语
+ - value: kg
+ label:
+ en_US: Kongo
+ zh_Hans: 刚果语
- value: ko
label:
en_US: Korean
zh_Hans: 韩语
+ - value: kri
+ label:
+ en_US: Krio (Sierra Leone)
+ zh_Hans: 塞拉利昂克里奥尔语
+ - value: ku
+ label:
+ en_US: Kurdish
+ zh_Hans: 库尔德语
+ - value: ckb
+ label:
+ en_US: Kurdish (Soranî)
+ zh_Hans: 库尔德语(索拉尼)
+ - value: ky
+ label:
+ en_US: Kyrgyz
+ zh_Hans: 吉尔吉斯语
+ - value: lo
+ label:
+ en_US: Laothian
+ zh_Hans: 老挝语
+ - value: la
+ label:
+ en_US: Latin
+ zh_Hans: 拉丁语
- value: lv
label:
en_US: Latvian
zh_Hans: 拉脱维亚语
+ - value: ln
+ label:
+ en_US: Lingala
+ zh_Hans: 林加拉语
- value: lt
label:
en_US: Lithuanian
zh_Hans: 立陶宛语
+ - value: loz
+ label:
+ en_US: Lozi
+ zh_Hans: 洛齐语
+ - value: lg
+ label:
+ en_US: Luganda
+ zh_Hans: 卢干达语
+ - value: ach
+ label:
+ en_US: Luo
+ zh_Hans: 卢奥语
+ - value: mk
+ label:
+ en_US: Macedonian
+ zh_Hans: 马其顿语
+ - value: mg
+ label:
+ en_US: Malagasy
+ zh_Hans: 马尔加什语
- value: my
label:
en_US: Malay
@@ -381,18 +1617,90 @@ parameters:
label:
en_US: Malayalam
zh_Hans: 马拉雅拉姆语
+ - value: mt
+ label:
+ en_US: Maltese
+ zh_Hans: 马耳他语
+ - value: mv
+ label:
+ en_US: Maldives
+ zh_Hans: 马尔代夫语
+ - value: mi
+ label:
+ en_US: Maori
+ zh_Hans: 毛利语
- value: mr
label:
en_US: Marathi
zh_Hans: 马拉地语
+ - value: mfe
+ label:
+ en_US: Mauritian Creole
+ zh_Hans: 毛里求斯克里奥尔语
+ - value: mo
+ label:
+ en_US: Moldavian
+ zh_Hans: 摩尔达维亚语
+ - value: mn
+ label:
+ en_US: Mongolian
+ zh_Hans: 蒙古语
+ - value: sr-me
+ label:
+ en_US: Montenegrin
+ zh_Hans: 黑山语
+ - value: ne
+ label:
+ en_US: Nepali
+ zh_Hans: 尼泊尔语
+ - value: pcm
+ label:
+ en_US: Nigerian Pidgin
+ zh_Hans: 尼日利亚皮钦语
+ - value: nso
+ label:
+ en_US: Northern Sotho
+ zh_Hans: 北索托语
- value: "no"
label:
en_US: Norwegian
zh_Hans: 挪威语
+ - value: nn
+ label:
+ en_US: Norwegian (Nynorsk)
+ zh_Hans: 挪威语(尼诺斯克语)
+ - value: oc
+ label:
+ en_US: Occitan
+ zh_Hans: 奥克语
+ - value: or
+ label:
+ en_US: Oriya
+ zh_Hans: 奥里亚语
+ - value: om
+ label:
+ en_US: Oromo
+ zh_Hans: 奥罗莫语
+ - value: ps
+ label:
+ en_US: Pashto
+ zh_Hans: 普什图语
+ - value: fa
+ label:
+ en_US: Persian
+ zh_Hans: 波斯语
+ - value: xx-pirate
+ label:
+ en_US: Pirate
+ zh_Hans: 海盗语
- value: pl
label:
en_US: Polish
zh_Hans: 波兰语
+ - value: pt
+ label:
+ en_US: Portuguese
+ zh_Hans: 葡萄牙语
- value: pt-br
label:
en_US: Portuguese (Brazil)
@@ -405,18 +1713,62 @@ parameters:
label:
en_US: Punjabi
zh_Hans: 旁遮普语
+ - value: qu
+ label:
+ en_US: Quechua
+ zh_Hans: 克丘亚语
- value: ro
label:
en_US: Romanian
zh_Hans: 罗马尼亚语
+ - value: rm
+ label:
+ en_US: Romansh
+ zh_Hans: 罗曼什语
+ - value: nyn
+ label:
+ en_US: Runyakitara
+ zh_Hans: 卢尼亚基塔拉语
- value: ru
label:
en_US: Russian
zh_Hans: 俄语
+ - value: gd
+ label:
+ en_US: Scots Gaelic
+ zh_Hans: 苏格兰盖尔语
- value: sr
label:
en_US: Serbian
zh_Hans: 塞尔维亚语
+ - value: sh
+ label:
+ en_US: Serbo-Croatian
+ zh_Hans: 塞尔维亚-克罗地亚语
+ - value: st
+ label:
+ en_US: Sesotho
+ zh_Hans: 塞索托语
+ - value: tn
+ label:
+ en_US: Setswana
+ zh_Hans: 塞茨瓦纳语
+ - value: crs
+ label:
+ en_US: Seychellois Creole
+ zh_Hans: 塞舌尔克里奥尔语
+ - value: sn
+ label:
+ en_US: Shona
+ zh_Hans: 绍纳语
+ - value: sd
+ label:
+ en_US: Sindhi
+ zh_Hans: 信德语
+ - value: si
+ label:
+ en_US: Sinhalese
+ zh_Hans: 僧伽罗语
- value: sk
label:
en_US: Slovak
@@ -425,18 +1777,42 @@ parameters:
label:
en_US: Slovenian
zh_Hans: 斯洛文尼亚语
+ - value: so
+ label:
+ en_US: Somali
+ zh_Hans: 索马里语
- value: es
label:
en_US: Spanish
zh_Hans: 西班牙语
+ - value: es-419
+ label:
+ en_US: Spanish (Latin American)
+ zh_Hans: 西班牙语(拉丁美洲)
+ - value: su
+ label:
+ en_US: Sundanese
+ zh_Hans: 巽他语
+ - value: sw
+ label:
+ en_US: Swahili
+ zh_Hans: 斯瓦希里语
- value: sv
label:
en_US: Swedish
zh_Hans: 瑞典语
+ - value: tg
+ label:
+ en_US: Tajik
+ zh_Hans: 塔吉克语
- value: ta
label:
en_US: Tamil
zh_Hans: 泰米尔语
+ - value: tt
+ label:
+ en_US: Tatar
+ zh_Hans: 鞑靼语
- value: te
label:
en_US: Telugu
@@ -445,18 +1821,82 @@ parameters:
label:
en_US: Thai
zh_Hans: 泰语
+ - value: ti
+ label:
+ en_US: Tigrinya
+ zh_Hans: 提格利尼亚语
+ - value: to
+ label:
+ en_US: Tonga
+ zh_Hans: 汤加语
+ - value: lua
+ label:
+ en_US: Tshiluba
+ zh_Hans: 卢巴语
+ - value: tum
+ label:
+ en_US: Tumbuka
+ zh_Hans: 图布卡语
- value: tr
label:
en_US: Turkish
zh_Hans: 土耳其语
+ - value: tk
+ label:
+ en_US: Turkmen
+ zh_Hans: 土库曼语
+ - value: tw
+ label:
+ en_US: Twi
+ zh_Hans: 契维语
+ - value: ug
+ label:
+ en_US: Uighur
+ zh_Hans: 维吾尔语
- value: uk
label:
en_US: Ukrainian
zh_Hans: 乌克兰语
+ - value: ur
+ label:
+ en_US: Urdu
+ zh_Hans: 乌尔都语
+ - value: uz
+ label:
+ en_US: Uzbek
+ zh_Hans: 乌兹别克语
+ - value: vu
+ label:
+ en_US: Vanuatu
+ zh_Hans: 瓦努阿图语
- value: vi
label:
en_US: Vietnamese
zh_Hans: 越南语
+ - value: cy
+ label:
+ en_US: Welsh
+ zh_Hans: 威尔士语
+ - value: wo
+ label:
+ en_US: Wolof
+ zh_Hans: 沃洛夫语
+ - value: xh
+ label:
+ en_US: Xhosa
+ zh_Hans: 科萨语
+ - value: yi
+ label:
+ en_US: Yiddish
+ zh_Hans: 意第绪语
+ - value: yo
+ label:
+ en_US: Yoruba
+ zh_Hans: 约鲁巴语
+ - value: zu
+ label:
+ en_US: Zulu
+ zh_Hans: 祖鲁语
- name: google_domain
type: string
required: false
diff --git a/api/core/tools/provider/builtin/searchapi/tools/google_jobs.yaml b/api/core/tools/provider/builtin/searchapi/tools/google_jobs.yaml
index 9033bc0f87..3e00e20fbd 100644
--- a/api/core/tools/provider/builtin/searchapi/tools/google_jobs.yaml
+++ b/api/core/tools/provider/builtin/searchapi/tools/google_jobs.yaml
@@ -65,36 +65,141 @@ parameters:
form: form
default: US
options:
- - value: AR
+ - value: DZ
label:
- en_US: Argentina
- zh_Hans: 阿根廷
- pt_BR: Argentina
- - value: AU
+ en_US: Algeria
+ zh_Hans: 阿尔及利亚
+ pt_BR: Algeria
+ - value: AS
label:
- en_US: Australia
- zh_Hans: 澳大利亚
- pt_BR: Australia
+ en_US: American Samoa
+ zh_Hans: 美属萨摩亚
+ pt_BR: American Samoa
+ - value: AO
+ label:
+ en_US: Angola
+ zh_Hans: 安哥拉
+ pt_BR: Angola
+ - value: AI
+ label:
+ en_US: Anguilla
+ zh_Hans: 安圭拉
+ pt_BR: Anguilla
+ - value: AG
+ label:
+ en_US: Antigua and Barbuda
+ zh_Hans: 安提瓜和巴布达
+ pt_BR: Antigua and Barbuda
+ - value: AW
+ label:
+ en_US: Aruba
+ zh_Hans: 阿鲁巴
+ pt_BR: Aruba
- value: AT
label:
en_US: Austria
zh_Hans: 奥地利
pt_BR: Austria
+ - value: BS
+ label:
+ en_US: Bahamas
+ zh_Hans: 巴哈马
+ pt_BR: Bahamas
+ - value: BH
+ label:
+ en_US: Bahrain
+ zh_Hans: 巴林
+ pt_BR: Bahrain
+ - value: BD
+ label:
+ en_US: Bangladesh
+ zh_Hans: 孟加拉国
+ pt_BR: Bangladesh
+ - value: BY
+ label:
+ en_US: Belarus
+ zh_Hans: 白俄罗斯
+ pt_BR: Belarus
- value: BE
label:
en_US: Belgium
zh_Hans: 比利时
pt_BR: Belgium
+ - value: BZ
+ label:
+ en_US: Belize
+ zh_Hans: 伯利兹
+ pt_BR: Belize
+ - value: BJ
+ label:
+ en_US: Benin
+ zh_Hans: 贝宁
+ pt_BR: Benin
+ - value: BM
+ label:
+ en_US: Bermuda
+ zh_Hans: 百慕大
+ pt_BR: Bermuda
+ - value: BO
+ label:
+ en_US: Bolivia
+ zh_Hans: 玻利维亚
+ pt_BR: Bolivia
+ - value: BW
+ label:
+ en_US: Botswana
+ zh_Hans: 博茨瓦纳
+ pt_BR: Botswana
- value: BR
label:
en_US: Brazil
zh_Hans: 巴西
pt_BR: Brazil
+ - value: IO
+ label:
+ en_US: British Indian Ocean Territory
+ zh_Hans: 英属印度洋领地
+ pt_BR: British Indian Ocean Territory
+ - value: BF
+ label:
+ en_US: Burkina Faso
+ zh_Hans: 布基纳法索
+ pt_BR: Burkina Faso
+ - value: BI
+ label:
+ en_US: Burundi
+ zh_Hans: 布隆迪
+ pt_BR: Burundi
+ - value: CM
+ label:
+ en_US: Cameroon
+ zh_Hans: 喀麦隆
+ pt_BR: Cameroon
- value: CA
label:
en_US: Canada
zh_Hans: 加拿大
pt_BR: Canada
+ - value: CV
+ label:
+ en_US: Cape Verde
+ zh_Hans: 佛得角
+ pt_BR: Cape Verde
+ - value: KY
+ label:
+ en_US: Cayman Islands
+ zh_Hans: 开曼群岛
+ pt_BR: Cayman Islands
+ - value: CF
+ label:
+ en_US: Central African Republic
+ zh_Hans: 中非共和国
+ pt_BR: Central African Republic
+ - value: TD
+ label:
+ en_US: Chad
+ zh_Hans: 乍得
+ pt_BR: Chad
- value: CL
label:
en_US: Chile
@@ -105,36 +210,141 @@ parameters:
en_US: Colombia
zh_Hans: 哥伦比亚
pt_BR: Colombia
- - value: CN
+ - value: CD
label:
- en_US: China
- zh_Hans: 中国
- pt_BR: China
- - value: CZ
+ en_US: Congo, the Democratic Republic of the
+ zh_Hans: 刚果民主共和国
+ pt_BR: Congo, the Democratic Republic of the
+ - value: CR
label:
- en_US: Czech Republic
- zh_Hans: 捷克共和国
- pt_BR: Czech Republic
+ en_US: Costa Rica
+ zh_Hans: 哥斯达黎加
+ pt_BR: Costa Rica
+ - value: CI
+ label:
+ en_US: Cote D'ivoire
+ zh_Hans: 科特迪瓦
+ pt_BR: Cote D'ivoire
+ - value: CU
+ label:
+ en_US: Cuba
+ zh_Hans: 古巴
+ pt_BR: Cuba
- value: DK
label:
en_US: Denmark
zh_Hans: 丹麦
pt_BR: Denmark
- - value: FI
+ - value: DJ
label:
- en_US: Finland
- zh_Hans: 芬兰
- pt_BR: Finland
+ en_US: Djibouti
+ zh_Hans: 吉布提
+ pt_BR: Djibouti
+ - value: DM
+ label:
+ en_US: Dominica
+ zh_Hans: 多米尼克
+ pt_BR: Dominica
+ - value: DO
+ label:
+ en_US: Dominican Republic
+ zh_Hans: 多米尼加共和国
+ pt_BR: Dominican Republic
+ - value: EC
+ label:
+ en_US: Ecuador
+ zh_Hans: 厄瓜多尔
+ pt_BR: Ecuador
+ - value: EG
+ label:
+ en_US: Egypt
+ zh_Hans: 埃及
+ pt_BR: Egypt
+ - value: SV
+ label:
+ en_US: El Salvador
+ zh_Hans: 萨尔瓦多
+ pt_BR: El Salvador
+ - value: ET
+ label:
+ en_US: Ethiopia
+ zh_Hans: 埃塞俄比亚
+ pt_BR: Ethiopia
+ - value: FK
+ label:
+ en_US: Falkland Islands (Malvinas)
+ zh_Hans: 福克兰群岛(马尔维纳斯)
+ pt_BR: Falkland Islands (Malvinas)
- value: FR
label:
en_US: France
zh_Hans: 法国
pt_BR: France
+ - value: GF
+ label:
+ en_US: French Guiana
+ zh_Hans: 法属圭亚那
+ pt_BR: French Guiana
+ - value: PF
+ label:
+ en_US: French Polynesia
+ zh_Hans: 法属波利尼西亚
+ pt_BR: French Polynesia
+ - value: TF
+ label:
+ en_US: French Southern Territories
+ zh_Hans: 法属南部领地
+ pt_BR: French Southern Territories
+ - value: GA
+ label:
+ en_US: Gabon
+ zh_Hans: 加蓬
+ pt_BR: Gabon
+ - value: GM
+ label:
+ en_US: Gambia
+ zh_Hans: 冈比亚
+ pt_BR: Gambia
- value: DE
label:
en_US: Germany
zh_Hans: 德国
pt_BR: Germany
+ - value: GH
+ label:
+ en_US: Ghana
+ zh_Hans: 加纳
+ pt_BR: Ghana
+ - value: GR
+ label:
+ en_US: Greece
+ zh_Hans: 希腊
+ pt_BR: Greece
+ - value: GP
+ label:
+ en_US: Guadeloupe
+ zh_Hans: 瓜德罗普
+ pt_BR: Guadeloupe
+ - value: GT
+ label:
+ en_US: Guatemala
+ zh_Hans: 危地马拉
+ pt_BR: Guatemala
+ - value: GY
+ label:
+ en_US: Guyana
+ zh_Hans: 圭亚那
+ pt_BR: Guyana
+ - value: HT
+ label:
+ en_US: Haiti
+ zh_Hans: 海地
+ pt_BR: Haiti
+ - value: HN
+ label:
+ en_US: Honduras
+ zh_Hans: 洪都拉斯
+ pt_BR: Honduras
- value: HK
label:
en_US: Hong Kong
@@ -150,91 +360,291 @@ parameters:
en_US: Indonesia
zh_Hans: 印度尼西亚
pt_BR: Indonesia
+ - value: IQ
+ label:
+ en_US: Iraq
+ zh_Hans: 伊拉克
+ pt_BR: Iraq
- value: IT
label:
en_US: Italy
zh_Hans: 意大利
pt_BR: Italy
+ - value: JM
+ label:
+ en_US: Jamaica
+ zh_Hans: 牙买加
+ pt_BR: Jamaica
- value: JP
label:
en_US: Japan
zh_Hans: 日本
pt_BR: Japan
- - value: KR
+ - value: JO
label:
- en_US: Korea
- zh_Hans: 韩国
- pt_BR: Korea
+ en_US: Jordan
+ zh_Hans: 约旦
+ pt_BR: Jordan
+ - value: KZ
+ label:
+ en_US: Kazakhstan
+ zh_Hans: 哈萨克斯坦
+ pt_BR: Kazakhstan
+ - value: KE
+ label:
+ en_US: Kenya
+ zh_Hans: 肯尼亚
+ pt_BR: Kenya
+ - value: KW
+ label:
+ en_US: Kuwait
+ zh_Hans: 科威特
+ pt_BR: Kuwait
+ - value: KG
+ label:
+ en_US: Kyrgyzstan
+ zh_Hans: 吉尔吉斯斯坦
+ pt_BR: Kyrgyzstan
+ - value: LB
+ label:
+ en_US: Lebanon
+ zh_Hans: 黎巴嫩
+ pt_BR: Lebanon
+ - value: LS
+ label:
+ en_US: Lesotho
+ zh_Hans: 莱索托
+ pt_BR: Lesotho
+ - value: LY
+ label:
+ en_US: Libyan Arab Jamahiriya
+ zh_Hans: 利比亚
+ pt_BR: Libyan Arab Jamahiriya
+ - value: MG
+ label:
+ en_US: Madagascar
+ zh_Hans: 马达加斯加
+ pt_BR: Madagascar
+ - value: MW
+ label:
+ en_US: Malawi
+ zh_Hans: 马拉维
+ pt_BR: Malawi
- value: MY
label:
en_US: Malaysia
zh_Hans: 马来西亚
pt_BR: Malaysia
+ - value: ML
+ label:
+ en_US: Mali
+ zh_Hans: 马里
+ pt_BR: Mali
+ - value: MQ
+ label:
+ en_US: Martinique
+ zh_Hans: 马提尼克
+ pt_BR: Martinique
+ - value: MU
+ label:
+ en_US: Mauritius
+ zh_Hans: 毛里求斯
+ pt_BR: Mauritius
+ - value: YT
+ label:
+ en_US: Mayotte
+ zh_Hans: 马约特
+ pt_BR: Mayotte
- value: MX
label:
en_US: Mexico
zh_Hans: 墨西哥
pt_BR: Mexico
+ - value: MS
+ label:
+ en_US: Montserrat
+ zh_Hans: 蒙特塞拉特
+ pt_BR: Montserrat
+ - value: MA
+ label:
+ en_US: Morocco
+ zh_Hans: 摩洛哥
+ pt_BR: Morocco
+ - value: MZ
+ label:
+ en_US: Mozambique
+ zh_Hans: 莫桑比克
+ pt_BR: Mozambique
+ - value: NA
+ label:
+ en_US: Namibia
+ zh_Hans: 纳米比亚
+ pt_BR: Namibia
- value: NL
label:
en_US: Netherlands
zh_Hans: 荷兰
pt_BR: Netherlands
- - value: NZ
+ - value: NC
label:
- en_US: New Zealand
- zh_Hans: 新西兰
- pt_BR: New Zealand
- - value: 'NO'
+ en_US: New Caledonia
+ zh_Hans: 新喀里多尼亚
+ pt_BR: New Caledonia
+ - value: NI
label:
- en_US: Norway
- zh_Hans: 挪威
- pt_BR: Norway
+ en_US: Nicaragua
+ zh_Hans: 尼加拉瓜
+ pt_BR: Nicaragua
+ - value: NE
+ label:
+ en_US: Niger
+ zh_Hans: 尼日尔
+ pt_BR: Niger
+ - value: NG
+ label:
+ en_US: Nigeria
+ zh_Hans: 尼日利亚
+ pt_BR: Nigeria
+ - value: OM
+ label:
+ en_US: Oman
+ zh_Hans: 阿曼
+ pt_BR: Oman
+ - value: PK
+ label:
+ en_US: Pakistan
+ zh_Hans: 巴基斯坦
+ pt_BR: Pakistan
+ - value: PS
+ label:
+ en_US: Palestinian Territory, Occupied
+ zh_Hans: 巴勒斯坦领土
+ pt_BR: Palestinian Territory, Occupied
+ - value: PA
+ label:
+ en_US: Panama
+ zh_Hans: 巴拿马
+ pt_BR: Panama
+ - value: PY
+ label:
+ en_US: Paraguay
+ zh_Hans: 巴拉圭
+ pt_BR: Paraguay
+ - value: PE
+ label:
+ en_US: Peru
+ zh_Hans: 秘鲁
+ pt_BR: Peru
- value: PH
label:
en_US: Philippines
zh_Hans: 菲律宾
pt_BR: Philippines
- - value: PL
- label:
- en_US: Poland
- zh_Hans: 波兰
- pt_BR: Poland
- value: PT
label:
en_US: Portugal
zh_Hans: 葡萄牙
pt_BR: Portugal
+ - value: PR
+ label:
+ en_US: Puerto Rico
+ zh_Hans: 波多黎各
+ pt_BR: Puerto Rico
+ - value: QA
+ label:
+ en_US: Qatar
+ zh_Hans: 卡塔尔
+ pt_BR: Qatar
+ - value: RE
+ label:
+ en_US: Reunion
+ zh_Hans: 留尼旺
+ pt_BR: Reunion
- value: RU
label:
- en_US: Russia
- zh_Hans: 俄罗斯
- pt_BR: Russia
+ en_US: Russian Federation
+ zh_Hans: 俄罗斯联邦
+ pt_BR: Russian Federation
+ - value: RW
+ label:
+ en_US: Rwanda
+ zh_Hans: 卢旺达
+ pt_BR: Rwanda
+ - value: SH
+ label:
+ en_US: Saint Helena
+ zh_Hans: 圣赫勒拿
+ pt_BR: Saint Helena
+ - value: PM
+ label:
+ en_US: Saint Pierre and Miquelon
+ zh_Hans: 圣皮埃尔和密克隆
+ pt_BR: Saint Pierre and Miquelon
+ - value: VC
+ label:
+ en_US: Saint Vincent and the Grenadines
+ zh_Hans: 圣文森特和格林纳丁斯
+ pt_BR: Saint Vincent and the Grenadines
+ - value: ST
+ label:
+ en_US: Sao Tome and Principe
+ zh_Hans: 圣多美和普林西比
+ pt_BR: Sao Tome and Principe
- value: SA
label:
en_US: Saudi Arabia
zh_Hans: 沙特阿拉伯
pt_BR: Saudi Arabia
+ - value: SN
+ label:
+ en_US: Senegal
+ zh_Hans: 塞内加尔
+ pt_BR: Senegal
+ - value: SC
+ label:
+ en_US: Seychelles
+ zh_Hans: 塞舌尔
+ pt_BR: Seychelles
+ - value: SL
+ label:
+ en_US: Sierra Leone
+ zh_Hans: 塞拉利昂
+ pt_BR: Sierra Leone
- value: SG
label:
en_US: Singapore
zh_Hans: 新加坡
pt_BR: Singapore
+ - value: SO
+ label:
+ en_US: Somalia
+ zh_Hans: 索马里
+ pt_BR: Somalia
- value: ZA
label:
en_US: South Africa
zh_Hans: 南非
pt_BR: South Africa
+ - value: GS
+ label:
+ en_US: South Georgia and the South Sandwich Islands
+ zh_Hans: 南乔治亚和南桑威奇群岛
+ pt_BR: South Georgia and the South Sandwich Islands
- value: ES
label:
en_US: Spain
zh_Hans: 西班牙
pt_BR: Spain
- - value: SE
+ - value: LK
label:
- en_US: Sweden
- zh_Hans: 瑞典
- pt_BR: Sweden
+ en_US: Sri Lanka
+ zh_Hans: 斯里兰卡
+ pt_BR: Sri Lanka
+ - value: SR
+ label:
+ en_US: Suriname
+ zh_Hans: 苏里南
+ pt_BR: Suriname
- value: CH
label:
en_US: Switzerland
@@ -242,19 +652,54 @@ parameters:
pt_BR: Switzerland
- value: TW
label:
- en_US: Taiwan
- zh_Hans: 台湾
- pt_BR: Taiwan
+ en_US: Taiwan, Province of China
+ zh_Hans: 中国台湾省
+ pt_BR: Taiwan, Province of China
+ - value: TZ
+ label:
+ en_US: Tanzania, United Republic of
+ zh_Hans: 坦桑尼亚联合共和国
+ pt_BR: Tanzania, United Republic of
- value: TH
label:
en_US: Thailand
zh_Hans: 泰国
pt_BR: Thailand
- - value: TR
+ - value: TG
label:
- en_US: Turkey
- zh_Hans: 土耳其
- pt_BR: Turkey
+ en_US: Togo
+ zh_Hans: 多哥
+ pt_BR: Togo
+ - value: TT
+ label:
+ en_US: Trinidad and Tobago
+ zh_Hans: 特立尼达和多巴哥
+ pt_BR: Trinidad and Tobago
+ - value: TN
+ label:
+ en_US: Tunisia
+ zh_Hans: 突尼斯
+ pt_BR: Tunisia
+ - value: TC
+ label:
+ en_US: Turks and Caicos Islands
+ zh_Hans: 特克斯和凯科斯群岛
+ pt_BR: Turks and Caicos Islands
+ - value: UG
+ label:
+ en_US: Uganda
+ zh_Hans: 乌干达
+ pt_BR: Uganda
+ - value: AE
+ label:
+ en_US: United Arab Emirates
+ zh_Hans: 阿联酋
+ pt_BR: United Arab Emirates
+ - value: UK
+ label:
+ en_US: United Kingdom
+ zh_Hans: 英国
+ pt_BR: United Kingdom
- value: GB
label:
en_US: United Kingdom
@@ -265,6 +710,46 @@ parameters:
en_US: United States
zh_Hans: 美国
pt_BR: United States
+ - value: UY
+ label:
+ en_US: Uruguay
+ zh_Hans: 乌拉圭
+ pt_BR: Uruguay
+ - value: UZ
+ label:
+ en_US: Uzbekistan
+ zh_Hans: 乌兹别克斯坦
+ pt_BR: Uzbekistan
+ - value: VE
+ label:
+ en_US: Venezuela
+ zh_Hans: 委内瑞拉
+ pt_BR: Venezuela
+ - value: VN
+ label:
+ en_US: Viet Nam
+ zh_Hans: 越南
+ pt_BR: Viet Nam
+ - value: VG
+ label:
+ en_US: Virgin Islands, British
+ zh_Hans: 英属维尔京群岛
+ pt_BR: Virgin Islands, British
+ - value: VI
+ label:
+ en_US: Virgin Islands, U.S.
+ zh_Hans: 美属维尔京群岛
+ pt_BR: Virgin Islands, U.S.
+ - value: ZM
+ label:
+ en_US: Zambia
+ zh_Hans: 赞比亚
+ pt_BR: Zambia
+ - value: ZW
+ label:
+ en_US: Zimbabwe
+ zh_Hans: 津巴布韦
+ pt_BR: Zimbabwe
- name: hl
type: select
label:
@@ -277,18 +762,94 @@ parameters:
default: en
form: form
options:
+ - value: af
+ label:
+ en_US: Afrikaans
+ zh_Hans: 南非语
+ - value: ak
+ label:
+ en_US: Akan
+ zh_Hans: 阿坎语
+ - value: sq
+ label:
+ en_US: Albanian
+ zh_Hans: 阿尔巴尼亚语
+ - value: ws
+ label:
+ en_US: Samoa
+ zh_Hans: 萨摩亚语
+ - value: am
+ label:
+ en_US: Amharic
+ zh_Hans: 阿姆哈拉语
- value: ar
label:
en_US: Arabic
zh_Hans: 阿拉伯语
+ - value: hy
+ label:
+ en_US: Armenian
+ zh_Hans: 亚美尼亚语
+ - value: az
+ label:
+ en_US: Azerbaijani
+ zh_Hans: 阿塞拜疆语
+ - value: eu
+ label:
+ en_US: Basque
+ zh_Hans: 巴斯克语
+ - value: be
+ label:
+ en_US: Belarusian
+ zh_Hans: 白俄罗斯语
+ - value: bem
+ label:
+ en_US: Bemba
+ zh_Hans: 班巴语
+ - value: bn
+ label:
+ en_US: Bengali
+ zh_Hans: 孟加拉语
+ - value: bh
+ label:
+ en_US: Bihari
+ zh_Hans: 比哈尔语
+ - value: xx-bork
+ label:
+ en_US: Bork, bork, bork!
+ zh_Hans: 博克语
+ - value: bs
+ label:
+ en_US: Bosnian
+ zh_Hans: 波斯尼亚语
+ - value: br
+ label:
+ en_US: Breton
+ zh_Hans: 布列塔尼语
- value: bg
label:
en_US: Bulgarian
zh_Hans: 保加利亚语
+ - value: bt
+ label:
+ en_US: Bhutanese
+ zh_Hans: 不丹语
+ - value: km
+ label:
+ en_US: Cambodian
+ zh_Hans: 高棉语
- value: ca
label:
en_US: Catalan
zh_Hans: 加泰罗尼亚语
+ - value: chr
+ label:
+ en_US: Cherokee
+ zh_Hans: 切罗基语
+ - value: ny
+ label:
+ en_US: Chichewa
+ zh_Hans: 齐切瓦语
- value: zh-cn
label:
en_US: Chinese (Simplified)
@@ -297,6 +858,14 @@ parameters:
label:
en_US: Chinese (Traditional)
zh_Hans: 中文(繁体)
+ - value: co
+ label:
+ en_US: Corsican
+ zh_Hans: 科西嘉语
+ - value: hr
+ label:
+ en_US: Croatian
+ zh_Hans: 克罗地亚语
- value: cs
label:
en_US: Czech
@@ -309,14 +878,34 @@ parameters:
label:
en_US: Dutch
zh_Hans: 荷兰语
+ - value: xx-elmer
+ label:
+ en_US: Elmer Fudd
+ zh_Hans: 艾尔默福德语
- value: en
label:
en_US: English
zh_Hans: 英语
+ - value: eo
+ label:
+ en_US: Esperanto
+ zh_Hans: 世界语
- value: et
label:
en_US: Estonian
zh_Hans: 爱沙尼亚语
+ - value: ee
+ label:
+ en_US: Ewe
+ zh_Hans: 埃维语
+ - value: fo
+ label:
+ en_US: Faroese
+ zh_Hans: 法罗语
+ - value: tl
+ label:
+ en_US: Filipino
+ zh_Hans: 菲律宾语
- value: fi
label:
en_US: Finnish
@@ -325,6 +914,22 @@ parameters:
label:
en_US: French
zh_Hans: 法语
+ - value: fy
+ label:
+ en_US: Frisian
+ zh_Hans: 弗里西亚语
+ - value: gaa
+ label:
+ en_US: Ga
+ zh_Hans: 加语
+ - value: gl
+ label:
+ en_US: Galician
+ zh_Hans: 加利西亚语
+ - value: ka
+ label:
+ en_US: Georgian
+ zh_Hans: 格鲁吉亚语
- value: de
label:
en_US: German
@@ -333,6 +938,34 @@ parameters:
label:
en_US: Greek
zh_Hans: 希腊语
+ - value: kl
+ label:
+ en_US: Greenlandic
+ zh_Hans: 格陵兰语
+ - value: gn
+ label:
+ en_US: Guarani
+ zh_Hans: 瓜拉尼语
+ - value: gu
+ label:
+ en_US: Gujarati
+ zh_Hans: 古吉拉特语
+ - value: xx-hacker
+ label:
+ en_US: Hacker
+ zh_Hans: 黑客语
+ - value: ht
+ label:
+ en_US: Haitian Creole
+ zh_Hans: 海地克里奥尔语
+ - value: ha
+ label:
+ en_US: Hausa
+ zh_Hans: 豪萨语
+ - value: haw
+ label:
+ en_US: Hawaiian
+ zh_Hans: 夏威夷语
- value: iw
label:
en_US: Hebrew
@@ -345,10 +978,26 @@ parameters:
label:
en_US: Hungarian
zh_Hans: 匈牙利语
+ - value: is
+ label:
+ en_US: Icelandic
+ zh_Hans: 冰岛语
+ - value: ig
+ label:
+ en_US: Igbo
+ zh_Hans: 伊博语
- value: id
label:
en_US: Indonesian
zh_Hans: 印尼语
+ - value: ia
+ label:
+ en_US: Interlingua
+ zh_Hans: 国际语
+ - value: ga
+ label:
+ en_US: Irish
+ zh_Hans: 爱尔兰语
- value: it
label:
en_US: Italian
@@ -357,22 +1006,94 @@ parameters:
label:
en_US: Japanese
zh_Hans: 日语
+ - value: jw
+ label:
+ en_US: Javanese
+ zh_Hans: 爪哇语
- value: kn
label:
en_US: Kannada
zh_Hans: 卡纳达语
+ - value: kk
+ label:
+ en_US: Kazakh
+ zh_Hans: 哈萨克语
+ - value: rw
+ label:
+ en_US: Kinyarwanda
+ zh_Hans: 基尼亚卢旺达语
+ - value: rn
+ label:
+ en_US: Kirundi
+ zh_Hans: 基隆迪语
+ - value: xx-klingon
+ label:
+ en_US: Klingon
+ zh_Hans: 克林贡语
+ - value: kg
+ label:
+ en_US: Kongo
+ zh_Hans: 刚果语
- value: ko
label:
en_US: Korean
zh_Hans: 韩语
+ - value: kri
+ label:
+ en_US: Krio (Sierra Leone)
+ zh_Hans: 塞拉利昂克里奥尔语
+ - value: ku
+ label:
+ en_US: Kurdish
+ zh_Hans: 库尔德语
+ - value: ckb
+ label:
+ en_US: Kurdish (Soranî)
+ zh_Hans: 库尔德语(索拉尼)
+ - value: ky
+ label:
+ en_US: Kyrgyz
+ zh_Hans: 吉尔吉斯语
+ - value: lo
+ label:
+ en_US: Laothian
+ zh_Hans: 老挝语
+ - value: la
+ label:
+ en_US: Latin
+ zh_Hans: 拉丁语
- value: lv
label:
en_US: Latvian
zh_Hans: 拉脱维亚语
+ - value: ln
+ label:
+ en_US: Lingala
+ zh_Hans: 林加拉语
- value: lt
label:
en_US: Lithuanian
zh_Hans: 立陶宛语
+ - value: loz
+ label:
+ en_US: Lozi
+ zh_Hans: 洛齐语
+ - value: lg
+ label:
+ en_US: Luganda
+ zh_Hans: 卢干达语
+ - value: ach
+ label:
+ en_US: Luo
+ zh_Hans: 卢奥语
+ - value: mk
+ label:
+ en_US: Macedonian
+ zh_Hans: 马其顿语
+ - value: mg
+ label:
+ en_US: Malagasy
+ zh_Hans: 马尔加什语
- value: my
label:
en_US: Malay
@@ -381,18 +1102,90 @@ parameters:
label:
en_US: Malayalam
zh_Hans: 马拉雅拉姆语
+ - value: mt
+ label:
+ en_US: Maltese
+ zh_Hans: 马耳他语
+ - value: mv
+ label:
+ en_US: Maldives
+ zh_Hans: 马尔代夫语
+ - value: mi
+ label:
+ en_US: Maori
+ zh_Hans: 毛利语
- value: mr
label:
en_US: Marathi
zh_Hans: 马拉地语
+ - value: mfe
+ label:
+ en_US: Mauritian Creole
+ zh_Hans: 毛里求斯克里奥尔语
+ - value: mo
+ label:
+ en_US: Moldavian
+ zh_Hans: 摩尔达维亚语
+ - value: mn
+ label:
+ en_US: Mongolian
+ zh_Hans: 蒙古语
+ - value: sr-me
+ label:
+ en_US: Montenegrin
+ zh_Hans: 黑山语
+ - value: ne
+ label:
+ en_US: Nepali
+ zh_Hans: 尼泊尔语
+ - value: pcm
+ label:
+ en_US: Nigerian Pidgin
+ zh_Hans: 尼日利亚皮钦语
+ - value: nso
+ label:
+ en_US: Northern Sotho
+ zh_Hans: 北索托语
- value: "no"
label:
en_US: Norwegian
zh_Hans: 挪威语
+ - value: nn
+ label:
+ en_US: Norwegian (Nynorsk)
+ zh_Hans: 挪威语(尼诺斯克语)
+ - value: oc
+ label:
+ en_US: Occitan
+ zh_Hans: 奥克语
+ - value: or
+ label:
+ en_US: Oriya
+ zh_Hans: 奥里亚语
+ - value: om
+ label:
+ en_US: Oromo
+ zh_Hans: 奥罗莫语
+ - value: ps
+ label:
+ en_US: Pashto
+ zh_Hans: 普什图语
+ - value: fa
+ label:
+ en_US: Persian
+ zh_Hans: 波斯语
+ - value: xx-pirate
+ label:
+ en_US: Pirate
+ zh_Hans: 海盗语
- value: pl
label:
en_US: Polish
zh_Hans: 波兰语
+ - value: pt
+ label:
+ en_US: Portuguese
+ zh_Hans: 葡萄牙语
- value: pt-br
label:
en_US: Portuguese (Brazil)
@@ -405,18 +1198,62 @@ parameters:
label:
en_US: Punjabi
zh_Hans: 旁遮普语
+ - value: qu
+ label:
+ en_US: Quechua
+ zh_Hans: 克丘亚语
- value: ro
label:
en_US: Romanian
zh_Hans: 罗马尼亚语
+ - value: rm
+ label:
+ en_US: Romansh
+ zh_Hans: 罗曼什语
+ - value: nyn
+ label:
+ en_US: Runyakitara
+ zh_Hans: 卢尼亚基塔拉语
- value: ru
label:
en_US: Russian
zh_Hans: 俄语
+ - value: gd
+ label:
+ en_US: Scots Gaelic
+ zh_Hans: 苏格兰盖尔语
- value: sr
label:
en_US: Serbian
zh_Hans: 塞尔维亚语
+ - value: sh
+ label:
+ en_US: Serbo-Croatian
+ zh_Hans: 塞尔维亚-克罗地亚语
+ - value: st
+ label:
+ en_US: Sesotho
+ zh_Hans: 塞索托语
+ - value: tn
+ label:
+ en_US: Setswana
+ zh_Hans: 塞茨瓦纳语
+ - value: crs
+ label:
+ en_US: Seychellois Creole
+ zh_Hans: 塞舌尔克里奥尔语
+ - value: sn
+ label:
+ en_US: Shona
+ zh_Hans: 绍纳语
+ - value: sd
+ label:
+ en_US: Sindhi
+ zh_Hans: 信德语
+ - value: si
+ label:
+ en_US: Sinhalese
+ zh_Hans: 僧伽罗语
- value: sk
label:
en_US: Slovak
@@ -425,18 +1262,42 @@ parameters:
label:
en_US: Slovenian
zh_Hans: 斯洛文尼亚语
+ - value: so
+ label:
+ en_US: Somali
+ zh_Hans: 索马里语
- value: es
label:
en_US: Spanish
zh_Hans: 西班牙语
+ - value: es-419
+ label:
+ en_US: Spanish (Latin American)
+ zh_Hans: 西班牙语(拉丁美洲)
+ - value: su
+ label:
+ en_US: Sundanese
+ zh_Hans: 巽他语
+ - value: sw
+ label:
+ en_US: Swahili
+ zh_Hans: 斯瓦希里语
- value: sv
label:
en_US: Swedish
zh_Hans: 瑞典语
+ - value: tg
+ label:
+ en_US: Tajik
+ zh_Hans: 塔吉克语
- value: ta
label:
en_US: Tamil
zh_Hans: 泰米尔语
+ - value: tt
+ label:
+ en_US: Tatar
+ zh_Hans: 鞑靼语
- value: te
label:
en_US: Telugu
@@ -445,18 +1306,82 @@ parameters:
label:
en_US: Thai
zh_Hans: 泰语
+ - value: ti
+ label:
+ en_US: Tigrinya
+ zh_Hans: 提格利尼亚语
+ - value: to
+ label:
+ en_US: Tonga
+ zh_Hans: 汤加语
+ - value: lua
+ label:
+ en_US: Tshiluba
+ zh_Hans: 卢巴语
+ - value: tum
+ label:
+ en_US: Tumbuka
+ zh_Hans: 图布卡语
- value: tr
label:
en_US: Turkish
zh_Hans: 土耳其语
+ - value: tk
+ label:
+ en_US: Turkmen
+ zh_Hans: 土库曼语
+ - value: tw
+ label:
+ en_US: Twi
+ zh_Hans: 契维语
+ - value: ug
+ label:
+ en_US: Uighur
+ zh_Hans: 维吾尔语
- value: uk
label:
en_US: Ukrainian
zh_Hans: 乌克兰语
+ - value: ur
+ label:
+ en_US: Urdu
+ zh_Hans: 乌尔都语
+ - value: uz
+ label:
+ en_US: Uzbek
+ zh_Hans: 乌兹别克语
+ - value: vu
+ label:
+ en_US: Vanuatu
+ zh_Hans: 瓦努阿图语
- value: vi
label:
en_US: Vietnamese
zh_Hans: 越南语
+ - value: cy
+ label:
+ en_US: Welsh
+ zh_Hans: 威尔士语
+ - value: wo
+ label:
+ en_US: Wolof
+ zh_Hans: 沃洛夫语
+ - value: xh
+ label:
+ en_US: Xhosa
+ zh_Hans: 科萨语
+ - value: yi
+ label:
+ en_US: Yiddish
+ zh_Hans: 意第绪语
+ - value: yo
+ label:
+ en_US: Yoruba
+ zh_Hans: 约鲁巴语
+ - value: zu
+ label:
+ en_US: Zulu
+ zh_Hans: 祖鲁语
- name: is_remote
type: select
label:
diff --git a/api/core/tools/provider/builtin/searchapi/tools/google_news.yaml b/api/core/tools/provider/builtin/searchapi/tools/google_news.yaml
index cbb0edf982..ff34af34cc 100644
--- a/api/core/tools/provider/builtin/searchapi/tools/google_news.yaml
+++ b/api/core/tools/provider/builtin/searchapi/tools/google_news.yaml
@@ -65,206 +65,1206 @@ parameters:
form: form
default: US
options:
+ - value: AF
+ label:
+ en_US: Afghanistan
+ zh_Hans: 阿富汗
+ pt_BR: Afeganistão
+ - value: AL
+ label:
+ en_US: Albania
+ zh_Hans: 阿尔巴尼亚
+ pt_BR: Albânia
+ - value: DZ
+ label:
+ en_US: Algeria
+ zh_Hans: 阿尔及利亚
+ pt_BR: Argélia
+ - value: AS
+ label:
+ en_US: American Samoa
+ zh_Hans: 美属萨摩亚
+ pt_BR: Samoa Americana
+ - value: AD
+ label:
+ en_US: Andorra
+ zh_Hans: 安道尔
+ pt_BR: Andorra
+ - value: AO
+ label:
+ en_US: Angola
+ zh_Hans: 安哥拉
+ pt_BR: Angola
+ - value: AI
+ label:
+ en_US: Anguilla
+ zh_Hans: 安圭拉
+ pt_BR: Anguilla
+ - value: AQ
+ label:
+ en_US: Antarctica
+ zh_Hans: 南极洲
+ pt_BR: Antártica
+ - value: AG
+ label:
+ en_US: Antigua and Barbuda
+ zh_Hans: 安提瓜和巴布达
+ pt_BR: Antígua e Barbuda
- value: AR
label:
en_US: Argentina
zh_Hans: 阿根廷
pt_BR: Argentina
+ - value: AM
+ label:
+ en_US: Armenia
+ zh_Hans: 亚美尼亚
+ pt_BR: Armênia
+ - value: AW
+ label:
+ en_US: Aruba
+ zh_Hans: 阿鲁巴
+ pt_BR: Aruba
- value: AU
label:
en_US: Australia
zh_Hans: 澳大利亚
- pt_BR: Australia
+ pt_BR: Austrália
- value: AT
label:
en_US: Austria
zh_Hans: 奥地利
- pt_BR: Austria
+ pt_BR: Áustria
+ - value: AZ
+ label:
+ en_US: Azerbaijan
+ zh_Hans: 阿塞拜疆
+ pt_BR: Azerbaijão
+ - value: BS
+ label:
+ en_US: Bahamas
+ zh_Hans: 巴哈马
+ pt_BR: Bahamas
+ - value: BH
+ label:
+ en_US: Bahrain
+ zh_Hans: 巴林
+ pt_BR: Bahrein
+ - value: BD
+ label:
+ en_US: Bangladesh
+ zh_Hans: 孟加拉国
+ pt_BR: Bangladesh
+ - value: BB
+ label:
+ en_US: Barbados
+ zh_Hans: 巴巴多斯
+ pt_BR: Barbados
+ - value: BY
+ label:
+ en_US: Belarus
+ zh_Hans: 白俄罗斯
+ pt_BR: Bielorrússia
- value: BE
label:
en_US: Belgium
zh_Hans: 比利时
- pt_BR: Belgium
+ pt_BR: Bélgica
+ - value: BZ
+ label:
+ en_US: Belize
+ zh_Hans: 伯利兹
+ pt_BR: Belize
+ - value: BJ
+ label:
+ en_US: Benin
+ zh_Hans: 贝宁
+ pt_BR: Benim
+ - value: BM
+ label:
+ en_US: Bermuda
+ zh_Hans: 百慕大
+ pt_BR: Bermudas
+ - value: BT
+ label:
+ en_US: Bhutan
+ zh_Hans: 不丹
+ pt_BR: Butão
+ - value: BO
+ label:
+ en_US: Bolivia
+ zh_Hans: 玻利维亚
+ pt_BR: Bolívia
+ - value: BA
+ label:
+ en_US: Bosnia and Herzegovina
+ zh_Hans: 波斯尼亚和黑塞哥维那
+ pt_BR: Bósnia e Herzegovina
+ - value: BW
+ label:
+ en_US: Botswana
+ zh_Hans: 博茨瓦纳
+ pt_BR: Botsuana
+ - value: BV
+ label:
+ en_US: Bouvet Island
+ zh_Hans: 布韦岛
+ pt_BR: Ilha Bouvet
- value: BR
label:
en_US: Brazil
zh_Hans: 巴西
- pt_BR: Brazil
+ pt_BR: Brasil
+ - value: IO
+ label:
+ en_US: British Indian Ocean Territory
+ zh_Hans: 英属印度洋领地
+ pt_BR: Território Britânico do Oceano Índico
+ - value: BN
+ label:
+ en_US: Brunei Darussalam
+ zh_Hans: 文莱
+ pt_BR: Brunei Darussalam
+ - value: BG
+ label:
+ en_US: Bulgaria
+ zh_Hans: 保加利亚
+ pt_BR: Bulgária
+ - value: BF
+ label:
+ en_US: Burkina Faso
+ zh_Hans: 布基纳法索
+ pt_BR: Burkina Faso
+ - value: BI
+ label:
+ en_US: Burundi
+ zh_Hans: 布隆迪
+ pt_BR: Burundi
+ - value: KH
+ label:
+ en_US: Cambodia
+ zh_Hans: 柬埔寨
+ pt_BR: Camboja
+ - value: CM
+ label:
+ en_US: Cameroon
+ zh_Hans: 喀麦隆
+ pt_BR: Camarões
- value: CA
label:
en_US: Canada
zh_Hans: 加拿大
- pt_BR: Canada
+ pt_BR: Canadá
+ - value: CV
+ label:
+ en_US: Cape Verde
+ zh_Hans: 佛得角
+ pt_BR: Cabo Verde
+ - value: KY
+ label:
+ en_US: Cayman Islands
+ zh_Hans: 开曼群岛
+ pt_BR: Ilhas Cayman
+ - value: CF
+ label:
+ en_US: Central African Republic
+ zh_Hans: 中非共和国
+ pt_BR: República Centro-Africana
+ - value: TD
+ label:
+ en_US: Chad
+ zh_Hans: 乍得
+ pt_BR: Chade
- value: CL
label:
en_US: Chile
zh_Hans: 智利
pt_BR: Chile
- - value: CO
- label:
- en_US: Colombia
- zh_Hans: 哥伦比亚
- pt_BR: Colombia
- value: CN
label:
en_US: China
zh_Hans: 中国
pt_BR: China
+ - value: CX
+ label:
+ en_US: Christmas Island
+ zh_Hans: 圣诞岛
+ pt_BR: Ilha do Natal
+ - value: CC
+ label:
+ en_US: Cocos (Keeling) Islands
+ zh_Hans: 科科斯(基林)群岛
+ pt_BR: Ilhas Cocos (Keeling)
+ - value: CO
+ label:
+ en_US: Colombia
+ zh_Hans: 哥伦比亚
+ pt_BR: Colômbia
+ - value: KM
+ label:
+ en_US: Comoros
+ zh_Hans: 科摩罗
+ pt_BR: Comores
+ - value: CG
+ label:
+ en_US: Congo
+ zh_Hans: 刚果
+ pt_BR: Congo
+ - value: CD
+ label:
+ en_US: Congo, the Democratic Republic of the
+ zh_Hans: 刚果民主共和国
+ pt_BR: Congo, República Democrática do
+ - value: CK
+ label:
+ en_US: Cook Islands
+ zh_Hans: 库克群岛
+ pt_BR: Ilhas Cook
+ - value: CR
+ label:
+ en_US: Costa Rica
+ zh_Hans: 哥斯达黎加
+ pt_BR: Costa Rica
+ - value: CI
+ label:
+ en_US: Cote D'ivoire
+ zh_Hans: 科特迪瓦
+ pt_BR: Costa do Marfim
+ - value: HR
+ label:
+ en_US: Croatia
+ zh_Hans: 克罗地亚
+ pt_BR: Croácia
+ - value: CU
+ label:
+ en_US: Cuba
+ zh_Hans: 古巴
+ pt_BR: Cuba
+ - value: CY
+ label:
+ en_US: Cyprus
+ zh_Hans: 塞浦路斯
+ pt_BR: Chipre
- value: CZ
label:
en_US: Czech Republic
zh_Hans: 捷克共和国
- pt_BR: Czech Republic
+ pt_BR: República Tcheca
- value: DK
label:
en_US: Denmark
zh_Hans: 丹麦
- pt_BR: Denmark
+ pt_BR: Dinamarca
+ - value: DJ
+ label:
+ en_US: Djibouti
+ zh_Hans: 吉布提
+ pt_BR: Djibuti
+ - value: DM
+ label:
+ en_US: Dominica
+ zh_Hans: 多米尼克
+ pt_BR: Dominica
+ - value: DO
+ label:
+ en_US: Dominican Republic
+ zh_Hans: 多米尼加共和国
+ pt_BR: República Dominicana
+ - value: EC
+ label:
+ en_US: Ecuador
+ zh_Hans: 厄瓜多尔
+ pt_BR: Equador
+ - value: EG
+ label:
+ en_US: Egypt
+ zh_Hans: 埃及
+ pt_BR: Egito
+ - value: SV
+ label:
+ en_US: El Salvador
+ zh_Hans: 萨尔瓦多
+ pt_BR: El Salvador
+ - value: GQ
+ label:
+ en_US: Equatorial Guinea
+ zh_Hans: 赤道几内亚
+ pt_BR: Guiné Equatorial
+ - value: ER
+ label:
+ en_US: Eritrea
+ zh_Hans: 厄立特里亚
+ pt_BR: Eritreia
+ - value: EE
+ label:
+ en_US: Estonia
+ zh_Hans: 爱沙尼亚
+ pt_BR: Estônia
+ - value: ET
+ label:
+ en_US: Ethiopia
+ zh_Hans: 埃塞俄比亚
+ pt_BR: Etiópia
+ - value: FK
+ label:
+ en_US: Falkland Islands (Malvinas)
+ zh_Hans: 福克兰群岛(马尔维纳斯)
+ pt_BR: Ilhas Falkland (Malvinas)
+ - value: FO
+ label:
+ en_US: Faroe Islands
+ zh_Hans: 法罗群岛
+ pt_BR: Ilhas Faroe
+ - value: FJ
+ label:
+ en_US: Fiji
+ zh_Hans: 斐济
+ pt_BR: Fiji
- value: FI
label:
en_US: Finland
zh_Hans: 芬兰
- pt_BR: Finland
+ pt_BR: Finlândia
- value: FR
label:
en_US: France
zh_Hans: 法国
- pt_BR: France
+ pt_BR: França
+ - value: GF
+ label:
+ en_US: French Guiana
+ zh_Hans: 法属圭亚那
+ pt_BR: Guiana Francesa
+ - value: PF
+ label:
+ en_US: French Polynesia
+ zh_Hans: 法属波利尼西亚
+ pt_BR: Polinésia Francesa
+ - value: TF
+ label:
+ en_US: French Southern Territories
+ zh_Hans: 法属南部领地
+ pt_BR: Territórios Franceses do Sul
+ - value: GA
+ label:
+ en_US: Gabon
+ zh_Hans: 加蓬
+ pt_BR: Gabão
+ - value: GM
+ label:
+ en_US: Gambia
+ zh_Hans: 冈比亚
+ pt_BR: Gâmbia
+ - value: GE
+ label:
+ en_US: Georgia
+ zh_Hans: 格鲁吉亚
+ pt_BR: Geórgia
- value: DE
label:
en_US: Germany
zh_Hans: 德国
- pt_BR: Germany
+ pt_BR: Alemanha
+ - value: GH
+ label:
+ en_US: Ghana
+ zh_Hans: 加纳
+ pt_BR: Gana
+ - value: GI
+ label:
+ en_US: Gibraltar
+ zh_Hans: 直布罗陀
+ pt_BR: Gibraltar
+ - value: GR
+ label:
+ en_US: Greece
+ zh_Hans: 希腊
+ pt_BR: Grécia
+ - value: GL
+ label:
+ en_US: Greenland
+ zh_Hans: 格陵兰
+ pt_BR: Groenlândia
+ - value: GD
+ label:
+ en_US: Grenada
+ zh_Hans: 格林纳达
+ pt_BR: Granada
+ - value: GP
+ label:
+ en_US: Guadeloupe
+ zh_Hans: 瓜德罗普
+ pt_BR: Guadalupe
+ - value: GU
+ label:
+ en_US: Guam
+ zh_Hans: 关岛
+ pt_BR: Guam
+ - value: GT
+ label:
+ en_US: Guatemala
+ zh_Hans: 危地马拉
+ pt_BR: Guatemala
+ - value: GN
+ label:
+ en_US: Guinea
+ zh_Hans: 几内亚
+ pt_BR: Guiné
+ - value: GW
+ label:
+ en_US: Guinea-Bissau
+ zh_Hans: 几内亚比绍
+ pt_BR: Guiné-Bissau
+ - value: GY
+ label:
+ en_US: Guyana
+ zh_Hans: 圭亚那
+ pt_BR: Guiana
+ - value: HT
+ label:
+ en_US: Haiti
+ zh_Hans: 海地
+ pt_BR: Haiti
+ - value: HM
+ label:
+ en_US: Heard Island and McDonald Islands
+ zh_Hans: 赫德岛和麦克唐纳群岛
+ pt_BR: Ilha Heard e Ilhas McDonald
+ - value: VA
+ label:
+ en_US: Holy See (Vatican City State)
+ zh_Hans: 教廷(梵蒂冈城国)
+ pt_BR: Santa Sé (Estado da Cidade do Vaticano)
+ - value: HN
+ label:
+ en_US: Honduras
+ zh_Hans: 洪都拉斯
+ pt_BR: Honduras
- value: HK
label:
en_US: Hong Kong
zh_Hans: 香港
pt_BR: Hong Kong
+ - value: HU
+ label:
+ en_US: Hungary
+ zh_Hans: 匈牙利
+ pt_BR: Hungria
+ - value: IS
+ label:
+ en_US: Iceland
+ zh_Hans: 冰岛
+ pt_BR: Islândia
- value: IN
label:
en_US: India
zh_Hans: 印度
- pt_BR: India
+ pt_BR: Índia
- value: ID
label:
en_US: Indonesia
zh_Hans: 印度尼西亚
- pt_BR: Indonesia
+ pt_BR: Indonésia
+ - value: IR
+ label:
+ en_US: Iran, Islamic Republic of
+ zh_Hans: 伊朗
+ pt_BR: Irã
+ - value: IQ
+ label:
+ en_US: Iraq
+ zh_Hans: 伊拉克
+ pt_BR: Iraque
+ - value: IE
+ label:
+ en_US: Ireland
+ zh_Hans: 爱尔兰
+ pt_BR: Irlanda
+ - value: IL
+ label:
+ en_US: Israel
+ zh_Hans: 以色列
+ pt_BR: Israel
- value: IT
label:
en_US: Italy
zh_Hans: 意大利
- pt_BR: Italy
+ pt_BR: Itália
+ - value: JM
+ label:
+ en_US: Jamaica
+ zh_Hans: 牙买加
+ pt_BR: Jamaica
- value: JP
label:
en_US: Japan
zh_Hans: 日本
- pt_BR: Japan
+ pt_BR: Japão
+ - value: JO
+ label:
+ en_US: Jordan
+ zh_Hans: 约旦
+ pt_BR: Jordânia
+ - value: KZ
+ label:
+ en_US: Kazakhstan
+ zh_Hans: 哈萨克斯坦
+ pt_BR: Cazaquistão
+ - value: KE
+ label:
+ en_US: Kenya
+ zh_Hans: 肯尼亚
+ pt_BR: Quênia
+ - value: KI
+ label:
+ en_US: Kiribati
+ zh_Hans: 基里巴斯
+ pt_BR: Kiribati
+ - value: KP
+ label:
+ en_US: Korea, Democratic People's Republic of
+ zh_Hans: 朝鲜
+ pt_BR: Coreia, República Democrática Popular da
- value: KR
label:
- en_US: Korea
+ en_US: Korea, Republic of
zh_Hans: 韩国
- pt_BR: Korea
+ pt_BR: Coreia, República da
+ - value: KW
+ label:
+ en_US: Kuwait
+ zh_Hans: 科威特
+ pt_BR: Kuwait
+ - value: KG
+ label:
+ en_US: Kyrgyzstan
+ zh_Hans: 吉尔吉斯斯坦
+ pt_BR: Quirguistão
+ - value: LA
+ label:
+ en_US: Lao People's Democratic Republic
+ zh_Hans: 老挝
+ pt_BR: República Democrática Popular do Laos
+ - value: LV
+ label:
+ en_US: Latvia
+ zh_Hans: 拉脱维亚
+ pt_BR: Letônia
+ - value: LB
+ label:
+ en_US: Lebanon
+ zh_Hans: 黎巴嫩
+ pt_BR: Líbano
+ - value: LS
+ label:
+ en_US: Lesotho
+ zh_Hans: 莱索托
+ pt_BR: Lesoto
+ - value: LR
+ label:
+ en_US: Liberia
+ zh_Hans: 利比里亚
+ pt_BR: Libéria
+ - value: LY
+ label:
+ en_US: Libyan Arab Jamahiriya
+ zh_Hans: 利比亚
+ pt_BR: Líbia
+ - value: LI
+ label:
+ en_US: Liechtenstein
+ zh_Hans: 列支敦士登
+ pt_BR: Liechtenstein
+ - value: LT
+ label:
+ en_US: Lithuania
+ zh_Hans: 立陶宛
+ pt_BR: Lituânia
+ - value: LU
+ label:
+ en_US: Luxembourg
+ zh_Hans: 卢森堡
+ pt_BR: Luxemburgo
+ - value: MO
+ label:
+ en_US: Macao
+ zh_Hans: 澳门
+ pt_BR: Macau
+ - value: MK
+ label:
+ en_US: Macedonia, the Former Yugosalv Republic of
+ zh_Hans: 前南斯拉夫马其顿共和国
+ pt_BR: Macedônia, Ex-República Iugoslava da
+ - value: MG
+ label:
+ en_US: Madagascar
+ zh_Hans: 马达加斯加
+ pt_BR: Madagascar
+ - value: MW
+ label:
+ en_US: Malawi
+ zh_Hans: 马拉维
+ pt_BR: Malaui
- value: MY
label:
en_US: Malaysia
zh_Hans: 马来西亚
- pt_BR: Malaysia
+ pt_BR: Malásia
+ - value: MV
+ label:
+ en_US: Maldives
+ zh_Hans: 马尔代夫
+ pt_BR: Maldivas
+ - value: ML
+ label:
+ en_US: Mali
+ zh_Hans: 马里
+ pt_BR: Mali
+ - value: MT
+ label:
+ en_US: Malta
+ zh_Hans: 马耳他
+ pt_BR: Malta
+ - value: MH
+ label:
+ en_US: Marshall Islands
+ zh_Hans: 马绍尔群岛
+ pt_BR: Ilhas Marshall
+ - value: MQ
+ label:
+ en_US: Martinique
+ zh_Hans: 马提尼克
+ pt_BR: Martinica
+ - value: MR
+ label:
+ en_US: Mauritania
+ zh_Hans: 毛里塔尼亚
+ pt_BR: Mauritânia
+ - value: MU
+ label:
+ en_US: Mauritius
+ zh_Hans: 毛里求斯
+ pt_BR: Maurício
+ - value: YT
+ label:
+ en_US: Mayotte
+ zh_Hans: 马约特
+ pt_BR: Mayotte
- value: MX
label:
en_US: Mexico
zh_Hans: 墨西哥
- pt_BR: Mexico
+ pt_BR: México
+ - value: FM
+ label:
+ en_US: Micronesia, Federated States of
+ zh_Hans: 密克罗尼西亚联邦
+ pt_BR: Micronésia, Estados Federados da
+ - value: MD
+ label:
+ en_US: Moldova, Republic of
+ zh_Hans: 摩尔多瓦共和国
+ pt_BR: Moldávia, República da
+ - value: MC
+ label:
+ en_US: Monaco
+ zh_Hans: 摩纳哥
+ pt_BR: Mônaco
+ - value: MN
+ label:
+ en_US: Mongolia
+ zh_Hans: 蒙古
+ pt_BR: Mongólia
+ - value: MS
+ label:
+ en_US: Montserrat
+ zh_Hans: 蒙特塞拉特
+ pt_BR: Montserrat
+ - value: MA
+ label:
+ en_US: Morocco
+ zh_Hans: 摩洛哥
+ pt_BR: Marrocos
+ - value: MZ
+ label:
+ en_US: Mozambique
+ zh_Hans: 莫桑比克
+ pt_BR: Moçambique
+ - value: MM
+ label:
+ en_US: Myanmar
+ zh_Hans: 缅甸
+ pt_BR: Mianmar
+ - value: NA
+ label:
+ en_US: Namibia
+ zh_Hans: 纳米比亚
+ pt_BR: Namíbia
+ - value: NR
+ label:
+ en_US: Nauru
+ zh_Hans: 瑙鲁
+ pt_BR: Nauru
+ - value: NP
+ label:
+ en_US: Nepal
+ zh_Hans: 尼泊尔
+ pt_BR: Nepal
- value: NL
label:
en_US: Netherlands
zh_Hans: 荷兰
- pt_BR: Netherlands
+ pt_BR: Países Baixos
+ - value: AN
+ label:
+ en_US: Netherlands Antilles
+ zh_Hans: 荷属安的列斯
+ pt_BR: Antilhas Holandesas
+ - value: NC
+ label:
+ en_US: New Caledonia
+ zh_Hans: 新喀里多尼亚
+ pt_BR: Nova Caledônia
- value: NZ
label:
en_US: New Zealand
zh_Hans: 新西兰
- pt_BR: New Zealand
- - value: 'NO'
+ pt_BR: Nova Zelândia
+ - value: NI
+ label:
+ en_US: Nicaragua
+ zh_Hans: 尼加拉瓜
+ pt_BR: Nicarágua
+ - value: NE
+ label:
+ en_US: Niger
+ zh_Hans: 尼日尔
+ pt_BR: Níger
+ - value: NG
+ label:
+ en_US: Nigeria
+ zh_Hans: 尼日利亚
+ pt_BR: Nigéria
+ - value: NU
+ label:
+ en_US: Niue
+ zh_Hans: 纽埃
+ pt_BR: Niue
+ - value: NF
+ label:
+ en_US: Norfolk Island
+ zh_Hans: 诺福克岛
+ pt_BR: Ilha Norfolk
+ - value: MP
+ label:
+ en_US: Northern Mariana Islands
+ zh_Hans: 北马里亚纳群岛
+ pt_BR: Ilhas Marianas do Norte
+ - value: "NO"
label:
en_US: Norway
zh_Hans: 挪威
- pt_BR: Norway
+ pt_BR: Noruega
+ - value: OM
+ label:
+ en_US: Oman
+ zh_Hans: 阿曼
+ pt_BR: Omã
+ - value: PK
+ label:
+ en_US: Pakistan
+ zh_Hans: 巴基斯坦
+ pt_BR: Paquistão
+ - value: PW
+ label:
+ en_US: Palau
+ zh_Hans: 帕劳
+ pt_BR: Palau
+ - value: PS
+ label:
+ en_US: Palestinian Territory, Occupied
+ zh_Hans: 巴勒斯坦领土
+ pt_BR: Palestina, Território Ocupado
+ - value: PA
+ label:
+ en_US: Panama
+ zh_Hans: 巴拿马
+ pt_BR: Panamá
+ - value: PG
+ label:
+ en_US: Papua New Guinea
+ zh_Hans: 巴布亚新几内亚
+ pt_BR: Papua Nova Guiné
+ - value: PY
+ label:
+ en_US: Paraguay
+ zh_Hans: 巴拉圭
+ pt_BR: Paraguai
+ - value: PE
+ label:
+ en_US: Peru
+ zh_Hans: 秘鲁
+ pt_BR: Peru
- value: PH
label:
en_US: Philippines
zh_Hans: 菲律宾
- pt_BR: Philippines
+ pt_BR: Filipinas
+ - value: PN
+ label:
+ en_US: Pitcairn
+ zh_Hans: 皮特凯恩岛
+ pt_BR: Pitcairn
- value: PL
label:
en_US: Poland
zh_Hans: 波兰
- pt_BR: Poland
+ pt_BR: Polônia
- value: PT
label:
en_US: Portugal
zh_Hans: 葡萄牙
pt_BR: Portugal
+ - value: PR
+ label:
+ en_US: Puerto Rico
+ zh_Hans: 波多黎各
+ pt_BR: Porto Rico
+ - value: QA
+ label:
+ en_US: Qatar
+ zh_Hans: 卡塔尔
+ pt_BR: Catar
+ - value: RE
+ label:
+ en_US: Reunion
+ zh_Hans: 留尼旺
+ pt_BR: Reunião
+ - value: RO
+ label:
+ en_US: Romania
+ zh_Hans: 罗马尼亚
+ pt_BR: Romênia
- value: RU
label:
- en_US: Russia
- zh_Hans: 俄罗斯
- pt_BR: Russia
+ en_US: Russian Federation
+ zh_Hans: 俄罗斯联邦
+ pt_BR: Rússia
+ - value: RW
+ label:
+ en_US: Rwanda
+ zh_Hans: 卢旺达
+ pt_BR: Ruanda
+ - value: SH
+ label:
+ en_US: Saint Helena
+ zh_Hans: 圣赫勒拿
+ pt_BR: Santa Helena
+ - value: KN
+ label:
+ en_US: Saint Kitts and Nevis
+ zh_Hans: 圣基茨和尼维斯
+ pt_BR: São Cristóvão e Nevis
+ - value: LC
+ label:
+ en_US: Saint Lucia
+ zh_Hans: 圣卢西亚
+ pt_BR: Santa Lúcia
+ - value: PM
+ label:
+ en_US: Saint Pierre and Miquelon
+ zh_Hans: 圣皮埃尔和密克隆
+ pt_BR: São Pedro e Miquelon
+ - value: VC
+ label:
+ en_US: Saint Vincent and the Grenadines
+ zh_Hans: 圣文森特和格林纳丁斯
+ pt_BR: São Vicente e Granadinas
+ - value: WS
+ label:
+ en_US: Samoa
+ zh_Hans: 萨摩亚
+ pt_BR: Samoa
+ - value: SM
+ label:
+ en_US: San Marino
+ zh_Hans: 圣马力诺
+ pt_BR: San Marino
+ - value: ST
+ label:
+ en_US: Sao Tome and Principe
+ zh_Hans: 圣多美和普林西比
+ pt_BR: São Tomé e Príncipe
- value: SA
label:
en_US: Saudi Arabia
zh_Hans: 沙特阿拉伯
- pt_BR: Saudi Arabia
+ pt_BR: Arábia Saudita
+ - value: SN
+ label:
+ en_US: Senegal
+ zh_Hans: 塞内加尔
+ pt_BR: Senegal
+ - value: RS
+ label:
+ en_US: Serbia and Montenegro
+ zh_Hans: 塞尔维亚和黑山
+ pt_BR: Sérvia e Montenegro
+ - value: SC
+ label:
+ en_US: Seychelles
+ zh_Hans: 塞舌尔
+ pt_BR: Seicheles
+ - value: SL
+ label:
+ en_US: Sierra Leone
+ zh_Hans: 塞拉利昂
+ pt_BR: Serra Leoa
- value: SG
label:
en_US: Singapore
zh_Hans: 新加坡
- pt_BR: Singapore
+ pt_BR: Singapura
+ - value: SK
+ label:
+ en_US: Slovakia
+ zh_Hans: 斯洛伐克
+ pt_BR: Eslováquia
+ - value: SI
+ label:
+ en_US: Slovenia
+ zh_Hans: 斯洛文尼亚
+ pt_BR: Eslovênia
+ - value: SB
+ label:
+ en_US: Solomon Islands
+ zh_Hans: 所罗门群岛
+ pt_BR: Ilhas Salomão
+ - value: SO
+ label:
+ en_US: Somalia
+ zh_Hans: 索马里
+ pt_BR: Somália
- value: ZA
label:
en_US: South Africa
zh_Hans: 南非
- pt_BR: South Africa
+ pt_BR: África do Sul
+ - value: GS
+ label:
+ en_US: South Georgia and the South Sandwich Islands
+ zh_Hans: 南乔治亚和南桑威奇群岛
+ pt_BR: Geórgia do Sul e Ilhas Sandwich do Sul
- value: ES
label:
en_US: Spain
zh_Hans: 西班牙
- pt_BR: Spain
+ pt_BR: Espanha
+ - value: LK
+ label:
+ en_US: Sri Lanka
+ zh_Hans: 斯里兰卡
+ pt_BR: Sri Lanka
+ - value: SD
+ label:
+ en_US: Sudan
+ zh_Hans: 苏丹
+ pt_BR: Sudão
+ - value: SR
+ label:
+ en_US: Suriname
+ zh_Hans: 苏里南
+ pt_BR: Suriname
+ - value: SJ
+ label:
+ en_US: Svalbard and Jan Mayen
+ zh_Hans: 斯瓦尔巴特和扬马延岛
+ pt_BR: Svalbard e Jan Mayen
+ - value: SZ
+ label:
+ en_US: Swaziland
+ zh_Hans: 斯威士兰
+ pt_BR: Essuatíni
- value: SE
label:
en_US: Sweden
zh_Hans: 瑞典
- pt_BR: Sweden
+ pt_BR: Suécia
- value: CH
label:
en_US: Switzerland
zh_Hans: 瑞士
- pt_BR: Switzerland
+ pt_BR: Suíça
+ - value: SY
+ label:
+ en_US: Syrian Arab Republic
+ zh_Hans: 叙利亚
+ pt_BR: Síria
- value: TW
label:
- en_US: Taiwan
+ en_US: Taiwan, Province of China
zh_Hans: 台湾
pt_BR: Taiwan
+ - value: TJ
+ label:
+ en_US: Tajikistan
+ zh_Hans: 塔吉克斯坦
+ pt_BR: Tajiquistão
+ - value: TZ
+ label:
+ en_US: Tanzania, United Republic of
+ zh_Hans: 坦桑尼亚联合共和国
+ pt_BR: Tanzânia
- value: TH
label:
en_US: Thailand
zh_Hans: 泰国
- pt_BR: Thailand
+ pt_BR: Tailândia
+ - value: TL
+ label:
+ en_US: Timor-Leste
+ zh_Hans: 东帝汶
+ pt_BR: Timor-Leste
+ - value: TG
+ label:
+ en_US: Togo
+ zh_Hans: 多哥
+ pt_BR: Togo
+ - value: TK
+ label:
+ en_US: Tokelau
+ zh_Hans: 托克劳
+ pt_BR: Toquelau
+ - value: TO
+ label:
+ en_US: Tonga
+ zh_Hans: 汤加
+ pt_BR: Tonga
+ - value: TT
+ label:
+ en_US: Trinidad and Tobago
+ zh_Hans: 特立尼达和多巴哥
+ pt_BR: Trindade e Tobago
+ - value: TN
+ label:
+ en_US: Tunisia
+ zh_Hans: 突尼斯
+ pt_BR: Tunísia
- value: TR
label:
en_US: Turkey
zh_Hans: 土耳其
- pt_BR: Turkey
+ pt_BR: Turquia
+ - value: TM
+ label:
+ en_US: Turkmenistan
+ zh_Hans: 土库曼斯坦
+ pt_BR: Turcomenistão
+ - value: TC
+ label:
+ en_US: Turks and Caicos Islands
+ zh_Hans: 特克斯和凯科斯群岛
+ pt_BR: Ilhas Turks e Caicos
+ - value: TV
+ label:
+ en_US: Tuvalu
+ zh_Hans: 图瓦卢
+ pt_BR: Tuvalu
+ - value: UG
+ label:
+ en_US: Uganda
+ zh_Hans: 乌干达
+ pt_BR: Uganda
+ - value: UA
+ label:
+ en_US: Ukraine
+ zh_Hans: 乌克兰
+ pt_BR: Ucrânia
+ - value: AE
+ label:
+ en_US: United Arab Emirates
+ zh_Hans: 阿联酋
+ pt_BR: Emirados Árabes Unidos
+ - value: UK
+ label:
+ en_US: United Kingdom
+ zh_Hans: 英国
+ pt_BR: Reino Unido
- value: GB
label:
en_US: United Kingdom
zh_Hans: 英国
- pt_BR: United Kingdom
+ pt_BR: Reino Unido
- value: US
label:
en_US: United States
zh_Hans: 美国
- pt_BR: United States
+ pt_BR: Estados Unidos
+ - value: UM
+ label:
+ en_US: United States Minor Outlying Islands
+ zh_Hans: 美国本土外小岛屿
+ pt_BR: Ilhas Menores Distantes dos Estados Unidos
+ - value: UY
+ label:
+ en_US: Uruguay
+ zh_Hans: 乌拉圭
+ pt_BR: Uruguai
+ - value: UZ
+ label:
+ en_US: Uzbekistan
+ zh_Hans: 乌兹别克斯坦
+ pt_BR: Uzbequistão
+ - value: VU
+ label:
+ en_US: Vanuatu
+ zh_Hans: 瓦努阿图
+ pt_BR: Vanuatu
+ - value: VE
+ label:
+ en_US: Venezuela
+ zh_Hans: 委内瑞拉
+ pt_BR: Venezuela
+ - value: VN
+ label:
+ en_US: Viet Nam
+ zh_Hans: 越南
+ pt_BR: Vietnã
+ - value: VG
+ label:
+ en_US: Virgin Islands, British
+ zh_Hans: 英属维尔京群岛
+ pt_BR: Ilhas Virgens Britânicas
+ - value: VI
+ label:
+ en_US: Virgin Islands, U.S.
+ zh_Hans: 美属维尔京群岛
+ pt_BR: Ilhas Virgens dos EUA
+ - value: WF
+ label:
+ en_US: Wallis and Futuna
+ zh_Hans: 瓦利斯和富图纳群岛
+ pt_BR: Wallis e Futuna
+ - value: EH
+ label:
+ en_US: Western Sahara
+ zh_Hans: 西撒哈拉
+ pt_BR: Saara Ocidental
+ - value: YE
+ label:
+ en_US: Yemen
+ zh_Hans: 也门
+ pt_BR: Iémen
+ - value: ZM
+ label:
+ en_US: Zambia
+ zh_Hans: 赞比亚
+ pt_BR: Zâmbia
+ - value: ZW
+ label:
+ en_US: Zimbabwe
+ zh_Hans: 津巴布韦
+ pt_BR: Zimbábue
- name: hl
type: select
label:
@@ -277,18 +1277,94 @@ parameters:
default: en
form: form
options:
+ - value: af
+ label:
+ en_US: Afrikaans
+ zh_Hans: 南非语
+ - value: ak
+ label:
+ en_US: Akan
+ zh_Hans: 阿坎语
+ - value: sq
+ label:
+ en_US: Albanian
+ zh_Hans: 阿尔巴尼亚语
+ - value: ws
+ label:
+ en_US: Samoa
+ zh_Hans: 萨摩亚语
+ - value: am
+ label:
+ en_US: Amharic
+ zh_Hans: 阿姆哈拉语
- value: ar
label:
en_US: Arabic
zh_Hans: 阿拉伯语
+ - value: hy
+ label:
+ en_US: Armenian
+ zh_Hans: 亚美尼亚语
+ - value: az
+ label:
+ en_US: Azerbaijani
+ zh_Hans: 阿塞拜疆语
+ - value: eu
+ label:
+ en_US: Basque
+ zh_Hans: 巴斯克语
+ - value: be
+ label:
+ en_US: Belarusian
+ zh_Hans: 白俄罗斯语
+ - value: bem
+ label:
+ en_US: Bemba
+ zh_Hans: 班巴语
+ - value: bn
+ label:
+ en_US: Bengali
+ zh_Hans: 孟加拉语
+ - value: bh
+ label:
+ en_US: Bihari
+ zh_Hans: 比哈尔语
+ - value: xx-bork
+ label:
+ en_US: Bork, bork, bork!
+ zh_Hans: 博克语
+ - value: bs
+ label:
+ en_US: Bosnian
+ zh_Hans: 波斯尼亚语
+ - value: br
+ label:
+ en_US: Breton
+ zh_Hans: 布列塔尼语
- value: bg
label:
en_US: Bulgarian
zh_Hans: 保加利亚语
+ - value: bt
+ label:
+ en_US: Bhutanese
+ zh_Hans: 不丹语
+ - value: km
+ label:
+ en_US: Cambodian
+ zh_Hans: 高棉语
- value: ca
label:
en_US: Catalan
zh_Hans: 加泰罗尼亚语
+ - value: chr
+ label:
+ en_US: Cherokee
+ zh_Hans: 切罗基语
+ - value: ny
+ label:
+ en_US: Chichewa
+ zh_Hans: 齐切瓦语
- value: zh-cn
label:
en_US: Chinese (Simplified)
@@ -297,6 +1373,14 @@ parameters:
label:
en_US: Chinese (Traditional)
zh_Hans: 中文(繁体)
+ - value: co
+ label:
+ en_US: Corsican
+ zh_Hans: 科西嘉语
+ - value: hr
+ label:
+ en_US: Croatian
+ zh_Hans: 克罗地亚语
- value: cs
label:
en_US: Czech
@@ -309,14 +1393,34 @@ parameters:
label:
en_US: Dutch
zh_Hans: 荷兰语
+ - value: xx-elmer
+ label:
+ en_US: Elmer Fudd
+ zh_Hans: 艾尔默福德语
- value: en
label:
en_US: English
zh_Hans: 英语
+ - value: eo
+ label:
+ en_US: Esperanto
+ zh_Hans: 世界语
- value: et
label:
en_US: Estonian
zh_Hans: 爱沙尼亚语
+ - value: ee
+ label:
+ en_US: Ewe
+ zh_Hans: 埃维语
+ - value: fo
+ label:
+ en_US: Faroese
+ zh_Hans: 法罗语
+ - value: tl
+ label:
+ en_US: Filipino
+ zh_Hans: 菲律宾语
- value: fi
label:
en_US: Finnish
@@ -325,6 +1429,22 @@ parameters:
label:
en_US: French
zh_Hans: 法语
+ - value: fy
+ label:
+ en_US: Frisian
+ zh_Hans: 弗里西亚语
+ - value: gaa
+ label:
+ en_US: Ga
+ zh_Hans: 加语
+ - value: gl
+ label:
+ en_US: Galician
+ zh_Hans: 加利西亚语
+ - value: ka
+ label:
+ en_US: Georgian
+ zh_Hans: 格鲁吉亚语
- value: de
label:
en_US: German
@@ -333,6 +1453,34 @@ parameters:
label:
en_US: Greek
zh_Hans: 希腊语
+ - value: kl
+ label:
+ en_US: Greenlandic
+ zh_Hans: 格陵兰语
+ - value: gn
+ label:
+ en_US: Guarani
+ zh_Hans: 瓜拉尼语
+ - value: gu
+ label:
+ en_US: Gujarati
+ zh_Hans: 古吉拉特语
+ - value: xx-hacker
+ label:
+ en_US: Hacker
+ zh_Hans: 黑客语
+ - value: ht
+ label:
+ en_US: Haitian Creole
+ zh_Hans: 海地克里奥尔语
+ - value: ha
+ label:
+ en_US: Hausa
+ zh_Hans: 豪萨语
+ - value: haw
+ label:
+ en_US: Hawaiian
+ zh_Hans: 夏威夷语
- value: iw
label:
en_US: Hebrew
@@ -345,10 +1493,26 @@ parameters:
label:
en_US: Hungarian
zh_Hans: 匈牙利语
+ - value: is
+ label:
+ en_US: Icelandic
+ zh_Hans: 冰岛语
+ - value: ig
+ label:
+ en_US: Igbo
+ zh_Hans: 伊博语
- value: id
label:
en_US: Indonesian
zh_Hans: 印尼语
+ - value: ia
+ label:
+ en_US: Interlingua
+ zh_Hans: 国际语
+ - value: ga
+ label:
+ en_US: Irish
+ zh_Hans: 爱尔兰语
- value: it
label:
en_US: Italian
@@ -357,22 +1521,94 @@ parameters:
label:
en_US: Japanese
zh_Hans: 日语
+ - value: jw
+ label:
+ en_US: Javanese
+ zh_Hans: 爪哇语
- value: kn
label:
en_US: Kannada
zh_Hans: 卡纳达语
+ - value: kk
+ label:
+ en_US: Kazakh
+ zh_Hans: 哈萨克语
+ - value: rw
+ label:
+ en_US: Kinyarwanda
+ zh_Hans: 基尼亚卢旺达语
+ - value: rn
+ label:
+ en_US: Kirundi
+ zh_Hans: 基隆迪语
+ - value: xx-klingon
+ label:
+ en_US: Klingon
+ zh_Hans: 克林贡语
+ - value: kg
+ label:
+ en_US: Kongo
+ zh_Hans: 刚果语
- value: ko
label:
en_US: Korean
zh_Hans: 韩语
+ - value: kri
+ label:
+ en_US: Krio (Sierra Leone)
+ zh_Hans: 塞拉利昂克里奥尔语
+ - value: ku
+ label:
+ en_US: Kurdish
+ zh_Hans: 库尔德语
+ - value: ckb
+ label:
+ en_US: Kurdish (Soranî)
+ zh_Hans: 库尔德语(索拉尼)
+ - value: ky
+ label:
+ en_US: Kyrgyz
+ zh_Hans: 吉尔吉斯语
+ - value: lo
+ label:
+ en_US: Laothian
+ zh_Hans: 老挝语
+ - value: la
+ label:
+ en_US: Latin
+ zh_Hans: 拉丁语
- value: lv
label:
en_US: Latvian
zh_Hans: 拉脱维亚语
+ - value: ln
+ label:
+ en_US: Lingala
+ zh_Hans: 林加拉语
- value: lt
label:
en_US: Lithuanian
zh_Hans: 立陶宛语
+ - value: loz
+ label:
+ en_US: Lozi
+ zh_Hans: 洛齐语
+ - value: lg
+ label:
+ en_US: Luganda
+ zh_Hans: 卢干达语
+ - value: ach
+ label:
+ en_US: Luo
+ zh_Hans: 卢奥语
+ - value: mk
+ label:
+ en_US: Macedonian
+ zh_Hans: 马其顿语
+ - value: mg
+ label:
+ en_US: Malagasy
+ zh_Hans: 马尔加什语
- value: my
label:
en_US: Malay
@@ -381,18 +1617,90 @@ parameters:
label:
en_US: Malayalam
zh_Hans: 马拉雅拉姆语
+ - value: mt
+ label:
+ en_US: Maltese
+ zh_Hans: 马耳他语
+ - value: mv
+ label:
+ en_US: Maldives
+ zh_Hans: 马尔代夫语
+ - value: mi
+ label:
+ en_US: Maori
+ zh_Hans: 毛利语
- value: mr
label:
en_US: Marathi
zh_Hans: 马拉地语
+ - value: mfe
+ label:
+ en_US: Mauritian Creole
+ zh_Hans: 毛里求斯克里奥尔语
+ - value: mo
+ label:
+ en_US: Moldavian
+ zh_Hans: 摩尔达维亚语
+ - value: mn
+ label:
+ en_US: Mongolian
+ zh_Hans: 蒙古语
+ - value: sr-me
+ label:
+ en_US: Montenegrin
+ zh_Hans: 黑山语
+ - value: ne
+ label:
+ en_US: Nepali
+ zh_Hans: 尼泊尔语
+ - value: pcm
+ label:
+ en_US: Nigerian Pidgin
+ zh_Hans: 尼日利亚皮钦语
+ - value: nso
+ label:
+ en_US: Northern Sotho
+ zh_Hans: 北索托语
- value: "no"
label:
en_US: Norwegian
zh_Hans: 挪威语
+ - value: nn
+ label:
+ en_US: Norwegian (Nynorsk)
+ zh_Hans: 挪威语(尼诺斯克语)
+ - value: oc
+ label:
+ en_US: Occitan
+ zh_Hans: 奥克语
+ - value: or
+ label:
+ en_US: Oriya
+ zh_Hans: 奥里亚语
+ - value: om
+ label:
+ en_US: Oromo
+ zh_Hans: 奥罗莫语
+ - value: ps
+ label:
+ en_US: Pashto
+ zh_Hans: 普什图语
+ - value: fa
+ label:
+ en_US: Persian
+ zh_Hans: 波斯语
+ - value: xx-pirate
+ label:
+ en_US: Pirate
+ zh_Hans: 海盗语
- value: pl
label:
en_US: Polish
zh_Hans: 波兰语
+ - value: pt
+ label:
+ en_US: Portuguese
+ zh_Hans: 葡萄牙语
- value: pt-br
label:
en_US: Portuguese (Brazil)
@@ -405,18 +1713,62 @@ parameters:
label:
en_US: Punjabi
zh_Hans: 旁遮普语
+ - value: qu
+ label:
+ en_US: Quechua
+ zh_Hans: 克丘亚语
- value: ro
label:
en_US: Romanian
zh_Hans: 罗马尼亚语
+ - value: rm
+ label:
+ en_US: Romansh
+ zh_Hans: 罗曼什语
+ - value: nyn
+ label:
+ en_US: Runyakitara
+ zh_Hans: 卢尼亚基塔拉语
- value: ru
label:
en_US: Russian
zh_Hans: 俄语
+ - value: gd
+ label:
+ en_US: Scots Gaelic
+ zh_Hans: 苏格兰盖尔语
- value: sr
label:
en_US: Serbian
zh_Hans: 塞尔维亚语
+ - value: sh
+ label:
+ en_US: Serbo-Croatian
+ zh_Hans: 塞尔维亚-克罗地亚语
+ - value: st
+ label:
+ en_US: Sesotho
+ zh_Hans: 塞索托语
+ - value: tn
+ label:
+ en_US: Setswana
+ zh_Hans: 塞茨瓦纳语
+ - value: crs
+ label:
+ en_US: Seychellois Creole
+ zh_Hans: 塞舌尔克里奥尔语
+ - value: sn
+ label:
+ en_US: Shona
+ zh_Hans: 绍纳语
+ - value: sd
+ label:
+ en_US: Sindhi
+ zh_Hans: 信德语
+ - value: si
+ label:
+ en_US: Sinhalese
+ zh_Hans: 僧伽罗语
- value: sk
label:
en_US: Slovak
@@ -425,18 +1777,42 @@ parameters:
label:
en_US: Slovenian
zh_Hans: 斯洛文尼亚语
+ - value: so
+ label:
+ en_US: Somali
+ zh_Hans: 索马里语
- value: es
label:
en_US: Spanish
zh_Hans: 西班牙语
+ - value: es-419
+ label:
+ en_US: Spanish (Latin American)
+ zh_Hans: 西班牙语(拉丁美洲)
+ - value: su
+ label:
+ en_US: Sundanese
+ zh_Hans: 巽他语
+ - value: sw
+ label:
+ en_US: Swahili
+ zh_Hans: 斯瓦希里语
- value: sv
label:
en_US: Swedish
zh_Hans: 瑞典语
+ - value: tg
+ label:
+ en_US: Tajik
+ zh_Hans: 塔吉克语
- value: ta
label:
en_US: Tamil
zh_Hans: 泰米尔语
+ - value: tt
+ label:
+ en_US: Tatar
+ zh_Hans: 鞑靼语
- value: te
label:
en_US: Telugu
@@ -445,18 +1821,82 @@ parameters:
label:
en_US: Thai
zh_Hans: 泰语
+ - value: ti
+ label:
+ en_US: Tigrinya
+ zh_Hans: 提格利尼亚语
+ - value: to
+ label:
+ en_US: Tonga
+ zh_Hans: 汤加语
+ - value: lua
+ label:
+ en_US: Tshiluba
+ zh_Hans: 卢巴语
+ - value: tum
+ label:
+ en_US: Tumbuka
+ zh_Hans: 图布卡语
- value: tr
label:
en_US: Turkish
zh_Hans: 土耳其语
+ - value: tk
+ label:
+ en_US: Turkmen
+ zh_Hans: 土库曼语
+ - value: tw
+ label:
+ en_US: Twi
+ zh_Hans: 契维语
+ - value: ug
+ label:
+ en_US: Uighur
+ zh_Hans: 维吾尔语
- value: uk
label:
en_US: Ukrainian
zh_Hans: 乌克兰语
+ - value: ur
+ label:
+ en_US: Urdu
+ zh_Hans: 乌尔都语
+ - value: uz
+ label:
+ en_US: Uzbek
+ zh_Hans: 乌兹别克语
+ - value: vu
+ label:
+ en_US: Vanuatu
+ zh_Hans: 瓦努阿图语
- value: vi
label:
en_US: Vietnamese
zh_Hans: 越南语
+ - value: cy
+ label:
+ en_US: Welsh
+ zh_Hans: 威尔士语
+ - value: wo
+ label:
+ en_US: Wolof
+ zh_Hans: 沃洛夫语
+ - value: xh
+ label:
+ en_US: Xhosa
+ zh_Hans: 科萨语
+ - value: yi
+ label:
+ en_US: Yiddish
+ zh_Hans: 意第绪语
+ - value: yo
+ label:
+ en_US: Yoruba
+ zh_Hans: 约鲁巴语
+ - value: zu
+ label:
+ en_US: Zulu
+ zh_Hans: 祖鲁语
- name: google_domain
type: string
required: false
diff --git a/api/core/tools/provider/builtin/stepfun/tools/image.py b/api/core/tools/provider/builtin/stepfun/tools/image.py
index eb55dae518..61cc14fac6 100644
--- a/api/core/tools/provider/builtin/stepfun/tools/image.py
+++ b/api/core/tools/provider/builtin/stepfun/tools/image.py
@@ -32,16 +32,17 @@ class StepfunTool(BuiltinTool):
prompt = tool_parameters.get("prompt", "")
if not prompt:
return self.create_text_message("Please input prompt")
-
+ if len(prompt) > 1024:
+ return self.create_text_message("The prompt length should less than 1024")
seed = tool_parameters.get("seed", 0)
if seed > 0:
extra_body["seed"] = seed
- steps = tool_parameters.get("steps", 0)
+ steps = tool_parameters.get("steps", 50)
if steps > 0:
extra_body["steps"] = steps
- negative_prompt = tool_parameters.get("negative_prompt", "")
- if negative_prompt:
- extra_body["negative_prompt"] = negative_prompt
+ cfg_scale = tool_parameters.get("cfg_scale", 7.5)
+ if cfg_scale > 0:
+ extra_body["cfg_scale"] = cfg_scale
# call openapi stepfun model
response = client.images.generate(
@@ -51,7 +52,6 @@ class StepfunTool(BuiltinTool):
n=tool_parameters.get("n", 1),
extra_body=extra_body,
)
- print(response)
result = []
for image in response.data:
diff --git a/api/core/tools/provider/builtin/stepfun/tools/image.yaml b/api/core/tools/provider/builtin/stepfun/tools/image.yaml
index 8d7c9b6586..dfda6ed191 100644
--- a/api/core/tools/provider/builtin/stepfun/tools/image.yaml
+++ b/api/core/tools/provider/builtin/stepfun/tools/image.yaml
@@ -33,9 +33,9 @@ parameters:
type: select
required: false
human_description:
- en_US: used for selecting the image size
- zh_Hans: 用于选择图像大小
- pt_BR: used for selecting the image size
+ en_US: The size of the generated image
+ zh_Hans: 生成的图片大小
+ pt_BR: The size of the generated image
label:
en_US: Image size
zh_Hans: 图像大小
@@ -77,17 +77,17 @@ parameters:
type: number
required: true
human_description:
- en_US: used for selecting the number of images
- zh_Hans: 用于选择图像数量
- pt_BR: used for selecting the number of images
+ en_US: Number of generated images, now only one image can be generated at a time
+ zh_Hans: 生成的图像数量,当前仅支持每次生成一张图片
+ pt_BR: Number of generated images, now only one image can be generated at a time
label:
- en_US: Number of images
- zh_Hans: 图像数量
- pt_BR: Number of images
+ en_US: Number of generated images
+ zh_Hans: 生成的图像数量
+ pt_BR: Number of generated images
form: form
default: 1
min: 1
- max: 10
+ max: 1
- name: seed
type: number
required: false
@@ -109,21 +109,25 @@ parameters:
zh_Hans: Steps
pt_BR: Steps
human_description:
- en_US: Steps
- zh_Hans: Steps
- pt_BR: Steps
+ en_US: Steps, now support integers between 1 and 100
+ zh_Hans: Steps, 当前支持 1~100 之间整数
+ pt_BR: Steps, now support integers between 1 and 100
form: form
- default: 10
- - name: negative_prompt
- type: string
+ default: 50
+ min: 1
+ max: 100
+ - name: cfg_scale
+ type: number
required: false
label:
- en_US: Negative prompt
- zh_Hans: Negative prompt
- pt_BR: Negative prompt
+ en_US: classifier-free guidance scale
+ zh_Hans: classifier-free guidance scale
+ pt_BR: classifier-free guidance scale
human_description:
- en_US: Negative prompt
- zh_Hans: Negative prompt
- pt_BR: Negative prompt
+ en_US: classifier-free guidance scale
+ zh_Hans: classifier-free guidance scale
+ pt_BR: classifier-free guidance scale
form: form
- default: (worst quality:1.3), (nsfw), low quality
+ default: 7.5
+ min: 1
+ max: 10
diff --git a/api/core/tools/provider/builtin/time/tools/localtime_to_timestamp.py b/api/core/tools/provider/builtin/time/tools/localtime_to_timestamp.py
new file mode 100644
index 0000000000..e16b732d02
--- /dev/null
+++ b/api/core/tools/provider/builtin/time/tools/localtime_to_timestamp.py
@@ -0,0 +1,44 @@
+from datetime import datetime
+from typing import Any, Union
+
+import pytz
+
+from core.tools.entities.tool_entities import ToolInvokeMessage
+from core.tools.errors import ToolInvokeError
+from core.tools.tool.builtin_tool import BuiltinTool
+
+
+class LocaltimeToTimestampTool(BuiltinTool):
+ def _invoke(
+ self,
+ user_id: str,
+ tool_parameters: dict[str, Any],
+ ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
+ """
+ Convert localtime to timestamp
+ """
+ localtime = tool_parameters.get("localtime")
+ timezone = tool_parameters.get("timezone", "Asia/Shanghai")
+ if not timezone:
+ timezone = None
+ time_format = "%Y-%m-%d %H:%M:%S"
+
+ timestamp = self.localtime_to_timestamp(localtime, time_format, timezone)
+ if not timestamp:
+ return self.create_text_message(f"Invalid localtime: {localtime}")
+
+ return self.create_text_message(f"{timestamp}")
+
+ @staticmethod
+ def localtime_to_timestamp(localtime: str, time_format: str, local_tz=None) -> int | None:
+ try:
+ if local_tz is None:
+ local_tz = datetime.now().astimezone().tzinfo
+ if isinstance(local_tz, str):
+ local_tz = pytz.timezone(local_tz)
+ local_time = datetime.strptime(localtime, time_format)
+ localtime = local_tz.localize(local_time)
+ timestamp = int(localtime.timestamp())
+ return timestamp
+ except Exception as e:
+ raise ToolInvokeError(str(e))
diff --git a/api/core/tools/provider/builtin/time/tools/localtime_to_timestamp.yaml b/api/core/tools/provider/builtin/time/tools/localtime_to_timestamp.yaml
new file mode 100644
index 0000000000..6a3b90595f
--- /dev/null
+++ b/api/core/tools/provider/builtin/time/tools/localtime_to_timestamp.yaml
@@ -0,0 +1,33 @@
+identity:
+ name: localtime_to_timestamp
+ author: zhuhao
+ label:
+ en_US: localtime to timestamp
+ zh_Hans: 获取时间戳
+description:
+ human:
+ en_US: A tool for localtime convert to timestamp
+ zh_Hans: 获取时间戳
+ llm: A tool for localtime convert to timestamp
+parameters:
+ - name: localtime
+ type: string
+ required: true
+ form: llm
+ label:
+ en_US: localtime
+ zh_Hans: 本地时间
+ human_description:
+ en_US: localtime, such as 2024-1-1 0:0:0
+ zh_Hans: 本地时间, 比如2024-1-1 0:0:0
+ - name: timezone
+ type: string
+ required: false
+ form: llm
+ label:
+ en_US: Timezone
+ zh_Hans: 时区
+ human_description:
+ en_US: Timezone, such as Asia/Shanghai
+ zh_Hans: 时区, 比如Asia/Shanghai
+ default: Asia/Shanghai
diff --git a/api/core/tools/provider/builtin/time/tools/timestamp_to_localtime.py b/api/core/tools/provider/builtin/time/tools/timestamp_to_localtime.py
new file mode 100644
index 0000000000..bcdd34fd4e
--- /dev/null
+++ b/api/core/tools/provider/builtin/time/tools/timestamp_to_localtime.py
@@ -0,0 +1,44 @@
+from datetime import datetime
+from typing import Any, Union
+
+import pytz
+
+from core.tools.entities.tool_entities import ToolInvokeMessage
+from core.tools.errors import ToolInvokeError
+from core.tools.tool.builtin_tool import BuiltinTool
+
+
+class TimestampToLocaltimeTool(BuiltinTool):
+ def _invoke(
+ self,
+ user_id: str,
+ tool_parameters: dict[str, Any],
+ ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
+ """
+ Convert timestamp to localtime
+ """
+ timestamp = tool_parameters.get("timestamp")
+ timezone = tool_parameters.get("timezone", "Asia/Shanghai")
+ if not timezone:
+ timezone = None
+ time_format = "%Y-%m-%d %H:%M:%S"
+
+ locatime = self.timestamp_to_localtime(timestamp, timezone)
+ if not locatime:
+ return self.create_text_message(f"Invalid timestamp: {timestamp}")
+
+ localtime_format = locatime.strftime(time_format)
+
+ return self.create_text_message(f"{localtime_format}")
+
+ @staticmethod
+ def timestamp_to_localtime(timestamp: int, local_tz=None) -> datetime | None:
+ try:
+ if local_tz is None:
+ local_tz = datetime.now().astimezone().tzinfo
+ if isinstance(local_tz, str):
+ local_tz = pytz.timezone(local_tz)
+ local_time = datetime.fromtimestamp(timestamp, local_tz)
+ return local_time
+ except Exception as e:
+ raise ToolInvokeError(str(e))
diff --git a/api/core/tools/provider/builtin/time/tools/timestamp_to_localtime.yaml b/api/core/tools/provider/builtin/time/tools/timestamp_to_localtime.yaml
new file mode 100644
index 0000000000..3794e717b4
--- /dev/null
+++ b/api/core/tools/provider/builtin/time/tools/timestamp_to_localtime.yaml
@@ -0,0 +1,33 @@
+identity:
+ name: timestamp_to_localtime
+ author: zhuhao
+ label:
+ en_US: Timestamp to localtime
+ zh_Hans: 时间戳转换
+description:
+ human:
+ en_US: A tool for timestamp convert to localtime
+ zh_Hans: 时间戳转换
+ llm: A tool for timestamp convert to localtime
+parameters:
+ - name: timestamp
+ type: number
+ required: true
+ form: llm
+ label:
+ en_US: Timestamp
+ zh_Hans: 时间戳
+ human_description:
+ en_US: Timestamp
+ zh_Hans: 时间戳
+ - name: timezone
+ type: string
+ required: false
+ form: llm
+ label:
+ en_US: Timezone
+ zh_Hans: 时区
+ human_description:
+ en_US: Timezone, such as Asia/Shanghai
+ zh_Hans: 时区, 比如Asia/Shanghai
+ default: Asia/Shanghai
diff --git a/api/core/tools/provider/builtin/vanna/vanna.yaml b/api/core/tools/provider/builtin/vanna/vanna.yaml
index b29fa103e1..7f953be172 100644
--- a/api/core/tools/provider/builtin/vanna/vanna.yaml
+++ b/api/core/tools/provider/builtin/vanna/vanna.yaml
@@ -8,6 +8,9 @@ identity:
en_US: The fastest way to get actionable insights from your database just by asking questions.
zh_Hans: 一个基于大模型和RAG的Text2SQL工具。
icon: icon.png
+ tags:
+ - utilities
+ - productivity
credentials_for_provider:
api_key:
type: secret-input
diff --git a/api/core/tools/provider/builtin/xinference/tools/stable_diffusion.py b/api/core/tools/provider/builtin/xinference/tools/stable_diffusion.py
index 847f2730f2..a44d3b730a 100644
--- a/api/core/tools/provider/builtin/xinference/tools/stable_diffusion.py
+++ b/api/core/tools/provider/builtin/xinference/tools/stable_diffusion.py
@@ -104,14 +104,15 @@ class StableDiffusionTool(BuiltinTool):
model = self.runtime.credentials.get("model", None)
if not model:
return self.create_text_message("Please input model")
-
+ api_key = self.runtime.credentials.get("api_key") or "abc"
+ headers = {"Authorization": f"Bearer {api_key}"}
# set model
try:
url = str(URL(base_url) / "sdapi" / "v1" / "options")
response = post(
url,
json={"sd_model_checkpoint": model},
- headers={"Authorization": f"Bearer {self.runtime.credentials['api_key']}"},
+ headers=headers,
)
if response.status_code != 200:
raise ToolProviderCredentialValidationError("Failed to set model, please tell user to set model")
@@ -257,14 +258,15 @@ class StableDiffusionTool(BuiltinTool):
draw_options["prompt"] = f"{lora},{prompt}"
else:
draw_options["prompt"] = prompt
-
+ api_key = self.runtime.credentials.get("api_key") or "abc"
+ headers = {"Authorization": f"Bearer {api_key}"}
try:
url = str(URL(base_url) / "sdapi" / "v1" / "img2img")
response = post(
url,
json=draw_options,
timeout=120,
- headers={"Authorization": f"Bearer {self.runtime.credentials['api_key']}"},
+ headers=headers,
)
if response.status_code != 200:
return self.create_text_message("Failed to generate image")
@@ -298,14 +300,15 @@ class StableDiffusionTool(BuiltinTool):
else:
draw_options["prompt"] = prompt
draw_options["override_settings"]["sd_model_checkpoint"] = model
-
+ api_key = self.runtime.credentials.get("api_key") or "abc"
+ headers = {"Authorization": f"Bearer {api_key}"}
try:
url = str(URL(base_url) / "sdapi" / "v1" / "txt2img")
response = post(
url,
json=draw_options,
timeout=120,
- headers={"Authorization": f"Bearer {self.runtime.credentials['api_key']}"},
+ headers=headers,
)
if response.status_code != 200:
return self.create_text_message("Failed to generate image")
diff --git a/api/core/tools/provider/builtin/xinference/xinference.py b/api/core/tools/provider/builtin/xinference/xinference.py
index 7c2428cc00..9692e4060e 100644
--- a/api/core/tools/provider/builtin/xinference/xinference.py
+++ b/api/core/tools/provider/builtin/xinference/xinference.py
@@ -6,12 +6,18 @@ from core.tools.provider.builtin_tool_provider import BuiltinToolProviderControl
class XinferenceProvider(BuiltinToolProviderController):
def _validate_credentials(self, credentials: dict) -> None:
- base_url = credentials.get("base_url")
- api_key = credentials.get("api_key")
- model = credentials.get("model")
+ base_url = credentials.get("base_url", "").removesuffix("/")
+ api_key = credentials.get("api_key", "")
+ if not api_key:
+ api_key = "abc"
+ credentials["api_key"] = api_key
+ model = credentials.get("model", "")
+ if not base_url or not model:
+ raise ToolProviderCredentialValidationError("Xinference base_url and model is required")
+ headers = {"Authorization": f"Bearer {api_key}"}
res = requests.post(
f"{base_url}/sdapi/v1/options",
- headers={"Authorization": f"Bearer {api_key}"},
+ headers=headers,
json={"sd_model_checkpoint": model},
)
if res.status_code != 200:
diff --git a/api/core/tools/provider/builtin/xinference/xinference.yaml b/api/core/tools/provider/builtin/xinference/xinference.yaml
index 19aaf5cbd1..b0c02b9cbc 100644
--- a/api/core/tools/provider/builtin/xinference/xinference.yaml
+++ b/api/core/tools/provider/builtin/xinference/xinference.yaml
@@ -31,7 +31,7 @@ credentials_for_provider:
zh_Hans: 请输入你的模型名称
api_key:
type: secret-input
- required: true
+ required: false
label:
en_US: API Key
zh_Hans: Xinference 服务器的 API Key
diff --git a/api/core/tools/tool/builtin_tool.py b/api/core/tools/tool/builtin_tool.py
index 8edaf7c0e6..e2a81ed0a3 100644
--- a/api/core/tools/tool/builtin_tool.py
+++ b/api/core/tools/tool/builtin_tool.py
@@ -1,3 +1,5 @@
+from typing import Optional
+
from core.model_runtime.entities.llm_entities import LLMResult
from core.model_runtime.entities.message_entities import PromptMessage, SystemPromptMessage, UserPromptMessage
from core.tools.entities.tool_entities import ToolProviderType
@@ -124,7 +126,7 @@ class BuiltinTool(Tool):
return result
- def get_url(self, url: str, user_agent: str = None) -> str:
+ def get_url(self, url: str, user_agent: Optional[str] = None) -> str:
"""
get url
"""
diff --git a/api/core/tools/tool/tool.py b/api/core/tools/tool/tool.py
index d9e9a0faad..cb4ab51ceb 100644
--- a/api/core/tools/tool/tool.py
+++ b/api/core/tools/tool/tool.py
@@ -318,7 +318,7 @@ class Tool(BaseModel, ABC):
"""
return ToolInvokeMessage(type=ToolInvokeMessage.MessageType.TEXT, message=text, save_as=save_as)
- def create_blob_message(self, blob: bytes, meta: dict = None, save_as: str = "") -> ToolInvokeMessage:
+ def create_blob_message(self, blob: bytes, meta: Optional[dict] = None, save_as: str = "") -> ToolInvokeMessage:
"""
create a blob message
diff --git a/api/core/tools/tool/workflow_tool.py b/api/core/tools/tool/workflow_tool.py
index ad0c7fc631..a885b8784f 100644
--- a/api/core/tools/tool/workflow_tool.py
+++ b/api/core/tools/tool/workflow_tool.py
@@ -68,10 +68,13 @@ class WorkflowTool(Tool):
result = []
- outputs = data.get("outputs", {})
- outputs, files = self._extract_files(outputs)
- for file in files:
- result.append(self.create_file_var_message(file))
+ outputs = data.get("outputs")
+ if outputs == None:
+ outputs = {}
+ else:
+ outputs, files = self._extract_files(outputs)
+ for file in files:
+ result.append(self.create_file_var_message(file))
result.append(self.create_text_message(json.dumps(outputs, ensure_ascii=False)))
result.append(self.create_json_message(outputs))
diff --git a/api/core/tools/tool_manager.py b/api/core/tools/tool_manager.py
index a3303797e1..ed66dd1357 100644
--- a/api/core/tools/tool_manager.py
+++ b/api/core/tools/tool_manager.py
@@ -4,7 +4,7 @@ import mimetypes
from collections.abc import Generator
from os import listdir, path
from threading import Lock
-from typing import Any, Union
+from typing import Any, Optional, Union
from configs import dify_config
from core.agent.entities import AgentToolEntity
@@ -72,7 +72,7 @@ class ToolManager:
@classmethod
def get_tool(
- cls, provider_type: str, provider_id: str, tool_name: str, tenant_id: str = None
+ cls, provider_type: str, provider_id: str, tool_name: str, tenant_id: Optional[str] = None
) -> Union[BuiltinTool, ApiTool]:
"""
get the tool
diff --git a/api/core/tools/utils/feishu_api_utils.py b/api/core/tools/utils/feishu_api_utils.py
index ce1fd7dc19..245b296d18 100644
--- a/api/core/tools/utils/feishu_api_utils.py
+++ b/api/core/tools/utils/feishu_api_utils.py
@@ -1,3 +1,5 @@
+from typing import Optional
+
import httpx
from core.tools.errors import ToolProviderCredentialValidationError
@@ -32,7 +34,12 @@ class FeishuRequest:
return res.get("tenant_access_token")
def _send_request(
- self, url: str, method: str = "post", require_token: bool = True, payload: dict = None, params: dict = None
+ self,
+ url: str,
+ method: str = "post",
+ require_token: bool = True,
+ payload: Optional[dict] = None,
+ params: Optional[dict] = None,
):
headers = {
"Content-Type": "application/json",
diff --git a/api/core/tools/utils/parser.py b/api/core/tools/utils/parser.py
index 9ead4f8e5c..0d801d36c4 100644
--- a/api/core/tools/utils/parser.py
+++ b/api/core/tools/utils/parser.py
@@ -3,6 +3,7 @@ import uuid
from json import dumps as json_dumps
from json import loads as json_loads
from json.decoder import JSONDecodeError
+from typing import Optional
from requests import get
from yaml import YAMLError, safe_load
@@ -16,7 +17,7 @@ from core.tools.errors import ToolApiSchemaError, ToolNotSupportedError, ToolPro
class ApiBasedToolSchemaParser:
@staticmethod
def parse_openapi_to_tool_bundle(
- openapi: dict, extra_info: dict = None, warning: dict = None
+ openapi: dict, extra_info: Optional[dict], warning: Optional[dict]
) -> list[ApiToolBundle]:
warning = warning if warning is not None else {}
extra_info = extra_info if extra_info is not None else {}
@@ -174,7 +175,7 @@ class ApiBasedToolSchemaParser:
@staticmethod
def parse_openapi_yaml_to_tool_bundle(
- yaml: str, extra_info: dict = None, warning: dict = None
+ yaml: str, extra_info: Optional[dict], warning: Optional[dict]
) -> list[ApiToolBundle]:
"""
parse openapi yaml to tool bundle
@@ -191,7 +192,7 @@ class ApiBasedToolSchemaParser:
return ApiBasedToolSchemaParser.parse_openapi_to_tool_bundle(openapi, extra_info=extra_info, warning=warning)
@staticmethod
- def parse_swagger_to_openapi(swagger: dict, extra_info: dict = None, warning: dict = None) -> dict:
+ def parse_swagger_to_openapi(swagger: dict, extra_info: Optional[dict], warning: Optional[dict]) -> dict:
"""
parse swagger to openapi
@@ -253,7 +254,7 @@ class ApiBasedToolSchemaParser:
@staticmethod
def parse_openai_plugin_json_to_tool_bundle(
- json: str, extra_info: dict = None, warning: dict = None
+ json: str, extra_info: Optional[dict], warning: Optional[dict]
) -> list[ApiToolBundle]:
"""
parse openapi plugin yaml to tool bundle
@@ -287,7 +288,7 @@ class ApiBasedToolSchemaParser:
@staticmethod
def auto_parse_to_tool_bundle(
- content: str, extra_info: dict = None, warning: dict = None
+ content: str, extra_info: Optional[dict], warning: Optional[dict]
) -> tuple[list[ApiToolBundle], str]:
"""
auto parse to tool bundle
diff --git a/api/core/tools/utils/web_reader_tool.py b/api/core/tools/utils/web_reader_tool.py
index 1ced7d0488..5807d61b94 100644
--- a/api/core/tools/utils/web_reader_tool.py
+++ b/api/core/tools/utils/web_reader_tool.py
@@ -9,6 +9,7 @@ import tempfile
import unicodedata
from contextlib import contextmanager
from pathlib import Path
+from typing import Optional
from urllib.parse import unquote
import chardet
@@ -36,7 +37,7 @@ def page_result(text: str, cursor: int, max_length: int) -> str:
return text[cursor : cursor + max_length]
-def get_url(url: str, user_agent: str = None) -> str:
+def get_url(url: str, user_agent: Optional[str] = None) -> str:
"""Fetch URL and return the contents as a string."""
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
diff --git a/api/core/workflow/nodes/knowledge_retrieval/knowledge_retrieval_node.py b/api/core/workflow/nodes/knowledge_retrieval/knowledge_retrieval_node.py
index c08dc143a6..0caf99a963 100644
--- a/api/core/workflow/nodes/knowledge_retrieval/knowledge_retrieval_node.py
+++ b/api/core/workflow/nodes/knowledge_retrieval/knowledge_retrieval_node.py
@@ -229,7 +229,9 @@ class KnowledgeRetrievalNode(BaseNode):
source["content"] = segment.get_sign_content()
retrieval_resource_list.append(source)
if retrieval_resource_list:
- retrieval_resource_list = sorted(retrieval_resource_list, key=lambda x: x.get("score"), reverse=True)
+ retrieval_resource_list = sorted(
+ retrieval_resource_list, key=lambda x: x.get("metadata").get("score"), reverse=True
+ )
position = 1
for item in retrieval_resource_list:
item["metadata"]["position"] = position
diff --git a/api/extensions/ext_proxy_fix.py b/api/extensions/ext_proxy_fix.py
new file mode 100644
index 0000000000..c106a4384a
--- /dev/null
+++ b/api/extensions/ext_proxy_fix.py
@@ -0,0 +1,10 @@
+from flask import Flask
+
+from configs import dify_config
+
+
+def init_app(app: Flask):
+ if dify_config.RESPECT_XFORWARD_HEADERS_ENABLED:
+ from werkzeug.middleware.proxy_fix import ProxyFix
+
+ app.wsgi_app = ProxyFix(app.wsgi_app)
diff --git a/api/extensions/ext_storage.py b/api/extensions/ext_storage.py
index 1e6530f6f4..be57b633be 100644
--- a/api/extensions/ext_storage.py
+++ b/api/extensions/ext_storage.py
@@ -4,15 +4,9 @@ from typing import Union
from flask import Flask
-from extensions.storage.aliyun_storage import AliyunStorage
-from extensions.storage.azure_storage import AzureStorage
-from extensions.storage.google_storage import GoogleStorage
-from extensions.storage.huawei_storage import HuaweiStorage
-from extensions.storage.local_storage import LocalStorage
-from extensions.storage.oci_storage import OCIStorage
-from extensions.storage.s3_storage import S3Storage
-from extensions.storage.tencent_storage import TencentStorage
-from extensions.storage.volcengine_storage import VolcengineStorage
+from configs import dify_config
+from extensions.storage.base_storage import BaseStorage
+from extensions.storage.storage_type import StorageType
class Storage:
@@ -20,25 +14,52 @@ class Storage:
self.storage_runner = None
def init_app(self, app: Flask):
- storage_type = app.config.get("STORAGE_TYPE")
- if storage_type == "s3":
- self.storage_runner = S3Storage(app=app)
- elif storage_type == "azure-blob":
- self.storage_runner = AzureStorage(app=app)
- elif storage_type == "aliyun-oss":
- self.storage_runner = AliyunStorage(app=app)
- elif storage_type == "google-storage":
- self.storage_runner = GoogleStorage(app=app)
- elif storage_type == "tencent-cos":
- self.storage_runner = TencentStorage(app=app)
- elif storage_type == "oci-storage":
- self.storage_runner = OCIStorage(app=app)
- elif storage_type == "huawei-obs":
- self.storage_runner = HuaweiStorage(app=app)
- elif storage_type == "volcengine-tos":
- self.storage_runner = VolcengineStorage(app=app)
- else:
- self.storage_runner = LocalStorage(app=app)
+ storage_factory = self.get_storage_factory(dify_config.STORAGE_TYPE)
+ self.storage_runner = storage_factory(app=app)
+
+ @staticmethod
+ def get_storage_factory(storage_type: str) -> type[BaseStorage]:
+ match storage_type:
+ case StorageType.S3:
+ from extensions.storage.aws_s3_storage import AwsS3Storage
+
+ return AwsS3Storage
+ case StorageType.AZURE_BLOB:
+ from extensions.storage.azure_blob_storage import AzureBlobStorage
+
+ return AzureBlobStorage
+ case StorageType.ALIYUN_OSS:
+ from extensions.storage.aliyun_oss_storage import AliyunOssStorage
+
+ return AliyunOssStorage
+ case StorageType.GOOGLE_STORAGE:
+ from extensions.storage.google_cloud_storage import GoogleCloudStorage
+
+ return GoogleCloudStorage
+ case StorageType.TENCENT_COS:
+ from extensions.storage.tencent_cos_storage import TencentCosStorage
+
+ return TencentCosStorage
+ case StorageType.OCI_STORAGE:
+ from extensions.storage.oracle_oci_storage import OracleOCIStorage
+
+ return OracleOCIStorage
+ case StorageType.HUAWEI_OBS:
+ from extensions.storage.huawei_obs_storage import HuaweiObsStorage
+
+ return HuaweiObsStorage
+ case StorageType.BAIDU_OBS:
+ from extensions.storage.baidu_obs_storage import BaiduObsStorage
+
+ return BaiduObsStorage
+ case StorageType.VOLCENGINE_TOS:
+ from extensions.storage.volcengine_tos_storage import VolcengineTosStorage
+
+ return VolcengineTosStorage
+ case StorageType.LOCAL | _:
+ from extensions.storage.local_fs_storage import LocalFsStorage
+
+ return LocalFsStorage
def save(self, filename, data):
try:
diff --git a/api/extensions/storage/aliyun_storage.py b/api/extensions/storage/aliyun_oss_storage.py
similarity index 96%
rename from api/extensions/storage/aliyun_storage.py
rename to api/extensions/storage/aliyun_oss_storage.py
index 2677912aa9..53bd399d6d 100644
--- a/api/extensions/storage/aliyun_storage.py
+++ b/api/extensions/storage/aliyun_oss_storage.py
@@ -7,8 +7,8 @@ from flask import Flask
from extensions.storage.base_storage import BaseStorage
-class AliyunStorage(BaseStorage):
- """Implementation for aliyun storage."""
+class AliyunOssStorage(BaseStorage):
+ """Implementation for Aliyun OSS storage."""
def __init__(self, app: Flask):
super().__init__(app)
diff --git a/api/extensions/storage/s3_storage.py b/api/extensions/storage/aws_s3_storage.py
similarity index 97%
rename from api/extensions/storage/s3_storage.py
rename to api/extensions/storage/aws_s3_storage.py
index 0858be3af6..fede683aa7 100644
--- a/api/extensions/storage/s3_storage.py
+++ b/api/extensions/storage/aws_s3_storage.py
@@ -9,8 +9,8 @@ from flask import Flask
from extensions.storage.base_storage import BaseStorage
-class S3Storage(BaseStorage):
- """Implementation for s3 storage."""
+class AwsS3Storage(BaseStorage):
+ """Implementation for Amazon Web Services S3 storage."""
def __init__(self, app: Flask):
super().__init__(app)
diff --git a/api/extensions/storage/azure_storage.py b/api/extensions/storage/azure_blob_storage.py
similarity index 97%
rename from api/extensions/storage/azure_storage.py
rename to api/extensions/storage/azure_blob_storage.py
index ca8cbb9188..daea660a49 100644
--- a/api/extensions/storage/azure_storage.py
+++ b/api/extensions/storage/azure_blob_storage.py
@@ -8,8 +8,8 @@ from extensions.ext_redis import redis_client
from extensions.storage.base_storage import BaseStorage
-class AzureStorage(BaseStorage):
- """Implementation for azure storage."""
+class AzureBlobStorage(BaseStorage):
+ """Implementation for Azure Blob storage."""
def __init__(self, app: Flask):
super().__init__(app)
diff --git a/api/extensions/storage/baidu_obs_storage.py b/api/extensions/storage/baidu_obs_storage.py
new file mode 100644
index 0000000000..c5acff4a9d
--- /dev/null
+++ b/api/extensions/storage/baidu_obs_storage.py
@@ -0,0 +1,60 @@
+import base64
+import hashlib
+from collections.abc import Generator
+
+from baidubce.auth.bce_credentials import BceCredentials
+from baidubce.bce_client_configuration import BceClientConfiguration
+from baidubce.services.bos.bos_client import BosClient
+from flask import Flask
+
+from extensions.storage.base_storage import BaseStorage
+
+
+class BaiduObsStorage(BaseStorage):
+ """Implementation for Baidu OBS storage."""
+
+ def __init__(self, app: Flask):
+ super().__init__(app)
+ app_config = self.app.config
+ self.bucket_name = app_config.get("BAIDU_OBS_BUCKET_NAME")
+ client_config = BceClientConfiguration(
+ credentials=BceCredentials(
+ access_key_id=app_config.get("BAIDU_OBS_ACCESS_KEY"),
+ secret_access_key=app_config.get("BAIDU_OBS_SECRET_KEY"),
+ ),
+ endpoint=app_config.get("BAIDU_OBS_ENDPOINT"),
+ )
+
+ self.client = BosClient(config=client_config)
+
+ def save(self, filename, data):
+ md5 = hashlib.md5()
+ md5.update(data)
+ content_md5 = base64.standard_b64encode(md5.digest())
+ self.client.put_object(
+ bucket_name=self.bucket_name, key=filename, data=data, content_length=len(data), content_md5=content_md5
+ )
+
+ def load_once(self, filename: str) -> bytes:
+ response = self.client.get_object(bucket_name=self.bucket_name, key=filename)
+ return response.data.read()
+
+ def load_stream(self, filename: str) -> Generator:
+ def generate(filename: str = filename) -> Generator:
+ response = self.client.get_object(bucket_name=self.bucket_name, key=filename).data
+ while chunk := response.read(4096):
+ yield chunk
+
+ return generate()
+
+ def download(self, filename, target_filepath):
+ self.client.get_object_to_file(bucket_name=self.bucket_name, key=filename, file_name=target_filepath)
+
+ def exists(self, filename):
+ res = self.client.get_object_meta_data(bucket_name=self.bucket_name, key=filename)
+ if res is None:
+ return False
+ return True
+
+ def delete(self, filename):
+ self.client.delete_object(bucket_name=self.bucket_name, key=filename)
diff --git a/api/extensions/storage/google_storage.py b/api/extensions/storage/google_cloud_storage.py
similarity index 96%
rename from api/extensions/storage/google_storage.py
rename to api/extensions/storage/google_cloud_storage.py
index c42f946fa8..d9c74b8d40 100644
--- a/api/extensions/storage/google_storage.py
+++ b/api/extensions/storage/google_cloud_storage.py
@@ -10,8 +10,8 @@ from google.cloud import storage as google_cloud_storage
from extensions.storage.base_storage import BaseStorage
-class GoogleStorage(BaseStorage):
- """Implementation for google storage."""
+class GoogleCloudStorage(BaseStorage):
+ """Implementation for Google Cloud storage."""
def __init__(self, app: Flask):
super().__init__(app)
diff --git a/api/extensions/storage/huawei_storage.py b/api/extensions/storage/huawei_obs_storage.py
similarity index 91%
rename from api/extensions/storage/huawei_storage.py
rename to api/extensions/storage/huawei_obs_storage.py
index 269a008fba..dd243d4001 100644
--- a/api/extensions/storage/huawei_storage.py
+++ b/api/extensions/storage/huawei_obs_storage.py
@@ -6,8 +6,8 @@ from obs import ObsClient
from extensions.storage.base_storage import BaseStorage
-class HuaweiStorage(BaseStorage):
- """Implementation for huawei obs storage."""
+class HuaweiObsStorage(BaseStorage):
+ """Implementation for Huawei OBS storage."""
def __init__(self, app: Flask):
super().__init__(app)
@@ -29,7 +29,8 @@ class HuaweiStorage(BaseStorage):
def load_stream(self, filename: str) -> Generator:
def generate(filename: str = filename) -> Generator:
response = self.client.getObject(bucketName=self.bucket_name, objectKey=filename)["body"].response
- yield from response.read(4096)
+ while chunk := response.read(4096):
+ yield chunk
return generate()
diff --git a/api/extensions/storage/local_storage.py b/api/extensions/storage/local_fs_storage.py
similarity index 96%
rename from api/extensions/storage/local_storage.py
rename to api/extensions/storage/local_fs_storage.py
index f833ae85dc..9308c4d180 100644
--- a/api/extensions/storage/local_storage.py
+++ b/api/extensions/storage/local_fs_storage.py
@@ -8,8 +8,8 @@ from flask import Flask
from extensions.storage.base_storage import BaseStorage
-class LocalStorage(BaseStorage):
- """Implementation for local storage."""
+class LocalFsStorage(BaseStorage):
+ """Implementation for local filesystem storage."""
def __init__(self, app: Flask):
super().__init__(app)
diff --git a/api/extensions/storage/oci_storage.py b/api/extensions/storage/oracle_oci_storage.py
similarity index 96%
rename from api/extensions/storage/oci_storage.py
rename to api/extensions/storage/oracle_oci_storage.py
index e32fa0a0ae..6934583567 100644
--- a/api/extensions/storage/oci_storage.py
+++ b/api/extensions/storage/oracle_oci_storage.py
@@ -8,7 +8,9 @@ from flask import Flask
from extensions.storage.base_storage import BaseStorage
-class OCIStorage(BaseStorage):
+class OracleOCIStorage(BaseStorage):
+ """Implementation for Oracle OCI storage."""
+
def __init__(self, app: Flask):
super().__init__(app)
app_config = self.app.config
diff --git a/api/extensions/storage/storage_type.py b/api/extensions/storage/storage_type.py
new file mode 100644
index 0000000000..e494a520a2
--- /dev/null
+++ b/api/extensions/storage/storage_type.py
@@ -0,0 +1,14 @@
+from enum import Enum
+
+
+class StorageType(str, Enum):
+ ALIYUN_OSS = "aliyun-oss"
+ AZURE_BLOB = "azure-blob"
+ BAIDU_OBS = "baidu-obs"
+ GOOGLE_STORAGE = "google-storage"
+ HUAWEI_OBS = "huawei-obs"
+ LOCAL = "local"
+ OCI_STORAGE = "oci-storage"
+ S3 = "s3"
+ TENCENT_COS = "tencent-cos"
+ VOLCENGINE_TOS = "volcengine-tos"
diff --git a/api/extensions/storage/tencent_storage.py b/api/extensions/storage/tencent_cos_storage.py
similarity index 94%
rename from api/extensions/storage/tencent_storage.py
rename to api/extensions/storage/tencent_cos_storage.py
index 1d499cd3bc..c529dce7ad 100644
--- a/api/extensions/storage/tencent_storage.py
+++ b/api/extensions/storage/tencent_cos_storage.py
@@ -6,8 +6,8 @@ from qcloud_cos import CosConfig, CosS3Client
from extensions.storage.base_storage import BaseStorage
-class TencentStorage(BaseStorage):
- """Implementation for tencent cos storage."""
+class TencentCosStorage(BaseStorage):
+ """Implementation for Tencent Cloud COS storage."""
def __init__(self, app: Flask):
super().__init__(app)
diff --git a/api/extensions/storage/volcengine_storage.py b/api/extensions/storage/volcengine_tos_storage.py
similarity index 97%
rename from api/extensions/storage/volcengine_storage.py
rename to api/extensions/storage/volcengine_tos_storage.py
index f74ad2ee6d..1bedcf24c2 100644
--- a/api/extensions/storage/volcengine_storage.py
+++ b/api/extensions/storage/volcengine_tos_storage.py
@@ -6,7 +6,7 @@ from flask import Flask
from extensions.storage.base_storage import BaseStorage
-class VolcengineStorage(BaseStorage):
+class VolcengineTosStorage(BaseStorage):
"""Implementation for Volcengine TOS storage."""
def __init__(self, app: Flask):
diff --git a/api/libs/helper.py b/api/libs/helper.py
index d664ef1ae7..9c3a1ff04d 100644
--- a/api/libs/helper.py
+++ b/api/libs/helper.py
@@ -189,7 +189,7 @@ def compact_generate_response(response: Union[dict, RateLimitGenerator]) -> Resp
class TokenManager:
@classmethod
- def generate_token(cls, account: Account, token_type: str, additional_data: dict = None) -> str:
+ def generate_token(cls, account: Account, token_type: str, additional_data: Optional[dict] = None) -> str:
old_token = cls._get_current_token_for_account(account.id, token_type)
if old_token:
if isinstance(old_token, bytes):
diff --git a/api/libs/json_in_md_parser.py b/api/libs/json_in_md_parser.py
index 185ff3f95e..9131408817 100644
--- a/api/libs/json_in_md_parser.py
+++ b/api/libs/json_in_md_parser.py
@@ -4,25 +4,28 @@ from core.llm_generator.output_parser.errors import OutputParserError
def parse_json_markdown(json_string: str) -> dict:
- # Remove the triple backticks if present
+ # Get json from the backticks/braces
json_string = json_string.strip()
- start_index = json_string.find("```json")
- end_index = json_string.find("```", start_index + len("```json"))
-
- if start_index != -1 and end_index != -1:
- extracted_content = json_string[start_index + len("```json") : end_index].strip()
-
- # Parse the JSON string into a Python dictionary
+ starts = ["```json", "```", "``", "`", "{"]
+ ends = ["```", "``", "`", "}"]
+ end_index = -1
+ for s in starts:
+ start_index = json_string.find(s)
+ if start_index != -1:
+ if json_string[start_index] != "{":
+ start_index += len(s)
+ break
+ if start_index != -1:
+ for e in ends:
+ end_index = json_string.rfind(e, start_index)
+ if end_index != -1:
+ if json_string[end_index] == "}":
+ end_index += 1
+ break
+ if start_index != -1 and end_index != -1 and start_index < end_index:
+ extracted_content = json_string[start_index:end_index].strip()
+ print("content:", extracted_content, start_index, end_index)
parsed = json.loads(extracted_content)
- elif start_index != -1 and end_index == -1 and json_string.endswith("``"):
- end_index = json_string.find("``", start_index + len("```json"))
- extracted_content = json_string[start_index + len("```json") : end_index].strip()
-
- # Parse the JSON string into a Python dictionary
- parsed = json.loads(extracted_content)
- elif json_string.startswith("{"):
- # Parse the JSON string into a Python dictionary
- parsed = json.loads(json_string)
else:
raise Exception("Could not find JSON block in the output.")
diff --git a/api/poetry.lock b/api/poetry.lock
index 4fb8d54f11..6b96350ffd 100644
--- a/api/poetry.lock
+++ b/api/poetry.lock
@@ -2,13 +2,13 @@
[[package]]
name = "aiohappyeyeballs"
-version = "2.4.2"
+version = "2.4.3"
description = "Happy Eyeballs for asyncio"
optional = false
python-versions = ">=3.8"
files = [
- {file = "aiohappyeyeballs-2.4.2-py3-none-any.whl", hash = "sha256:8522691d9a154ba1145b157d6d5c15e5c692527ce6a53c5e5f9876977f6dab2f"},
- {file = "aiohappyeyeballs-2.4.2.tar.gz", hash = "sha256:4ca893e6c5c1f5bf3888b04cb5a3bee24995398efef6e0b9f747b5e89d84fd74"},
+ {file = "aiohappyeyeballs-2.4.3-py3-none-any.whl", hash = "sha256:8a7a83727b2756f394ab2895ea0765a0a8c475e3c71e98d43d76f22b4b435572"},
+ {file = "aiohappyeyeballs-2.4.3.tar.gz", hash = "sha256:75cf88a15106a5002a8eb1dab212525c00d1f4c0fa96e551c9fbe6f09a621586"},
]
[[package]]
@@ -727,6 +727,22 @@ files = [
{file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"},
]
+[[package]]
+name = "bce-python-sdk"
+version = "0.9.23"
+description = "BCE SDK for python"
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,<4,>=2.7"
+files = [
+ {file = "bce_python_sdk-0.9.23-py3-none-any.whl", hash = "sha256:8debe21a040e00060f6044877d594765ed7b18bc765c6bf16b878bca864140a3"},
+ {file = "bce_python_sdk-0.9.23.tar.gz", hash = "sha256:19739fed5cd0725356fc5ffa2acbdd8fb23f2a81edb91db21a03174551d0cf41"},
+]
+
+[package.dependencies]
+future = ">=0.6.0"
+pycryptodome = ">=3.8.0"
+six = ">=1.4.0"
+
[[package]]
name = "bcrypt"
version = "4.2.0"
@@ -828,13 +844,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"]
[[package]]
name = "botocore"
-version = "1.35.29"
+version = "1.35.34"
description = "Low-level, data-driven core of boto 3."
optional = false
python-versions = ">=3.8"
files = [
- {file = "botocore-1.35.29-py3-none-any.whl", hash = "sha256:f8e3ae0d84214eff3fb69cb4dc51cea6c43d3bde82027a94d00c52b941d6c3d5"},
- {file = "botocore-1.35.29.tar.gz", hash = "sha256:4ed28ab03675bb008a290c452c5ddd7aaa5d4e3fa1912aadbdf93057ee84362b"},
+ {file = "botocore-1.35.34-py3-none-any.whl", hash = "sha256:ccb0fe397b11b81c9abc0c87029d17298e17bf658d8db5c0c5a551a12a207e7a"},
+ {file = "botocore-1.35.34.tar.gz", hash = "sha256:789b6501a3bb4a9591c1fe10da200cc315c1fa5df5ada19c720d8ef06439b3e3"},
]
[package.dependencies]
@@ -843,7 +859,7 @@ python-dateutil = ">=2.1,<3.0.0"
urllib3 = {version = ">=1.25.4,<2.2.0 || >2.2.0,<3", markers = "python_version >= \"3.10\""}
[package.extras]
-crt = ["awscrt (==0.21.5)"]
+crt = ["awscrt (==0.22.0)"]
[[package]]
name = "bottleneck"
@@ -1049,13 +1065,13 @@ beautifulsoup4 = "*"
[[package]]
name = "build"
-version = "1.2.2"
+version = "1.2.2.post1"
description = "A simple, correct Python build frontend"
optional = false
python-versions = ">=3.8"
files = [
- {file = "build-1.2.2-py3-none-any.whl", hash = "sha256:277ccc71619d98afdd841a0e96ac9fe1593b823af481d3b0cea748e8894e0613"},
- {file = "build-1.2.2.tar.gz", hash = "sha256:119b2fb462adef986483438377a13b2f42064a2a3a4161f24a0cca698a07ac8c"},
+ {file = "build-1.2.2.post1-py3-none-any.whl", hash = "sha256:1d61c0887fa860c01971625baae8bdd338e517b836a2f70dd1f7aa3a6b2fc5b5"},
+ {file = "build-1.2.2.post1.tar.gz", hash = "sha256:b36993e92ca9375a219c99e606a122ff365a760a2d4bba0caa09bd5278b608b7"},
]
[package.dependencies]
@@ -2302,13 +2318,13 @@ files = [
[[package]]
name = "duckduckgo-search"
-version = "6.2.13"
+version = "6.3.0"
description = "Search for words, documents, images, news, maps and text translation using the DuckDuckGo.com search engine."
optional = false
python-versions = ">=3.8"
files = [
- {file = "duckduckgo_search-6.2.13-py3-none-any.whl", hash = "sha256:a6618fb2744fa1d081b1bf2e47ef8051de993276a15c20f4e879a150726472de"},
- {file = "duckduckgo_search-6.2.13.tar.gz", hash = "sha256:f89a9782f0f47d18c01a761c83453d0aef7a4335d1b6466fc47709652d5ca791"},
+ {file = "duckduckgo_search-6.3.0-py3-none-any.whl", hash = "sha256:9a231a7b325226811cf7d35a240f3f501e718ae10a1aa0a638cabc80e129dfe7"},
+ {file = "duckduckgo_search-6.3.0.tar.gz", hash = "sha256:e9f56955569325a7d9cacda2488ca78bf6629a459e74415892bee560b664f5eb"},
]
[package.dependencies]
@@ -2321,12 +2337,13 @@ lxml = ["lxml (>=5.2.2)"]
[[package]]
name = "durationpy"
-version = "0.7"
+version = "0.9"
description = "Module for converting between datetime.timedelta and Go's Duration strings."
optional = false
python-versions = "*"
files = [
- {file = "durationpy-0.7.tar.gz", hash = "sha256:8447c43df4f1a0b434e70c15a38d77f5c9bd17284bfc1ff1d430f233d5083732"},
+ {file = "durationpy-0.9-py3-none-any.whl", hash = "sha256:e65359a7af5cedad07fb77a2dd3f390f8eb0b74cb845589fa6c057086834dd38"},
+ {file = "durationpy-0.9.tar.gz", hash = "sha256:fd3feb0a69a0057d582ef643c355c40d2fa1c942191f914d12203b1a01ac722a"},
]
[[package]]
@@ -2372,13 +2389,13 @@ vectorstore-mmr = ["numpy (>=1)", "simsimd (>=3)"]
[[package]]
name = "emoji"
-version = "2.13.2"
+version = "2.14.0"
description = "Emoji for Python"
optional = false
python-versions = ">=3.7"
files = [
- {file = "emoji-2.13.2-py3-none-any.whl", hash = "sha256:ef6f2ee63b245e934c763b1a9a0637713955aa3d9e322432e036bb60559de4d6"},
- {file = "emoji-2.13.2.tar.gz", hash = "sha256:f95d10d96c5f21299ed2c4b32511611ba890b8c07f5f2bf5b04d5d3eee91fd19"},
+ {file = "emoji-2.14.0-py3-none-any.whl", hash = "sha256:fcc936bf374b1aec67dda5303ae99710ba88cc9cdce2d1a71c5f2204e6d78799"},
+ {file = "emoji-2.14.0.tar.gz", hash = "sha256:f68ac28915a2221667cddb3e6c589303c3c6954c6c5af6fefaec7f9bdf72fdca"},
]
[package.extras]
@@ -2785,44 +2802,49 @@ woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"]
[[package]]
name = "frozendict"
-version = "2.4.4"
+version = "2.4.5"
description = "A simple immutable dictionary"
optional = false
python-versions = ">=3.6"
files = [
- {file = "frozendict-2.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4a59578d47b3949437519b5c39a016a6116b9e787bb19289e333faae81462e59"},
- {file = "frozendict-2.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12a342e439aef28ccec533f0253ea53d75fe9102bd6ea928ff530e76eac38906"},
- {file = "frozendict-2.4.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f79c26dff10ce11dad3b3627c89bb2e87b9dd5958c2b24325f16a23019b8b94"},
- {file = "frozendict-2.4.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2bd009cf4fc47972838a91e9b83654dc9a095dc4f2bb3a37c3f3124c8a364543"},
- {file = "frozendict-2.4.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:87ebcde21565a14fe039672c25550060d6f6d88cf1f339beac094c3b10004eb0"},
- {file = "frozendict-2.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:fefeb700bc7eb8b4c2dc48704e4221860d254c8989fb53488540bc44e44a1ac2"},
- {file = "frozendict-2.4.4-cp310-cp310-win_arm64.whl", hash = "sha256:4297d694eb600efa429769125a6f910ec02b85606f22f178bafbee309e7d3ec7"},
- {file = "frozendict-2.4.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:812ab17522ba13637826e65454115a914c2da538356e85f43ecea069813e4b33"},
- {file = "frozendict-2.4.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fee9420475bb6ff357000092aa9990c2f6182b2bab15764330f4ad7de2eae49"},
- {file = "frozendict-2.4.4-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:3148062675536724502c6344d7c485dd4667fdf7980ca9bd05e338ccc0c4471e"},
- {file = "frozendict-2.4.4-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:78c94991944dd33c5376f720228e5b252ee67faf3bac50ef381adc9e51e90d9d"},
- {file = "frozendict-2.4.4-cp36-cp36m-win_amd64.whl", hash = "sha256:1697793b5f62b416c0fc1d94638ec91ed3aa4ab277f6affa3a95216ecb3af170"},
- {file = "frozendict-2.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:199a4d32194f3afed6258de7e317054155bc9519252b568d9cfffde7e4d834e5"},
- {file = "frozendict-2.4.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85375ec6e979e6373bffb4f54576a68bf7497c350861d20686ccae38aab69c0a"},
- {file = "frozendict-2.4.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:2d8536e068d6bf281f23fa835ac07747fb0f8851879dd189e9709f9567408b4d"},
- {file = "frozendict-2.4.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:259528ba6b56fa051bc996f1c4d8b57e30d6dd3bc2f27441891b04babc4b5e73"},
- {file = "frozendict-2.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:07c3a5dee8bbb84cba770e273cdbf2c87c8e035903af8f781292d72583416801"},
- {file = "frozendict-2.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6874fec816b37b6eb5795b00e0574cba261bf59723e2de607a195d5edaff0786"},
- {file = "frozendict-2.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8f92425686323a950337da4b75b4c17a3327b831df8c881df24038d560640d4"},
- {file = "frozendict-2.4.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d58d9a8d9e49662c6dafbea5e641f97decdb3d6ccd76e55e79818415362ba25"},
- {file = "frozendict-2.4.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:93a7b19afb429cbf99d56faf436b45ef2fa8fe9aca89c49eb1610c3bd85f1760"},
- {file = "frozendict-2.4.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2b70b431e3a72d410a2cdf1497b3aba2f553635e0c0f657ce311d841bf8273b6"},
- {file = "frozendict-2.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:e1b941132d79ce72d562a13341d38fc217bc1ee24d8c35a20d754e79ff99e038"},
- {file = "frozendict-2.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dc2228874eacae390e63fd4f2bb513b3144066a977dc192163c9f6c7f6de6474"},
- {file = "frozendict-2.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63aa49f1919af7d45fb8fd5dec4c0859bc09f46880bd6297c79bb2db2969b63d"},
- {file = "frozendict-2.4.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6bf9260018d653f3cab9bd147bd8592bf98a5c6e338be0491ced3c196c034a3"},
- {file = "frozendict-2.4.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6eb716e6a6d693c03b1d53280a1947716129f5ef9bcdd061db5c17dea44b80fe"},
- {file = "frozendict-2.4.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d13b4310db337f4d2103867c5a05090b22bc4d50ca842093779ef541ea9c9eea"},
- {file = "frozendict-2.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:b3b967d5065872e27b06f785a80c0ed0a45d1f7c9b85223da05358e734d858ca"},
- {file = "frozendict-2.4.4-cp39-cp39-win_arm64.whl", hash = "sha256:4ae8d05c8d0b6134bfb6bfb369d5fa0c4df21eabb5ca7f645af95fdc6689678e"},
- {file = "frozendict-2.4.4-py311-none-any.whl", hash = "sha256:705efca8d74d3facbb6ace80ab3afdd28eb8a237bfb4063ed89996b024bc443d"},
- {file = "frozendict-2.4.4-py312-none-any.whl", hash = "sha256:d9647563e76adb05b7cde2172403123380871360a114f546b4ae1704510801e5"},
- {file = "frozendict-2.4.4.tar.gz", hash = "sha256:3f7c031b26e4ee6a3f786ceb5e3abf1181c4ade92dce1f847da26ea2c96008c7"},
+ {file = "frozendict-2.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1f364cfe5ef97523a4434e9f458bb4821594d3531d898621e5acae43463dcb5e"},
+ {file = "frozendict-2.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4f073c926b1f88fa85ed85222101f61f6c4b2180c95d1528ca6ecc7cef835442"},
+ {file = "frozendict-2.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8582f26ca862bb1e40ed790d934adf6afcfc904b0425dcfe01aed2103bed27fb"},
+ {file = "frozendict-2.4.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b3eea1678607174c468fe4e3b903625bccfb3215ae2b0138220dc1f6ef71f37"},
+ {file = "frozendict-2.4.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3af1b09bad761d5500b096b757c346591b5dfdc8443aa9642c2c02b4885dc09e"},
+ {file = "frozendict-2.4.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76c7af5f9db9ae01531edaf38fd3e8faae1bb6b94abbf8fa5bd0326f52e777df"},
+ {file = "frozendict-2.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:a5448639058157ccd7f26ba83e441066c6ae515beb68b9b99d5b2dbb0bb36b19"},
+ {file = "frozendict-2.4.5-cp310-cp310-win_arm64.whl", hash = "sha256:24953a1cfe344415e7557413e493e21fa9c4cecbc13284b6f334837aa5601c9f"},
+ {file = "frozendict-2.4.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:754924d53b1fd2dae7b15f9c86b0610334a840ae728cc717f24aa040fc94136f"},
+ {file = "frozendict-2.4.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95bf788d65e3a50d9deef5c68e568c59acf473fea8a7a4d7e405a7e63ac85cdd"},
+ {file = "frozendict-2.4.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35730ff269b8a6eb07c3d91d5fd6a7f5c32e08bef665fe1ef51012bdb2702196"},
+ {file = "frozendict-2.4.5-cp36-cp36m-musllinux_1_2_aarch64.whl", hash = "sha256:eb58e0c41bc6bb60a8b0852d50da8836380fb78311608dc26791e3e9aa25bcfe"},
+ {file = "frozendict-2.4.5-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:0483776fa25f0c3f9ff75a89b5276a582231f83baea85b091dfefde99b95ac5c"},
+ {file = "frozendict-2.4.5-cp36-cp36m-win_amd64.whl", hash = "sha256:a967730a115cb8b5d028e0d07cd680c04324e913ee3d1caef9e039ca740343c4"},
+ {file = "frozendict-2.4.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6d10ad91ded20fae8737fddcfed1b6358207f95292a335f96c4cd365d97f5e30"},
+ {file = "frozendict-2.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3702438d81deab127963ab41dca1738a0fbf11038a50a25c5f814943a2d25de5"},
+ {file = "frozendict-2.4.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de1126d6dd39d7939be388161b973ffadb9c6e97f8f9fdcb52ba790828621191"},
+ {file = "frozendict-2.4.5-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:f8d677a6066ca3289181028fccabf77413addddaa7a6629485d52aeaa4f4899c"},
+ {file = "frozendict-2.4.5-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:f2ff03ed21657cde7ea04fffc76f0c1736100a03671e4682722685e63486cd96"},
+ {file = "frozendict-2.4.5-cp37-cp37m-win_amd64.whl", hash = "sha256:14755127b988b428f95f11fa626374e247f8a40316697218f1e2f44c107c5027"},
+ {file = "frozendict-2.4.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bbf9dcb69a44519308c775bcf72b8417c3102f415f77df19b8eddb97b8f88d78"},
+ {file = "frozendict-2.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ee3e6f4013446d17c580ce0bac41a1f81371c21dd6e34a85c0f26bae94fdfd9b"},
+ {file = "frozendict-2.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b51e0aae859fc8d56138eac4be121a76647fa66ea620af8a62d9d6938729441"},
+ {file = "frozendict-2.4.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af4bdffecff350a68f1a966dec84459d3ea8e2606c14fb3ebe937b8c6c9e9129"},
+ {file = "frozendict-2.4.5-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f1385852cb05a31ae76c972caa3a07679414b01a664848bde2bae71c9910f045"},
+ {file = "frozendict-2.4.5-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:e591124818f2d5d8f2d284a7b78604f4180e73d770c33252370edccff5969293"},
+ {file = "frozendict-2.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:05786d9cff61ee95149c15cdfc10cf4b4cb10e1eab1d4648b0c99ed58fedb86d"},
+ {file = "frozendict-2.4.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:98b1483980c47bb74ef777ab748031a69eb41c43ef44494e9db79111638fdb84"},
+ {file = "frozendict-2.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:08e8d4ebc950916b5cdeedcb697cf893c5903d9cb8ab27dffe41072a08e1cfc1"},
+ {file = "frozendict-2.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:73ff80ce3f95c3ec60b38ef4ddf5cb8e20ea3edce2f56e89af7c4c45013684bf"},
+ {file = "frozendict-2.4.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dee64c44e1a146171bdd2bf4501210f273a5ab73cc2e924a01f81b14e4612f94"},
+ {file = "frozendict-2.4.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a81d80ded07f0e34a3fa2b78235a48259b886ad20a96da5526a9404d192c6eb3"},
+ {file = "frozendict-2.4.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:043bce9f5e7e8df8313d0c961b2da3346c0b002311d88c74cadae2b1f8fd2904"},
+ {file = "frozendict-2.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:d2b2a9c809ebb54c8c0fe2acc38d45299f3e9a9d90061773468896221cab1eaa"},
+ {file = "frozendict-2.4.5-cp39-cp39-win_arm64.whl", hash = "sha256:20cf1db30ca0c8f76a05ec1256132f505cf6f93eb382a5961c738377037b5b9d"},
+ {file = "frozendict-2.4.5-py311-none-any.whl", hash = "sha256:6be054ba76e8a49c6846a7369db3eaaa0593c29a644026c25923f13fdea06483"},
+ {file = "frozendict-2.4.5-py312-none-any.whl", hash = "sha256:b8481d83a7219e9e14c719113ea2d8321d7840af35af58c72b3864b7123e7de3"},
+ {file = "frozendict-2.4.5.tar.gz", hash = "sha256:fd7add309789595c044c0155a0bddfa9d20c77f65de1e33a14aa3033b936ef63"},
]
[[package]]
@@ -2950,6 +2972,17 @@ test-downstream = ["aiobotocore (>=2.5.4,<3.0.0)", "dask-expr", "dask[dataframe,
test-full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "cloudpickle", "dask", "distributed", "dropbox", "dropboxdrivefs", "fastparquet", "fusepy", "gcsfs", "jinja2", "kerchunk", "libarchive-c", "lz4", "notebook", "numpy", "ocifs", "pandas", "panel", "paramiko", "pyarrow", "pyarrow (>=1)", "pyftpdlib", "pygit2", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "python-snappy", "requests", "smbprotocol", "tqdm", "urllib3", "zarr", "zstandard"]
tqdm = ["tqdm"]
+[[package]]
+name = "future"
+version = "1.0.0"
+description = "Clean single-source support for Python 3 and 2"
+optional = false
+python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
+files = [
+ {file = "future-1.0.0-py3-none-any.whl", hash = "sha256:929292d34f5872e70396626ef385ec22355a1fae8ad29e1a734c3e43f9fbc216"},
+ {file = "future-1.0.0.tar.gz", hash = "sha256:bd2968309307861edae1458a4f8a4f3598c03be43b97521076aebf5d94c07b05"},
+]
+
[[package]]
name = "gevent"
version = "23.9.1"
@@ -3861,13 +3894,13 @@ lxml = ["lxml"]
[[package]]
name = "httpcore"
-version = "1.0.5"
+version = "1.0.6"
description = "A minimal low-level HTTP client."
optional = false
python-versions = ">=3.8"
files = [
- {file = "httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5"},
- {file = "httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61"},
+ {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"},
+ {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"},
]
[package.dependencies]
@@ -3878,7 +3911,7 @@ h11 = ">=0.13,<0.15"
asyncio = ["anyio (>=4.0,<5.0)"]
http2 = ["h2 (>=3,<5)"]
socks = ["socksio (==1.*)"]
-trio = ["trio (>=0.22.0,<0.26.0)"]
+trio = ["trio (>=0.22.0,<1.0)"]
[[package]]
name = "httplib2"
@@ -4450,13 +4483,13 @@ six = "*"
[[package]]
name = "langfuse"
-version = "2.51.2"
+version = "2.51.3"
description = "A client library for accessing langfuse"
optional = false
python-versions = "<4.0,>=3.8.1"
files = [
- {file = "langfuse-2.51.2-py3-none-any.whl", hash = "sha256:7aab94a9452cda4587a2cd4917e455da1afd7f8a2696688742130e2f2d23ca59"},
- {file = "langfuse-2.51.2.tar.gz", hash = "sha256:0982b108ab4c02947f682e442b0796b7a73825d31eeace1771575f6454b8f79a"},
+ {file = "langfuse-2.51.3-py3-none-any.whl", hash = "sha256:32aba050123656ec0c165583e1d33243cc7a14e7b8498ed3c9de808aa90306f1"},
+ {file = "langfuse-2.51.3.tar.gz", hash = "sha256:ccd2109556ee232db717abfb751ee8a3139f074db7d3e06a4f1a756c349fc5ba"},
]
[package.dependencies]
@@ -4475,13 +4508,13 @@ openai = ["openai (>=0.27.8)"]
[[package]]
name = "langsmith"
-version = "0.1.129"
+version = "0.1.131"
description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform."
optional = false
python-versions = "<4.0,>=3.8.1"
files = [
- {file = "langsmith-0.1.129-py3-none-any.whl", hash = "sha256:31393fbbb17d6be5b99b9b22d530450094fab23c6c37281a6a6efb2143d05347"},
- {file = "langsmith-0.1.129.tar.gz", hash = "sha256:6c3ba66471bef41b9f87da247cc0b493268b3f54656f73648a256a205261b6a0"},
+ {file = "langsmith-0.1.131-py3-none-any.whl", hash = "sha256:80c106b1c42307195cc0bb3a596472c41ef91b79d15bcee9938307800336c563"},
+ {file = "langsmith-0.1.131.tar.gz", hash = "sha256:626101a3bf3ca481e5110d5155ace8aa066e4e9cc2fa7d96c8290ade0fbff797"},
]
[package.dependencies]
@@ -4492,6 +4525,7 @@ pydantic = [
{version = ">=2.7.4,<3.0.0", markers = "python_full_version >= \"3.12.4\""},
]
requests = ">=2,<3"
+requests-toolbelt = ">=1.0.0,<2.0.0"
[[package]]
name = "llvmlite"
@@ -5318,27 +5352,31 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.11\""}
[[package]]
name = "multiprocess"
-version = "0.70.16"
+version = "0.70.17"
description = "better multiprocessing and multithreading in Python"
optional = false
python-versions = ">=3.8"
files = [
- {file = "multiprocess-0.70.16-pp310-pypy310_pp73-macosx_10_13_x86_64.whl", hash = "sha256:476887be10e2f59ff183c006af746cb6f1fd0eadcfd4ef49e605cbe2659920ee"},
- {file = "multiprocess-0.70.16-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d951bed82c8f73929ac82c61f01a7b5ce8f3e5ef40f5b52553b4f547ce2b08ec"},
- {file = "multiprocess-0.70.16-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:37b55f71c07e2d741374998c043b9520b626a8dddc8b3129222ca4f1a06ef67a"},
- {file = "multiprocess-0.70.16-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:ba8c31889abf4511c7308a8c52bb4a30b9d590e7f58523302ba00237702ca054"},
- {file = "multiprocess-0.70.16-pp39-pypy39_pp73-macosx_10_13_x86_64.whl", hash = "sha256:0dfd078c306e08d46d7a8d06fb120313d87aa43af60d66da43ffff40b44d2f41"},
- {file = "multiprocess-0.70.16-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e7b9d0f307cd9bd50851afaac0dba2cb6c44449efff697df7c7645f7d3f2be3a"},
- {file = "multiprocess-0.70.16-py310-none-any.whl", hash = "sha256:c4a9944c67bd49f823687463660a2d6daae94c289adff97e0f9d696ba6371d02"},
- {file = "multiprocess-0.70.16-py311-none-any.whl", hash = "sha256:af4cabb0dac72abfb1e794fa7855c325fd2b55a10a44628a3c1ad3311c04127a"},
- {file = "multiprocess-0.70.16-py312-none-any.whl", hash = "sha256:fc0544c531920dde3b00c29863377f87e1632601092ea2daca74e4beb40faa2e"},
- {file = "multiprocess-0.70.16-py38-none-any.whl", hash = "sha256:a71d82033454891091a226dfc319d0cfa8019a4e888ef9ca910372a446de4435"},
- {file = "multiprocess-0.70.16-py39-none-any.whl", hash = "sha256:a0bafd3ae1b732eac64be2e72038231c1ba97724b60b09400d68f229fcc2fbf3"},
- {file = "multiprocess-0.70.16.tar.gz", hash = "sha256:161af703d4652a0e1410be6abccecde4a7ddffd19341be0a7011b94aeb171ac1"},
+ {file = "multiprocess-0.70.17-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7ddb24e5bcdb64e90ec5543a1f05a39463068b6d3b804aa3f2a4e16ec28562d6"},
+ {file = "multiprocess-0.70.17-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d729f55198a3579f6879766a6d9b72b42d4b320c0dcb7844afb774d75b573c62"},
+ {file = "multiprocess-0.70.17-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c2c82d0375baed8d8dd0d8c38eb87c5ae9c471f8e384ad203a36f095ee860f67"},
+ {file = "multiprocess-0.70.17-pp38-pypy38_pp73-macosx_10_9_arm64.whl", hash = "sha256:a22a6b1a482b80eab53078418bb0f7025e4f7d93cc8e1f36481477a023884861"},
+ {file = "multiprocess-0.70.17-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:349525099a0c9ac5936f0488b5ee73199098dac3ac899d81d326d238f9fd3ccd"},
+ {file = "multiprocess-0.70.17-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:27b8409c02b5dd89d336107c101dfbd1530a2cd4fd425fc27dcb7adb6e0b47bf"},
+ {file = "multiprocess-0.70.17-pp39-pypy39_pp73-macosx_10_13_arm64.whl", hash = "sha256:2ea0939b0f4760a16a548942c65c76ff5afd81fbf1083c56ae75e21faf92e426"},
+ {file = "multiprocess-0.70.17-pp39-pypy39_pp73-macosx_10_13_x86_64.whl", hash = "sha256:2b12e081df87ab755190e227341b2c3b17ee6587e9c82fecddcbe6aa812cd7f7"},
+ {file = "multiprocess-0.70.17-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:a0f01cd9d079af7a8296f521dc03859d1a414d14c1e2b6e676ef789333421c95"},
+ {file = "multiprocess-0.70.17-py310-none-any.whl", hash = "sha256:38357ca266b51a2e22841b755d9a91e4bb7b937979a54d411677111716c32744"},
+ {file = "multiprocess-0.70.17-py311-none-any.whl", hash = "sha256:2884701445d0177aec5bd5f6ee0df296773e4fb65b11903b94c613fb46cfb7d1"},
+ {file = "multiprocess-0.70.17-py312-none-any.whl", hash = "sha256:2818af14c52446b9617d1b0755fa70ca2f77c28b25ed97bdaa2c69a22c47b46c"},
+ {file = "multiprocess-0.70.17-py313-none-any.whl", hash = "sha256:20c28ca19079a6c879258103a6d60b94d4ffe2d9da07dda93fb1c8bc6243f522"},
+ {file = "multiprocess-0.70.17-py38-none-any.whl", hash = "sha256:1d52f068357acd1e5bbc670b273ef8f81d57863235d9fbf9314751886e141968"},
+ {file = "multiprocess-0.70.17-py39-none-any.whl", hash = "sha256:c3feb874ba574fbccfb335980020c1ac631fbf2a3f7bee4e2042ede62558a021"},
+ {file = "multiprocess-0.70.17.tar.gz", hash = "sha256:4ae2f11a3416809ebc9a48abfc8b14ecce0652a0944731a1493a3c1ba44ff57a"},
]
[package.dependencies]
-dill = ">=0.3.8"
+dill = ">=0.3.9"
[[package]]
name = "multitasking"
@@ -5597,13 +5635,13 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"]
[[package]]
name = "oci"
-version = "2.135.0"
+version = "2.135.1"
description = "Oracle Cloud Infrastructure Python SDK"
optional = false
python-versions = "*"
files = [
- {file = "oci-2.135.0-py3-none-any.whl", hash = "sha256:c01f1d103ed034fa7ca2bceb297bf00e6f6c456d14a46b35ee9007b25f3ea397"},
- {file = "oci-2.135.0.tar.gz", hash = "sha256:6e28e6595264705d8fd0719045ffc4b23170e7fd2cd76a1c3aa25e4cdaa5883a"},
+ {file = "oci-2.135.1-py3-none-any.whl", hash = "sha256:249e24638faa2058b2fa9ab4917ff230f2a8b3b97cd11a261ce6c7f97c3ed2ff"},
+ {file = "oci-2.135.1.tar.gz", hash = "sha256:bea8aaba19d3fed186ceaeedba6d46f1cdb3c6c7d93b39ab225a15cbd63f9ce8"},
]
[package.dependencies]
@@ -6212,20 +6250,20 @@ xml = ["lxml (>=4.9.2)"]
[[package]]
name = "pathos"
-version = "0.3.2"
+version = "0.3.3"
description = "parallel graph management and execution in heterogeneous computing"
optional = false
python-versions = ">=3.8"
files = [
- {file = "pathos-0.3.2-py3-none-any.whl", hash = "sha256:d669275e6eb4b3fbcd2846d7a6d1bba315fe23add0c614445ba1408d8b38bafe"},
- {file = "pathos-0.3.2.tar.gz", hash = "sha256:4f2a42bc1e10ccf0fe71961e7145fc1437018b6b21bd93b2446abc3983e49a7a"},
+ {file = "pathos-0.3.3-py3-none-any.whl", hash = "sha256:e04616c6448608ad1f809360be22e3f2078d949a36a81e6991da6c2dd1f82513"},
+ {file = "pathos-0.3.3.tar.gz", hash = "sha256:dcb2a5f321aa34ca541c1c1861011ea49df357bb908379c21dd5741f666e0a58"},
]
[package.dependencies]
-dill = ">=0.3.8"
-multiprocess = ">=0.70.16"
-pox = ">=0.3.4"
-ppft = ">=1.7.6.8"
+dill = ">=0.3.9"
+multiprocess = ">=0.70.17"
+pox = ">=0.3.5"
+ppft = ">=1.7.6.9"
[[package]]
name = "peewee"
@@ -6447,13 +6485,13 @@ tests = ["pytest (>=5.4.1)", "pytest-cov (>=2.8.1)", "pytest-mypy (>=0.8.0)", "p
[[package]]
name = "posthog"
-version = "3.6.6"
+version = "3.7.0"
description = "Integrate PostHog into any python application."
optional = false
python-versions = "*"
files = [
- {file = "posthog-3.6.6-py2.py3-none-any.whl", hash = "sha256:38834fd7f0732582a20d4eb4674c8d5c088e464d14d1b3f8c176e389aecaa4ef"},
- {file = "posthog-3.6.6.tar.gz", hash = "sha256:1e04783293117109189ad7048f3eedbe21caff0e39bee5e2d47a93dd790fefac"},
+ {file = "posthog-3.7.0-py2.py3-none-any.whl", hash = "sha256:3555161c3a9557b5666f96d8e1f17f410ea0f07db56e399e336a1656d4e5c722"},
+ {file = "posthog-3.7.0.tar.gz", hash = "sha256:b095d4354ba23f8b346ab5daed8ecfc5108772f922006982dfe8b2d29ebc6e0e"},
]
[package.dependencies]
@@ -6715,6 +6753,19 @@ files = [
{file = "pyarrow-17.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:392bc9feabc647338e6c89267635e111d71edad5fcffba204425a7c8d13610d7"},
{file = "pyarrow-17.0.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:af5ff82a04b2171415f1410cff7ebb79861afc5dae50be73ce06d6e870615204"},
{file = "pyarrow-17.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:edca18eaca89cd6382dfbcff3dd2d87633433043650c07375d095cd3517561d8"},
+ {file = "pyarrow-17.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c7916bff914ac5d4a8fe25b7a25e432ff921e72f6f2b7547d1e325c1ad9d155"},
+ {file = "pyarrow-17.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f553ca691b9e94b202ff741bdd40f6ccb70cdd5fbf65c187af132f1317de6145"},
+ {file = "pyarrow-17.0.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:0cdb0e627c86c373205a2f94a510ac4376fdc523f8bb36beab2e7f204416163c"},
+ {file = "pyarrow-17.0.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:d7d192305d9d8bc9082d10f361fc70a73590a4c65cf31c3e6926cd72b76bc35c"},
+ {file = "pyarrow-17.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:02dae06ce212d8b3244dd3e7d12d9c4d3046945a5933d28026598e9dbbda1fca"},
+ {file = "pyarrow-17.0.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:13d7a460b412f31e4c0efa1148e1d29bdf18ad1411eb6757d38f8fbdcc8645fb"},
+ {file = "pyarrow-17.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9b564a51fbccfab5a04a80453e5ac6c9954a9c5ef2890d1bcf63741909c3f8df"},
+ {file = "pyarrow-17.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32503827abbc5aadedfa235f5ece8c4f8f8b0a3cf01066bc8d29de7539532687"},
+ {file = "pyarrow-17.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a155acc7f154b9ffcc85497509bcd0d43efb80d6f733b0dc3bb14e281f131c8b"},
+ {file = "pyarrow-17.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:dec8d129254d0188a49f8a1fc99e0560dc1b85f60af729f47de4046015f9b0a5"},
+ {file = "pyarrow-17.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:a48ddf5c3c6a6c505904545c25a4ae13646ae1f8ba703c4df4a1bfe4f4006bda"},
+ {file = "pyarrow-17.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:42bf93249a083aca230ba7e2786c5f673507fa97bbd9725a1e2754715151a204"},
+ {file = "pyarrow-17.0.0.tar.gz", hash = "sha256:4beca9521ed2c0921c1023e68d097d0299b62c362639ea315572a58f3f50fd28"},
]
[package.dependencies]
@@ -7446,25 +7497,29 @@ files = [
[[package]]
name = "pywin32"
-version = "306"
+version = "307"
description = "Python for Window Extensions"
optional = false
python-versions = "*"
files = [
- {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"},
- {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"},
- {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"},
- {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"},
- {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"},
- {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"},
- {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"},
- {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"},
- {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"},
- {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"},
- {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"},
- {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"},
- {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"},
- {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"},
+ {file = "pywin32-307-cp310-cp310-win32.whl", hash = "sha256:f8f25d893c1e1ce2d685ef6d0a481e87c6f510d0f3f117932781f412e0eba31b"},
+ {file = "pywin32-307-cp310-cp310-win_amd64.whl", hash = "sha256:36e650c5e5e6b29b5d317385b02d20803ddbac5d1031e1f88d20d76676dd103d"},
+ {file = "pywin32-307-cp310-cp310-win_arm64.whl", hash = "sha256:0c12d61e0274e0c62acee79e3e503c312426ddd0e8d4899c626cddc1cafe0ff4"},
+ {file = "pywin32-307-cp311-cp311-win32.whl", hash = "sha256:fec5d27cc893178fab299de911b8e4d12c5954e1baf83e8a664311e56a272b75"},
+ {file = "pywin32-307-cp311-cp311-win_amd64.whl", hash = "sha256:987a86971753ed7fdd52a7fb5747aba955b2c7fbbc3d8b76ec850358c1cc28c3"},
+ {file = "pywin32-307-cp311-cp311-win_arm64.whl", hash = "sha256:fd436897c186a2e693cd0437386ed79f989f4d13d6f353f8787ecbb0ae719398"},
+ {file = "pywin32-307-cp312-cp312-win32.whl", hash = "sha256:07649ec6b01712f36debf39fc94f3d696a46579e852f60157a729ac039df0815"},
+ {file = "pywin32-307-cp312-cp312-win_amd64.whl", hash = "sha256:00d047992bb5dcf79f8b9b7c81f72e0130f9fe4b22df613f755ab1cc021d8347"},
+ {file = "pywin32-307-cp312-cp312-win_arm64.whl", hash = "sha256:b53658acbfc6a8241d72cc09e9d1d666be4e6c99376bc59e26cdb6223c4554d2"},
+ {file = "pywin32-307-cp313-cp313-win32.whl", hash = "sha256:ea4d56e48dc1ab2aa0a5e3c0741ad6e926529510516db7a3b6981a1ae74405e5"},
+ {file = "pywin32-307-cp313-cp313-win_amd64.whl", hash = "sha256:576d09813eaf4c8168d0bfd66fb7cb3b15a61041cf41598c2db4a4583bf832d2"},
+ {file = "pywin32-307-cp313-cp313-win_arm64.whl", hash = "sha256:b30c9bdbffda6a260beb2919f918daced23d32c79109412c2085cbc513338a0a"},
+ {file = "pywin32-307-cp37-cp37m-win32.whl", hash = "sha256:5101472f5180c647d4525a0ed289ec723a26231550dbfd369ec19d5faf60e511"},
+ {file = "pywin32-307-cp37-cp37m-win_amd64.whl", hash = "sha256:05de55a7c110478dc4b202230e98af5e0720855360d2b31a44bb4e296d795fba"},
+ {file = "pywin32-307-cp38-cp38-win32.whl", hash = "sha256:13d059fb7f10792542082f5731d5d3d9645320fc38814759313e5ee97c3fac01"},
+ {file = "pywin32-307-cp38-cp38-win_amd64.whl", hash = "sha256:7e0b2f93769d450a98ac7a31a087e07b126b6d571e8b4386a5762eb85325270b"},
+ {file = "pywin32-307-cp39-cp39-win32.whl", hash = "sha256:55ee87f2f8c294e72ad9d4261ca423022310a6e79fb314a8ca76ab3f493854c6"},
+ {file = "pywin32-307-cp39-cp39-win_amd64.whl", hash = "sha256:e9d5202922e74985b037c9ef46778335c102b74b95cec70f629453dbe7235d87"},
]
[[package]]
@@ -7968,18 +8023,19 @@ requests = "2.31.0"
[[package]]
name = "rich"
-version = "13.8.1"
+version = "13.9.2"
description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
optional = false
-python-versions = ">=3.7.0"
+python-versions = ">=3.8.0"
files = [
- {file = "rich-13.8.1-py3-none-any.whl", hash = "sha256:1760a3c0848469b97b558fc61c85233e3dafb69c7a071b4d60c38099d3cd4c06"},
- {file = "rich-13.8.1.tar.gz", hash = "sha256:8260cda28e3db6bf04d2d1ef4dbc03ba80a824c88b0e7668a0f23126a424844a"},
+ {file = "rich-13.9.2-py3-none-any.whl", hash = "sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1"},
+ {file = "rich-13.9.2.tar.gz", hash = "sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c"},
]
[package.dependencies]
markdown-it-py = ">=2.2.0"
pygments = ">=2.13.0,<3.0.0"
+typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.11\""}
[package.extras]
jupyter = ["ipywidgets (>=7.5.1,<9)"]
@@ -8112,29 +8168,29 @@ pyasn1 = ">=0.1.3"
[[package]]
name = "ruff"
-version = "0.6.8"
+version = "0.6.9"
description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false
python-versions = ">=3.7"
files = [
- {file = "ruff-0.6.8-py3-none-linux_armv6l.whl", hash = "sha256:77944bca110ff0a43b768f05a529fecd0706aac7bcce36d7f1eeb4cbfca5f0f2"},
- {file = "ruff-0.6.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:27b87e1801e786cd6ede4ada3faa5e254ce774de835e6723fd94551464c56b8c"},
- {file = "ruff-0.6.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cd48f945da2a6334f1793d7f701725a76ba93bf3d73c36f6b21fb04d5338dcf5"},
- {file = "ruff-0.6.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:677e03c00f37c66cea033274295a983c7c546edea5043d0c798833adf4cf4c6f"},
- {file = "ruff-0.6.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9f1476236b3eacfacfc0f66aa9e6cd39f2a624cb73ea99189556015f27c0bdeb"},
- {file = "ruff-0.6.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f5a2f17c7d32991169195d52a04c95b256378bbf0de8cb98478351eb70d526f"},
- {file = "ruff-0.6.8-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5fd0d4b7b1457c49e435ee1e437900ced9b35cb8dc5178921dfb7d98d65a08d0"},
- {file = "ruff-0.6.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8034b19b993e9601f2ddf2c517451e17a6ab5cdb1c13fdff50c1442a7171d87"},
- {file = "ruff-0.6.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6cfb227b932ba8ef6e56c9f875d987973cd5e35bc5d05f5abf045af78ad8e098"},
- {file = "ruff-0.6.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ef0411eccfc3909269fed47c61ffebdcb84a04504bafa6b6df9b85c27e813b0"},
- {file = "ruff-0.6.8-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:007dee844738c3d2e6c24ab5bc7d43c99ba3e1943bd2d95d598582e9c1b27750"},
- {file = "ruff-0.6.8-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:ce60058d3cdd8490e5e5471ef086b3f1e90ab872b548814e35930e21d848c9ce"},
- {file = "ruff-0.6.8-py3-none-musllinux_1_2_i686.whl", hash = "sha256:1085c455d1b3fdb8021ad534379c60353b81ba079712bce7a900e834859182fa"},
- {file = "ruff-0.6.8-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:70edf6a93b19481affd287d696d9e311388d808671bc209fb8907b46a8c3af44"},
- {file = "ruff-0.6.8-py3-none-win32.whl", hash = "sha256:792213f7be25316f9b46b854df80a77e0da87ec66691e8f012f887b4a671ab5a"},
- {file = "ruff-0.6.8-py3-none-win_amd64.whl", hash = "sha256:ec0517dc0f37cad14a5319ba7bba6e7e339d03fbf967a6d69b0907d61be7a263"},
- {file = "ruff-0.6.8-py3-none-win_arm64.whl", hash = "sha256:8d3bb2e3fbb9875172119021a13eed38849e762499e3cfde9588e4b4d70968dc"},
- {file = "ruff-0.6.8.tar.gz", hash = "sha256:a5bf44b1aa0adaf6d9d20f86162b34f7c593bfedabc51239953e446aefc8ce18"},
+ {file = "ruff-0.6.9-py3-none-linux_armv6l.whl", hash = "sha256:064df58d84ccc0ac0fcd63bc3090b251d90e2a372558c0f057c3f75ed73e1ccd"},
+ {file = "ruff-0.6.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:140d4b5c9f5fc7a7b074908a78ab8d384dd7f6510402267bc76c37195c02a7ec"},
+ {file = "ruff-0.6.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:53fd8ca5e82bdee8da7f506d7b03a261f24cd43d090ea9db9a1dc59d9313914c"},
+ {file = "ruff-0.6.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645d7d8761f915e48a00d4ecc3686969761df69fb561dd914a773c1a8266e14e"},
+ {file = "ruff-0.6.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eae02b700763e3847595b9d2891488989cac00214da7f845f4bcf2989007d577"},
+ {file = "ruff-0.6.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d5ccc9e58112441de8ad4b29dcb7a86dc25c5f770e3c06a9d57e0e5eba48829"},
+ {file = "ruff-0.6.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:417b81aa1c9b60b2f8edc463c58363075412866ae4e2b9ab0f690dc1e87ac1b5"},
+ {file = "ruff-0.6.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c866b631f5fbce896a74a6e4383407ba7507b815ccc52bcedabb6810fdb3ef7"},
+ {file = "ruff-0.6.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b118afbb3202f5911486ad52da86d1d52305b59e7ef2031cea3425142b97d6f"},
+ {file = "ruff-0.6.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a67267654edc23c97335586774790cde402fb6bbdb3c2314f1fc087dee320bfa"},
+ {file = "ruff-0.6.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3ef0cc774b00fec123f635ce5c547dac263f6ee9fb9cc83437c5904183b55ceb"},
+ {file = "ruff-0.6.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:12edd2af0c60fa61ff31cefb90aef4288ac4d372b4962c2864aeea3a1a2460c0"},
+ {file = "ruff-0.6.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:55bb01caeaf3a60b2b2bba07308a02fca6ab56233302406ed5245180a05c5625"},
+ {file = "ruff-0.6.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:925d26471fa24b0ce5a6cdfab1bb526fb4159952385f386bdcc643813d472039"},
+ {file = "ruff-0.6.9-py3-none-win32.whl", hash = "sha256:eb61ec9bdb2506cffd492e05ac40e5bc6284873aceb605503d8494180d6fc84d"},
+ {file = "ruff-0.6.9-py3-none-win_amd64.whl", hash = "sha256:785d31851c1ae91f45b3d8fe23b8ae4b5170089021fbb42402d811135f0b7117"},
+ {file = "ruff-0.6.9-py3-none-win_arm64.whl", hash = "sha256:a9641e31476d601f83cd602608739a0840e348bda93fec9f1ee816f8b6798b93"},
+ {file = "ruff-0.6.9.tar.gz", hash = "sha256:b076ef717a8e5bc819514ee1d602bbdca5b4420ae13a9cf61a0c0a4f53a2baa2"},
]
[[package]]
@@ -8331,13 +8387,13 @@ test = ["accelerate (>=0.24.1,<=0.27.0)", "apache-airflow (==2.9.3)", "apache-ai
[[package]]
name = "sagemaker-core"
-version = "1.0.9"
+version = "1.0.10"
description = "An python package for sagemaker core functionalities"
optional = false
python-versions = ">=3.8"
files = [
- {file = "sagemaker_core-1.0.9-py3-none-any.whl", hash = "sha256:7a22c46cf93594f8d44e3523d4ba98407911f3530af68a8ffdde5082d3b26fa3"},
- {file = "sagemaker_core-1.0.9.tar.gz", hash = "sha256:664115faf797412553fb81b97a4777e78e51dfd4454c32edb2c8371bf203c535"},
+ {file = "sagemaker_core-1.0.10-py3-none-any.whl", hash = "sha256:0bdcf6a467db988919cc6b6d0077f74871ee24c24adf7f759f9cb98460e08953"},
+ {file = "sagemaker_core-1.0.10.tar.gz", hash = "sha256:6d34a9b6dc5e17e8bfffd1d0650726865779c92b3b8f1b59fc15d42061a0dd29"},
]
[package.dependencies]
@@ -8887,13 +8943,13 @@ test = ["pytest", "tornado (>=4.5)", "typeguard"]
[[package]]
name = "tencentcloud-sdk-python-common"
-version = "3.0.1243"
+version = "3.0.1244"
description = "Tencent Cloud Common SDK for Python"
optional = false
python-versions = "*"
files = [
- {file = "tencentcloud-sdk-python-common-3.0.1243.tar.gz", hash = "sha256:4008126b5506543ddc33ea53ef25abe19b4fa025006ec7751b3d5b3c046438b6"},
- {file = "tencentcloud_sdk_python_common-3.0.1243-py2.py3-none-any.whl", hash = "sha256:ed5d2040627aeed2df1fe5f9d65b9987ef842222d79fb13136cc5866aa5ac50c"},
+ {file = "tencentcloud-sdk-python-common-3.0.1244.tar.gz", hash = "sha256:51e895a4f380ead51de5ebcef990cfda17cf466b130b8d1be7a95c11158a66e2"},
+ {file = "tencentcloud_sdk_python_common-3.0.1244-py2.py3-none-any.whl", hash = "sha256:a3275496740d7876386166e83331eab7ad66e70fe4216c96893e9697fdeb9848"},
]
[package.dependencies]
@@ -8901,17 +8957,17 @@ requests = ">=2.16.0"
[[package]]
name = "tencentcloud-sdk-python-hunyuan"
-version = "3.0.1243"
+version = "3.0.1244"
description = "Tencent Cloud Hunyuan SDK for Python"
optional = false
python-versions = "*"
files = [
- {file = "tencentcloud-sdk-python-hunyuan-3.0.1243.tar.gz", hash = "sha256:2caad419f24106574f05faf69d162060689e03452832fda890a28eb8814199bc"},
- {file = "tencentcloud_sdk_python_hunyuan-3.0.1243-py2.py3-none-any.whl", hash = "sha256:b5a5c0dfa8b6de68c2c8747bf34b880c7fd2a1cbd59efc372e076260228ce231"},
+ {file = "tencentcloud-sdk-python-hunyuan-3.0.1244.tar.gz", hash = "sha256:b43f6848ac464cb244f6b1a17c97b00cd36ea40e91a4fba9f7b8ac1e94ae600a"},
+ {file = "tencentcloud_sdk_python_hunyuan-3.0.1244-py2.py3-none-any.whl", hash = "sha256:c2679f49d129dd5ec905cbac97884f6a872e50300ec7ba1ab4fe654d1458213f"},
]
[package.dependencies]
-tencentcloud-sdk-python-common = "3.0.1243"
+tencentcloud-sdk-python-common = "3.0.1244"
[[package]]
name = "threadpoolctl"
@@ -9164,13 +9220,13 @@ files = [
[[package]]
name = "tomli"
-version = "2.0.1"
+version = "2.0.2"
description = "A lil' TOML parser"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
- {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
+ {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"},
+ {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"},
]
[[package]]
@@ -10293,13 +10349,13 @@ multidict = ">=4.0"
[[package]]
name = "yfinance"
-version = "0.2.43"
+version = "0.2.44"
description = "Download market data from Yahoo! Finance API"
optional = false
python-versions = "*"
files = [
- {file = "yfinance-0.2.43-py2.py3-none-any.whl", hash = "sha256:11b4f5515b17450bd3bdcdc26b299aeeaea7ff9cb63d0fa0a865f460c0c7618f"},
- {file = "yfinance-0.2.43.tar.gz", hash = "sha256:32404597f325a2a2c2708aceb8d552088dd26891ac0e6018f6c5f3f2f61055f0"},
+ {file = "yfinance-0.2.44-py2.py3-none-any.whl", hash = "sha256:fdc18791662f286539f7a08dccd7e8191b1ca509814f7b0faac264623bebe8a8"},
+ {file = "yfinance-0.2.44.tar.gz", hash = "sha256:532ad1644ee9cf4024ec0d9cade0cc073664ec0d140cc6c22a0cce8a9118b523"},
]
[package.dependencies]
@@ -10539,4 +10595,4 @@ cffi = ["cffi (>=1.11)"]
[metadata]
lock-version = "2.0"
python-versions = ">=3.10,<3.13"
-content-hash = "74a22b763f5f6f1414e843f1a508ff48210d32f9523b696e5dd443489deaad46"
+content-hash = "34ba8efcc67da342036ef075b693f59fdc67d246f40b857c9c1bd6f80c7283bd"
diff --git a/api/pyproject.toml b/api/pyproject.toml
index fe9e64907b..48418974d4 100644
--- a/api/pyproject.toml
+++ b/api/pyproject.toml
@@ -28,6 +28,7 @@ select = [
"PLR0402", # manual-from-import
"PLR1711", # useless-return
"PLR1714", # repeated-equality-comparison
+ "RUF013", # implicit-optional
"RUF019", # unnecessary-key-check
"RUF100", # unused-noqa
"RUF101", # redirected-noqa
@@ -74,8 +75,6 @@ ignore = [
[tool.ruff.lint.per-file-ignores]
"app.py" = [
- "F401", # unused-import
- "F811", # redefined-while-unused
]
"__init__.py" = [
"F401", # unused-import
@@ -88,66 +87,40 @@ ignore = [
"N803", # invalid-argument-name
]
"tests/*" = [
- "F401", # unused-import
"F811", # redefined-while-unused
]
+[tool.ruff.lint.pyflakes]
+allowed-unused-imports=[
+ "_pytest.monkeypatch",
+ "tests.integration_tests",
+]
+
[tool.ruff.format]
exclude = [
]
-[tool.pytest_env]
-OPENAI_API_KEY = "sk-IamNotARealKeyJustForMockTestKawaiiiiiiiiii"
-UPSTAGE_API_KEY = "up-aaaaaaaaaaaaaaaaaaaa"
-FIREWORKS_API_KEY = "fw_aaaaaaaaaaaaaaaaaaaa"
-NOMIC_API_KEY = "nk-aaaaaaaaaaaaaaaaaaaa"
-AZURE_OPENAI_API_BASE = "https://difyai-openai.openai.azure.com"
-AZURE_OPENAI_API_KEY = "xxxxb1707exxxxxxxxxxaaxxxxxf94"
-ANTHROPIC_API_KEY = "sk-ant-api11-IamNotARealKeyJustForMockTestKawaiiiiiiiiii-NotBaka-ASkksz"
-CHATGLM_API_BASE = "http://a.abc.com:11451"
-XINFERENCE_SERVER_URL = "http://a.abc.com:11451"
-XINFERENCE_GENERATION_MODEL_UID = "generate"
-XINFERENCE_CHAT_MODEL_UID = "chat"
-XINFERENCE_EMBEDDINGS_MODEL_UID = "embedding"
-XINFERENCE_RERANK_MODEL_UID = "rerank"
-GOOGLE_API_KEY = "abcdefghijklmnopqrstuvwxyz"
-HUGGINGFACE_API_KEY = "hf-awuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwu"
-HUGGINGFACE_TEXT_GEN_ENDPOINT_URL = "a"
-HUGGINGFACE_TEXT2TEXT_GEN_ENDPOINT_URL = "b"
-HUGGINGFACE_EMBEDDINGS_ENDPOINT_URL = "c"
-MOCK_SWITCH = "true"
-CODE_MAX_STRING_LENGTH = "80000"
-CODE_EXECUTION_ENDPOINT = "http://127.0.0.1:8194"
-CODE_EXECUTION_API_KEY = "dify-sandbox"
-FIRECRAWL_API_KEY = "fc-"
-TEI_EMBEDDING_SERVER_URL = "http://a.abc.com:11451"
-TEI_RERANK_SERVER_URL = "http://a.abc.com:11451"
-MIXEDBREAD_API_KEY = "mk-aaaaaaaaaaaaaaaaaaaa"
-VOYAGE_API_KEY = "va-aaaaaaaaaaaaaaaaaaaa"
-
[tool.poetry]
name = "dify-api"
package-mode = false
############################################################
-# Main dependencies
+# [ Main ] Dependency group
############################################################
[tool.poetry.dependencies]
anthropic = "~0.23.1"
authlib = "1.3.1"
+azure-ai-inference = "~1.0.0b3"
+azure-ai-ml = "~1.20.0"
azure-identity = "1.16.1"
-azure-storage-blob = "12.13.0"
beautifulsoup4 = "4.12.2"
boto3 = "1.35.17"
-sagemaker = "2.231.0"
bs4 = "~0.0.1"
cachetools = "~5.3.0"
celery = "~5.3.6"
chardet = "~5.1.0"
cohere = "~5.2.4"
-cos-python-sdk-v5 = "1.9.30"
-esdk-obs-python = "3.24.6.1"
dashscope = { version = "~1.17.0", extras = ["tokenizer"] }
flask = "~3.0.1"
flask-compress = "~1.14"
@@ -155,7 +128,7 @@ flask-cors = "~4.0.0"
flask-login = "~0.6.3"
flask-migrate = "~4.0.5"
flask-restful = "~0.3.10"
-Flask-SQLAlchemy = "~3.1.1"
+flask-sqlalchemy = "~3.1.1"
gevent = "~23.9.1"
gmpy2 = "~2.2.1"
google-ai-generativelanguage = "0.6.9"
@@ -164,22 +137,22 @@ google-api-python-client = "2.90.0"
google-auth = "2.29.0"
google-auth-httplib2 = "0.2.0"
google-cloud-aiplatform = "1.49.0"
-google-cloud-storage = "2.16.0"
google-generativeai = "0.8.1"
googleapis-common-protos = "1.63.0"
gunicorn = "~22.0.0"
httpx = { version = "~0.27.0", extras = ["socks"] }
huggingface-hub = "~0.16.4"
jieba = "0.42.1"
-langfuse = "^2.48.0"
-langsmith = "^0.1.77"
+langfuse = "~2.51.3"
+langsmith = "~0.1.77"
mailchimp-transactional = "~1.0.50"
markdown = "~3.5.1"
-novita-client = "^0.5.7"
+nomic = "~3.1.2"
+novita-client = "~0.5.7"
numpy = "~1.26.4"
+oci = "~2.135.1"
openai = "~1.29.0"
openpyxl = "~3.1.5"
-oss2 = "2.18.5"
pandas = { version = "~2.2.2", extras = ["performance", "excel"] }
psycopg2-binary = "~2.9.6"
pycryptodome = "3.19.1"
@@ -196,7 +169,8 @@ readabilipy = "0.2.0"
redis = { version = "~5.0.3", extras = ["hiredis"] }
replicate = "~0.22.0"
resend = "~0.7.0"
-scikit-learn = "^1.5.1"
+sagemaker = "2.231.0"
+scikit-learn = "~1.5.1"
sentry-sdk = { version = "~1.44.1", extras = ["flask"] }
sqlalchemy = "~2.0.29"
tencentcloud-sdk-python-hunyuan = "~3.0.1158"
@@ -204,6 +178,8 @@ tiktoken = "~0.7.0"
tokenizers = "~0.15.0"
transformers = "~4.35.0"
unstructured = { version = "~0.10.27", extras = ["docx", "epub", "md", "msg", "ppt", "pptx"] }
+validators = "0.21.0"
+volcengine-python-sdk = {extras = ["ark"], version = "~1.0.98"}
websocket-client = "~1.7.0"
werkzeug = "~3.0.1"
xinference-client = "0.15.2"
@@ -212,32 +188,26 @@ zhipuai = "1.0.7"
# Before adding new dependency, consider place it in alphabet order (a-z) and suitable group.
############################################################
+# [ Indirect ] dependency group
# Related transparent dependencies with pinned version
# required by main implementations
############################################################
-azure-ai-ml = "^1.19.0"
-azure-ai-inference = "^1.0.0b3"
-volcengine-python-sdk = {extras = ["ark"], version = "^1.0.98"}
-oci = "^2.133.0"
-tos = "^2.7.1"
-nomic = "^3.1.2"
-validators = "0.21.0"
-[tool.poetry.group.indriect.dependencies]
+[tool.poetry.group.indirect.dependencies]
kaleido = "0.2.1"
rank-bm25 = "~0.2.2"
safetensors = "~0.4.3"
############################################################
-# Tool dependencies required by tool implementations
+# [ Tools ] dependency group
############################################################
-
-[tool.poetry.group.tool.dependencies]
+[tool.poetry.group.tools.dependencies]
arxiv = "2.1.0"
cloudscraper = "1.2.71"
+duckduckgo-search = "~6.3.0"
+jsonpath-ng = "1.6.1"
matplotlib = "~3.8.2"
newspaper3k = "0.2.8"
-duckduckgo-search = "^6.2.6"
-jsonpath-ng = "1.6.1"
+nltk = "3.8.1"
numexpr = "~2.9.0"
opensearch-py = "2.4.0"
qrcode = "~7.4.2"
@@ -245,11 +215,24 @@ twilio = "~9.0.4"
vanna = { version = "0.5.5", extras = ["postgres", "mysql", "clickhouse", "duckdb"] }
wikipedia = "1.4.0"
yfinance = "~0.2.40"
-nltk = "3.8.1"
-############################################################
-# VDB dependencies required by vector store clients
-############################################################
+############################################################
+# [ Storage ] dependency group
+# Required for storage clients
+############################################################
+[tool.poetry.group.storage.dependencies]
+azure-storage-blob = "12.13.0"
+bce-python-sdk = "~0.9.23"
+cos-python-sdk-v5 = "1.9.30"
+esdk-obs-python = "3.24.6.1"
+google-cloud-storage = "2.16.0"
+oss2 = "2.18.5"
+tos = "~2.7.1"
+
+############################################################
+# [ VDB ] dependency group
+# Required by vector store clients
+############################################################
[tool.poetry.group.vdb.dependencies]
alibabacloud_gpdb20160503 = "~3.8.0"
alibabacloud_tea_openapi = "~0.3.9"
@@ -260,18 +243,17 @@ oracledb = "~2.2.1"
pgvecto-rs = { version = "~0.2.1", extras = ['sqlalchemy'] }
pgvector = "0.2.5"
pymilvus = "~2.4.4"
+qdrant-client = "1.7.3"
tcvectordb = "1.3.2"
tidb-vector = "0.0.9"
-qdrant-client = "1.7.3"
weaviate-client = "~3.21.0"
############################################################
-# Dev dependencies for running tests
+# [ Dev ] dependency group
+# Required for development and running tests
############################################################
-
[tool.poetry.group.dev]
optional = true
-
[tool.poetry.group.dev.dependencies]
coverage = "~7.2.4"
pytest = "~8.3.2"
@@ -280,12 +262,11 @@ pytest-env = "~1.1.3"
pytest-mock = "~3.14.0"
############################################################
-# Lint dependencies for code style linting
+# [ Lint ] dependency group
+# Required for code style linting
############################################################
-
[tool.poetry.group.lint]
optional = true
-
[tool.poetry.group.lint.dependencies]
dotenv-linter = "~0.5.0"
-ruff = "~0.6.8"
+ruff = "~0.6.9"
diff --git a/api/pytest.ini b/api/pytest.ini
new file mode 100644
index 0000000000..dcca08e2e5
--- /dev/null
+++ b/api/pytest.ini
@@ -0,0 +1,29 @@
+[pytest]
+env =
+ ANTHROPIC_API_KEY = sk-ant-api11-IamNotARealKeyJustForMockTestKawaiiiiiiiiii-NotBaka-ASkksz
+ AZURE_OPENAI_API_BASE = https://difyai-openai.openai.azure.com
+ AZURE_OPENAI_API_KEY = xxxxb1707exxxxxxxxxxaaxxxxxf94
+ CHATGLM_API_BASE = http://a.abc.com:11451
+ CODE_EXECUTION_API_KEY = dify-sandbox
+ CODE_EXECUTION_ENDPOINT = http://127.0.0.1:8194
+ CODE_MAX_STRING_LENGTH = 80000
+ FIRECRAWL_API_KEY = fc-
+ FIREWORKS_API_KEY = fw_aaaaaaaaaaaaaaaaaaaa
+ GOOGLE_API_KEY = abcdefghijklmnopqrstuvwxyz
+ HUGGINGFACE_API_KEY = hf-awuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwu
+ HUGGINGFACE_EMBEDDINGS_ENDPOINT_URL = c
+ HUGGINGFACE_TEXT2TEXT_GEN_ENDPOINT_URL = b
+ HUGGINGFACE_TEXT_GEN_ENDPOINT_URL = a
+ MIXEDBREAD_API_KEY = mk-aaaaaaaaaaaaaaaaaaaa
+ MOCK_SWITCH = true
+ NOMIC_API_KEY = nk-aaaaaaaaaaaaaaaaaaaa
+ OPENAI_API_KEY = sk-IamNotARealKeyJustForMockTestKawaiiiiiiiiii
+ TEI_EMBEDDING_SERVER_URL = http://a.abc.com:11451
+ TEI_RERANK_SERVER_URL = http://a.abc.com:11451
+ UPSTAGE_API_KEY = up-aaaaaaaaaaaaaaaaaaaa
+ VOYAGE_API_KEY = va-aaaaaaaaaaaaaaaaaaaa
+ XINFERENCE_CHAT_MODEL_UID = chat
+ XINFERENCE_EMBEDDINGS_MODEL_UID = embedding
+ XINFERENCE_GENERATION_MODEL_UID = generate
+ XINFERENCE_RERANK_MODEL_UID = rerank
+ XINFERENCE_SERVER_URL = http://a.abc.com:11451
diff --git a/api/services/account_service.py b/api/services/account_service.py
index 66ff5d2b7c..c3d3354a1d 100644
--- a/api/services/account_service.py
+++ b/api/services/account_service.py
@@ -321,7 +321,7 @@ class TenantService:
return tenant
@staticmethod
- def switch_tenant(account: Account, tenant_id: int = None) -> None:
+ def switch_tenant(account: Account, tenant_id: Optional[int] = None) -> None:
"""Switch the current workspace for the account"""
# Ensure tenant_id is provided
diff --git a/api/services/dataset_service.py b/api/services/dataset_service.py
index c165def6d5..b8f80a9f77 100644
--- a/api/services/dataset_service.py
+++ b/api/services/dataset_service.py
@@ -250,6 +250,9 @@ class DatasetService:
db.session.commit()
else:
data.pop("partial_member_list", None)
+ data.pop("external_knowledge_api_id", None)
+ data.pop("external_knowledge_id", None)
+ data.pop("external_retrieval_model", None)
filtered_data = {k: v for k, v in data.items() if v is not None or k == "description"}
action = None
if dataset.indexing_technique != data["indexing_technique"]:
diff --git a/api/services/errors/base.py b/api/services/errors/base.py
index 1fed71cf9e..4d39f956b8 100644
--- a/api/services/errors/base.py
+++ b/api/services/errors/base.py
@@ -1,3 +1,6 @@
+from typing import Optional
+
+
class BaseServiceError(Exception):
- def __init__(self, description: str = None):
+ def __init__(self, description: Optional[str] = None):
self.description = description
diff --git a/api/services/tag_service.py b/api/services/tag_service.py
index 5e2851cd8f..a374bdcf00 100644
--- a/api/services/tag_service.py
+++ b/api/services/tag_service.py
@@ -1,4 +1,5 @@
import uuid
+from typing import Optional
from flask_login import current_user
from sqlalchemy import func
@@ -11,7 +12,7 @@ from models.model import App, Tag, TagBinding
class TagService:
@staticmethod
- def get_tags(tag_type: str, current_tenant_id: str, keyword: str = None) -> list:
+ def get_tags(tag_type: str, current_tenant_id: str, keyword: Optional[str] = None) -> list:
query = (
db.session.query(Tag.id, Tag.type, Tag.name, func.count(TagBinding.id).label("binding_count"))
.outerjoin(TagBinding, Tag.id == TagBinding.tag_id)
diff --git a/api/services/tools/api_tools_manage_service.py b/api/services/tools/api_tools_manage_service.py
index 6f6074f596..9f5298a506 100644
--- a/api/services/tools/api_tools_manage_service.py
+++ b/api/services/tools/api_tools_manage_service.py
@@ -1,5 +1,6 @@
import json
import logging
+from typing import Optional
from httpx import get
@@ -79,7 +80,7 @@ class ApiToolManageService:
raise ValueError(f"invalid schema: {str(e)}")
@staticmethod
- def convert_schema_to_tool_bundles(schema: str, extra_info: dict = None) -> list[ApiToolBundle]:
+ def convert_schema_to_tool_bundles(schema: str, extra_info: Optional[dict] = None) -> list[ApiToolBundle]:
"""
convert schema to tool bundles
diff --git a/api/services/tools/tools_transform_service.py b/api/services/tools/tools_transform_service.py
index 2bc48c4185..4af73d5063 100644
--- a/api/services/tools/tools_transform_service.py
+++ b/api/services/tools/tools_transform_service.py
@@ -144,7 +144,7 @@ class ToolTransformService:
@staticmethod
def workflow_provider_to_user_provider(
- provider_controller: WorkflowToolProviderController, labels: list[str] = None
+ provider_controller: WorkflowToolProviderController, labels: Optional[list[str]] = None
):
"""
convert provider controller to user provider
@@ -174,7 +174,7 @@ class ToolTransformService:
provider_controller: ApiToolProviderController,
db_provider: ApiToolProvider,
decrypt_credentials: bool = True,
- labels: list[str] = None,
+ labels: Optional[list[str]] = None,
) -> UserToolProvider:
"""
convert provider controller to user provider
@@ -223,9 +223,9 @@ class ToolTransformService:
@staticmethod
def tool_to_user_tool(
tool: Union[ApiToolBundle, WorkflowTool, Tool],
- credentials: dict = None,
- tenant_id: str = None,
- labels: list[str] = None,
+ credentials: Optional[dict] = None,
+ tenant_id: Optional[str] = None,
+ labels: Optional[list[str]] = None,
) -> UserTool:
"""
convert tool to user tool
diff --git a/api/services/tools/workflow_tools_manage_service.py b/api/services/tools/workflow_tools_manage_service.py
index 3830e75339..5868ef3755 100644
--- a/api/services/tools/workflow_tools_manage_service.py
+++ b/api/services/tools/workflow_tools_manage_service.py
@@ -1,5 +1,6 @@
import json
from datetime import datetime
+from typing import Optional
from sqlalchemy import or_
@@ -32,7 +33,7 @@ class WorkflowToolManageService:
description: str,
parameters: list[dict],
privacy_policy: str = "",
- labels: list[str] = None,
+ labels: Optional[list[str]] = None,
) -> dict:
"""
Create a workflow tool.
@@ -106,7 +107,7 @@ class WorkflowToolManageService:
description: str,
parameters: list[dict],
privacy_policy: str = "",
- labels: list[str] = None,
+ labels: Optional[list[str]] = None,
) -> dict:
"""
Update a workflow tool.
diff --git a/api/services/website_service.py b/api/services/website_service.py
index be01815720..13cc9c679a 100644
--- a/api/services/website_service.py
+++ b/api/services/website_service.py
@@ -166,6 +166,8 @@ class WebsiteService:
@classmethod
def get_crawl_url_data(cls, job_id: str, provider: str, url: str, tenant_id: str) -> dict | None:
credentials = ApiKeyAuthService.get_auth_credentials(tenant_id, "website", provider)
+ # decrypt api_key
+ api_key = encrypter.decrypt_token(tenant_id=tenant_id, token=credentials.get("config").get("api_key"))
if provider == "firecrawl":
file_key = "website_files/" + job_id + ".txt"
if storage.exists(file_key):
@@ -173,8 +175,6 @@ class WebsiteService:
if data:
data = json.loads(data.decode("utf-8"))
else:
- # decrypt api_key
- api_key = encrypter.decrypt_token(tenant_id=tenant_id, token=credentials.get("config").get("api_key"))
firecrawl_app = FirecrawlApp(api_key=api_key, base_url=credentials.get("config").get("base_url", None))
result = firecrawl_app.check_crawl_status(job_id)
if result.get("status") != "completed":
diff --git a/api/tests/artifact_tests/dependencies/__init__.py b/api/tests/artifact_tests/dependencies/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/api/tests/artifact_tests/dependencies/test_dependencies_sorted.py b/api/tests/artifact_tests/dependencies/test_dependencies_sorted.py
new file mode 100644
index 0000000000..518cee1a3a
--- /dev/null
+++ b/api/tests/artifact_tests/dependencies/test_dependencies_sorted.py
@@ -0,0 +1,61 @@
+from typing import Any
+
+import toml
+
+ALL_DEPENDENCY_GROUP_NAMES = [
+ # default main group
+ "",
+ # required groups
+ "indirect",
+ "storage",
+ "tools",
+ "vdb",
+ # optional groups
+ "dev",
+ "lint",
+]
+
+
+def load_api_poetry_configs() -> dict[str, Any]:
+ pyproject_toml = toml.load("api/pyproject.toml")
+ return pyproject_toml.get("tool").get("poetry")
+
+
+def load_dependency_groups() -> dict[str, dict[str, dict[str, Any]]]:
+ poetry_configs = load_api_poetry_configs()
+ group_name_to_dependencies = {
+ group_name: (poetry_configs.get("group").get(group_name) if group_name else poetry_configs).get("dependencies")
+ for group_name in ALL_DEPENDENCY_GROUP_NAMES
+ }
+ return group_name_to_dependencies
+
+
+def test_group_dependencies_sorted():
+ for group_name, dependencies in load_dependency_groups().items():
+ dependency_names = list(dependencies.keys())
+ expected_dependency_names = sorted(set(dependency_names))
+ section = f"tool.poetry.group.{group_name}.dependencies" if group_name else "tool.poetry.dependencies"
+ assert expected_dependency_names == dependency_names, (
+ f"Dependencies in group {group_name} are not sorted. "
+ f"Check and fix [{section}] section in pyproject.toml file"
+ )
+
+
+def test_group_dependencies_version_operator():
+ for group_name, dependencies in load_dependency_groups().items():
+ for dependency_name, specification in dependencies.items():
+ version_spec = specification if isinstance(specification, str) else specification.get("version")
+ assert not version_spec.startswith("^"), (
+ f"'^' is not allowed in dependency version," f" but found in '{dependency_name} = {version_spec}'"
+ )
+
+
+def test_duplicated_dependency_crossing_groups():
+ all_dependency_names: list[str] = []
+ for dependencies in load_dependency_groups().values():
+ dependency_names = list(dependencies.keys())
+ all_dependency_names.extend(dependency_names)
+ expected_all_dependency_names = set(all_dependency_names)
+ assert sorted(expected_all_dependency_names) == sorted(
+ all_dependency_names
+ ), "Duplicated dependencies crossing groups are found"
diff --git a/api/tests/integration_tests/model_runtime/__mock/anthropic.py b/api/tests/integration_tests/model_runtime/__mock/anthropic.py
index 79a3dc0394..5092af4f13 100644
--- a/api/tests/integration_tests/model_runtime/__mock/anthropic.py
+++ b/api/tests/integration_tests/model_runtime/__mock/anthropic.py
@@ -5,7 +5,7 @@ from typing import Any, Literal, Union
import anthropic
import pytest
from _pytest.monkeypatch import MonkeyPatch
-from anthropic import Anthropic, Stream
+from anthropic import Stream
from anthropic.resources import Messages
from anthropic.types import (
ContentBlock,
diff --git a/api/tests/integration_tests/model_runtime/__mock/nomic_embeddings.py b/api/tests/integration_tests/model_runtime/__mock/nomic_embeddings.py
index 281e866e45..6a25398cbf 100644
--- a/api/tests/integration_tests/model_runtime/__mock/nomic_embeddings.py
+++ b/api/tests/integration_tests/model_runtime/__mock/nomic_embeddings.py
@@ -1,6 +1,6 @@
import os
from collections.abc import Callable
-from typing import Any, Literal, Union
+from typing import Any, Literal
import pytest
diff --git a/api/tests/integration_tests/model_runtime/__mock/openai_chat.py b/api/tests/integration_tests/model_runtime/__mock/openai_chat.py
index 439f7d56e9..1dc5df7667 100644
--- a/api/tests/integration_tests/model_runtime/__mock/openai_chat.py
+++ b/api/tests/integration_tests/model_runtime/__mock/openai_chat.py
@@ -1,6 +1,6 @@
import re
from collections.abc import Generator
-from json import dumps, loads
+from json import dumps
from time import time
# import monkeypatch
@@ -11,11 +11,9 @@ from openai._types import NOT_GIVEN, NotGiven
from openai.resources.chat.completions import Completions
from openai.types import Completion as CompletionMessage
from openai.types.chat import (
- ChatCompletion,
ChatCompletionChunk,
ChatCompletionMessageParam,
ChatCompletionMessageToolCall,
- ChatCompletionToolChoiceOptionParam,
ChatCompletionToolParam,
completion_create_params,
)
diff --git a/api/tests/integration_tests/model_runtime/__mock/openai_embeddings.py b/api/tests/integration_tests/model_runtime/__mock/openai_embeddings.py
index e27b9891f5..3cc1fa9ff1 100644
--- a/api/tests/integration_tests/model_runtime/__mock/openai_embeddings.py
+++ b/api/tests/integration_tests/model_runtime/__mock/openai_embeddings.py
@@ -1,7 +1,6 @@
import re
from typing import Any, Literal, Union
-from openai import OpenAI
from openai._types import NOT_GIVEN, NotGiven
from openai.resources.embeddings import Embeddings
from openai.types.create_embedding_response import CreateEmbeddingResponse, Usage
diff --git a/api/tests/integration_tests/model_runtime/__mock/openai_remote.py b/api/tests/integration_tests/model_runtime/__mock/openai_remote.py
index cb8f249543..704dbad5d2 100644
--- a/api/tests/integration_tests/model_runtime/__mock/openai_remote.py
+++ b/api/tests/integration_tests/model_runtime/__mock/openai_remote.py
@@ -1,6 +1,5 @@
from time import time
-from openai.resources.models import Models
from openai.types.model import Model
diff --git a/api/tests/integration_tests/model_runtime/__mock/xinference.py b/api/tests/integration_tests/model_runtime/__mock/xinference.py
index 8deb50635f..5f7dad50c1 100644
--- a/api/tests/integration_tests/model_runtime/__mock/xinference.py
+++ b/api/tests/integration_tests/model_runtime/__mock/xinference.py
@@ -5,7 +5,6 @@ from typing import Union
import pytest
from _pytest.monkeypatch import MonkeyPatch
from requests import Response
-from requests.exceptions import ConnectionError
from requests.sessions import Session
from xinference_client.client.restful.restful_client import (
Client,
diff --git a/api/tests/integration_tests/model_runtime/azure_ai_studio/test_llm.py b/api/tests/integration_tests/model_runtime/azure_ai_studio/test_llm.py
index 8655b43d8f..85a4f7734d 100644
--- a/api/tests/integration_tests/model_runtime/azure_ai_studio/test_llm.py
+++ b/api/tests/integration_tests/model_runtime/azure_ai_studio/test_llm.py
@@ -6,10 +6,7 @@ import pytest
from core.model_runtime.entities.llm_entities import LLMResult, LLMResultChunk, LLMResultChunkDelta
from core.model_runtime.entities.message_entities import (
AssistantPromptMessage,
- ImagePromptMessageContent,
- PromptMessageTool,
SystemPromptMessage,
- TextPromptMessageContent,
UserPromptMessage,
)
from core.model_runtime.errors.validate import CredentialsValidateFailedError
diff --git a/api/tests/integration_tests/model_runtime/chatglm/test_llm.py b/api/tests/integration_tests/model_runtime/chatglm/test_llm.py
index 418e88874d..a7c5229e05 100644
--- a/api/tests/integration_tests/model_runtime/chatglm/test_llm.py
+++ b/api/tests/integration_tests/model_runtime/chatglm/test_llm.py
@@ -8,7 +8,6 @@ from core.model_runtime.entities.message_entities import (
AssistantPromptMessage,
PromptMessageTool,
SystemPromptMessage,
- TextPromptMessageContent,
UserPromptMessage,
)
from core.model_runtime.entities.model_entities import AIModelEntity
diff --git a/api/tests/integration_tests/model_runtime/huggingface_tei/test_rerank.py b/api/tests/integration_tests/model_runtime/huggingface_tei/test_rerank.py
index 45370d9fba..cd1c20dd02 100644
--- a/api/tests/integration_tests/model_runtime/huggingface_tei/test_rerank.py
+++ b/api/tests/integration_tests/model_runtime/huggingface_tei/test_rerank.py
@@ -2,8 +2,7 @@ import os
import pytest
-from core.model_runtime.entities.rerank_entities import RerankDocument, RerankResult
-from core.model_runtime.entities.text_embedding_entities import TextEmbeddingResult
+from core.model_runtime.entities.rerank_entities import RerankResult
from core.model_runtime.errors.validate import CredentialsValidateFailedError
from core.model_runtime.model_providers.huggingface_tei.rerank.rerank import (
HuggingfaceTeiRerankModel,
diff --git a/api/tests/integration_tests/model_runtime/localai/test_llm.py b/api/tests/integration_tests/model_runtime/localai/test_llm.py
index aa5436c34f..51e899fd51 100644
--- a/api/tests/integration_tests/model_runtime/localai/test_llm.py
+++ b/api/tests/integration_tests/model_runtime/localai/test_llm.py
@@ -8,10 +8,8 @@ from core.model_runtime.entities.message_entities import (
AssistantPromptMessage,
PromptMessageTool,
SystemPromptMessage,
- TextPromptMessageContent,
UserPromptMessage,
)
-from core.model_runtime.entities.model_entities import ParameterRule
from core.model_runtime.errors.validate import CredentialsValidateFailedError
from core.model_runtime.model_providers.localai.llm.llm import LocalAILanguageModel
diff --git a/api/tests/integration_tests/model_runtime/nomic/test_provider.py b/api/tests/integration_tests/model_runtime/nomic/test_provider.py
index 6cad400c06..ece4bb9200 100644
--- a/api/tests/integration_tests/model_runtime/nomic/test_provider.py
+++ b/api/tests/integration_tests/model_runtime/nomic/test_provider.py
@@ -4,7 +4,6 @@ import pytest
from core.model_runtime.errors.validate import CredentialsValidateFailedError
from core.model_runtime.model_providers.nomic.nomic import NomicAtlasProvider
-from core.model_runtime.model_providers.nomic.text_embedding.text_embedding import NomicTextEmbeddingModel
from tests.integration_tests.model_runtime.__mock.nomic_embeddings import setup_nomic_mock
diff --git a/api/tests/integration_tests/model_runtime/novita/test_llm.py b/api/tests/integration_tests/model_runtime/novita/test_llm.py
index 35fa0dc190..9f92679cd5 100644
--- a/api/tests/integration_tests/model_runtime/novita/test_llm.py
+++ b/api/tests/integration_tests/model_runtime/novita/test_llm.py
@@ -6,7 +6,6 @@ import pytest
from core.model_runtime.entities.llm_entities import LLMResult, LLMResultChunk, LLMResultChunkDelta
from core.model_runtime.entities.message_entities import (
AssistantPromptMessage,
- PromptMessageTool,
SystemPromptMessage,
UserPromptMessage,
)
diff --git a/api/tests/integration_tests/model_runtime/oci/test_llm.py b/api/tests/integration_tests/model_runtime/oci/test_llm.py
index 531f26a32e..bd5d27eb0f 100644
--- a/api/tests/integration_tests/model_runtime/oci/test_llm.py
+++ b/api/tests/integration_tests/model_runtime/oci/test_llm.py
@@ -8,7 +8,6 @@ from core.model_runtime.entities.message_entities import (
AssistantPromptMessage,
PromptMessageTool,
SystemPromptMessage,
- TextPromptMessageContent,
UserPromptMessage,
)
from core.model_runtime.errors.validate import CredentialsValidateFailedError
diff --git a/api/tests/integration_tests/model_runtime/openai/test_llm.py b/api/tests/integration_tests/model_runtime/openai/test_llm.py
index 3b3ea9ec80..41c99f6875 100644
--- a/api/tests/integration_tests/model_runtime/openai/test_llm.py
+++ b/api/tests/integration_tests/model_runtime/openai/test_llm.py
@@ -14,7 +14,6 @@ from core.model_runtime.entities.message_entities import (
)
from core.model_runtime.entities.model_entities import AIModelEntity, ModelType
from core.model_runtime.errors.validate import CredentialsValidateFailedError
-from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel
from core.model_runtime.model_providers.openai.llm.llm import OpenAILargeLanguageModel
"""FOR MOCK FIXTURES, DO NOT REMOVE"""
diff --git a/api/tests/integration_tests/model_runtime/openrouter/test_llm.py b/api/tests/integration_tests/model_runtime/openrouter/test_llm.py
index ce4876a73a..1b0cc6bf4b 100644
--- a/api/tests/integration_tests/model_runtime/openrouter/test_llm.py
+++ b/api/tests/integration_tests/model_runtime/openrouter/test_llm.py
@@ -6,7 +6,6 @@ import pytest
from core.model_runtime.entities.llm_entities import LLMResult, LLMResultChunk, LLMResultChunkDelta
from core.model_runtime.entities.message_entities import (
AssistantPromptMessage,
- PromptMessageTool,
SystemPromptMessage,
UserPromptMessage,
)
diff --git a/api/tests/integration_tests/model_runtime/sagemaker/test_provider.py b/api/tests/integration_tests/model_runtime/sagemaker/test_provider.py
index 9f0b439d6c..41de2a17fd 100644
--- a/api/tests/integration_tests/model_runtime/sagemaker/test_provider.py
+++ b/api/tests/integration_tests/model_runtime/sagemaker/test_provider.py
@@ -1,5 +1,3 @@
-import os
-
import pytest
from core.model_runtime.errors.validate import CredentialsValidateFailedError
diff --git a/api/tests/integration_tests/model_runtime/sagemaker/test_text_embedding.py b/api/tests/integration_tests/model_runtime/sagemaker/test_text_embedding.py
index e4e404c7a8..f77601eea2 100644
--- a/api/tests/integration_tests/model_runtime/sagemaker/test_text_embedding.py
+++ b/api/tests/integration_tests/model_runtime/sagemaker/test_text_embedding.py
@@ -1,5 +1,3 @@
-import os
-
import pytest
from core.model_runtime.entities.text_embedding_entities import TextEmbeddingResult
diff --git a/api/tests/integration_tests/model_runtime/stepfun/test_llm.py b/api/tests/integration_tests/model_runtime/stepfun/test_llm.py
index c03b1bae1f..f9afca6f59 100644
--- a/api/tests/integration_tests/model_runtime/stepfun/test_llm.py
+++ b/api/tests/integration_tests/model_runtime/stepfun/test_llm.py
@@ -6,13 +6,11 @@ import pytest
from core.model_runtime.entities.llm_entities import LLMResult, LLMResultChunk, LLMResultChunkDelta
from core.model_runtime.entities.message_entities import (
AssistantPromptMessage,
- ImagePromptMessageContent,
PromptMessageTool,
SystemPromptMessage,
- TextPromptMessageContent,
UserPromptMessage,
)
-from core.model_runtime.entities.model_entities import AIModelEntity, ModelType
+from core.model_runtime.entities.model_entities import AIModelEntity
from core.model_runtime.errors.validate import CredentialsValidateFailedError
from core.model_runtime.model_providers.stepfun.llm.llm import StepfunLargeLanguageModel
diff --git a/api/tests/integration_tests/model_runtime/togetherai/test_llm.py b/api/tests/integration_tests/model_runtime/togetherai/test_llm.py
index 06ebc2a82d..5787e1bf6a 100644
--- a/api/tests/integration_tests/model_runtime/togetherai/test_llm.py
+++ b/api/tests/integration_tests/model_runtime/togetherai/test_llm.py
@@ -6,7 +6,6 @@ import pytest
from core.model_runtime.entities.llm_entities import LLMResult, LLMResultChunk, LLMResultChunkDelta
from core.model_runtime.entities.message_entities import (
AssistantPromptMessage,
- PromptMessageTool,
SystemPromptMessage,
UserPromptMessage,
)
diff --git a/api/tests/integration_tests/model_runtime/upstage/test_llm.py b/api/tests/integration_tests/model_runtime/upstage/test_llm.py
index bc7517acbe..0f39e902f3 100644
--- a/api/tests/integration_tests/model_runtime/upstage/test_llm.py
+++ b/api/tests/integration_tests/model_runtime/upstage/test_llm.py
@@ -10,9 +10,8 @@ from core.model_runtime.entities.message_entities import (
SystemPromptMessage,
UserPromptMessage,
)
-from core.model_runtime.entities.model_entities import AIModelEntity, ModelType
+from core.model_runtime.entities.model_entities import AIModelEntity
from core.model_runtime.errors.validate import CredentialsValidateFailedError
-from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel
from core.model_runtime.model_providers.upstage.llm.llm import UpstageLargeLanguageModel
"""FOR MOCK FIXTURES, DO NOT REMOVE"""
diff --git a/api/tests/integration_tests/model_runtime/xinference/test_llm.py b/api/tests/integration_tests/model_runtime/xinference/test_llm.py
index fb5e03855d..5e4cde3638 100644
--- a/api/tests/integration_tests/model_runtime/xinference/test_llm.py
+++ b/api/tests/integration_tests/model_runtime/xinference/test_llm.py
@@ -8,10 +8,8 @@ from core.model_runtime.entities.message_entities import (
AssistantPromptMessage,
PromptMessageTool,
SystemPromptMessage,
- TextPromptMessageContent,
UserPromptMessage,
)
-from core.model_runtime.entities.model_entities import AIModelEntity
from core.model_runtime.errors.validate import CredentialsValidateFailedError
from core.model_runtime.model_providers.xinference.llm.llm import XinferenceAILargeLanguageModel
diff --git a/api/tests/integration_tests/vdb/__mock/tcvectordb.py b/api/tests/integration_tests/vdb/__mock/tcvectordb.py
index 53c9b3cae3..61d6ed1656 100644
--- a/api/tests/integration_tests/vdb/__mock/tcvectordb.py
+++ b/api/tests/integration_tests/vdb/__mock/tcvectordb.py
@@ -48,7 +48,7 @@ class MockTcvectordbClass:
description: str,
index: Index,
embedding: Embedding = None,
- timeout: float = None,
+ timeout: Optional[float] = None,
) -> Collection:
return Collection(
self,
@@ -97,9 +97,9 @@ class MockTcvectordbClass:
def collection_delete(
self,
- document_ids: list[str] = None,
+ document_ids: Optional[list[str]] = None,
filter: Filter = None,
- timeout: float = None,
+ timeout: Optional[float] = None,
):
return {"code": 0, "msg": "operation success"}
diff --git a/api/tests/integration_tests/vdb/pgvector/test_pgvector.py b/api/tests/integration_tests/vdb/pgvector/test_pgvector.py
index 72efdc2780..3d2cfde5d1 100644
--- a/api/tests/integration_tests/vdb/pgvector/test_pgvector.py
+++ b/api/tests/integration_tests/vdb/pgvector/test_pgvector.py
@@ -1,5 +1,4 @@
from core.rag.datasource.vdb.pgvector.pgvector import PGVector, PGVectorConfig
-from core.rag.models.document import Document
from tests.integration_tests.vdb.test_vector_store import (
AbstractVectorTest,
get_example_text,
diff --git a/api/tests/integration_tests/vdb/test_vector_store.py b/api/tests/integration_tests/vdb/test_vector_store.py
index a11cd225b3..50519e2052 100644
--- a/api/tests/integration_tests/vdb/test_vector_store.py
+++ b/api/tests/integration_tests/vdb/test_vector_store.py
@@ -1,4 +1,3 @@
-import random
import uuid
from unittest.mock import MagicMock
diff --git a/api/tests/integration_tests/workflow/nodes/__mock/code_executor.py b/api/tests/integration_tests/workflow/nodes/__mock/code_executor.py
index 6fb8c86b82..30414811ea 100644
--- a/api/tests/integration_tests/workflow/nodes/__mock/code_executor.py
+++ b/api/tests/integration_tests/workflow/nodes/__mock/code_executor.py
@@ -1,5 +1,5 @@
import os
-from typing import Literal, Optional
+from typing import Literal
import pytest
from _pytest.monkeypatch import MonkeyPatch
diff --git a/api/tests/integration_tests/workflow/nodes/test_parameter_extractor.py b/api/tests/integration_tests/workflow/nodes/test_parameter_extractor.py
index 88435c4022..4c695f7443 100644
--- a/api/tests/integration_tests/workflow/nodes/test_parameter_extractor.py
+++ b/api/tests/integration_tests/workflow/nodes/test_parameter_extractor.py
@@ -1,4 +1,3 @@
-import json
import os
import time
import uuid
diff --git a/api/tests/unit_tests/core/app/segments/test_variables.py b/api/tests/unit_tests/core/app/segments/test_variables.py
index b3f0ae626c..6179675cde 100644
--- a/api/tests/unit_tests/core/app/segments/test_variables.py
+++ b/api/tests/unit_tests/core/app/segments/test_variables.py
@@ -2,7 +2,6 @@ import pytest
from pydantic import ValidationError
from core.app.segments import (
- ArrayAnyVariable,
FloatVariable,
IntegerVariable,
ObjectVariable,
diff --git a/api/tests/unit_tests/core/rag/extractor/firecrawl/test_firecrawl.py b/api/tests/unit_tests/core/rag/extractor/firecrawl/test_firecrawl.py
index d5a1d8f436..8fcdf2e8e5 100644
--- a/api/tests/unit_tests/core/rag/extractor/firecrawl/test_firecrawl.py
+++ b/api/tests/unit_tests/core/rag/extractor/firecrawl/test_firecrawl.py
@@ -1,9 +1,6 @@
import os
-from unittest import mock
from core.rag.extractor.firecrawl.firecrawl_app import FirecrawlApp
-from core.rag.extractor.firecrawl.firecrawl_web_extractor import FirecrawlWebExtractor
-from core.rag.models.document import Document
from tests.unit_tests.core.rag.extractor.test_notion_extractor import _mock_response
diff --git a/dev/pytest/pytest_artifacts.sh b/dev/pytest/pytest_artifacts.sh
new file mode 100755
index 0000000000..d52acb2273
--- /dev/null
+++ b/dev/pytest/pytest_artifacts.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+set -x
+
+pytest api/tests/artifact_tests/
diff --git a/dev/pytest/pytest_vdb.sh b/dev/pytest/pytest_vdb.sh
index 0b23200dc3..bad809cbfd 100755
--- a/dev/pytest/pytest_vdb.sh
+++ b/dev/pytest/pytest_vdb.sh
@@ -7,5 +7,4 @@ pytest api/tests/integration_tests/vdb/chroma \
api/tests/integration_tests/vdb/pgvector \
api/tests/integration_tests/vdb/qdrant \
api/tests/integration_tests/vdb/weaviate \
- api/tests/integration_tests/vdb/elasticsearch \
- api/tests/integration_tests/vdb/test_vector_store.py
\ No newline at end of file
+ api/tests/integration_tests/vdb/elasticsearch
\ No newline at end of file
diff --git a/dev/sync-poetry b/dev/sync-poetry
index 2dd4dd4fc3..23d5d79e90 100755
--- a/dev/sync-poetry
+++ b/dev/sync-poetry
@@ -11,5 +11,8 @@ poetry check -C api --lock
if [ $? -ne 0 ]; then
# update poetry.lock
# refreshing lockfile only without updating locked versions
+ echo "poetry.lock is outdated, refreshing without updating locked versions ..."
poetry lock -C api --no-update
+else
+ echo "poetry.lock is ready."
fi
diff --git a/docker-legacy/docker-compose.yaml b/docker-legacy/docker-compose.yaml
index 1636bb6a21..3f230b47ab 100644
--- a/docker-legacy/docker-compose.yaml
+++ b/docker-legacy/docker-compose.yaml
@@ -2,7 +2,7 @@ version: '3'
services:
# API service
api:
- image: langgenius/dify-api:0.8.3
+ image: langgenius/dify-api:0.9.1
restart: always
environment:
# Startup mode, 'api' starts the API server.
@@ -227,7 +227,7 @@ services:
# worker service
# The Celery worker for processing the queue.
worker:
- image: langgenius/dify-api:0.8.3
+ image: langgenius/dify-api:0.9.1
restart: always
environment:
CONSOLE_WEB_URL: ''
@@ -396,7 +396,7 @@ services:
# Frontend web application.
web:
- image: langgenius/dify-web:0.8.3
+ image: langgenius/dify-web:0.9.1
restart: always
environment:
# The base URL of console application api server, refers to the Console base URL of WEB service if console domain is
diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml
index 95e271a0e9..ddb6ded206 100644
--- a/docker/docker-compose.yaml
+++ b/docker/docker-compose.yaml
@@ -213,7 +213,7 @@ x-shared-env: &shared-api-worker-env
services:
# API service
api:
- image: langgenius/dify-api:0.8.3
+ image: langgenius/dify-api:0.9.1
restart: always
environment:
# Use the shared environment variables.
@@ -233,7 +233,7 @@ services:
# worker service
# The Celery worker for processing the queue.
worker:
- image: langgenius/dify-api:0.8.3
+ image: langgenius/dify-api:0.9.1
restart: always
environment:
# Use the shared environment variables.
@@ -252,7 +252,7 @@ services:
# Frontend web application.
web:
- image: langgenius/dify-web:0.8.3
+ image: langgenius/dify-web:0.9.1
restart: always
environment:
CONSOLE_API_URL: ${CONSOLE_API_URL:-}
diff --git a/web/Dockerfile b/web/Dockerfile
index 48bdb2301a..29f7675f4a 100644
--- a/web/Dockerfile
+++ b/web/Dockerfile
@@ -46,21 +46,27 @@ ENV TZ=UTC
RUN ln -s /usr/share/zoneinfo/${TZ} /etc/localtime \
&& echo ${TZ} > /etc/timezone
-# global runtime packages
-RUN yarn global add pm2 \
- && yarn cache clean
WORKDIR /app/web
COPY --from=builder /app/web/public ./public
COPY --from=builder /app/web/.next/standalone ./
COPY --from=builder /app/web/.next/static ./.next/static
-
COPY docker/pm2.json ./pm2.json
COPY docker/entrypoint.sh ./entrypoint.sh
+
+# global runtime packages
+RUN yarn global add pm2 \
+ && yarn cache clean \
+ && mkdir /.pm2 \
+ && chown -R 1001:0 /.pm2 /app/web \
+ && chmod -R g=u /.pm2 /app/web
+
+
ARG COMMIT_SHA
ENV COMMIT_SHA=${COMMIT_SHA}
+USER 1001
EXPOSE 3000
ENTRYPOINT ["/bin/sh", "./entrypoint.sh"]
diff --git a/web/app/components/app/configuration/dataset-config/settings-modal/index.tsx b/web/app/components/app/configuration/dataset-config/settings-modal/index.tsx
index 81a2ccc72b..389ae0d1fa 100644
--- a/web/app/components/app/configuration/dataset-config/settings-modal/index.tsx
+++ b/web/app/components/app/configuration/dataset-config/settings-modal/index.tsx
@@ -61,10 +61,10 @@ const SettingsModal: FC = ({
const { t } = useTranslation()
const { notify } = useToastContext()
const ref = useRef(null)
+ const isExternal = currentDataset.provider === 'external'
const [topK, setTopK] = useState(currentDataset?.external_retrieval_model.top_k ?? 2)
const [scoreThreshold, setScoreThreshold] = useState(currentDataset?.external_retrieval_model.score_threshold ?? 0.5)
const [scoreThresholdEnabled, setScoreThresholdEnabled] = useState(currentDataset?.external_retrieval_model.score_threshold_enabled ?? false)
-
const { setShowAccountSettingModal } = useModalContext()
const [loading, setLoading] = useState(false)
const { isCurrentWorkspaceDatasetOperator } = useAppContext()
@@ -124,19 +124,21 @@ const SettingsModal: FC = ({
description,
permission,
indexing_technique: indexMethod,
- external_retrieval_model: {
- top_k: topK,
- score_threshold: scoreThreshold,
- score_threshold_enabled: scoreThresholdEnabled,
- },
retrieval_model: {
...postRetrievalConfig,
score_threshold: postRetrievalConfig.score_threshold_enabled ? postRetrievalConfig.score_threshold : 0,
},
- external_knowledge_id: currentDataset!.external_knowledge_info.external_knowledge_id,
- external_knowledge_api_id: currentDataset!.external_knowledge_info.external_knowledge_api_id,
embedding_model: localeCurrentDataset.embedding_model,
embedding_model_provider: localeCurrentDataset.embedding_model_provider,
+ ...(isExternal && {
+ external_knowledge_id: currentDataset!.external_knowledge_info.external_knowledge_id,
+ external_knowledge_api_id: currentDataset!.external_knowledge_info.external_knowledge_api_id,
+ external_retrieval_model: {
+ top_k: topK,
+ score_threshold: scoreThreshold,
+ score_threshold_enabled: scoreThresholdEnabled,
+ },
+ }),
},
} as any
if (permission === 'partial_members') {
diff --git a/web/app/components/app/overview/embedded/index.tsx b/web/app/components/app/overview/embedded/index.tsx
index fa023192c9..b71a3c3fdf 100644
--- a/web/app/components/app/overview/embedded/index.tsx
+++ b/web/app/components/app/overview/embedded/index.tsx
@@ -52,6 +52,10 @@ const OPTION_MAP = {
#dify-chatbot-bubble-button {
background-color: ${primaryColor} !important;
}
+ #dify-chatbot-bubble-window {
+ width: 24rem !important;
+ height: 40rem !important;
+ }
`,
},
chromePlugin: {
diff --git a/web/app/components/base/chat/embedded-chatbot/theme/theme-context.ts b/web/app/components/base/chat/embedded-chatbot/theme/theme-context.ts
index fd424cd046..7a814e2521 100644
--- a/web/app/components/base/chat/embedded-chatbot/theme/theme-context.ts
+++ b/web/app/components/base/chat/embedded-chatbot/theme/theme-context.ts
@@ -26,7 +26,7 @@ export class Theme {
if (this.chatColorTheme !== null && this.chatColorTheme !== '') {
this.primaryColor = this.chatColorTheme ?? '#1C64F2'
this.backgroundHeaderColorStyle = `backgroundColor: ${this.primaryColor}`
- this.backgroundButtonDefaultColorStyle = `backgroundColor: ${this.primaryColor}`
+ this.backgroundButtonDefaultColorStyle = `backgroundColor: ${this.primaryColor}; color: ${colorFontOnHeaderStyle};`
this.roundedBackgroundColorStyle = `backgroundColor: ${hexToRGBA(this.primaryColor, 0.05)}`
this.chatBubbleColorStyle = `backgroundColor: ${hexToRGBA(this.primaryColor, 0.15)}`
this.chatBubbleColor = `${hexToRGBA(this.primaryColor, 0.15)}`
diff --git a/web/app/components/base/prompt-editor/plugins/workflow-variable-block/workflow-variable-block-replacement-block.tsx b/web/app/components/base/prompt-editor/plugins/workflow-variable-block/workflow-variable-block-replacement-block.tsx
index c88b1661ad..0a80ecc220 100644
--- a/web/app/components/base/prompt-editor/plugins/workflow-variable-block/workflow-variable-block-replacement-block.tsx
+++ b/web/app/components/base/prompt-editor/plugins/workflow-variable-block/workflow-variable-block-replacement-block.tsx
@@ -12,7 +12,7 @@ import type { WorkflowVariableBlockType } from '../../types'
import { CustomTextNode } from '../custom-text/node'
import { $createWorkflowVariableBlockNode } from './node'
import { WorkflowVariableBlockNode } from './index'
-import { VAR_REGEX as REGEX } from '@/config'
+import { VAR_REGEX as REGEX, resetReg } from '@/config'
const WorkflowVariableBlockReplacementBlock = ({
workflowNodesMap,
@@ -48,11 +48,12 @@ const WorkflowVariableBlockReplacementBlock = ({
}, [])
const transformListener = useCallback((textNode: any) => {
+ resetReg()
return decoratorTransform(textNode, getMatch, createWorkflowVariableBlockNode)
}, [createWorkflowVariableBlockNode, getMatch])
useEffect(() => {
- REGEX.lastIndex = 0
+ resetReg()
return mergeRegister(
editor.registerNodeTransform(CustomTextNode, transformListener),
)
diff --git a/web/app/components/datasets/settings/form/index.tsx b/web/app/components/datasets/settings/form/index.tsx
index 3fc153cc36..0de2883f54 100644
--- a/web/app/components/datasets/settings/form/index.tsx
+++ b/web/app/components/datasets/settings/form/index.tsx
@@ -139,19 +139,21 @@ const Form = () => {
description,
permission,
indexing_technique: indexMethod,
- external_retrieval_model: {
- top_k: topK,
- score_threshold: scoreThreshold,
- score_threshold_enabled: scoreThresholdEnabled,
- },
retrieval_model: {
...postRetrievalConfig,
score_threshold: postRetrievalConfig.score_threshold_enabled ? postRetrievalConfig.score_threshold : 0,
},
- external_knowledge_id: currentDataset!.external_knowledge_info.external_knowledge_id,
- external_knowledge_api_id: currentDataset!.external_knowledge_info.external_knowledge_api_id,
embedding_model: embeddingModel.model,
embedding_model_provider: embeddingModel.provider,
+ ...(currentDataset!.provider === 'external' && {
+ external_knowledge_id: currentDataset!.external_knowledge_info.external_knowledge_id,
+ external_knowledge_api_id: currentDataset!.external_knowledge_info.external_knowledge_api_id,
+ external_retrieval_model: {
+ top_k: topK,
+ score_threshold: scoreThreshold,
+ score_threshold_enabled: scoreThresholdEnabled,
+ },
+ }),
},
} as any
if (permission === 'partial_members') {
diff --git a/web/config/index.ts b/web/config/index.ts
index 21fc2f211c..9eb4889441 100644
--- a/web/config/index.ts
+++ b/web/config/index.ts
@@ -158,28 +158,28 @@ export const DEFAULT_AGENT_SETTING = {
}
export const DEFAULT_AGENT_PROMPT = {
- chat: `Respond to the human as helpfully and accurately as possible.
+ chat: `Respond to the human as helpfully and accurately as possible.
{{instruction}}
-
+
You have access to the following tools:
-
+
{{tools}}
-
+
Use a json blob to specify a tool by providing an {{TOOL_NAME_KEY}} key (tool name) and an {{ACTION_INPUT_KEY}} key (tool input).
Valid "{{TOOL_NAME_KEY}}" values: "Final Answer" or {{tool_names}}
-
+
Provide only ONE action per $JSON_BLOB, as shown:
-
+
\`\`\`
{
"{{TOOL_NAME_KEY}}": $TOOL_NAME,
"{{ACTION_INPUT_KEY}}": $ACTION_INPUT
}
\`\`\`
-
+
Follow this format:
-
+
Question: input question to answer
Thought: consider previous and subsequent steps
Action:
@@ -196,10 +196,10 @@ export const DEFAULT_AGENT_PROMPT = {
"{{ACTION_INPUT_KEY}}": "Final response to human"
}
\`\`\`
-
+
Begin! Reminder to ALWAYS respond with a valid json blob of a single action. Use tools if necessary. Respond directly if appropriate. Format is Action:\`\`\`$JSON_BLOB\`\`\`then Observation:.`,
completion: `
- Respond to the human as helpfully and accurately as possible.
+ Respond to the human as helpfully and accurately as possible.
{{instruction}}
@@ -246,6 +246,8 @@ Thought: {{agent_scratchpad}}
export const VAR_REGEX = /\{\{(#[a-zA-Z0-9_-]{1,50}(\.[a-zA-Z_][a-zA-Z0-9_]{0,29}){1,10}#)\}\}/gi
+export const resetReg = () => VAR_REGEX.lastIndex = 0
+
export let textGenerationTimeoutMs = 60000
if (process.env.NEXT_PUBLIC_TEXT_GENERATION_TIMEOUT_MS && process.env.NEXT_PUBLIC_TEXT_GENERATION_TIMEOUT_MS !== '')
diff --git a/web/i18n/language.ts b/web/i18n/language.ts
index c2e23cc19a..fde69328bd 100644
--- a/web/i18n/language.ts
+++ b/web/i18n/language.ts
@@ -31,8 +31,10 @@ export const languages = data.languages
export const LanguagesSupported = languages.filter(item => item.supported).map(item => item.value)
export const getLanguage = (locale: string) => {
- const supportedLocale = LanguagesSupported.find(lang => lang.startsWith(locale.split('-')[0]))
- return (supportedLocale || LanguagesSupported[0]).replace('-', '_')
+ if (locale === 'zh-Hans')
+ return locale.replace('-', '_')
+
+ return LanguagesSupported[0].replace('-', '_')
}
export const NOTICE_I18N = {
diff --git a/web/package.json b/web/package.json
index 77fb842737..d9534b22d3 100644
--- a/web/package.json
+++ b/web/package.json
@@ -1,6 +1,6 @@
{
"name": "dify-web",
- "version": "0.8.3",
+ "version": "0.9.1",
"private": true,
"engines": {
"node": ">=18.17.0"
diff --git a/web/service/base.ts b/web/service/base.ts
index 83389d8be8..fbdd5c1fd3 100644
--- a/web/service/base.ts
+++ b/web/service/base.ts
@@ -359,9 +359,6 @@ const baseFetch = (
case 401: {
if (isPublicAPI) {
return bodyJson.then((data: ResponseError) => {
- if (!silent)
- Toast.notify({ type: 'error', message: data.message })
-
if (data.code === 'web_sso_auth_required')
requiredWebSSOLogin()
@@ -536,8 +533,6 @@ export const ssePost = (
.then((res) => {
if (!/^(2|3)\d{2}$/.test(String(res.status))) {
res.json().then((data: any) => {
- Toast.notify({ type: 'error', message: data.message || 'Server Error' })
-
if (isPublicAPI) {
if (data.code === 'web_sso_auth_required')
requiredWebSSOLogin()
@@ -546,7 +541,10 @@ export const ssePost = (
removeAccessToken()
globalThis.location.reload()
}
+ if (res.status === 401)
+ return
}
+ Toast.notify({ type: 'error', message: data.message || 'Server Error' })
})
onError?.('Server Error')
return
diff --git a/web/service/datasets.ts b/web/service/datasets.ts
index b3bb19b9f3..90411efd4e 100644
--- a/web/service/datasets.ts
+++ b/web/service/datasets.ts
@@ -30,8 +30,9 @@ import type {
createDocumentResponse,
} from '@/models/datasets'
import type { CreateKnowledgeBaseReq } from '@/app/components/datasets/external-knowledge-base/create/declarations'
-import type { CreateExternalAPIReq } from '@/app/components/datasets/external-api/declarations.ts'
+import type { CreateExternalAPIReq } from '@/app/components/datasets/external-api/declarations'
import type { CommonResponse, DataSourceNotionWorkspace } from '@/models/common'
+import { DataSourceProvider } from '@/models/common'
import type {
ApiKeysListResponse,
CreateApiKeyResponse,