diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index d681dc6627..719e6cfe90 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -20,7 +20,7 @@ jobs: - name: Check changed files id: changed-files - uses: tj-actions/changed-files@v44 + uses: tj-actions/changed-files@v45 with: files: api/** @@ -66,7 +66,7 @@ jobs: - name: Check changed files id: changed-files - uses: tj-actions/changed-files@v44 + uses: tj-actions/changed-files@v45 with: files: web/** @@ -97,7 +97,7 @@ jobs: - name: Check changed files id: changed-files - uses: tj-actions/changed-files@v44 + uses: tj-actions/changed-files@v45 with: files: | **.sh @@ -107,7 +107,7 @@ jobs: dev/** - name: Super-linter - uses: super-linter/super-linter/slim@v6 + uses: super-linter/super-linter/slim@v7 if: steps.changed-files.outputs.any_changed == 'true' env: BASH_SEVERITY: warning diff --git a/.github/workflows/translate-i18n-base-on-english.yml b/.github/workflows/translate-i18n-base-on-english.yml new file mode 100644 index 0000000000..3f51b3b2c7 --- /dev/null +++ b/.github/workflows/translate-i18n-base-on-english.yml @@ -0,0 +1,54 @@ +name: Check i18n Files and Create PR + +on: + pull_request: + types: [closed] + branches: [main] + +jobs: + check-and-update: + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + defaults: + run: + working-directory: web + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 2 # last 2 commits + + - name: Check for file changes in i18n/en-US + id: check_files + run: | + recent_commit_sha=$(git rev-parse HEAD) + second_recent_commit_sha=$(git rev-parse HEAD~1) + changed_files=$(git diff --name-only $recent_commit_sha $second_recent_commit_sha -- 'i18n/en-US/*.ts') + echo "Changed files: $changed_files" + if [ -n "$changed_files" ]; then + echo "FILES_CHANGED=true" >> $GITHUB_ENV + else + echo "FILES_CHANGED=false" >> $GITHUB_ENV + fi + + - name: Set up Node.js + if: env.FILES_CHANGED == 'true' + uses: actions/setup-node@v2 + with: + node-version: 'lts/*' + + - name: Install dependencies + if: env.FILES_CHANGED == 'true' + run: yarn install --frozen-lockfile + + - name: Run npm script + if: env.FILES_CHANGED == 'true' + run: npm run auto-gen-i18n + + - name: Create Pull Request + if: env.FILES_CHANGED == 'true' + uses: peter-evans/create-pull-request@v6 + with: + commit-message: Update i18n files based on en-US changes + title: 'chore: translate i18n files' + body: This PR was automatically created to update i18n files based on changes in en-US locale. + branch: chore/automated-i18n-updates diff --git a/LICENSE b/LICENSE index 071ef42bda..06b0fa1d12 100644 --- a/LICENSE +++ b/LICENSE @@ -4,7 +4,7 @@ Dify is licensed under the Apache License 2.0, with the following additional con 1. Dify may be utilized commercially, including as a backend service for other applications or as an application development platform for enterprises. Should the conditions below be met, a commercial license must be obtained from the producer: -a. Multi-tenant SaaS service: Unless explicitly authorized by Dify in writing, you may not use the Dify source code to operate a multi-tenant environment. +a. Multi-tenant service: Unless explicitly authorized by Dify in writing, you may not use the Dify source code to operate a multi-tenant environment. - Tenant Definition: Within the context of Dify, one tenant corresponds to one workspace. The workspace provides a separated area for each tenant's data and configurations. b. LOGO and copyright information: In the process of using Dify's frontend components, you may not remove or modify the LOGO or copyright information in the Dify console or applications. This restriction is inapplicable to uses of Dify that do not involve its frontend components. diff --git a/api/.env.example b/api/.env.example index 2a48c20d84..21940402f4 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 +# storage type: local, s3, azure-blob, google-storage, tencent-cos, huawei-obs, volcengine-tos STORAGE_TYPE=local STORAGE_LOCAL_PATH=storage S3_USE_AWS_MANAGED_IAM=false @@ -60,7 +60,8 @@ ALIYUN_OSS_SECRET_KEY=your-secret-key ALIYUN_OSS_ENDPOINT=your-endpoint ALIYUN_OSS_AUTH_VERSION=v1 ALIYUN_OSS_REGION=your-region - +# Don't start with '/'. OSS doesn't support leading slash in object names. +ALIYUN_OSS_PATH=your-path # Google Storage configuration GOOGLE_STORAGE_BUCKET_NAME=yout-bucket-name GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64=your-google-service-account-json-base64-string @@ -72,6 +73,12 @@ TENCENT_COS_SECRET_ID=your-secret-id TENCENT_COS_REGION=your-region TENCENT_COS_SCHEME=your-scheme +# Huawei OBS Storage Configuration +HUAWEI_OBS_BUCKET_NAME=your-bucket-name +HUAWEI_OBS_SECRET_KEY=your-secret-key +HUAWEI_OBS_ACCESS_KEY=your-access-key +HUAWEI_OBS_SERVER=your-server-url + # OCI Storage configuration OCI_ENDPOINT=your-endpoint OCI_BUCKET_NAME=your-bucket-name @@ -79,6 +86,13 @@ OCI_ACCESS_KEY=your-access-key OCI_SECRET_KEY=your-secret-key OCI_REGION=your-region +# Volcengine tos Storage configuration +VOLCENGINE_TOS_ENDPOINT=your-endpoint +VOLCENGINE_TOS_BUCKET_NAME=your-bucket-name +VOLCENGINE_TOS_ACCESS_KEY=your-access-key +VOLCENGINE_TOS_SECRET_KEY=your-secret-key +VOLCENGINE_TOS_REGION=your-region + # CORS configuration WEB_API_CORS_ALLOW_ORIGINS=http://127.0.0.1:3000,* CONSOLE_CORS_ALLOW_ORIGINS=http://127.0.0.1:3000,* @@ -100,11 +114,10 @@ QDRANT_GRPC_ENABLED=false QDRANT_GRPC_PORT=6334 # Milvus configuration -MILVUS_HOST=127.0.0.1 -MILVUS_PORT=19530 +MILVUS_URI=http://127.0.0.1:19530 +MILVUS_TOKEN= MILVUS_USER=root MILVUS_PASSWORD=Milvus -MILVUS_SECURE=false # MyScale configuration MYSCALE_HOST=127.0.0.1 diff --git a/api/Dockerfile b/api/Dockerfile index 82b89ad77b..6483f8281b 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -55,7 +55,7 @@ RUN apt-get update \ && echo "deb http://deb.debian.org/debian testing main" > /etc/apt/sources.list \ && apt-get update \ # For Security - && apt-get install -y --no-install-recommends zlib1g=1:1.3.dfsg+really1.3.1-1 expat=2.6.2-1 libldap-2.5-0=2.5.18+dfsg-3 perl=5.38.2-5 libsqlite3-0=3.46.0-1 \ + && apt-get install -y --no-install-recommends zlib1g=1:1.3.dfsg+really1.3.1-1 expat=2.6.3-1 libldap-2.5-0=2.5.18+dfsg-3 perl=5.38.2-5 libsqlite3-0=3.46.0-1 \ && apt-get autoremove -y \ && rm -rf /var/lib/apt/lists/* diff --git a/api/configs/feature/__init__.py b/api/configs/feature/__init__.py index 8309ed13e4..903f66a53d 100644 --- a/api/configs/feature/__init__.py +++ b/api/configs/feature/__init__.py @@ -1,4 +1,4 @@ -from typing import Optional +from typing import Annotated, Optional from pydantic import AliasChoices, Field, HttpUrl, NegativeInt, NonNegativeInt, PositiveInt, computed_field from pydantic_settings import BaseSettings @@ -46,7 +46,7 @@ class CodeExecutionSandboxConfig(BaseSettings): """ CODE_EXECUTION_ENDPOINT: HttpUrl = Field( - description="endpoint URL of code execution servcie", + description="endpoint URL of code execution service", default="http://sandbox:8194", ) @@ -230,20 +230,17 @@ class HttpConfig(BaseSettings): def WEB_API_CORS_ALLOW_ORIGINS(self) -> list[str]: return self.inner_WEB_API_CORS_ALLOW_ORIGINS.split(",") - HTTP_REQUEST_MAX_CONNECT_TIMEOUT: NonNegativeInt = Field( - description="", - default=300, - ) + HTTP_REQUEST_MAX_CONNECT_TIMEOUT: Annotated[ + PositiveInt, Field(ge=10, description="connect timeout in seconds for HTTP request") + ] = 10 - HTTP_REQUEST_MAX_READ_TIMEOUT: NonNegativeInt = Field( - description="", - default=600, - ) + HTTP_REQUEST_MAX_READ_TIMEOUT: Annotated[ + PositiveInt, Field(ge=60, description="read timeout in seconds for HTTP request") + ] = 60 - HTTP_REQUEST_MAX_WRITE_TIMEOUT: NonNegativeInt = Field( - description="", - default=600, - ) + HTTP_REQUEST_MAX_WRITE_TIMEOUT: Annotated[ + PositiveInt, Field(ge=10, description="read timeout in seconds for HTTP request") + ] = 20 HTTP_REQUEST_NODE_MAX_BINARY_SIZE: PositiveInt = Field( description="", @@ -431,7 +428,7 @@ class MailConfig(BaseSettings): """ MAIL_TYPE: Optional[str] = Field( - description="Mail provider type name, default to None, availabile values are `smtp` and `resend`.", + description="Mail provider type name, default to None, available values are `smtp` and `resend`.", default=None, ) diff --git a/api/configs/middleware/__init__.py b/api/configs/middleware/__init__.py index f25979e5d8..e017c2c5b8 100644 --- a/api/configs/middleware/__init__.py +++ b/api/configs/middleware/__init__.py @@ -1,7 +1,7 @@ from typing import Any, Optional from urllib.parse import quote_plus -from pydantic import Field, NonNegativeInt, PositiveInt, computed_field +from pydantic import Field, NonNegativeInt, PositiveFloat, PositiveInt, computed_field from pydantic_settings import BaseSettings from configs.middleware.cache.redis_config import RedisConfig @@ -9,8 +9,10 @@ from configs.middleware.storage.aliyun_oss_storage_config import AliyunOSSStorag from configs.middleware.storage.amazon_s3_storage_config import S3StorageConfig from configs.middleware.storage.azure_blob_storage_config import AzureBlobStorageConfig 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 from configs.middleware.storage.tencent_cos_storage_config import TencentCloudCOSStorageConfig +from configs.middleware.storage.volcengine_tos_storage_config import VolcengineTOSStorageConfig from configs.middleware.vdb.analyticdb_config import AnalyticdbConfig from configs.middleware.vdb.chroma_config import ChromaConfig from configs.middleware.vdb.elasticsearch_config import ElasticsearchConfig @@ -157,6 +159,21 @@ class CeleryConfig(DatabaseConfig): default=None, ) + CELERY_USE_SENTINEL: Optional[bool] = Field( + description="Whether to use Redis Sentinel mode", + default=False, + ) + + CELERY_SENTINEL_MASTER_NAME: Optional[str] = Field( + description="Redis Sentinel master name", + default=None, + ) + + CELERY_SENTINEL_SOCKET_TIMEOUT: Optional[PositiveFloat] = Field( + description="Redis Sentinel socket timeout", + default=0.1, + ) + @computed_field @property def CELERY_RESULT_BACKEND(self) -> str | None: @@ -184,6 +201,8 @@ class MiddlewareConfig( AzureBlobStorageConfig, GoogleCloudStorageConfig, TencentCloudCOSStorageConfig, + HuaweiCloudOBSStorageConfig, + VolcengineTOSStorageConfig, S3StorageConfig, OCIStorageConfig, # configs of vdb and vdb providers diff --git a/api/configs/middleware/cache/redis_config.py b/api/configs/middleware/cache/redis_config.py index cacdaf6fb6..4fcd52ddc9 100644 --- a/api/configs/middleware/cache/redis_config.py +++ b/api/configs/middleware/cache/redis_config.py @@ -1,6 +1,6 @@ from typing import Optional -from pydantic import Field, NonNegativeInt, PositiveInt +from pydantic import Field, NonNegativeInt, PositiveFloat, PositiveInt from pydantic_settings import BaseSettings @@ -38,3 +38,33 @@ class RedisConfig(BaseSettings): description="whether to use SSL for Redis connection", default=False, ) + + REDIS_USE_SENTINEL: Optional[bool] = Field( + description="Whether to use Redis Sentinel mode", + default=False, + ) + + REDIS_SENTINELS: Optional[str] = Field( + description="Redis Sentinel nodes", + default=None, + ) + + REDIS_SENTINEL_SERVICE_NAME: Optional[str] = Field( + description="Redis Sentinel service name", + default=None, + ) + + REDIS_SENTINEL_USERNAME: Optional[str] = Field( + description="Redis Sentinel username", + default=None, + ) + + REDIS_SENTINEL_PASSWORD: Optional[str] = Field( + description="Redis Sentinel password", + default=None, + ) + + REDIS_SENTINEL_SOCKET_TIMEOUT: Optional[PositiveFloat] = Field( + description="Redis Sentinel socket timeout", + default=0.1, + ) diff --git a/api/configs/middleware/storage/aliyun_oss_storage_config.py b/api/configs/middleware/storage/aliyun_oss_storage_config.py index 78f70b7ad3..c1843dc26c 100644 --- a/api/configs/middleware/storage/aliyun_oss_storage_config.py +++ b/api/configs/middleware/storage/aliyun_oss_storage_config.py @@ -38,3 +38,8 @@ class AliyunOSSStorageConfig(BaseSettings): description="Aliyun OSS authentication version", default=None, ) + + ALIYUN_OSS_PATH: Optional[str] = Field( + description="Aliyun OSS path", + default=None, + ) diff --git a/api/configs/middleware/storage/huawei_obs_storage_config.py b/api/configs/middleware/storage/huawei_obs_storage_config.py new file mode 100644 index 0000000000..c5cb379cae --- /dev/null +++ b/api/configs/middleware/storage/huawei_obs_storage_config.py @@ -0,0 +1,29 @@ +from typing import Optional + +from pydantic import BaseModel, Field + + +class HuaweiCloudOBSStorageConfig(BaseModel): + """ + Huawei Cloud OBS storage configs + """ + + HUAWEI_OBS_BUCKET_NAME: Optional[str] = Field( + description="Huawei Cloud OBS bucket name", + default=None, + ) + + HUAWEI_OBS_ACCESS_KEY: Optional[str] = Field( + description="Huawei Cloud OBS Access key", + default=None, + ) + + HUAWEI_OBS_SECRET_KEY: Optional[str] = Field( + description="Huawei Cloud OBS Secret key", + default=None, + ) + + HUAWEI_OBS_SERVER: Optional[str] = Field( + description="Huawei Cloud OBS server URL", + default=None, + ) diff --git a/api/configs/middleware/storage/volcengine_tos_storage_config.py b/api/configs/middleware/storage/volcengine_tos_storage_config.py new file mode 100644 index 0000000000..a0e09a3cc7 --- /dev/null +++ b/api/configs/middleware/storage/volcengine_tos_storage_config.py @@ -0,0 +1,34 @@ +from typing import Optional + +from pydantic import BaseModel, Field + + +class VolcengineTOSStorageConfig(BaseModel): + """ + Volcengine tos storage configs + """ + + VOLCENGINE_TOS_BUCKET_NAME: Optional[str] = Field( + description="Volcengine TOS Bucket Name", + default=None, + ) + + VOLCENGINE_TOS_ACCESS_KEY: Optional[str] = Field( + description="Volcengine TOS Access Key", + default=None, + ) + + VOLCENGINE_TOS_SECRET_KEY: Optional[str] = Field( + description="Volcengine TOS Secret Key", + default=None, + ) + + VOLCENGINE_TOS_ENDPOINT: Optional[str] = Field( + description="Volcengine TOS Endpoint URL", + default=None, + ) + + VOLCENGINE_TOS_REGION: Optional[str] = Field( + description="Volcengine TOS Region", + default=None, + ) diff --git a/api/configs/middleware/vdb/milvus_config.py b/api/configs/middleware/vdb/milvus_config.py index 85466cd5cc..98d375966a 100644 --- a/api/configs/middleware/vdb/milvus_config.py +++ b/api/configs/middleware/vdb/milvus_config.py @@ -1,6 +1,6 @@ from typing import Optional -from pydantic import Field, PositiveInt +from pydantic import Field from pydantic_settings import BaseSettings @@ -9,14 +9,14 @@ class MilvusConfig(BaseSettings): Milvus configs """ - MILVUS_HOST: Optional[str] = Field( - description="Milvus host", - default=None, + MILVUS_URI: Optional[str] = Field( + description="Milvus uri", + default="http://127.0.0.1:19530", ) - MILVUS_PORT: PositiveInt = Field( - description="Milvus RestFul API port", - default=9091, + MILVUS_TOKEN: Optional[str] = Field( + description="Milvus token", + default=None, ) MILVUS_USER: Optional[str] = Field( @@ -29,11 +29,6 @@ class MilvusConfig(BaseSettings): default=None, ) - MILVUS_SECURE: bool = Field( - description="whether to use SSL connection for Milvus", - default=False, - ) - MILVUS_DATABASE: str = Field( description="Milvus database, default to `default`", default="default", diff --git a/api/configs/packaging/__init__.py b/api/configs/packaging/__init__.py index dd09671612..2d540ca584 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.7.2", + default="0.7.3", ) COMMIT_SHA: str = Field( diff --git a/api/constants/recommended_apps.json b/api/constants/recommended_apps.json index df4adc4a1f..3779fb0180 100644 --- a/api/constants/recommended_apps.json +++ b/api/constants/recommended_apps.json @@ -320,7 +320,7 @@ "icon_background": "#FFEAD5", "id": "e9870913-dd01-4710-9f06-15d4180ca1ce", "mode": "advanced-chat", - "name": "Knowledge Retreival + Chatbot " + "name": "Knowledge Retrieval + Chatbot " }, "app_id": "e9870913-dd01-4710-9f06-15d4180ca1ce", "category": "Workflow", @@ -423,7 +423,7 @@ "name": "Website Generator" }, "a23b57fa-85da-49c0-a571-3aff375976c1": { - "export_data": "app:\n icon: \"\\U0001F911\"\n icon_background: '#E4FBCC'\n mode: agent-chat\n name: Investment Analysis Report Copilot\nmodel_config:\n agent_mode:\n enabled: true\n max_iteration: 5\n strategy: function_call\n tools:\n - enabled: true\n isDeleted: false\n notAuthor: false\n provider_id: yahoo\n provider_name: yahoo\n provider_type: builtin\n tool_label: Analytics\n tool_name: yahoo_finance_analytics\n tool_parameters:\n end_date: ''\n start_date: ''\n symbol: ''\n - enabled: true\n isDeleted: false\n notAuthor: false\n provider_id: yahoo\n provider_name: yahoo\n provider_type: builtin\n tool_label: News\n tool_name: yahoo_finance_news\n tool_parameters:\n symbol: ''\n - enabled: true\n isDeleted: false\n notAuthor: false\n provider_id: yahoo\n provider_name: yahoo\n provider_type: builtin\n tool_label: Ticker\n tool_name: yahoo_finance_ticker\n tool_parameters:\n symbol: ''\n annotation_reply:\n enabled: false\n chat_prompt_config: {}\n completion_prompt_config: {}\n dataset_configs:\n datasets:\n datasets: []\n retrieval_model: single\n dataset_query_variable: ''\n external_data_tools: []\n file_upload:\n image:\n detail: high\n enabled: false\n number_limits: 3\n transfer_methods:\n - remote_url\n - local_file\n model:\n completion_params:\n frequency_penalty: 0.5\n max_tokens: 4096\n presence_penalty: 0.5\n stop: []\n temperature: 0.2\n top_p: 0.75\n mode: chat\n name: gpt-4-1106-preview\n provider: openai\n more_like_this:\n enabled: false\n opening_statement: 'Welcome to your personalized Investment Analysis Copilot service,\n where we delve into the depths of stock analysis to provide you with comprehensive\n insights. To begin our journey into the financial world, try to ask:\n\n '\n pre_prompt: \"# Job Description: Data Analysis Copilot\\n## Character\\nMy primary\\\n \\ goal is to provide user with expert data analysis advice. Using extensive and\\\n \\ detailed data. Tell me the stock (with ticket symbol) you want to analyze. I\\\n \\ will do all fundemental, technical, market sentiment, and Marcoeconomical analysis\\\n \\ for the stock as an expert. \\n\\n## Skills \\n### Skill 1: Search for stock information\\\n \\ using 'Ticker' from Yahoo Finance \\n### Skill 2: Search for recent news using\\\n \\ 'News' for the target company. \\n### Skill 3: Search for financial figures and\\\n \\ analytics using 'Analytics' for the target company\\n\\n## Workflow\\nAsks the\\\n \\ user which stocks with ticker name need to be analyzed and then performs the\\\n \\ following analysis in sequence. \\n**Part I: Fundamental analysis: financial\\\n \\ reporting analysis\\n*Objective 1: In-depth analysis of the financial situation\\\n \\ of the target company.\\n*Steps:\\n1. Identify the object of analysis:\\n\\n\\n\\n2. Access to financial\\\n \\ reports \\n\\n- Obtain the key data\\\n \\ of the latest financial report of the target company {{company}} organized by\\\n \\ Yahoo Finance. \\n\\n\\n\\n3. Vertical Analysis:\\n- Get the insight of the company's\\\n \\ balance sheet Income Statement and cash flow. \\n- Analyze Income Statement:\\\n \\ Analyze the proportion of each type of income and expense to total income. /Analyze\\\n \\ Balance Sheet: Analyze the proportion of each asset and liability to total assets\\\n \\ or total liabilities./ Analyze Cash Flow \\n-\\n4. Ratio Analysis:\\n\\\n - analyze the Profitability Ratios Solvency Ratios Operational Efficiency Ratios\\\n \\ and Market Performance Ratios of the company. \\n(Profitability Ratios: Such\\\n \\ as net profit margin gross profit margin operating profit margin to assess the\\\n \\ company's profitability.)\\n(Solvency Ratios: Such as debt-to-asset ratio interest\\\n \\ coverage ratio to assess the company's ability to pay its debts.)\\n(Operational\\\n \\ Efficiency Ratios: Such as inventory turnover accounts receivable turnover to\\\n \\ assess the company's operational efficiency.)\\n(Market Performance Ratios: Such\\\n \\ as price-to-earnings ratio price-to-book ratio to assess the company's market\\\n \\ performance.)>\\n-\\n5. Comprehensive Analysis and Conclusion:\\n- Combine the above analyses to\\\n \\ evaluate the company's financial health profitability solvency and operational\\\n \\ efficiency comprehensively. Identify the main financial risks and potential\\\n \\ opportunities facing the company.\\n-\\nOrganize and output [Record 1.1] [Record 1.2] [Record\\\n \\ 1.3] [Record 1.4] [Record 1.5] \\nPart II: Foundamental Analysis: Industry\\n\\\n *Objective 2: To analyze the position and competitiveness of the target company\\\n \\ {{company}} in the industry. \\n\\n\\n* Steps:\\n1. Determine the industry classification:\\n\\\n - Define the industry to which the target company belongs.\\n- Search for company\\\n \\ information to determine its main business and industry.\\n-\\n2. Market Positioning and Segmentation\\\n \\ analysis:\\n- To assess the company's market positioning and segmentation. \\n\\\n - Understand the company's market share growth rate and competitors in the industry\\\n \\ to analyze them. \\n-\\n3. Analysis \\n- Analyze the development\\\n \\ trend of the industry. \\n- \\n4. Competitors\\n- Analyze the competition around the target company \\n-\\\n \\ \\nOrganize\\\n \\ and output [Record 2.1] [Record 2.2] [Record 2.3] [Record 2.4]\\nCombine the\\\n \\ above Record and output all the analysis in the form of a investment analysis\\\n \\ report. Use markdown syntax for a structured output. \\n\\n## Constraints\\n- Your\\\n \\ responses should be strictly on analysis tasks. Use a structured language and\\\n \\ think step by step. \\n- The language you use should be identical to the user's\\\n \\ language.\\n- Avoid addressing questions regarding work tools and regulations.\\n\\\n - Give a structured response using bullet points and markdown syntax. Give an\\\n \\ introduction to the situation first then analyse the main trend in the graph.\\\n \\ \\n\"\n prompt_type: simple\n retriever_resource:\n enabled: true\n sensitive_word_avoidance:\n configs: []\n enabled: false\n type: ''\n speech_to_text:\n enabled: false\n suggested_questions:\n - 'Analyze the stock of Tesla. '\n - What are some recent development on Nvidia?\n - 'Do a fundamental analysis for Amazon. '\n suggested_questions_after_answer:\n enabled: true\n text_to_speech:\n enabled: false\n user_input_form:\n - text-input:\n default: ''\n label: company\n required: false\n variable: company\n", + "export_data": "app:\n icon: \"\\U0001F911\"\n icon_background: '#E4FBCC'\n mode: agent-chat\n name: Investment Analysis Report Copilot\nmodel_config:\n agent_mode:\n enabled: true\n max_iteration: 5\n strategy: function_call\n tools:\n - enabled: true\n isDeleted: false\n notAuthor: false\n provider_id: yahoo\n provider_name: yahoo\n provider_type: builtin\n tool_label: Analytics\n tool_name: yahoo_finance_analytics\n tool_parameters:\n end_date: ''\n start_date: ''\n symbol: ''\n - enabled: true\n isDeleted: false\n notAuthor: false\n provider_id: yahoo\n provider_name: yahoo\n provider_type: builtin\n tool_label: News\n tool_name: yahoo_finance_news\n tool_parameters:\n symbol: ''\n - enabled: true\n isDeleted: false\n notAuthor: false\n provider_id: yahoo\n provider_name: yahoo\n provider_type: builtin\n tool_label: Ticker\n tool_name: yahoo_finance_ticker\n tool_parameters:\n symbol: ''\n annotation_reply:\n enabled: false\n chat_prompt_config: {}\n completion_prompt_config: {}\n dataset_configs:\n datasets:\n datasets: []\n retrieval_model: single\n dataset_query_variable: ''\n external_data_tools: []\n file_upload:\n image:\n detail: high\n enabled: false\n number_limits: 3\n transfer_methods:\n - remote_url\n - local_file\n model:\n completion_params:\n frequency_penalty: 0.5\n max_tokens: 4096\n presence_penalty: 0.5\n stop: []\n temperature: 0.2\n top_p: 0.75\n mode: chat\n name: gpt-4-1106-preview\n provider: openai\n more_like_this:\n enabled: false\n opening_statement: 'Welcome to your personalized Investment Analysis Copilot service,\n where we delve into the depths of stock analysis to provide you with comprehensive\n insights. To begin our journey into the financial world, try to ask:\n\n '\n pre_prompt: \"# Job Description: Data Analysis Copilot\\n## Character\\nMy primary\\\n \\ goal is to provide user with expert data analysis advice. Using extensive and\\\n \\ detailed data. Tell me the stock (with ticket symbol) you want to analyze. I\\\n \\ will do all fundamental, technical, market sentiment, and Marco economical analysis\\\n \\ for the stock as an expert. \\n\\n## Skills \\n### Skill 1: Search for stock information\\\n \\ using 'Ticker' from Yahoo Finance \\n### Skill 2: Search for recent news using\\\n \\ 'News' for the target company. \\n### Skill 3: Search for financial figures and\\\n \\ analytics using 'Analytics' for the target company\\n\\n## Workflow\\nAsks the\\\n \\ user which stocks with ticker name need to be analyzed and then performs the\\\n \\ following analysis in sequence. \\n**Part I: Fundamental analysis: financial\\\n \\ reporting analysis\\n*Objective 1: In-depth analysis of the financial situation\\\n \\ of the target company.\\n*Steps:\\n1. Identify the object of analysis:\\n\\n\\n\\n2. Access to financial\\\n \\ reports \\n\\n- Obtain the key data\\\n \\ of the latest financial report of the target company {{company}} organized by\\\n \\ Yahoo Finance. \\n\\n\\n\\n3. Vertical Analysis:\\n- Get the insight of the company's\\\n \\ balance sheet Income Statement and cash flow. \\n- Analyze Income Statement:\\\n \\ Analyze the proportion of each type of income and expense to total income. /Analyze\\\n \\ Balance Sheet: Analyze the proportion of each asset and liability to total assets\\\n \\ or total liabilities./ Analyze Cash Flow \\n-\\n4. Ratio Analysis:\\n\\\n - analyze the Profitability Ratios Solvency Ratios Operational Efficiency Ratios\\\n \\ and Market Performance Ratios of the company. \\n(Profitability Ratios: Such\\\n \\ as net profit margin gross profit margin operating profit margin to assess the\\\n \\ company's profitability.)\\n(Solvency Ratios: Such as debt-to-asset ratio interest\\\n \\ coverage ratio to assess the company's ability to pay its debts.)\\n(Operational\\\n \\ Efficiency Ratios: Such as inventory turnover accounts receivable turnover to\\\n \\ assess the company's operational efficiency.)\\n(Market Performance Ratios: Such\\\n \\ as price-to-earnings ratio price-to-book ratio to assess the company's market\\\n \\ performance.)>\\n-\\n5. Comprehensive Analysis and Conclusion:\\n- Combine the above analyses to\\\n \\ evaluate the company's financial health profitability solvency and operational\\\n \\ efficiency comprehensively. Identify the main financial risks and potential\\\n \\ opportunities facing the company.\\n-\\nOrganize and output [Record 1.1] [Record 1.2] [Record\\\n \\ 1.3] [Record 1.4] [Record 1.5] \\nPart II: Fundamental Analysis: Industry\\n\\\n *Objective 2: To analyze the position and competitiveness of the target company\\\n \\ {{company}} in the industry. \\n\\n\\n* Steps:\\n1. Determine the industry classification:\\n\\\n - Define the industry to which the target company belongs.\\n- Search for company\\\n \\ information to determine its main business and industry.\\n-\\n2. Market Positioning and Segmentation\\\n \\ analysis:\\n- To assess the company's market positioning and segmentation. \\n\\\n - Understand the company's market share growth rate and competitors in the industry\\\n \\ to analyze them. \\n-\\n3. Analysis \\n- Analyze the development\\\n \\ trend of the industry. \\n- \\n4. Competitors\\n- Analyze the competition around the target company \\n-\\\n \\ \\nOrganize\\\n \\ and output [Record 2.1] [Record 2.2] [Record 2.3] [Record 2.4]\\nCombine the\\\n \\ above Record and output all the analysis in the form of a investment analysis\\\n \\ report. Use markdown syntax for a structured output. \\n\\n## Constraints\\n- Your\\\n \\ responses should be strictly on analysis tasks. Use a structured language and\\\n \\ think step by step. \\n- The language you use should be identical to the user's\\\n \\ language.\\n- Avoid addressing questions regarding work tools and regulations.\\n\\\n - Give a structured response using bullet points and markdown syntax. Give an\\\n \\ introduction to the situation first then analyse the main trend in the graph.\\\n \\ \\n\"\n prompt_type: simple\n retriever_resource:\n enabled: true\n sensitive_word_avoidance:\n configs: []\n enabled: false\n type: ''\n speech_to_text:\n enabled: false\n suggested_questions:\n - 'Analyze the stock of Tesla. '\n - What are some recent development on Nvidia?\n - 'Do a fundamental analysis for Amazon. '\n suggested_questions_after_answer:\n enabled: true\n text_to_speech:\n enabled: false\n user_input_form:\n - text-input:\n default: ''\n label: company\n required: false\n variable: company\n", "icon": "🤑", "icon_background": "#E4FBCC", "id": "a23b57fa-85da-49c0-a571-3aff375976c1", @@ -438,8 +438,8 @@ "mode": "advanced-chat", "name": "Workflow Planning Assistant " }, - "e9d92058-7d20-4904-892f-75d90bef7587":{"export_data":"app:\n icon: \"\\U0001F916\"\n icon_background: '#FFEAD5'\n mode: advanced-chat\n name: 'Automated Email Reply '\nworkflow:\n features:\n file_upload:\n image:\n enabled: false\n opening_statement: ''\n retriever_resource:\n enabled: false\n sensitive_word_avoidance:\n enabled: false\n speech_to_text:\n enabled: false\n suggested_questions: []\n suggested_questions_after_answer:\n enabled: false\n text_to_speech:\n enabled: false\n language: ''\n voice: ''\n graph:\n edges:\n - data:\n isInIteration: false\n sourceType: code\n targetType: iteration\n id: 1716909112104-source-1716909114582-target\n source: '1716909112104'\n sourceHandle: source\n target: '1716909114582'\n targetHandle: target\n type: custom\n zIndex: 0\n - data:\n isInIteration: false\n sourceType: iteration\n targetType: template-transform\n id: 1716909114582-source-1716913435742-target\n source: '1716909114582'\n sourceHandle: source\n target: '1716913435742'\n targetHandle: target\n type: custom\n zIndex: 0\n - data:\n isInIteration: false\n sourceType: template-transform\n targetType: answer\n id: 1716913435742-source-1716806267180-target\n source: '1716913435742'\n sourceHandle: source\n target: '1716806267180'\n targetHandle: target\n type: custom\n zIndex: 0\n - data:\n isInIteration: false\n sourceType: start\n targetType: tool\n id: 1716800588219-source-1716946869294-target\n source: '1716800588219'\n sourceHandle: source\n target: '1716946869294'\n targetHandle: target\n type: custom\n zIndex: 0\n - data:\n isInIteration: false\n sourceType: tool\n targetType: code\n id: 1716946869294-source-1716909112104-target\n source: '1716946869294'\n sourceHandle: source\n target: '1716909112104'\n targetHandle: target\n type: custom\n zIndex: 0\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: tool\n targetType: code\n id: 1716946889408-source-1716909122343-target\n source: '1716946889408'\n sourceHandle: source\n target: '1716909122343'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: code\n targetType: code\n id: 1716909122343-source-1716951357236-target\n source: '1716909122343'\n sourceHandle: source\n target: '1716951357236'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: code\n targetType: llm\n id: 1716951357236-source-1716913272656-target\n source: '1716951357236'\n sourceHandle: source\n target: '1716913272656'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: template-transform\n targetType: llm\n id: 1716951236700-source-1716951159073-target\n source: '1716951236700'\n sourceHandle: source\n target: '1716951159073'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: llm\n targetType: template-transform\n id: 1716951159073-source-1716952228079-target\n source: '1716951159073'\n sourceHandle: source\n target: '1716952228079'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: template-transform\n targetType: tool\n id: 1716952228079-source-1716952912103-target\n source: '1716952228079'\n sourceHandle: source\n target: '1716952912103'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: llm\n targetType: question-classifier\n id: 1716913272656-source-1716960721611-target\n source: '1716913272656'\n sourceHandle: source\n target: '1716960721611'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: question-classifier\n targetType: llm\n id: 1716960721611-1-1716909125498-target\n source: '1716960721611'\n sourceHandle: '1'\n target: '1716909125498'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: question-classifier\n targetType: llm\n id: 1716960721611-2-1716960728136-target\n source: '1716960721611'\n sourceHandle: '2'\n target: '1716960728136'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: llm\n targetType: variable-aggregator\n id: 1716909125498-source-1716960791399-target\n source: '1716909125498'\n sourceHandle: source\n target: '1716960791399'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: variable-aggregator\n targetType: template-transform\n id: 1716960791399-source-1716951236700-target\n source: '1716960791399'\n sourceHandle: source\n target: '1716951236700'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: question-classifier\n targetType: template-transform\n id: 1716960721611-1716960736883-1716960834468-target\n source: '1716960721611'\n sourceHandle: '1716960736883'\n target: '1716960834468'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: llm\n targetType: variable-aggregator\n id: 1716960728136-source-1716960791399-target\n source: '1716960728136'\n sourceHandle: source\n target: '1716960791399'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: template-transform\n targetType: variable-aggregator\n id: 1716960834468-source-1716960791399-target\n source: '1716960834468'\n sourceHandle: source\n target: '1716960791399'\n targetHandle: target\n type: custom\n zIndex: 1002\n nodes:\n - data:\n desc: ''\n selected: false\n title: Start\n type: start\n variables:\n - label: Your Email\n max_length: 256\n options: []\n required: true\n type: text-input\n variable: email\n - label: Maximum Number of Email you want to retrieve\n max_length: 256\n options: []\n required: true\n type: number\n variable: maxResults\n height: 115\n id: '1716800588219'\n position:\n x: 30\n y: 445\n positionAbsolute:\n x: 30\n y: 445\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n - data:\n answer: '{{#1716913435742.output#}}'\n desc: ''\n selected: false\n title: Direct Reply\n type: answer\n variables: []\n height: 106\n id: '1716806267180'\n position:\n x: 4700\n y: 445\n positionAbsolute:\n x: 4700\n y: 445\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n - data:\n code: \"def main(message: str) -> dict:\\n import json\\n \\n # Parse\\\n \\ the JSON string\\n parsed_data = json.loads(message)\\n \\n # Extract\\\n \\ all the \\\"id\\\" values\\n ids = [msg['id'] for msg in parsed_data['messages']]\\n\\\n \\ \\n return {\\n \\\"result\\\": ids\\n }\"\n code_language: python3\n desc: ''\n outputs:\n result:\n children: null\n type: array[string]\n selected: false\n title: 'Code: Extract Email ID'\n type: code\n variables:\n - value_selector:\n - '1716946869294'\n - text\n variable: message\n height: 53\n id: '1716909112104'\n position:\n x: 638\n y: 445\n positionAbsolute:\n x: 638\n y: 445\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n - data:\n desc: ''\n height: 490\n iterator_selector:\n - '1716909112104'\n - result\n output_selector:\n - '1716909125498'\n - text\n output_type: array[string]\n selected: false\n startNodeType: tool\n start_node_id: '1716946889408'\n title: 'Iteraction '\n type: iteration\n width: 3393.7520359289056\n height: 490\n id: '1716909114582'\n position:\n x: 942\n y: 445\n positionAbsolute:\n x: 942\n y: 445\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 3394\n zIndex: 1\n - data:\n desc: ''\n isInIteration: true\n isIterationStart: true\n iteration_id: '1716909114582'\n provider_id: e64b4c7f-2795-499c-8d11-a971a7d57fc9\n provider_name: List and Get Gmail\n provider_type: api\n selected: false\n title: getMessage\n tool_configurations: {}\n tool_label: getMessage\n tool_name: getMessage\n tool_parameters:\n format:\n type: mixed\n value: full\n id:\n type: mixed\n value: '{{#1716909114582.item#}}'\n userId:\n type: mixed\n value: '{{#1716800588219.email#}}'\n type: tool\n extent: parent\n height: 53\n id: '1716946889408'\n parentId: '1716909114582'\n position:\n x: 117\n y: 85\n positionAbsolute:\n x: 1059\n y: 530\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1001\n - data:\n code: \"\\ndef main(email_json: dict) -> dict:\\n import json \\n email_dict\\\n \\ = json.loads(email_json)\\n base64_data = email_dict['payload']['parts'][0]['body']['data']\\n\\\n \\n return {\\n \\\"result\\\": base64_data, \\n }\\n\"\n code_language: python3\n desc: ''\n isInIteration: true\n iteration_id: '1716909114582'\n outputs:\n result:\n children: null\n type: string\n selected: false\n title: 'Code: Extract Email Body'\n type: code\n variables:\n - value_selector:\n - '1716946889408'\n - text\n variable: email_json\n extent: parent\n height: 53\n id: '1716909122343'\n parentId: '1716909114582'\n position:\n x: 421\n y: 85\n positionAbsolute:\n x: 1363\n y: 530\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: 'Generate reply. '\n isInIteration: true\n iteration_id: '1716909114582'\n model:\n completion_params:\n temperature: 0.7\n mode: chat\n name: gpt-4o\n provider: openai\n prompt_template:\n - id: 982014aa-702b-4d7c-ae1f-08dbceb6e930\n role: system\n text: \" \\nRespond to the emails. \\n\\n{{#1716913272656.text#}}\\n\\\n \"\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n configs:\n detail: high\n enabled: true\n extent: parent\n height: 127\n id: '1716909125498'\n parentId: '1716909114582'\n position:\n x: 1625\n y: 85\n positionAbsolute:\n x: 2567\n y: 530\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: ''\n isInIteration: true\n iteration_id: '1716909114582'\n model:\n completion_params:\n temperature: 0.7\n mode: chat\n name: gpt-4o\n provider: openai\n prompt_template:\n - id: fd8de569-c099-4320-955b-61aa4b054789\n role: system\n text: \"\\nYou need to transform the input data (in base64 encoding)\\\n \\ to text. Input base64. Output text. \\n\\n{{#1716909122343.result#}}\\n\\\n \"\n selected: false\n title: 'Base64 Decoder '\n type: llm\n variables: []\n vision:\n configs:\n detail: high\n enabled: false\n extent: parent\n height: 97\n id: '1716913272656'\n parentId: '1716909114582'\n position:\n x: 1025\n y: 85\n positionAbsolute:\n x: 1967\n y: 530\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n desc: ''\n selected: false\n template: '{{ arg1 | join(\"\\n\\n -------------------------\\n\\n\") }}'\n title: 'Template '\n type: template-transform\n variables:\n - value_selector:\n - '1716909114582'\n - output\n variable: arg1\n height: 53\n id: '1716913435742'\n position:\n x: 4396\n y: 445\n positionAbsolute:\n x: 4396\n y: 445\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n - data:\n desc: ''\n provider_id: e64b4c7f-2795-499c-8d11-a971a7d57fc9\n provider_name: List and Get Gmail\n provider_type: api\n selected: false\n title: listMessages\n tool_configurations: {}\n tool_label: listMessages\n tool_name: listMessages\n tool_parameters:\n maxResults:\n type: variable\n value:\n - '1716800588219'\n - maxResults\n userId:\n type: mixed\n value: '{{#1716800588219.email#}}'\n type: tool\n height: 53\n id: '1716946869294'\n position:\n x: 334\n y: 445\n positionAbsolute:\n x: 334\n y: 445\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: ''\n isInIteration: true\n iteration_id: '1716909114582'\n model:\n completion_params:\n temperature: 0.7\n mode: chat\n name: gpt-4o\n provider: openai\n prompt_template:\n - id: b7fd0ec5-864a-42c6-9d04-a1958bd4fc0d\n role: system\n text: \"\\nYou need to encode the input data from text to base64. Input\\\n \\ text. Output base64 encoding. Output nothing other than base64 encoding.\\\n \\ \\n\\n{{#1716951236700.output#}}\\n \"\n selected: false\n title: Base64 Encoder\n type: llm\n variables: []\n vision:\n configs:\n detail: high\n enabled: true\n extent: parent\n height: 97\n id: '1716951159073'\n parentId: '1716909114582'\n position:\n x: 2525.7520359289056\n y: 85\n positionAbsolute:\n x: 3467.7520359289056\n y: 530\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n desc: Generaate MIME email template\n isInIteration: true\n iteration_id: '1716909114582'\n selected: false\n template: \"Content-Type: text/plain; charset=\\\"utf-8\\\"\\r\\nContent-Transfer-Encoding:\\\n \\ 7bit\\r\\nMIME-Version: 1.0\\r\\nTo: {{ emailMetadata.recipientEmail }} #\\\n \\ xiaoyi@dify.ai\\r\\nFrom: {{ emailMetadata.senderEmail }} # sxy.hj156@gmail.com\\r\\\n \\nSubject: Re: {{ emailMetadata.subject }} \\r\\n\\r\\n{{ text }}\\r\\n\"\n title: 'Template: Reply Email'\n type: template-transform\n variables:\n - value_selector:\n - '1716951357236'\n - result\n variable: emailMetadata\n - value_selector:\n - '1716960791399'\n - output\n variable: text\n extent: parent\n height: 83\n id: '1716951236700'\n parentId: '1716909114582'\n position:\n x: 2231.269960149744\n y: 85\n positionAbsolute:\n x: 3173.269960149744\n y: 530\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n code: \"def main(email_json: dict) -> dict:\\n import json\\n if isinstance(email_json,\\\n \\ str): \\n email_json = json.loads(email_json)\\n\\n subject = None\\n\\\n \\ recipient_email = None \\n sender_email = None\\n \\n headers\\\n \\ = email_json['payload']['headers']\\n for header in headers:\\n \\\n \\ if header['name'] == 'Subject':\\n subject = header['value']\\n\\\n \\ elif header['name'] == 'To':\\n recipient_email = header['value']\\n\\\n \\ elif header['name'] == 'From':\\n sender_email = header['value']\\n\\\n \\n return {\\n \\\"result\\\": [subject, recipient_email, sender_email]\\n\\\n \\ }\\n\"\n code_language: python3\n desc: \"Recipient, Sender, Subject\\uFF0COutput Array[String]\"\n isInIteration: true\n iteration_id: '1716909114582'\n outputs:\n result:\n children: null\n type: array[string]\n selected: false\n title: Extract Email Metadata\n type: code\n variables:\n - value_selector:\n - '1716946889408'\n - text\n variable: email_json\n extent: parent\n height: 101\n id: '1716951357236'\n parentId: '1716909114582'\n position:\n x: 725\n y: 85\n positionAbsolute:\n x: 1667\n y: 530\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n desc: ''\n isInIteration: true\n iteration_id: '1716909114582'\n selected: false\n template: '{\"raw\": \"{{ encoded_message }}\"}'\n title: \"Template\\uFF1AEmail Request Body\"\n type: template-transform\n variables:\n - value_selector:\n - '1716951159073'\n - text\n variable: encoded_message\n extent: parent\n height: 53\n id: '1716952228079'\n parentId: '1716909114582'\n position:\n x: 2828.4325280181324\n y: 86.31950791077293\n positionAbsolute:\n x: 3770.4325280181324\n y: 531.3195079107729\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n desc: ''\n isInIteration: true\n iteration_id: '1716909114582'\n provider_id: 038963aa-43c8-47fc-be4b-0255c19959c1\n provider_name: Draft Gmail\n provider_type: api\n selected: false\n title: createDraft\n tool_configurations: {}\n tool_label: createDraft\n tool_name: createDraft\n tool_parameters:\n message:\n type: mixed\n value: '{{#1716952228079.output#}}'\n userId:\n type: mixed\n value: '{{#1716800588219.email#}}'\n type: tool\n extent: parent\n height: 53\n id: '1716952912103'\n parentId: '1716909114582'\n position:\n x: 3133.7520359289056\n y: 85\n positionAbsolute:\n x: 4075.7520359289056\n y: 530\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n classes:\n - id: '1'\n name: 'Technical questions, related to product '\n - id: '2'\n name: Unrelated to technicals, non technical\n - id: '1716960736883'\n name: Other questions\n desc: ''\n instructions: ''\n isInIteration: true\n iteration_id: '1716909114582'\n model:\n completion_params:\n temperature: 0.7\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n query_variable_selector:\n - '1716800588219'\n - sys.query\n selected: false\n title: Question Classifier\n topics: []\n type: question-classifier\n extent: parent\n height: 255\n id: '1716960721611'\n parentId: '1716909114582'\n position:\n x: 1325\n y: 85\n positionAbsolute:\n x: 2267\n y: 530\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: ''\n isInIteration: true\n iteration_id: '1716909114582'\n model:\n completion_params:\n temperature: 0.7\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - id: a639bbf8-bc58-42a2-b477-6748e80ecda2\n role: system\n text: \" \\nRespond to the emails. \\n\\n{{#1716913272656.text#}}\\n\\\n \"\n selected: false\n title: 'LLM - Non technical '\n type: llm\n variables: []\n vision:\n enabled: false\n extent: parent\n height: 97\n id: '1716960728136'\n parentId: '1716909114582'\n position:\n x: 1625\n y: 251\n positionAbsolute:\n x: 2567\n y: 696\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n desc: ''\n isInIteration: true\n iteration_id: '1716909114582'\n output_type: string\n selected: false\n title: Variable Aggregator\n type: variable-aggregator\n variables:\n - - '1716909125498'\n - text\n - - '1716960728136'\n - text\n - - '1716960834468'\n - output\n extent: parent\n height: 164\n id: '1716960791399'\n parentId: '1716909114582'\n position:\n x: 1931.2699601497438\n y: 85\n positionAbsolute:\n x: 2873.269960149744\n y: 530\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n desc: Other questions\n isInIteration: true\n iteration_id: '1716909114582'\n selected: false\n template: 'Sorry, I cannot answer that. This is outside my capabilities. '\n title: 'Direct Reply '\n type: template-transform\n variables: []\n extent: parent\n height: 83\n id: '1716960834468'\n parentId: '1716909114582'\n position:\n x: 1625\n y: 385.57142857142856\n positionAbsolute:\n x: 2567\n y: 830.5714285714286\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n author: Dify\n desc: ''\n height: 153\n selected: false\n showAuthor: true\n text: '{\"root\":{\"children\":[{\"children\":[{\"detail\":0,\"format\":3,\"mode\":\"normal\",\"style\":\"font-size:\n 14px;\",\"text\":\"OpenAPI-Swagger for all custom tools: \",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":3},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"openapi:\n 3.0.0\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"info:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" title:\n Gmail API\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n OpenAPI schema for Gmail API methods `users.messages.get`, `users.messages.list`,\n and `users.drafts.create`.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" version:\n 1.0.0\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"servers:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n url: https://gmail.googleapis.com\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Gmail API Server\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"paths:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" /gmail/v1/users/{userId}/messages/{id}:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" get:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" summary:\n Get a message.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Retrieves a specific message by ID.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" operationId:\n getMessage\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" parameters:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n name: userId\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" in:\n path\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" required:\n true\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" schema:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n The user''s email address. The special value `me` can be used to indicate\n the authenticated user.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n name: id\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" in:\n path\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" required:\n true\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" schema:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n The ID of the message to retrieve.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n name: format\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" in:\n query\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" required:\n false\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" schema:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" enum:\n [full, metadata, minimal, raw]\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" default:\n full\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n The format to return the message in.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" responses:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''200'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Successful response\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" content:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" application/json:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" schema:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n object\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" properties:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" id:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" threadId:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" labelIds:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n array\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" items:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" snippet:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" historyId:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" internalDate:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" payload:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n object\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" sizeEstimate:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n integer\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" raw:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''401'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Unauthorized\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''403'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Forbidden\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''404'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Not Found\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" /gmail/v1/users/{userId}/messages:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" get:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" summary:\n List messages.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Lists the messages in the user''s mailbox.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" operationId:\n listMessages\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" parameters:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n name: userId\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" in:\n path\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" required:\n true\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" schema:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n The user''s email address. The special value `me` can be used to indicate\n the authenticated user.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n name: maxResults\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" in:\n query\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" schema:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n integer\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" format:\n int32\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" default:\n 100\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Maximum number of messages to return.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" responses:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''200'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Successful response\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" content:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" application/json:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" schema:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n object\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" properties:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" messages:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n array\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" items:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n object\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" properties:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" id:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" threadId:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" nextPageToken:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" resultSizeEstimate:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n integer\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''401'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Unauthorized\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" /gmail/v1/users/{userId}/drafts:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" post:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" summary:\n Creates a new draft.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" operationId:\n createDraft\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" tags:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n Drafts\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" parameters:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n name: userId\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" in:\n path\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" required:\n true\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n The user''s email address. The special value \\\"me\\\" can be used to indicate\n the authenticated user.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" schema:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" requestBody:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" required:\n true\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" content:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" application/json:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" schema:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n object\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" properties:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" message:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n object\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" properties:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" raw:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n The entire email message in an RFC 2822 formatted and base64url encoded\n string.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" responses:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''200'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Successful response with the created draft.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" content:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" application/json:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" schema:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n object\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" properties:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" id:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n The immutable ID of the draft.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" message:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n object\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" properties:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" id:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n The immutable ID of the message.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" threadId:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n The ID of the thread the message belongs to.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" labelIds:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n array\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" items:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" snippet:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n A short part of the message text.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" historyId:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n The ID of the last history record that modified this message.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''400'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Bad Request - The request is invalid.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''401'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Unauthorized - Authentication is required.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''403'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Forbidden - The user does not have permission to create drafts.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''404'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Not Found - The specified user does not exist.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''500'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Internal Server Error - An error occurred on the server.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"components:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" securitySchemes:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" OAuth2:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n oauth2\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" flows:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" authorizationCode:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" authorizationUrl:\n https://accounts.google.com/o/oauth2/auth\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" tokenUrl:\n https://oauth2.googleapis.com/token\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" scopes:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" https://mail.google.com/:\n All access to Gmail.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" https://www.googleapis.com/auth/gmail.compose:\n Send email on your behalf.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" https://www.googleapis.com/auth/gmail.modify:\n Modify your email.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"security:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n OAuth2:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n https://mail.google.com/\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n https://www.googleapis.com/auth/gmail.compose\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n https://www.googleapis.com/auth/gmail.modify\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"root\",\"version\":1}}'\n theme: yellow\n title: ''\n type: ''\n width: 367\n height: 153\n id: '1718992681576'\n position:\n x: 321.9646831030669\n y: 538.1642616264143\n positionAbsolute:\n x: 321.9646831030669\n y: 538.1642616264143\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom-note\n width: 367\n - data:\n author: Dify\n desc: ''\n height: 158\n selected: false\n showAuthor: true\n text: '{\"root\":{\"children\":[{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Replace\n custom tools after added this template to your own workspace. \",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Fill\n in \",\"type\":\"text\",\"version\":1},{\"detail\":0,\"format\":1,\"mode\":\"normal\",\"style\":\"\",\"text\":\"your\n email \",\"type\":\"text\",\"version\":1},{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"and\n the \",\"type\":\"text\",\"version\":1},{\"detail\":0,\"format\":1,\"mode\":\"normal\",\"style\":\"\",\"text\":\"maximum\n number of results you want to retrieve from your inbox \",\"type\":\"text\",\"version\":1},{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"to\n get started. \",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"root\",\"version\":1}}'\n theme: blue\n title: ''\n type: ''\n width: 287\n height: 158\n id: '1718992805687'\n position:\n x: 18.571428571428356\n y: 237.80887395992687\n positionAbsolute:\n x: 18.571428571428356\n y: 237.80887395992687\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom-note\n width: 287\n - data:\n author: Dify\n desc: ''\n height: 375\n selected: true\n showAuthor: true\n text: '{\"root\":{\"children\":[{\"children\":[{\"detail\":0,\"format\":1,\"mode\":\"normal\",\"style\":\"font-size:\n 16px;\",\"text\":\"Steps within Iteraction node: \",\"type\":\"text\",\"version\":1},{\"type\":\"linebreak\",\"version\":1},{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"1.\n getMessage: This step retrieves the incoming email message.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":1},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"2.\n Code: Extract Email Body: Custom code is executed to extract the body of\n the email from the retrieved message.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"3.\n Extract Email Metadata: Extracts metadata from the email, such as the recipient,\n sender, subject, and other relevant information.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"4.\n Base64 Decoder: Decodes the email content from Base64 encoding.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"5.\n Question Classifier (gpt-3.5-turbo): Uses a GPT-3.5-turbo model to classify\n the email content into different categories. For each classified question,\n the workflow uses a GPT-4.0 model to generate an appropriate reply:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"6.\n Template: Reply Email: Uses a template to generate a MIME email format for\n the reply.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"6.\n Base64 Encoder: Encodes the generated reply email content back to Base64.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"7.\n Template: Email Request: Prepares the email request using a template.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"8.\n createDraft: Creates a draft of the email reply.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"This\n workflow automates the process of reading, classifying, responding to, and\n drafting replies to incoming emails, leveraging advanced language models\n to generate contextually appropriate responses.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"root\",\"version\":1}}'\n theme: blue\n title: ''\n type: ''\n width: 640\n height: 375\n id: '1718993366836'\n position:\n x: 966.7525290975368\n y: 971.80362905854\n positionAbsolute:\n x: 966.7525290975368\n y: 971.80362905854\n selected: true\n sourcePosition: right\n targetPosition: left\n type: custom-note\n width: 640\n - data:\n author: Dify\n desc: ''\n height: 400\n selected: false\n showAuthor: true\n text: '{\"root\":{\"children\":[{\"children\":[{\"detail\":0,\"format\":3,\"mode\":\"normal\",\"style\":\"font-size:\n 16px;\",\"text\":\"Preparation\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":3},{\"children\":[{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Enable\n Gmail API in Google Cloud Console\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"listitem\",\"version\":1,\"value\":1},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Configure\n OAuth Client ID, OAuth Client Secrets, and OAuth Consent Screen for the\n Web Application in Google Cloud Console\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"listitem\",\"version\":1,\"value\":2},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Use\n Postman to authorize and obtain the OAuth Access Token (Google''s Access\n Token will expire after 1 hour and cannot be used for a long time)\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"listitem\",\"version\":1,\"value\":3}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"list\",\"version\":1,\"listType\":\"bullet\",\"start\":1,\"tag\":\"ul\"},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Users\n who want to try building an AI auto-reply email can refer to this document\n to use Postman (Postman.com) to obtain all the above keys: https://blog.postman.com/how-to-access-google-apis-using-oauth-in-postman/.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Developers\n who want to use Google OAuth to call the Gmail API to develop corresponding\n plugins can refer to this official document: \",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"https://developers.google.com/identity/protocols/oauth2/web-server.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"At\n this stage, it is still a bit difficult to reproduce this example within\n the Dify platform. If you have development capabilities, developing the\n corresponding plugin externally and using an external database to automatically\n read and write the user''s Access Token and write the Refresh Token would\n be a better choice.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"root\",\"version\":1}}'\n theme: blue\n title: ''\n type: ''\n width: 608\n height: 400\n id: '1718993557447'\n position:\n x: 354.0157230378119\n y: -1.2732157979666\n positionAbsolute:\n x: 354.0157230378119\n y: -1.2732157979666\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom-note\n width: 608\n viewport:\n x: 147.09446825757777\n y: 101.03530130020579\n zoom: 0.9548416039104178\n","icon":"\ud83e\udd16","icon_background":"#FFEAD5","id":"e9d92058-7d20-4904-892f-75d90bef7587","mode":"advanced-chat","name":"Automated Email Reply "}, - "98b87f88-bd22-4d86-8b74-86beba5e0ed4":{"export_data":"app:\n icon: \"\\U0001F916\"\n icon_background: '#FFEAD5'\n mode: workflow\n name: 'Book Translation '\nworkflow:\n features:\n file_upload:\n image:\n enabled: false\n number_limits: 3\n transfer_methods:\n - local_file\n - remote_url\n opening_statement: ''\n retriever_resource:\n enabled: false\n sensitive_word_avoidance:\n enabled: false\n speech_to_text:\n enabled: false\n suggested_questions: []\n suggested_questions_after_answer:\n enabled: false\n text_to_speech:\n enabled: false\n language: ''\n voice: ''\n graph:\n edges:\n - data:\n isInIteration: false\n sourceType: start\n targetType: code\n id: 1711067409646-source-1717916867969-target\n source: '1711067409646'\n sourceHandle: source\n target: '1717916867969'\n targetHandle: target\n type: custom\n zIndex: 0\n - data:\n isInIteration: false\n sourceType: code\n targetType: iteration\n id: 1717916867969-source-1717916955547-target\n source: '1717916867969'\n sourceHandle: source\n target: '1717916955547'\n targetHandle: target\n type: custom\n zIndex: 0\n - data:\n isInIteration: true\n iteration_id: '1717916955547'\n sourceType: llm\n targetType: llm\n id: 1717916961837-source-1717916977413-target\n source: '1717916961837'\n sourceHandle: source\n target: '1717916977413'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1717916955547'\n sourceType: llm\n targetType: llm\n id: 1717916977413-source-1717916984996-target\n source: '1717916977413'\n sourceHandle: source\n target: '1717916984996'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1717916955547'\n sourceType: llm\n targetType: llm\n id: 1717916984996-source-1717916991709-target\n source: '1717916984996'\n sourceHandle: source\n target: '1717916991709'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: false\n sourceType: iteration\n targetType: template-transform\n id: 1717916955547-source-1717917057450-target\n source: '1717916955547'\n sourceHandle: source\n target: '1717917057450'\n targetHandle: target\n type: custom\n zIndex: 0\n - data:\n isInIteration: false\n sourceType: template-transform\n targetType: end\n id: 1717917057450-source-1711068257370-target\n source: '1717917057450'\n sourceHandle: source\n target: '1711068257370'\n targetHandle: target\n type: custom\n zIndex: 0\n nodes:\n - data:\n desc: ''\n selected: false\n title: Start\n type: start\n variables:\n - label: Input Text\n max_length: null\n options: []\n required: true\n type: paragraph\n variable: input_text\n dragging: false\n height: 89\n id: '1711067409646'\n position:\n x: 30\n y: 301.5\n positionAbsolute:\n x: 30\n y: 301.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n - data:\n desc: ''\n outputs:\n - value_selector:\n - '1717917057450'\n - output\n variable: final\n selected: false\n title: End\n type: end\n height: 89\n id: '1711068257370'\n position:\n x: 2291\n y: 301.5\n positionAbsolute:\n x: 2291\n y: 301.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n - data:\n code: \"\\ndef main(input_text: str) -> str:\\n token_limit = 1000\\n overlap\\\n \\ = 100\\n chunk_size = int(token_limit * 6 * (4/3))\\n\\n # Initialize\\\n \\ variables\\n chunks = []\\n start_index = 0\\n text_length = len(input_text)\\n\\\n \\n # Loop until the end of the text is reached\\n while start_index\\\n \\ < text_length:\\n # If we are not at the beginning, adjust the start_index\\\n \\ to ensure overlap\\n if start_index > 0:\\n start_index\\\n \\ -= overlap\\n\\n # Calculate end index for the current chunk\\n \\\n \\ end_index = start_index + chunk_size\\n if end_index > text_length:\\n\\\n \\ end_index = text_length\\n\\n # Add the current chunk\\\n \\ to the list\\n chunks.append(input_text[start_index:end_index])\\n\\\n \\n # Update the start_index for the next chunk\\n start_index\\\n \\ += chunk_size\\n\\n return {\\n \\\"chunks\\\": chunks,\\n }\\n\"\n code_language: python3\n dependencies: []\n desc: 'token_limit = 1000\n\n overlap = 100'\n outputs:\n chunks:\n children: null\n type: array[string]\n selected: false\n title: Code\n type: code\n variables:\n - value_selector:\n - '1711067409646'\n - input_text\n variable: input_text\n height: 101\n id: '1717916867969'\n position:\n x: 336\n y: 301.5\n positionAbsolute:\n x: 336\n y: 301.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n - data:\n desc: 'Take good care on maximum number of iterations. '\n height: 203\n iterator_selector:\n - '1717916867969'\n - chunks\n output_selector:\n - '1717916991709'\n - text\n output_type: array[string]\n selected: false\n startNodeType: llm\n start_node_id: '1717916961837'\n title: Iteration\n type: iteration\n width: 1289\n height: 203\n id: '1717916955547'\n position:\n x: 638\n y: 301.5\n positionAbsolute:\n x: 638\n y: 301.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 1289\n zIndex: 1\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: ''\n isInIteration: true\n isIterationStart: true\n iteration_id: '1717916955547'\n model:\n completion_params:\n temperature: 0.7\n mode: chat\n name: gpt-4o\n provider: openai\n prompt_template:\n - id: 7261280b-cb27-4f84-8363-b93e09246d16\n role: system\n text: \" Identify the technical terms in the users input. Use the following\\\n \\ format {XXX} -> {XXX} to show the corresponding technical terms before\\\n \\ and after translation. \\n\\n \\n{{#1717916955547.item#}}\\n\\\n \\n\\n| \\u82F1\\u6587 | \\u4E2D\\u6587 |\\n| --- | --- |\\n| Prompt\\\n \\ Engineering | \\u63D0\\u793A\\u8BCD\\u5DE5\\u7A0B |\\n| Text Generation \\_\\\n | \\u6587\\u672C\\u751F\\u6210 |\\n| Token \\_| Token |\\n| Prompt \\_| \\u63D0\\\n \\u793A\\u8BCD |\\n| Meta Prompting \\_| \\u5143\\u63D0\\u793A |\\n| diffusion\\\n \\ models \\_| \\u6269\\u6563\\u6A21\\u578B |\\n| Agent \\_| \\u667A\\u80FD\\u4F53\\\n \\ |\\n| Transformer \\_| Transformer |\\n| Zero Shot \\_| \\u96F6\\u6837\\u672C\\\n \\ |\\n| Few Shot \\_| \\u5C11\\u6837\\u672C |\\n| chat window \\_| \\u804A\\u5929\\\n \\ |\\n| context | \\u4E0A\\u4E0B\\u6587 |\\n| stock photo \\_| \\u56FE\\u5E93\\u7167\\\n \\u7247 |\\n\\n\\n \"\n selected: false\n title: 'Identify Terms '\n type: llm\n variables: []\n vision:\n configs:\n detail: high\n enabled: true\n extent: parent\n height: 97\n id: '1717916961837'\n parentId: '1717916955547'\n position:\n x: 117\n y: 85\n positionAbsolute:\n x: 755\n y: 386.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1001\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: ''\n isInIteration: true\n iteration_id: '1717916955547'\n model:\n completion_params:\n temperature: 0.7\n mode: chat\n name: gpt-4o\n provider: openai\n prompt_template:\n - id: 05e03f0d-c1a9-43ab-b4c0-44b55049434d\n role: system\n text: \" You are a professional translator proficient in Simplified\\\n \\ Chinese especially skilled in translating professional academic papers\\\n \\ into easy-to-understand popular science articles. Please help me translate\\\n \\ the following english paragraph into Chinese, in a style similar to\\\n \\ Chinese popular science articles .\\n \\nTranslate directly\\\n \\ based on the English content, maintain the original format and do not\\\n \\ omit any information. \\n \\n{{#1717916955547.item#}}\\n\\\n \\n{{#1717916961837.text#}}\\n \"\n selected: false\n title: 1st Translation\n type: llm\n variables: []\n vision:\n configs:\n detail: high\n enabled: true\n extent: parent\n height: 97\n id: '1717916977413'\n parentId: '1717916955547'\n position:\n x: 421\n y: 85\n positionAbsolute:\n x: 1059\n y: 386.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: ''\n isInIteration: true\n iteration_id: '1717916955547'\n model:\n completion_params:\n temperature: 0.7\n mode: chat\n name: gpt-4o\n provider: openai\n prompt_template:\n - id: 9e6cc050-465e-4632-abc9-411acb255a95\n role: system\n text: \"\\nBased on the results of the direct translation, point out\\\n \\ specific issues it have. Accurate descriptions are required, avoiding\\\n \\ vague statements, and there's no need to add content or formats that\\\n \\ were not present in the original text, including but not liimited to:\\\n \\ \\n- inconsistent with chinese expression habits, clearly indicate where\\\n \\ it does not conform\\n- Clumsy sentences, specify the location, no need\\\n \\ to offer suggestions for modification, which will be fixed during free\\\n \\ translation\\n- Obscure and difficult to understand, attempts to explain\\\n \\ may be made\\n- \\u65E0\\u6F0F\\u8BD1\\uFF08\\u539F\\u2F42\\u4E2D\\u7684\\u5173\\\n \\u952E\\u8BCD\\u3001\\u53E5\\u2F26\\u3001\\u6BB5\\u843D\\u90FD\\u5E94\\u4F53\\u73B0\\\n \\u5728\\u8BD1\\u2F42\\u4E2D\\uFF09\\u3002\\n- \\u2F46\\u9519\\u8BD1\\uFF08\\u770B\\\n \\u9519\\u539F\\u2F42\\u3001\\u8BEF\\u89E3\\u539F\\u2F42\\u610F\\u601D\\u5747\\u7B97\\\n \\u9519\\u8BD1\\uFF09\\u3002\\n- \\u2F46\\u6709\\u610F\\u589E\\u52A0\\u6216\\u8005\\\n \\u5220\\u51CF\\u7684\\u539F\\u2F42\\u5185\\u5BB9\\uFF08\\u7FFB\\u8BD1\\u5E76\\u2FAE\\\n \\u521B\\u4F5C\\uFF0C\\u9700\\u5C0A\\u91CD\\u4F5C\\u8005\\u89C2 \\u70B9\\uFF1B\\u53EF\\\n \\u4EE5\\u9002\\u5F53\\u52A0\\u8BD1\\u8005\\u6CE8\\u8BF4\\u660E\\uFF09\\u3002\\n-\\\n \\ \\u8BD1\\u2F42\\u6D41\\u7545\\uFF0C\\u7B26\\u5408\\u4E2D\\u2F42\\u8868\\u8FBE\\u4E60\\\n \\u60EF\\u3002\\n- \\u5173\\u4E8E\\u2F08\\u540D\\u7684\\u7FFB\\u8BD1\\u3002\\u6280\\\n \\u672F\\u56FE\\u4E66\\u4E2D\\u7684\\u2F08\\u540D\\u901A\\u5E38\\u4E0D\\u7FFB\\u8BD1\\\n \\uFF0C\\u4F46\\u662F\\u2F00\\u4E9B\\u4F17\\u6240 \\u5468\\u77E5\\u7684\\u2F08\\u540D\\\n \\u9700\\u2F64\\u4E2D\\u2F42\\uFF08\\u5982\\u4E54\\u5E03\\u65AF\\uFF09\\u3002\\n-\\\n \\ \\u5173\\u4E8E\\u4E66\\u540D\\u7684\\u7FFB\\u8BD1\\u3002\\u6709\\u4E2D\\u2F42\\u7248\\\n \\u7684\\u56FE\\u4E66\\uFF0C\\u8BF7\\u2F64\\u4E2D\\u2F42\\u7248\\u4E66\\u540D\\uFF1B\\\n \\u2F46\\u4E2D\\u2F42\\u7248 \\u7684\\u56FE\\u4E66\\uFF0C\\u76F4\\u63A5\\u2F64\\u82F1\\\n \\u2F42\\u4E66\\u540D\\u3002\\n- \\u5173\\u4E8E\\u56FE\\u8868\\u7684\\u7FFB\\u8BD1\\\n \\u3002\\u8868\\u683C\\u4E2D\\u7684\\u8868\\u9898\\u3001\\u8868\\u5B57\\u548C\\u6CE8\\\n \\u89E3\\u7B49\\u5747\\u9700\\u7FFB\\u8BD1\\u3002\\u56FE\\u9898 \\u9700\\u8981\\u7FFB\\\n \\u8BD1\\u3002\\u754C\\u2FAF\\u622A\\u56FE\\u4E0D\\u9700\\u8981\\u7FFB\\u8BD1\\u56FE\\\n \\u5B57\\u3002\\u89E3\\u91CA\\u6027\\u56FE\\u9700\\u8981\\u6309\\u7167\\u4E2D\\u82F1\\\n \\u2F42 \\u5BF9\\u7167\\u683C\\u5F0F\\u7ED9\\u51FA\\u56FE\\u5B57\\u7FFB\\u8BD1\\u3002\\\n \\n- \\u5173\\u4E8E\\u82F1\\u2F42\\u672F\\u8BED\\u7684\\u8868\\u8FF0\\u3002\\u82F1\\\n \\u2F42\\u672F\\u8BED\\u2FB8\\u6B21\\u51FA\\u73B0\\u65F6\\uFF0C\\u5E94\\u8BE5\\u6839\\\n \\u636E\\u8BE5\\u672F\\u8BED\\u7684 \\u6D41\\u2F8F\\u60C5\\u51B5\\uFF0C\\u4F18\\u5148\\\n \\u4F7F\\u2F64\\u7B80\\u5199\\u5F62\\u5F0F\\uFF0C\\u5E76\\u5728\\u5176\\u540E\\u4F7F\\\n \\u2F64\\u62EC\\u53F7\\u52A0\\u82F1\\u2F42\\u3001\\u4E2D\\u2F42 \\u5168\\u79F0\\u6CE8\\\n \\u89E3\\uFF0C\\u683C\\u5F0F\\u4E3A\\uFF08\\u4E3E\\u4F8B\\uFF09\\uFF1AHTML\\uFF08\\\n Hypertext Markup Language\\uFF0C\\u8D85\\u2F42\\u672C\\u6807\\u8BC6\\u8BED\\u2F94\\\n \\uFF09\\u3002\\u7136\\u540E\\u5728\\u4E0B\\u2F42\\u4E2D\\u76F4\\u63A5\\u4F7F\\u2F64\\\n \\u7B80\\u5199\\u5F62 \\u5F0F\\u3002\\u5F53\\u7136\\uFF0C\\u5FC5\\u8981\\u65F6\\u4E5F\\\n \\u53EF\\u4EE5\\u6839\\u636E\\u8BED\\u5883\\u4F7F\\u2F64\\u4E2D\\u3001\\u82F1\\u2F42\\\n \\u5168\\u79F0\\u3002\\n- \\u5173\\u4E8E\\u4EE3\\u7801\\u6E05\\u5355\\u548C\\u4EE3\\\n \\u7801\\u2F5A\\u6BB5\\u3002\\u539F\\u4E66\\u4E2D\\u5305\\u542B\\u7684\\u7A0B\\u5E8F\\\n \\u4EE3\\u7801\\u4E0D\\u8981\\u6C42\\u8BD1\\u8005\\u5F55 \\u2F0A\\uFF0C\\u4F46\\u5E94\\\n \\u8BE5\\u4F7F\\u2F64\\u201C\\u539F\\u4E66P99\\u2EDA\\u4EE3\\u78011\\u201D\\uFF08\\\n \\u5373\\u539F\\u4E66\\u7B2C99\\u2EDA\\u4E2D\\u7684\\u7B2C\\u2F00\\u6BB5\\u4EE3 \\u7801\\\n \\uFF09\\u7684\\u683C\\u5F0F\\u4F5C\\u51FA\\u6807\\u6CE8\\u3002\\u540C\\u65F6\\uFF0C\\\n \\u8BD1\\u8005\\u5E94\\u8BE5\\u5728\\u6709\\u6761\\u4EF6\\u7684\\u60C5\\u51B5\\u4E0B\\\n \\u68C0\\u6838\\u4EE3 \\u7801\\u7684\\u6B63\\u786E\\u6027\\uFF0C\\u5BF9\\u53D1\\u73B0\\\n \\u7684\\u9519\\u8BEF\\u4EE5\\u8BD1\\u8005\\u6CE8\\u5F62\\u5F0F\\u8BF4\\u660E\\u3002\\\n \\u7A0B\\u5E8F\\u4EE3\\u7801\\u4E2D\\u7684\\u6CE8 \\u91CA\\u8981\\u6C42\\u7FFB\\u8BD1\\\n \\uFF0C\\u5982\\u679C\\u8BD1\\u7A3F\\u4E2D\\u6CA1\\u6709\\u4EE3\\u7801\\uFF0C\\u5219\\\n \\u5E94\\u8BE5\\u4EE5\\u2F00\\u53E5\\u82F1\\u2F42\\uFF08\\u6CE8\\u91CA\\uFF09 \\u2F00\\\n \\u53E5\\u4E2D\\u2F42\\uFF08\\u6CE8\\u91CA\\uFF09\\u7684\\u5F62\\u5F0F\\u7ED9\\u51FA\\\n \\u6CE8\\u91CA\\u3002\\n- \\u5173\\u4E8E\\u6807\\u70B9\\u7B26\\u53F7\\u3002\\u8BD1\\\n \\u7A3F\\u4E2D\\u7684\\u6807\\u70B9\\u7B26\\u53F7\\u8981\\u9075\\u5FAA\\u4E2D\\u2F42\\\n \\u8868\\u8FBE\\u4E60\\u60EF\\u548C\\u4E2D\\u2F42\\u6807 \\u70B9\\u7B26\\u53F7\\u7684\\\n \\u4F7F\\u2F64\\u4E60\\u60EF\\uFF0C\\u4E0D\\u80FD\\u7167\\u642C\\u539F\\u2F42\\u7684\\\n \\u6807\\u70B9\\u7B26\\u53F7\\u3002\\n\\n\\n{{#1717916977413.text#}}\\n\\\n \\n{{#1717916955547.item#}}\\n\\n{{#1717916961837.text#}}\\n\\\n \"\n selected: false\n title: 'Problems '\n type: llm\n variables: []\n vision:\n configs:\n detail: high\n enabled: true\n extent: parent\n height: 97\n id: '1717916984996'\n parentId: '1717916955547'\n position:\n x: 725\n y: 85\n positionAbsolute:\n x: 1363\n y: 386.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: ''\n isInIteration: true\n iteration_id: '1717916955547'\n model:\n completion_params:\n temperature: 0.7\n mode: chat\n name: gpt-4o\n provider: openai\n prompt_template:\n - id: 4d7ae758-2d7b-4404-ad9f-d6748ee64439\n role: system\n text: \"\\nBased on the results of the direct translation in the first\\\n \\ step and the problems identified in the second step, re-translate to\\\n \\ achieve a meaning-based interpretation. Ensure the original intent of\\\n \\ the content is preserved while making it easier to understand and more\\\n \\ in line with Chinese expression habits. All the while maintaining the\\\n \\ original format unchanged. \\n\\n\\n- inconsistent with chinese\\\n \\ expression habits, clearly indicate where it does not conform\\n- Clumsy\\\n \\ sentences, specify the location, no need to offer suggestions for modification,\\\n \\ which will be fixed during free translation\\n- Obscure and difficult\\\n \\ to understand, attempts to explain may be made\\n- \\u65E0\\u6F0F\\u8BD1\\\n \\uFF08\\u539F\\u2F42\\u4E2D\\u7684\\u5173\\u952E\\u8BCD\\u3001\\u53E5\\u2F26\\u3001\\\n \\u6BB5\\u843D\\u90FD\\u5E94\\u4F53\\u73B0\\u5728\\u8BD1\\u2F42\\u4E2D\\uFF09\\u3002\\\n \\n- \\u2F46\\u9519\\u8BD1\\uFF08\\u770B\\u9519\\u539F\\u2F42\\u3001\\u8BEF\\u89E3\\\n \\u539F\\u2F42\\u610F\\u601D\\u5747\\u7B97\\u9519\\u8BD1\\uFF09\\u3002\\n- \\u2F46\\\n \\u6709\\u610F\\u589E\\u52A0\\u6216\\u8005\\u5220\\u51CF\\u7684\\u539F\\u2F42\\u5185\\\n \\u5BB9\\uFF08\\u7FFB\\u8BD1\\u5E76\\u2FAE\\u521B\\u4F5C\\uFF0C\\u9700\\u5C0A\\u91CD\\\n \\u4F5C\\u8005\\u89C2 \\u70B9\\uFF1B\\u53EF\\u4EE5\\u9002\\u5F53\\u52A0\\u8BD1\\u8005\\\n \\u6CE8\\u8BF4\\u660E\\uFF09\\u3002\\n- \\u8BD1\\u2F42\\u6D41\\u7545\\uFF0C\\u7B26\\\n \\u5408\\u4E2D\\u2F42\\u8868\\u8FBE\\u4E60\\u60EF\\u3002\\n- \\u5173\\u4E8E\\u2F08\\\n \\u540D\\u7684\\u7FFB\\u8BD1\\u3002\\u6280\\u672F\\u56FE\\u4E66\\u4E2D\\u7684\\u2F08\\\n \\u540D\\u901A\\u5E38\\u4E0D\\u7FFB\\u8BD1\\uFF0C\\u4F46\\u662F\\u2F00\\u4E9B\\u4F17\\\n \\u6240 \\u5468\\u77E5\\u7684\\u2F08\\u540D\\u9700\\u2F64\\u4E2D\\u2F42\\uFF08\\u5982\\\n \\u4E54\\u5E03\\u65AF\\uFF09\\u3002\\n- \\u5173\\u4E8E\\u4E66\\u540D\\u7684\\u7FFB\\\n \\u8BD1\\u3002\\u6709\\u4E2D\\u2F42\\u7248\\u7684\\u56FE\\u4E66\\uFF0C\\u8BF7\\u2F64\\\n \\u4E2D\\u2F42\\u7248\\u4E66\\u540D\\uFF1B\\u2F46\\u4E2D\\u2F42\\u7248 \\u7684\\u56FE\\\n \\u4E66\\uFF0C\\u76F4\\u63A5\\u2F64\\u82F1\\u2F42\\u4E66\\u540D\\u3002\\n- \\u5173\\\n \\u4E8E\\u56FE\\u8868\\u7684\\u7FFB\\u8BD1\\u3002\\u8868\\u683C\\u4E2D\\u7684\\u8868\\\n \\u9898\\u3001\\u8868\\u5B57\\u548C\\u6CE8\\u89E3\\u7B49\\u5747\\u9700\\u7FFB\\u8BD1\\\n \\u3002\\u56FE\\u9898 \\u9700\\u8981\\u7FFB\\u8BD1\\u3002\\u754C\\u2FAF\\u622A\\u56FE\\\n \\u4E0D\\u9700\\u8981\\u7FFB\\u8BD1\\u56FE\\u5B57\\u3002\\u89E3\\u91CA\\u6027\\u56FE\\\n \\u9700\\u8981\\u6309\\u7167\\u4E2D\\u82F1\\u2F42 \\u5BF9\\u7167\\u683C\\u5F0F\\u7ED9\\\n \\u51FA\\u56FE\\u5B57\\u7FFB\\u8BD1\\u3002\\n- \\u5173\\u4E8E\\u82F1\\u2F42\\u672F\\\n \\u8BED\\u7684\\u8868\\u8FF0\\u3002\\u82F1\\u2F42\\u672F\\u8BED\\u2FB8\\u6B21\\u51FA\\\n \\u73B0\\u65F6\\uFF0C\\u5E94\\u8BE5\\u6839\\u636E\\u8BE5\\u672F\\u8BED\\u7684 \\u6D41\\\n \\u2F8F\\u60C5\\u51B5\\uFF0C\\u4F18\\u5148\\u4F7F\\u2F64\\u7B80\\u5199\\u5F62\\u5F0F\\\n \\uFF0C\\u5E76\\u5728\\u5176\\u540E\\u4F7F\\u2F64\\u62EC\\u53F7\\u52A0\\u82F1\\u2F42\\\n \\u3001\\u4E2D\\u2F42 \\u5168\\u79F0\\u6CE8\\u89E3\\uFF0C\\u683C\\u5F0F\\u4E3A\\uFF08\\\n \\u4E3E\\u4F8B\\uFF09\\uFF1AHTML\\uFF08Hypertext Markup Language\\uFF0C\\u8D85\\\n \\u2F42\\u672C\\u6807\\u8BC6\\u8BED\\u2F94\\uFF09\\u3002\\u7136\\u540E\\u5728\\u4E0B\\\n \\u2F42\\u4E2D\\u76F4\\u63A5\\u4F7F\\u2F64\\u7B80\\u5199\\u5F62 \\u5F0F\\u3002\\u5F53\\\n \\u7136\\uFF0C\\u5FC5\\u8981\\u65F6\\u4E5F\\u53EF\\u4EE5\\u6839\\u636E\\u8BED\\u5883\\\n \\u4F7F\\u2F64\\u4E2D\\u3001\\u82F1\\u2F42\\u5168\\u79F0\\u3002\\n- \\u5173\\u4E8E\\\n \\u4EE3\\u7801\\u6E05\\u5355\\u548C\\u4EE3\\u7801\\u2F5A\\u6BB5\\u3002\\u539F\\u4E66\\\n \\u4E2D\\u5305\\u542B\\u7684\\u7A0B\\u5E8F\\u4EE3\\u7801\\u4E0D\\u8981\\u6C42\\u8BD1\\\n \\u8005\\u5F55 \\u2F0A\\uFF0C\\u4F46\\u5E94\\u8BE5\\u4F7F\\u2F64\\u201C\\u539F\\u4E66\\\n P99\\u2EDA\\u4EE3\\u78011\\u201D\\uFF08\\u5373\\u539F\\u4E66\\u7B2C99\\u2EDA\\u4E2D\\\n \\u7684\\u7B2C\\u2F00\\u6BB5\\u4EE3 \\u7801\\uFF09\\u7684\\u683C\\u5F0F\\u4F5C\\u51FA\\\n \\u6807\\u6CE8\\u3002\\u540C\\u65F6\\uFF0C\\u8BD1\\u8005\\u5E94\\u8BE5\\u5728\\u6709\\\n \\u6761\\u4EF6\\u7684\\u60C5\\u51B5\\u4E0B\\u68C0\\u6838\\u4EE3 \\u7801\\u7684\\u6B63\\\n \\u786E\\u6027\\uFF0C\\u5BF9\\u53D1\\u73B0\\u7684\\u9519\\u8BEF\\u4EE5\\u8BD1\\u8005\\\n \\u6CE8\\u5F62\\u5F0F\\u8BF4\\u660E\\u3002\\u7A0B\\u5E8F\\u4EE3\\u7801\\u4E2D\\u7684\\\n \\u6CE8 \\u91CA\\u8981\\u6C42\\u7FFB\\u8BD1\\uFF0C\\u5982\\u679C\\u8BD1\\u7A3F\\u4E2D\\\n \\u6CA1\\u6709\\u4EE3\\u7801\\uFF0C\\u5219\\u5E94\\u8BE5\\u4EE5\\u2F00\\u53E5\\u82F1\\\n \\u2F42\\uFF08\\u6CE8\\u91CA\\uFF09 \\u2F00\\u53E5\\u4E2D\\u2F42\\uFF08\\u6CE8\\u91CA\\\n \\uFF09\\u7684\\u5F62\\u5F0F\\u7ED9\\u51FA\\u6CE8\\u91CA\\u3002\\n- \\u5173\\u4E8E\\\n \\u6807\\u70B9\\u7B26\\u53F7\\u3002\\u8BD1\\u7A3F\\u4E2D\\u7684\\u6807\\u70B9\\u7B26\\\n \\u53F7\\u8981\\u9075\\u5FAA\\u4E2D\\u2F42\\u8868\\u8FBE\\u4E60\\u60EF\\u548C\\u4E2D\\\n \\u2F42\\u6807 \\u70B9\\u7B26\\u53F7\\u7684\\u4F7F\\u2F64\\u4E60\\u60EF\\uFF0C\\u4E0D\\\n \\u80FD\\u7167\\u642C\\u539F\\u2F42\\u7684\\u6807\\u70B9\\u7B26\\u53F7\\u3002\\n\\n\\\n \\n{{#1717916977413.text#}}\\n\\n{{#1717916984996.text#}}\\n\\n{{#1711067409646.input_text#}}\\n\\\n \\n{{#1717916961837.text#}}\\n \"\n selected: false\n title: '2nd Translation '\n type: llm\n variables: []\n vision:\n configs:\n detail: high\n enabled: true\n extent: parent\n height: 97\n id: '1717916991709'\n parentId: '1717916955547'\n position:\n x: 1029\n y: 85\n positionAbsolute:\n x: 1667\n y: 386.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n desc: 'Combine all chunks of translation. '\n selected: false\n template: '{{ translated_text | join('' '') }}'\n title: Template\n type: template-transform\n variables:\n - value_selector:\n - '1717916955547'\n - output\n variable: translated_text\n height: 83\n id: '1717917057450'\n position:\n x: 1987\n y: 301.5\n positionAbsolute:\n x: 1987\n y: 301.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n - data:\n author: Dify\n desc: ''\n height: 186\n selected: false\n showAuthor: true\n text: '{\"root\":{\"children\":[{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Code\n node separates the input_text into chunks with length of token_limit. Each\n chunk overlap with each other to make sure the texts are consistent. \",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"The\n code node outputs an array of segmented texts of input_texts. \",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"root\",\"version\":1}}'\n theme: blue\n title: ''\n type: ''\n width: 340\n height: 186\n id: '1718990593686'\n position:\n x: 259.3026056936437\n y: 451.6924912936374\n positionAbsolute:\n x: 259.3026056936437\n y: 451.6924912936374\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom-note\n width: 340\n - data:\n author: Dify\n desc: ''\n height: 128\n selected: false\n showAuthor: true\n text: '{\"root\":{\"children\":[{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Iterate\n through all the elements in output of the code node and translate each chunk\n using a three steps translation workflow. \",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"root\",\"version\":1}}'\n theme: blue\n title: ''\n type: ''\n width: 355\n height: 128\n id: '1718991836605'\n position:\n x: 764.3891977435923\n y: 530.8917807505335\n positionAbsolute:\n x: 764.3891977435923\n y: 530.8917807505335\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom-note\n width: 355\n - data:\n author: Dify\n desc: ''\n height: 126\n selected: false\n showAuthor: true\n text: '{\"root\":{\"children\":[{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Avoid\n using a high token_limit, LLM''s performance decreases with longer context\n length for gpt-4o. \",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Recommend\n to use less than or equal to 1000 tokens. \",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"root\",\"version\":1}}'\n theme: yellow\n title: ''\n type: ''\n width: 351\n height: 126\n id: '1718991882984'\n position:\n x: 304.49115824454367\n y: 148.4042994607805\n positionAbsolute:\n x: 304.49115824454367\n y: 148.4042994607805\n selected: true\n sourcePosition: right\n targetPosition: left\n type: custom-note\n width: 351\n viewport:\n x: 335.92505067152274\n y: 18.806553508850584\n zoom: 0.8705505632961259\n","icon":"\ud83e\udd16","icon_background":"#FFEAD5","id":"98b87f88-bd22-4d86-8b74-86beba5e0ed4","mode":"workflow","name":"Book Translation "}, + "e9d92058-7d20-4904-892f-75d90bef7587":{"export_data":"app:\n icon: \"\\U0001F916\"\n icon_background: '#FFEAD5'\n mode: advanced-chat\n name: 'Automated Email Reply '\nworkflow:\n features:\n file_upload:\n image:\n enabled: false\n opening_statement: ''\n retriever_resource:\n enabled: false\n sensitive_word_avoidance:\n enabled: false\n speech_to_text:\n enabled: false\n suggested_questions: []\n suggested_questions_after_answer:\n enabled: false\n text_to_speech:\n enabled: false\n language: ''\n voice: ''\n graph:\n edges:\n - data:\n isInIteration: false\n sourceType: code\n targetType: iteration\n id: 1716909112104-source-1716909114582-target\n source: '1716909112104'\n sourceHandle: source\n target: '1716909114582'\n targetHandle: target\n type: custom\n zIndex: 0\n - data:\n isInIteration: false\n sourceType: iteration\n targetType: template-transform\n id: 1716909114582-source-1716913435742-target\n source: '1716909114582'\n sourceHandle: source\n target: '1716913435742'\n targetHandle: target\n type: custom\n zIndex: 0\n - data:\n isInIteration: false\n sourceType: template-transform\n targetType: answer\n id: 1716913435742-source-1716806267180-target\n source: '1716913435742'\n sourceHandle: source\n target: '1716806267180'\n targetHandle: target\n type: custom\n zIndex: 0\n - data:\n isInIteration: false\n sourceType: start\n targetType: tool\n id: 1716800588219-source-1716946869294-target\n source: '1716800588219'\n sourceHandle: source\n target: '1716946869294'\n targetHandle: target\n type: custom\n zIndex: 0\n - data:\n isInIteration: false\n sourceType: tool\n targetType: code\n id: 1716946869294-source-1716909112104-target\n source: '1716946869294'\n sourceHandle: source\n target: '1716909112104'\n targetHandle: target\n type: custom\n zIndex: 0\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: tool\n targetType: code\n id: 1716946889408-source-1716909122343-target\n source: '1716946889408'\n sourceHandle: source\n target: '1716909122343'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: code\n targetType: code\n id: 1716909122343-source-1716951357236-target\n source: '1716909122343'\n sourceHandle: source\n target: '1716951357236'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: code\n targetType: llm\n id: 1716951357236-source-1716913272656-target\n source: '1716951357236'\n sourceHandle: source\n target: '1716913272656'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: template-transform\n targetType: llm\n id: 1716951236700-source-1716951159073-target\n source: '1716951236700'\n sourceHandle: source\n target: '1716951159073'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: llm\n targetType: template-transform\n id: 1716951159073-source-1716952228079-target\n source: '1716951159073'\n sourceHandle: source\n target: '1716952228079'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: template-transform\n targetType: tool\n id: 1716952228079-source-1716952912103-target\n source: '1716952228079'\n sourceHandle: source\n target: '1716952912103'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: llm\n targetType: question-classifier\n id: 1716913272656-source-1716960721611-target\n source: '1716913272656'\n sourceHandle: source\n target: '1716960721611'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: question-classifier\n targetType: llm\n id: 1716960721611-1-1716909125498-target\n source: '1716960721611'\n sourceHandle: '1'\n target: '1716909125498'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: question-classifier\n targetType: llm\n id: 1716960721611-2-1716960728136-target\n source: '1716960721611'\n sourceHandle: '2'\n target: '1716960728136'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: llm\n targetType: variable-aggregator\n id: 1716909125498-source-1716960791399-target\n source: '1716909125498'\n sourceHandle: source\n target: '1716960791399'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: variable-aggregator\n targetType: template-transform\n id: 1716960791399-source-1716951236700-target\n source: '1716960791399'\n sourceHandle: source\n target: '1716951236700'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: question-classifier\n targetType: template-transform\n id: 1716960721611-1716960736883-1716960834468-target\n source: '1716960721611'\n sourceHandle: '1716960736883'\n target: '1716960834468'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: llm\n targetType: variable-aggregator\n id: 1716960728136-source-1716960791399-target\n source: '1716960728136'\n sourceHandle: source\n target: '1716960791399'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1716909114582'\n sourceType: template-transform\n targetType: variable-aggregator\n id: 1716960834468-source-1716960791399-target\n source: '1716960834468'\n sourceHandle: source\n target: '1716960791399'\n targetHandle: target\n type: custom\n zIndex: 1002\n nodes:\n - data:\n desc: ''\n selected: false\n title: Start\n type: start\n variables:\n - label: Your Email\n max_length: 256\n options: []\n required: true\n type: text-input\n variable: email\n - label: Maximum Number of Email you want to retrieve\n max_length: 256\n options: []\n required: true\n type: number\n variable: maxResults\n height: 115\n id: '1716800588219'\n position:\n x: 30\n y: 445\n positionAbsolute:\n x: 30\n y: 445\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n - data:\n answer: '{{#1716913435742.output#}}'\n desc: ''\n selected: false\n title: Direct Reply\n type: answer\n variables: []\n height: 106\n id: '1716806267180'\n position:\n x: 4700\n y: 445\n positionAbsolute:\n x: 4700\n y: 445\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n - data:\n code: \"def main(message: str) -> dict:\\n import json\\n \\n # Parse\\\n \\ the JSON string\\n parsed_data = json.loads(message)\\n \\n # Extract\\\n \\ all the \\\"id\\\" values\\n ids = [msg['id'] for msg in parsed_data['messages']]\\n\\\n \\ \\n return {\\n \\\"result\\\": ids\\n }\"\n code_language: python3\n desc: ''\n outputs:\n result:\n children: null\n type: array[string]\n selected: false\n title: 'Code: Extract Email ID'\n type: code\n variables:\n - value_selector:\n - '1716946869294'\n - text\n variable: message\n height: 53\n id: '1716909112104'\n position:\n x: 638\n y: 445\n positionAbsolute:\n x: 638\n y: 445\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n - data:\n desc: ''\n height: 490\n iterator_selector:\n - '1716909112104'\n - result\n output_selector:\n - '1716909125498'\n - text\n output_type: array[string]\n selected: false\n startNodeType: tool\n start_node_id: '1716946889408'\n title: 'Iteraction '\n type: iteration\n width: 3393.7520359289056\n height: 490\n id: '1716909114582'\n position:\n x: 942\n y: 445\n positionAbsolute:\n x: 942\n y: 445\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 3394\n zIndex: 1\n - data:\n desc: ''\n isInIteration: true\n isIterationStart: true\n iteration_id: '1716909114582'\n provider_id: e64b4c7f-2795-499c-8d11-a971a7d57fc9\n provider_name: List and Get Gmail\n provider_type: api\n selected: false\n title: getMessage\n tool_configurations: {}\n tool_label: getMessage\n tool_name: getMessage\n tool_parameters:\n format:\n type: mixed\n value: full\n id:\n type: mixed\n value: '{{#1716909114582.item#}}'\n userId:\n type: mixed\n value: '{{#1716800588219.email#}}'\n type: tool\n extent: parent\n height: 53\n id: '1716946889408'\n parentId: '1716909114582'\n position:\n x: 117\n y: 85\n positionAbsolute:\n x: 1059\n y: 530\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1001\n - data:\n code: \"\\ndef main(email_json: dict) -> dict:\\n import json \\n email_dict\\\n \\ = json.loads(email_json)\\n base64_data = email_dict['payload']['parts'][0]['body']['data']\\n\\\n \\n return {\\n \\\"result\\\": base64_data, \\n }\\n\"\n code_language: python3\n desc: ''\n isInIteration: true\n iteration_id: '1716909114582'\n outputs:\n result:\n children: null\n type: string\n selected: false\n title: 'Code: Extract Email Body'\n type: code\n variables:\n - value_selector:\n - '1716946889408'\n - text\n variable: email_json\n extent: parent\n height: 53\n id: '1716909122343'\n parentId: '1716909114582'\n position:\n x: 421\n y: 85\n positionAbsolute:\n x: 1363\n y: 530\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: 'Generate reply. '\n isInIteration: true\n iteration_id: '1716909114582'\n model:\n completion_params:\n temperature: 0.7\n mode: chat\n name: gpt-4o\n provider: openai\n prompt_template:\n - id: 982014aa-702b-4d7c-ae1f-08dbceb6e930\n role: system\n text: \" \\nRespond to the emails. \\n\\n{{#1716913272656.text#}}\\n\\\n \"\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n configs:\n detail: high\n enabled: true\n extent: parent\n height: 127\n id: '1716909125498'\n parentId: '1716909114582'\n position:\n x: 1625\n y: 85\n positionAbsolute:\n x: 2567\n y: 530\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: ''\n isInIteration: true\n iteration_id: '1716909114582'\n model:\n completion_params:\n temperature: 0.7\n mode: chat\n name: gpt-4o\n provider: openai\n prompt_template:\n - id: fd8de569-c099-4320-955b-61aa4b054789\n role: system\n text: \"\\nYou need to transform the input data (in base64 encoding)\\\n \\ to text. Input base64. Output text. \\n\\n{{#1716909122343.result#}}\\n\\\n \"\n selected: false\n title: 'Base64 Decoder '\n type: llm\n variables: []\n vision:\n configs:\n detail: high\n enabled: false\n extent: parent\n height: 97\n id: '1716913272656'\n parentId: '1716909114582'\n position:\n x: 1025\n y: 85\n positionAbsolute:\n x: 1967\n y: 530\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n desc: ''\n selected: false\n template: '{{ arg1 | join(\"\\n\\n -------------------------\\n\\n\") }}'\n title: 'Template '\n type: template-transform\n variables:\n - value_selector:\n - '1716909114582'\n - output\n variable: arg1\n height: 53\n id: '1716913435742'\n position:\n x: 4396\n y: 445\n positionAbsolute:\n x: 4396\n y: 445\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n - data:\n desc: ''\n provider_id: e64b4c7f-2795-499c-8d11-a971a7d57fc9\n provider_name: List and Get Gmail\n provider_type: api\n selected: false\n title: listMessages\n tool_configurations: {}\n tool_label: listMessages\n tool_name: listMessages\n tool_parameters:\n maxResults:\n type: variable\n value:\n - '1716800588219'\n - maxResults\n userId:\n type: mixed\n value: '{{#1716800588219.email#}}'\n type: tool\n height: 53\n id: '1716946869294'\n position:\n x: 334\n y: 445\n positionAbsolute:\n x: 334\n y: 445\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: ''\n isInIteration: true\n iteration_id: '1716909114582'\n model:\n completion_params:\n temperature: 0.7\n mode: chat\n name: gpt-4o\n provider: openai\n prompt_template:\n - id: b7fd0ec5-864a-42c6-9d04-a1958bd4fc0d\n role: system\n text: \"\\nYou need to encode the input data from text to base64. Input\\\n \\ text. Output base64 encoding. Output nothing other than base64 encoding.\\\n \\ \\n\\n{{#1716951236700.output#}}\\n \"\n selected: false\n title: Base64 Encoder\n type: llm\n variables: []\n vision:\n configs:\n detail: high\n enabled: true\n extent: parent\n height: 97\n id: '1716951159073'\n parentId: '1716909114582'\n position:\n x: 2525.7520359289056\n y: 85\n positionAbsolute:\n x: 3467.7520359289056\n y: 530\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n desc: Generate MIME email template\n isInIteration: true\n iteration_id: '1716909114582'\n selected: false\n template: \"Content-Type: text/plain; charset=\\\"utf-8\\\"\\r\\nContent-Transfer-Encoding:\\\n \\ 7bit\\r\\nMIME-Version: 1.0\\r\\nTo: {{ emailMetadata.recipientEmail }} #\\\n \\ xiaoyi@dify.ai\\r\\nFrom: {{ emailMetadata.senderEmail }} # sxy.hj156@gmail.com\\r\\\n \\nSubject: Re: {{ emailMetadata.subject }} \\r\\n\\r\\n{{ text }}\\r\\n\"\n title: 'Template: Reply Email'\n type: template-transform\n variables:\n - value_selector:\n - '1716951357236'\n - result\n variable: emailMetadata\n - value_selector:\n - '1716960791399'\n - output\n variable: text\n extent: parent\n height: 83\n id: '1716951236700'\n parentId: '1716909114582'\n position:\n x: 2231.269960149744\n y: 85\n positionAbsolute:\n x: 3173.269960149744\n y: 530\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n code: \"def main(email_json: dict) -> dict:\\n import json\\n if isinstance(email_json,\\\n \\ str): \\n email_json = json.loads(email_json)\\n\\n subject = None\\n\\\n \\ recipient_email = None \\n sender_email = None\\n \\n headers\\\n \\ = email_json['payload']['headers']\\n for header in headers:\\n \\\n \\ if header['name'] == 'Subject':\\n subject = header['value']\\n\\\n \\ elif header['name'] == 'To':\\n recipient_email = header['value']\\n\\\n \\ elif header['name'] == 'From':\\n sender_email = header['value']\\n\\\n \\n return {\\n \\\"result\\\": [subject, recipient_email, sender_email]\\n\\\n \\ }\\n\"\n code_language: python3\n desc: \"Recipient, Sender, Subject\\uFF0COutput Array[String]\"\n isInIteration: true\n iteration_id: '1716909114582'\n outputs:\n result:\n children: null\n type: array[string]\n selected: false\n title: Extract Email Metadata\n type: code\n variables:\n - value_selector:\n - '1716946889408'\n - text\n variable: email_json\n extent: parent\n height: 101\n id: '1716951357236'\n parentId: '1716909114582'\n position:\n x: 725\n y: 85\n positionAbsolute:\n x: 1667\n y: 530\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n desc: ''\n isInIteration: true\n iteration_id: '1716909114582'\n selected: false\n template: '{\"raw\": \"{{ encoded_message }}\"}'\n title: \"Template\\uFF1AEmail Request Body\"\n type: template-transform\n variables:\n - value_selector:\n - '1716951159073'\n - text\n variable: encoded_message\n extent: parent\n height: 53\n id: '1716952228079'\n parentId: '1716909114582'\n position:\n x: 2828.4325280181324\n y: 86.31950791077293\n positionAbsolute:\n x: 3770.4325280181324\n y: 531.3195079107729\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n desc: ''\n isInIteration: true\n iteration_id: '1716909114582'\n provider_id: 038963aa-43c8-47fc-be4b-0255c19959c1\n provider_name: Draft Gmail\n provider_type: api\n selected: false\n title: createDraft\n tool_configurations: {}\n tool_label: createDraft\n tool_name: createDraft\n tool_parameters:\n message:\n type: mixed\n value: '{{#1716952228079.output#}}'\n userId:\n type: mixed\n value: '{{#1716800588219.email#}}'\n type: tool\n extent: parent\n height: 53\n id: '1716952912103'\n parentId: '1716909114582'\n position:\n x: 3133.7520359289056\n y: 85\n positionAbsolute:\n x: 4075.7520359289056\n y: 530\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n classes:\n - id: '1'\n name: 'Technical questions, related to product '\n - id: '2'\n name: Unrelated to technicals, non technical\n - id: '1716960736883'\n name: Other questions\n desc: ''\n instructions: ''\n isInIteration: true\n iteration_id: '1716909114582'\n model:\n completion_params:\n temperature: 0.7\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n query_variable_selector:\n - '1716800588219'\n - sys.query\n selected: false\n title: Question Classifier\n topics: []\n type: question-classifier\n extent: parent\n height: 255\n id: '1716960721611'\n parentId: '1716909114582'\n position:\n x: 1325\n y: 85\n positionAbsolute:\n x: 2267\n y: 530\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: ''\n isInIteration: true\n iteration_id: '1716909114582'\n model:\n completion_params:\n temperature: 0.7\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - id: a639bbf8-bc58-42a2-b477-6748e80ecda2\n role: system\n text: \" \\nRespond to the emails. \\n\\n{{#1716913272656.text#}}\\n\\\n \"\n selected: false\n title: 'LLM - Non technical '\n type: llm\n variables: []\n vision:\n enabled: false\n extent: parent\n height: 97\n id: '1716960728136'\n parentId: '1716909114582'\n position:\n x: 1625\n y: 251\n positionAbsolute:\n x: 2567\n y: 696\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n desc: ''\n isInIteration: true\n iteration_id: '1716909114582'\n output_type: string\n selected: false\n title: Variable Aggregator\n type: variable-aggregator\n variables:\n - - '1716909125498'\n - text\n - - '1716960728136'\n - text\n - - '1716960834468'\n - output\n extent: parent\n height: 164\n id: '1716960791399'\n parentId: '1716909114582'\n position:\n x: 1931.2699601497438\n y: 85\n positionAbsolute:\n x: 2873.269960149744\n y: 530\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n desc: Other questions\n isInIteration: true\n iteration_id: '1716909114582'\n selected: false\n template: 'Sorry, I cannot answer that. This is outside my capabilities. '\n title: 'Direct Reply '\n type: template-transform\n variables: []\n extent: parent\n height: 83\n id: '1716960834468'\n parentId: '1716909114582'\n position:\n x: 1625\n y: 385.57142857142856\n positionAbsolute:\n x: 2567\n y: 830.5714285714286\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n author: Dify\n desc: ''\n height: 153\n selected: false\n showAuthor: true\n text: '{\"root\":{\"children\":[{\"children\":[{\"detail\":0,\"format\":3,\"mode\":\"normal\",\"style\":\"font-size:\n 14px;\",\"text\":\"OpenAPI-Swagger for all custom tools: \",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":3},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"openapi:\n 3.0.0\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"info:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" title:\n Gmail API\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n OpenAPI schema for Gmail API methods `users.messages.get`, `users.messages.list`,\n and `users.drafts.create`.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" version:\n 1.0.0\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"servers:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n url: https://gmail.googleapis.com\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Gmail API Server\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"paths:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" /gmail/v1/users/{userId}/messages/{id}:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" get:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" summary:\n Get a message.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Retrieves a specific message by ID.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" operationId:\n getMessage\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" parameters:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n name: userId\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" in:\n path\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" required:\n true\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" schema:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n The user''s email address. The special value `me` can be used to indicate\n the authenticated user.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n name: id\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" in:\n path\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" required:\n true\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" schema:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n The ID of the message to retrieve.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n name: format\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" in:\n query\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" required:\n false\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" schema:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" enum:\n [full, metadata, minimal, raw]\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" default:\n full\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n The format to return the message in.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" responses:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''200'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Successful response\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" content:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" application/json:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" schema:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n object\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" properties:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" id:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" threadId:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" labelIds:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n array\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" items:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" snippet:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" historyId:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" internalDate:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" payload:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n object\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" sizeEstimate:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n integer\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" raw:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''401'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Unauthorized\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''403'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Forbidden\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''404'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Not Found\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" /gmail/v1/users/{userId}/messages:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" get:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" summary:\n List messages.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Lists the messages in the user''s mailbox.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" operationId:\n listMessages\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" parameters:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n name: userId\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" in:\n path\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" required:\n true\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" schema:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n The user''s email address. The special value `me` can be used to indicate\n the authenticated user.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n name: maxResults\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" in:\n query\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" schema:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n integer\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" format:\n int32\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" default:\n 100\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Maximum number of messages to return.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" responses:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''200'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Successful response\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" content:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" application/json:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" schema:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n object\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" properties:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" messages:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n array\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" items:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n object\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" properties:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" id:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" threadId:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" nextPageToken:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" resultSizeEstimate:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n integer\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''401'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Unauthorized\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" /gmail/v1/users/{userId}/drafts:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" post:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" summary:\n Creates a new draft.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" operationId:\n createDraft\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" tags:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n Drafts\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" parameters:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n name: userId\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" in:\n path\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" required:\n true\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n The user''s email address. The special value \\\"me\\\" can be used to indicate\n the authenticated user.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" schema:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" requestBody:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" required:\n true\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" content:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" application/json:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" schema:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n object\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" properties:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" message:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n object\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" properties:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" raw:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n The entire email message in an RFC 2822 formatted and base64url encoded\n string.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" responses:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''200'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Successful response with the created draft.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" content:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" application/json:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" schema:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n object\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" properties:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" id:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n The immutable ID of the draft.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" message:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n object\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" properties:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" id:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n The immutable ID of the message.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" threadId:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n The ID of the thread the message belongs to.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" labelIds:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n array\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" items:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" snippet:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n A short part of the message text.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" historyId:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n string\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n The ID of the last history record that modified this message.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''400'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Bad Request - The request is invalid.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''401'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Unauthorized - Authentication is required.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''403'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Forbidden - The user does not have permission to create drafts.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''404'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Not Found - The specified user does not exist.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" ''500'':\",\"type\":\"text\",\"version\":1}],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" description:\n Internal Server Error - An error occurred on the server.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"components:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" securitySchemes:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" OAuth2:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" type:\n oauth2\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" flows:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" authorizationCode:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" authorizationUrl:\n https://accounts.google.com/o/oauth2/auth\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" tokenUrl:\n https://oauth2.googleapis.com/token\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" scopes:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" https://mail.google.com/:\n All access to Gmail.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" https://www.googleapis.com/auth/gmail.compose:\n Send email on your behalf.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" https://www.googleapis.com/auth/gmail.modify:\n Modify your email.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"security:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n OAuth2:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n https://mail.google.com/\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n https://www.googleapis.com/auth/gmail.compose\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\" -\n https://www.googleapis.com/auth/gmail.modify\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"root\",\"version\":1}}'\n theme: yellow\n title: ''\n type: ''\n width: 367\n height: 153\n id: '1718992681576'\n position:\n x: 321.9646831030669\n y: 538.1642616264143\n positionAbsolute:\n x: 321.9646831030669\n y: 538.1642616264143\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom-note\n width: 367\n - data:\n author: Dify\n desc: ''\n height: 158\n selected: false\n showAuthor: true\n text: '{\"root\":{\"children\":[{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Replace\n custom tools after added this template to your own workspace. \",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Fill\n in \",\"type\":\"text\",\"version\":1},{\"detail\":0,\"format\":1,\"mode\":\"normal\",\"style\":\"\",\"text\":\"your\n email \",\"type\":\"text\",\"version\":1},{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"and\n the \",\"type\":\"text\",\"version\":1},{\"detail\":0,\"format\":1,\"mode\":\"normal\",\"style\":\"\",\"text\":\"maximum\n number of results you want to retrieve from your inbox \",\"type\":\"text\",\"version\":1},{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"to\n get started. \",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"root\",\"version\":1}}'\n theme: blue\n title: ''\n type: ''\n width: 287\n height: 158\n id: '1718992805687'\n position:\n x: 18.571428571428356\n y: 237.80887395992687\n positionAbsolute:\n x: 18.571428571428356\n y: 237.80887395992687\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom-note\n width: 287\n - data:\n author: Dify\n desc: ''\n height: 375\n selected: true\n showAuthor: true\n text: '{\"root\":{\"children\":[{\"children\":[{\"detail\":0,\"format\":1,\"mode\":\"normal\",\"style\":\"font-size:\n 16px;\",\"text\":\"Steps within Iteraction node: \",\"type\":\"text\",\"version\":1},{\"type\":\"linebreak\",\"version\":1},{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"1.\n getMessage: This step retrieves the incoming email message.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":1},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"2.\n Code: Extract Email Body: Custom code is executed to extract the body of\n the email from the retrieved message.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"3.\n Extract Email Metadata: Extracts metadata from the email, such as the recipient,\n sender, subject, and other relevant information.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"4.\n Base64 Decoder: Decodes the email content from Base64 encoding.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"5.\n Question Classifier (gpt-3.5-turbo): Uses a GPT-3.5-turbo model to classify\n the email content into different categories. For each classified question,\n the workflow uses a GPT-4.0 model to generate an appropriate reply:\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"6.\n Template: Reply Email: Uses a template to generate a MIME email format for\n the reply.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"6.\n Base64 Encoder: Encodes the generated reply email content back to Base64.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"7.\n Template: Email Request: Prepares the email request using a template.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"8.\n createDraft: Creates a draft of the email reply.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"This\n workflow automates the process of reading, classifying, responding to, and\n drafting replies to incoming emails, leveraging advanced language models\n to generate contextually appropriate responses.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"root\",\"version\":1}}'\n theme: blue\n title: ''\n type: ''\n width: 640\n height: 375\n id: '1718993366836'\n position:\n x: 966.7525290975368\n y: 971.80362905854\n positionAbsolute:\n x: 966.7525290975368\n y: 971.80362905854\n selected: true\n sourcePosition: right\n targetPosition: left\n type: custom-note\n width: 640\n - data:\n author: Dify\n desc: ''\n height: 400\n selected: false\n showAuthor: true\n text: '{\"root\":{\"children\":[{\"children\":[{\"detail\":0,\"format\":3,\"mode\":\"normal\",\"style\":\"font-size:\n 16px;\",\"text\":\"Preparation\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":3},{\"children\":[{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Enable\n Gmail API in Google Cloud Console\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"listitem\",\"version\":1,\"value\":1},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Configure\n OAuth Client ID, OAuth Client Secrets, and OAuth Consent Screen for the\n Web Application in Google Cloud Console\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"listitem\",\"version\":1,\"value\":2},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Use\n Postman to authorize and obtain the OAuth Access Token (Google''s Access\n Token will expire after 1 hour and cannot be used for a long time)\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"listitem\",\"version\":1,\"value\":3}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"list\",\"version\":1,\"listType\":\"bullet\",\"start\":1,\"tag\":\"ul\"},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Users\n who want to try building an AI auto-reply email can refer to this document\n to use Postman (Postman.com) to obtain all the above keys: https://blog.postman.com/how-to-access-google-apis-using-oauth-in-postman/.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Developers\n who want to use Google OAuth to call the Gmail API to develop corresponding\n plugins can refer to this official document: \",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"https://developers.google.com/identity/protocols/oauth2/web-server.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"At\n this stage, it is still a bit difficult to reproduce this example within\n the Dify platform. If you have development capabilities, developing the\n corresponding plugin externally and using an external database to automatically\n read and write the user''s Access Token and write the Refresh Token would\n be a better choice.\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"root\",\"version\":1}}'\n theme: blue\n title: ''\n type: ''\n width: 608\n height: 400\n id: '1718993557447'\n position:\n x: 354.0157230378119\n y: -1.2732157979666\n positionAbsolute:\n x: 354.0157230378119\n y: -1.2732157979666\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom-note\n width: 608\n viewport:\n x: 147.09446825757777\n y: 101.03530130020579\n zoom: 0.9548416039104178\n","icon":"\ud83e\udd16","icon_background":"#FFEAD5","id":"e9d92058-7d20-4904-892f-75d90bef7587","mode":"advanced-chat","name":"Automated Email Reply "}, + "98b87f88-bd22-4d86-8b74-86beba5e0ed4":{"export_data":"app:\n icon: \"\\U0001F916\"\n icon_background: '#FFEAD5'\n mode: workflow\n name: 'Book Translation '\nworkflow:\n features:\n file_upload:\n image:\n enabled: false\n number_limits: 3\n transfer_methods:\n - local_file\n - remote_url\n opening_statement: ''\n retriever_resource:\n enabled: false\n sensitive_word_avoidance:\n enabled: false\n speech_to_text:\n enabled: false\n suggested_questions: []\n suggested_questions_after_answer:\n enabled: false\n text_to_speech:\n enabled: false\n language: ''\n voice: ''\n graph:\n edges:\n - data:\n isInIteration: false\n sourceType: start\n targetType: code\n id: 1711067409646-source-1717916867969-target\n source: '1711067409646'\n sourceHandle: source\n target: '1717916867969'\n targetHandle: target\n type: custom\n zIndex: 0\n - data:\n isInIteration: false\n sourceType: code\n targetType: iteration\n id: 1717916867969-source-1717916955547-target\n source: '1717916867969'\n sourceHandle: source\n target: '1717916955547'\n targetHandle: target\n type: custom\n zIndex: 0\n - data:\n isInIteration: true\n iteration_id: '1717916955547'\n sourceType: llm\n targetType: llm\n id: 1717916961837-source-1717916977413-target\n source: '1717916961837'\n sourceHandle: source\n target: '1717916977413'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1717916955547'\n sourceType: llm\n targetType: llm\n id: 1717916977413-source-1717916984996-target\n source: '1717916977413'\n sourceHandle: source\n target: '1717916984996'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: true\n iteration_id: '1717916955547'\n sourceType: llm\n targetType: llm\n id: 1717916984996-source-1717916991709-target\n source: '1717916984996'\n sourceHandle: source\n target: '1717916991709'\n targetHandle: target\n type: custom\n zIndex: 1002\n - data:\n isInIteration: false\n sourceType: iteration\n targetType: template-transform\n id: 1717916955547-source-1717917057450-target\n source: '1717916955547'\n sourceHandle: source\n target: '1717917057450'\n targetHandle: target\n type: custom\n zIndex: 0\n - data:\n isInIteration: false\n sourceType: template-transform\n targetType: end\n id: 1717917057450-source-1711068257370-target\n source: '1717917057450'\n sourceHandle: source\n target: '1711068257370'\n targetHandle: target\n type: custom\n zIndex: 0\n nodes:\n - data:\n desc: ''\n selected: false\n title: Start\n type: start\n variables:\n - label: Input Text\n max_length: null\n options: []\n required: true\n type: paragraph\n variable: input_text\n dragging: false\n height: 89\n id: '1711067409646'\n position:\n x: 30\n y: 301.5\n positionAbsolute:\n x: 30\n y: 301.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n - data:\n desc: ''\n outputs:\n - value_selector:\n - '1717917057450'\n - output\n variable: final\n selected: false\n title: End\n type: end\n height: 89\n id: '1711068257370'\n position:\n x: 2291\n y: 301.5\n positionAbsolute:\n x: 2291\n y: 301.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n - data:\n code: \"\\ndef main(input_text: str) -> str:\\n token_limit = 1000\\n overlap\\\n \\ = 100\\n chunk_size = int(token_limit * 6 * (4/3))\\n\\n # Initialize\\\n \\ variables\\n chunks = []\\n start_index = 0\\n text_length = len(input_text)\\n\\\n \\n # Loop until the end of the text is reached\\n while start_index\\\n \\ < text_length:\\n # If we are not at the beginning, adjust the start_index\\\n \\ to ensure overlap\\n if start_index > 0:\\n start_index\\\n \\ -= overlap\\n\\n # Calculate end index for the current chunk\\n \\\n \\ end_index = start_index + chunk_size\\n if end_index > text_length:\\n\\\n \\ end_index = text_length\\n\\n # Add the current chunk\\\n \\ to the list\\n chunks.append(input_text[start_index:end_index])\\n\\\n \\n # Update the start_index for the next chunk\\n start_index\\\n \\ += chunk_size\\n\\n return {\\n \\\"chunks\\\": chunks,\\n }\\n\"\n code_language: python3\n dependencies: []\n desc: 'token_limit = 1000\n\n overlap = 100'\n outputs:\n chunks:\n children: null\n type: array[string]\n selected: false\n title: Code\n type: code\n variables:\n - value_selector:\n - '1711067409646'\n - input_text\n variable: input_text\n height: 101\n id: '1717916867969'\n position:\n x: 336\n y: 301.5\n positionAbsolute:\n x: 336\n y: 301.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n - data:\n desc: 'Take good care on maximum number of iterations. '\n height: 203\n iterator_selector:\n - '1717916867969'\n - chunks\n output_selector:\n - '1717916991709'\n - text\n output_type: array[string]\n selected: false\n startNodeType: llm\n start_node_id: '1717916961837'\n title: Iteration\n type: iteration\n width: 1289\n height: 203\n id: '1717916955547'\n position:\n x: 638\n y: 301.5\n positionAbsolute:\n x: 638\n y: 301.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 1289\n zIndex: 1\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: ''\n isInIteration: true\n isIterationStart: true\n iteration_id: '1717916955547'\n model:\n completion_params:\n temperature: 0.7\n mode: chat\n name: gpt-4o\n provider: openai\n prompt_template:\n - id: 7261280b-cb27-4f84-8363-b93e09246d16\n role: system\n text: \" Identify the technical terms in the users input. Use the following\\\n \\ format {XXX} -> {XXX} to show the corresponding technical terms before\\\n \\ and after translation. \\n\\n \\n{{#1717916955547.item#}}\\n\\\n \\n\\n| \\u82F1\\u6587 | \\u4E2D\\u6587 |\\n| --- | --- |\\n| Prompt\\\n \\ Engineering | \\u63D0\\u793A\\u8BCD\\u5DE5\\u7A0B |\\n| Text Generation \\_\\\n | \\u6587\\u672C\\u751F\\u6210 |\\n| Token \\_| Token |\\n| Prompt \\_| \\u63D0\\\n \\u793A\\u8BCD |\\n| Meta Prompting \\_| \\u5143\\u63D0\\u793A |\\n| diffusion\\\n \\ models \\_| \\u6269\\u6563\\u6A21\\u578B |\\n| Agent \\_| \\u667A\\u80FD\\u4F53\\\n \\ |\\n| Transformer \\_| Transformer |\\n| Zero Shot \\_| \\u96F6\\u6837\\u672C\\\n \\ |\\n| Few Shot \\_| \\u5C11\\u6837\\u672C |\\n| chat window \\_| \\u804A\\u5929\\\n \\ |\\n| context | \\u4E0A\\u4E0B\\u6587 |\\n| stock photo \\_| \\u56FE\\u5E93\\u7167\\\n \\u7247 |\\n\\n\\n \"\n selected: false\n title: 'Identify Terms '\n type: llm\n variables: []\n vision:\n configs:\n detail: high\n enabled: true\n extent: parent\n height: 97\n id: '1717916961837'\n parentId: '1717916955547'\n position:\n x: 117\n y: 85\n positionAbsolute:\n x: 755\n y: 386.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1001\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: ''\n isInIteration: true\n iteration_id: '1717916955547'\n model:\n completion_params:\n temperature: 0.7\n mode: chat\n name: gpt-4o\n provider: openai\n prompt_template:\n - id: 05e03f0d-c1a9-43ab-b4c0-44b55049434d\n role: system\n text: \" You are a professional translator proficient in Simplified\\\n \\ Chinese especially skilled in translating professional academic papers\\\n \\ into easy-to-understand popular science articles. Please help me translate\\\n \\ the following english paragraph into Chinese, in a style similar to\\\n \\ Chinese popular science articles .\\n \\nTranslate directly\\\n \\ based on the English content, maintain the original format and do not\\\n \\ omit any information. \\n \\n{{#1717916955547.item#}}\\n\\\n \\n{{#1717916961837.text#}}\\n \"\n selected: false\n title: 1st Translation\n type: llm\n variables: []\n vision:\n configs:\n detail: high\n enabled: true\n extent: parent\n height: 97\n id: '1717916977413'\n parentId: '1717916955547'\n position:\n x: 421\n y: 85\n positionAbsolute:\n x: 1059\n y: 386.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: ''\n isInIteration: true\n iteration_id: '1717916955547'\n model:\n completion_params:\n temperature: 0.7\n mode: chat\n name: gpt-4o\n provider: openai\n prompt_template:\n - id: 9e6cc050-465e-4632-abc9-411acb255a95\n role: system\n text: \"\\nBased on the results of the direct translation, point out\\\n \\ specific issues it have. Accurate descriptions are required, avoiding\\\n \\ vague statements, and there's no need to add content or formats that\\\n \\ were not present in the original text, including but not limited to:\\\n \\ \\n- inconsistent with chinese expression habits, clearly indicate where\\\n \\ it does not conform\\n- Clumsy sentences, specify the location, no need\\\n \\ to offer suggestions for modification, which will be fixed during free\\\n \\ translation\\n- Obscure and difficult to understand, attempts to explain\\\n \\ may be made\\n- \\u65E0\\u6F0F\\u8BD1\\uFF08\\u539F\\u2F42\\u4E2D\\u7684\\u5173\\\n \\u952E\\u8BCD\\u3001\\u53E5\\u2F26\\u3001\\u6BB5\\u843D\\u90FD\\u5E94\\u4F53\\u73B0\\\n \\u5728\\u8BD1\\u2F42\\u4E2D\\uFF09\\u3002\\n- \\u2F46\\u9519\\u8BD1\\uFF08\\u770B\\\n \\u9519\\u539F\\u2F42\\u3001\\u8BEF\\u89E3\\u539F\\u2F42\\u610F\\u601D\\u5747\\u7B97\\\n \\u9519\\u8BD1\\uFF09\\u3002\\n- \\u2F46\\u6709\\u610F\\u589E\\u52A0\\u6216\\u8005\\\n \\u5220\\u51CF\\u7684\\u539F\\u2F42\\u5185\\u5BB9\\uFF08\\u7FFB\\u8BD1\\u5E76\\u2FAE\\\n \\u521B\\u4F5C\\uFF0C\\u9700\\u5C0A\\u91CD\\u4F5C\\u8005\\u89C2 \\u70B9\\uFF1B\\u53EF\\\n \\u4EE5\\u9002\\u5F53\\u52A0\\u8BD1\\u8005\\u6CE8\\u8BF4\\u660E\\uFF09\\u3002\\n-\\\n \\ \\u8BD1\\u2F42\\u6D41\\u7545\\uFF0C\\u7B26\\u5408\\u4E2D\\u2F42\\u8868\\u8FBE\\u4E60\\\n \\u60EF\\u3002\\n- \\u5173\\u4E8E\\u2F08\\u540D\\u7684\\u7FFB\\u8BD1\\u3002\\u6280\\\n \\u672F\\u56FE\\u4E66\\u4E2D\\u7684\\u2F08\\u540D\\u901A\\u5E38\\u4E0D\\u7FFB\\u8BD1\\\n \\uFF0C\\u4F46\\u662F\\u2F00\\u4E9B\\u4F17\\u6240 \\u5468\\u77E5\\u7684\\u2F08\\u540D\\\n \\u9700\\u2F64\\u4E2D\\u2F42\\uFF08\\u5982\\u4E54\\u5E03\\u65AF\\uFF09\\u3002\\n-\\\n \\ \\u5173\\u4E8E\\u4E66\\u540D\\u7684\\u7FFB\\u8BD1\\u3002\\u6709\\u4E2D\\u2F42\\u7248\\\n \\u7684\\u56FE\\u4E66\\uFF0C\\u8BF7\\u2F64\\u4E2D\\u2F42\\u7248\\u4E66\\u540D\\uFF1B\\\n \\u2F46\\u4E2D\\u2F42\\u7248 \\u7684\\u56FE\\u4E66\\uFF0C\\u76F4\\u63A5\\u2F64\\u82F1\\\n \\u2F42\\u4E66\\u540D\\u3002\\n- \\u5173\\u4E8E\\u56FE\\u8868\\u7684\\u7FFB\\u8BD1\\\n \\u3002\\u8868\\u683C\\u4E2D\\u7684\\u8868\\u9898\\u3001\\u8868\\u5B57\\u548C\\u6CE8\\\n \\u89E3\\u7B49\\u5747\\u9700\\u7FFB\\u8BD1\\u3002\\u56FE\\u9898 \\u9700\\u8981\\u7FFB\\\n \\u8BD1\\u3002\\u754C\\u2FAF\\u622A\\u56FE\\u4E0D\\u9700\\u8981\\u7FFB\\u8BD1\\u56FE\\\n \\u5B57\\u3002\\u89E3\\u91CA\\u6027\\u56FE\\u9700\\u8981\\u6309\\u7167\\u4E2D\\u82F1\\\n \\u2F42 \\u5BF9\\u7167\\u683C\\u5F0F\\u7ED9\\u51FA\\u56FE\\u5B57\\u7FFB\\u8BD1\\u3002\\\n \\n- \\u5173\\u4E8E\\u82F1\\u2F42\\u672F\\u8BED\\u7684\\u8868\\u8FF0\\u3002\\u82F1\\\n \\u2F42\\u672F\\u8BED\\u2FB8\\u6B21\\u51FA\\u73B0\\u65F6\\uFF0C\\u5E94\\u8BE5\\u6839\\\n \\u636E\\u8BE5\\u672F\\u8BED\\u7684 \\u6D41\\u2F8F\\u60C5\\u51B5\\uFF0C\\u4F18\\u5148\\\n \\u4F7F\\u2F64\\u7B80\\u5199\\u5F62\\u5F0F\\uFF0C\\u5E76\\u5728\\u5176\\u540E\\u4F7F\\\n \\u2F64\\u62EC\\u53F7\\u52A0\\u82F1\\u2F42\\u3001\\u4E2D\\u2F42 \\u5168\\u79F0\\u6CE8\\\n \\u89E3\\uFF0C\\u683C\\u5F0F\\u4E3A\\uFF08\\u4E3E\\u4F8B\\uFF09\\uFF1AHTML\\uFF08\\\n Hypertext Markup Language\\uFF0C\\u8D85\\u2F42\\u672C\\u6807\\u8BC6\\u8BED\\u2F94\\\n \\uFF09\\u3002\\u7136\\u540E\\u5728\\u4E0B\\u2F42\\u4E2D\\u76F4\\u63A5\\u4F7F\\u2F64\\\n \\u7B80\\u5199\\u5F62 \\u5F0F\\u3002\\u5F53\\u7136\\uFF0C\\u5FC5\\u8981\\u65F6\\u4E5F\\\n \\u53EF\\u4EE5\\u6839\\u636E\\u8BED\\u5883\\u4F7F\\u2F64\\u4E2D\\u3001\\u82F1\\u2F42\\\n \\u5168\\u79F0\\u3002\\n- \\u5173\\u4E8E\\u4EE3\\u7801\\u6E05\\u5355\\u548C\\u4EE3\\\n \\u7801\\u2F5A\\u6BB5\\u3002\\u539F\\u4E66\\u4E2D\\u5305\\u542B\\u7684\\u7A0B\\u5E8F\\\n \\u4EE3\\u7801\\u4E0D\\u8981\\u6C42\\u8BD1\\u8005\\u5F55 \\u2F0A\\uFF0C\\u4F46\\u5E94\\\n \\u8BE5\\u4F7F\\u2F64\\u201C\\u539F\\u4E66P99\\u2EDA\\u4EE3\\u78011\\u201D\\uFF08\\\n \\u5373\\u539F\\u4E66\\u7B2C99\\u2EDA\\u4E2D\\u7684\\u7B2C\\u2F00\\u6BB5\\u4EE3 \\u7801\\\n \\uFF09\\u7684\\u683C\\u5F0F\\u4F5C\\u51FA\\u6807\\u6CE8\\u3002\\u540C\\u65F6\\uFF0C\\\n \\u8BD1\\u8005\\u5E94\\u8BE5\\u5728\\u6709\\u6761\\u4EF6\\u7684\\u60C5\\u51B5\\u4E0B\\\n \\u68C0\\u6838\\u4EE3 \\u7801\\u7684\\u6B63\\u786E\\u6027\\uFF0C\\u5BF9\\u53D1\\u73B0\\\n \\u7684\\u9519\\u8BEF\\u4EE5\\u8BD1\\u8005\\u6CE8\\u5F62\\u5F0F\\u8BF4\\u660E\\u3002\\\n \\u7A0B\\u5E8F\\u4EE3\\u7801\\u4E2D\\u7684\\u6CE8 \\u91CA\\u8981\\u6C42\\u7FFB\\u8BD1\\\n \\uFF0C\\u5982\\u679C\\u8BD1\\u7A3F\\u4E2D\\u6CA1\\u6709\\u4EE3\\u7801\\uFF0C\\u5219\\\n \\u5E94\\u8BE5\\u4EE5\\u2F00\\u53E5\\u82F1\\u2F42\\uFF08\\u6CE8\\u91CA\\uFF09 \\u2F00\\\n \\u53E5\\u4E2D\\u2F42\\uFF08\\u6CE8\\u91CA\\uFF09\\u7684\\u5F62\\u5F0F\\u7ED9\\u51FA\\\n \\u6CE8\\u91CA\\u3002\\n- \\u5173\\u4E8E\\u6807\\u70B9\\u7B26\\u53F7\\u3002\\u8BD1\\\n \\u7A3F\\u4E2D\\u7684\\u6807\\u70B9\\u7B26\\u53F7\\u8981\\u9075\\u5FAA\\u4E2D\\u2F42\\\n \\u8868\\u8FBE\\u4E60\\u60EF\\u548C\\u4E2D\\u2F42\\u6807 \\u70B9\\u7B26\\u53F7\\u7684\\\n \\u4F7F\\u2F64\\u4E60\\u60EF\\uFF0C\\u4E0D\\u80FD\\u7167\\u642C\\u539F\\u2F42\\u7684\\\n \\u6807\\u70B9\\u7B26\\u53F7\\u3002\\n\\n\\n{{#1717916977413.text#}}\\n\\\n \\n{{#1717916955547.item#}}\\n\\n{{#1717916961837.text#}}\\n\\\n \"\n selected: false\n title: 'Problems '\n type: llm\n variables: []\n vision:\n configs:\n detail: high\n enabled: true\n extent: parent\n height: 97\n id: '1717916984996'\n parentId: '1717916955547'\n position:\n x: 725\n y: 85\n positionAbsolute:\n x: 1363\n y: 386.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: ''\n isInIteration: true\n iteration_id: '1717916955547'\n model:\n completion_params:\n temperature: 0.7\n mode: chat\n name: gpt-4o\n provider: openai\n prompt_template:\n - id: 4d7ae758-2d7b-4404-ad9f-d6748ee64439\n role: system\n text: \"\\nBased on the results of the direct translation in the first\\\n \\ step and the problems identified in the second step, re-translate to\\\n \\ achieve a meaning-based interpretation. Ensure the original intent of\\\n \\ the content is preserved while making it easier to understand and more\\\n \\ in line with Chinese expression habits. All the while maintaining the\\\n \\ original format unchanged. \\n\\n\\n- inconsistent with chinese\\\n \\ expression habits, clearly indicate where it does not conform\\n- Clumsy\\\n \\ sentences, specify the location, no need to offer suggestions for modification,\\\n \\ which will be fixed during free translation\\n- Obscure and difficult\\\n \\ to understand, attempts to explain may be made\\n- \\u65E0\\u6F0F\\u8BD1\\\n \\uFF08\\u539F\\u2F42\\u4E2D\\u7684\\u5173\\u952E\\u8BCD\\u3001\\u53E5\\u2F26\\u3001\\\n \\u6BB5\\u843D\\u90FD\\u5E94\\u4F53\\u73B0\\u5728\\u8BD1\\u2F42\\u4E2D\\uFF09\\u3002\\\n \\n- \\u2F46\\u9519\\u8BD1\\uFF08\\u770B\\u9519\\u539F\\u2F42\\u3001\\u8BEF\\u89E3\\\n \\u539F\\u2F42\\u610F\\u601D\\u5747\\u7B97\\u9519\\u8BD1\\uFF09\\u3002\\n- \\u2F46\\\n \\u6709\\u610F\\u589E\\u52A0\\u6216\\u8005\\u5220\\u51CF\\u7684\\u539F\\u2F42\\u5185\\\n \\u5BB9\\uFF08\\u7FFB\\u8BD1\\u5E76\\u2FAE\\u521B\\u4F5C\\uFF0C\\u9700\\u5C0A\\u91CD\\\n \\u4F5C\\u8005\\u89C2 \\u70B9\\uFF1B\\u53EF\\u4EE5\\u9002\\u5F53\\u52A0\\u8BD1\\u8005\\\n \\u6CE8\\u8BF4\\u660E\\uFF09\\u3002\\n- \\u8BD1\\u2F42\\u6D41\\u7545\\uFF0C\\u7B26\\\n \\u5408\\u4E2D\\u2F42\\u8868\\u8FBE\\u4E60\\u60EF\\u3002\\n- \\u5173\\u4E8E\\u2F08\\\n \\u540D\\u7684\\u7FFB\\u8BD1\\u3002\\u6280\\u672F\\u56FE\\u4E66\\u4E2D\\u7684\\u2F08\\\n \\u540D\\u901A\\u5E38\\u4E0D\\u7FFB\\u8BD1\\uFF0C\\u4F46\\u662F\\u2F00\\u4E9B\\u4F17\\\n \\u6240 \\u5468\\u77E5\\u7684\\u2F08\\u540D\\u9700\\u2F64\\u4E2D\\u2F42\\uFF08\\u5982\\\n \\u4E54\\u5E03\\u65AF\\uFF09\\u3002\\n- \\u5173\\u4E8E\\u4E66\\u540D\\u7684\\u7FFB\\\n \\u8BD1\\u3002\\u6709\\u4E2D\\u2F42\\u7248\\u7684\\u56FE\\u4E66\\uFF0C\\u8BF7\\u2F64\\\n \\u4E2D\\u2F42\\u7248\\u4E66\\u540D\\uFF1B\\u2F46\\u4E2D\\u2F42\\u7248 \\u7684\\u56FE\\\n \\u4E66\\uFF0C\\u76F4\\u63A5\\u2F64\\u82F1\\u2F42\\u4E66\\u540D\\u3002\\n- \\u5173\\\n \\u4E8E\\u56FE\\u8868\\u7684\\u7FFB\\u8BD1\\u3002\\u8868\\u683C\\u4E2D\\u7684\\u8868\\\n \\u9898\\u3001\\u8868\\u5B57\\u548C\\u6CE8\\u89E3\\u7B49\\u5747\\u9700\\u7FFB\\u8BD1\\\n \\u3002\\u56FE\\u9898 \\u9700\\u8981\\u7FFB\\u8BD1\\u3002\\u754C\\u2FAF\\u622A\\u56FE\\\n \\u4E0D\\u9700\\u8981\\u7FFB\\u8BD1\\u56FE\\u5B57\\u3002\\u89E3\\u91CA\\u6027\\u56FE\\\n \\u9700\\u8981\\u6309\\u7167\\u4E2D\\u82F1\\u2F42 \\u5BF9\\u7167\\u683C\\u5F0F\\u7ED9\\\n \\u51FA\\u56FE\\u5B57\\u7FFB\\u8BD1\\u3002\\n- \\u5173\\u4E8E\\u82F1\\u2F42\\u672F\\\n \\u8BED\\u7684\\u8868\\u8FF0\\u3002\\u82F1\\u2F42\\u672F\\u8BED\\u2FB8\\u6B21\\u51FA\\\n \\u73B0\\u65F6\\uFF0C\\u5E94\\u8BE5\\u6839\\u636E\\u8BE5\\u672F\\u8BED\\u7684 \\u6D41\\\n \\u2F8F\\u60C5\\u51B5\\uFF0C\\u4F18\\u5148\\u4F7F\\u2F64\\u7B80\\u5199\\u5F62\\u5F0F\\\n \\uFF0C\\u5E76\\u5728\\u5176\\u540E\\u4F7F\\u2F64\\u62EC\\u53F7\\u52A0\\u82F1\\u2F42\\\n \\u3001\\u4E2D\\u2F42 \\u5168\\u79F0\\u6CE8\\u89E3\\uFF0C\\u683C\\u5F0F\\u4E3A\\uFF08\\\n \\u4E3E\\u4F8B\\uFF09\\uFF1AHTML\\uFF08Hypertext Markup Language\\uFF0C\\u8D85\\\n \\u2F42\\u672C\\u6807\\u8BC6\\u8BED\\u2F94\\uFF09\\u3002\\u7136\\u540E\\u5728\\u4E0B\\\n \\u2F42\\u4E2D\\u76F4\\u63A5\\u4F7F\\u2F64\\u7B80\\u5199\\u5F62 \\u5F0F\\u3002\\u5F53\\\n \\u7136\\uFF0C\\u5FC5\\u8981\\u65F6\\u4E5F\\u53EF\\u4EE5\\u6839\\u636E\\u8BED\\u5883\\\n \\u4F7F\\u2F64\\u4E2D\\u3001\\u82F1\\u2F42\\u5168\\u79F0\\u3002\\n- \\u5173\\u4E8E\\\n \\u4EE3\\u7801\\u6E05\\u5355\\u548C\\u4EE3\\u7801\\u2F5A\\u6BB5\\u3002\\u539F\\u4E66\\\n \\u4E2D\\u5305\\u542B\\u7684\\u7A0B\\u5E8F\\u4EE3\\u7801\\u4E0D\\u8981\\u6C42\\u8BD1\\\n \\u8005\\u5F55 \\u2F0A\\uFF0C\\u4F46\\u5E94\\u8BE5\\u4F7F\\u2F64\\u201C\\u539F\\u4E66\\\n P99\\u2EDA\\u4EE3\\u78011\\u201D\\uFF08\\u5373\\u539F\\u4E66\\u7B2C99\\u2EDA\\u4E2D\\\n \\u7684\\u7B2C\\u2F00\\u6BB5\\u4EE3 \\u7801\\uFF09\\u7684\\u683C\\u5F0F\\u4F5C\\u51FA\\\n \\u6807\\u6CE8\\u3002\\u540C\\u65F6\\uFF0C\\u8BD1\\u8005\\u5E94\\u8BE5\\u5728\\u6709\\\n \\u6761\\u4EF6\\u7684\\u60C5\\u51B5\\u4E0B\\u68C0\\u6838\\u4EE3 \\u7801\\u7684\\u6B63\\\n \\u786E\\u6027\\uFF0C\\u5BF9\\u53D1\\u73B0\\u7684\\u9519\\u8BEF\\u4EE5\\u8BD1\\u8005\\\n \\u6CE8\\u5F62\\u5F0F\\u8BF4\\u660E\\u3002\\u7A0B\\u5E8F\\u4EE3\\u7801\\u4E2D\\u7684\\\n \\u6CE8 \\u91CA\\u8981\\u6C42\\u7FFB\\u8BD1\\uFF0C\\u5982\\u679C\\u8BD1\\u7A3F\\u4E2D\\\n \\u6CA1\\u6709\\u4EE3\\u7801\\uFF0C\\u5219\\u5E94\\u8BE5\\u4EE5\\u2F00\\u53E5\\u82F1\\\n \\u2F42\\uFF08\\u6CE8\\u91CA\\uFF09 \\u2F00\\u53E5\\u4E2D\\u2F42\\uFF08\\u6CE8\\u91CA\\\n \\uFF09\\u7684\\u5F62\\u5F0F\\u7ED9\\u51FA\\u6CE8\\u91CA\\u3002\\n- \\u5173\\u4E8E\\\n \\u6807\\u70B9\\u7B26\\u53F7\\u3002\\u8BD1\\u7A3F\\u4E2D\\u7684\\u6807\\u70B9\\u7B26\\\n \\u53F7\\u8981\\u9075\\u5FAA\\u4E2D\\u2F42\\u8868\\u8FBE\\u4E60\\u60EF\\u548C\\u4E2D\\\n \\u2F42\\u6807 \\u70B9\\u7B26\\u53F7\\u7684\\u4F7F\\u2F64\\u4E60\\u60EF\\uFF0C\\u4E0D\\\n \\u80FD\\u7167\\u642C\\u539F\\u2F42\\u7684\\u6807\\u70B9\\u7B26\\u53F7\\u3002\\n\\n\\\n \\n{{#1717916977413.text#}}\\n\\n{{#1717916984996.text#}}\\n\\n{{#1711067409646.input_text#}}\\n\\\n \\n{{#1717916961837.text#}}\\n \"\n selected: false\n title: '2nd Translation '\n type: llm\n variables: []\n vision:\n configs:\n detail: high\n enabled: true\n extent: parent\n height: 97\n id: '1717916991709'\n parentId: '1717916955547'\n position:\n x: 1029\n y: 85\n positionAbsolute:\n x: 1667\n y: 386.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n zIndex: 1002\n - data:\n desc: 'Combine all chunks of translation. '\n selected: false\n template: '{{ translated_text | join('' '') }}'\n title: Template\n type: template-transform\n variables:\n - value_selector:\n - '1717916955547'\n - output\n variable: translated_text\n height: 83\n id: '1717917057450'\n position:\n x: 1987\n y: 301.5\n positionAbsolute:\n x: 1987\n y: 301.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 244\n - data:\n author: Dify\n desc: ''\n height: 186\n selected: false\n showAuthor: true\n text: '{\"root\":{\"children\":[{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Code\n node separates the input_text into chunks with length of token_limit. Each\n chunk overlap with each other to make sure the texts are consistent. \",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"The\n code node outputs an array of segmented texts of input_texts. \",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"root\",\"version\":1}}'\n theme: blue\n title: ''\n type: ''\n width: 340\n height: 186\n id: '1718990593686'\n position:\n x: 259.3026056936437\n y: 451.6924912936374\n positionAbsolute:\n x: 259.3026056936437\n y: 451.6924912936374\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom-note\n width: 340\n - data:\n author: Dify\n desc: ''\n height: 128\n selected: false\n showAuthor: true\n text: '{\"root\":{\"children\":[{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Iterate\n through all the elements in output of the code node and translate each chunk\n using a three steps translation workflow. \",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"root\",\"version\":1}}'\n theme: blue\n title: ''\n type: ''\n width: 355\n height: 128\n id: '1718991836605'\n position:\n x: 764.3891977435923\n y: 530.8917807505335\n positionAbsolute:\n x: 764.3891977435923\n y: 530.8917807505335\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom-note\n width: 355\n - data:\n author: Dify\n desc: ''\n height: 126\n selected: false\n showAuthor: true\n text: '{\"root\":{\"children\":[{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Avoid\n using a high token_limit, LLM''s performance decreases with longer context\n length for gpt-4o. \",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[],\"direction\":null,\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0},{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Recommend\n to use less than or equal to 1000 tokens. \",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1,\"textFormat\":0}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"root\",\"version\":1}}'\n theme: yellow\n title: ''\n type: ''\n width: 351\n height: 126\n id: '1718991882984'\n position:\n x: 304.49115824454367\n y: 148.4042994607805\n positionAbsolute:\n x: 304.49115824454367\n y: 148.4042994607805\n selected: true\n sourcePosition: right\n targetPosition: left\n type: custom-note\n width: 351\n viewport:\n x: 335.92505067152274\n y: 18.806553508850584\n zoom: 0.8705505632961259\n","icon":"\ud83e\udd16","icon_background":"#FFEAD5","id":"98b87f88-bd22-4d86-8b74-86beba5e0ed4","mode":"workflow","name":"Book Translation "}, "cae337e6-aec5-4c7b-beca-d6f1a808bd5e":{ "export_data": "app:\n icon: \"\\U0001F916\"\n icon_background: '#FFEAD5'\n mode: chat\n name: Python bug fixer\nmodel_config:\n agent_mode:\n enabled: false\n max_iteration: 5\n strategy: function_call\n tools: []\n annotation_reply:\n enabled: false\n chat_prompt_config: {}\n completion_prompt_config: {}\n dataset_configs:\n datasets:\n datasets: []\n retrieval_model: single\n dataset_query_variable: ''\n external_data_tools: []\n file_upload:\n image:\n detail: high\n enabled: false\n number_limits: 3\n transfer_methods:\n - remote_url\n - local_file\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n stop: []\n temperature: 0\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n more_like_this:\n enabled: false\n opening_statement: ''\n pre_prompt: Your task is to analyze the provided Python code snippet, identify any\n bugs or errors present, and provide a corrected version of the code that resolves\n these issues. Explain the problems you found in the original code and how your\n fixes address them. The corrected code should be functional, efficient, and adhere\n to best practices in Python programming.\n prompt_type: simple\n retriever_resource:\n enabled: false\n sensitive_word_avoidance:\n configs: []\n enabled: false\n type: ''\n speech_to_text:\n enabled: false\n suggested_questions: []\n suggested_questions_after_answer:\n enabled: false\n text_to_speech:\n enabled: false\n language: ''\n voice: ''\n user_input_form: []\n", "icon": "🤖", @@ -553,15 +553,15 @@ "name": "AI Front-end interviewer" }, "e9870913-dd01-4710-9f06-15d4180ca1ce": { - "export_data": "app:\n icon: \"\\U0001F916\"\n icon_background: '#FFEAD5'\n mode: advanced-chat\n name: 'Knowledge Retreival + Chatbot '\nworkflow:\n features:\n file_upload:\n image:\n enabled: false\n number_limits: 3\n transfer_methods:\n - local_file\n - remote_url\n opening_statement: ''\n retriever_resource:\n enabled: false\n sensitive_word_avoidance:\n enabled: false\n speech_to_text:\n enabled: false\n suggested_questions: []\n suggested_questions_after_answer:\n enabled: false\n text_to_speech:\n enabled: false\n language: ''\n voice: ''\n graph:\n edges:\n - data:\n sourceType: start\n targetType: knowledge-retrieval\n id: 1711528914102-1711528915811\n source: '1711528914102'\n sourceHandle: source\n target: '1711528915811'\n targetHandle: target\n type: custom\n - data:\n sourceType: knowledge-retrieval\n targetType: llm\n id: 1711528915811-1711528917469\n source: '1711528915811'\n sourceHandle: source\n target: '1711528917469'\n targetHandle: target\n type: custom\n - data:\n sourceType: llm\n targetType: answer\n id: 1711528917469-1711528919501\n source: '1711528917469'\n sourceHandle: source\n target: '1711528919501'\n targetHandle: target\n type: custom\n nodes:\n - data:\n desc: ''\n selected: true\n title: Start\n type: start\n variables: []\n height: 53\n id: '1711528914102'\n position:\n x: 79.5\n y: 2634.5\n positionAbsolute:\n x: 79.5\n y: 2634.5\n selected: true\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n dataset_ids:\n - 6084ed3f-d100-4df2-a277-b40d639ea7c6\n desc: Allows you to query text content related to user questions from the\n Knowledge\n query_variable_selector:\n - '1711528914102'\n - sys.query\n retrieval_mode: single\n selected: false\n single_retrieval_config:\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n title: Knowledge Retrieval\n type: knowledge-retrieval\n dragging: false\n height: 101\n id: '1711528915811'\n position:\n x: 362.5\n y: 2634.5\n positionAbsolute:\n x: 362.5\n y: 2634.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: Invoking large language models to answer questions or process natural\n language\n memory:\n role_prefix:\n assistant: ''\n user: ''\n window:\n enabled: false\n size: 50\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - role: system\n text: \"You are a helpful assistant. \\nUse the following context as your\\\n \\ learned knowledge, inside XML tags.\\n\\n\\\n {{#context#}}\\n\\nWhen answer to user:\\n- If you don't know,\\\n \\ just say that you don't know.\\n- If you don't know when you are not\\\n \\ sure, ask for clarification.\\nAvoid mentioning that you obtained the\\\n \\ information from the context.\\nAnd answer according to the language\\\n \\ of the user's question.\"\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n enabled: false\n height: 163\n id: '1711528917469'\n position:\n x: 645.5\n y: 2634.5\n positionAbsolute:\n x: 645.5\n y: 2634.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n answer: '{{#1711528917469.text#}}'\n desc: ''\n selected: false\n title: Answer\n type: answer\n variables: []\n height: 105\n id: '1711528919501'\n position:\n x: 928.5\n y: 2634.5\n positionAbsolute:\n x: 928.5\n y: 2634.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n viewport:\n x: 86.31278232100044\n y: -2276.452137533831\n zoom: 0.9753554615276419\n", + "export_data": "app:\n icon: \"\\U0001F916\"\n icon_background: '#FFEAD5'\n mode: advanced-chat\n name: 'Knowledge Retrieval + Chatbot '\nworkflow:\n features:\n file_upload:\n image:\n enabled: false\n number_limits: 3\n transfer_methods:\n - local_file\n - remote_url\n opening_statement: ''\n retriever_resource:\n enabled: false\n sensitive_word_avoidance:\n enabled: false\n speech_to_text:\n enabled: false\n suggested_questions: []\n suggested_questions_after_answer:\n enabled: false\n text_to_speech:\n enabled: false\n language: ''\n voice: ''\n graph:\n edges:\n - data:\n sourceType: start\n targetType: knowledge-retrieval\n id: 1711528914102-1711528915811\n source: '1711528914102'\n sourceHandle: source\n target: '1711528915811'\n targetHandle: target\n type: custom\n - data:\n sourceType: knowledge-retrieval\n targetType: llm\n id: 1711528915811-1711528917469\n source: '1711528915811'\n sourceHandle: source\n target: '1711528917469'\n targetHandle: target\n type: custom\n - data:\n sourceType: llm\n targetType: answer\n id: 1711528917469-1711528919501\n source: '1711528917469'\n sourceHandle: source\n target: '1711528919501'\n targetHandle: target\n type: custom\n nodes:\n - data:\n desc: ''\n selected: true\n title: Start\n type: start\n variables: []\n height: 53\n id: '1711528914102'\n position:\n x: 79.5\n y: 2634.5\n positionAbsolute:\n x: 79.5\n y: 2634.5\n selected: true\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n dataset_ids:\n - 6084ed3f-d100-4df2-a277-b40d639ea7c6\n desc: Allows you to query text content related to user questions from the\n Knowledge\n query_variable_selector:\n - '1711528914102'\n - sys.query\n retrieval_mode: single\n selected: false\n single_retrieval_config:\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n title: Knowledge Retrieval\n type: knowledge-retrieval\n dragging: false\n height: 101\n id: '1711528915811'\n position:\n x: 362.5\n y: 2634.5\n positionAbsolute:\n x: 362.5\n y: 2634.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: Invoking large language models to answer questions or process natural\n language\n memory:\n role_prefix:\n assistant: ''\n user: ''\n window:\n enabled: false\n size: 50\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - role: system\n text: \"You are a helpful assistant. \\nUse the following context as your\\\n \\ learned knowledge, inside XML tags.\\n\\n\\\n {{#context#}}\\n\\nWhen answer to user:\\n- If you don't know,\\\n \\ just say that you don't know.\\n- If you don't know when you are not\\\n \\ sure, ask for clarification.\\nAvoid mentioning that you obtained the\\\n \\ information from the context.\\nAnd answer according to the language\\\n \\ of the user's question.\"\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n enabled: false\n height: 163\n id: '1711528917469'\n position:\n x: 645.5\n y: 2634.5\n positionAbsolute:\n x: 645.5\n y: 2634.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n answer: '{{#1711528917469.text#}}'\n desc: ''\n selected: false\n title: Answer\n type: answer\n variables: []\n height: 105\n id: '1711528919501'\n position:\n x: 928.5\n y: 2634.5\n positionAbsolute:\n x: 928.5\n y: 2634.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n viewport:\n x: 86.31278232100044\n y: -2276.452137533831\n zoom: 0.9753554615276419\n", "icon": "🤖", "icon_background": "#FFEAD5", "id": "e9870913-dd01-4710-9f06-15d4180ca1ce", "mode": "advanced-chat", - "name": "Knowledge Retreival + Chatbot " + "name": "Knowledge Retrieval + Chatbot " }, "dd5b6353-ae9b-4bce-be6a-a681a12cf709":{ - "export_data": "app:\n icon: \"\\U0001F916\"\n icon_background: '#FFEAD5'\n mode: workflow\n name: 'Email Assistant Workflow '\nworkflow:\n features:\n file_upload:\n image:\n enabled: false\n number_limits: 3\n transfer_methods:\n - local_file\n - remote_url\n opening_statement: ''\n retriever_resource:\n enabled: false\n sensitive_word_avoidance:\n enabled: false\n speech_to_text:\n enabled: false\n suggested_questions: []\n suggested_questions_after_answer:\n enabled: false\n text_to_speech:\n enabled: false\n language: ''\n voice: ''\n graph:\n edges:\n - data:\n sourceType: start\n targetType: question-classifier\n id: 1711511281652-1711512802873\n source: '1711511281652'\n sourceHandle: source\n target: '1711512802873'\n targetHandle: target\n type: custom\n - data:\n sourceType: question-classifier\n targetType: question-classifier\n id: 1711512802873-1711512837494\n source: '1711512802873'\n sourceHandle: '1711512813038'\n target: '1711512837494'\n targetHandle: target\n type: custom\n - data:\n sourceType: question-classifier\n targetType: llm\n id: 1711512802873-1711512911454\n source: '1711512802873'\n sourceHandle: '1711512811520'\n target: '1711512911454'\n targetHandle: target\n type: custom\n - data:\n sourceType: question-classifier\n targetType: llm\n id: 1711512802873-1711512914870\n source: '1711512802873'\n sourceHandle: '1711512812031'\n target: '1711512914870'\n targetHandle: target\n type: custom\n - data:\n sourceType: question-classifier\n targetType: llm\n id: 1711512802873-1711512916516\n source: '1711512802873'\n sourceHandle: '1711512812510'\n target: '1711512916516'\n targetHandle: target\n type: custom\n - data:\n sourceType: question-classifier\n targetType: llm\n id: 1711512837494-1711512924231\n source: '1711512837494'\n sourceHandle: '1711512846439'\n target: '1711512924231'\n targetHandle: target\n type: custom\n - data:\n sourceType: question-classifier\n targetType: llm\n id: 1711512837494-1711512926020\n source: '1711512837494'\n sourceHandle: '1711512847112'\n target: '1711512926020'\n targetHandle: target\n type: custom\n - data:\n sourceType: question-classifier\n targetType: llm\n id: 1711512837494-1711512927569\n source: '1711512837494'\n sourceHandle: '1711512847641'\n target: '1711512927569'\n targetHandle: target\n type: custom\n - data:\n sourceType: question-classifier\n targetType: llm\n id: 1711512837494-1711512929190\n source: '1711512837494'\n sourceHandle: '1711512848120'\n target: '1711512929190'\n targetHandle: target\n type: custom\n - data:\n sourceType: question-classifier\n targetType: llm\n id: 1711512837494-1711512930700\n source: '1711512837494'\n sourceHandle: '1711512848616'\n target: '1711512930700'\n targetHandle: target\n type: custom\n - data:\n sourceType: llm\n targetType: template-transform\n id: 1711512911454-1711513015189\n source: '1711512911454'\n sourceHandle: source\n target: '1711513015189'\n targetHandle: target\n type: custom\n - data:\n sourceType: llm\n targetType: template-transform\n id: 1711512914870-1711513017096\n source: '1711512914870'\n sourceHandle: source\n target: '1711513017096'\n targetHandle: target\n type: custom\n - data:\n sourceType: llm\n targetType: template-transform\n id: 1711512916516-1711513018759\n source: '1711512916516'\n sourceHandle: source\n target: '1711513018759'\n targetHandle: target\n type: custom\n - data:\n sourceType: llm\n targetType: template-transform\n id: 1711512924231-1711513020857\n source: '1711512924231'\n sourceHandle: source\n target: '1711513020857'\n targetHandle: target\n type: custom\n - data:\n sourceType: llm\n targetType: template-transform\n id: 1711512926020-1711513022516\n source: '1711512926020'\n sourceHandle: source\n target: '1711513022516'\n targetHandle: target\n type: custom\n - data:\n sourceType: llm\n targetType: template-transform\n id: 1711512927569-1711513024315\n source: '1711512927569'\n sourceHandle: source\n target: '1711513024315'\n targetHandle: target\n type: custom\n - data:\n sourceType: llm\n targetType: template-transform\n id: 1711512929190-1711513025732\n source: '1711512929190'\n sourceHandle: source\n target: '1711513025732'\n targetHandle: target\n type: custom\n - data:\n sourceType: llm\n targetType: template-transform\n id: 1711512930700-1711513027347\n source: '1711512930700'\n sourceHandle: source\n target: '1711513027347'\n targetHandle: target\n type: custom\n - data:\n sourceType: template-transform\n targetType: end\n id: 1711513015189-1711513029058\n source: '1711513015189'\n sourceHandle: source\n target: '1711513029058'\n targetHandle: target\n type: custom\n - data:\n sourceType: template-transform\n targetType: end\n id: 1711513017096-1711513030924\n source: '1711513017096'\n sourceHandle: source\n target: '1711513030924'\n targetHandle: target\n type: custom\n - data:\n sourceType: template-transform\n targetType: end\n id: 1711513018759-1711513032459\n source: '1711513018759'\n sourceHandle: source\n target: '1711513032459'\n targetHandle: target\n type: custom\n - data:\n sourceType: template-transform\n targetType: end\n id: 1711513020857-1711513034850\n source: '1711513020857'\n sourceHandle: source\n target: '1711513034850'\n targetHandle: target\n type: custom\n - data:\n sourceType: template-transform\n targetType: end\n id: 1711513022516-1711513036356\n source: '1711513022516'\n sourceHandle: source\n target: '1711513036356'\n targetHandle: target\n type: custom\n - data:\n sourceType: template-transform\n targetType: end\n id: 1711513024315-1711513037973\n source: '1711513024315'\n sourceHandle: source\n target: '1711513037973'\n targetHandle: target\n type: custom\n - data:\n sourceType: template-transform\n targetType: end\n id: 1711513025732-1711513039350\n source: '1711513025732'\n sourceHandle: source\n target: '1711513039350'\n targetHandle: target\n type: custom\n - data:\n sourceType: template-transform\n targetType: end\n id: 1711513027347-1711513041219\n source: '1711513027347'\n sourceHandle: source\n target: '1711513041219'\n targetHandle: target\n type: custom\n - data:\n sourceType: question-classifier\n targetType: llm\n id: 1711512802873-1711513940609\n source: '1711512802873'\n sourceHandle: '1711513927279'\n target: '1711513940609'\n targetHandle: target\n type: custom\n - data:\n sourceType: llm\n targetType: template-transform\n id: 1711513940609-1711513967853\n source: '1711513940609'\n sourceHandle: source\n target: '1711513967853'\n targetHandle: target\n type: custom\n - data:\n sourceType: template-transform\n targetType: end\n id: 1711513967853-1711513974643\n source: '1711513967853'\n sourceHandle: source\n target: '1711513974643'\n targetHandle: target\n type: custom\n nodes:\n - data:\n desc: ''\n selected: true\n title: Start\n type: start\n variables:\n - label: Email\n max_length: null\n options: []\n required: true\n type: paragraph\n variable: Input_Text\n - label: What do you need to do? (Summarize / Reply / Write / Improve)\n max_length: 48\n options:\n - Summarize\n - 'Reply '\n - Write a email\n - 'Improve writings '\n required: true\n type: select\n variable: user_request\n - label: 'How do you want it to be polished? (Optional) '\n max_length: 48\n options:\n - 'Imporve writing and clarity '\n - Shorten\n - 'Lengthen '\n - 'Simplify '\n - Rewrite in my voice\n required: false\n type: select\n variable: how_polish\n dragging: false\n height: 141\n id: '1711511281652'\n position:\n x: 79.5\n y: 409.5\n positionAbsolute:\n x: 79.5\n y: 409.5\n selected: true\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n classes:\n - id: '1711512811520'\n name: Summarize\n - id: '1711512812031'\n name: Reply to emails\n - id: '1711512812510'\n name: Help me write the email\n - id: '1711512813038'\n name: Improve writings or polish\n - id: '1711513927279'\n name: Grammer check\n desc: 'Classify users'' demands. '\n instructions: ''\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n query_variable_selector:\n - '1711511281652'\n - user_request\n selected: false\n title: 'Question Classifier '\n topics: []\n type: question-classifier\n dragging: false\n height: 333\n id: '1711512802873'\n position:\n x: 362.5\n y: 409.5\n positionAbsolute:\n x: 362.5\n y: 409.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n classes:\n - id: '1711512846439'\n name: 'Improve writing and clarity '\n - id: '1711512847112'\n name: 'Shorten '\n - id: '1711512847641'\n name: 'Lengthen '\n - id: '1711512848120'\n name: 'Simplify '\n - id: '1711512848616'\n name: Rewrite in my voice\n desc: 'Improve writings. '\n instructions: ''\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n query_variable_selector:\n - '1711511281652'\n - how_polish\n selected: false\n title: 'Question Classifier '\n topics: []\n type: question-classifier\n dragging: false\n height: 333\n id: '1711512837494'\n position:\n x: 645.5\n y: 409.5\n positionAbsolute:\n x: 645.5\n y: 409.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: Summary\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - role: system\n text: ' Summary the email for me. {{#1711511281652.Input_Text#}}\n\n '\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n enabled: false\n dragging: false\n height: 127\n id: '1711512911454'\n position:\n x: 645.5\n y: 1327.5\n positionAbsolute:\n x: 645.5\n y: 1327.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: Reply\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - role: system\n text: ' Rely the emails for me, in my own voice. {{#1711511281652.Input_Text#}}\n\n '\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n enabled: false\n dragging: false\n height: 127\n id: '1711512914870'\n position:\n x: 645.5\n y: 1518.5\n positionAbsolute:\n x: 645.5\n y: 1518.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: Turn idea into email\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - role: system\n text: ' Turn my idea into email. {{#1711511281652.Input_Text#}}\n\n '\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n enabled: false\n dragging: false\n height: 127\n id: '1711512916516'\n position:\n x: 645.5\n y: 1709.5\n positionAbsolute:\n x: 645.5\n y: 1709.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: 'Improve the clarity. '\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - role: system\n text: \" Imporve the clarity of the email for me. \\n{{#1711511281652.Input_Text#}}\\n\\\n \"\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n enabled: false\n dragging: false\n height: 127\n id: '1711512924231'\n position:\n x: 928.5\n y: 409.5\n positionAbsolute:\n x: 928.5\n y: 409.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: 'Shorten. '\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - role: system\n text: ' Shorten the email for me. {{#1711511281652.Input_Text#}}\n\n '\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n enabled: false\n dragging: false\n height: 127\n id: '1711512926020'\n position:\n x: 928.5\n y: 600.5\n positionAbsolute:\n x: 928.5\n y: 600.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: 'Lengthen '\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - role: system\n text: ' Lengthen the email for me. {{#1711511281652.Input_Text#}}\n\n '\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n enabled: false\n dragging: false\n height: 127\n id: '1711512927569'\n position:\n x: 928.5\n y: 791.5\n positionAbsolute:\n x: 928.5\n y: 791.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: Simplify\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - role: system\n text: ' Simplify the email for me. {{#1711511281652.Input_Text#}}\n\n '\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n enabled: false\n dragging: false\n height: 127\n id: '1711512929190'\n position:\n x: 928.5\n y: 982.5\n positionAbsolute:\n x: 928.5\n y: 982.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: Rewrite in my voice\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - role: system\n text: ' Rewrite the email for me. {{#1711511281652.Input_Text#}}\n\n '\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n enabled: false\n dragging: false\n height: 127\n id: '1711512930700'\n position:\n x: 928.5\n y: 1173.5\n positionAbsolute:\n x: 928.5\n y: 1173.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n selected: false\n template: '{{ arg1 }}'\n title: Template\n type: template-transform\n variables:\n - value_selector:\n - '1711512911454'\n - text\n variable: arg1\n dragging: false\n height: 53\n id: '1711513015189'\n position:\n x: 928.5\n y: 1327.5\n positionAbsolute:\n x: 928.5\n y: 1327.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n selected: false\n template: '{{ arg1 }}'\n title: Template 2\n type: template-transform\n variables:\n - value_selector:\n - '1711512914870'\n - text\n variable: arg1\n dragging: false\n height: 53\n id: '1711513017096'\n position:\n x: 928.5\n y: 1518.5\n positionAbsolute:\n x: 928.5\n y: 1518.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n selected: false\n template: '{{ arg1 }}'\n title: Template 3\n type: template-transform\n variables:\n - value_selector:\n - '1711512916516'\n - text\n variable: arg1\n dragging: false\n height: 53\n id: '1711513018759'\n position:\n x: 928.5\n y: 1709.5\n positionAbsolute:\n x: 928.5\n y: 1709.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n selected: false\n template: '{{ arg1 }}'\n title: Template 4\n type: template-transform\n variables:\n - value_selector:\n - '1711512924231'\n - text\n variable: arg1\n dragging: false\n height: 53\n id: '1711513020857'\n position:\n x: 1211.5\n y: 409.5\n positionAbsolute:\n x: 1211.5\n y: 409.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n selected: false\n template: '{{ arg1 }}'\n title: Template 5\n type: template-transform\n variables:\n - value_selector:\n - '1711512926020'\n - text\n variable: arg1\n dragging: false\n height: 53\n id: '1711513022516'\n position:\n x: 1211.5\n y: 600.5\n positionAbsolute:\n x: 1211.5\n y: 600.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n selected: false\n template: '{{ arg1 }}'\n title: Template 6\n type: template-transform\n variables:\n - value_selector:\n - '1711512927569'\n - text\n variable: arg1\n dragging: false\n height: 53\n id: '1711513024315'\n position:\n x: 1211.5\n y: 791.5\n positionAbsolute:\n x: 1211.5\n y: 791.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n selected: false\n template: '{{ arg1 }}'\n title: Template 7\n type: template-transform\n variables:\n - value_selector:\n - '1711512929190'\n - text\n variable: arg1\n dragging: false\n height: 53\n id: '1711513025732'\n position:\n x: 1211.5\n y: 982.5\n positionAbsolute:\n x: 1211.5\n y: 982.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n selected: false\n template: '{{ arg1 }}'\n title: Template 8\n type: template-transform\n variables:\n - value_selector:\n - '1711512930700'\n - text\n variable: arg1\n dragging: false\n height: 53\n id: '1711513027347'\n position:\n x: 1211.5\n y: 1173.5\n positionAbsolute:\n x: 1211.5\n y: 1173.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n outputs:\n - value_selector:\n - '1711512911454'\n - text\n variable: text\n selected: false\n title: End\n type: end\n dragging: false\n height: 89\n id: '1711513029058'\n position:\n x: 1211.5\n y: 1327.5\n positionAbsolute:\n x: 1211.5\n y: 1327.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n outputs:\n - value_selector:\n - '1711512914870'\n - text\n variable: text\n selected: false\n title: End 2\n type: end\n dragging: false\n height: 89\n id: '1711513030924'\n position:\n x: 1211.5\n y: 1518.5\n positionAbsolute:\n x: 1211.5\n y: 1518.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n outputs:\n - value_selector:\n - '1711512916516'\n - text\n variable: text\n selected: false\n title: End 3\n type: end\n dragging: false\n height: 89\n id: '1711513032459'\n position:\n x: 1211.5\n y: 1709.5\n positionAbsolute:\n x: 1211.5\n y: 1709.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n outputs:\n - value_selector:\n - '1711512924231'\n - text\n variable: text\n selected: false\n title: End 4\n type: end\n dragging: false\n height: 89\n id: '1711513034850'\n position:\n x: 1494.5\n y: 409.5\n positionAbsolute:\n x: 1494.5\n y: 409.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n outputs:\n - value_selector:\n - '1711512926020'\n - text\n variable: text\n selected: false\n title: End 5\n type: end\n dragging: false\n height: 89\n id: '1711513036356'\n position:\n x: 1494.5\n y: 600.5\n positionAbsolute:\n x: 1494.5\n y: 600.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n outputs:\n - value_selector:\n - '1711512927569'\n - text\n variable: text\n selected: false\n title: End 6\n type: end\n dragging: false\n height: 89\n id: '1711513037973'\n position:\n x: 1494.5\n y: 791.5\n positionAbsolute:\n x: 1494.5\n y: 791.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n outputs:\n - value_selector:\n - '1711512929190'\n - text\n variable: text\n selected: false\n title: End 7\n type: end\n dragging: false\n height: 89\n id: '1711513039350'\n position:\n x: 1494.5\n y: 982.5\n positionAbsolute:\n x: 1494.5\n y: 982.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n outputs:\n - value_selector:\n - '1711512930700'\n - text\n variable: text\n selected: false\n title: End 8\n type: end\n dragging: false\n height: 89\n id: '1711513041219'\n position:\n x: 1494.5\n y: 1173.5\n positionAbsolute:\n x: 1494.5\n y: 1173.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: Grammer Check\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - role: system\n text: 'Please check grammer of my email and comment on the grammer. {{#1711511281652.Input_Text#}}\n\n '\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n enabled: false\n dragging: false\n height: 127\n id: '1711513940609'\n position:\n x: 645.5\n y: 1900.5\n positionAbsolute:\n x: 645.5\n y: 1900.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n selected: false\n template: '{{ arg1 }}'\n title: Template 9\n type: template-transform\n variables:\n - value_selector:\n - '1711513940609'\n - text\n variable: arg1\n height: 53\n id: '1711513967853'\n position:\n x: 928.5\n y: 1900.5\n positionAbsolute:\n x: 928.5\n y: 1900.5\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n outputs:\n - value_selector:\n - '1711513940609'\n - text\n variable: text\n selected: false\n title: End 9\n type: end\n height: 89\n id: '1711513974643'\n position:\n x: 1211.5\n y: 1900.5\n positionAbsolute:\n x: 1211.5\n y: 1900.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n viewport:\n x: 0\n y: 0\n zoom: 0.7\n", + "export_data": "app:\n icon: \"\\U0001F916\"\n icon_background: '#FFEAD5'\n mode: workflow\n name: 'Email Assistant Workflow '\nworkflow:\n features:\n file_upload:\n image:\n enabled: false\n number_limits: 3\n transfer_methods:\n - local_file\n - remote_url\n opening_statement: ''\n retriever_resource:\n enabled: false\n sensitive_word_avoidance:\n enabled: false\n speech_to_text:\n enabled: false\n suggested_questions: []\n suggested_questions_after_answer:\n enabled: false\n text_to_speech:\n enabled: false\n language: ''\n voice: ''\n graph:\n edges:\n - data:\n sourceType: start\n targetType: question-classifier\n id: 1711511281652-1711512802873\n source: '1711511281652'\n sourceHandle: source\n target: '1711512802873'\n targetHandle: target\n type: custom\n - data:\n sourceType: question-classifier\n targetType: question-classifier\n id: 1711512802873-1711512837494\n source: '1711512802873'\n sourceHandle: '1711512813038'\n target: '1711512837494'\n targetHandle: target\n type: custom\n - data:\n sourceType: question-classifier\n targetType: llm\n id: 1711512802873-1711512911454\n source: '1711512802873'\n sourceHandle: '1711512811520'\n target: '1711512911454'\n targetHandle: target\n type: custom\n - data:\n sourceType: question-classifier\n targetType: llm\n id: 1711512802873-1711512914870\n source: '1711512802873'\n sourceHandle: '1711512812031'\n target: '1711512914870'\n targetHandle: target\n type: custom\n - data:\n sourceType: question-classifier\n targetType: llm\n id: 1711512802873-1711512916516\n source: '1711512802873'\n sourceHandle: '1711512812510'\n target: '1711512916516'\n targetHandle: target\n type: custom\n - data:\n sourceType: question-classifier\n targetType: llm\n id: 1711512837494-1711512924231\n source: '1711512837494'\n sourceHandle: '1711512846439'\n target: '1711512924231'\n targetHandle: target\n type: custom\n - data:\n sourceType: question-classifier\n targetType: llm\n id: 1711512837494-1711512926020\n source: '1711512837494'\n sourceHandle: '1711512847112'\n target: '1711512926020'\n targetHandle: target\n type: custom\n - data:\n sourceType: question-classifier\n targetType: llm\n id: 1711512837494-1711512927569\n source: '1711512837494'\n sourceHandle: '1711512847641'\n target: '1711512927569'\n targetHandle: target\n type: custom\n - data:\n sourceType: question-classifier\n targetType: llm\n id: 1711512837494-1711512929190\n source: '1711512837494'\n sourceHandle: '1711512848120'\n target: '1711512929190'\n targetHandle: target\n type: custom\n - data:\n sourceType: question-classifier\n targetType: llm\n id: 1711512837494-1711512930700\n source: '1711512837494'\n sourceHandle: '1711512848616'\n target: '1711512930700'\n targetHandle: target\n type: custom\n - data:\n sourceType: llm\n targetType: template-transform\n id: 1711512911454-1711513015189\n source: '1711512911454'\n sourceHandle: source\n target: '1711513015189'\n targetHandle: target\n type: custom\n - data:\n sourceType: llm\n targetType: template-transform\n id: 1711512914870-1711513017096\n source: '1711512914870'\n sourceHandle: source\n target: '1711513017096'\n targetHandle: target\n type: custom\n - data:\n sourceType: llm\n targetType: template-transform\n id: 1711512916516-1711513018759\n source: '1711512916516'\n sourceHandle: source\n target: '1711513018759'\n targetHandle: target\n type: custom\n - data:\n sourceType: llm\n targetType: template-transform\n id: 1711512924231-1711513020857\n source: '1711512924231'\n sourceHandle: source\n target: '1711513020857'\n targetHandle: target\n type: custom\n - data:\n sourceType: llm\n targetType: template-transform\n id: 1711512926020-1711513022516\n source: '1711512926020'\n sourceHandle: source\n target: '1711513022516'\n targetHandle: target\n type: custom\n - data:\n sourceType: llm\n targetType: template-transform\n id: 1711512927569-1711513024315\n source: '1711512927569'\n sourceHandle: source\n target: '1711513024315'\n targetHandle: target\n type: custom\n - data:\n sourceType: llm\n targetType: template-transform\n id: 1711512929190-1711513025732\n source: '1711512929190'\n sourceHandle: source\n target: '1711513025732'\n targetHandle: target\n type: custom\n - data:\n sourceType: llm\n targetType: template-transform\n id: 1711512930700-1711513027347\n source: '1711512930700'\n sourceHandle: source\n target: '1711513027347'\n targetHandle: target\n type: custom\n - data:\n sourceType: template-transform\n targetType: end\n id: 1711513015189-1711513029058\n source: '1711513015189'\n sourceHandle: source\n target: '1711513029058'\n targetHandle: target\n type: custom\n - data:\n sourceType: template-transform\n targetType: end\n id: 1711513017096-1711513030924\n source: '1711513017096'\n sourceHandle: source\n target: '1711513030924'\n targetHandle: target\n type: custom\n - data:\n sourceType: template-transform\n targetType: end\n id: 1711513018759-1711513032459\n source: '1711513018759'\n sourceHandle: source\n target: '1711513032459'\n targetHandle: target\n type: custom\n - data:\n sourceType: template-transform\n targetType: end\n id: 1711513020857-1711513034850\n source: '1711513020857'\n sourceHandle: source\n target: '1711513034850'\n targetHandle: target\n type: custom\n - data:\n sourceType: template-transform\n targetType: end\n id: 1711513022516-1711513036356\n source: '1711513022516'\n sourceHandle: source\n target: '1711513036356'\n targetHandle: target\n type: custom\n - data:\n sourceType: template-transform\n targetType: end\n id: 1711513024315-1711513037973\n source: '1711513024315'\n sourceHandle: source\n target: '1711513037973'\n targetHandle: target\n type: custom\n - data:\n sourceType: template-transform\n targetType: end\n id: 1711513025732-1711513039350\n source: '1711513025732'\n sourceHandle: source\n target: '1711513039350'\n targetHandle: target\n type: custom\n - data:\n sourceType: template-transform\n targetType: end\n id: 1711513027347-1711513041219\n source: '1711513027347'\n sourceHandle: source\n target: '1711513041219'\n targetHandle: target\n type: custom\n - data:\n sourceType: question-classifier\n targetType: llm\n id: 1711512802873-1711513940609\n source: '1711512802873'\n sourceHandle: '1711513927279'\n target: '1711513940609'\n targetHandle: target\n type: custom\n - data:\n sourceType: llm\n targetType: template-transform\n id: 1711513940609-1711513967853\n source: '1711513940609'\n sourceHandle: source\n target: '1711513967853'\n targetHandle: target\n type: custom\n - data:\n sourceType: template-transform\n targetType: end\n id: 1711513967853-1711513974643\n source: '1711513967853'\n sourceHandle: source\n target: '1711513974643'\n targetHandle: target\n type: custom\n nodes:\n - data:\n desc: ''\n selected: true\n title: Start\n type: start\n variables:\n - label: Email\n max_length: null\n options: []\n required: true\n type: paragraph\n variable: Input_Text\n - label: What do you need to do? (Summarize / Reply / Write / Improve)\n max_length: 48\n options:\n - Summarize\n - 'Reply '\n - Write a email\n - 'Improve writings '\n required: true\n type: select\n variable: user_request\n - label: 'How do you want it to be polished? (Optional) '\n max_length: 48\n options:\n - 'Imporve writing and clarity '\n - Shorten\n - 'Lengthen '\n - 'Simplify '\n - Rewrite in my voice\n required: false\n type: select\n variable: how_polish\n dragging: false\n height: 141\n id: '1711511281652'\n position:\n x: 79.5\n y: 409.5\n positionAbsolute:\n x: 79.5\n y: 409.5\n selected: true\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n classes:\n - id: '1711512811520'\n name: Summarize\n - id: '1711512812031'\n name: Reply to emails\n - id: '1711512812510'\n name: Help me write the email\n - id: '1711512813038'\n name: Improve writings or polish\n - id: '1711513927279'\n name: Grammar check\n desc: 'Classify users'' demands. '\n instructions: ''\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n query_variable_selector:\n - '1711511281652'\n - user_request\n selected: false\n title: 'Question Classifier '\n topics: []\n type: question-classifier\n dragging: false\n height: 333\n id: '1711512802873'\n position:\n x: 362.5\n y: 409.5\n positionAbsolute:\n x: 362.5\n y: 409.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n classes:\n - id: '1711512846439'\n name: 'Improve writing and clarity '\n - id: '1711512847112'\n name: 'Shorten '\n - id: '1711512847641'\n name: 'Lengthen '\n - id: '1711512848120'\n name: 'Simplify '\n - id: '1711512848616'\n name: Rewrite in my voice\n desc: 'Improve writings. '\n instructions: ''\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n query_variable_selector:\n - '1711511281652'\n - how_polish\n selected: false\n title: 'Question Classifier '\n topics: []\n type: question-classifier\n dragging: false\n height: 333\n id: '1711512837494'\n position:\n x: 645.5\n y: 409.5\n positionAbsolute:\n x: 645.5\n y: 409.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: Summary\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - role: system\n text: ' Summary the email for me. {{#1711511281652.Input_Text#}}\n\n '\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n enabled: false\n dragging: false\n height: 127\n id: '1711512911454'\n position:\n x: 645.5\n y: 1327.5\n positionAbsolute:\n x: 645.5\n y: 1327.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: Reply\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - role: system\n text: ' Rely the emails for me, in my own voice. {{#1711511281652.Input_Text#}}\n\n '\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n enabled: false\n dragging: false\n height: 127\n id: '1711512914870'\n position:\n x: 645.5\n y: 1518.5\n positionAbsolute:\n x: 645.5\n y: 1518.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: Turn idea into email\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - role: system\n text: ' Turn my idea into email. {{#1711511281652.Input_Text#}}\n\n '\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n enabled: false\n dragging: false\n height: 127\n id: '1711512916516'\n position:\n x: 645.5\n y: 1709.5\n positionAbsolute:\n x: 645.5\n y: 1709.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: 'Improve the clarity. '\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - role: system\n text: \" Imporve the clarity of the email for me. \\n{{#1711511281652.Input_Text#}}\\n\\\n \"\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n enabled: false\n dragging: false\n height: 127\n id: '1711512924231'\n position:\n x: 928.5\n y: 409.5\n positionAbsolute:\n x: 928.5\n y: 409.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: 'Shorten. '\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - role: system\n text: ' Shorten the email for me. {{#1711511281652.Input_Text#}}\n\n '\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n enabled: false\n dragging: false\n height: 127\n id: '1711512926020'\n position:\n x: 928.5\n y: 600.5\n positionAbsolute:\n x: 928.5\n y: 600.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: 'Lengthen '\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - role: system\n text: ' Lengthen the email for me. {{#1711511281652.Input_Text#}}\n\n '\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n enabled: false\n dragging: false\n height: 127\n id: '1711512927569'\n position:\n x: 928.5\n y: 791.5\n positionAbsolute:\n x: 928.5\n y: 791.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: Simplify\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - role: system\n text: ' Simplify the email for me. {{#1711511281652.Input_Text#}}\n\n '\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n enabled: false\n dragging: false\n height: 127\n id: '1711512929190'\n position:\n x: 928.5\n y: 982.5\n positionAbsolute:\n x: 928.5\n y: 982.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: Rewrite in my voice\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - role: system\n text: ' Rewrite the email for me. {{#1711511281652.Input_Text#}}\n\n '\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n enabled: false\n dragging: false\n height: 127\n id: '1711512930700'\n position:\n x: 928.5\n y: 1173.5\n positionAbsolute:\n x: 928.5\n y: 1173.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n selected: false\n template: '{{ arg1 }}'\n title: Template\n type: template-transform\n variables:\n - value_selector:\n - '1711512911454'\n - text\n variable: arg1\n dragging: false\n height: 53\n id: '1711513015189'\n position:\n x: 928.5\n y: 1327.5\n positionAbsolute:\n x: 928.5\n y: 1327.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n selected: false\n template: '{{ arg1 }}'\n title: Template 2\n type: template-transform\n variables:\n - value_selector:\n - '1711512914870'\n - text\n variable: arg1\n dragging: false\n height: 53\n id: '1711513017096'\n position:\n x: 928.5\n y: 1518.5\n positionAbsolute:\n x: 928.5\n y: 1518.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n selected: false\n template: '{{ arg1 }}'\n title: Template 3\n type: template-transform\n variables:\n - value_selector:\n - '1711512916516'\n - text\n variable: arg1\n dragging: false\n height: 53\n id: '1711513018759'\n position:\n x: 928.5\n y: 1709.5\n positionAbsolute:\n x: 928.5\n y: 1709.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n selected: false\n template: '{{ arg1 }}'\n title: Template 4\n type: template-transform\n variables:\n - value_selector:\n - '1711512924231'\n - text\n variable: arg1\n dragging: false\n height: 53\n id: '1711513020857'\n position:\n x: 1211.5\n y: 409.5\n positionAbsolute:\n x: 1211.5\n y: 409.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n selected: false\n template: '{{ arg1 }}'\n title: Template 5\n type: template-transform\n variables:\n - value_selector:\n - '1711512926020'\n - text\n variable: arg1\n dragging: false\n height: 53\n id: '1711513022516'\n position:\n x: 1211.5\n y: 600.5\n positionAbsolute:\n x: 1211.5\n y: 600.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n selected: false\n template: '{{ arg1 }}'\n title: Template 6\n type: template-transform\n variables:\n - value_selector:\n - '1711512927569'\n - text\n variable: arg1\n dragging: false\n height: 53\n id: '1711513024315'\n position:\n x: 1211.5\n y: 791.5\n positionAbsolute:\n x: 1211.5\n y: 791.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n selected: false\n template: '{{ arg1 }}'\n title: Template 7\n type: template-transform\n variables:\n - value_selector:\n - '1711512929190'\n - text\n variable: arg1\n dragging: false\n height: 53\n id: '1711513025732'\n position:\n x: 1211.5\n y: 982.5\n positionAbsolute:\n x: 1211.5\n y: 982.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n selected: false\n template: '{{ arg1 }}'\n title: Template 8\n type: template-transform\n variables:\n - value_selector:\n - '1711512930700'\n - text\n variable: arg1\n dragging: false\n height: 53\n id: '1711513027347'\n position:\n x: 1211.5\n y: 1173.5\n positionAbsolute:\n x: 1211.5\n y: 1173.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n outputs:\n - value_selector:\n - '1711512911454'\n - text\n variable: text\n selected: false\n title: End\n type: end\n dragging: false\n height: 89\n id: '1711513029058'\n position:\n x: 1211.5\n y: 1327.5\n positionAbsolute:\n x: 1211.5\n y: 1327.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n outputs:\n - value_selector:\n - '1711512914870'\n - text\n variable: text\n selected: false\n title: End 2\n type: end\n dragging: false\n height: 89\n id: '1711513030924'\n position:\n x: 1211.5\n y: 1518.5\n positionAbsolute:\n x: 1211.5\n y: 1518.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n outputs:\n - value_selector:\n - '1711512916516'\n - text\n variable: text\n selected: false\n title: End 3\n type: end\n dragging: false\n height: 89\n id: '1711513032459'\n position:\n x: 1211.5\n y: 1709.5\n positionAbsolute:\n x: 1211.5\n y: 1709.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n outputs:\n - value_selector:\n - '1711512924231'\n - text\n variable: text\n selected: false\n title: End 4\n type: end\n dragging: false\n height: 89\n id: '1711513034850'\n position:\n x: 1494.5\n y: 409.5\n positionAbsolute:\n x: 1494.5\n y: 409.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n outputs:\n - value_selector:\n - '1711512926020'\n - text\n variable: text\n selected: false\n title: End 5\n type: end\n dragging: false\n height: 89\n id: '1711513036356'\n position:\n x: 1494.5\n y: 600.5\n positionAbsolute:\n x: 1494.5\n y: 600.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n outputs:\n - value_selector:\n - '1711512927569'\n - text\n variable: text\n selected: false\n title: End 6\n type: end\n dragging: false\n height: 89\n id: '1711513037973'\n position:\n x: 1494.5\n y: 791.5\n positionAbsolute:\n x: 1494.5\n y: 791.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n outputs:\n - value_selector:\n - '1711512929190'\n - text\n variable: text\n selected: false\n title: End 7\n type: end\n dragging: false\n height: 89\n id: '1711513039350'\n position:\n x: 1494.5\n y: 982.5\n positionAbsolute:\n x: 1494.5\n y: 982.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n outputs:\n - value_selector:\n - '1711512930700'\n - text\n variable: text\n selected: false\n title: End 8\n type: end\n dragging: false\n height: 89\n id: '1711513041219'\n position:\n x: 1494.5\n y: 1173.5\n positionAbsolute:\n x: 1494.5\n y: 1173.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n context:\n enabled: false\n variable_selector: []\n desc: Grammar Check\n model:\n completion_params:\n frequency_penalty: 0\n max_tokens: 512\n presence_penalty: 0\n temperature: 0.7\n top_p: 1\n mode: chat\n name: gpt-3.5-turbo\n provider: openai\n prompt_template:\n - role: system\n text: 'Please check grammar of my email and comment on the grammar. {{#1711511281652.Input_Text#}}\n\n '\n selected: false\n title: LLM\n type: llm\n variables: []\n vision:\n enabled: false\n dragging: false\n height: 127\n id: '1711513940609'\n position:\n x: 645.5\n y: 1900.5\n positionAbsolute:\n x: 645.5\n y: 1900.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n selected: false\n template: '{{ arg1 }}'\n title: Template 9\n type: template-transform\n variables:\n - value_selector:\n - '1711513940609'\n - text\n variable: arg1\n height: 53\n id: '1711513967853'\n position:\n x: 928.5\n y: 1900.5\n positionAbsolute:\n x: 928.5\n y: 1900.5\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n - data:\n desc: ''\n outputs:\n - value_selector:\n - '1711513940609'\n - text\n variable: text\n selected: false\n title: End 9\n type: end\n height: 89\n id: '1711513974643'\n position:\n x: 1211.5\n y: 1900.5\n positionAbsolute:\n x: 1211.5\n y: 1900.5\n selected: false\n sourcePosition: right\n targetPosition: left\n type: custom\n width: 243\n viewport:\n x: 0\n y: 0\n zoom: 0.7\n", "icon": "🤖", "icon_background": "#FFEAD5", "id": "dd5b6353-ae9b-4bce-be6a-a681a12cf709", diff --git a/api/controllers/console/app/app.py b/api/controllers/console/app/app.py index cc9c8b31cb..1b46a3a7d3 100644 --- a/api/controllers/console/app/app.py +++ b/api/controllers/console/app/app.py @@ -174,6 +174,7 @@ class AppApi(Resource): parser.add_argument("icon", type=str, location="json") parser.add_argument("icon_background", type=str, location="json") parser.add_argument("max_active_requests", type=int, location="json") + parser.add_argument("use_icon_as_answer_icon", type=bool, location="json") args = parser.parse_args() app_service = AppService() diff --git a/api/controllers/console/app/conversation.py b/api/controllers/console/app/conversation.py index 753a6be20c..46c0b22993 100644 --- a/api/controllers/console/app/conversation.py +++ b/api/controllers/console/app/conversation.py @@ -201,7 +201,11 @@ class ChatConversationApi(Resource): start_datetime_timezone = timezone.localize(start_datetime) start_datetime_utc = start_datetime_timezone.astimezone(utc_timezone) - query = query.where(Conversation.created_at >= start_datetime_utc) + match args["sort_by"]: + case "updated_at" | "-updated_at": + query = query.where(Conversation.updated_at >= start_datetime_utc) + case "created_at" | "-created_at" | _: + query = query.where(Conversation.created_at >= start_datetime_utc) if args["end"]: end_datetime = datetime.strptime(args["end"], "%Y-%m-%d %H:%M") @@ -210,7 +214,11 @@ class ChatConversationApi(Resource): end_datetime_timezone = timezone.localize(end_datetime) end_datetime_utc = end_datetime_timezone.astimezone(utc_timezone) - query = query.where(Conversation.created_at < end_datetime_utc) + match args["sort_by"]: + case "updated_at" | "-updated_at": + query = query.where(Conversation.updated_at <= end_datetime_utc) + case "created_at" | "-created_at" | _: + query = query.where(Conversation.created_at <= end_datetime_utc) if args["annotation_status"] == "annotated": query = query.options(joinedload(Conversation.message_annotations)).join( diff --git a/api/controllers/console/app/site.py b/api/controllers/console/app/site.py index f936642acd..26da1ef26d 100644 --- a/api/controllers/console/app/site.py +++ b/api/controllers/console/app/site.py @@ -34,6 +34,7 @@ def parse_app_site_args(): ) parser.add_argument("prompt_public", type=bool, required=False, location="json") parser.add_argument("show_workflow_steps", type=bool, required=False, location="json") + parser.add_argument("use_icon_as_answer_icon", type=bool, required=False, location="json") return parser.parse_args() @@ -68,6 +69,7 @@ class AppSite(Resource): "customize_token_strategy", "prompt_public", "show_workflow_steps", + "use_icon_as_answer_icon", ]: value = args.get(attr_name) if value is not None: diff --git a/api/controllers/console/datasets/datasets.py b/api/controllers/console/datasets/datasets.py index 44c1390c14..6ccacc78ee 100644 --- a/api/controllers/console/datasets/datasets.py +++ b/api/controllers/console/datasets/datasets.py @@ -18,7 +18,7 @@ from core.model_runtime.entities.model_entities import ModelType from core.provider_manager import ProviderManager from core.rag.datasource.vdb.vector_type import VectorType from core.rag.extractor.entity.extract_setting import ExtractSetting -from core.rag.retrieval.retrival_methods import RetrievalMethod +from core.rag.retrieval.retrieval_methods import RetrievalMethod from extensions.ext_database import db from fields.app_fields import related_app_list from fields.dataset_fields import dataset_detail_fields, dataset_query_detail_fields diff --git a/api/controllers/console/datasets/datasets_document.py b/api/controllers/console/datasets/datasets_document.py index 6bc29a8643..076f3cd44d 100644 --- a/api/controllers/console/datasets/datasets_document.py +++ b/api/controllers/console/datasets/datasets_document.py @@ -302,6 +302,8 @@ class DatasetInitApi(Resource): "doc_language", type=str, default="English", required=False, nullable=False, location="json" ) parser.add_argument("retrieval_model", type=dict, required=False, nullable=False, location="json") + parser.add_argument("embedding_model", type=str, required=False, nullable=True, location="json") + parser.add_argument("embedding_model_provider", type=str, required=False, nullable=True, location="json") args = parser.parse_args() # The role of the current user in the ta table must be admin, owner, or editor, or dataset_operator @@ -309,6 +311,8 @@ class DatasetInitApi(Resource): raise Forbidden() if args["indexing_technique"] == "high_quality": + if args["embedding_model"] is None or args["embedding_model_provider"] is None: + raise ValueError("embedding model and embedding model provider are required for high quality indexing.") try: model_manager = ModelManager() model_manager.get_default_model_instance( diff --git a/api/controllers/service_api/dataset/segment.py b/api/controllers/service_api/dataset/segment.py index 5e10f3b48c..e68f6b4dc4 100644 --- a/api/controllers/service_api/dataset/segment.py +++ b/api/controllers/service_api/dataset/segment.py @@ -36,6 +36,10 @@ class SegmentApi(DatasetApiResource): document = DocumentService.get_document(dataset.id, document_id) if not document: raise NotFound("Document not found.") + if document.indexing_status != "completed": + raise NotFound("Document is not completed.") + if not document.enabled: + raise NotFound("Document is disabled.") # check embedding model setting if dataset.indexing_technique == "high_quality": try: @@ -63,7 +67,7 @@ class SegmentApi(DatasetApiResource): segments = SegmentService.multi_create_segment(args["segments"], document, dataset) return {"data": marshal(segments, segment_fields), "doc_form": document.doc_form}, 200 else: - return {"error": "Segemtns is required"}, 400 + return {"error": "Segments is required"}, 400 def get(self, tenant_id, dataset_id, document_id): """Create single segment.""" diff --git a/api/controllers/web/site.py b/api/controllers/web/site.py index 2b4d0e7630..0564b15ea3 100644 --- a/api/controllers/web/site.py +++ b/api/controllers/web/site.py @@ -39,6 +39,7 @@ class AppSiteApi(WebApiResource): "default_language": fields.String, "prompt_public": fields.Boolean, "show_workflow_steps": fields.Boolean, + "use_icon_as_answer_icon": fields.Boolean, } app_fields = { diff --git a/api/core/app/app_config/easy_ui_based_app/dataset/manager.py b/api/core/app/app_config/easy_ui_based_app/dataset/manager.py index a8eb1f9f76..1a621d2090 100644 --- a/api/core/app/app_config/easy_ui_based_app/dataset/manager.py +++ b/api/core/app/app_config/easy_ui_based_app/dataset/manager.py @@ -93,7 +93,7 @@ class DatasetConfigManager: reranking_model=dataset_configs.get('reranking_model'), weights=dataset_configs.get('weights'), reranking_enabled=dataset_configs.get('reranking_enabled', True), - rerank_mode=dataset_configs.get('rerank_mode', 'reranking_model'), + rerank_mode=dataset_configs.get('reranking_mode', 'reranking_model'), ) ) diff --git a/api/core/extension/extensible.py b/api/core/extension/extensible.py index 0296126d8b..8d73aa2b8b 100644 --- a/api/core/extension/extensible.py +++ b/api/core/extension/extensible.py @@ -65,7 +65,7 @@ class Extensible: if os.path.exists(builtin_file_path): with open(builtin_file_path, encoding='utf-8') as f: position = int(f.read().strip()) - position_map[extension_name] = position + position_map[extension_name] = position if (extension_name + '.py') not in file_names: logging.warning(f"Missing {extension_name}.py file in {subdir_path}, Skip.") diff --git a/api/core/helper/position_helper.py b/api/core/helper/position_helper.py index 8cf184ac44..32e3806231 100644 --- a/api/core/helper/position_helper.py +++ b/api/core/helper/position_helper.py @@ -79,7 +79,7 @@ def is_filtered( name_func: Callable[[Any], str], ) -> bool: """ - Chcek if the object should be filtered out. + Check if the object should be filtered out. Overall logic: exclude > include > pin :param include_set: the set of names to be included :param exclude_set: the set of names to be excluded diff --git a/api/core/indexing_runner.py b/api/core/indexing_runner.py index 062666ac6a..df563f609b 100644 --- a/api/core/indexing_runner.py +++ b/api/core/indexing_runner.py @@ -16,9 +16,7 @@ from configs import dify_config from core.errors.error import ProviderTokenNotInitError from core.llm_generator.llm_generator import LLMGenerator from core.model_manager import ModelInstance, ModelManager -from core.model_runtime.entities.model_entities import ModelType, PriceType -from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel -from core.model_runtime.model_providers.__base.text_embedding_model import TextEmbeddingModel +from core.model_runtime.entities.model_entities import ModelType from core.rag.datasource.keyword.keyword_factory import Keyword from core.rag.docstore.dataset_docstore import DatasetDocumentStore from core.rag.extractor.entity.extract_setting import ExtractSetting @@ -255,11 +253,8 @@ class IndexingRunner: tenant_id=tenant_id, model_type=ModelType.TEXT_EMBEDDING, ) - tokens = 0 preview_texts = [] total_segments = 0 - total_price = 0 - currency = 'USD' index_type = doc_form index_processor = IndexProcessorFactory(index_type).init_index_processor() all_text_docs = [] @@ -286,54 +281,22 @@ class IndexingRunner: for document in documents: if len(preview_texts) < 5: preview_texts.append(document.page_content) - if indexing_technique == 'high_quality' or embedding_model_instance: - tokens += embedding_model_instance.get_text_embedding_num_tokens( - texts=[self.filter_string(document.page_content)] - ) if doc_form and doc_form == 'qa_model': - model_instance = self.model_manager.get_default_model_instance( - tenant_id=tenant_id, - model_type=ModelType.LLM - ) - - model_type_instance = model_instance.model_type_instance - model_type_instance = cast(LargeLanguageModel, model_type_instance) if len(preview_texts) > 0: # qa model document response = LLMGenerator.generate_qa_document(current_user.current_tenant_id, preview_texts[0], doc_language) document_qa_list = self.format_split_text(response) - price_info = model_type_instance.get_price( - model=model_instance.model, - credentials=model_instance.credentials, - price_type=PriceType.INPUT, - tokens=total_segments * 2000, - ) + return { "total_segments": total_segments * 20, - "tokens": total_segments * 2000, - "total_price": '{:f}'.format(price_info.total_amount), - "currency": price_info.currency, "qa_preview": document_qa_list, "preview": preview_texts } - if embedding_model_instance: - embedding_model_type_instance = cast(TextEmbeddingModel, embedding_model_instance.model_type_instance) - embedding_price_info = embedding_model_type_instance.get_price( - model=embedding_model_instance.model, - credentials=embedding_model_instance.credentials, - price_type=PriceType.INPUT, - tokens=tokens - ) - total_price = '{:f}'.format(embedding_price_info.total_amount) - currency = embedding_price_info.currency return { "total_segments": total_segments, - "tokens": tokens, - "total_price": total_price, - "currency": currency, "preview": preview_texts } @@ -531,7 +494,7 @@ class IndexingRunner: hash = helper.generate_text_hash(document_node.page_content) document_node.metadata['doc_id'] = doc_id document_node.metadata['doc_hash'] = hash - # delete Spliter character + # delete Splitter character page_content = document_node.page_content if page_content.startswith(".") or page_content.startswith("。"): page_content = page_content[1:] diff --git a/api/core/llm_generator/prompts.py b/api/core/llm_generator/prompts.py index 87361b385a..dbd6e26c7c 100644 --- a/api/core/llm_generator/prompts.py +++ b/api/core/llm_generator/prompts.py @@ -87,7 +87,7 @@ Here is a task description for which I would like you to create a high-quality p {{TASK_DESCRIPTION}} Based on task description, please create a well-structured prompt template that another AI could use to consistently complete the task. The prompt template should include: -- Do not inlcude or section and variables in the prompt, assume user will add them at their own will. +- Do not include or section and variables in the prompt, assume user will add them at their own will. - Clear instructions for the AI that will be using this prompt, demarcated with tags. The instructions should provide step-by-step directions on how to complete the task using the input variables. Also Specifies in the instructions that the output should not contain any xml tag. - Relevant examples if needed to clarify the task further, demarcated with tags. Do not include variables in the prompt. Give three pairs of input and output examples. - Include other relevant sections demarcated with appropriate XML tags like , . diff --git a/api/core/model_runtime/docs/en_US/schema.md b/api/core/model_runtime/docs/en_US/schema.md index 67f4e0879d..f819a4dbdc 100644 --- a/api/core/model_runtime/docs/en_US/schema.md +++ b/api/core/model_runtime/docs/en_US/schema.md @@ -52,7 +52,7 @@ - `mode` (string) voice model.(available for model type `tts`) - `name` (string) voice model display name.(available for model type `tts`) - `language` (string) the voice model supports languages.(available for model type `tts`) - - `word_limit` (int) Single conversion word limit, paragraphwise by default(available for model type `tts`) + - `word_limit` (int) Single conversion word limit, paragraph-wise by default(available for model type `tts`) - `audio_type` (string) Support audio file extension format, e.g.:mp3,wav(available for model type `tts`) - `max_workers` (int) Number of concurrent workers supporting text and audio conversion(available for model type`tts`) - `max_characters_per_chunk` (int) Maximum characters per chunk (available for model type `moderation`) @@ -150,7 +150,7 @@ - `input` (float) Input price, i.e., Prompt price - `output` (float) Output price, i.e., returned content price -- `unit` (float) Pricing unit, e.g., if the price is meausred in 1M tokens, the corresponding token amount for the unit price is `0.000001`. +- `unit` (float) Pricing unit, e.g., if the price is measured in 1M tokens, the corresponding token amount for the unit price is `0.000001`. - `currency` (string) Currency unit ### ProviderCredentialSchema diff --git a/api/core/model_runtime/entities/defaults.py b/api/core/model_runtime/entities/defaults.py index d2076bf74a..e04d9fcbbb 100644 --- a/api/core/model_runtime/entities/defaults.py +++ b/api/core/model_runtime/entities/defaults.py @@ -33,6 +33,22 @@ PARAMETER_RULE_TEMPLATE: dict[DefaultParameterName, dict] = { 'max': 1.0, 'precision': 2, }, + DefaultParameterName.TOP_K: { + 'label': { + 'en_US': 'Top K', + 'zh_Hans': 'Top K', + }, + 'type': 'int', + 'help': { + 'en_US': 'Limits the number of tokens to consider for each step by keeping only the k most likely tokens.', + 'zh_Hans': '通过只保留每一步中最可能的 k 个标记来限制要考虑的标记数量。', + }, + 'required': False, + 'default': 50, + 'min': 1, + 'max': 100, + 'precision': 0, + }, DefaultParameterName.PRESENCE_PENALTY: { 'label': { 'en_US': 'Presence Penalty', diff --git a/api/core/model_runtime/entities/model_entities.py b/api/core/model_runtime/entities/model_entities.py index c257ce63d2..d6377d7e88 100644 --- a/api/core/model_runtime/entities/model_entities.py +++ b/api/core/model_runtime/entities/model_entities.py @@ -85,12 +85,13 @@ class ModelFeature(Enum): STREAM_TOOL_CALL = "stream-tool-call" -class DefaultParameterName(Enum): +class DefaultParameterName(str, Enum): """ Enum class for parameter template variable. """ TEMPERATURE = "temperature" TOP_P = "top_p" + TOP_K = "top_k" PRESENCE_PENALTY = "presence_penalty" FREQUENCY_PENALTY = "frequency_penalty" MAX_TOKENS = "max_tokens" diff --git a/api/core/model_runtime/model_providers/__base/tts_model.py b/api/core/model_runtime/model_providers/__base/tts_model.py index 64e85d2c11..2dfd323a47 100644 --- a/api/core/model_runtime/model_providers/__base/tts_model.py +++ b/api/core/model_runtime/model_providers/__base/tts_model.py @@ -13,7 +13,7 @@ logger = logging.getLogger(__name__) class TTSModel(AIModel): """ - Model class for ttstext model. + Model class for TTS model. """ model_type: ModelType = ModelType.TTS diff --git a/api/core/model_runtime/model_providers/anthropic/anthropic.py b/api/core/model_runtime/model_providers/anthropic/anthropic.py index 00a6bbce3b..325c6c060e 100644 --- a/api/core/model_runtime/model_providers/anthropic/anthropic.py +++ b/api/core/model_runtime/model_providers/anthropic/anthropic.py @@ -19,9 +19,9 @@ class AnthropicProvider(ModelProvider): try: model_instance = self.get_model_instance(ModelType.LLM) - # Use `claude-instant-1` model for validate, + # Use `claude-3-opus-20240229` model for validate, model_instance.validate_credentials( - model='claude-instant-1.2', + model='claude-3-opus-20240229', credentials=credentials ) except CredentialsValidateFailedError as ex: diff --git a/api/core/model_runtime/model_providers/anthropic/llm/claude-instant-1.2.yaml b/api/core/model_runtime/model_providers/anthropic/llm/claude-instant-1.2.yaml index 929a7f8725..ac69bbf4d2 100644 --- a/api/core/model_runtime/model_providers/anthropic/llm/claude-instant-1.2.yaml +++ b/api/core/model_runtime/model_providers/anthropic/llm/claude-instant-1.2.yaml @@ -33,3 +33,4 @@ pricing: output: '5.51' unit: '0.000001' currency: USD +deprecated: true 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 984cca3744..f4f7d964ef 100644 --- a/api/core/model_runtime/model_providers/azure_openai/_constant.py +++ b/api/core/model_runtime/model_providers/azure_openai/_constant.py @@ -637,7 +637,19 @@ LLM_BASE_MODELS = [ en_US='specifying the format that the model must output' ), required=False, - options=['text', 'json_object'] + options=['text', 'json_object', 'json_schema'] + ), + ParameterRule( + name='json_schema', + label=I18nObject( + en_US='JSON Schema' + ), + type='text', + help=I18nObject( + zh_Hans='设置返回的json schema,llm将按照它返回', + en_US='Set a response json schema will ensure LLM to adhere it.' + ), + required=False ), ], pricing=PriceConfig( @@ -800,6 +812,94 @@ LLM_BASE_MODELS = [ ) ) ), + AzureBaseModel( + base_model_name='gpt-4o-2024-08-06', + entity=AIModelEntity( + model='fake-deployment-name', + label=I18nObject( + en_US='fake-deployment-name-label', + ), + model_type=ModelType.LLM, + features=[ + ModelFeature.AGENT_THOUGHT, + ModelFeature.VISION, + ModelFeature.MULTI_TOOL_CALL, + ModelFeature.STREAM_TOOL_CALL, + ], + fetch_from=FetchFrom.CUSTOMIZABLE_MODEL, + model_properties={ + ModelPropertyKey.MODE: LLMMode.CHAT.value, + ModelPropertyKey.CONTEXT_SIZE: 128000, + }, + parameter_rules=[ + ParameterRule( + name='temperature', + **PARAMETER_RULE_TEMPLATE[DefaultParameterName.TEMPERATURE], + ), + ParameterRule( + name='top_p', + **PARAMETER_RULE_TEMPLATE[DefaultParameterName.TOP_P], + ), + ParameterRule( + name='presence_penalty', + **PARAMETER_RULE_TEMPLATE[DefaultParameterName.PRESENCE_PENALTY], + ), + ParameterRule( + name='frequency_penalty', + **PARAMETER_RULE_TEMPLATE[DefaultParameterName.FREQUENCY_PENALTY], + ), + _get_max_tokens(default=512, min_val=1, max_val=4096), + ParameterRule( + name='seed', + label=I18nObject( + zh_Hans='种子', + en_US='Seed' + ), + type='int', + help=I18nObject( + zh_Hans='如果指定,模型将尽最大努力进行确定性采样,使得重复的具有相同种子和参数的请求应该返回相同的结果。不能保证确定性,您应该参考 system_fingerprint 响应参数来监视变化。', + en_US='If specified, model will make a best effort to sample deterministically, such that repeated requests with the same seed and parameters should return the same result. Determinism is not guaranteed, and you should refer to the system_fingerprint response parameter to monitor changes in the backend.' + ), + required=False, + precision=2, + min=0, + max=1, + ), + 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', 'json_schema'] + ), + ParameterRule( + name='json_schema', + label=I18nObject( + en_US='JSON Schema' + ), + type='text', + help=I18nObject( + zh_Hans='设置返回的json schema,llm将按照它返回', + en_US='Set a response json schema will ensure LLM to adhere it.' + ), + required=False + ), + ], + pricing=PriceConfig( + input=5.00, + output=15.00, + unit=0.000001, + currency='USD', + ) + ) + ), AzureBaseModel( base_model_name='gpt-4-turbo', entity=AIModelEntity( 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 be4d4651d7..700935b07b 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 @@ -138,6 +138,12 @@ model_credential_schema: show_on: - variable: __model_type value: llm + - label: + en_US: gpt-4o-2024-08-06 + value: gpt-4o-2024-08-06 + show_on: + - variable: __model_type + value: llm - label: en_US: gpt-4-turbo value: gpt-4-turbo 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 1911caa952..c0c782e42b 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 @@ -1,4 +1,5 @@ import copy +import json import logging from collections.abc import Generator, Sequence from typing import Optional, Union, cast @@ -276,12 +277,18 @@ class AzureOpenAILargeLanguageModel(_CommonAzureOpenAI, LargeLanguageModel): response_format = model_parameters.get("response_format") if response_format: - if response_format == "json_object": - response_format = {"type": "json_object"} + if response_format == "json_schema": + json_schema = model_parameters.get("json_schema") + if not json_schema: + raise ValueError("Must define JSON Schema when the response format is json_schema") + try: + schema = json.loads(json_schema) + except: + raise ValueError(f"not correct json_schema format: {json_schema}") + model_parameters.pop("json_schema") + model_parameters["response_format"] = {"type": "json_schema", "json_schema": schema} else: - response_format = {"type": "text"} - - model_parameters["response_format"] = response_format + model_parameters["response_format"] = {"type": response_format} extra_model_kwargs = {} diff --git a/api/core/model_runtime/model_providers/baichuan/baichuan.yaml b/api/core/model_runtime/model_providers/baichuan/baichuan.yaml index 792126af7f..81e6e36215 100644 --- a/api/core/model_runtime/model_providers/baichuan/baichuan.yaml +++ b/api/core/model_runtime/model_providers/baichuan/baichuan.yaml @@ -27,11 +27,3 @@ provider_credential_schema: placeholder: zh_Hans: 在此输入您的 API Key en_US: Enter your API Key - - variable: secret_key - label: - en_US: Secret Key - type: secret-input - required: false - placeholder: - zh_Hans: 在此输入您的 Secret Key - en_US: Enter your Secret Key diff --git a/api/core/model_runtime/model_providers/baichuan/llm/baichuan2-53b.yaml b/api/core/model_runtime/model_providers/baichuan/llm/baichuan2-53b.yaml index 04849500dc..8360dd5faf 100644 --- a/api/core/model_runtime/model_providers/baichuan/llm/baichuan2-53b.yaml +++ b/api/core/model_runtime/model_providers/baichuan/llm/baichuan2-53b.yaml @@ -43,3 +43,4 @@ parameter_rules: zh_Hans: 允许模型自行进行外部搜索,以增强生成结果。 en_US: Allow the model to perform external search to enhance the generation results. required: false +deprecated: true diff --git a/api/core/model_runtime/model_providers/baichuan/llm/baichuan2-turbo-192k.yaml b/api/core/model_runtime/model_providers/baichuan/llm/baichuan2-turbo-192k.yaml index c8156c152b..0ce0265cfe 100644 --- a/api/core/model_runtime/model_providers/baichuan/llm/baichuan2-turbo-192k.yaml +++ b/api/core/model_runtime/model_providers/baichuan/llm/baichuan2-turbo-192k.yaml @@ -43,3 +43,4 @@ parameter_rules: zh_Hans: 允许模型自行进行外部搜索,以增强生成结果。 en_US: Allow the model to perform external search to enhance the generation results. required: false +deprecated: true diff --git a/api/core/model_runtime/model_providers/baichuan/llm/baichuan2-turbo.yaml b/api/core/model_runtime/model_providers/baichuan/llm/baichuan2-turbo.yaml index f91329c77a..ccb4ee8b92 100644 --- a/api/core/model_runtime/model_providers/baichuan/llm/baichuan2-turbo.yaml +++ b/api/core/model_runtime/model_providers/baichuan/llm/baichuan2-turbo.yaml @@ -4,36 +4,32 @@ label: model_type: llm features: - agent-thought + - multi-tool-call model_properties: mode: chat context_size: 32000 parameter_rules: - name: temperature use_template: temperature + default: 0.3 - name: top_p use_template: top_p + default: 0.85 - name: top_k label: zh_Hans: 取样数量 en_US: Top k type: int + min: 0 + max: 20 + default: 5 help: zh_Hans: 仅从每个后续标记的前 K 个选项中采样。 en_US: Only sample from the top K options for each subsequent token. required: false - name: max_tokens use_template: max_tokens - required: true - default: 8000 - min: 1 - max: 192000 - - name: presence_penalty - use_template: presence_penalty - - name: frequency_penalty - use_template: frequency_penalty - default: 1 - min: 1 - max: 2 + default: 2048 - name: with_search_enhance label: zh_Hans: 搜索增强 diff --git a/api/core/model_runtime/model_providers/baichuan/llm/baichuan3-turbo-128k.yaml b/api/core/model_runtime/model_providers/baichuan/llm/baichuan3-turbo-128k.yaml index bf72e82296..c6c6c7e9e9 100644 --- a/api/core/model_runtime/model_providers/baichuan/llm/baichuan3-turbo-128k.yaml +++ b/api/core/model_runtime/model_providers/baichuan/llm/baichuan3-turbo-128k.yaml @@ -4,36 +4,44 @@ label: model_type: llm features: - agent-thought + - multi-tool-call model_properties: mode: chat context_size: 128000 parameter_rules: - name: temperature use_template: temperature + default: 0.3 - name: top_p use_template: top_p + default: 0.85 - name: top_k label: zh_Hans: 取样数量 en_US: Top k type: int + min: 0 + max: 20 + default: 5 help: zh_Hans: 仅从每个后续标记的前 K 个选项中采样。 en_US: Only sample from the top K options for each subsequent token. required: false - name: max_tokens use_template: max_tokens - required: true - default: 8000 - min: 1 - max: 128000 - - name: presence_penalty - use_template: presence_penalty - - name: frequency_penalty - use_template: frequency_penalty - default: 1 - min: 1 - max: 2 + default: 2048 + - name: res_format + label: + zh_Hans: 回复格式 + en_US: response format + type: string + help: + zh_Hans: 指定模型必须输出的格式 + en_US: specifying the format that the model must output + required: false + options: + - text + - json_object - name: with_search_enhance label: zh_Hans: 搜索增强 diff --git a/api/core/model_runtime/model_providers/baichuan/llm/baichuan3-turbo.yaml b/api/core/model_runtime/model_providers/baichuan/llm/baichuan3-turbo.yaml index 85882519b8..ee8a9ff0d5 100644 --- a/api/core/model_runtime/model_providers/baichuan/llm/baichuan3-turbo.yaml +++ b/api/core/model_runtime/model_providers/baichuan/llm/baichuan3-turbo.yaml @@ -4,36 +4,44 @@ label: model_type: llm features: - agent-thought + - multi-tool-call model_properties: mode: chat context_size: 32000 parameter_rules: - name: temperature use_template: temperature + default: 0.3 - name: top_p use_template: top_p + default: 0.85 - name: top_k label: zh_Hans: 取样数量 en_US: Top k type: int + min: 0 + max: 20 + default: 5 help: zh_Hans: 仅从每个后续标记的前 K 个选项中采样。 en_US: Only sample from the top K options for each subsequent token. required: false - name: max_tokens use_template: max_tokens - required: true - default: 8000 - min: 1 - max: 32000 - - name: presence_penalty - use_template: presence_penalty - - name: frequency_penalty - use_template: frequency_penalty - default: 1 - min: 1 - max: 2 + default: 2048 + - name: res_format + label: + zh_Hans: 回复格式 + en_US: response format + type: string + help: + zh_Hans: 指定模型必须输出的格式 + en_US: specifying the format that the model must output + required: false + options: + - text + - json_object - name: with_search_enhance label: zh_Hans: 搜索增强 diff --git a/api/core/model_runtime/model_providers/baichuan/llm/baichuan4.yaml b/api/core/model_runtime/model_providers/baichuan/llm/baichuan4.yaml index f8c6566081..e5e6aeb491 100644 --- a/api/core/model_runtime/model_providers/baichuan/llm/baichuan4.yaml +++ b/api/core/model_runtime/model_providers/baichuan/llm/baichuan4.yaml @@ -4,36 +4,44 @@ label: model_type: llm features: - agent-thought + - multi-tool-call model_properties: mode: chat context_size: 32000 parameter_rules: - name: temperature use_template: temperature + default: 0.3 - name: top_p use_template: top_p + default: 0.85 - name: top_k label: zh_Hans: 取样数量 en_US: Top k type: int + min: 0 + max: 20 + default: 5 help: zh_Hans: 仅从每个后续标记的前 K 个选项中采样。 en_US: Only sample from the top K options for each subsequent token. required: false - name: max_tokens use_template: max_tokens - required: true - default: 8000 - min: 1 - max: 32000 - - name: presence_penalty - use_template: presence_penalty - - name: frequency_penalty - use_template: frequency_penalty - default: 1 - min: 1 - max: 2 + default: 2048 + - name: res_format + label: + zh_Hans: 回复格式 + en_US: response format + type: string + help: + zh_Hans: 指定模型必须输出的格式 + en_US: specifying the format that the model must output + required: false + options: + - text + - json_object - name: with_search_enhance label: zh_Hans: 搜索增强 diff --git a/api/core/model_runtime/model_providers/baichuan/llm/baichuan_turbo.py b/api/core/model_runtime/model_providers/baichuan/llm/baichuan_turbo.py index d7d8b7c91b..a8fd9dce91 100644 --- a/api/core/model_runtime/model_providers/baichuan/llm/baichuan_turbo.py +++ b/api/core/model_runtime/model_providers/baichuan/llm/baichuan_turbo.py @@ -1,11 +1,10 @@ -from collections.abc import Generator -from enum import Enum -from hashlib import md5 -from json import dumps, loads -from typing import Any, Union +import json +from collections.abc import Iterator +from typing import Any, Optional, Union from requests import post +from core.model_runtime.entities.message_entities import PromptMessageTool from core.model_runtime.model_providers.baichuan.llm.baichuan_turbo_errors import ( BadRequestError, InsufficientAccountBalance, @@ -16,203 +15,133 @@ from core.model_runtime.model_providers.baichuan.llm.baichuan_turbo_errors impor ) -class BaichuanMessage: - class Role(Enum): - USER = 'user' - ASSISTANT = 'assistant' - # Baichuan does not have system message - _SYSTEM = 'system' - - role: str = Role.USER.value - content: str - usage: dict[str, int] = None - stop_reason: str = '' - - def to_dict(self) -> dict[str, Any]: - return { - 'role': self.role, - 'content': self.content, - } - - def __init__(self, content: str, role: str = 'user') -> None: - self.content = content - self.role = role - class BaichuanModel: api_key: str - secret_key: str - def __init__(self, api_key: str, secret_key: str = '') -> None: + def __init__(self, api_key: str) -> None: self.api_key = api_key - self.secret_key = secret_key - def _model_mapping(self, model: str) -> str: + @property + def _model_mapping(self) -> dict: return { - 'baichuan2-turbo': 'Baichuan2-Turbo', - 'baichuan2-turbo-192k': 'Baichuan2-Turbo-192k', - 'baichuan2-53b': 'Baichuan2-53B', - 'baichuan3-turbo': 'Baichuan3-Turbo', - 'baichuan3-turbo-128k': 'Baichuan3-Turbo-128k', - 'baichuan4': 'Baichuan4', - }[model] + "baichuan2-turbo": "Baichuan2-Turbo", + "baichuan3-turbo": "Baichuan3-Turbo", + "baichuan3-turbo-128k": "Baichuan3-Turbo-128k", + "baichuan4": "Baichuan4", + } - def _handle_chat_generate_response(self, response) -> BaichuanMessage: - resp = response.json() - choices = resp.get('choices', []) - message = BaichuanMessage(content='', role='assistant') - for choice in choices: - message.content += choice['message']['content'] - message.role = choice['message']['role'] - if choice['finish_reason']: - message.stop_reason = choice['finish_reason'] + @property + def request_headers(self) -> dict[str, Any]: + return { + "Content-Type": "application/json", + "Authorization": "Bearer " + self.api_key, + } - if 'usage' in resp: - message.usage = { - 'prompt_tokens': resp['usage']['prompt_tokens'], - 'completion_tokens': resp['usage']['completion_tokens'], - 'total_tokens': resp['usage']['total_tokens'], - } + def _build_parameters( + self, + model: str, + stream: bool, + messages: list[dict], + parameters: dict[str, Any], + tools: Optional[list[PromptMessageTool]] = None, + ) -> dict[str, Any]: + if model in self._model_mapping.keys(): + # the LargeLanguageModel._code_block_mode_wrapper() method will remove the response_format of parameters. + # we need to rename it to res_format to get its value + if parameters.get("res_format") == "json_object": + parameters["response_format"] = {"type": "json_object"} - return message - - def _handle_chat_stream_generate_response(self, response) -> Generator: - for line in response.iter_lines(): - if not line: - continue - line = line.decode('utf-8') - # remove the first `data: ` prefix - if line.startswith('data:'): - line = line[5:].strip() - try: - data = loads(line) - except Exception as e: - if line.strip() == '[DONE]': - return - choices = data.get('choices', []) - # save stop reason temporarily - stop_reason = '' - for choice in choices: - if choice.get('finish_reason'): - stop_reason = choice['finish_reason'] + if tools or parameters.get("with_search_enhance") is True: + parameters["tools"] = [] - if len(choice['delta']['content']) == 0: - continue - yield BaichuanMessage(**choice['delta']) - - # if there is usage, the response is the last one, yield it and return - if 'usage' in data: - message = BaichuanMessage(content='', role='assistant') - message.usage = { - 'prompt_tokens': data['usage']['prompt_tokens'], - 'completion_tokens': data['usage']['completion_tokens'], - 'total_tokens': data['usage']['total_tokens'], - } - message.stop_reason = stop_reason - yield message - - def _build_parameters(self, model: str, stream: bool, messages: list[BaichuanMessage], - parameters: dict[str, Any]) \ - -> dict[str, Any]: - if (model == 'baichuan2-turbo' or model == 'baichuan2-turbo-192k' or model == 'baichuan2-53b' - or model == 'baichuan3-turbo' or model == 'baichuan3-turbo-128k' or model == 'baichuan4'): - prompt_messages = [] - for message in messages: - if message.role == BaichuanMessage.Role.USER.value or message.role == BaichuanMessage.Role._SYSTEM.value: - # check if the latest message is a user message - if len(prompt_messages) > 0 and prompt_messages[-1]['role'] == BaichuanMessage.Role.USER.value: - prompt_messages[-1]['content'] += message.content - else: - prompt_messages.append({ - 'content': message.content, - 'role': BaichuanMessage.Role.USER.value, - }) - elif message.role == BaichuanMessage.Role.ASSISTANT.value: - prompt_messages.append({ - 'content': message.content, - 'role': message.role, - }) - # [baichuan] frequency_penalty must be between 1 and 2 - if 'frequency_penalty' in parameters: - if parameters['frequency_penalty'] < 1 or parameters['frequency_penalty'] > 2: - parameters['frequency_penalty'] = 1 + # with_search_enhance is deprecated, use web_search instead + if parameters.get("with_search_enhance") is True: + parameters["tools"].append( + { + "type": "web_search", + "web_search": {"enable": True}, + } + ) + if tools: + for tool in tools: + parameters["tools"].append( + { + "type": "function", + "function": { + "name": tool.name, + "description": tool.description, + "parameters": tool.parameters, + }, + } + ) # turbo api accepts flat parameters return { - 'model': self._model_mapping(model), - 'stream': stream, - 'messages': prompt_messages, + "model": self._model_mapping.get(model), + "stream": stream, + "messages": messages, **parameters, } else: raise BadRequestError(f"Unknown model: {model}") - - def _build_headers(self, model: str, data: dict[str, Any]) -> dict[str, Any]: - if (model == 'baichuan2-turbo' or model == 'baichuan2-turbo-192k' or model == 'baichuan2-53b' - or model == 'baichuan3-turbo' or model == 'baichuan3-turbo-128k' or model == 'baichuan4'): - # there is no secret key for turbo api - return { - 'Content-Type': 'application/json', - 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ', - 'Authorization': 'Bearer ' + self.api_key, - } - else: - raise BadRequestError(f"Unknown model: {model}") - - def _calculate_md5(self, input_string): - return md5(input_string.encode('utf-8')).hexdigest() - def generate(self, model: str, stream: bool, messages: list[BaichuanMessage], - parameters: dict[str, Any], timeout: int) \ - -> Union[Generator, BaichuanMessage]: - - if (model == 'baichuan2-turbo' or model == 'baichuan2-turbo-192k' or model == 'baichuan2-53b' - or model == 'baichuan3-turbo' or model == 'baichuan3-turbo-128k' or model == 'baichuan4'): - api_base = 'https://api.baichuan-ai.com/v1/chat/completions' + def generate( + self, + model: str, + stream: bool, + messages: list[dict], + parameters: dict[str, Any], + timeout: int, + tools: Optional[list[PromptMessageTool]] = None, + ) -> Union[Iterator, dict]: + + if model in self._model_mapping.keys(): + api_base = "https://api.baichuan-ai.com/v1/chat/completions" else: raise BadRequestError(f"Unknown model: {model}") - - try: - data = self._build_parameters(model, stream, messages, parameters) - headers = self._build_headers(model, data) - except KeyError: - raise InternalServerError(f"Failed to build parameters for model: {model}") + + data = self._build_parameters(model, stream, messages, parameters, tools) try: response = post( url=api_base, - headers=headers, - data=dumps(data), + headers=self.request_headers, + data=json.dumps(data), timeout=timeout, - stream=stream + stream=stream, ) except Exception as e: raise InternalServerError(f"Failed to invoke model: {e}") - + if response.status_code != 200: try: resp = response.json() # try to parse error message - err = resp['error']['code'] - msg = resp['error']['message'] + err = resp["error"]["type"] + msg = resp["error"]["message"] except Exception as e: - raise InternalServerError(f"Failed to convert response to json: {e} with text: {response.text}") + raise InternalServerError( + f"Failed to convert response to json: {e} with text: {response.text}" + ) - if err == 'invalid_api_key': + if err == "invalid_api_key": raise InvalidAPIKeyError(msg) - elif err == 'insufficient_quota': + elif err == "insufficient_quota": raise InsufficientAccountBalance(msg) - elif err == 'invalid_authentication': + elif err == "invalid_authentication": raise InvalidAuthenticationError(msg) - elif 'rate' in err: + elif err == "invalid_request_error": + raise BadRequestError(msg) + elif "rate" in err: raise RateLimitReachedError(msg) - elif 'internal' in err: + elif "internal" in err: raise InternalServerError(msg) - elif err == 'api_key_empty': + elif err == "api_key_empty": raise InvalidAPIKeyError(msg) else: raise InternalServerError(f"Unknown error: {err} with message: {msg}") - + if stream: - return self._handle_chat_stream_generate_response(response) + return response.iter_lines() else: - return self._handle_chat_generate_response(response) \ No newline at end of file + return response.json() diff --git a/api/core/model_runtime/model_providers/baichuan/llm/llm.py b/api/core/model_runtime/model_providers/baichuan/llm/llm.py index edcd3af420..36c7003d1b 100644 --- a/api/core/model_runtime/model_providers/baichuan/llm/llm.py +++ b/api/core/model_runtime/model_providers/baichuan/llm/llm.py @@ -1,7 +1,12 @@ -from collections.abc import Generator +import json +from collections.abc import Generator, Iterator from typing import cast -from core.model_runtime.entities.llm_entities import LLMResult, LLMResultChunk, LLMResultChunkDelta +from core.model_runtime.entities.llm_entities import ( + LLMResult, + LLMResultChunk, + LLMResultChunkDelta, +) from core.model_runtime.entities.message_entities import ( AssistantPromptMessage, PromptMessage, @@ -21,7 +26,7 @@ from core.model_runtime.errors.invoke import ( 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.baichuan.llm.baichuan_tokenizer import BaichuanTokenizer -from core.model_runtime.model_providers.baichuan.llm.baichuan_turbo import BaichuanMessage, BaichuanModel +from core.model_runtime.model_providers.baichuan.llm.baichuan_turbo import BaichuanModel from core.model_runtime.model_providers.baichuan.llm.baichuan_turbo_errors import ( BadRequestError, InsufficientAccountBalance, @@ -32,20 +37,41 @@ from core.model_runtime.model_providers.baichuan.llm.baichuan_turbo_errors impor ) -class BaichuanLarguageModel(LargeLanguageModel): - def _invoke(self, model: str, credentials: dict, - prompt_messages: list[PromptMessage], model_parameters: dict, - tools: list[PromptMessageTool] | None = None, stop: list[str] | None = None, - stream: bool = True, user: str | None = None) \ - -> LLMResult | Generator: - return self._generate(model=model, credentials=credentials, prompt_messages=prompt_messages, - model_parameters=model_parameters, tools=tools, stop=stop, stream=stream, user=user) +class BaichuanLanguageModel(LargeLanguageModel): - def get_num_tokens(self, model: str, credentials: dict, prompt_messages: list[PromptMessage], - tools: list[PromptMessageTool] | None = None) -> int: + def _invoke( + self, + model: str, + credentials: dict, + prompt_messages: list[PromptMessage], + model_parameters: dict, + tools: list[PromptMessageTool] | None = None, + stop: list[str] | None = None, + stream: bool = True, + user: str | None = None, + ) -> LLMResult | Generator: + return self._generate( + model=model, + credentials=credentials, + prompt_messages=prompt_messages, + model_parameters=model_parameters, + tools=tools, + stream=stream, + ) + + def get_num_tokens( + self, + model: str, + credentials: dict, + prompt_messages: list[PromptMessage], + tools: list[PromptMessageTool] | None = None, + ) -> int: return self._num_tokens_from_messages(prompt_messages) - def _num_tokens_from_messages(self, messages: list[PromptMessage], ) -> int: + def _num_tokens_from_messages( + self, + messages: list[PromptMessage], + ) -> int: """Calculate num tokens for baichuan model""" def tokens(text: str): @@ -59,10 +85,10 @@ class BaichuanLarguageModel(LargeLanguageModel): num_tokens += tokens_per_message for key, value in message.items(): if isinstance(value, list): - text = '' + text = "" for item in value: - if isinstance(item, dict) and item['type'] == 'text': - text += item['text'] + if isinstance(item, dict) and item["type"] == "text": + text += item["text"] value = text @@ -84,19 +110,18 @@ class BaichuanLarguageModel(LargeLanguageModel): elif isinstance(message, AssistantPromptMessage): message = cast(AssistantPromptMessage, message) message_dict = {"role": "assistant", "content": message.content} + if message.tool_calls: + message_dict["tool_calls"] = [tool_call.dict() for tool_call in + message.tool_calls] elif isinstance(message, SystemPromptMessage): message = cast(SystemPromptMessage, message) - message_dict = {"role": "user", "content": message.content} + message_dict = {"role": "system", "content": message.content} elif isinstance(message, ToolPromptMessage): - # copy from core/model_runtime/model_providers/anthropic/llm/llm.py message = cast(ToolPromptMessage, message) message_dict = { - "role": "user", - "content": [{ - "type": "tool_result", - "tool_use_id": message.tool_call_id, - "content": message.content - }] + "role": "tool", + "content": message.content, + "tool_call_id": message.tool_call_id } else: raise ValueError(f"Unknown message type {type(message)}") @@ -105,102 +130,159 @@ class BaichuanLarguageModel(LargeLanguageModel): def validate_credentials(self, model: str, credentials: dict) -> None: # ping - instance = BaichuanModel( - api_key=credentials['api_key'], - secret_key=credentials.get('secret_key', '') - ) + instance = BaichuanModel(api_key=credentials["api_key"]) try: - instance.generate(model=model, stream=False, messages=[ - BaichuanMessage(content='ping', role='user') - ], parameters={ - 'max_tokens': 1, - }, timeout=60) + instance.generate( + model=model, + stream=False, + messages=[{"content": "ping", "role": "user"}], + parameters={ + "max_tokens": 1, + }, + timeout=60, + ) except Exception as e: raise CredentialsValidateFailedError(f"Invalid API key: {e}") - def _generate(self, model: str, credentials: dict, prompt_messages: list[PromptMessage], - model_parameters: dict, tools: list[PromptMessageTool] | None = None, - stop: list[str] | None = None, stream: bool = True, user: str | None = None) \ - -> LLMResult | Generator: - if tools is not None and len(tools) > 0: - raise InvokeBadRequestError("Baichuan model doesn't support tools") + def _generate( + self, + model: str, + credentials: dict, + prompt_messages: list[PromptMessage], + model_parameters: dict, + tools: list[PromptMessageTool] | None = None, + stream: bool = True, + ) -> LLMResult | Generator: - instance = BaichuanModel( - api_key=credentials['api_key'], - secret_key=credentials.get('secret_key', '') - ) - - # convert prompt messages to baichuan messages - messages = [ - BaichuanMessage( - content=message.content if isinstance(message.content, str) else ''.join([ - content.data for content in message.content - ]), - role=message.role.value - ) for message in prompt_messages - ] + instance = BaichuanModel(api_key=credentials["api_key"]) + messages = [self._convert_prompt_message_to_dict(m) for m in prompt_messages] # invoke model - response = instance.generate(model=model, stream=stream, messages=messages, parameters=model_parameters, - timeout=60) + response = instance.generate( + model=model, + stream=stream, + messages=messages, + parameters=model_parameters, + timeout=60, + tools=tools, + ) if stream: - return self._handle_chat_generate_stream_response(model, prompt_messages, credentials, response) + return self._handle_chat_generate_stream_response( + model, prompt_messages, credentials, response + ) - return self._handle_chat_generate_response(model, prompt_messages, credentials, response) + return self._handle_chat_generate_response( + model, prompt_messages, credentials, response + ) + + def _handle_chat_generate_response( + self, + model: str, + prompt_messages: list[PromptMessage], + credentials: dict, + response: dict, + ) -> LLMResult: + choices = response.get("choices", []) + assistant_message = AssistantPromptMessage(content='', tool_calls=[]) + if choices and choices[0]["finish_reason"] == "tool_calls": + for choice in choices: + for tool_call in choice["message"]["tool_calls"]: + tool = AssistantPromptMessage.ToolCall( + id=tool_call.get("id", ""), + type=tool_call.get("type", ""), + function=AssistantPromptMessage.ToolCall.ToolCallFunction( + name=tool_call.get("function", {}).get("name", ""), + arguments=tool_call.get("function", {}).get("arguments", "") + ), + ) + assistant_message.tool_calls.append(tool) + else: + for choice in choices: + assistant_message.content += choice["message"]["content"] + assistant_message.role = choice["message"]["role"] + + usage = response.get("usage") + if usage: + # transform usage + prompt_tokens = usage["prompt_tokens"] + completion_tokens = usage["completion_tokens"] + else: + # calculate num tokens + prompt_tokens = self._num_tokens_from_messages(prompt_messages) + completion_tokens = self._num_tokens_from_messages([assistant_message]) + + usage = self._calc_response_usage( + model=model, + credentials=credentials, + prompt_tokens=prompt_tokens, + completion_tokens=completion_tokens, + ) - def _handle_chat_generate_response(self, model: str, - prompt_messages: list[PromptMessage], - credentials: dict, - response: BaichuanMessage) -> LLMResult: - # convert baichuan message to llm result - usage = self._calc_response_usage(model=model, credentials=credentials, - prompt_tokens=response.usage['prompt_tokens'], - completion_tokens=response.usage['completion_tokens']) return LLMResult( model=model, prompt_messages=prompt_messages, - message=AssistantPromptMessage( - content=response.content, - tool_calls=[] - ), + message=assistant_message, usage=usage, ) - def _handle_chat_generate_stream_response(self, model: str, - prompt_messages: list[PromptMessage], - credentials: dict, - response: Generator[BaichuanMessage, None, None]) -> Generator: - for message in response: - if message.usage: - usage = self._calc_response_usage(model=model, credentials=credentials, - prompt_tokens=message.usage['prompt_tokens'], - completion_tokens=message.usage['completion_tokens']) + def _handle_chat_generate_stream_response( + self, + model: str, + prompt_messages: list[PromptMessage], + credentials: dict, + response: Iterator, + ) -> Generator: + for line in response: + if not line: + continue + line = line.decode("utf-8") + # remove the first `data: ` prefix + if line.startswith("data:"): + line = line[5:].strip() + try: + data = json.loads(line) + except Exception as e: + if line.strip() == "[DONE]": + return + choices = data.get("choices", []) + + stop_reason = "" + for choice in choices: + if choice.get("finish_reason"): + stop_reason = choice["finish_reason"] + + if len(choice["delta"]["content"]) == 0: + continue yield LLMResultChunk( model=model, prompt_messages=prompt_messages, delta=LLMResultChunkDelta( index=0, message=AssistantPromptMessage( - content=message.content, - tool_calls=[] + content=choice["delta"]["content"], tool_calls=[] ), - usage=usage, - finish_reason=message.stop_reason if message.stop_reason else None, + finish_reason=stop_reason, ), ) - else: + + # if there is usage, the response is the last one, yield it and return + if "usage" in data: + usage = self._calc_response_usage( + model=model, + credentials=credentials, + prompt_tokens=data["usage"]["prompt_tokens"], + completion_tokens=data["usage"]["completion_tokens"], + ) yield LLMResultChunk( model=model, prompt_messages=prompt_messages, delta=LLMResultChunkDelta( index=0, - message=AssistantPromptMessage( - content=message.content, - tool_calls=[] - ), - finish_reason=message.stop_reason if message.stop_reason else None, + message=AssistantPromptMessage(content="", tool_calls=[]), + usage=usage, + finish_reason=stop_reason, ), ) @@ -215,21 +297,13 @@ class BaichuanLarguageModel(LargeLanguageModel): :return: Invoke error mapping """ return { - InvokeConnectionError: [ - ], - InvokeServerUnavailableError: [ - InternalServerError - ], - InvokeRateLimitError: [ - RateLimitReachedError - ], + InvokeConnectionError: [], + InvokeServerUnavailableError: [InternalServerError], + InvokeRateLimitError: [RateLimitReachedError], InvokeAuthorizationError: [ InvalidAuthenticationError, InsufficientAccountBalance, InvalidAPIKeyError, ], - InvokeBadRequestError: [ - BadRequestError, - KeyError - ] + InvokeBadRequestError: [BadRequestError, KeyError], } diff --git a/api/core/model_runtime/model_providers/baichuan/text_embedding/text_embedding.py b/api/core/model_runtime/model_providers/baichuan/text_embedding/text_embedding.py index 5ae90d54b5..81bd58e3ce 100644 --- a/api/core/model_runtime/model_providers/baichuan/text_embedding/text_embedding.py +++ b/api/core/model_runtime/model_providers/baichuan/text_embedding/text_embedding.py @@ -60,7 +60,7 @@ class BaichuanTextEmbeddingModel(TextEmbeddingModel): token_usage = 0 for chunk in chunks: - # embeding chunk + # embedding chunk chunk_embeddings, chunk_usage = self.embedding( model=model, api_key=api_key, 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 3f7266f600..c325ac3cec 100644 --- a/api/core/model_runtime/model_providers/bedrock/llm/llm.py +++ b/api/core/model_runtime/model_providers/bedrock/llm/llm.py @@ -793,11 +793,11 @@ class BedrockLargeLanguageModel(LargeLanguageModel): def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[Exception]]]: """ Map model invoke error to unified error - The key is the ermd = genai.GenerativeModel(model)ror type thrown to the caller - The value is the md = genai.GenerativeModel(model)error type thrown by the model, + The key is the ermd = genai.GenerativeModel(model) error type thrown to the caller + The value is the md = genai.GenerativeModel(model) error type thrown by the model, which needs to be converted into a unified error type for the caller. - :return: Invoke emd = genai.GenerativeModel(model)rror mapping + :return: Invoke emd = genai.GenerativeModel(model) error mapping """ return { InvokeConnectionError: [], diff --git a/api/core/model_runtime/model_providers/bedrock/text_embedding/text_embedding.py b/api/core/model_runtime/model_providers/bedrock/text_embedding/text_embedding.py index 993416cdc8..ef22a9c868 100644 --- a/api/core/model_runtime/model_providers/bedrock/text_embedding/text_embedding.py +++ b/api/core/model_runtime/model_providers/bedrock/text_embedding/text_embedding.py @@ -130,11 +130,11 @@ class BedrockTextEmbeddingModel(TextEmbeddingModel): def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[Exception]]]: """ Map model invoke error to unified error - The key is the ermd = genai.GenerativeModel(model)ror type thrown to the caller - The value is the md = genai.GenerativeModel(model)error type thrown by the model, + The key is the ermd = genai.GenerativeModel(model) error type thrown to the caller + The value is the md = genai.GenerativeModel(model) error type thrown by the model, which needs to be converted into a unified error type for the caller. - :return: Invoke emd = genai.GenerativeModel(model)rror mapping + :return: Invoke emd = genai.GenerativeModel(model) error mapping """ return { InvokeConnectionError: [], diff --git a/api/core/model_runtime/model_providers/fishaudio/__init__.py b/api/core/model_runtime/model_providers/fishaudio/__init__.py new file mode 100644 index 0000000000..5f282702bb --- /dev/null +++ b/api/core/model_runtime/model_providers/fishaudio/__init__.py @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/api/core/model_runtime/model_providers/fishaudio/_assets/fishaudio_l_en.svg b/api/core/model_runtime/model_providers/fishaudio/_assets/fishaudio_l_en.svg new file mode 100644 index 0000000000..d6f7723bd5 --- /dev/null +++ b/api/core/model_runtime/model_providers/fishaudio/_assets/fishaudio_l_en.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/api/core/model_runtime/model_providers/fishaudio/_assets/fishaudio_s_en.svg b/api/core/model_runtime/model_providers/fishaudio/_assets/fishaudio_s_en.svg new file mode 100644 index 0000000000..d6f7723bd5 --- /dev/null +++ b/api/core/model_runtime/model_providers/fishaudio/_assets/fishaudio_s_en.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/api/core/model_runtime/model_providers/fishaudio/fishaudio.py b/api/core/model_runtime/model_providers/fishaudio/fishaudio.py new file mode 100644 index 0000000000..9f80996d9d --- /dev/null +++ b/api/core/model_runtime/model_providers/fishaudio/fishaudio.py @@ -0,0 +1,28 @@ +import logging + +from core.model_runtime.entities.model_entities import ModelType +from core.model_runtime.errors.validate import CredentialsValidateFailedError +from core.model_runtime.model_providers.__base.model_provider import ModelProvider + +logger = logging.getLogger(__name__) + + +class FishAudioProvider(ModelProvider): + def validate_provider_credentials(self, credentials: dict) -> None: + """ + Validate provider credentials + + For debugging purposes, this method now always passes validation. + + :param credentials: provider credentials, credentials form defined in `provider_credential_schema`. + """ + try: + model_instance = self.get_model_instance(ModelType.TTS) + model_instance.validate_credentials( + credentials=credentials + ) + except CredentialsValidateFailedError as ex: + raise ex + except Exception as ex: + logger.exception(f'{self.get_provider_schema().provider} credentials validate failed') + raise ex diff --git a/api/core/model_runtime/model_providers/fishaudio/fishaudio.yaml b/api/core/model_runtime/model_providers/fishaudio/fishaudio.yaml new file mode 100644 index 0000000000..479eb7fb85 --- /dev/null +++ b/api/core/model_runtime/model_providers/fishaudio/fishaudio.yaml @@ -0,0 +1,76 @@ +provider: fishaudio +label: + en_US: Fish Audio +description: + en_US: Models provided by Fish Audio, currently only support TTS. + zh_Hans: Fish Audio 提供的模型,目前仅支持 TTS。 +icon_small: + en_US: fishaudio_s_en.svg +icon_large: + en_US: fishaudio_l_en.svg +background: "#E5E7EB" +help: + title: + en_US: Get your API key from Fish Audio + zh_Hans: 从 Fish Audio 获取你的 API Key + url: + en_US: https://fish.audio/go-api/ +supported_model_types: + - tts +configurate_methods: + - predefined-model +provider_credential_schema: + credential_form_schemas: + - variable: api_key + label: + en_US: API Key + type: secret-input + required: true + placeholder: + zh_Hans: 在此输入您的 API Key + en_US: Enter your API Key + - variable: api_base + label: + en_US: API URL + type: text-input + required: false + default: https://api.fish.audio + placeholder: + en_US: Enter your API URL + zh_Hans: 在此输入您的 API URL + - variable: use_public_models + label: + en_US: Use Public Models + type: select + required: false + default: "false" + placeholder: + en_US: Toggle to use public models + zh_Hans: 切换以使用公共模型 + options: + - value: "true" + label: + en_US: Allow Public Models + zh_Hans: 使用公共模型 + - value: "false" + label: + en_US: Private Models Only + zh_Hans: 仅使用私有模型 + - variable: latency + label: + en_US: Latency + type: select + required: false + default: "normal" + placeholder: + en_US: Toggle to choice latency + zh_Hans: 切换以调整延迟 + options: + - value: "balanced" + label: + en_US: Low (may affect quality) + zh_Hans: 低延迟 (可能降低质量) + - value: "normal" + label: + en_US: Normal + zh_Hans: 标准 diff --git a/api/core/model_runtime/model_providers/fishaudio/tts/__init__.py b/api/core/model_runtime/model_providers/fishaudio/tts/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/core/model_runtime/model_providers/fishaudio/tts/tts.py b/api/core/model_runtime/model_providers/fishaudio/tts/tts.py new file mode 100644 index 0000000000..5b673ce186 --- /dev/null +++ b/api/core/model_runtime/model_providers/fishaudio/tts/tts.py @@ -0,0 +1,174 @@ +from typing import Optional + +import httpx + +from core.model_runtime.errors.invoke import InvokeBadRequestError, InvokeError +from core.model_runtime.errors.validate import CredentialsValidateFailedError +from core.model_runtime.model_providers.__base.tts_model import TTSModel + + +class FishAudioText2SpeechModel(TTSModel): + """ + Model class for Fish.audio Text to Speech model. + """ + + def get_tts_model_voices( + self, model: str, credentials: dict, language: Optional[str] = None + ) -> list: + api_base = credentials.get("api_base", "https://api.fish.audio") + api_key = credentials.get("api_key") + use_public_models = credentials.get("use_public_models", "false") == "true" + + params = { + "self": str(not use_public_models).lower(), + "page_size": "100", + } + + if language is not None: + if "-" in language: + language = language.split("-")[0] + params["language"] = language + + results = httpx.get( + f"{api_base}/model", + headers={"Authorization": f"Bearer {api_key}"}, + params=params, + ) + + results.raise_for_status() + data = results.json() + + return [{"name": i["title"], "value": i["_id"]} for i in data["items"]] + + def _invoke( + self, + model: str, + tenant_id: str, + credentials: dict, + content_text: str, + voice: str, + user: Optional[str] = None, + ) -> any: + """ + Invoke text2speech model + + :param model: model name + :param tenant_id: user tenant id + :param credentials: model credentials + :param voice: model timbre + :param content_text: text content to be translated + :param user: unique user id + :return: generator yielding audio chunks + """ + + return self._tts_invoke_streaming( + model=model, + credentials=credentials, + content_text=content_text, + voice=voice, + ) + + def validate_credentials( + self, credentials: dict, user: Optional[str] = None + ) -> None: + """ + Validate credentials for text2speech model + + :param credentials: model credentials + :param user: unique user id + """ + + try: + self.get_tts_model_voices( + None, + credentials={ + "api_key": credentials["api_key"], + "api_base": credentials["api_base"], + # Disable public models will trigger a 403 error if user is not logged in + "use_public_models": "false", + }, + ) + except Exception as ex: + raise CredentialsValidateFailedError(str(ex)) + + def _tts_invoke_streaming( + self, model: str, credentials: dict, content_text: str, voice: str + ) -> any: + """ + Invoke streaming text2speech model + :param model: model name + :param credentials: model credentials + :param content_text: text content to be translated + :param voice: ID of the reference audio (if any) + :return: generator yielding audio chunks + """ + + try: + word_limit = self._get_model_word_limit(model, credentials) + if len(content_text) > word_limit: + sentences = self._split_text_into_sentences( + content_text, max_length=word_limit + ) + else: + sentences = [content_text.strip()] + + for i in range(len(sentences)): + yield from self._tts_invoke_streaming_sentence( + credentials=credentials, content_text=sentences[i], voice=voice + ) + + except Exception as ex: + raise InvokeBadRequestError(str(ex)) + + def _tts_invoke_streaming_sentence( + self, credentials: dict, content_text: str, voice: Optional[str] = None + ) -> any: + """ + Invoke streaming text2speech model + + :param credentials: model credentials + :param content_text: text content to be translated + :param voice: ID of the reference audio (if any) + :return: generator yielding audio chunks + """ + api_key = credentials.get("api_key") + api_url = credentials.get("api_base", "https://api.fish.audio") + latency = credentials.get("latency") + + if not api_key: + raise InvokeBadRequestError("API key is required") + + with httpx.stream( + "POST", + api_url + "/v1/tts", + json={ + "text": content_text, + "reference_id": voice, + "latency": latency + }, + headers={ + "Authorization": f"Bearer {api_key}", + }, + timeout=None, + ) as response: + if response.status_code != 200: + raise InvokeBadRequestError( + f"Error: {response.status_code} - {response.text}" + ) + yield from response.iter_bytes() + + @property + def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[Exception]]]: + """ + Map model invoke error to unified error + The key is the error type thrown to the caller + The value is the error type thrown by the model, + which needs to be converted into a unified error type for the caller. + + :return: Invoke error mapping + """ + return { + InvokeBadRequestError: [ + httpx.HTTPStatusError, + ], + } diff --git a/api/core/model_runtime/model_providers/fishaudio/tts/tts.yaml b/api/core/model_runtime/model_providers/fishaudio/tts/tts.yaml new file mode 100644 index 0000000000..b4a446a957 --- /dev/null +++ b/api/core/model_runtime/model_providers/fishaudio/tts/tts.yaml @@ -0,0 +1,5 @@ +model: tts-default +model_type: tts +model_properties: + word_limit: 1000 + audio_type: 'mp3' diff --git a/api/core/model_runtime/model_providers/google/llm/llm.py b/api/core/model_runtime/model_providers/google/llm/llm.py index 84241fb6c8..11f9f32f96 100644 --- a/api/core/model_runtime/model_providers/google/llm/llm.py +++ b/api/core/model_runtime/model_providers/google/llm/llm.py @@ -416,11 +416,11 @@ class GoogleLargeLanguageModel(LargeLanguageModel): def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[Exception]]]: """ Map model invoke error to unified error - The key is the ermd = genai.GenerativeModel(model)ror type thrown to the caller - The value is the md = genai.GenerativeModel(model)error type thrown by the model, + The key is the ermd = genai.GenerativeModel(model) error type thrown to the caller + The value is the md = genai.GenerativeModel(model) error type thrown by the model, which needs to be converted into a unified error type for the caller. - :return: Invoke emd = genai.GenerativeModel(model)rror mapping + :return: Invoke emd = genai.GenerativeModel(model) error mapping """ return { InvokeConnectionError: [ diff --git a/api/core/model_runtime/model_providers/minimax/llm/llm.py b/api/core/model_runtime/model_providers/minimax/llm/llm.py index 1fab20ebbc..feeba75f49 100644 --- a/api/core/model_runtime/model_providers/minimax/llm/llm.py +++ b/api/core/model_runtime/model_providers/minimax/llm/llm.py @@ -86,7 +86,7 @@ class MinimaxLargeLanguageModel(LargeLanguageModel): Calculate num tokens for minimax model not like ChatGLM, Minimax has a special prompt structure, we could not find a proper way - to caculate the num tokens, so we use str() to convert the prompt to string + to calculate the num tokens, so we use str() to convert the prompt to string Minimax does not provide their own tokenizer of adab5.5 and abab5 model therefore, we use gpt2 tokenizer instead diff --git a/api/core/model_runtime/model_providers/novita/llm/llm.py b/api/core/model_runtime/model_providers/novita/llm/llm.py index c7b223d1b7..7662bf914a 100644 --- a/api/core/model_runtime/model_providers/novita/llm/llm.py +++ b/api/core/model_runtime/model_providers/novita/llm/llm.py @@ -10,6 +10,7 @@ from core.model_runtime.model_providers.openai_api_compatible.llm.llm import OAI class NovitaLargeLanguageModel(OAIAPICompatLargeLanguageModel): def _update_endpoint_url(self, credentials: dict): + credentials['endpoint_url'] = "https://api.novita.ai/v3/openai" credentials['extra_headers'] = { 'X-Novita-Source': 'dify.ai' } return credentials diff --git a/api/core/model_runtime/model_providers/nvidia/rerank/rerank.py b/api/core/model_runtime/model_providers/nvidia/rerank/rerank.py index 9d33f55bc2..80c24b0555 100644 --- a/api/core/model_runtime/model_providers/nvidia/rerank/rerank.py +++ b/api/core/model_runtime/model_providers/nvidia/rerank/rerank.py @@ -54,7 +54,6 @@ class NvidiaRerankModel(RerankModel): "query": {"text": query}, "passages": [{"text": doc} for doc in docs], } - session = requests.Session() response = session.post(invoke_url, headers=headers, json=payload) response.raise_for_status() @@ -71,7 +70,10 @@ class NvidiaRerankModel(RerankModel): ) rerank_documents.append(rerank_document) - + if rerank_documents: + rerank_documents = sorted(rerank_documents, key=lambda x: x.score, reverse=True) + if top_n: + rerank_documents = rerank_documents[:top_n] return RerankResult(model=model, docs=rerank_documents) except requests.HTTPError as e: raise InvokeServerUnavailableError(str(e)) diff --git a/api/core/model_runtime/model_providers/oci/__init__.py b/api/core/model_runtime/model_providers/oci/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/core/model_runtime/model_providers/oci/_assets/icon_l_en.svg b/api/core/model_runtime/model_providers/oci/_assets/icon_l_en.svg new file mode 100644 index 0000000000..0981dfcff2 --- /dev/null +++ b/api/core/model_runtime/model_providers/oci/_assets/icon_l_en.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/api/core/model_runtime/model_providers/oci/_assets/icon_s_en.svg b/api/core/model_runtime/model_providers/oci/_assets/icon_s_en.svg new file mode 100644 index 0000000000..0981dfcff2 --- /dev/null +++ b/api/core/model_runtime/model_providers/oci/_assets/icon_s_en.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/api/core/model_runtime/model_providers/oci/llm/cohere.command-r-16k.yaml b/api/core/model_runtime/model_providers/oci/llm/cohere.command-r-16k.yaml new file mode 100644 index 0000000000..eb60cbcd90 --- /dev/null +++ b/api/core/model_runtime/model_providers/oci/llm/cohere.command-r-16k.yaml @@ -0,0 +1,52 @@ +model: cohere.command-r-16k +label: + en_US: cohere.command-r-16k v1.2 +model_type: llm +features: + - multi-tool-call + - agent-thought + - stream-tool-call +model_properties: + mode: chat + context_size: 128000 +parameter_rules: + - name: temperature + use_template: temperature + default: 1 + max: 1.0 + - name: topP + use_template: top_p + default: 0.75 + min: 0 + max: 1 + - name: topK + 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. + required: false + default: 0 + min: 0 + max: 500 + - name: presencePenalty + use_template: presence_penalty + min: 0 + max: 1 + default: 0 + - name: frequencyPenalty + use_template: frequency_penalty + min: 0 + max: 1 + default: 0 + - name: maxTokens + use_template: max_tokens + default: 600 + max: 4000 +pricing: + input: '0.004' + output: '0.004' + unit: '0.0001' + currency: USD diff --git a/api/core/model_runtime/model_providers/oci/llm/cohere.command-r-plus.yaml b/api/core/model_runtime/model_providers/oci/llm/cohere.command-r-plus.yaml new file mode 100644 index 0000000000..df31b0d0df --- /dev/null +++ b/api/core/model_runtime/model_providers/oci/llm/cohere.command-r-plus.yaml @@ -0,0 +1,52 @@ +model: cohere.command-r-plus +label: + en_US: cohere.command-r-plus v1.2 +model_type: llm +features: + - multi-tool-call + - agent-thought + - stream-tool-call +model_properties: + mode: chat + context_size: 128000 +parameter_rules: + - name: temperature + use_template: temperature + default: 1 + max: 1.0 + - name: topP + use_template: top_p + default: 0.75 + min: 0 + max: 1 + - name: topK + 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. + required: false + default: 0 + min: 0 + max: 500 + - name: presencePenalty + use_template: presence_penalty + min: 0 + max: 1 + default: 0 + - name: frequencyPenalty + use_template: frequency_penalty + min: 0 + max: 1 + default: 0 + - name: maxTokens + use_template: max_tokens + default: 600 + max: 4000 +pricing: + input: '0.0219' + output: '0.0219' + unit: '0.0001' + currency: USD diff --git a/api/core/model_runtime/model_providers/oci/llm/llm.py b/api/core/model_runtime/model_providers/oci/llm/llm.py new file mode 100644 index 0000000000..37787c459d --- /dev/null +++ b/api/core/model_runtime/model_providers/oci/llm/llm.py @@ -0,0 +1,461 @@ +import base64 +import copy +import json +import logging +from collections.abc import Generator +from typing import Optional, Union + +import oci +from oci.generative_ai_inference.models.base_chat_response import BaseChatResponse + +from core.model_runtime.entities.llm_entities import LLMResult, LLMResultChunk, LLMResultChunkDelta +from core.model_runtime.entities.message_entities import ( + AssistantPromptMessage, + PromptMessage, + PromptMessageContentType, + PromptMessageTool, + SystemPromptMessage, + ToolPromptMessage, + UserPromptMessage, +) +from core.model_runtime.errors.invoke import ( + InvokeAuthorizationError, + InvokeBadRequestError, + InvokeConnectionError, + InvokeError, + InvokeRateLimitError, + InvokeServerUnavailableError, +) +from core.model_runtime.errors.validate import CredentialsValidateFailedError +from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel + +logger = logging.getLogger(__name__) + +request_template = { + "compartmentId": "", + "servingMode": { + "modelId": "cohere.command-r-plus", + "servingType": "ON_DEMAND" + }, + "chatRequest": { + "apiFormat": "COHERE", + #"preambleOverride": "You are a helpful assistant.", + #"message": "Hello!", + #"chatHistory": [], + "maxTokens": 600, + "isStream": False, + "frequencyPenalty": 0, + "presencePenalty": 0, + "temperature": 1, + "topP": 0.75 + } +} +oci_config_template = { + "user": "", + "fingerprint": "", + "tenancy": "", + "region": "", + "compartment_id": "", + "key_content": "" + } + +class OCILargeLanguageModel(LargeLanguageModel): + # https://docs.oracle.com/en-us/iaas/Content/generative-ai/pretrained-models.htm + _supported_models = { + "meta.llama-3-70b-instruct": { + "system": True, + "multimodal": False, + "tool_call": False, + "stream_tool_call": False, + }, + "cohere.command-r-16k": { + "system": True, + "multimodal": False, + "tool_call": True, + "stream_tool_call": False, + }, + "cohere.command-r-plus": { + "system": True, + "multimodal": False, + "tool_call": True, + "stream_tool_call": False, + }, + } + + def _is_tool_call_supported(self, model_id: str, stream: bool = False) -> bool: + feature = self._supported_models.get(model_id) + if not feature: + return False + return feature["stream_tool_call"] if stream else feature["tool_call"] + + def _is_multimodal_supported(self, model_id: str) -> bool: + feature = self._supported_models.get(model_id) + if not feature: + return False + return feature["multimodal"] + + def _is_system_prompt_supported(self, model_id: str) -> bool: + feature = self._supported_models.get(model_id) + if not feature: + return False + return feature["system"] + + def _invoke(self, model: str, credentials: dict, + prompt_messages: list[PromptMessage], model_parameters: dict, + tools: Optional[list[PromptMessageTool]] = None, stop: Optional[list[str]] = None, + stream: bool = True, user: Optional[str] = None) \ + -> Union[LLMResult, Generator]: + """ + Invoke large language model + + :param model: model name + :param credentials: model credentials + :param prompt_messages: prompt messages + :param model_parameters: model parameters + :param tools: tools for tool calling + :param stop: stop words + :param stream: is stream response + :param user: unique user id + :return: full response or stream response chunk generator result + """ + #print("model"+"*"*20) + #print(model) + #print("credentials"+"*"*20) + #print(credentials) + #print("model_parameters"+"*"*20) + #print(model_parameters) + #print("prompt_messages"+"*"*200) + #print(prompt_messages) + #print("tools"+"*"*20) + #print(tools) + + # invoke model + return self._generate(model, credentials, prompt_messages, model_parameters, tools, stop, stream, user) + + def get_num_tokens(self, model: str, credentials: dict, prompt_messages: list[PromptMessage], + tools: Optional[list[PromptMessageTool]] = None) -> int: + """ + Get number of tokens for given prompt messages + + :param model: model name + :param credentials: model credentials + :param prompt_messages: prompt messages + :param tools: tools for tool calling + :return:md = genai.GenerativeModel(model) + """ + prompt = self._convert_messages_to_prompt(prompt_messages) + + return self._get_num_tokens_by_gpt2(prompt) + + def get_num_characters(self, model: str, credentials: dict, prompt_messages: list[PromptMessage], + tools: Optional[list[PromptMessageTool]] = None) -> int: + """ + Get number of tokens for given prompt messages + + :param model: model name + :param credentials: model credentials + :param prompt_messages: prompt messages + :param tools: tools for tool calling + :return:md = genai.GenerativeModel(model) + """ + prompt = self._convert_messages_to_prompt(prompt_messages) + + return len(prompt) + + def _convert_messages_to_prompt(self, messages: list[PromptMessage]) -> str: + """ + :param messages: List of PromptMessage to combine. + :return: Combined string with necessary human_prompt and ai_prompt tags. + """ + messages = messages.copy() # don't mutate the original list + + text = "".join( + self._convert_one_message_to_text(message) + for message in messages + ) + + return text.rstrip() + + def validate_credentials(self, model: str, credentials: dict) -> None: + """ + Validate model credentials + + :param model: model name + :param credentials: model credentials + :return: + """ + # Setup basic variables + # Auth Config + try: + ping_message = SystemPromptMessage(content="ping") + self._generate(model, credentials, [ping_message], {"maxTokens": 5}) + except Exception as ex: + raise CredentialsValidateFailedError(str(ex)) + + def _generate(self, model: str, credentials: dict, + prompt_messages: list[PromptMessage], model_parameters: dict, + tools: Optional[list[PromptMessageTool]] = None, stop: Optional[list[str]] = None, + stream: bool = True, user: Optional[str] = None + ) -> Union[LLMResult, Generator]: + """ + Invoke large language model + + :param model: model name + :param credentials: credentials kwargs + :param prompt_messages: prompt messages + :param model_parameters: model parameters + :param stop: stop words + :param stream: is stream response + :param user: unique user id + :return: full response or stream response chunk generator result + """ + # config_kwargs = model_parameters.copy() + # config_kwargs['max_output_tokens'] = config_kwargs.pop('max_tokens_to_sample', None) + # if stop: + # config_kwargs["stop_sequences"] = stop + + # initialize client + # ref: https://docs.oracle.com/en-us/iaas/api/#/en/generative-ai-inference/20231130/ChatResult/Chat + oci_config = copy.deepcopy(oci_config_template) + if "oci_config_content" in credentials: + oci_config_content = base64.b64decode(credentials.get('oci_config_content')).decode('utf-8') + config_items = oci_config_content.split("/") + if len(config_items) != 5: + raise CredentialsValidateFailedError("oci_config_content should be base64.b64encode('user_ocid/fingerprint/tenancy_ocid/region/compartment_ocid'.encode('utf-8'))") + oci_config["user"] = config_items[0] + oci_config["fingerprint"] = config_items[1] + oci_config["tenancy"] = config_items[2] + oci_config["region"] = config_items[3] + oci_config["compartment_id"] = config_items[4] + else: + raise CredentialsValidateFailedError("need to set oci_config_content in credentials ") + if "oci_key_content" in credentials: + oci_key_content = base64.b64decode(credentials.get('oci_key_content')).decode('utf-8') + oci_config["key_content"] = oci_key_content.encode(encoding="utf-8") + else: + raise CredentialsValidateFailedError("need to set oci_config_content in credentials ") + + #oci_config = oci.config.from_file('~/.oci/config', credentials.get('oci_api_profile')) + compartment_id = oci_config["compartment_id"] + client = oci.generative_ai_inference.GenerativeAiInferenceClient(config=oci_config) + # call embedding model + request_args = copy.deepcopy(request_template) + request_args["compartmentId"] = compartment_id + request_args["servingMode"]["modelId"] = model + + chat_history = [] + system_prompts = [] + #if "meta.llama" in model: + # request_args["chatRequest"]["apiFormat"] = "GENERIC" + request_args["chatRequest"]["maxTokens"] = model_parameters.pop('maxTokens', 600) + request_args["chatRequest"].update(model_parameters) + frequency_penalty = model_parameters.get("frequencyPenalty", 0) + presence_penalty = model_parameters.get("presencePenalty", 0) + if frequency_penalty > 0 and presence_penalty > 0: + raise InvokeBadRequestError("Cannot set both frequency penalty and presence penalty") + + # for msg in prompt_messages: # makes message roles strictly alternating + # content = self._format_message_to_glm_content(msg) + # if history and history[-1]["role"] == content["role"]: + # history[-1]["parts"].extend(content["parts"]) + # else: + # history.append(content) + + # temporary not implement the tool call function + valid_value = self._is_tool_call_supported(model, stream) + if tools is not None and len(tools) > 0: + if not valid_value: + raise InvokeBadRequestError("Does not support function calling") + if model.startswith("cohere"): + #print("run cohere " * 10) + for message in prompt_messages[:-1]: + text = "" + if isinstance(message.content, str): + text = message.content + if isinstance(message, UserPromptMessage): + chat_history.append({"role": "USER", "message": text}) + else: + chat_history.append({"role": "CHATBOT", "message": text}) + if isinstance(message, SystemPromptMessage): + if isinstance(message.content, str): + system_prompts.append(message.content) + args = {"apiFormat": "COHERE", + "preambleOverride": ' '.join(system_prompts), + "message": prompt_messages[-1].content, + "chatHistory": chat_history, } + request_args["chatRequest"].update(args) + elif model.startswith("meta"): + #print("run meta " * 10) + meta_messages = [] + for message in prompt_messages: + text = message.content + meta_messages.append({"role": message.role.name, "content": [{"type": "TEXT", "text": text}]}) + args = {"apiFormat": "GENERIC", + "messages": meta_messages, + "numGenerations": 1, + "topK": -1} + request_args["chatRequest"].update(args) + + if stream: + request_args["chatRequest"]["isStream"] = True + #print("final request" + "|" * 20) + #print(request_args) + response = client.chat(request_args) + #print(vars(response)) + + if stream: + return self._handle_generate_stream_response(model, credentials, response, prompt_messages) + + return self._handle_generate_response(model, credentials, response, prompt_messages) + + def _handle_generate_response(self, model: str, credentials: dict, response: BaseChatResponse, + prompt_messages: list[PromptMessage]) -> LLMResult: + """ + Handle llm response + + :param model: model name + :param credentials: credentials + :param response: response + :param prompt_messages: prompt messages + :return: llm response + """ + # transform assistant message to prompt message + assistant_prompt_message = AssistantPromptMessage( + content=response.data.chat_response.text + ) + + # calculate num tokens + prompt_tokens = self.get_num_characters(model, credentials, prompt_messages) + completion_tokens = self.get_num_characters(model, credentials, [assistant_prompt_message]) + + # transform usage + usage = self._calc_response_usage(model, credentials, prompt_tokens, completion_tokens) + + # transform response + result = LLMResult( + model=model, + prompt_messages=prompt_messages, + message=assistant_prompt_message, + usage=usage, + ) + + return result + + def _handle_generate_stream_response(self, model: str, credentials: dict, response: BaseChatResponse, + prompt_messages: list[PromptMessage]) -> Generator: + """ + Handle llm stream response + + :param model: model name + :param credentials: credentials + :param response: response + :param prompt_messages: prompt messages + :return: llm response chunk generator result + """ + index = -1 + events = response.data.events() + for stream in events: + chunk = json.loads(stream.data) + #print(chunk) + #chunk: {'apiFormat': 'COHERE', 'text': 'Hello'} + + + + #for chunk in response: + #for part in chunk.parts: + #if part.function_call: + # assistant_prompt_message.tool_calls = [ + # AssistantPromptMessage.ToolCall( + # id=part.function_call.name, + # type='function', + # function=AssistantPromptMessage.ToolCall.ToolCallFunction( + # name=part.function_call.name, + # arguments=json.dumps(dict(part.function_call.args.items())) + # ) + # ) + # ] + + if "finishReason" not in chunk: + assistant_prompt_message = AssistantPromptMessage( + content='' + ) + if model.startswith("cohere"): + if chunk["text"]: + assistant_prompt_message.content += chunk["text"] + elif model.startswith("meta"): + assistant_prompt_message.content += chunk["message"]["content"][0]["text"] + index += 1 + # transform assistant message to prompt message + yield LLMResultChunk( + model=model, + prompt_messages=prompt_messages, + delta=LLMResultChunkDelta( + index=index, + message=assistant_prompt_message + ) + ) + else: + # calculate num tokens + prompt_tokens = self.get_num_characters(model, credentials, prompt_messages) + completion_tokens = self.get_num_characters(model, credentials, [assistant_prompt_message]) + + # transform usage + usage = self._calc_response_usage(model, credentials, prompt_tokens, completion_tokens) + + yield LLMResultChunk( + model=model, + prompt_messages=prompt_messages, + delta=LLMResultChunkDelta( + index=index, + message=assistant_prompt_message, + finish_reason=str(chunk["finishReason"]), + usage=usage + ) + ) + + def _convert_one_message_to_text(self, message: PromptMessage) -> str: + """ + Convert a single message to a string. + + :param message: PromptMessage to convert. + :return: String representation of the message. + """ + human_prompt = "\n\nuser:" + ai_prompt = "\n\nmodel:" + + content = message.content + if isinstance(content, list): + content = "".join( + c.data for c in content if c.type != PromptMessageContentType.IMAGE + ) + + if isinstance(message, UserPromptMessage): + message_text = f"{human_prompt} {content}" + elif isinstance(message, AssistantPromptMessage): + message_text = f"{ai_prompt} {content}" + elif isinstance(message, SystemPromptMessage): + message_text = f"{human_prompt} {content}" + elif isinstance(message, ToolPromptMessage): + message_text = f"{human_prompt} {content}" + else: + raise ValueError(f"Got unknown type {message}") + + return message_text + + @property + def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[Exception]]]: + """ + Map model invoke error to unified error + The key is the error type thrown to the caller + The value is the error type thrown by the model, + which needs to be converted into a unified error type for the caller. + + :return: Invoke error mapping + """ + return { + InvokeConnectionError: [], + InvokeServerUnavailableError: [], + InvokeRateLimitError: [], + InvokeAuthorizationError: [], + InvokeBadRequestError: [] + } diff --git a/api/core/model_runtime/model_providers/oci/llm/meta.llama-3-70b-instruct.yaml b/api/core/model_runtime/model_providers/oci/llm/meta.llama-3-70b-instruct.yaml new file mode 100644 index 0000000000..dd5be107c0 --- /dev/null +++ b/api/core/model_runtime/model_providers/oci/llm/meta.llama-3-70b-instruct.yaml @@ -0,0 +1,51 @@ +model: meta.llama-3-70b-instruct +label: + zh_Hans: meta.llama-3-70b-instruct + en_US: meta.llama-3-70b-instruct +model_type: llm +features: + - agent-thought +model_properties: + mode: chat + context_size: 131072 +parameter_rules: + - name: temperature + use_template: temperature + default: 1 + max: 2.0 + - name: topP + use_template: top_p + default: 0.75 + min: 0 + max: 1 + - name: topK + 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. + required: false + default: 0 + min: 0 + max: 500 + - name: presencePenalty + use_template: presence_penalty + min: -2 + max: 2 + default: 0 + - name: frequencyPenalty + use_template: frequency_penalty + min: -2 + max: 2 + default: 0 + - name: maxTokens + use_template: max_tokens + default: 600 + max: 8000 +pricing: + input: '0.015' + output: '0.015' + unit: '0.0001' + currency: USD diff --git a/api/core/model_runtime/model_providers/oci/oci.py b/api/core/model_runtime/model_providers/oci/oci.py new file mode 100644 index 0000000000..11d67790a0 --- /dev/null +++ b/api/core/model_runtime/model_providers/oci/oci.py @@ -0,0 +1,34 @@ +import logging + +from core.model_runtime.entities.model_entities import ModelType +from core.model_runtime.errors.validate import CredentialsValidateFailedError +from core.model_runtime.model_providers.__base.model_provider import ModelProvider + +logger = logging.getLogger(__name__) + + +class OCIGENAIProvider(ModelProvider): + + def validate_provider_credentials(self, credentials: dict) -> None: + """ + Validate provider credentials + + if validate failed, raise exception + + :param credentials: provider credentials, credentials form defined in `provider_credential_schema`. + """ + try: + model_instance = self.get_model_instance(ModelType.LLM) + + # Use `cohere.command-r-plus` model for validate, + model_instance.validate_credentials( + model='cohere.command-r-plus', + credentials=credentials + ) + except CredentialsValidateFailedError as ex: + raise ex + except Exception as ex: + logger.exception(f'{self.get_provider_schema().provider} credentials validate failed') + raise ex + + diff --git a/api/core/model_runtime/model_providers/oci/oci.yaml b/api/core/model_runtime/model_providers/oci/oci.yaml new file mode 100644 index 0000000000..f2f23e18f1 --- /dev/null +++ b/api/core/model_runtime/model_providers/oci/oci.yaml @@ -0,0 +1,42 @@ +provider: oci +label: + en_US: OCIGenerativeAI +description: + en_US: Models provided by OCI, such as Cohere Command R and Cohere Command R+. + zh_Hans: OCI 提供的模型,例如 Cohere Command R 和 Cohere Command R+。 +icon_small: + en_US: icon_s_en.svg +icon_large: + en_US: icon_l_en.svg +background: "#FFFFFF" +help: + title: + en_US: Get your API Key from OCI + zh_Hans: 从 OCI 获取 API Key + url: + en_US: https://docs.cloud.oracle.com/Content/API/Concepts/sdkconfig.htm +supported_model_types: + - llm + - text-embedding + #- rerank +configurate_methods: + - predefined-model + #- customizable-model +provider_credential_schema: + credential_form_schemas: + - variable: oci_config_content + label: + en_US: oci api key config file's content + type: text-input + required: true + placeholder: + zh_Hans: 在此输入您的 oci api key config 文件的内容(base64.b64encode("user_ocid/fingerprint/tenancy_ocid/region/compartment_ocid".encode('utf-8')) ) + en_US: Enter your oci api key config file's content(base64.b64encode("user_ocid/fingerprint/tenancy_ocid/region/compartment_ocid".encode('utf-8')) ) + - variable: oci_key_content + label: + en_US: oci api key file's content + type: text-input + required: true + placeholder: + zh_Hans: 在此输入您的 oci api key 文件的内容(base64.b64encode("pem file content".encode('utf-8'))) + en_US: Enter your oci api key file's content(base64.b64encode("pem file content".encode('utf-8'))) diff --git a/api/core/model_runtime/model_providers/oci/text_embedding/__init__.py b/api/core/model_runtime/model_providers/oci/text_embedding/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/core/model_runtime/model_providers/oci/text_embedding/_position.yaml b/api/core/model_runtime/model_providers/oci/text_embedding/_position.yaml new file mode 100644 index 0000000000..149f1e3797 --- /dev/null +++ b/api/core/model_runtime/model_providers/oci/text_embedding/_position.yaml @@ -0,0 +1,5 @@ +- cohere.embed-english-light-v2.0 +- cohere.embed-english-light-v3.0 +- cohere.embed-english-v3.0 +- cohere.embed-multilingual-light-v3.0 +- cohere.embed-multilingual-v3.0 diff --git a/api/core/model_runtime/model_providers/oci/text_embedding/cohere.embed-english-light-v2.0.yaml b/api/core/model_runtime/model_providers/oci/text_embedding/cohere.embed-english-light-v2.0.yaml new file mode 100644 index 0000000000..259d5b45b7 --- /dev/null +++ b/api/core/model_runtime/model_providers/oci/text_embedding/cohere.embed-english-light-v2.0.yaml @@ -0,0 +1,9 @@ +model: cohere.embed-english-light-v2.0 +model_type: text-embedding +model_properties: + context_size: 1024 + max_chunks: 48 +pricing: + input: '0.001' + unit: '0.0001' + currency: USD diff --git a/api/core/model_runtime/model_providers/oci/text_embedding/cohere.embed-english-light-v3.0.yaml b/api/core/model_runtime/model_providers/oci/text_embedding/cohere.embed-english-light-v3.0.yaml new file mode 100644 index 0000000000..065e7474c0 --- /dev/null +++ b/api/core/model_runtime/model_providers/oci/text_embedding/cohere.embed-english-light-v3.0.yaml @@ -0,0 +1,9 @@ +model: cohere.embed-english-light-v3.0 +model_type: text-embedding +model_properties: + context_size: 384 + max_chunks: 48 +pricing: + input: '0.001' + unit: '0.0001' + currency: USD diff --git a/api/core/model_runtime/model_providers/oci/text_embedding/cohere.embed-english-v3.0.yaml b/api/core/model_runtime/model_providers/oci/text_embedding/cohere.embed-english-v3.0.yaml new file mode 100644 index 0000000000..3e2deea16a --- /dev/null +++ b/api/core/model_runtime/model_providers/oci/text_embedding/cohere.embed-english-v3.0.yaml @@ -0,0 +1,9 @@ +model: cohere.embed-english-v3.0 +model_type: text-embedding +model_properties: + context_size: 1024 + max_chunks: 48 +pricing: + input: '0.001' + unit: '0.0001' + currency: USD diff --git a/api/core/model_runtime/model_providers/oci/text_embedding/cohere.embed-multilingual-light-v3.0.yaml b/api/core/model_runtime/model_providers/oci/text_embedding/cohere.embed-multilingual-light-v3.0.yaml new file mode 100644 index 0000000000..0d2b892c64 --- /dev/null +++ b/api/core/model_runtime/model_providers/oci/text_embedding/cohere.embed-multilingual-light-v3.0.yaml @@ -0,0 +1,9 @@ +model: cohere.embed-multilingual-light-v3.0 +model_type: text-embedding +model_properties: + context_size: 384 + max_chunks: 48 +pricing: + input: '0.001' + unit: '0.0001' + currency: USD diff --git a/api/core/model_runtime/model_providers/oci/text_embedding/cohere.embed-multilingual-v3.0.yaml b/api/core/model_runtime/model_providers/oci/text_embedding/cohere.embed-multilingual-v3.0.yaml new file mode 100644 index 0000000000..9ebe260b32 --- /dev/null +++ b/api/core/model_runtime/model_providers/oci/text_embedding/cohere.embed-multilingual-v3.0.yaml @@ -0,0 +1,9 @@ +model: cohere.embed-multilingual-v3.0 +model_type: text-embedding +model_properties: + context_size: 1024 + max_chunks: 48 +pricing: + input: '0.001' + unit: '0.0001' + currency: USD diff --git a/api/core/model_runtime/model_providers/oci/text_embedding/text_embedding.py b/api/core/model_runtime/model_providers/oci/text_embedding/text_embedding.py new file mode 100644 index 0000000000..5e0a85583e --- /dev/null +++ b/api/core/model_runtime/model_providers/oci/text_embedding/text_embedding.py @@ -0,0 +1,242 @@ +import base64 +import copy +import time +from typing import Optional + +import numpy as np +import oci + +from core.model_runtime.entities.model_entities import PriceType +from core.model_runtime.entities.text_embedding_entities import EmbeddingUsage, TextEmbeddingResult +from core.model_runtime.errors.invoke import ( + InvokeAuthorizationError, + InvokeBadRequestError, + InvokeConnectionError, + InvokeError, + InvokeRateLimitError, + InvokeServerUnavailableError, +) +from core.model_runtime.errors.validate import CredentialsValidateFailedError +from core.model_runtime.model_providers.__base.text_embedding_model import TextEmbeddingModel + +request_template = { + "compartmentId": "", + "servingMode": { + "modelId": "cohere.embed-english-light-v3.0", + "servingType": "ON_DEMAND" + }, + "truncate": "NONE", + "inputs": [""] +} +oci_config_template = { + "user": "", + "fingerprint": "", + "tenancy": "", + "region": "", + "compartment_id": "", + "key_content": "" + } +class OCITextEmbeddingModel(TextEmbeddingModel): + """ + Model class for Cohere text embedding model. + """ + + def _invoke(self, model: str, credentials: dict, + texts: list[str], user: Optional[str] = None) \ + -> TextEmbeddingResult: + """ + Invoke text embedding model + + :param model: model name + :param credentials: model credentials + :param texts: texts to embed + :param user: unique user id + :return: embeddings result + """ + # get model properties + context_size = self._get_context_size(model, credentials) + max_chunks = self._get_max_chunks(model, credentials) + + inputs = [] + indices = [] + used_tokens = 0 + + for i, text in enumerate(texts): + + # Here token count is only an approximation based on the GPT2 tokenizer + num_tokens = self._get_num_tokens_by_gpt2(text) + + if num_tokens >= context_size: + cutoff = int(len(text) * (np.floor(context_size / num_tokens))) + # if num tokens is larger than context length, only use the start + inputs.append(text[0: cutoff]) + else: + inputs.append(text) + indices += [i] + + batched_embeddings = [] + _iter = range(0, len(inputs), max_chunks) + + for i in _iter: + # call embedding model + embeddings_batch, embedding_used_tokens = self._embedding_invoke( + model=model, + credentials=credentials, + texts=inputs[i: i + max_chunks] + ) + + used_tokens += embedding_used_tokens + batched_embeddings += embeddings_batch + + # calc usage + usage = self._calc_response_usage( + model=model, + credentials=credentials, + tokens=used_tokens + ) + + return TextEmbeddingResult( + embeddings=batched_embeddings, + usage=usage, + model=model + ) + + def get_num_tokens(self, model: str, credentials: dict, texts: list[str]) -> int: + """ + Get number of tokens for given prompt messages + + :param model: model name + :param credentials: model credentials + :param texts: texts to embed + :return: + """ + return sum(self._get_num_tokens_by_gpt2(text) for text in texts) + + def get_num_characters(self, model: str, credentials: dict, texts: list[str]) -> int: + """ + Get number of tokens for given prompt messages + + :param model: model name + :param credentials: model credentials + :param texts: texts to embed + :return: + """ + characters = 0 + for text in texts: + characters += len(text) + return characters + def validate_credentials(self, model: str, credentials: dict) -> None: + """ + Validate model credentials + + :param model: model name + :param credentials: model credentials + :return: + """ + try: + # call embedding model + self._embedding_invoke( + model=model, + credentials=credentials, + texts=['ping'] + ) + except Exception as ex: + raise CredentialsValidateFailedError(str(ex)) + + def _embedding_invoke(self, model: str, credentials: dict, texts: list[str]) -> tuple[list[list[float]], int]: + """ + Invoke embedding model + + :param model: model name + :param credentials: model credentials + :param texts: texts to embed + :return: embeddings and used tokens + """ + + # oci + # initialize client + oci_config = copy.deepcopy(oci_config_template) + if "oci_config_content" in credentials: + oci_config_content = base64.b64decode(credentials.get('oci_config_content')).decode('utf-8') + config_items = oci_config_content.split("/") + if len(config_items) != 5: + raise CredentialsValidateFailedError("oci_config_content should be base64.b64encode('user_ocid/fingerprint/tenancy_ocid/region/compartment_ocid'.encode('utf-8'))") + oci_config["user"] = config_items[0] + oci_config["fingerprint"] = config_items[1] + oci_config["tenancy"] = config_items[2] + oci_config["region"] = config_items[3] + oci_config["compartment_id"] = config_items[4] + else: + raise CredentialsValidateFailedError("need to set oci_config_content in credentials ") + if "oci_key_content" in credentials: + oci_key_content = base64.b64decode(credentials.get('oci_key_content')).decode('utf-8') + oci_config["key_content"] = oci_key_content.encode(encoding="utf-8") + else: + raise CredentialsValidateFailedError("need to set oci_config_content in credentials ") + # oci_config = oci.config.from_file('~/.oci/config', credentials.get('oci_api_profile')) + compartment_id = oci_config["compartment_id"] + client = oci.generative_ai_inference.GenerativeAiInferenceClient(config=oci_config) + # call embedding model + request_args = copy.deepcopy(request_template) + request_args["compartmentId"] = compartment_id + request_args["servingMode"]["modelId"] = model + request_args["inputs"] = texts + response = client.embed_text(request_args) + return response.data.embeddings, self.get_num_characters(model=model, credentials=credentials, texts=texts) + + def _calc_response_usage(self, model: str, credentials: dict, tokens: int) -> EmbeddingUsage: + """ + Calculate response usage + + :param model: model name + :param credentials: model credentials + :param tokens: input tokens + :return: usage + """ + # get input price info + input_price_info = self.get_price( + model=model, + credentials=credentials, + price_type=PriceType.INPUT, + tokens=tokens + ) + + # transform usage + usage = EmbeddingUsage( + tokens=tokens, + total_tokens=tokens, + unit_price=input_price_info.unit_price, + price_unit=input_price_info.unit, + total_price=input_price_info.total_amount, + currency=input_price_info.currency, + latency=time.perf_counter() - self.started_at + ) + + return usage + + @property + def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[Exception]]]: + """ + Map model invoke error to unified error + The key is the error type thrown to the caller + The value is the error type thrown by the model, + which needs to be converted into a unified error type for the caller. + :return: Invoke error mapping + """ + return { + InvokeConnectionError: [ + InvokeConnectionError + ], + InvokeServerUnavailableError: [ + InvokeServerUnavailableError + ], + InvokeRateLimitError: [ + InvokeRateLimitError + ], + InvokeAuthorizationError: [ + InvokeAuthorizationError + ], + InvokeBadRequestError: [ + KeyError + ] + } diff --git a/api/core/model_runtime/model_providers/ollama/text_embedding/text_embedding.py b/api/core/model_runtime/model_providers/ollama/text_embedding/text_embedding.py index 9e26d35afc..8f7d54c516 100644 --- a/api/core/model_runtime/model_providers/ollama/text_embedding/text_embedding.py +++ b/api/core/model_runtime/model_providers/ollama/text_embedding/text_embedding.py @@ -89,7 +89,8 @@ class OllamaEmbeddingModel(TextEmbeddingModel): endpoint_url, headers=headers, data=json.dumps(payload), - timeout=(10, 300) + timeout=(10, 300), + options={"use_mmap": "true"} ) response.raise_for_status() # Raise an exception for HTTP errors 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 06135c9584..dc85f7c9f2 100644 --- a/api/core/model_runtime/model_providers/openai/llm/llm.py +++ b/api/core/model_runtime/model_providers/openai/llm/llm.py @@ -552,7 +552,7 @@ class OpenAILargeLanguageModel(_CommonOpenAI, LargeLanguageModel): try: schema = json.loads(json_schema) except: - raise ValueError(f"not currect json_schema format: {json_schema}") + raise ValueError(f"not correct json_schema format: {json_schema}") model_parameters.pop("json_schema") model_parameters["response_format"] = {"type": "json_schema", "json_schema": schema} else: diff --git a/api/core/model_runtime/model_providers/sagemaker/llm/llm.py b/api/core/model_runtime/model_providers/sagemaker/llm/llm.py index f8e7757a96..3d4c5825af 100644 --- a/api/core/model_runtime/model_providers/sagemaker/llm/llm.py +++ b/api/core/model_runtime/model_providers/sagemaker/llm/llm.py @@ -1,17 +1,36 @@ import json import logging -from collections.abc import Generator -from typing import Any, Optional, Union +import re +from collections.abc import Generator, Iterator +from typing import Any, Optional, Union, cast +# from openai.types.chat import ChatCompletion, ChatCompletionChunk import boto3 +from sagemaker import Predictor, serializers +from sagemaker.session import Session -from core.model_runtime.entities.llm_entities import LLMMode, LLMResult +from core.model_runtime.entities.llm_entities import LLMMode, LLMResult, LLMResultChunk, LLMResultChunkDelta from core.model_runtime.entities.message_entities import ( AssistantPromptMessage, + ImagePromptMessageContent, PromptMessage, + PromptMessageContent, + PromptMessageContentType, PromptMessageTool, + SystemPromptMessage, + ToolPromptMessage, + UserPromptMessage, +) +from core.model_runtime.entities.model_entities import ( + AIModelEntity, + FetchFrom, + I18nObject, + ModelFeature, + ModelPropertyKey, + ModelType, + ParameterRule, + ParameterType, ) -from core.model_runtime.entities.model_entities import AIModelEntity, FetchFrom, I18nObject, ModelType from core.model_runtime.errors.invoke import ( InvokeAuthorizationError, InvokeBadRequestError, @@ -25,12 +44,140 @@ from core.model_runtime.model_providers.__base.large_language_model import Large logger = logging.getLogger(__name__) +def inference(predictor, messages:list[dict[str,Any]], params:dict[str,Any], stop:list, stream=False): + """ + params: + predictor : Sagemaker Predictor + messages (List[Dict[str,Any]]): message list。 + messages = [ + {"role": "system", "content":"please answer in Chinese"}, + {"role": "user", "content": "who are you? what are you doing?"}, + ] + params (Dict[str,Any]): model parameters for LLM。 + stream (bool): False by default。 + + response: + result of inference if stream is False + Iterator of Chunks if stream is True + """ + payload = { + "model" : params.get('model_name'), + "stop" : stop, + "messages": messages, + "stream" : stream, + "max_tokens" : params.get('max_new_tokens', params.get('max_tokens', 2048)), + "temperature" : params.get('temperature', 0.1), + "top_p" : params.get('top_p', 0.9), + } + + if not stream: + response = predictor.predict(payload) + return response + else: + response_stream = predictor.predict_stream(payload) + return response_stream class SageMakerLargeLanguageModel(LargeLanguageModel): """ Model class for Cohere large language model. """ sagemaker_client: Any = None + sagemaker_sess : Any = None + predictor : Any = None + + def _handle_chat_generate_response(self, model: str, credentials: dict, prompt_messages: list[PromptMessage], + tools: list[PromptMessageTool], + resp: bytes) -> LLMResult: + """ + handle normal chat generate response + """ + resp_obj = json.loads(resp.decode('utf-8')) + resp_str = resp_obj.get('choices')[0].get('message').get('content') + + if len(resp_str) == 0: + raise InvokeServerUnavailableError("Empty response") + + assistant_prompt_message = AssistantPromptMessage( + content=resp_str, + tool_calls=[] + ) + + prompt_tokens = self._num_tokens_from_messages(messages=prompt_messages, tools=tools) + completion_tokens = self._num_tokens_from_messages(messages=[assistant_prompt_message], tools=tools) + + usage = self._calc_response_usage(model=model, credentials=credentials, prompt_tokens=prompt_tokens, + completion_tokens=completion_tokens) + + response = LLMResult( + model=model, + prompt_messages=prompt_messages, + system_fingerprint=None, + usage=usage, + message=assistant_prompt_message, + ) + + return response + + def _handle_chat_stream_response(self, model: str, credentials: dict, prompt_messages: list[PromptMessage], + tools: list[PromptMessageTool], + resp: Iterator[bytes]) -> Generator: + """ + handle stream chat generate response + """ + full_response = '' + buffer = "" + for chunk_bytes in resp: + buffer += chunk_bytes.decode('utf-8') + last_idx = 0 + for match in re.finditer(r'^data:\s*(.+?)(\n\n)', buffer): + try: + data = json.loads(match.group(1).strip()) + last_idx = match.span()[1] + + if "content" in data["choices"][0]["delta"]: + chunk_content = data["choices"][0]["delta"]["content"] + assistant_prompt_message = AssistantPromptMessage( + content=chunk_content, + tool_calls=[] + ) + + if data["choices"][0]['finish_reason'] is not None: + temp_assistant_prompt_message = AssistantPromptMessage( + content=full_response, + tool_calls=[] + ) + prompt_tokens = self._num_tokens_from_messages(messages=prompt_messages, tools=tools) + completion_tokens = self._num_tokens_from_messages(messages=[temp_assistant_prompt_message], tools=[]) + usage = self._calc_response_usage(model=model, credentials=credentials, prompt_tokens=prompt_tokens, completion_tokens=completion_tokens) + + yield LLMResultChunk( + model=model, + prompt_messages=prompt_messages, + system_fingerprint=None, + delta=LLMResultChunkDelta( + index=0, + message=assistant_prompt_message, + finish_reason=data["choices"][0]['finish_reason'], + usage=usage + ), + ) + else: + yield LLMResultChunk( + model=model, + prompt_messages=prompt_messages, + system_fingerprint=None, + delta=LLMResultChunkDelta( + index=0, + message=assistant_prompt_message + ), + ) + + full_response += chunk_content + except (json.JSONDecodeError, KeyError, IndexError) as e: + logger.info("json parse exception, content: {}".format(match.group(1).strip())) + pass + + buffer = buffer[last_idx:] def _invoke(self, model: str, credentials: dict, prompt_messages: list[PromptMessage], model_parameters: dict, @@ -50,9 +197,6 @@ class SageMakerLargeLanguageModel(LargeLanguageModel): :param user: unique user id :return: full response or stream response chunk generator result """ - # get model mode - model_mode = self.get_model_mode(model, credentials) - if not self.sagemaker_client: access_key = credentials.get('access_key') secret_key = credentials.get('secret_key') @@ -68,37 +212,132 @@ class SageMakerLargeLanguageModel(LargeLanguageModel): else: self.sagemaker_client = boto3.client("sagemaker-runtime") + sagemaker_session = Session(sagemaker_runtime_client=self.sagemaker_client) + self.predictor = Predictor( + endpoint_name=credentials.get('sagemaker_endpoint'), + sagemaker_session=sagemaker_session, + serializer=serializers.JSONSerializer(), + ) - sagemaker_endpoint = credentials.get('sagemaker_endpoint') - response_model = self.sagemaker_client.invoke_endpoint( - EndpointName=sagemaker_endpoint, - Body=json.dumps( - { - "inputs": prompt_messages[0].content, - "parameters": { "stop" : stop}, - "history" : [] - } - ), - ContentType="application/json", - ) - assistant_text = response_model['Body'].read().decode('utf8') + messages:list[dict[str,Any]] = [ {"role": p.role.value, "content": p.content} for p in prompt_messages ] + response = inference(predictor=self.predictor, messages=messages, params=model_parameters, stop=stop, stream=stream) - # transform assistant message to prompt message - assistant_prompt_message = AssistantPromptMessage( - content=assistant_text - ) + if stream: + if tools and len(tools) > 0: + raise InvokeBadRequestError(f"{model}'s tool calls does not support stream mode") - usage = self._calc_response_usage(model, credentials, 0, 0) + return self._handle_chat_stream_response(model=model, credentials=credentials, + prompt_messages=prompt_messages, + tools=tools, resp=response) + return self._handle_chat_generate_response(model=model, credentials=credentials, + prompt_messages=prompt_messages, + tools=tools, resp=response) - response = LLMResult( - model=model, - prompt_messages=prompt_messages, - message=assistant_prompt_message, - usage=usage - ) + def _convert_prompt_message_to_dict(self, message: PromptMessage) -> dict: + """ + Convert PromptMessage to dict for OpenAI Compatibility API + """ + if isinstance(message, UserPromptMessage): + message = cast(UserPromptMessage, message) + if isinstance(message.content, str): + message_dict = {"role": "user", "content": message.content} + else: + sub_messages = [] + for message_content in message.content: + if message_content.type == PromptMessageContentType.TEXT: + message_content = cast(PromptMessageContent, message_content) + sub_message_dict = { + "type": "text", + "text": message_content.data + } + sub_messages.append(sub_message_dict) + elif message_content.type == PromptMessageContentType.IMAGE: + message_content = cast(ImagePromptMessageContent, message_content) + sub_message_dict = { + "type": "image_url", + "image_url": { + "url": message_content.data, + "detail": message_content.detail.value + } + } + sub_messages.append(sub_message_dict) + message_dict = {"role": "user", "content": sub_messages} + elif isinstance(message, AssistantPromptMessage): + message = cast(AssistantPromptMessage, message) + message_dict = {"role": "assistant", "content": message.content} + if message.tool_calls and len(message.tool_calls) > 0: + message_dict["function_call"] = { + "name": message.tool_calls[0].function.name, + "arguments": message.tool_calls[0].function.arguments + } + elif isinstance(message, SystemPromptMessage): + message = cast(SystemPromptMessage, message) + message_dict = {"role": "system", "content": message.content} + elif isinstance(message, ToolPromptMessage): + message = cast(ToolPromptMessage, message) + message_dict = {"tool_call_id": message.tool_call_id, "role": "tool", "content": message.content} + else: + raise ValueError(f"Unknown message type {type(message)}") - return response + return message_dict + + def _num_tokens_from_messages(self, messages: list[PromptMessage], tools: list[PromptMessageTool], + is_completion_model: bool = False) -> int: + def tokens(text: str): + return self._get_num_tokens_by_gpt2(text) + + if is_completion_model: + return sum(tokens(str(message.content)) for message in messages) + + tokens_per_message = 3 + tokens_per_name = 1 + + num_tokens = 0 + messages_dict = [self._convert_prompt_message_to_dict(m) for m in messages] + for message in messages_dict: + num_tokens += tokens_per_message + for key, value in message.items(): + if isinstance(value, list): + text = '' + for item in value: + if isinstance(item, dict) and item['type'] == 'text': + text += item['text'] + + value = text + + if key == "tool_calls": + for tool_call in value: + for t_key, t_value in tool_call.items(): + num_tokens += tokens(t_key) + if t_key == "function": + for f_key, f_value in t_value.items(): + num_tokens += tokens(f_key) + num_tokens += tokens(f_value) + else: + num_tokens += tokens(t_key) + num_tokens += tokens(t_value) + if key == "function_call": + for t_key, t_value in value.items(): + num_tokens += tokens(t_key) + if t_key == "function": + for f_key, f_value in t_value.items(): + num_tokens += tokens(f_key) + num_tokens += tokens(f_value) + else: + num_tokens += tokens(t_key) + num_tokens += tokens(t_value) + else: + num_tokens += tokens(str(value)) + + if key == "name": + num_tokens += tokens_per_name + num_tokens += 3 + + if tools: + num_tokens += self._num_tokens_for_tools(tools) + + return num_tokens def get_num_tokens(self, model: str, credentials: dict, prompt_messages: list[PromptMessage], tools: Optional[list[PromptMessageTool]] = None) -> int: @@ -112,10 +351,8 @@ class SageMakerLargeLanguageModel(LargeLanguageModel): :return: """ # get model mode - model_mode = self.get_model_mode(model) - try: - return 0 + return self._num_tokens_from_messages(prompt_messages, tools) except Exception as e: raise self._transform_invoke_error(e) @@ -129,7 +366,7 @@ class SageMakerLargeLanguageModel(LargeLanguageModel): """ try: # get model mode - model_mode = self.get_model_mode(model) + pass except Exception as ex: raise CredentialsValidateFailedError(str(ex)) @@ -200,13 +437,7 @@ class SageMakerLargeLanguageModel(LargeLanguageModel): ) ] - completion_type = LLMMode.value_of(credentials["mode"]) - - if completion_type == LLMMode.CHAT: - print(f"completion_type : {LLMMode.CHAT.value}") - - if completion_type == LLMMode.COMPLETION: - print(f"completion_type : {LLMMode.COMPLETION.value}") + completion_type = LLMMode.value_of(credentials["mode"]).value features = [] diff --git a/api/core/model_runtime/model_providers/sagemaker/rerank/rerank.py b/api/core/model_runtime/model_providers/sagemaker/rerank/rerank.py index 0b06f54ef1..6b7cfc210b 100644 --- a/api/core/model_runtime/model_providers/sagemaker/rerank/rerank.py +++ b/api/core/model_runtime/model_providers/sagemaker/rerank/rerank.py @@ -22,7 +22,7 @@ logger = logging.getLogger(__name__) class SageMakerRerankModel(RerankModel): """ - Model class for Cohere rerank model. + Model class for SageMaker rerank model. """ sagemaker_client: Any = None diff --git a/api/core/model_runtime/model_providers/sagemaker/sagemaker.py b/api/core/model_runtime/model_providers/sagemaker/sagemaker.py index 02d05f406c..6f3e02489f 100644 --- a/api/core/model_runtime/model_providers/sagemaker/sagemaker.py +++ b/api/core/model_runtime/model_providers/sagemaker/sagemaker.py @@ -1,10 +1,11 @@ import logging +import uuid +from typing import IO, Any from core.model_runtime.model_providers.__base.model_provider import ModelProvider logger = logging.getLogger(__name__) - class SageMakerProvider(ModelProvider): def validate_provider_credentials(self, credentials: dict) -> None: """ @@ -15,3 +16,28 @@ class SageMakerProvider(ModelProvider): :param credentials: provider credentials, credentials form defined in `provider_credential_schema`. """ pass + +def buffer_to_s3(s3_client:Any, file: IO[bytes], bucket:str, s3_prefix:str) -> str: + ''' + return s3_uri of this file + ''' + s3_key = f'{s3_prefix}{uuid.uuid4()}.mp3' + s3_client.put_object( + Body=file.read(), + Bucket=bucket, + Key=s3_key, + ContentType='audio/mp3' + ) + return s3_key + +def generate_presigned_url(s3_client:Any, file: IO[bytes], bucket_name:str, s3_prefix:str, expiration=600) -> str: + object_key = buffer_to_s3(s3_client, file, bucket_name, s3_prefix) + try: + response = s3_client.generate_presigned_url('get_object', + Params={'Bucket': bucket_name, 'Key': object_key}, + ExpiresIn=expiration) + except Exception as e: + print(f"Error generating presigned URL: {e}") + return None + + return response \ No newline at end of file diff --git a/api/core/model_runtime/model_providers/sagemaker/sagemaker.yaml b/api/core/model_runtime/model_providers/sagemaker/sagemaker.yaml index 290cb0edab..87cd50f50c 100644 --- a/api/core/model_runtime/model_providers/sagemaker/sagemaker.yaml +++ b/api/core/model_runtime/model_providers/sagemaker/sagemaker.yaml @@ -21,6 +21,8 @@ supported_model_types: - llm - text-embedding - rerank + - speech2text + - tts configurate_methods: - customizable-model model_credential_schema: @@ -45,14 +47,10 @@ model_credential_schema: zh_Hans: 选择对话类型 en_US: Select completion mode options: - - value: completion - label: - en_US: Completion - zh_Hans: 补全 - value: chat label: en_US: Chat - zh_Hans: 对话 + zh_Hans: Chat - variable: sagemaker_endpoint label: en_US: sagemaker endpoint @@ -61,6 +59,76 @@ model_credential_schema: placeholder: zh_Hans: 请输出你的Sagemaker推理端点 en_US: Enter your Sagemaker Inference endpoint + - variable: audio_s3_cache_bucket + show_on: + - variable: __model_type + value: speech2text + label: + zh_Hans: 音频缓存桶(s3 bucket) + en_US: audio cache bucket(s3 bucket) + type: text-input + required: true + placeholder: + zh_Hans: sagemaker-us-east-1-******207838 + en_US: sagemaker-us-east-1-*******7838 + - variable: audio_model_type + show_on: + - variable: __model_type + value: tts + label: + en_US: Audio model type + type: select + required: true + placeholder: + zh_Hans: 语音模型类型 + en_US: Audio model type + options: + - value: PresetVoice + label: + en_US: preset voice + zh_Hans: 内置音色 + - value: CloneVoice + label: + en_US: clone voice + zh_Hans: 克隆音色 + - value: CloneVoice_CrossLingual + label: + en_US: crosslingual clone voice + zh_Hans: 跨语种克隆音色 + - value: InstructVoice + label: + en_US: Instruct voice + zh_Hans: 文字指令音色 + - variable: prompt_audio + show_on: + - variable: __model_type + value: tts + label: + en_US: Mock Audio Source + type: text-input + required: false + placeholder: + zh_Hans: 被模仿的音色音频 + en_US: source audio to be mocked + - variable: prompt_text + show_on: + - variable: __model_type + value: tts + label: + en_US: Prompt Audio Text + type: text-input + required: false + placeholder: + zh_Hans: 模仿音色的对应文本 + en_US: text for the mocked source audio + - variable: instruct_text + show_on: + - variable: __model_type + value: tts + label: + en_US: instruct text for speaker + type: text-input + required: false - variable: aws_access_key_id required: false label: diff --git a/api/core/model_runtime/model_providers/sagemaker/speech2text/__init__.py b/api/core/model_runtime/model_providers/sagemaker/speech2text/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/core/model_runtime/model_providers/sagemaker/speech2text/speech2text.py b/api/core/model_runtime/model_providers/sagemaker/speech2text/speech2text.py new file mode 100644 index 0000000000..8b57f182fe --- /dev/null +++ b/api/core/model_runtime/model_providers/sagemaker/speech2text/speech2text.py @@ -0,0 +1,142 @@ +import json +import logging +from typing import IO, Any, Optional + +import boto3 + +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 ( + InvokeAuthorizationError, + InvokeBadRequestError, + InvokeConnectionError, + InvokeError, + InvokeRateLimitError, + InvokeServerUnavailableError, +) +from core.model_runtime.model_providers.__base.speech2text_model import Speech2TextModel +from core.model_runtime.model_providers.sagemaker.sagemaker import generate_presigned_url + +logger = logging.getLogger(__name__) + +class SageMakerSpeech2TextModel(Speech2TextModel): + """ + Model class for Xinference speech to text model. + """ + sagemaker_client: Any = None + s3_client : Any = None + + def _invoke(self, model: str, credentials: dict, + file: IO[bytes], user: Optional[str] = None) \ + -> str: + """ + Invoke speech2text model + + :param model: model name + :param credentials: model credentials + :param file: audio file + :param user: unique user id + :return: text for given audio file + """ + asr_text = None + + try: + if not self.sagemaker_client: + access_key = credentials.get('aws_access_key_id') + secret_key = credentials.get('aws_secret_access_key') + aws_region = credentials.get('aws_region') + if aws_region: + if access_key and secret_key: + self.sagemaker_client = boto3.client("sagemaker-runtime", + aws_access_key_id=access_key, + aws_secret_access_key=secret_key, + region_name=aws_region) + self.s3_client = boto3.client("s3", + aws_access_key_id=access_key, + aws_secret_access_key=secret_key, + region_name=aws_region) + else: + self.sagemaker_client = boto3.client("sagemaker-runtime", region_name=aws_region) + self.s3_client = boto3.client("s3", region_name=aws_region) + else: + self.sagemaker_client = boto3.client("sagemaker-runtime") + self.s3_client = boto3.client("s3") + + s3_prefix='dify/speech2text/' + sagemaker_endpoint = credentials.get('sagemaker_endpoint') + bucket = credentials.get('audio_s3_cache_bucket') + + s3_presign_url = generate_presigned_url(self.s3_client, file, bucket, s3_prefix) + payload = { + "audio_s3_presign_uri" : s3_presign_url + } + + response_model = self.sagemaker_client.invoke_endpoint( + EndpointName=sagemaker_endpoint, + Body=json.dumps(payload), + ContentType="application/json" + ) + json_str = response_model['Body'].read().decode('utf8') + json_obj = json.loads(json_str) + asr_text = json_obj['text'] + except Exception as e: + logger.exception(f'Exception {e}, line : {line}') + + return asr_text + + def validate_credentials(self, model: str, credentials: dict) -> None: + """ + Validate model credentials + + :param model: model name + :param credentials: model credentials + :return: + """ + pass + + @property + def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[Exception]]]: + """ + Map model invoke error to unified error + The key is the error type thrown to the caller + The value is the error type thrown by the model, + which needs to be converted into a unified error type for the caller. + + :return: Invoke error mapping + """ + return { + InvokeConnectionError: [ + InvokeConnectionError + ], + InvokeServerUnavailableError: [ + InvokeServerUnavailableError + ], + InvokeRateLimitError: [ + InvokeRateLimitError + ], + InvokeAuthorizationError: [ + InvokeAuthorizationError + ], + InvokeBadRequestError: [ + InvokeBadRequestError, + KeyError, + ValueError + ] + } + + 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/sagemaker/tts/__init__.py b/api/core/model_runtime/model_providers/sagemaker/tts/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/core/model_runtime/model_providers/sagemaker/tts/tts.py b/api/core/model_runtime/model_providers/sagemaker/tts/tts.py new file mode 100644 index 0000000000..315b31fd85 --- /dev/null +++ b/api/core/model_runtime/model_providers/sagemaker/tts/tts.py @@ -0,0 +1,287 @@ +import concurrent.futures +import copy +import json +import logging +from enum import Enum +from typing import Any, Optional + +import boto3 +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 ( + InvokeAuthorizationError, + InvokeBadRequestError, + InvokeConnectionError, + InvokeError, + InvokeRateLimitError, + InvokeServerUnavailableError, +) +from core.model_runtime.model_providers.__base.tts_model import TTSModel + +logger = logging.getLogger(__name__) + +class TTSModelType(Enum): + PresetVoice = "PresetVoice" + CloneVoice = "CloneVoice" + CloneVoice_CrossLingual = "CloneVoice_CrossLingual" + InstructVoice = "InstructVoice" + +class SageMakerText2SpeechModel(TTSModel): + + sagemaker_client: Any = None + s3_client : Any = None + comprehend_client : Any = None + + def __init__(self): + # preset voices, need support custom voice + self.model_voices = { + '__default': { + 'all': [ + {'name': 'Default', 'value': 'default'}, + ] + }, + 'CosyVoice': { + 'zh-Hans': [ + {'name': '中文男', 'value': '中文男'}, + {'name': '中文女', 'value': '中文女'}, + {'name': '粤语女', 'value': '粤语女'}, + ], + 'zh-Hant': [ + {'name': '中文男', 'value': '中文男'}, + {'name': '中文女', 'value': '中文女'}, + {'name': '粤语女', 'value': '粤语女'}, + ], + 'en-US': [ + {'name': '英文男', 'value': '英文男'}, + {'name': '英文女', 'value': '英文女'}, + ], + 'ja-JP': [ + {'name': '日语男', 'value': '日语男'}, + ], + 'ko-KR': [ + {'name': '韩语女', 'value': '韩语女'}, + ] + } + } + + def validate_credentials(self, model: str, credentials: dict) -> None: + """ + Validate model credentials + + :param model: model name + :param credentials: model credentials + :return: + """ + pass + + def _detect_lang_code(self, content:str, map_dict:dict=None): + map_dict = { + "zh" : "<|zh|>", + "en" : "<|en|>", + "ja" : "<|jp|>", + "zh-TW" : "<|yue|>", + "ko" : "<|ko|>" + } + + response = self.comprehend_client.detect_dominant_language(Text=content) + language_code = response['Languages'][0]['LanguageCode'] + + return map_dict.get(language_code, '<|zh|>') + + def _build_tts_payload(self, model_type:str, content_text:str, model_role:str, prompt_text:str, prompt_audio:str, instruct_text:str): + if model_type == TTSModelType.PresetVoice.value and model_role: + return { "tts_text" : content_text, "role" : model_role } + if model_type == TTSModelType.CloneVoice.value and prompt_text and prompt_audio: + return { "tts_text" : content_text, "prompt_text": prompt_text, "prompt_audio" : prompt_audio } + if model_type == TTSModelType.CloneVoice_CrossLingual.value and prompt_audio: + lang_tag = self._detect_lang_code(content_text) + return { "tts_text" : f"{content_text}", "prompt_audio" : prompt_audio, "lang_tag" : lang_tag } + if model_type == TTSModelType.InstructVoice.value and instruct_text and model_role: + return { "tts_text" : content_text, "role" : model_role, "instruct_text" : instruct_text } + + raise RuntimeError(f"Invalid params for {model_type}") + + def _invoke(self, model: str, tenant_id: str, credentials: dict, content_text: str, voice: str, + user: Optional[str] = None): + """ + _invoke text2speech model + + :param model: model name + :param tenant_id: user tenant id + :param credentials: model credentials + :param voice: model timbre + :param content_text: text content to be translated + :param user: unique user id + :return: text translated to audio file + """ + if not self.sagemaker_client: + access_key = credentials.get('aws_access_key_id') + secret_key = credentials.get('aws_secret_access_key') + aws_region = credentials.get('aws_region') + if aws_region: + if access_key and secret_key: + self.sagemaker_client = boto3.client("sagemaker-runtime", + aws_access_key_id=access_key, + aws_secret_access_key=secret_key, + region_name=aws_region) + self.s3_client = boto3.client("s3", + aws_access_key_id=access_key, + aws_secret_access_key=secret_key, + region_name=aws_region) + self.comprehend_client = boto3.client('comprehend', + aws_access_key_id=access_key, + aws_secret_access_key=secret_key, + region_name=aws_region) + else: + self.sagemaker_client = boto3.client("sagemaker-runtime", region_name=aws_region) + self.s3_client = boto3.client("s3", region_name=aws_region) + self.comprehend_client = boto3.client('comprehend', region_name=aws_region) + else: + self.sagemaker_client = boto3.client("sagemaker-runtime") + self.s3_client = boto3.client("s3") + self.comprehend_client = boto3.client('comprehend') + + model_type = credentials.get('audio_model_type', 'PresetVoice') + prompt_text = credentials.get('prompt_text') + prompt_audio = credentials.get('prompt_audio') + instruct_text = credentials.get('instruct_text') + sagemaker_endpoint = credentials.get('sagemaker_endpoint') + payload = self._build_tts_payload( + model_type, + content_text, + voice, + prompt_text, + prompt_audio, + instruct_text + ) + + return self._tts_invoke_streaming(model_type, payload, sagemaker_endpoint) + + 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.TTS, + model_properties={}, + parameter_rules=[] + ) + + return entity + + @property + def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[Exception]]]: + """ + Map model invoke error to unified error + The key is the error type thrown to the caller + The value is the error type thrown by the model, + which needs to be converted into a unified error type for the caller. + + :return: Invoke error mapping + """ + return { + InvokeConnectionError: [ + InvokeConnectionError + ], + InvokeServerUnavailableError: [ + InvokeServerUnavailableError + ], + InvokeRateLimitError: [ + InvokeRateLimitError + ], + InvokeAuthorizationError: [ + InvokeAuthorizationError + ], + InvokeBadRequestError: [ + InvokeBadRequestError, + KeyError, + ValueError + ] + } + + def _get_model_default_voice(self, model: str, credentials: dict) -> any: + return "" + + def _get_model_word_limit(self, model: str, credentials: dict) -> int: + return 15 + + def _get_model_audio_type(self, model: str, credentials: dict) -> str: + return "mp3" + + def _get_model_workers_limit(self, model: str, credentials: dict) -> int: + return 5 + + def get_tts_model_voices(self, model: str, credentials: dict, language: Optional[str] = None) -> list: + audio_model_name = 'CosyVoice' + for key, voices in self.model_voices.items(): + if key in audio_model_name: + if language and language in voices: + return voices[language] + elif 'all' in voices: + return voices['all'] + + return self.model_voices['__default']['all'] + + def _invoke_sagemaker(self, payload:dict, endpoint:str): + response_model = self.sagemaker_client.invoke_endpoint( + EndpointName=endpoint, + Body=json.dumps(payload), + ContentType="application/json", + ) + json_str = response_model['Body'].read().decode('utf8') + json_obj = json.loads(json_str) + return json_obj + + def _tts_invoke_streaming(self, model_type:str, payload:dict, sagemaker_endpoint:str) -> any: + """ + _tts_invoke_streaming text2speech model + + :param model: model name + :param credentials: model credentials + :param content_text: text content to be translated + :param voice: model timbre + :return: text translated to audio file + """ + try: + lang_tag = '' + if model_type == TTSModelType.CloneVoice_CrossLingual.value: + lang_tag = payload.pop('lang_tag') + + word_limit = self._get_model_word_limit(model='', credentials={}) + content_text = payload.get("tts_text") + if len(content_text) > word_limit: + split_sentences = self._split_text_into_sentences(content_text, max_length=word_limit) + sentences = [ f"{lang_tag}{s}" for s in split_sentences if len(s) ] + len_sent = len(sentences) + executor = concurrent.futures.ThreadPoolExecutor(max_workers=min(4, len_sent)) + payloads = [ copy.deepcopy(payload) for i in range(len_sent) ] + for idx in range(len_sent): + payloads[idx]["tts_text"] = sentences[idx] + + futures = [ executor.submit( + self._invoke_sagemaker, + payload=payload, + endpoint=sagemaker_endpoint, + ) + for payload in payloads] + + for index, future in enumerate(futures): + resp = future.result() + audio_bytes = requests.get(resp.get('s3_presign_url')).content + for i in range(0, len(audio_bytes), 1024): + yield audio_bytes[i:i + 1024] + else: + resp = self._invoke_sagemaker(payload, sagemaker_endpoint) + audio_bytes = requests.get(resp.get('s3_presign_url')).content + + for i in range(0, len(audio_bytes), 1024): + yield audio_bytes[i:i + 1024] + except Exception as ex: + raise InvokeBadRequestError(str(ex)) diff --git a/api/core/model_runtime/model_providers/spark/llm/_client.py b/api/core/model_runtime/model_providers/spark/llm/_client.py index 10da265701..d57766a87a 100644 --- a/api/core/model_runtime/model_providers/spark/llm/_client.py +++ b/api/core/model_runtime/model_providers/spark/llm/_client.py @@ -19,27 +19,25 @@ class SparkLLMClient: endpoint = 'chat' if api_domain: domain = api_domain - if model == 'spark-v3': - endpoint = 'multimodal' model_api_configs = { - 'spark-1.5': { + 'spark-lite': { 'version': 'v1.1', 'chat_domain': 'general' }, - 'spark-2': { - 'version': 'v2.1', - 'chat_domain': 'generalv2' - }, - 'spark-3': { + 'spark-pro': { 'version': 'v3.1', 'chat_domain': 'generalv3' }, - 'spark-3.5': { + 'spark-pro-128k': { + 'version': 'pro-128k', + 'chat_domain': 'pro-128k' + }, + 'spark-max': { 'version': 'v3.5', 'chat_domain': 'generalv3.5' }, - 'spark-4': { + 'spark-4.0-ultra': { 'version': 'v4.0', 'chat_domain': '4.0Ultra' } @@ -48,7 +46,12 @@ class SparkLLMClient: api_version = model_api_configs[model]['version'] self.chat_domain = model_api_configs[model]['chat_domain'] - self.api_base = f"wss://{domain}/{api_version}/{endpoint}" + + if model == 'spark-pro-128k': + self.api_base = f"wss://{domain}/{endpoint}/{api_version}" + else: + self.api_base = f"wss://{domain}/{api_version}/{endpoint}" + self.app_id = app_id self.ws_url = self.create_url( urlparse(self.api_base).netloc, diff --git a/api/core/model_runtime/model_providers/spark/llm/_position.yaml b/api/core/model_runtime/model_providers/spark/llm/_position.yaml index e49ee97db7..458397f2aa 100644 --- a/api/core/model_runtime/model_providers/spark/llm/_position.yaml +++ b/api/core/model_runtime/model_providers/spark/llm/_position.yaml @@ -1,3 +1,8 @@ +- spark-4.0-ultra +- spark-max +- spark-pro-128k +- spark-pro +- spark-lite - spark-4 - spark-3.5 - spark-3 diff --git a/api/core/model_runtime/model_providers/spark/llm/spark-1.5.yaml b/api/core/model_runtime/model_providers/spark/llm/spark-1.5.yaml index 41b8765fe6..fcd65c24e0 100644 --- a/api/core/model_runtime/model_providers/spark/llm/spark-1.5.yaml +++ b/api/core/model_runtime/model_providers/spark/llm/spark-1.5.yaml @@ -1,4 +1,5 @@ model: spark-1.5 +deprecated: true label: en_US: Spark V1.5 model_type: llm diff --git a/api/core/model_runtime/model_providers/spark/llm/spark-3.5.yaml b/api/core/model_runtime/model_providers/spark/llm/spark-3.5.yaml index 6d24932ea8..86617a53d0 100644 --- a/api/core/model_runtime/model_providers/spark/llm/spark-3.5.yaml +++ b/api/core/model_runtime/model_providers/spark/llm/spark-3.5.yaml @@ -1,4 +1,5 @@ model: spark-3.5 +deprecated: true label: en_US: Spark V3.5 model_type: llm diff --git a/api/core/model_runtime/model_providers/spark/llm/spark-3.yaml b/api/core/model_runtime/model_providers/spark/llm/spark-3.yaml index 2ef9e10f45..9f296c684d 100644 --- a/api/core/model_runtime/model_providers/spark/llm/spark-3.yaml +++ b/api/core/model_runtime/model_providers/spark/llm/spark-3.yaml @@ -1,4 +1,5 @@ model: spark-3 +deprecated: true label: en_US: Spark V3.0 model_type: llm diff --git a/api/core/model_runtime/model_providers/spark/llm/spark-4.0-ultra.yaml b/api/core/model_runtime/model_providers/spark/llm/spark-4.0-ultra.yaml new file mode 100644 index 0000000000..bbf85764f1 --- /dev/null +++ b/api/core/model_runtime/model_providers/spark/llm/spark-4.0-ultra.yaml @@ -0,0 +1,42 @@ +model: spark-4.0-ultra +label: + en_US: Spark 4.0 Ultra +model_type: llm +model_properties: + mode: chat +parameter_rules: + - name: temperature + use_template: temperature + default: 0.5 + help: + zh_Hans: 核采样阈值。用于决定结果随机性,取值越高随机性越强即相同的问题得到的不同答案的可能性越高。 + en_US: Kernel sampling threshold. Used to determine the randomness of the results. The higher the value, the stronger the randomness, that is, the higher the possibility of getting different answers to the same question. + - name: max_tokens + use_template: max_tokens + default: 4096 + min: 1 + max: 8192 + help: + zh_Hans: 模型回答的tokens的最大长度。 + en_US: Maximum length of tokens for the model response. + - name: top_k + label: + zh_Hans: 取样数量 + en_US: Top k + type: int + default: 4 + min: 1 + max: 6 + help: + zh_Hans: 从 k 个候选中随机选择一个(非等概率)。 + en_US: Randomly select one from k candidates (non-equal probability). + required: false + - name: show_ref_label + label: + zh_Hans: 联网检索 + en_US: web search + type: boolean + default: false + help: + zh_Hans: 该参数仅4.0 Ultra版本支持,当设置为true时,如果输入内容触发联网检索插件,会先返回检索信源列表,然后再返回星火回复结果,否则仅返回星火回复结果 + en_US: The parameter is only supported in the 4.0 Ultra version. When set to true, if the input triggers the online search plugin, it will first return a list of search sources and then return the Spark response. Otherwise, it will only return the Spark response. diff --git a/api/core/model_runtime/model_providers/spark/llm/spark-4.yaml b/api/core/model_runtime/model_providers/spark/llm/spark-4.yaml index 4b0bf27029..4b5529e81c 100644 --- a/api/core/model_runtime/model_providers/spark/llm/spark-4.yaml +++ b/api/core/model_runtime/model_providers/spark/llm/spark-4.yaml @@ -1,4 +1,5 @@ model: spark-4 +deprecated: true label: en_US: Spark V4.0 model_type: llm diff --git a/api/core/model_runtime/model_providers/spark/llm/spark-lite.yaml b/api/core/model_runtime/model_providers/spark/llm/spark-lite.yaml new file mode 100644 index 0000000000..1f6141a816 --- /dev/null +++ b/api/core/model_runtime/model_providers/spark/llm/spark-lite.yaml @@ -0,0 +1,33 @@ +model: spark-lite +label: + en_US: Spark Lite +model_type: llm +model_properties: + mode: chat +parameter_rules: + - name: temperature + use_template: temperature + default: 0.5 + help: + zh_Hans: 核采样阈值。用于决定结果随机性,取值越高随机性越强即相同的问题得到的不同答案的可能性越高。 + en_US: Kernel sampling threshold. Used to determine the randomness of the results. The higher the value, the stronger the randomness, that is, the higher the possibility of getting different answers to the same question. + - name: max_tokens + use_template: max_tokens + default: 4096 + min: 1 + max: 4096 + help: + zh_Hans: 模型回答的tokens的最大长度。 + en_US: Maximum length of tokens for the model response. + - name: top_k + label: + zh_Hans: 取样数量 + en_US: Top k + type: int + default: 4 + min: 1 + max: 6 + help: + zh_Hans: 从 k 个候选中随机选择一个(非等概率)。 + en_US: Randomly select one from k candidates (non-equal probability). + required: false diff --git a/api/core/model_runtime/model_providers/spark/llm/spark-max.yaml b/api/core/model_runtime/model_providers/spark/llm/spark-max.yaml new file mode 100644 index 0000000000..71eb2b86d3 --- /dev/null +++ b/api/core/model_runtime/model_providers/spark/llm/spark-max.yaml @@ -0,0 +1,33 @@ +model: spark-max +label: + en_US: Spark Max +model_type: llm +model_properties: + mode: chat +parameter_rules: + - name: temperature + use_template: temperature + default: 0.5 + help: + zh_Hans: 核采样阈值。用于决定结果随机性,取值越高随机性越强即相同的问题得到的不同答案的可能性越高。 + en_US: Kernel sampling threshold. Used to determine the randomness of the results. The higher the value, the stronger the randomness, that is, the higher the possibility of getting different answers to the same question. + - name: max_tokens + use_template: max_tokens + default: 4096 + min: 1 + max: 8192 + help: + zh_Hans: 模型回答的tokens的最大长度。 + en_US: Maximum length of tokens for the model response. + - name: top_k + label: + zh_Hans: 取样数量 + en_US: Top k + type: int + default: 4 + min: 1 + max: 6 + help: + zh_Hans: 从 k 个候选中随机选择一个(非等概率)。 + en_US: Randomly select one from k candidates (non-equal probability). + required: false diff --git a/api/core/model_runtime/model_providers/spark/llm/spark-pro-128k.yaml b/api/core/model_runtime/model_providers/spark/llm/spark-pro-128k.yaml new file mode 100644 index 0000000000..da1fead6da --- /dev/null +++ b/api/core/model_runtime/model_providers/spark/llm/spark-pro-128k.yaml @@ -0,0 +1,33 @@ +model: spark-pro-128k +label: + en_US: Spark Pro-128K +model_type: llm +model_properties: + mode: chat +parameter_rules: + - name: temperature + use_template: temperature + default: 0.5 + help: + zh_Hans: 核采样阈值。用于决定结果随机性,取值越高随机性越强即相同的问题得到的不同答案的可能性越高。 + en_US: Kernel sampling threshold. Used to determine the randomness of the results. The higher the value, the stronger the randomness, that is, the higher the possibility of getting different answers to the same question. + - name: max_tokens + use_template: max_tokens + default: 4096 + min: 1 + max: 4096 + help: + zh_Hans: 模型回答的tokens的最大长度。 + en_US: Maximum length of tokens for the model response. + - name: top_k + label: + zh_Hans: 取样数量 + en_US: Top k + type: int + default: 4 + min: 1 + max: 6 + help: + zh_Hans: 从 k 个候选中随机选择一个(非等概率)。 + en_US: Randomly select one from k candidates (non-equal probability). + required: false diff --git a/api/core/model_runtime/model_providers/spark/llm/spark-pro.yaml b/api/core/model_runtime/model_providers/spark/llm/spark-pro.yaml new file mode 100644 index 0000000000..9ee479f15b --- /dev/null +++ b/api/core/model_runtime/model_providers/spark/llm/spark-pro.yaml @@ -0,0 +1,33 @@ +model: spark-pro +label: + en_US: Spark Pro +model_type: llm +model_properties: + mode: chat +parameter_rules: + - name: temperature + use_template: temperature + default: 0.5 + help: + zh_Hans: 核采样阈值。用于决定结果随机性,取值越高随机性越强即相同的问题得到的不同答案的可能性越高。 + en_US: Kernel sampling threshold. Used to determine the randomness of the results. The higher the value, the stronger the randomness, that is, the higher the possibility of getting different answers to the same question. + - name: max_tokens + use_template: max_tokens + default: 4096 + min: 1 + max: 8192 + help: + zh_Hans: 模型回答的tokens的最大长度。 + en_US: Maximum length of tokens for the model response. + - name: top_k + label: + zh_Hans: 取样数量 + en_US: Top k + type: int + default: 4 + min: 1 + max: 6 + help: + zh_Hans: 从 k 个候选中随机选择一个(非等概率)。 + en_US: Randomly select one from k candidates (non-equal probability). + required: false diff --git a/api/core/model_runtime/model_providers/tencent/speech2text/flash_recognizer.py b/api/core/model_runtime/model_providers/tencent/speech2text/flash_recognizer.py index c3e3b7c258..b62b9860cb 100644 --- a/api/core/model_runtime/model_providers/tencent/speech2text/flash_recognizer.py +++ b/api/core/model_runtime/model_providers/tencent/speech2text/flash_recognizer.py @@ -67,7 +67,7 @@ class FlashRecognitionRequest: class FlashRecognizer: """ - reponse: + response: request_id string status Integer message String @@ -132,9 +132,9 @@ class FlashRecognizer: signstr = self._format_sign_string(query) signature = self._sign(signstr, secret_key) header["Authorization"] = signature - requrl = "https://" - requrl += signstr[4::] - return requrl + req_url = "https://" + req_url += signstr[4::] + return req_url def _create_query_arr(self, req): return { diff --git a/api/core/model_runtime/model_providers/tongyi/llm/llm.py b/api/core/model_runtime/model_providers/tongyi/llm/llm.py index 4e1bb0a5a4..6667d40440 100644 --- a/api/core/model_runtime/model_providers/tongyi/llm/llm.py +++ b/api/core/model_runtime/model_providers/tongyi/llm/llm.py @@ -17,7 +17,6 @@ from dashscope.common.error import ( UnsupportedModel, ) -from core.model_runtime.callbacks.base_callback import Callback from core.model_runtime.entities.llm_entities import LLMResult, LLMResultChunk, LLMResultChunkDelta from core.model_runtime.entities.message_entities import ( AssistantPromptMessage, @@ -64,88 +63,8 @@ class TongyiLargeLanguageModel(LargeLanguageModel): :param user: unique user id :return: full response or stream response chunk generator result """ - # invoke model + # invoke model without code wrapper return self._generate(model, credentials, prompt_messages, model_parameters, tools, stop, stream, user) - - def _code_block_mode_wrapper(self, model: str, credentials: dict, - prompt_messages: list[PromptMessage], model_parameters: dict, - tools: list[PromptMessageTool] | None = None, stop: list[str] | None = None, - stream: bool = True, user: str | None = None, callbacks: list[Callback] = None) \ - -> LLMResult | Generator: - """ - Wrapper for code block mode - """ - block_prompts = """You should always follow the instructions and output a valid {{block}} object. -The structure of the {{block}} object you can found in the instructions, use {"answer": "$your_answer"} as the default structure -if you are not sure about the structure. - - -{{instructions}} - -You should also complete the text started with ``` but not tell ``` directly. -""" - - code_block = model_parameters.get("response_format", "") - if not code_block: - return self._invoke( - model=model, - credentials=credentials, - prompt_messages=prompt_messages, - model_parameters=model_parameters, - tools=tools, - stop=stop, - stream=stream, - user=user - ) - - model_parameters.pop("response_format") - stop = stop or [] - stop.extend(["\n```", "```\n"]) - block_prompts = block_prompts.replace("{{block}}", code_block) - - # check if there is a system message - if len(prompt_messages) > 0 and isinstance(prompt_messages[0], SystemPromptMessage): - # override the system message - prompt_messages[0] = SystemPromptMessage( - content=block_prompts - .replace("{{instructions}}", prompt_messages[0].content) - ) - else: - # insert the system message - prompt_messages.insert(0, SystemPromptMessage( - content=block_prompts - .replace("{{instructions}}", f"Please output a valid {code_block} with markdown codeblocks.") - )) - - if len(prompt_messages) > 0 and isinstance(prompt_messages[-1], UserPromptMessage): - # add ```JSON\n to the last message - prompt_messages[-1].content += f"\n```{code_block}\n" - else: - # append a user message - prompt_messages.append(UserPromptMessage( - content=f"```{code_block}\n" - )) - - response = self._invoke( - model=model, - credentials=credentials, - prompt_messages=prompt_messages, - model_parameters=model_parameters, - tools=tools, - stop=stop, - stream=stream, - user=user - ) - - if isinstance(response, Generator): - return self._code_block_mode_stream_processor_with_backtick( - model=model, - prompt_messages=prompt_messages, - input_generator=response - ) - - return response - def get_num_tokens(self, model: str, credentials: dict, prompt_messages: list[PromptMessage], tools: Optional[list[PromptMessageTool]] = None) -> int: """ diff --git a/api/core/model_runtime/model_providers/tongyi/llm/qwen-long.yaml b/api/core/model_runtime/model_providers/tongyi/llm/qwen-long.yaml index b2cf3dd486..33b3435eb6 100644 --- a/api/core/model_runtime/model_providers/tongyi/llm/qwen-long.yaml +++ b/api/core/model_runtime/model_providers/tongyi/llm/qwen-long.yaml @@ -24,7 +24,7 @@ parameter_rules: type: int default: 2000 min: 1 - max: 2000 + max: 6000 help: zh_Hans: 用于指定模型在生成内容时token的最大数量,它定义了生成的上限,但不保证每次都会生成到这个数量。 en_US: It is used to specify the maximum number of tokens when the model generates content. It defines the upper limit of generation, but does not guarantee that this number will be generated every time. diff --git a/api/core/model_runtime/model_providers/vertex_ai/llm/llm.py b/api/core/model_runtime/model_providers/vertex_ai/llm/llm.py index 1a7368a2cf..af6ec3937c 100644 --- a/api/core/model_runtime/model_providers/vertex_ai/llm/llm.py +++ b/api/core/model_runtime/model_providers/vertex_ai/llm/llm.py @@ -695,11 +695,11 @@ class VertexAiLargeLanguageModel(LargeLanguageModel): def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[Exception]]]: """ Map model invoke error to unified error - The key is the ermd = gml.GenerativeModel(model)ror type thrown to the caller - The value is the md = gml.GenerativeModel(model)error type thrown by the model, + The key is the ermd = gml.GenerativeModel(model) error type thrown to the caller + The value is the md = gml.GenerativeModel(model) error type thrown by the model, which needs to be converted into a unified error type for the caller. - :return: Invoke emd = gml.GenerativeModel(model)rror mapping + :return: Invoke emd = gml.GenerativeModel(model) error mapping """ return { InvokeConnectionError: [ diff --git a/api/core/model_runtime/model_providers/volcengine_maas/client.py b/api/core/model_runtime/model_providers/volcengine_maas/client.py index 61f3521a43..a4d89dabcb 100644 --- a/api/core/model_runtime/model_providers/volcengine_maas/client.py +++ b/api/core/model_runtime/model_providers/volcengine_maas/client.py @@ -71,11 +71,24 @@ class ArkClientV3: args = { "base_url": credentials['api_endpoint_host'], "region": credentials['volc_region'], - "ak": credentials['volc_access_key_id'], - "sk": credentials['volc_secret_access_key'], } + if credentials.get("auth_method") == "api_key": + args = { + **args, + "api_key": credentials['volc_api_key'], + } + else: + args = { + **args, + "ak": credentials['volc_access_key_id'], + "sk": credentials['volc_secret_access_key'], + } + if cls.is_compatible_with_legacy(credentials): - args["base_url"] = DEFAULT_V3_ENDPOINT + args = { + **args, + "base_url": DEFAULT_V3_ENDPOINT + } client = ArkClientV3( **args diff --git a/api/core/model_runtime/model_providers/volcengine_maas/volcengine_maas.yaml b/api/core/model_runtime/model_providers/volcengine_maas/volcengine_maas.yaml index 735ba2b314..13e00da76f 100644 --- a/api/core/model_runtime/model_providers/volcengine_maas/volcengine_maas.yaml +++ b/api/core/model_runtime/model_providers/volcengine_maas/volcengine_maas.yaml @@ -30,8 +30,28 @@ model_credential_schema: en_US: Enter your Model Name zh_Hans: 输入模型名称 credential_form_schemas: + - variable: auth_method + required: true + label: + en_US: Authentication Method + zh_Hans: 鉴权方式 + type: select + default: aksk + options: + - label: + en_US: API Key + value: api_key + - label: + en_US: Access Key / Secret Access Key + value: aksk + placeholder: + en_US: Enter your Authentication Method + zh_Hans: 选择鉴权方式 - variable: volc_access_key_id required: true + show_on: + - variable: auth_method + value: aksk label: en_US: Access Key zh_Hans: Access Key @@ -41,6 +61,9 @@ model_credential_schema: zh_Hans: 输入您的 Access Key - variable: volc_secret_access_key required: true + show_on: + - variable: auth_method + value: aksk label: en_US: Secret Access Key zh_Hans: Secret Access Key @@ -48,6 +71,17 @@ model_credential_schema: placeholder: en_US: Enter your Secret Access Key zh_Hans: 输入您的 Secret Access Key + - variable: volc_api_key + required: true + show_on: + - variable: auth_method + value: api_key + label: + en_US: API Key + type: secret-input + placeholder: + en_US: Enter your API Key + zh_Hans: 输入您的 API Key - variable: volc_region required: true label: diff --git a/api/core/model_runtime/model_providers/wenxin/_common.py b/api/core/model_runtime/model_providers/wenxin/_common.py index 0230c78b75..017856bdde 100644 --- a/api/core/model_runtime/model_providers/wenxin/_common.py +++ b/api/core/model_runtime/model_providers/wenxin/_common.py @@ -79,11 +79,13 @@ class BaiduAccessToken: # if access token not in cache, request it token = BaiduAccessToken(api_key) baidu_access_tokens[api_key] = token - # release it to enhance performance - # btw, _get_access_token will raise exception if failed, release lock here to avoid deadlock - baidu_access_tokens_lock.release() - # try to get access token - token_str = BaiduAccessToken._get_access_token(api_key, secret_key) + try: + # try to get access token + token_str = BaiduAccessToken._get_access_token(api_key, secret_key) + finally: + # release it to enhance performance + # btw, _get_access_token will raise exception if failed, release lock here to avoid deadlock + baidu_access_tokens_lock.release() token.access_token = token_str token.expires = now + timedelta(days=3) return token diff --git a/api/core/model_runtime/model_providers/xinference/tts/tts.py b/api/core/model_runtime/model_providers/xinference/tts/tts.py index bfa752df8c..8cc99fef7c 100644 --- a/api/core/model_runtime/model_providers/xinference/tts/tts.py +++ b/api/core/model_runtime/model_providers/xinference/tts/tts.py @@ -174,6 +174,11 @@ class XinferenceText2SpeechModel(TTSModel): return voices[language] elif 'all' in voices: return voices['all'] + else: + all_voices = [] + for lang, lang_voices in voices.items(): + all_voices.extend(lang_voices) + return all_voices return self.model_voices['__default']['all'] diff --git a/api/core/model_runtime/model_providers/xinference/xinference_helper.py b/api/core/model_runtime/model_providers/xinference/xinference_helper.py index 75161ad376..151166f165 100644 --- a/api/core/model_runtime/model_providers/xinference/xinference_helper.py +++ b/api/core/model_runtime/model_providers/xinference/xinference_helper.py @@ -89,7 +89,7 @@ class XinferenceHelper: model_handle_type = 'embedding' elif response_json.get('model_type') == 'audio': model_handle_type = 'audio' - if model_family and model_family in ['ChatTTS', 'CosyVoice']: + if model_family and model_family in ['ChatTTS', 'CosyVoice', 'FishAudio']: model_ability.append('text-to-audio') else: model_ability.append('audio-to-text') diff --git a/api/core/model_runtime/model_providers/zhipuai/llm/chatglm_turbo.yaml b/api/core/model_runtime/model_providers/zhipuai/llm/chatglm_turbo.yaml index 8f51f80967..fcd5c5ef64 100644 --- a/api/core/model_runtime/model_providers/zhipuai/llm/chatglm_turbo.yaml +++ b/api/core/model_runtime/model_providers/zhipuai/llm/chatglm_turbo.yaml @@ -19,15 +19,24 @@ parameter_rules: help: zh_Hans: 用温度取样的另一种方法,称为核取样取值范围是:(0.0, 1.0) 开区间,不能等于 0 或 1,默认值为 0.7 模型考虑具有 top_p 概率质量tokens的结果例如:0.1 意味着模型解码器只考虑从前 10% 的概率的候选集中取 tokens 建议您根据应用场景调整 top_p 或 temperature 参数,但不要同时调整两个参数。 en_US: Another method of temperature sampling is called kernel sampling. The value range is (0.0, 1.0) open interval, which cannot be equal to 0 or 1. The default value is 0.7. The model considers the results with top_p probability mass tokens. For example 0.1 means The model decoder only considers tokens from the candidate set with the top 10% probability. It is recommended that you adjust the top_p or temperature parameters according to the application scenario, but do not adjust both parameters at the same time. - - name: incremental + - name: do_sample label: - zh_Hans: 增量返回 - en_US: Incremental + zh_Hans: 采样策略 + en_US: Sampling strategy type: boolean help: - zh_Hans: SSE接口调用时,用于控制每次返回内容方式是增量还是全量,不提供此参数时默认为增量返回,true 为增量返回,false 为全量返回。 - en_US: When the SSE interface is called, it is used to control whether the content is returned incrementally or in full. If this parameter is not provided, the default is incremental return. true means incremental return, false means full return. - required: false + zh_Hans: do_sample 为 true 时启用采样策略,do_sample 为 false 时采样策略 temperature、top_p 将不生效。默认值为 true。 + en_US: When `do_sample` is set to true, the sampling strategy is enabled. When `do_sample` is set to false, the sampling strategies such as `temperature` and `top_p` will not take effect. The default value is true. + default: true + - name: stream + label: + zh_Hans: 流处理 + en_US: Event Stream + type: boolean + help: + zh_Hans: 使用同步调用时,此参数应当设置为 fasle 或者省略。表示模型生成完所有内容后一次性返回所有内容。默认值为 false。如果设置为 true,模型将通过标准 Event Stream ,逐块返回模型生成内容。Event Stream 结束时会返回一条data:[DONE]消息。注意:在模型流式输出生成内容的过程中,我们会分批对模型生成内容进行检测,当检测到违法及不良信息时,API会返回错误码(1301)。开发者识别到错误码(1301),应及时采取(清屏、重启对话)等措施删除生成内容,并确保不将含有违法及不良信息的内容传递给模型继续生成,避免其造成负面影响。 + en_US: When using synchronous invocation, this parameter should be set to false or omitted. It indicates that the model will return all the generated content at once after the generation is complete. The default value is false. If set to true, the model will return the generated content in chunks via the standard Event Stream. A data:[DONE] message will be sent at the end of the Event Stream.Note:During the model's streaming output process, we will batch check the generated content. If illegal or harmful information is detected, the API will return an error code (1301). Developers who identify error code (1301) should promptly take actions such as clearing the screen or restarting the conversation to delete the generated content. They should also ensure that no illegal or harmful content is passed back to the model for continued generation to avoid negative impacts. + default: false - name: return_type label: zh_Hans: 回复类型 diff --git a/api/core/model_runtime/model_providers/zhipuai/llm/glm-4-0520.yaml b/api/core/model_runtime/model_providers/zhipuai/llm/glm-4-0520.yaml index 8391278e4f..b1f9b7485c 100644 --- a/api/core/model_runtime/model_providers/zhipuai/llm/glm-4-0520.yaml +++ b/api/core/model_runtime/model_providers/zhipuai/llm/glm-4-0520.yaml @@ -23,20 +23,29 @@ parameter_rules: help: zh_Hans: 用温度取样的另一种方法,称为核取样取值范围是:(0.0, 1.0) 开区间,不能等于 0 或 1,默认值为 0.7 模型考虑具有 top_p 概率质量tokens的结果例如:0.1 意味着模型解码器只考虑从前 10% 的概率的候选集中取 tokens 建议您根据应用场景调整 top_p 或 temperature 参数,但不要同时调整两个参数。 en_US: Another method of temperature sampling is called kernel sampling. The value range is (0.0, 1.0) open interval, which cannot be equal to 0 or 1. The default value is 0.7. The model considers the results with top_p probability mass tokens. For example 0.1 means The model decoder only considers tokens from the candidate set with the top 10% probability. It is recommended that you adjust the top_p or temperature parameters according to the application scenario, but do not adjust both parameters at the same time. - - name: incremental + - name: do_sample label: - zh_Hans: 增量返回 - en_US: Incremental + zh_Hans: 采样策略 + en_US: Sampling strategy type: boolean help: - zh_Hans: SSE接口调用时,用于控制每次返回内容方式是增量还是全量,不提供此参数时默认为增量返回,true 为增量返回,false 为全量返回。 - en_US: When the SSE interface is called, it is used to control whether the content is returned incrementally or in full. If this parameter is not provided, the default is incremental return. true means incremental return, false means full return. - required: false + zh_Hans: do_sample 为 true 时启用采样策略,do_sample 为 false 时采样策略 temperature、top_p 将不生效。默认值为 true。 + en_US: When `do_sample` is set to true, the sampling strategy is enabled. When `do_sample` is set to false, the sampling strategies such as `temperature` and `top_p` will not take effect. The default value is true. + default: true + - name: stream + label: + zh_Hans: 流处理 + en_US: Event Stream + type: boolean + help: + zh_Hans: 使用同步调用时,此参数应当设置为 fasle 或者省略。表示模型生成完所有内容后一次性返回所有内容。默认值为 false。如果设置为 true,模型将通过标准 Event Stream ,逐块返回模型生成内容。Event Stream 结束时会返回一条data:[DONE]消息。注意:在模型流式输出生成内容的过程中,我们会分批对模型生成内容进行检测,当检测到违法及不良信息时,API会返回错误码(1301)。开发者识别到错误码(1301),应及时采取(清屏、重启对话)等措施删除生成内容,并确保不将含有违法及不良信息的内容传递给模型继续生成,避免其造成负面影响。 + en_US: When using synchronous invocation, this parameter should be set to false or omitted. It indicates that the model will return all the generated content at once after the generation is complete. The default value is false. If set to true, the model will return the generated content in chunks via the standard Event Stream. A data:[DONE] message will be sent at the end of the Event Stream.Note:During the model's streaming output process, we will batch check the generated content. If illegal or harmful information is detected, the API will return an error code (1301). Developers who identify error code (1301) should promptly take actions such as clearing the screen or restarting the conversation to delete the generated content. They should also ensure that no illegal or harmful content is passed back to the model for continued generation to avoid negative impacts. + default: false - name: max_tokens use_template: max_tokens default: 1024 min: 1 - max: 8192 + max: 4095 pricing: input: '0.1' output: '0.1' diff --git a/api/core/model_runtime/model_providers/zhipuai/llm/glm-4-air.yaml b/api/core/model_runtime/model_providers/zhipuai/llm/glm-4-air.yaml index 7caebd3e4b..4e7d5fd3cc 100644 --- a/api/core/model_runtime/model_providers/zhipuai/llm/glm-4-air.yaml +++ b/api/core/model_runtime/model_providers/zhipuai/llm/glm-4-air.yaml @@ -23,20 +23,29 @@ parameter_rules: help: zh_Hans: 用温度取样的另一种方法,称为核取样取值范围是:(0.0, 1.0) 开区间,不能等于 0 或 1,默认值为 0.7 模型考虑具有 top_p 概率质量tokens的结果例如:0.1 意味着模型解码器只考虑从前 10% 的概率的候选集中取 tokens 建议您根据应用场景调整 top_p 或 temperature 参数,但不要同时调整两个参数。 en_US: Another method of temperature sampling is called kernel sampling. The value range is (0.0, 1.0) open interval, which cannot be equal to 0 or 1. The default value is 0.7. The model considers the results with top_p probability mass tokens. For example 0.1 means The model decoder only considers tokens from the candidate set with the top 10% probability. It is recommended that you adjust the top_p or temperature parameters according to the application scenario, but do not adjust both parameters at the same time. - - name: incremental + - name: do_sample label: - zh_Hans: 增量返回 - en_US: Incremental + zh_Hans: 采样策略 + en_US: Sampling strategy type: boolean help: - zh_Hans: SSE接口调用时,用于控制每次返回内容方式是增量还是全量,不提供此参数时默认为增量返回,true 为增量返回,false 为全量返回。 - en_US: When the SSE interface is called, it is used to control whether the content is returned incrementally or in full. If this parameter is not provided, the default is incremental return. true means incremental return, false means full return. - required: false + zh_Hans: do_sample 为 true 时启用采样策略,do_sample 为 false 时采样策略 temperature、top_p 将不生效。默认值为 true。 + en_US: When `do_sample` is set to true, the sampling strategy is enabled. When `do_sample` is set to false, the sampling strategies such as `temperature` and `top_p` will not take effect. The default value is true. + default: true + - name: stream + label: + zh_Hans: 流处理 + en_US: Event Stream + type: boolean + help: + zh_Hans: 使用同步调用时,此参数应当设置为 fasle 或者省略。表示模型生成完所有内容后一次性返回所有内容。默认值为 false。如果设置为 true,模型将通过标准 Event Stream ,逐块返回模型生成内容。Event Stream 结束时会返回一条data:[DONE]消息。注意:在模型流式输出生成内容的过程中,我们会分批对模型生成内容进行检测,当检测到违法及不良信息时,API会返回错误码(1301)。开发者识别到错误码(1301),应及时采取(清屏、重启对话)等措施删除生成内容,并确保不将含有违法及不良信息的内容传递给模型继续生成,避免其造成负面影响。 + en_US: When using synchronous invocation, this parameter should be set to false or omitted. It indicates that the model will return all the generated content at once after the generation is complete. The default value is false. If set to true, the model will return the generated content in chunks via the standard Event Stream. A data:[DONE] message will be sent at the end of the Event Stream.Note:During the model's streaming output process, we will batch check the generated content. If illegal or harmful information is detected, the API will return an error code (1301). Developers who identify error code (1301) should promptly take actions such as clearing the screen or restarting the conversation to delete the generated content. They should also ensure that no illegal or harmful content is passed back to the model for continued generation to avoid negative impacts. + default: false - name: max_tokens use_template: max_tokens default: 1024 min: 1 - max: 8192 + max: 4095 pricing: input: '0.001' output: '0.001' diff --git a/api/core/model_runtime/model_providers/zhipuai/llm/glm-4-airx.yaml b/api/core/model_runtime/model_providers/zhipuai/llm/glm-4-airx.yaml index dc123913de..14f17db5d6 100644 --- a/api/core/model_runtime/model_providers/zhipuai/llm/glm-4-airx.yaml +++ b/api/core/model_runtime/model_providers/zhipuai/llm/glm-4-airx.yaml @@ -23,20 +23,29 @@ parameter_rules: help: zh_Hans: 用温度取样的另一种方法,称为核取样取值范围是:(0.0, 1.0) 开区间,不能等于 0 或 1,默认值为 0.7 模型考虑具有 top_p 概率质量tokens的结果例如:0.1 意味着模型解码器只考虑从前 10% 的概率的候选集中取 tokens 建议您根据应用场景调整 top_p 或 temperature 参数,但不要同时调整两个参数。 en_US: Another method of temperature sampling is called kernel sampling. The value range is (0.0, 1.0) open interval, which cannot be equal to 0 or 1. The default value is 0.7. The model considers the results with top_p probability mass tokens. For example 0.1 means The model decoder only considers tokens from the candidate set with the top 10% probability. It is recommended that you adjust the top_p or temperature parameters according to the application scenario, but do not adjust both parameters at the same time. - - name: incremental + - name: do_sample label: - zh_Hans: 增量返回 - en_US: Incremental + zh_Hans: 采样策略 + en_US: Sampling strategy type: boolean help: - zh_Hans: SSE接口调用时,用于控制每次返回内容方式是增量还是全量,不提供此参数时默认为增量返回,true 为增量返回,false 为全量返回。 - en_US: When the SSE interface is called, it is used to control whether the content is returned incrementally or in full. If this parameter is not provided, the default is incremental return. true means incremental return, false means full return. - required: false + zh_Hans: do_sample 为 true 时启用采样策略,do_sample 为 false 时采样策略 temperature、top_p 将不生效。默认值为 true。 + en_US: When `do_sample` is set to true, the sampling strategy is enabled. When `do_sample` is set to false, the sampling strategies such as `temperature` and `top_p` will not take effect. The default value is true. + default: true + - name: stream + label: + zh_Hans: 流处理 + en_US: Event Stream + type: boolean + help: + zh_Hans: 使用同步调用时,此参数应当设置为 fasle 或者省略。表示模型生成完所有内容后一次性返回所有内容。默认值为 false。如果设置为 true,模型将通过标准 Event Stream ,逐块返回模型生成内容。Event Stream 结束时会返回一条data:[DONE]消息。注意:在模型流式输出生成内容的过程中,我们会分批对模型生成内容进行检测,当检测到违法及不良信息时,API会返回错误码(1301)。开发者识别到错误码(1301),应及时采取(清屏、重启对话)等措施删除生成内容,并确保不将含有违法及不良信息的内容传递给模型继续生成,避免其造成负面影响。 + en_US: When using synchronous invocation, this parameter should be set to false or omitted. It indicates that the model will return all the generated content at once after the generation is complete. The default value is false. If set to true, the model will return the generated content in chunks via the standard Event Stream. A data:[DONE] message will be sent at the end of the Event Stream.Note:During the model's streaming output process, we will batch check the generated content. If illegal or harmful information is detected, the API will return an error code (1301). Developers who identify error code (1301) should promptly take actions such as clearing the screen or restarting the conversation to delete the generated content. They should also ensure that no illegal or harmful content is passed back to the model for continued generation to avoid negative impacts. + default: false - name: max_tokens use_template: max_tokens default: 1024 min: 1 - max: 8192 + max: 4095 pricing: input: '0.01' output: '0.01' diff --git a/api/core/model_runtime/model_providers/zhipuai/llm/glm-4-flash.yaml b/api/core/model_runtime/model_providers/zhipuai/llm/glm-4-flash.yaml index 1b1d499ba7..3361474d73 100644 --- a/api/core/model_runtime/model_providers/zhipuai/llm/glm-4-flash.yaml +++ b/api/core/model_runtime/model_providers/zhipuai/llm/glm-4-flash.yaml @@ -23,22 +23,31 @@ parameter_rules: help: zh_Hans: 用温度取样的另一种方法,称为核取样取值范围是:(0.0, 1.0) 开区间,不能等于 0 或 1,默认值为 0.7 模型考虑具有 top_p 概率质量tokens的结果例如:0.1 意味着模型解码器只考虑从前 10% 的概率的候选集中取 tokens 建议您根据应用场景调整 top_p 或 temperature 参数,但不要同时调整两个参数。 en_US: Another method of temperature sampling is called kernel sampling. The value range is (0.0, 1.0) open interval, which cannot be equal to 0 or 1. The default value is 0.7. The model considers the results with top_p probability mass tokens. For example 0.1 means The model decoder only considers tokens from the candidate set with the top 10% probability. It is recommended that you adjust the top_p or temperature parameters according to the application scenario, but do not adjust both parameters at the same time. - - name: incremental + - name: do_sample label: - zh_Hans: 增量返回 - en_US: Incremental + zh_Hans: 采样策略 + en_US: Sampling strategy type: boolean help: - zh_Hans: SSE接口调用时,用于控制每次返回内容方式是增量还是全量,不提供此参数时默认为增量返回,true 为增量返回,false 为全量返回。 - en_US: When the SSE interface is called, it is used to control whether the content is returned incrementally or in full. If this parameter is not provided, the default is incremental return. true means incremental return, false means full return. - required: false + zh_Hans: do_sample 为 true 时启用采样策略,do_sample 为 false 时采样策略 temperature、top_p 将不生效。默认值为 true。 + en_US: When `do_sample` is set to true, the sampling strategy is enabled. When `do_sample` is set to false, the sampling strategies such as `temperature` and `top_p` will not take effect. The default value is true. + default: true + - name: stream + label: + zh_Hans: 流处理 + en_US: Event Stream + type: boolean + help: + zh_Hans: 使用同步调用时,此参数应当设置为 fasle 或者省略。表示模型生成完所有内容后一次性返回所有内容。默认值为 false。如果设置为 true,模型将通过标准 Event Stream ,逐块返回模型生成内容。Event Stream 结束时会返回一条data:[DONE]消息。注意:在模型流式输出生成内容的过程中,我们会分批对模型生成内容进行检测,当检测到违法及不良信息时,API会返回错误码(1301)。开发者识别到错误码(1301),应及时采取(清屏、重启对话)等措施删除生成内容,并确保不将含有违法及不良信息的内容传递给模型继续生成,避免其造成负面影响。 + en_US: When using synchronous invocation, this parameter should be set to false or omitted. It indicates that the model will return all the generated content at once after the generation is complete. The default value is false. If set to true, the model will return the generated content in chunks via the standard Event Stream. A data:[DONE] message will be sent at the end of the Event Stream.Note:During the model's streaming output process, we will batch check the generated content. If illegal or harmful information is detected, the API will return an error code (1301). Developers who identify error code (1301) should promptly take actions such as clearing the screen or restarting the conversation to delete the generated content. They should also ensure that no illegal or harmful content is passed back to the model for continued generation to avoid negative impacts. + default: false - name: max_tokens use_template: max_tokens default: 1024 min: 1 - max: 8192 + max: 4095 pricing: - input: '0.0001' - output: '0.0001' + input: '0' + output: '0' unit: '0.001' currency: RMB diff --git a/api/core/model_runtime/model_providers/zhipuai/llm/glm_3_turbo.yaml b/api/core/model_runtime/model_providers/zhipuai/llm/glm_3_turbo.yaml index 5bdb442840..bf0135d198 100644 --- a/api/core/model_runtime/model_providers/zhipuai/llm/glm_3_turbo.yaml +++ b/api/core/model_runtime/model_providers/zhipuai/llm/glm_3_turbo.yaml @@ -23,17 +23,31 @@ parameter_rules: help: zh_Hans: 用温度取样的另一种方法,称为核取样取值范围是:(0.0, 1.0) 开区间,不能等于 0 或 1,默认值为 0.7 模型考虑具有 top_p 概率质量tokens的结果例如:0.1 意味着模型解码器只考虑从前 10% 的概率的候选集中取 tokens 建议您根据应用场景调整 top_p 或 temperature 参数,但不要同时调整两个参数。 en_US: Another method of temperature sampling is called kernel sampling. The value range is (0.0, 1.0) open interval, which cannot be equal to 0 or 1. The default value is 0.7. The model considers the results with top_p probability mass tokens. For example 0.1 means The model decoder only considers tokens from the candidate set with the top 10% probability. It is recommended that you adjust the top_p or temperature parameters according to the application scenario, but do not adjust both parameters at the same time. - - name: incremental + - name: do_sample label: - zh_Hans: 增量返回 - en_US: Incremental + zh_Hans: 采样策略 + en_US: Sampling strategy type: boolean help: - zh_Hans: SSE接口调用时,用于控制每次返回内容方式是增量还是全量,不提供此参数时默认为增量返回,true 为增量返回,false 为全量返回。 - en_US: When the SSE interface is called, it is used to control whether the content is returned incrementally or in full. If this parameter is not provided, the default is incremental return. true means incremental return, false means full return. - required: false + zh_Hans: do_sample 为 true 时启用采样策略,do_sample 为 false 时采样策略 temperature、top_p 将不生效。默认值为 true。 + en_US: When `do_sample` is set to true, the sampling strategy is enabled. When `do_sample` is set to false, the sampling strategies such as `temperature` and `top_p` will not take effect. The default value is true. + default: true + - name: stream + label: + zh_Hans: 流处理 + en_US: Event Stream + type: boolean + help: + zh_Hans: 使用同步调用时,此参数应当设置为 fasle 或者省略。表示模型生成完所有内容后一次性返回所有内容。默认值为 false。如果设置为 true,模型将通过标准 Event Stream ,逐块返回模型生成内容。Event Stream 结束时会返回一条data:[DONE]消息。注意:在模型流式输出生成内容的过程中,我们会分批对模型生成内容进行检测,当检测到违法及不良信息时,API会返回错误码(1301)。开发者识别到错误码(1301),应及时采取(清屏、重启对话)等措施删除生成内容,并确保不将含有违法及不良信息的内容传递给模型继续生成,避免其造成负面影响。 + en_US: When using synchronous invocation, this parameter should be set to false or omitted. It indicates that the model will return all the generated content at once after the generation is complete. The default value is false. If set to true, the model will return the generated content in chunks via the standard Event Stream. A data:[DONE] message will be sent at the end of the Event Stream.Note:During the model's streaming output process, we will batch check the generated content. If illegal or harmful information is detected, the API will return an error code (1301). Developers who identify error code (1301) should promptly take actions such as clearing the screen or restarting the conversation to delete the generated content. They should also ensure that no illegal or harmful content is passed back to the model for continued generation to avoid negative impacts. + default: false - name: max_tokens use_template: max_tokens default: 1024 min: 1 max: 8192 +pricing: + input: '0.001' + output: '0.001' + unit: '0.001' + currency: RMB diff --git a/api/core/model_runtime/model_providers/zhipuai/llm/glm_4.yaml b/api/core/model_runtime/model_providers/zhipuai/llm/glm_4.yaml index 6b5bcc5bcf..ab4b32dd82 100644 --- a/api/core/model_runtime/model_providers/zhipuai/llm/glm_4.yaml +++ b/api/core/model_runtime/model_providers/zhipuai/llm/glm_4.yaml @@ -23,17 +23,31 @@ parameter_rules: help: zh_Hans: 用温度取样的另一种方法,称为核取样取值范围是:(0.0, 1.0) 开区间,不能等于 0 或 1,默认值为 0.7 模型考虑具有 top_p 概率质量tokens的结果例如:0.1 意味着模型解码器只考虑从前 10% 的概率的候选集中取 tokens 建议您根据应用场景调整 top_p 或 temperature 参数,但不要同时调整两个参数。 en_US: Another method of temperature sampling is called kernel sampling. The value range is (0.0, 1.0) open interval, which cannot be equal to 0 or 1. The default value is 0.7. The model considers the results with top_p probability mass tokens. For example 0.1 means The model decoder only considers tokens from the candidate set with the top 10% probability. It is recommended that you adjust the top_p or temperature parameters according to the application scenario, but do not adjust both parameters at the same time. - - name: incremental + - name: do_sample label: - zh_Hans: 增量返回 - en_US: Incremental + zh_Hans: 采样策略 + en_US: Sampling strategy type: boolean help: - zh_Hans: SSE接口调用时,用于控制每次返回内容方式是增量还是全量,不提供此参数时默认为增量返回,true 为增量返回,false 为全量返回。 - en_US: When the SSE interface is called, it is used to control whether the content is returned incrementally or in full. If this parameter is not provided, the default is incremental return. true means incremental return, false means full return. - required: false + zh_Hans: do_sample 为 true 时启用采样策略,do_sample 为 false 时采样策略 temperature、top_p 将不生效。默认值为 true。 + en_US: When `do_sample` is set to true, the sampling strategy is enabled. When `do_sample` is set to false, the sampling strategies such as `temperature` and `top_p` will not take effect. The default value is true. + default: true + - name: stream + label: + zh_Hans: 流处理 + en_US: Event Stream + type: boolean + help: + zh_Hans: 使用同步调用时,此参数应当设置为 fasle 或者省略。表示模型生成完所有内容后一次性返回所有内容。默认值为 false。如果设置为 true,模型将通过标准 Event Stream ,逐块返回模型生成内容。Event Stream 结束时会返回一条data:[DONE]消息。注意:在模型流式输出生成内容的过程中,我们会分批对模型生成内容进行检测,当检测到违法及不良信息时,API会返回错误码(1301)。开发者识别到错误码(1301),应及时采取(清屏、重启对话)等措施删除生成内容,并确保不将含有违法及不良信息的内容传递给模型继续生成,避免其造成负面影响。 + en_US: When using synchronous invocation, this parameter should be set to false or omitted. It indicates that the model will return all the generated content at once after the generation is complete. The default value is false. If set to true, the model will return the generated content in chunks via the standard Event Stream. A data:[DONE] message will be sent at the end of the Event Stream.Note:During the model's streaming output process, we will batch check the generated content. If illegal or harmful information is detected, the API will return an error code (1301). Developers who identify error code (1301) should promptly take actions such as clearing the screen or restarting the conversation to delete the generated content. They should also ensure that no illegal or harmful content is passed back to the model for continued generation to avoid negative impacts. + default: false - name: max_tokens use_template: max_tokens default: 1024 min: 1 - max: 8192 + max: 4095 +pricing: + input: '0.1' + output: '0.1' + unit: '0.001' + currency: RMB diff --git a/api/core/model_runtime/model_providers/zhipuai/llm/glm_4_long.yaml b/api/core/model_runtime/model_providers/zhipuai/llm/glm_4_long.yaml index 9d92e58f6c..d1b01731f5 100644 --- a/api/core/model_runtime/model_providers/zhipuai/llm/glm_4_long.yaml +++ b/api/core/model_runtime/model_providers/zhipuai/llm/glm_4_long.yaml @@ -26,8 +26,31 @@ parameter_rules: help: zh_Hans: 用温度取样的另一种方法,称为核取样取值范围是:(0.0, 1.0) 开区间,不能等于 0 或 1,默认值为 0.7 模型考虑具有 top_p 概率质量tokens的结果例如:0.1 意味着模型解码器只考虑从前 10% 的概率的候选集中取 tokens 建议您根据应用场景调整 top_p 或 temperature 参数,但不要同时调整两个参数。 en_US: Another method of temperature sampling is called kernel sampling. The value range is (0.0, 1.0) open interval, which cannot be equal to 0 or 1. The default value is 0.7. The model considers the results with top_p probability mass tokens. For example 0.1 means The model decoder only considers tokens from the candidate set with the top 10% probability. It is recommended that you adjust the top_p or temperature parameters according to the application scenario, but do not adjust both parameters at the same time. + - name: do_sample + label: + zh_Hans: 采样策略 + en_US: Sampling strategy + type: boolean + help: + zh_Hans: do_sample 为 true 时启用采样策略,do_sample 为 false 时采样策略 temperature、top_p 将不生效。默认值为 true。 + en_US: When `do_sample` is set to true, the sampling strategy is enabled. When `do_sample` is set to false, the sampling strategies such as `temperature` and `top_p` will not take effect. The default value is true. + default: true + - name: stream + label: + zh_Hans: 流处理 + en_US: Event Stream + type: boolean + help: + zh_Hans: 使用同步调用时,此参数应当设置为 fasle 或者省略。表示模型生成完所有内容后一次性返回所有内容。默认值为 false。如果设置为 true,模型将通过标准 Event Stream ,逐块返回模型生成内容。Event Stream 结束时会返回一条data:[DONE]消息。注意:在模型流式输出生成内容的过程中,我们会分批对模型生成内容进行检测,当检测到违法及不良信息时,API会返回错误码(1301)。开发者识别到错误码(1301),应及时采取(清屏、重启对话)等措施删除生成内容,并确保不将含有违法及不良信息的内容传递给模型继续生成,避免其造成负面影响。 + en_US: When using synchronous invocation, this parameter should be set to false or omitted. It indicates that the model will return all the generated content at once after the generation is complete. The default value is false. If set to true, the model will return the generated content in chunks via the standard Event Stream. A data:[DONE] message will be sent at the end of the Event Stream.Note:During the model's streaming output process, we will batch check the generated content. If illegal or harmful information is detected, the API will return an error code (1301). Developers who identify error code (1301) should promptly take actions such as clearing the screen or restarting the conversation to delete the generated content. They should also ensure that no illegal or harmful content is passed back to the model for continued generation to avoid negative impacts. + default: false - name: max_tokens use_template: max_tokens default: 1024 min: 1 - max: 4096 + max: 4095 +pricing: + input: '0.001' + output: '0.001' + unit: '0.001' + currency: RMB diff --git a/api/core/model_runtime/model_providers/zhipuai/llm/glm_4_plus.yaml b/api/core/model_runtime/model_providers/zhipuai/llm/glm_4_plus.yaml index d9132640b2..9ede308f18 100644 --- a/api/core/model_runtime/model_providers/zhipuai/llm/glm_4_plus.yaml +++ b/api/core/model_runtime/model_providers/zhipuai/llm/glm_4_plus.yaml @@ -23,17 +23,31 @@ parameter_rules: help: zh_Hans: 用温度取样的另一种方法,称为核取样取值范围是:(0.0, 1.0) 开区间,不能等于 0 或 1,默认值为 0.7 模型考虑具有 top_p 概率质量tokens的结果例如:0.1 意味着模型解码器只考虑从前 10% 的概率的候选集中取 tokens 建议您根据应用场景调整 top_p 或 temperature 参数,但不要同时调整两个参数。 en_US: Another method of temperature sampling is called kernel sampling. The value range is (0.0, 1.0) open interval, which cannot be equal to 0 or 1. The default value is 0.7. The model considers the results with top_p probability mass tokens. For example 0.1 means The model decoder only considers tokens from the candidate set with the top 10% probability. It is recommended that you adjust the top_p or temperature parameters according to the application scenario, but do not adjust both parameters at the same time. - - name: incremental + - name: do_sample label: - zh_Hans: 增量返回 - en_US: Incremental + zh_Hans: 采样策略 + en_US: Sampling strategy type: boolean help: - zh_Hans: SSE接口调用时,用于控制每次返回内容方式是增量还是全量,不提供此参数时默认为增量返回,true 为增量返回,false 为全量返回。 - en_US: When the SSE interface is called, it is used to control whether the content is returned incrementally or in full. If this parameter is not provided, the default is incremental return. true means incremental return, false means full return. - required: false + zh_Hans: do_sample 为 true 时启用采样策略,do_sample 为 false 时采样策略 temperature、top_p 将不生效。默认值为 true。 + en_US: When `do_sample` is set to true, the sampling strategy is enabled. When `do_sample` is set to false, the sampling strategies such as `temperature` and `top_p` will not take effect. The default value is true. + default: true + - name: stream + label: + zh_Hans: 流处理 + en_US: Event Stream + type: boolean + help: + zh_Hans: 使用同步调用时,此参数应当设置为 fasle 或者省略。表示模型生成完所有内容后一次性返回所有内容。默认值为 false。如果设置为 true,模型将通过标准 Event Stream ,逐块返回模型生成内容。Event Stream 结束时会返回一条data:[DONE]消息。注意:在模型流式输出生成内容的过程中,我们会分批对模型生成内容进行检测,当检测到违法及不良信息时,API会返回错误码(1301)。开发者识别到错误码(1301),应及时采取(清屏、重启对话)等措施删除生成内容,并确保不将含有违法及不良信息的内容传递给模型继续生成,避免其造成负面影响。 + en_US: When using synchronous invocation, this parameter should be set to false or omitted. It indicates that the model will return all the generated content at once after the generation is complete. The default value is false. If set to true, the model will return the generated content in chunks via the standard Event Stream. A data:[DONE] message will be sent at the end of the Event Stream.Note:During the model's streaming output process, we will batch check the generated content. If illegal or harmful information is detected, the API will return an error code (1301). Developers who identify error code (1301) should promptly take actions such as clearing the screen or restarting the conversation to delete the generated content. They should also ensure that no illegal or harmful content is passed back to the model for continued generation to avoid negative impacts. + default: false - name: max_tokens use_template: max_tokens default: 1024 min: 1 - max: 8192 + max: 4095 +pricing: + input: '0.05' + output: '0.05' + unit: '0.001' + currency: RMB diff --git a/api/core/model_runtime/model_providers/zhipuai/llm/glm_4v.yaml b/api/core/model_runtime/model_providers/zhipuai/llm/glm_4v.yaml index ddea331c8e..28286580a7 100644 --- a/api/core/model_runtime/model_providers/zhipuai/llm/glm_4v.yaml +++ b/api/core/model_runtime/model_providers/zhipuai/llm/glm_4v.yaml @@ -17,21 +17,35 @@ parameter_rules: en_US: Sampling temperature, controls the randomness of the output, must be a positive number. The value range is (0.0,1.0], which cannot be equal to 0. The default value is 0.95. The larger the value, the more random and creative the output will be; the smaller the value, The output will be more stable or certain. It is recommended that you adjust the top_p or temperature parameters according to the application scenario, but do not adjust both parameters at the same time. - name: top_p use_template: top_p - default: 0.7 + default: 0.6 help: zh_Hans: 用温度取样的另一种方法,称为核取样取值范围是:(0.0, 1.0) 开区间,不能等于 0 或 1,默认值为 0.7 模型考虑具有 top_p 概率质量tokens的结果例如:0.1 意味着模型解码器只考虑从前 10% 的概率的候选集中取 tokens 建议您根据应用场景调整 top_p 或 temperature 参数,但不要同时调整两个参数。 en_US: Another method of temperature sampling is called kernel sampling. The value range is (0.0, 1.0) open interval, which cannot be equal to 0 or 1. The default value is 0.7. The model considers the results with top_p probability mass tokens. For example 0.1 means The model decoder only considers tokens from the candidate set with the top 10% probability. It is recommended that you adjust the top_p or temperature parameters according to the application scenario, but do not adjust both parameters at the same time. - - name: incremental + - name: do_sample label: - zh_Hans: 增量返回 - en_US: Incremental + zh_Hans: 采样策略 + en_US: Sampling strategy type: boolean help: - zh_Hans: SSE接口调用时,用于控制每次返回内容方式是增量还是全量,不提供此参数时默认为增量返回,true 为增量返回,false 为全量返回。 - en_US: When the SSE interface is called, it is used to control whether the content is returned incrementally or in full. If this parameter is not provided, the default is incremental return. true means incremental return, false means full return. - required: false + zh_Hans: do_sample 为 true 时启用采样策略,do_sample 为 false 时采样策略 temperature、top_p 将不生效。默认值为 true。 + en_US: When `do_sample` is set to true, the sampling strategy is enabled. When `do_sample` is set to false, the sampling strategies such as `temperature` and `top_p` will not take effect. The default value is true. + default: true + - name: stream + label: + zh_Hans: 流处理 + en_US: Event Stream + type: boolean + help: + zh_Hans: 使用同步调用时,此参数应当设置为 fasle 或者省略。表示模型生成完所有内容后一次性返回所有内容。默认值为 false。如果设置为 true,模型将通过标准 Event Stream ,逐块返回模型生成内容。Event Stream 结束时会返回一条data:[DONE]消息。注意:在模型流式输出生成内容的过程中,我们会分批对模型生成内容进行检测,当检测到违法及不良信息时,API会返回错误码(1301)。开发者识别到错误码(1301),应及时采取(清屏、重启对话)等措施删除生成内容,并确保不将含有违法及不良信息的内容传递给模型继续生成,避免其造成负面影响。 + en_US: When using synchronous invocation, this parameter should be set to false or omitted. It indicates that the model will return all the generated content at once after the generation is complete. The default value is false. If set to true, the model will return the generated content in chunks via the standard Event Stream. A data:[DONE] message will be sent at the end of the Event Stream.Note:During the model's streaming output process, we will batch check the generated content. If illegal or harmful information is detected, the API will return an error code (1301). Developers who identify error code (1301) should promptly take actions such as clearing the screen or restarting the conversation to delete the generated content. They should also ensure that no illegal or harmful content is passed back to the model for continued generation to avoid negative impacts. + default: false - name: max_tokens use_template: max_tokens default: 1024 min: 1 - max: 8192 + max: 1024 +pricing: + input: '0.05' + output: '0.05' + unit: '0.001' + currency: RMB diff --git a/api/core/model_runtime/model_providers/zhipuai/llm/glm_4v_plus.yaml b/api/core/model_runtime/model_providers/zhipuai/llm/glm_4v_plus.yaml index 4a45c65f64..4c5fa24034 100644 --- a/api/core/model_runtime/model_providers/zhipuai/llm/glm_4v_plus.yaml +++ b/api/core/model_runtime/model_providers/zhipuai/llm/glm_4v_plus.yaml @@ -17,21 +17,35 @@ parameter_rules: en_US: Sampling temperature, controls the randomness of the output, must be a positive number. The value range is (0.0,1.0], which cannot be equal to 0. The default value is 0.95. The larger the value, the more random and creative the output will be; the smaller the value, The output will be more stable or certain. It is recommended that you adjust the top_p or temperature parameters according to the application scenario, but do not adjust both parameters at the same time. - name: top_p use_template: top_p - default: 0.7 + default: 0.6 help: zh_Hans: 用温度取样的另一种方法,称为核取样取值范围是:(0.0, 1.0) 开区间,不能等于 0 或 1,默认值为 0.7 模型考虑具有 top_p 概率质量tokens的结果例如:0.1 意味着模型解码器只考虑从前 10% 的概率的候选集中取 tokens 建议您根据应用场景调整 top_p 或 temperature 参数,但不要同时调整两个参数。 en_US: Another method of temperature sampling is called kernel sampling. The value range is (0.0, 1.0) open interval, which cannot be equal to 0 or 1. The default value is 0.7. The model considers the results with top_p probability mass tokens. For example 0.1 means The model decoder only considers tokens from the candidate set with the top 10% probability. It is recommended that you adjust the top_p or temperature parameters according to the application scenario, but do not adjust both parameters at the same time. - - name: incremental + - name: do_sample label: - zh_Hans: 增量返回 - en_US: Incremental + zh_Hans: 采样策略 + en_US: Sampling strategy type: boolean help: - zh_Hans: SSE接口调用时,用于控制每次返回内容方式是增量还是全量,不提供此参数时默认为增量返回,true 为增量返回,false 为全量返回。 - en_US: When the SSE interface is called, it is used to control whether the content is returned incrementally or in full. If this parameter is not provided, the default is incremental return. true means incremental return, false means full return. - required: false + zh_Hans: do_sample 为 true 时启用采样策略,do_sample 为 false 时采样策略 temperature、top_p 将不生效。默认值为 true。 + en_US: When `do_sample` is set to true, the sampling strategy is enabled. When `do_sample` is set to false, the sampling strategies such as `temperature` and `top_p` will not take effect. The default value is true. + default: true + - name: stream + label: + zh_Hans: 流处理 + en_US: Event Stream + type: boolean + help: + zh_Hans: 使用同步调用时,此参数应当设置为 fasle 或者省略。表示模型生成完所有内容后一次性返回所有内容。默认值为 false。如果设置为 true,模型将通过标准 Event Stream ,逐块返回模型生成内容。Event Stream 结束时会返回一条data:[DONE]消息。注意:在模型流式输出生成内容的过程中,我们会分批对模型生成内容进行检测,当检测到违法及不良信息时,API会返回错误码(1301)。开发者识别到错误码(1301),应及时采取(清屏、重启对话)等措施删除生成内容,并确保不将含有违法及不良信息的内容传递给模型继续生成,避免其造成负面影响。 + en_US: When using synchronous invocation, this parameter should be set to false or omitted. It indicates that the model will return all the generated content at once after the generation is complete. The default value is false. If set to true, the model will return the generated content in chunks via the standard Event Stream. A data:[DONE] message will be sent at the end of the Event Stream.Note:During the model's streaming output process, we will batch check the generated content. If illegal or harmful information is detected, the API will return an error code (1301). Developers who identify error code (1301) should promptly take actions such as clearing the screen or restarting the conversation to delete the generated content. They should also ensure that no illegal or harmful content is passed back to the model for continued generation to avoid negative impacts. + default: false - name: max_tokens use_template: max_tokens default: 1024 min: 1 - max: 8192 + max: 1024 +pricing: + input: '0.01' + output: '0.01' + unit: '0.001' + currency: RMB diff --git a/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/core/_http_client.py b/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/core/_http_client.py index 263fe82990..65401f6c1c 100644 --- a/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/core/_http_client.py +++ b/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/core/_http_client.py @@ -135,16 +135,16 @@ class HttpClient: **kwargs, ) - def _object_to_formfata(self, key: str, value: Data | Mapping[object, object]) -> list[tuple[str, str]]: + def _object_to_formdata(self, key: str, value: Data | Mapping[object, object]) -> list[tuple[str, str]]: items = [] if isinstance(value, Mapping): for k, v in value.items(): - items.extend(self._object_to_formfata(f"{key}[{k}]", v)) + items.extend(self._object_to_formdata(f"{key}[{k}]", v)) return items if isinstance(value, list | tuple): for v in value: - items.extend(self._object_to_formfata(key + "[]", v)) + items.extend(self._object_to_formdata(key + "[]", v)) return items def _primitive_value_to_str(val) -> str: @@ -165,7 +165,7 @@ class HttpClient: def _make_multipartform(self, data: Mapping[object, object]) -> dict[str, object]: - items = flatten([self._object_to_formfata(k, v) for k, v in data.items()]) + items = flatten([self._object_to_formdata(k, v) for k, v in data.items()]) serialized: dict[str, object] = {} for key, value in items: diff --git a/api/core/moderation/base.py b/api/core/moderation/base.py index 9a369a9f87..757dd2ab46 100644 --- a/api/core/moderation/base.py +++ b/api/core/moderation/base.py @@ -9,7 +9,7 @@ from core.extension.extensible import Extensible, ExtensionModule class ModerationAction(Enum): DIRECT_OUTPUT = 'direct_output' - OVERRIDED = 'overrided' + OVERRIDDEN = 'overridden' class ModerationInputsResult(BaseModel): diff --git a/api/core/moderation/input_moderation.py b/api/core/moderation/input_moderation.py index 8157b300b1..46dfacbc9e 100644 --- a/api/core/moderation/input_moderation.py +++ b/api/core/moderation/input_moderation.py @@ -64,7 +64,7 @@ class InputModeration: if moderation_result.action == ModerationAction.DIRECT_OUTPUT: raise ModerationException(moderation_result.preset_response) - elif moderation_result.action == ModerationAction.OVERRIDED: + elif moderation_result.action == ModerationAction.OVERRIDDEN: inputs = moderation_result.inputs query = moderation_result.query diff --git a/api/core/ops/langfuse_trace/langfuse_trace.py b/api/core/ops/langfuse_trace/langfuse_trace.py index a21c67ed50..a0f3ac7f86 100644 --- a/api/core/ops/langfuse_trace/langfuse_trace.py +++ b/api/core/ops/langfuse_trace/langfuse_trace.py @@ -204,6 +204,7 @@ class LangFuseDataTrace(BaseTraceInstance): node_generation_data = LangfuseGeneration( name="llm", trace_id=trace_id, + model=process_data.get("model_name"), parent_observation_id=node_execution_id, start_time=created_at, end_time=finished_at, diff --git a/api/core/ops/langsmith_trace/langsmith_trace.py b/api/core/ops/langsmith_trace/langsmith_trace.py index fde8a06c61..9cbc805fe7 100644 --- a/api/core/ops/langsmith_trace/langsmith_trace.py +++ b/api/core/ops/langsmith_trace/langsmith_trace.py @@ -1,9 +1,11 @@ import json import logging import os +import uuid from datetime import datetime, timedelta from langsmith import Client +from langsmith.schemas import RunBase from core.ops.base_trace_instance import BaseTraceInstance from core.ops.entities.config_entity import LangSmithConfig @@ -139,8 +141,7 @@ class LangSmithDataTrace(BaseTraceInstance): json.loads(node_execution.execution_metadata) if node_execution.execution_metadata else {} ) node_total_tokens = execution_metadata.get("total_tokens", 0) - - metadata = json.loads(node_execution.execution_metadata) if node_execution.execution_metadata else {} + metadata = execution_metadata.copy() metadata.update( { "workflow_run_id": trace_info.workflow_run_id, @@ -156,6 +157,12 @@ class LangSmithDataTrace(BaseTraceInstance): process_data = json.loads(node_execution.process_data) if node_execution.process_data else {} if process_data and process_data.get("model_mode") == "chat": run_type = LangSmithRunType.llm + metadata.update( + { + 'ls_provider': process_data.get('model_provider', ''), + 'ls_model_name': process_data.get('model_name', ''), + } + ) elif node_type == "knowledge-retrieval": run_type = LangSmithRunType.retriever else: @@ -366,3 +373,24 @@ class LangSmithDataTrace(BaseTraceInstance): except Exception as e: logger.debug(f"LangSmith API check failed: {str(e)}") raise ValueError(f"LangSmith API check failed: {str(e)}") + + def get_project_url(self): + try: + run_data = RunBase( + id=uuid.uuid4(), + name="tool", + inputs={"input": "test"}, + outputs={"output": "test"}, + run_type=LangSmithRunType.tool, + start_time=datetime.now(), + ) + + project_url = self.langsmith_client.get_run_url(run=run_data, + project_id=self.project_id, + project_name=self.project_name) + return project_url.split('/r/')[0] + except Exception as e: + logger.debug(f"LangSmith get run url failed: {str(e)}") + raise ValueError(f"LangSmith get run url failed: {str(e)}") + + diff --git a/api/core/ops/ops_trace_manager.py b/api/core/ops/ops_trace_manager.py index 1416d6bd2d..aefab6ed16 100644 --- a/api/core/ops/ops_trace_manager.py +++ b/api/core/ops/ops_trace_manager.py @@ -264,6 +264,19 @@ class OpsTraceManager: tracing_config = config_type(**tracing_config) return trace_instance(tracing_config).get_project_key() + @staticmethod + def get_trace_config_project_url(tracing_config: dict, tracing_provider: str): + """ + get trace config is project key + :param tracing_config: tracing config + :param tracing_provider: tracing provider + :return: + """ + config_type, trace_instance = provider_config_map[tracing_provider]['config_class'], \ + provider_config_map[tracing_provider]['trace_instance'] + tracing_config = config_type(**tracing_config) + return trace_instance(tracing_config).get_project_url() + class TraceTask: def __init__( diff --git a/api/core/rag/cleaner/unstructured/unstructured_non_ascii_chars_cleaner.py b/api/core/rag/cleaner/unstructured/unstructured_non_ascii_chars_cleaner.py index ca1ae8dfd1..87dc2d49fa 100644 --- a/api/core/rag/cleaner/unstructured/unstructured_non_ascii_chars_cleaner.py +++ b/api/core/rag/cleaner/unstructured/unstructured_non_ascii_chars_cleaner.py @@ -8,5 +8,5 @@ class UnstructuredNonAsciiCharsCleaner(BaseCleaner): """clean document content.""" from unstructured.cleaners.core import clean_non_ascii_chars - # Returns "This text containsnon-ascii characters!" + # Returns "This text contains non-ascii characters!" return clean_non_ascii_chars(content) diff --git a/api/core/rag/datasource/retrieval_service.py b/api/core/rag/datasource/retrieval_service.py index 3932e90042..0dac9bfae6 100644 --- a/api/core/rag/datasource/retrieval_service.py +++ b/api/core/rag/datasource/retrieval_service.py @@ -7,7 +7,7 @@ from core.rag.data_post_processor.data_post_processor import DataPostProcessor from core.rag.datasource.keyword.keyword_factory import Keyword from core.rag.datasource.vdb.vector_factory import Vector from core.rag.rerank.constants.rerank_mode import RerankMode -from core.rag.retrieval.retrival_methods import RetrievalMethod +from core.rag.retrieval.retrieval_methods import RetrievalMethod from extensions.ext_database import db from models.dataset import Dataset @@ -26,7 +26,7 @@ default_retrieval_model = { class RetrievalService: @classmethod - def retrieve(cls, retrival_method: str, dataset_id: str, query: str, + def retrieve(cls, retrieval_method: str, dataset_id: str, query: str, top_k: int, score_threshold: Optional[float] = .0, reranking_model: Optional[dict] = None, reranking_mode: Optional[str] = 'reranking_model', weights: Optional[dict] = None): @@ -39,7 +39,7 @@ class RetrievalService: threads = [] exceptions = [] # retrieval_model source with keyword - if retrival_method == 'keyword_search': + if retrieval_method == 'keyword_search': keyword_thread = threading.Thread(target=RetrievalService.keyword_search, kwargs={ 'flask_app': current_app._get_current_object(), 'dataset_id': dataset_id, @@ -51,7 +51,7 @@ class RetrievalService: threads.append(keyword_thread) keyword_thread.start() # retrieval_model source with semantic - if RetrievalMethod.is_support_semantic_search(retrival_method): + if RetrievalMethod.is_support_semantic_search(retrieval_method): embedding_thread = threading.Thread(target=RetrievalService.embedding_search, kwargs={ 'flask_app': current_app._get_current_object(), 'dataset_id': dataset_id, @@ -60,19 +60,19 @@ class RetrievalService: 'score_threshold': score_threshold, 'reranking_model': reranking_model, 'all_documents': all_documents, - 'retrival_method': retrival_method, + 'retrieval_method': retrieval_method, 'exceptions': exceptions, }) threads.append(embedding_thread) embedding_thread.start() # retrieval source with full text - if RetrievalMethod.is_support_fulltext_search(retrival_method): + if RetrievalMethod.is_support_fulltext_search(retrieval_method): full_text_index_thread = threading.Thread(target=RetrievalService.full_text_index_search, kwargs={ 'flask_app': current_app._get_current_object(), 'dataset_id': dataset_id, 'query': query, - 'retrival_method': retrival_method, + 'retrieval_method': retrieval_method, 'score_threshold': score_threshold, 'top_k': top_k, 'reranking_model': reranking_model, @@ -89,7 +89,7 @@ class RetrievalService: exception_message = ';\n'.join(exceptions) raise Exception(exception_message) - if retrival_method == RetrievalMethod.HYBRID_SEARCH.value: + if retrieval_method == RetrievalMethod.HYBRID_SEARCH.value: data_post_processor = DataPostProcessor(str(dataset.tenant_id), reranking_mode, reranking_model, weights, False) all_documents = data_post_processor.invoke( @@ -124,7 +124,7 @@ class RetrievalService: @classmethod def embedding_search(cls, flask_app: Flask, dataset_id: str, query: str, top_k: int, score_threshold: Optional[float], reranking_model: Optional[dict], - all_documents: list, retrival_method: str, exceptions: list): + all_documents: list, retrieval_method: str, exceptions: list): with flask_app.app_context(): try: dataset = db.session.query(Dataset).filter( @@ -146,7 +146,7 @@ class RetrievalService: ) if documents: - if reranking_model and retrival_method == RetrievalMethod.SEMANTIC_SEARCH.value: + if reranking_model and reranking_model.get('reranking_model_name') and reranking_model.get('reranking_provider_name') and retrieval_method == RetrievalMethod.SEMANTIC_SEARCH.value: data_post_processor = DataPostProcessor(str(dataset.tenant_id), RerankMode.RERANKING_MODEL.value, reranking_model, None, False) @@ -164,7 +164,7 @@ class RetrievalService: @classmethod def full_text_index_search(cls, flask_app: Flask, dataset_id: str, query: str, top_k: int, score_threshold: Optional[float], reranking_model: Optional[dict], - all_documents: list, retrival_method: str, exceptions: list): + all_documents: list, retrieval_method: str, exceptions: list): with flask_app.app_context(): try: dataset = db.session.query(Dataset).filter( @@ -180,7 +180,7 @@ class RetrievalService: top_k=top_k ) if documents: - if reranking_model and retrival_method == RetrievalMethod.FULL_TEXT_SEARCH.value: + if reranking_model and reranking_model.get('reranking_model_name') and reranking_model.get('reranking_provider_name') and retrieval_method == RetrievalMethod.FULL_TEXT_SEARCH.value: data_post_processor = DataPostProcessor(str(dataset.tenant_id), RerankMode.RERANKING_MODEL.value, reranking_model, None, False) diff --git a/api/core/rag/datasource/vdb/milvus/milvus_vector.py b/api/core/rag/datasource/vdb/milvus/milvus_vector.py index cfc533ed33..c1c73d1c0d 100644 --- a/api/core/rag/datasource/vdb/milvus/milvus_vector.py +++ b/api/core/rag/datasource/vdb/milvus/milvus_vector.py @@ -1,10 +1,9 @@ import json import logging from typing import Any, Optional -from uuid import uuid4 from pydantic import BaseModel, model_validator -from pymilvus import MilvusClient, MilvusException, connections +from pymilvus import MilvusClient, MilvusException from pymilvus.milvus_client import IndexParams from configs import dify_config @@ -21,20 +20,17 @@ logger = logging.getLogger(__name__) class MilvusConfig(BaseModel): - host: str - port: int + uri: str + token: Optional[str] = None user: str password: str - secure: bool = False batch_size: int = 100 database: str = "default" @model_validator(mode='before') def validate_config(cls, values: dict) -> dict: - if not values.get('host'): - raise ValueError("config MILVUS_HOST is required") - if not values.get('port'): - raise ValueError("config MILVUS_PORT is required") + if not values.get('uri'): + raise ValueError("config MILVUS_URI is required") if not values.get('user'): raise ValueError("config MILVUS_USER is required") if not values.get('password'): @@ -43,11 +39,10 @@ class MilvusConfig(BaseModel): def to_milvus_params(self): return { - 'host': self.host, - 'port': self.port, + 'uri': self.uri, + 'token': self.token, 'user': self.user, 'password': self.password, - 'secure': self.secure, 'db_name': self.database, } @@ -111,32 +106,14 @@ class MilvusVector(BaseVector): return None def delete_by_metadata_field(self, key: str, value: str): - alias = uuid4().hex - if self._client_config.secure: - uri = "https://" + str(self._client_config.host) + ":" + str(self._client_config.port) - else: - uri = "http://" + str(self._client_config.host) + ":" + str(self._client_config.port) - connections.connect(alias=alias, uri=uri, user=self._client_config.user, password=self._client_config.password, - db_name=self._client_config.database) - - from pymilvus import utility - if utility.has_collection(self._collection_name, using=alias): + if self._client.has_collection(self._collection_name): ids = self.get_ids_by_metadata_field(key, value) if ids: self._client.delete(collection_name=self._collection_name, pks=ids) def delete_by_ids(self, ids: list[str]) -> None: - alias = uuid4().hex - if self._client_config.secure: - uri = "https://" + str(self._client_config.host) + ":" + str(self._client_config.port) - else: - uri = "http://" + str(self._client_config.host) + ":" + str(self._client_config.port) - connections.connect(alias=alias, uri=uri, user=self._client_config.user, password=self._client_config.password, - db_name=self._client_config.database) - - from pymilvus import utility - if utility.has_collection(self._collection_name, using=alias): + if self._client.has_collection(self._collection_name): result = self._client.query(collection_name=self._collection_name, filter=f'metadata["doc_id"] in {ids}', @@ -146,29 +123,11 @@ class MilvusVector(BaseVector): self._client.delete(collection_name=self._collection_name, pks=ids) def delete(self) -> None: - alias = uuid4().hex - if self._client_config.secure: - uri = "https://" + str(self._client_config.host) + ":" + str(self._client_config.port) - else: - uri = "http://" + str(self._client_config.host) + ":" + str(self._client_config.port) - connections.connect(alias=alias, uri=uri, user=self._client_config.user, password=self._client_config.password, - db_name=self._client_config.database) - - from pymilvus import utility - if utility.has_collection(self._collection_name, using=alias): - utility.drop_collection(self._collection_name, None, using=alias) + if self._client.has_collection(self._collection_name): + self._client.drop_collection(self._collection_name, None) def text_exists(self, id: str) -> bool: - alias = uuid4().hex - if self._client_config.secure: - uri = "https://" + str(self._client_config.host) + ":" + str(self._client_config.port) - else: - uri = "http://" + str(self._client_config.host) + ":" + str(self._client_config.port) - connections.connect(alias=alias, uri=uri, user=self._client_config.user, password=self._client_config.password, - db_name=self._client_config.database) - - from pymilvus import utility - if not utility.has_collection(self._collection_name, using=alias): + if not self._client.has_collection(self._collection_name): return False result = self._client.query(collection_name=self._collection_name, @@ -210,15 +169,7 @@ class MilvusVector(BaseVector): if redis_client.get(collection_exist_cache_key): return # Grab the existing collection if it exists - from pymilvus import utility - alias = uuid4().hex - if self._client_config.secure: - uri = "https://" + str(self._client_config.host) + ":" + str(self._client_config.port) - else: - uri = "http://" + str(self._client_config.host) + ":" + str(self._client_config.port) - connections.connect(alias=alias, uri=uri, user=self._client_config.user, - password=self._client_config.password, db_name=self._client_config.database) - if not utility.has_collection(self._collection_name, using=alias): + if not self._client.has_collection(self._collection_name): from pymilvus import CollectionSchema, DataType, FieldSchema from pymilvus.orm.types import infer_dtype_bydata @@ -263,11 +214,7 @@ class MilvusVector(BaseVector): redis_client.set(collection_exist_cache_key, 1, ex=3600) def _init_client(self, config) -> MilvusClient: - if config.secure: - uri = "https://" + str(config.host) + ":" + str(config.port) - else: - uri = "http://" + str(config.host) + ":" + str(config.port) - client = MilvusClient(uri=uri, user=config.user, password=config.password, db_name=config.database) + client = MilvusClient(uri=config.uri, user=config.user, password=config.password, db_name=config.database) return client @@ -285,11 +232,10 @@ class MilvusVectorFactory(AbstractVectorFactory): return MilvusVector( collection_name=collection_name, config=MilvusConfig( - host=dify_config.MILVUS_HOST, - port=dify_config.MILVUS_PORT, + uri=dify_config.MILVUS_URI, + token=dify_config.MILVUS_TOKEN, user=dify_config.MILVUS_USER, password=dify_config.MILVUS_PASSWORD, - secure=dify_config.MILVUS_SECURE, database=dify_config.MILVUS_DATABASE, ) ) diff --git a/api/core/rag/datasource/vdb/vector_factory.py b/api/core/rag/datasource/vdb/vector_factory.py index 3e9ca8e1fe..627d7c3aeb 100644 --- a/api/core/rag/datasource/vdb/vector_factory.py +++ b/api/core/rag/datasource/vdb/vector_factory.py @@ -30,7 +30,7 @@ class AbstractVectorFactory(ABC): class Vector: def __init__(self, dataset: Dataset, attributes: list = None): if attributes is None: - attributes = ['doc_id', 'dataset_id', 'document_id', 'doc_hash'] + attributes = ['doc_id', 'dataset_id', 'document_id', 'doc_hash', 'page'] self._dataset = dataset self._embeddings = self._get_embeddings() self._attributes = attributes @@ -107,6 +107,7 @@ class Vector: def add_texts(self, documents: list[Document], **kwargs): if kwargs.get('duplicate_check', False): documents = self._filter_duplicate_texts(documents) + embeddings = self._embeddings.embed_documents([document.page_content for document in documents]) self._vector_processor.create( texts=documents, diff --git a/api/core/rag/extractor/blod/blod.py b/api/core/rag/extractor/blob/blob.py similarity index 100% rename from api/core/rag/extractor/blod/blod.py rename to api/core/rag/extractor/blob/blob.py diff --git a/api/core/rag/extractor/notion_extractor.py b/api/core/rag/extractor/notion_extractor.py index 9535455909..7e839804c8 100644 --- a/api/core/rag/extractor/notion_extractor.py +++ b/api/core/rag/extractor/notion_extractor.py @@ -275,26 +275,31 @@ class NotionExtractor(BaseExtractor): data = res.json() # get table headers text table_header_cell_texts = [] - tabel_header_cells = data["results"][0]['table_row']['cells'] - for tabel_header_cell in tabel_header_cells: - if tabel_header_cell: - for table_header_cell_text in tabel_header_cell: + table_header_cells = data["results"][0]['table_row']['cells'] + for table_header_cell in table_header_cells: + if table_header_cell: + for table_header_cell_text in table_header_cell: text = table_header_cell_text["text"]["content"] table_header_cell_texts.append(text) - # get table columns text and format + else: + table_header_cell_texts.append('') + # Initialize Markdown table with headers + markdown_table = "| " + " | ".join(table_header_cell_texts) + " |\n" + markdown_table += "| " + " | ".join(['---'] * len(table_header_cell_texts)) + " |\n" + + # Process data to format each row in Markdown table format results = data["results"] for i in range(len(results) - 1): column_texts = [] - tabel_column_cells = data["results"][i + 1]['table_row']['cells'] - for j in range(len(tabel_column_cells)): - if tabel_column_cells[j]: - for table_column_cell_text in tabel_column_cells[j]: + table_column_cells = data["results"][i + 1]['table_row']['cells'] + for j in range(len(table_column_cells)): + if table_column_cells[j]: + for table_column_cell_text in table_column_cells[j]: column_text = table_column_cell_text["text"]["content"] - column_texts.append(f'{table_header_cell_texts[j]}:{column_text}') - - cur_result_text = "\n".join(column_texts) - result_lines_arr.append(cur_result_text) - + column_texts.append(column_text) + # Add row to Markdown table + markdown_table += "| " + " | ".join(column_texts) + " |\n" + result_lines_arr.append(markdown_table) if data["next_cursor"] is None: done = True break diff --git a/api/core/rag/extractor/pdf_extractor.py b/api/core/rag/extractor/pdf_extractor.py index cbb2655390..0864fec6c8 100644 --- a/api/core/rag/extractor/pdf_extractor.py +++ b/api/core/rag/extractor/pdf_extractor.py @@ -2,7 +2,7 @@ from collections.abc import Iterator from typing import Optional -from core.rag.extractor.blod.blod import Blob +from core.rag.extractor.blob.blob import Blob from core.rag.extractor.extractor_base import BaseExtractor from core.rag.models.document import Document from extensions.ext_storage import storage diff --git a/api/core/rag/extractor/word_extractor.py b/api/core/rag/extractor/word_extractor.py index c3f0b75cfb..15822867bb 100644 --- a/api/core/rag/extractor/word_extractor.py +++ b/api/core/rag/extractor/word_extractor.py @@ -170,6 +170,8 @@ class WordExtractor(BaseExtractor): if run.element.xpath('.//a:blip'): for blip in run.element.xpath('.//a:blip'): image_id = blip.get("{http://schemas.openxmlformats.org/officeDocument/2006/relationships}embed") + if not image_id: + continue image_part = paragraph.part.rels[image_id].target_part if image_part in image_map: @@ -256,6 +258,6 @@ class WordExtractor(BaseExtractor): content.append(parsed_paragraph) elif isinstance(element.tag, str) and element.tag.endswith('tbl'): # table table = tables.pop(0) - content.append(self._table_to_markdown(table,image_map)) + content.append(self._table_to_markdown(table, image_map)) return '\n'.join(content) diff --git a/api/core/rag/index_processor/index_processor_base.py b/api/core/rag/index_processor/index_processor_base.py index 176d0c1ed6..630387fe3a 100644 --- a/api/core/rag/index_processor/index_processor_base.py +++ b/api/core/rag/index_processor/index_processor_base.py @@ -34,7 +34,7 @@ class BaseIndexProcessor(ABC): raise NotImplementedError @abstractmethod - def retrieve(self, retrival_method: str, query: str, dataset: Dataset, top_k: int, + def retrieve(self, retrieval_method: str, query: str, dataset: Dataset, top_k: int, score_threshold: float, reranking_model: dict) -> list[Document]: raise NotImplementedError diff --git a/api/core/rag/index_processor/processor/paragraph_index_processor.py b/api/core/rag/index_processor/processor/paragraph_index_processor.py index 5fbc319fd6..bd7f6093bd 100644 --- a/api/core/rag/index_processor/processor/paragraph_index_processor.py +++ b/api/core/rag/index_processor/processor/paragraph_index_processor.py @@ -42,7 +42,7 @@ class ParagraphIndexProcessor(BaseIndexProcessor): hash = helper.generate_text_hash(document_node.page_content) document_node.metadata['doc_id'] = doc_id document_node.metadata['doc_hash'] = hash - # delete Spliter character + # delete Splitter character page_content = document_node.page_content if page_content.startswith(".") or page_content.startswith("。"): page_content = page_content[1:].strip() @@ -76,10 +76,10 @@ class ParagraphIndexProcessor(BaseIndexProcessor): else: keyword.delete() - def retrieve(self, retrival_method: str, query: str, dataset: Dataset, top_k: int, + def retrieve(self, retrieval_method: str, query: str, dataset: Dataset, top_k: int, score_threshold: float, reranking_model: dict) -> list[Document]: # Set search parameters. - results = RetrievalService.retrieve(retrival_method=retrival_method, dataset_id=dataset.id, query=query, + results = RetrievalService.retrieve(retrieval_method=retrieval_method, dataset_id=dataset.id, query=query, top_k=top_k, score_threshold=score_threshold, reranking_model=reranking_model) # Organize results. diff --git a/api/core/rag/index_processor/processor/qa_index_processor.py b/api/core/rag/index_processor/processor/qa_index_processor.py index 139bfe15f3..a44fd98036 100644 --- a/api/core/rag/index_processor/processor/qa_index_processor.py +++ b/api/core/rag/index_processor/processor/qa_index_processor.py @@ -50,7 +50,7 @@ class QAIndexProcessor(BaseIndexProcessor): hash = helper.generate_text_hash(document_node.page_content) document_node.metadata['doc_id'] = doc_id document_node.metadata['doc_hash'] = hash - # delete Spliter character + # delete Splitter character page_content = document_node.page_content if page_content.startswith(".") or page_content.startswith("。"): page_content = page_content[1:] @@ -107,10 +107,10 @@ class QAIndexProcessor(BaseIndexProcessor): else: vector.delete() - def retrieve(self, retrival_method: str, query: str, dataset: Dataset, top_k: int, + def retrieve(self, retrieval_method: str, query: str, dataset: Dataset, top_k: int, score_threshold: float, reranking_model: dict): # Set search parameters. - results = RetrievalService.retrieve(retrival_method=retrival_method, dataset_id=dataset.id, query=query, + results = RetrievalService.retrieve(retrieval_method=retrieval_method, dataset_id=dataset.id, query=query, top_k=top_k, score_threshold=score_threshold, reranking_model=reranking_model) # Organize results. diff --git a/api/core/rag/retrieval/dataset_retrieval.py b/api/core/rag/retrieval/dataset_retrieval.py index c970e3dafa..db01652f89 100644 --- a/api/core/rag/retrieval/dataset_retrieval.py +++ b/api/core/rag/retrieval/dataset_retrieval.py @@ -21,7 +21,7 @@ from core.rag.data_post_processor.data_post_processor import DataPostProcessor from core.rag.datasource.keyword.jieba.jieba_keyword_table_handler import JiebaKeywordTableHandler from core.rag.datasource.retrieval_service import RetrievalService from core.rag.models.document import Document -from core.rag.retrieval.retrival_methods import RetrievalMethod +from core.rag.retrieval.retrieval_methods import RetrievalMethod from core.rag.retrieval.router.multi_dataset_function_call_router import FunctionCallMultiDatasetRouter from core.rag.retrieval.router.multi_dataset_react_route import ReactMultiDatasetRouter from core.tools.tool.dataset_retriever.dataset_multi_retriever_tool import DatasetMultiRetrieverTool @@ -261,9 +261,9 @@ class DatasetRetrieval: top_k = retrieval_model_config['top_k'] # get retrieval method if dataset.indexing_technique == "economy": - retrival_method = 'keyword_search' + retrieval_method = 'keyword_search' else: - retrival_method = retrieval_model_config['search_method'] + retrieval_method = retrieval_model_config['search_method'] # get reranking model reranking_model = retrieval_model_config['reranking_model'] \ if retrieval_model_config['reranking_enable'] else None @@ -275,7 +275,7 @@ class DatasetRetrieval: with measure_time() as timer: results = RetrievalService.retrieve( - retrival_method=retrival_method, dataset_id=dataset.id, + retrieval_method=retrieval_method, dataset_id=dataset.id, query=query, top_k=top_k, score_threshold=score_threshold, reranking_model=reranking_model, @@ -285,7 +285,7 @@ class DatasetRetrieval: self._on_query(query, [dataset_id], app_id, user_from, user_id) if results: - self._on_retrival_end(results, message_id, timer) + self._on_retrieval_end(results, message_id, timer) return results return [] @@ -347,14 +347,14 @@ class DatasetRetrieval: self._on_query(query, dataset_ids, app_id, user_from, user_id) if all_documents: - self._on_retrival_end(all_documents, message_id, timer) + self._on_retrieval_end(all_documents, message_id, timer) return all_documents - def _on_retrival_end( + def _on_retrieval_end( self, documents: list[Document], message_id: Optional[str] = None, timer: Optional[dict] = None ) -> None: - """Handle retrival end.""" + """Handle retrieval end.""" for document in documents: query = db.session.query(DocumentSegment).filter( DocumentSegment.index_node_id == document.metadata['doc_id'] @@ -419,7 +419,7 @@ class DatasetRetrieval: if dataset.indexing_technique == "economy": # use keyword table query - documents = RetrievalService.retrieve(retrival_method='keyword_search', + documents = RetrievalService.retrieve(retrieval_method='keyword_search', dataset_id=dataset.id, query=query, top_k=top_k @@ -429,7 +429,7 @@ class DatasetRetrieval: else: if top_k > 0: # retrieval source - documents = RetrievalService.retrieve(retrival_method=retrieval_model['search_method'], + documents = RetrievalService.retrieve(retrieval_method=retrieval_model['search_method'], dataset_id=dataset.id, query=query, top_k=top_k, diff --git a/api/core/rag/retrieval/retrival_methods.py b/api/core/rag/retrieval/retrieval_methods.py similarity index 100% rename from api/core/rag/retrieval/retrival_methods.py rename to api/core/rag/retrieval/retrieval_methods.py diff --git a/api/core/rag/splitter/fixed_text_splitter.py b/api/core/rag/splitter/fixed_text_splitter.py index 6a0804f890..0c1cb57c7f 100644 --- a/api/core/rag/splitter/fixed_text_splitter.py +++ b/api/core/rag/splitter/fixed_text_splitter.py @@ -93,17 +93,21 @@ class FixedRecursiveCharacterTextSplitter(EnhanceRecursiveCharacterTextSplitter) splits = list(text) # Now go merging things, recursively splitting longer texts. _good_splits = [] + _good_splits_lengths = [] # cache the lengths of the splits for s in splits: - if self._length_function(s) < self._chunk_size: + s_len = self._length_function(s) + if s_len < self._chunk_size: _good_splits.append(s) + _good_splits_lengths.append(s_len) else: if _good_splits: - merged_text = self._merge_splits(_good_splits, separator) + merged_text = self._merge_splits(_good_splits, separator, _good_splits_lengths) final_chunks.extend(merged_text) _good_splits = [] + _good_splits_lengths = [] other_info = self.recursive_split_text(s) final_chunks.extend(other_info) if _good_splits: - merged_text = self._merge_splits(_good_splits, separator) + merged_text = self._merge_splits(_good_splits, separator, _good_splits_lengths) final_chunks.extend(merged_text) return final_chunks diff --git a/api/core/rag/splitter/text_splitter.py b/api/core/rag/splitter/text_splitter.py index b3adcedc76..f06f22a00e 100644 --- a/api/core/rag/splitter/text_splitter.py +++ b/api/core/rag/splitter/text_splitter.py @@ -30,15 +30,14 @@ def _split_text_with_regex( if keep_separator: # The parentheses in the pattern keep the delimiters in the result. _splits = re.split(f"({re.escape(separator)})", text) - splits = [_splits[i] + _splits[i + 1] for i in range(1, len(_splits), 2)] - if len(_splits) % 2 == 0: + splits = [_splits[i - 1] + _splits[i] for i in range(1, len(_splits), 2)] + if len(_splits) % 2 != 0: splits += _splits[-1:] - splits = [_splits[0]] + splits else: splits = re.split(separator, text) else: splits = list(text) - return [s for s in splits if s != ""] + return [s for s in splits if (s != "" and s != '\n')] class TextSplitter(BaseDocumentTransformer, ABC): @@ -109,7 +108,7 @@ class TextSplitter(BaseDocumentTransformer, ABC): else: return text - def _merge_splits(self, splits: Iterable[str], separator: str) -> list[str]: + def _merge_splits(self, splits: Iterable[str], separator: str, lengths: list[int]) -> list[str]: # We now want to combine these smaller pieces into medium size # chunks to send to the LLM. separator_len = self._length_function(separator) @@ -117,8 +116,9 @@ class TextSplitter(BaseDocumentTransformer, ABC): docs = [] current_doc: list[str] = [] total = 0 + index = 0 for d in splits: - _len = self._length_function(d) + _len = lengths[index] if ( total + _len + (separator_len if len(current_doc) > 0 else 0) > self._chunk_size @@ -146,6 +146,7 @@ class TextSplitter(BaseDocumentTransformer, ABC): current_doc = current_doc[1:] current_doc.append(d) total += _len + (separator_len if len(current_doc) > 1 else 0) + index += 1 doc = self._join_docs(current_doc, separator) if doc is not None: docs.append(doc) @@ -242,7 +243,10 @@ class CharacterTextSplitter(TextSplitter): # First we naively split the large input into a bunch of smaller ones. splits = _split_text_with_regex(text, self._separator, self._keep_separator) _separator = "" if self._keep_separator else self._separator - return self._merge_splits(splits, _separator) + _good_splits_lengths = [] # cache the lengths of the splits + for split in splits: + _good_splits_lengths.append(self._length_function(split)) + return self._merge_splits(splits, _separator, _good_splits_lengths) class LineType(TypedDict): @@ -494,11 +498,10 @@ class RecursiveCharacterTextSplitter(TextSplitter): self._separators = separators or ["\n\n", "\n", " ", ""] def _split_text(self, text: str, separators: list[str]) -> list[str]: - """Split incoming text and return chunks.""" final_chunks = [] - # Get appropriate separator to use separator = separators[-1] new_separators = [] + for i, _s in enumerate(separators): if _s == "": separator = _s @@ -509,25 +512,31 @@ class RecursiveCharacterTextSplitter(TextSplitter): break splits = _split_text_with_regex(text, separator, self._keep_separator) - # Now go merging things, recursively splitting longer texts. _good_splits = [] + _good_splits_lengths = [] # cache the lengths of the splits _separator = "" if self._keep_separator else separator + for s in splits: - if self._length_function(s) < self._chunk_size: + s_len = self._length_function(s) + if s_len < self._chunk_size: _good_splits.append(s) + _good_splits_lengths.append(s_len) else: if _good_splits: - merged_text = self._merge_splits(_good_splits, _separator) + merged_text = self._merge_splits(_good_splits, _separator, _good_splits_lengths) final_chunks.extend(merged_text) _good_splits = [] + _good_splits_lengths = [] if not new_separators: final_chunks.append(s) else: other_info = self._split_text(s, new_separators) final_chunks.extend(other_info) + if _good_splits: - merged_text = self._merge_splits(_good_splits, _separator) + merged_text = self._merge_splits(_good_splits, _separator, _good_splits_lengths) final_chunks.extend(merged_text) + return final_chunks def split_text(self, text: str) -> list[str]: diff --git a/api/core/tools/provider/_position.yaml b/api/core/tools/provider/_position.yaml index 9b90dda3b2..40c3356116 100644 --- a/api/core/tools/provider/_position.yaml +++ b/api/core/tools/provider/_position.yaml @@ -1,5 +1,6 @@ - google - bing +- perplexity - duckduckgo - searchapi - serper diff --git a/api/core/tools/provider/builtin/aws/tools/apply_guardrail.py b/api/core/tools/provider/builtin/aws/tools/apply_guardrail.py index 9c006733bd..06fcf8a453 100644 --- a/api/core/tools/provider/builtin/aws/tools/apply_guardrail.py +++ b/api/core/tools/provider/builtin/aws/tools/apply_guardrail.py @@ -3,6 +3,7 @@ import logging from typing import Any, Union import boto3 +from botocore.exceptions import BotoCoreError from pydantic import BaseModel, Field from core.tools.entities.tool_entities import ToolInvokeMessage @@ -16,7 +17,7 @@ class GuardrailParameters(BaseModel): guardrail_version: str = Field(..., description="The version of the guardrail") source: str = Field(..., description="The source of the content") text: str = Field(..., description="The text to apply the guardrail to") - aws_region: str = Field(default="us-east-1", description="AWS region for the Bedrock client") + aws_region: str = Field(..., description="AWS region for the Bedrock client") class ApplyGuardrailTool(BuiltinTool): def _invoke(self, @@ -40,6 +41,8 @@ class ApplyGuardrailTool(BuiltinTool): source=params.source, content=[{"text": {"text": params.text}}] ) + + logger.info(f"Raw response from AWS: {json.dumps(response, indent=2)}") # Check for empty response if not response: @@ -69,7 +72,7 @@ class ApplyGuardrailTool(BuiltinTool): return self.create_text_message(text=result) - except boto3.exceptions.BotoCoreError as e: + except BotoCoreError as e: error_message = f'AWS service error: {str(e)}' logger.error(error_message, exc_info=True) return self.create_text_message(text=error_message) @@ -80,4 +83,4 @@ class ApplyGuardrailTool(BuiltinTool): except Exception as e: error_message = f'An unexpected error occurred: {str(e)}' logger.error(error_message, exc_info=True) - return self.create_text_message(text=error_message) + return self.create_text_message(text=error_message) \ No newline at end of file diff --git a/api/core/tools/provider/builtin/aws/tools/apply_guardrail.yaml b/api/core/tools/provider/builtin/aws/tools/apply_guardrail.yaml index 2b7c8abb44..66044e4ea8 100644 --- a/api/core/tools/provider/builtin/aws/tools/apply_guardrail.yaml +++ b/api/core/tools/provider/builtin/aws/tools/apply_guardrail.yaml @@ -54,3 +54,14 @@ parameters: zh_Hans: 用于请求护栏审查的内容,可以是用户输入或 LLM 输出。 llm_description: The content used for requesting guardrail review, which can be either user input or LLM output. form: llm + - name: aws_region + type: string + required: true + label: + en_US: AWS Region + zh_Hans: AWS 区域 + human_description: + en_US: Please enter the AWS region for the Bedrock client, for example 'us-east-1'. + zh_Hans: 请输入 Bedrock 客户端的 AWS 区域,例如 'us-east-1'。 + llm_description: Please enter the AWS region for the Bedrock client, for example 'us-east-1'. + form: form diff --git a/api/core/tools/provider/builtin/aws/tools/lambda_yaml_to_json.py b/api/core/tools/provider/builtin/aws/tools/lambda_yaml_to_json.py new file mode 100644 index 0000000000..bb7f6840b8 --- /dev/null +++ b/api/core/tools/provider/builtin/aws/tools/lambda_yaml_to_json.py @@ -0,0 +1,71 @@ +import json +import logging +from typing import Any, Union + +import boto3 + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +console_handler = logging.StreamHandler() +logger.addHandler(console_handler) + + +class LambdaYamlToJsonTool(BuiltinTool): + lambda_client: Any = None + + def _invoke_lambda(self, lambda_name: str, yaml_content: str) -> str: + msg = { + "body": yaml_content + } + logger.info(json.dumps(msg)) + + invoke_response = self.lambda_client.invoke(FunctionName=lambda_name, + InvocationType='RequestResponse', + Payload=json.dumps(msg)) + response_body = invoke_response['Payload'] + + response_str = response_body.read().decode("utf-8") + resp_json = json.loads(response_str) + + logger.info(resp_json) + if resp_json['statusCode'] != 200: + raise Exception(f"Invalid status code: {response_str}") + + return resp_json['body'] + + def _invoke(self, + user_id: str, + tool_parameters: dict[str, Any], + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + """ + invoke tools + """ + try: + if not self.lambda_client: + aws_region = tool_parameters.get('aws_region') # todo: move aws_region out, and update client region + if aws_region: + self.lambda_client = boto3.client("lambda", region_name=aws_region) + else: + self.lambda_client = boto3.client("lambda") + + yaml_content = tool_parameters.get('yaml_content', '') + if not yaml_content: + return self.create_text_message('Please input yaml_content') + + lambda_name = tool_parameters.get('lambda_name', '') + if not lambda_name: + return self.create_text_message('Please input lambda_name') + logger.debug(f'{json.dumps(tool_parameters, indent=2, ensure_ascii=False)}') + + result = self._invoke_lambda(lambda_name, yaml_content) + logger.debug(result) + + return self.create_text_message(result) + except Exception as e: + return self.create_text_message(f'Exception: {str(e)}') + + console_handler.flush() \ No newline at end of file diff --git a/api/core/tools/provider/builtin/aws/tools/lambda_yaml_to_json.yaml b/api/core/tools/provider/builtin/aws/tools/lambda_yaml_to_json.yaml new file mode 100644 index 0000000000..919c285348 --- /dev/null +++ b/api/core/tools/provider/builtin/aws/tools/lambda_yaml_to_json.yaml @@ -0,0 +1,53 @@ +identity: + name: lambda_yaml_to_json + author: AWS + label: + en_US: LambdaYamlToJson + zh_Hans: LambdaYamlToJson + pt_BR: LambdaYamlToJson + icon: icon.svg +description: + human: + en_US: A tool to convert yaml to json using AWS Lambda. + zh_Hans: 将 YAML 转为 JSON 的工具(通过AWS Lambda)。 + pt_BR: A tool to convert yaml to json using AWS Lambda. + llm: A tool to convert yaml to json. +parameters: + - name: yaml_content + type: string + required: true + label: + en_US: YAML content to convert for + zh_Hans: YAML 内容 + pt_BR: YAML content to convert for + human_description: + en_US: YAML content to convert for + zh_Hans: YAML 内容 + pt_BR: YAML content to convert for + llm_description: YAML content to convert for + form: llm + - name: aws_region + type: string + required: false + label: + en_US: region of lambda + zh_Hans: Lambda 所在的region + pt_BR: region of lambda + human_description: + en_US: region of lambda + zh_Hans: Lambda 所在的region + pt_BR: region of lambda + llm_description: region of lambda + form: form + - name: lambda_name + type: string + required: false + label: + en_US: name of lambda + zh_Hans: Lambda 名称 + pt_BR: name of lambda + human_description: + en_US: name of lambda + zh_Hans: Lambda 名称 + pt_BR: name of lambda + form: form diff --git a/api/core/tools/provider/builtin/aws/tools/sagemaker_text_rerank.py b/api/core/tools/provider/builtin/aws/tools/sagemaker_text_rerank.py index d4bc446e5b..2b3a3eaad6 100644 --- a/api/core/tools/provider/builtin/aws/tools/sagemaker_text_rerank.py +++ b/api/core/tools/provider/builtin/aws/tools/sagemaker_text_rerank.py @@ -78,9 +78,7 @@ class SageMakerReRankTool(BuiltinTool): sorted_candidate_docs = sorted(candidate_docs, key=lambda x: x['score'], reverse=True) line = 9 - results_str = json.dumps(sorted_candidate_docs[:self.topk], ensure_ascii=False) - return self.create_text_message(text=results_str) + return [ self.create_json_message(res) for res in sorted_candidate_docs[:self.topk] ] except Exception as e: - return self.create_text_message(f'Exception {str(e)}, line : {line}') - \ No newline at end of file + return self.create_text_message(f'Exception {str(e)}, line : {line}') \ No newline at end of file diff --git a/api/core/tools/provider/builtin/aws/tools/sagemaker_tts.py b/api/core/tools/provider/builtin/aws/tools/sagemaker_tts.py new file mode 100644 index 0000000000..a100e62230 --- /dev/null +++ b/api/core/tools/provider/builtin/aws/tools/sagemaker_tts.py @@ -0,0 +1,95 @@ +import json +from enum import Enum +from typing import Any, Union + +import boto3 + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool + + +class TTSModelType(Enum): + PresetVoice = "PresetVoice" + CloneVoice = "CloneVoice" + CloneVoice_CrossLingual = "CloneVoice_CrossLingual" + InstructVoice = "InstructVoice" + +class SageMakerTTSTool(BuiltinTool): + sagemaker_client: Any = None + sagemaker_endpoint:str = None + s3_client : Any = None + comprehend_client : Any = None + + def _detect_lang_code(self, content:str, map_dict:dict=None): + map_dict = { + "zh" : "<|zh|>", + "en" : "<|en|>", + "ja" : "<|jp|>", + "zh-TW" : "<|yue|>", + "ko" : "<|ko|>" + } + + response = self.comprehend_client.detect_dominant_language(Text=content) + language_code = response['Languages'][0]['LanguageCode'] + return map_dict.get(language_code, '<|zh|>') + + def _build_tts_payload(self, model_type:str, content_text:str, model_role:str, prompt_text:str, prompt_audio:str, instruct_text:str): + if model_type == TTSModelType.PresetVoice.value and model_role: + return { "tts_text" : content_text, "role" : model_role } + if model_type == TTSModelType.CloneVoice.value and prompt_text and prompt_audio: + return { "tts_text" : content_text, "prompt_text": prompt_text, "prompt_audio" : prompt_audio } + if model_type == TTSModelType.CloneVoice_CrossLingual.value and prompt_audio: + lang_tag = self._detect_lang_code(content_text) + return { "tts_text" : f"{content_text}", "prompt_audio" : prompt_audio, "lang_tag" : lang_tag } + if model_type == TTSModelType.InstructVoice.value and instruct_text and model_role: + return { "tts_text" : content_text, "role" : model_role, "instruct_text" : instruct_text } + + raise RuntimeError(f"Invalid params for {model_type}") + + def _invoke_sagemaker(self, payload:dict, endpoint:str): + response_model = self.sagemaker_client.invoke_endpoint( + EndpointName=endpoint, + Body=json.dumps(payload), + ContentType="application/json", + ) + json_str = response_model['Body'].read().decode('utf8') + json_obj = json.loads(json_str) + return json_obj + + def _invoke(self, + user_id: str, + tool_parameters: dict[str, Any], + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + """ + invoke tools + """ + try: + if not self.sagemaker_client: + aws_region = tool_parameters.get('aws_region') + if aws_region: + self.sagemaker_client = boto3.client("sagemaker-runtime", region_name=aws_region) + self.s3_client = boto3.client("s3", region_name=aws_region) + self.comprehend_client = boto3.client('comprehend', region_name=aws_region) + else: + self.sagemaker_client = boto3.client("sagemaker-runtime") + self.s3_client = boto3.client("s3") + self.comprehend_client = boto3.client('comprehend') + + if not self.sagemaker_endpoint: + self.sagemaker_endpoint = tool_parameters.get('sagemaker_endpoint') + + tts_text = tool_parameters.get('tts_text') + tts_infer_type = tool_parameters.get('tts_infer_type') + + voice = tool_parameters.get('voice') + mock_voice_audio = tool_parameters.get('mock_voice_audio') + mock_voice_text = tool_parameters.get('mock_voice_text') + voice_instruct_prompt = tool_parameters.get('voice_instruct_prompt') + payload = self._build_tts_payload(tts_infer_type, tts_text, voice, mock_voice_text, mock_voice_audio, voice_instruct_prompt) + + result = self._invoke_sagemaker(payload, self.sagemaker_endpoint) + + return self.create_text_message(text=result['s3_presign_url']) + + except Exception as e: + return self.create_text_message(f'Exception {str(e)}') \ No newline at end of file diff --git a/api/core/tools/provider/builtin/aws/tools/sagemaker_tts.yaml b/api/core/tools/provider/builtin/aws/tools/sagemaker_tts.yaml new file mode 100644 index 0000000000..a6a61dd4aa --- /dev/null +++ b/api/core/tools/provider/builtin/aws/tools/sagemaker_tts.yaml @@ -0,0 +1,149 @@ +identity: + name: sagemaker_tts + author: AWS + label: + en_US: SagemakerTTS + zh_Hans: Sagemaker语音合成 + pt_BR: SagemakerTTS + icon: icon.svg +description: + human: + en_US: A tool for Speech synthesis - https://github.com/aws-samples/dify-aws-tool + zh_Hans: Sagemaker语音合成工具, 请参考 Github Repo - https://github.com/aws-samples/dify-aws-tool上的部署脚本 + pt_BR: A tool for Speech synthesis. + llm: A tool for Speech synthesis. You can find deploy notebook on Github Repo - https://github.com/aws-samples/dify-aws-tool +parameters: + - name: sagemaker_endpoint + type: string + required: true + label: + en_US: sagemaker endpoint for tts + zh_Hans: 语音生成的SageMaker端点 + pt_BR: sagemaker endpoint for tts + human_description: + en_US: sagemaker endpoint for tts + zh_Hans: 语音生成的SageMaker端点 + pt_BR: sagemaker endpoint for tts + llm_description: sagemaker endpoint for tts + form: form + - name: tts_text + type: string + required: true + label: + en_US: tts text + zh_Hans: 语音合成原文 + pt_BR: tts text + human_description: + en_US: tts text + zh_Hans: 语音合成原文 + pt_BR: tts text + llm_description: tts text + form: llm + - name: tts_infer_type + type: select + required: false + label: + en_US: tts infer type + zh_Hans: 合成方式 + pt_BR: tts infer type + human_description: + en_US: tts infer type + zh_Hans: 合成方式 + pt_BR: tts infer type + llm_description: tts infer type + options: + - value: PresetVoice + label: + en_US: preset voice + zh_Hans: 预置音色 + - value: CloneVoice + label: + en_US: clone voice + zh_Hans: 克隆音色 + - value: CloneVoice_CrossLingual + label: + en_US: clone crossLingual voice + zh_Hans: 克隆音色(跨语言) + - value: InstructVoice + label: + en_US: instruct voice + zh_Hans: 指令音色 + form: form + - name: voice + type: select + required: false + label: + en_US: preset voice + zh_Hans: 预置音色 + pt_BR: preset voice + human_description: + en_US: preset voice + zh_Hans: 预置音色 + pt_BR: preset voice + llm_description: preset voice + options: + - value: 中文男 + label: + en_US: zh-cn male + zh_Hans: 中文男 + - value: 中文女 + label: + en_US: zh-cn female + zh_Hans: 中文女 + - value: 粤语女 + label: + en_US: zh-TW female + zh_Hans: 粤语女 + form: form + - name: mock_voice_audio + type: string + required: false + label: + en_US: clone voice link + zh_Hans: 克隆音频链接 + pt_BR: clone voice link + human_description: + en_US: clone voice link + zh_Hans: 克隆音频链接 + pt_BR: clone voice link + llm_description: clone voice link + form: llm + - name: mock_voice_text + type: string + required: false + label: + en_US: text of clone voice + zh_Hans: 克隆音频对应文本 + pt_BR: text of clone voice + human_description: + en_US: text of clone voice + zh_Hans: 克隆音频对应文本 + pt_BR: text of clone voice + llm_description: text of clone voice + form: llm + - name: voice_instruct_prompt + type: string + required: false + label: + en_US: instruct prompt for voice + zh_Hans: 音色指令文本 + pt_BR: instruct prompt for voice + human_description: + en_US: instruct prompt for voice + zh_Hans: 音色指令文本 + pt_BR: instruct prompt for voice + llm_description: instruct prompt for voice + form: llm + - name: aws_region + type: string + required: false + label: + en_US: region of sagemaker endpoint + zh_Hans: SageMaker 端点所在的region + pt_BR: region of sagemaker endpoint + human_description: + en_US: region of sagemaker endpoint + zh_Hans: SageMaker 端点所在的region + pt_BR: region of sagemaker endpoint + llm_description: region of sagemaker endpoint + form: form diff --git a/api/core/tools/provider/builtin/dalle/dalle.yaml b/api/core/tools/provider/builtin/dalle/dalle.yaml index f09a9177f2..37cf93c28a 100644 --- a/api/core/tools/provider/builtin/dalle/dalle.yaml +++ b/api/core/tools/provider/builtin/dalle/dalle.yaml @@ -29,7 +29,7 @@ credentials_for_provider: en_US: Please input your OpenAI API key zh_Hans: 请输入你的 OpenAI API key pt_BR: Please input your OpenAI API key - openai_organizaion_id: + openai_organization_id: type: text-input required: false label: diff --git a/api/core/tools/provider/builtin/dalle/tools/dalle2.py b/api/core/tools/provider/builtin/dalle/tools/dalle2.py index 450e782281..9e9f32d429 100644 --- a/api/core/tools/provider/builtin/dalle/tools/dalle2.py +++ b/api/core/tools/provider/builtin/dalle/tools/dalle2.py @@ -16,7 +16,7 @@ class DallE2Tool(BuiltinTool): """ invoke tools """ - openai_organization = self.runtime.credentials.get('openai_organizaion_id', None) + openai_organization = self.runtime.credentials.get('openai_organization_id', None) if not openai_organization: openai_organization = None openai_base_url = self.runtime.credentials.get('openai_base_url', None) diff --git a/api/core/tools/provider/builtin/dalle/tools/dalle3.py b/api/core/tools/provider/builtin/dalle/tools/dalle3.py index f985deade5..4f5033dd7f 100644 --- a/api/core/tools/provider/builtin/dalle/tools/dalle3.py +++ b/api/core/tools/provider/builtin/dalle/tools/dalle3.py @@ -17,7 +17,7 @@ class DallE3Tool(BuiltinTool): """ invoke tools """ - openai_organization = self.runtime.credentials.get('openai_organizaion_id', None) + openai_organization = self.runtime.credentials.get('openai_organization_id', None) if not openai_organization: openai_organization = None openai_base_url = self.runtime.credentials.get('openai_base_url', None) diff --git a/api/core/tools/provider/builtin/github/github.py b/api/core/tools/provider/builtin/github/github.py index 9275504208..b19f0896f8 100644 --- a/api/core/tools/provider/builtin/github/github.py +++ b/api/core/tools/provider/builtin/github/github.py @@ -4,7 +4,7 @@ from core.tools.errors import ToolProviderCredentialValidationError from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController -class GihubProvider(BuiltinToolProviderController): +class GithubProvider(BuiltinToolProviderController): def _validate_credentials(self, credentials: dict) -> None: try: if 'access_tokens' not in credentials or not credentials.get('access_tokens'): diff --git a/api/core/tools/provider/builtin/github/tools/github_repositories.py b/api/core/tools/provider/builtin/github/tools/github_repositories.py index a2f1e07fd4..305bf08ce8 100644 --- a/api/core/tools/provider/builtin/github/tools/github_repositories.py +++ b/api/core/tools/provider/builtin/github/tools/github_repositories.py @@ -9,7 +9,7 @@ from core.tools.entities.tool_entities import ToolInvokeMessage from core.tools.tool.builtin_tool import BuiltinTool -class GihubRepositoriesTool(BuiltinTool): +class GithubRepositoriesTool(BuiltinTool): def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: """ invoke tools diff --git a/api/core/tools/provider/builtin/gitlab/tools/gitlab_commits.py b/api/core/tools/provider/builtin/gitlab/tools/gitlab_commits.py index 880d722bda..0824eb3a26 100644 --- a/api/core/tools/provider/builtin/gitlab/tools/gitlab_commits.py +++ b/api/core/tools/provider/builtin/gitlab/tools/gitlab_commits.py @@ -60,7 +60,7 @@ class GitlabCommitsTool(BuiltinTool): project_name = project['name'] print(f"Project: {project_name}") - # Get all of proejct commits + # Get all of project commits commits_url = f"{domain}/api/v4/projects/{project_id}/repository/commits" params = { 'since': start_time, @@ -83,7 +83,7 @@ class GitlabCommitsTool(BuiltinTool): diffs = diff_response.json() for diff in diffs: - # Caculate code lines of changed + # Calculate code lines of changed added_lines = diff['diff'].count('\n+') removed_lines = diff['diff'].count('\n-') total_changes = added_lines + removed_lines diff --git a/api/core/tools/provider/builtin/gitlab/tools/gitlab_commits.yaml b/api/core/tools/provider/builtin/gitlab/tools/gitlab_commits.yaml index dd4e31d663..d38d943958 100644 --- a/api/core/tools/provider/builtin/gitlab/tools/gitlab_commits.yaml +++ b/api/core/tools/provider/builtin/gitlab/tools/gitlab_commits.yaml @@ -6,7 +6,7 @@ identity: zh_Hans: GitLab 提交内容查询 description: human: - en_US: A tool for query GitLab commits, Input should be a exists username or projec. + en_US: A tool for query GitLab commits, Input should be a exists username or project. zh_Hans: 一个用于查询 GitLab 代码提交内容的工具,输入的内容应该是一个已存在的用户名或者项目名。 llm: A tool for query GitLab commits, Input should be a exists username or project. parameters: diff --git a/api/core/tools/provider/builtin/openweather/tools/weather.py b/api/core/tools/provider/builtin/openweather/tools/weather.py index 536a3511f4..d6c49a230f 100644 --- a/api/core/tools/provider/builtin/openweather/tools/weather.py +++ b/api/core/tools/provider/builtin/openweather/tools/weather.py @@ -29,7 +29,7 @@ class OpenweatherTool(BuiltinTool): # request URL url = "https://api.openweathermap.org/data/2.5/weather" - # request parmas + # request params params = { "q": city, "appid": self.runtime.credentials.get("api_key"), diff --git a/api/core/tools/provider/builtin/perplexity/_assets/icon.svg b/api/core/tools/provider/builtin/perplexity/_assets/icon.svg new file mode 100644 index 0000000000..c2974c142f --- /dev/null +++ b/api/core/tools/provider/builtin/perplexity/_assets/icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/api/core/tools/provider/builtin/perplexity/perplexity.py b/api/core/tools/provider/builtin/perplexity/perplexity.py new file mode 100644 index 0000000000..ff91edf18d --- /dev/null +++ b/api/core/tools/provider/builtin/perplexity/perplexity.py @@ -0,0 +1,46 @@ +from typing import Any + +import requests + +from core.tools.errors import ToolProviderCredentialValidationError +from core.tools.provider.builtin.perplexity.tools.perplexity_search import PERPLEXITY_API_URL +from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController + + +class PerplexityProvider(BuiltinToolProviderController): + def _validate_credentials(self, credentials: dict[str, Any]) -> None: + headers = { + "Authorization": f"Bearer {credentials.get('perplexity_api_key')}", + "Content-Type": "application/json" + } + + payload = { + "model": "llama-3.1-sonar-small-128k-online", + "messages": [ + { + "role": "system", + "content": "You are a helpful assistant." + }, + { + "role": "user", + "content": "Hello" + } + ], + "max_tokens": 5, + "temperature": 0.1, + "top_p": 0.9, + "stream": False + } + + try: + response = requests.post(PERPLEXITY_API_URL, json=payload, headers=headers) + response.raise_for_status() + except requests.RequestException as e: + raise ToolProviderCredentialValidationError( + f"Failed to validate Perplexity API key: {str(e)}" + ) + + if response.status_code != 200: + raise ToolProviderCredentialValidationError( + f"Perplexity API key is invalid. Status code: {response.status_code}" + ) diff --git a/api/core/tools/provider/builtin/perplexity/perplexity.yaml b/api/core/tools/provider/builtin/perplexity/perplexity.yaml new file mode 100644 index 0000000000..c0b504f300 --- /dev/null +++ b/api/core/tools/provider/builtin/perplexity/perplexity.yaml @@ -0,0 +1,26 @@ +identity: + author: Dify + name: perplexity + label: + en_US: Perplexity + zh_Hans: Perplexity + description: + en_US: Perplexity.AI + zh_Hans: Perplexity.AI + icon: icon.svg + tags: + - search +credentials_for_provider: + perplexity_api_key: + type: secret-input + required: true + label: + en_US: Perplexity API key + zh_Hans: Perplexity API key + placeholder: + en_US: Please input your Perplexity API key + zh_Hans: 请输入你的 Perplexity API key + help: + en_US: Get your Perplexity API key from Perplexity + zh_Hans: 从 Perplexity 获取您的 Perplexity API key + url: https://www.perplexity.ai/settings/api diff --git a/api/core/tools/provider/builtin/perplexity/tools/perplexity_search.py b/api/core/tools/provider/builtin/perplexity/tools/perplexity_search.py new file mode 100644 index 0000000000..5b1a263f9b --- /dev/null +++ b/api/core/tools/provider/builtin/perplexity/tools/perplexity_search.py @@ -0,0 +1,72 @@ +import json +from typing import Any, Union + +import requests + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool + +PERPLEXITY_API_URL = "https://api.perplexity.ai/chat/completions" + +class PerplexityAITool(BuiltinTool): + def _parse_response(self, response: dict) -> dict: + """Parse the response from Perplexity AI API""" + if 'choices' in response and len(response['choices']) > 0: + message = response['choices'][0]['message'] + return { + 'content': message.get('content', ''), + 'role': message.get('role', ''), + 'citations': response.get('citations', []) + } + else: + return {'content': 'Unable to get a valid response', 'role': 'assistant', 'citations': []} + + def _invoke(self, + user_id: str, + tool_parameters: dict[str, Any], + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + headers = { + "Authorization": f"Bearer {self.runtime.credentials['perplexity_api_key']}", + "Content-Type": "application/json" + } + + payload = { + "model": tool_parameters.get('model', 'llama-3.1-sonar-small-128k-online'), + "messages": [ + { + "role": "system", + "content": "Be precise and concise." + }, + { + "role": "user", + "content": tool_parameters['query'] + } + ], + "max_tokens": tool_parameters.get('max_tokens', 4096), + "temperature": tool_parameters.get('temperature', 0.7), + "top_p": tool_parameters.get('top_p', 1), + "top_k": tool_parameters.get('top_k', 5), + "presence_penalty": tool_parameters.get('presence_penalty', 0), + "frequency_penalty": tool_parameters.get('frequency_penalty', 1), + "stream": False + } + + if 'search_recency_filter' in tool_parameters: + payload['search_recency_filter'] = tool_parameters['search_recency_filter'] + if 'return_citations' in tool_parameters: + payload['return_citations'] = tool_parameters['return_citations'] + if 'search_domain_filter' in tool_parameters: + if isinstance(tool_parameters['search_domain_filter'], str): + payload['search_domain_filter'] = [tool_parameters['search_domain_filter']] + elif isinstance(tool_parameters['search_domain_filter'], list): + payload['search_domain_filter'] = tool_parameters['search_domain_filter'] + + + response = requests.post(url=PERPLEXITY_API_URL, json=payload, headers=headers) + response.raise_for_status() + valuable_res = self._parse_response(response.json()) + + return [ + self.create_json_message(valuable_res), + self.create_text_message(json.dumps(valuable_res, ensure_ascii=False, indent=2)) + ] diff --git a/api/core/tools/provider/builtin/perplexity/tools/perplexity_search.yaml b/api/core/tools/provider/builtin/perplexity/tools/perplexity_search.yaml new file mode 100644 index 0000000000..02a645df33 --- /dev/null +++ b/api/core/tools/provider/builtin/perplexity/tools/perplexity_search.yaml @@ -0,0 +1,178 @@ +identity: + name: perplexity + author: Dify + label: + en_US: Perplexity Search +description: + human: + en_US: Search information using Perplexity AI's language models. + llm: This tool is used to search information using Perplexity AI's language models. +parameters: + - name: query + type: string + required: true + label: + en_US: Query + zh_Hans: 查询 + human_description: + en_US: The text query to be processed by the AI model. + zh_Hans: 要由 AI 模型处理的文本查询。 + form: llm + - name: model + type: select + required: false + label: + en_US: Model Name + zh_Hans: 模型名称 + human_description: + en_US: The Perplexity AI model to use for generating the response. + zh_Hans: 用于生成响应的 Perplexity AI 模型。 + form: form + default: "llama-3.1-sonar-small-128k-online" + options: + - value: llama-3.1-sonar-small-128k-online + label: + en_US: llama-3.1-sonar-small-128k-online + zh_Hans: llama-3.1-sonar-small-128k-online + - value: llama-3.1-sonar-large-128k-online + label: + en_US: llama-3.1-sonar-large-128k-online + zh_Hans: llama-3.1-sonar-large-128k-online + - value: llama-3.1-sonar-huge-128k-online + label: + en_US: llama-3.1-sonar-huge-128k-online + zh_Hans: llama-3.1-sonar-huge-128k-online + - name: max_tokens + type: number + required: false + label: + en_US: Max Tokens + zh_Hans: 最大令牌数 + pt_BR: Máximo de Tokens + human_description: + en_US: The maximum number of tokens to generate in the response. + zh_Hans: 在响应中生成的最大令牌数。 + pt_BR: O número máximo de tokens a serem gerados na resposta. + form: form + default: 4096 + min: 1 + max: 4096 + - name: temperature + type: number + required: false + label: + en_US: Temperature + zh_Hans: 温度 + pt_BR: Temperatura + human_description: + en_US: Controls randomness in the output. Lower values make the output more focused and deterministic. + zh_Hans: 控制输出的随机性。较低的值使输出更加集中和确定。 + form: form + default: 0.7 + min: 0 + max: 1 + - name: top_k + type: number + required: false + label: + en_US: Top K + zh_Hans: 取样数量 + human_description: + en_US: The number of top results to consider for response generation. + zh_Hans: 用于生成响应的顶部结果数量。 + form: form + default: 5 + min: 1 + max: 100 + - name: top_p + type: number + required: false + label: + en_US: Top P + zh_Hans: Top P + human_description: + en_US: Controls diversity via nucleus sampling. + zh_Hans: 通过核心采样控制多样性。 + form: form + default: 1 + min: 0.1 + max: 1 + step: 0.1 + - name: presence_penalty + type: number + required: false + label: + en_US: Presence Penalty + zh_Hans: 存在惩罚 + human_description: + en_US: Positive values penalize new tokens based on whether they appear in the text so far. + zh_Hans: 正值会根据新词元是否已经出现在文本中来对其进行惩罚。 + form: form + default: 0 + min: -1.0 + max: 1.0 + step: 0.1 + - name: frequency_penalty + type: number + required: false + label: + en_US: Frequency Penalty + zh_Hans: 频率惩罚 + human_description: + en_US: Positive values penalize new tokens based on their existing frequency in the text so far. + zh_Hans: 正值会根据新词元在文本中已经出现的频率来对其进行惩罚。 + form: form + default: 1 + min: 0.1 + max: 1.0 + step: 0.1 + - name: return_citations + type: boolean + required: false + label: + en_US: Return Citations + zh_Hans: 返回引用 + human_description: + en_US: Whether to return citations in the response. + zh_Hans: 是否在响应中返回引用。 + form: form + default: true + - name: search_domain_filter + type: string + required: false + label: + en_US: Search Domain Filter + zh_Hans: 搜索域过滤器 + human_description: + en_US: Domain to filter the search results. + zh_Hans: 用于过滤搜索结果的域名。 + form: form + default: "" + - name: search_recency_filter + type: select + required: false + label: + en_US: Search Recency Filter + zh_Hans: 搜索时间过滤器 + human_description: + en_US: Filter for search results based on recency. + zh_Hans: 基于时间筛选搜索结果。 + form: form + default: "month" + options: + - value: day + label: + en_US: Day + zh_Hans: 天 + - value: week + label: + en_US: Week + zh_Hans: 周 + - value: month + label: + en_US: Month + zh_Hans: 月 + - value: year + label: + en_US: Year + zh_Hans: 年 diff --git a/api/core/tools/provider/builtin/spark/tools/spark_img_generation.py b/api/core/tools/provider/builtin/spark/tools/spark_img_generation.py index a977af2b76..c7b0de014f 100644 --- a/api/core/tools/provider/builtin/spark/tools/spark_img_generation.py +++ b/api/core/tools/provider/builtin/spark/tools/spark_img_generation.py @@ -35,20 +35,20 @@ def sha256base64(data): return digest -def parse_url(requset_url): - stidx = requset_url.index("://") - host = requset_url[stidx + 3 :] - schema = requset_url[: stidx + 3] +def parse_url(request_url): + stidx = request_url.index("://") + host = request_url[stidx + 3 :] + schema = request_url[: stidx + 3] edidx = host.index("/") if edidx <= 0: - raise AssembleHeaderException("invalid request url:" + requset_url) + raise AssembleHeaderException("invalid request url:" + request_url) path = host[edidx:] host = host[:edidx] u = Url(host, path, schema) return u -def assemble_ws_auth_url(requset_url, method="GET", api_key="", api_secret=""): - u = parse_url(requset_url) +def assemble_ws_auth_url(request_url, method="GET", api_key="", api_secret=""): + u = parse_url(request_url) host = u.host path = u.path now = datetime.now() @@ -69,7 +69,7 @@ def assemble_ws_auth_url(requset_url, method="GET", api_key="", api_secret=""): ) values = {"host": host, "date": date, "authorization": authorization} - return requset_url + "?" + urlencode(values) + return request_url + "?" + urlencode(values) def get_body(appid, text): diff --git a/api/core/tools/provider/builtin/spider/tools/scraper_crawler.py b/api/core/tools/provider/builtin/spider/tools/scraper_crawler.py index 64bbcc10cc..40736cd402 100644 --- a/api/core/tools/provider/builtin/spider/tools/scraper_crawler.py +++ b/api/core/tools/provider/builtin/spider/tools/scraper_crawler.py @@ -42,6 +42,6 @@ class ScrapeTool(BuiltinTool): result += "URL: " + i.get('url', '') + "\n" result += "CONTENT: " + i.get('content', '') + "\n\n" except Exception as e: - return self.create_text_message("An error occured", str(e)) + return self.create_text_message("An error occurred", str(e)) return self.create_text_message(result) diff --git a/api/core/tools/provider/builtin/stepfun/tools/image.py b/api/core/tools/provider/builtin/stepfun/tools/image.py index 5e544aada6..c571f54675 100644 --- a/api/core/tools/provider/builtin/stepfun/tools/image.py +++ b/api/core/tools/provider/builtin/stepfun/tools/image.py @@ -17,11 +17,8 @@ class StepfunTool(BuiltinTool): """ invoke tools """ - base_url = self.runtime.credentials.get('stepfun_base_url', None) - if not base_url: - base_url = None - else: - base_url = str(URL(base_url) / 'v1') + base_url = self.runtime.credentials.get('stepfun_base_url', 'https://api.stepfun.com') + base_url = str(URL(base_url) / 'v1') client = OpenAI( api_key=self.runtime.credentials['stepfun_api_key'], diff --git a/api/core/tools/tool/dataset_retriever/dataset_multi_retriever_tool.py b/api/core/tools/tool/dataset_retriever/dataset_multi_retriever_tool.py index 7cb7c033bb..d6ecc9257b 100644 --- a/api/core/tools/tool/dataset_retriever/dataset_multi_retriever_tool.py +++ b/api/core/tools/tool/dataset_retriever/dataset_multi_retriever_tool.py @@ -8,7 +8,7 @@ from core.model_manager import ModelManager from core.model_runtime.entities.model_entities import ModelType from core.rag.datasource.retrieval_service import RetrievalService from core.rag.rerank.rerank_model import RerankModelRunner -from core.rag.retrieval.retrival_methods import RetrievalMethod +from core.rag.retrieval.retrieval_methods import RetrievalMethod from core.tools.tool.dataset_retriever.dataset_retriever_base_tool import DatasetRetrieverBaseTool from extensions.ext_database import db from models.dataset import Dataset, Document, DocumentSegment @@ -163,7 +163,7 @@ class DatasetMultiRetrieverTool(DatasetRetrieverBaseTool): if dataset.indexing_technique == "economy": # use keyword table query - documents = RetrievalService.retrieve(retrival_method='keyword_search', + documents = RetrievalService.retrieve(retrieval_method='keyword_search', dataset_id=dataset.id, query=query, top_k=self.top_k @@ -173,7 +173,7 @@ class DatasetMultiRetrieverTool(DatasetRetrieverBaseTool): else: if self.top_k > 0: # retrieval source - documents = RetrievalService.retrieve(retrival_method=retrieval_model['search_method'], + documents = RetrievalService.retrieve(retrieval_method=retrieval_model['search_method'], dataset_id=dataset.id, query=query, top_k=self.top_k, diff --git a/api/core/tools/tool/dataset_retriever/dataset_retriever_tool.py b/api/core/tools/tool/dataset_retriever/dataset_retriever_tool.py index a7e70af628..220e4baa85 100644 --- a/api/core/tools/tool/dataset_retriever/dataset_retriever_tool.py +++ b/api/core/tools/tool/dataset_retriever/dataset_retriever_tool.py @@ -2,7 +2,7 @@ from pydantic import BaseModel, Field from core.rag.datasource.retrieval_service import RetrievalService -from core.rag.retrieval.retrival_methods import RetrievalMethod +from core.rag.retrieval.retrieval_methods import RetrievalMethod from core.tools.tool.dataset_retriever.dataset_retriever_base_tool import DatasetRetrieverBaseTool from extensions.ext_database import db from models.dataset import Dataset, Document, DocumentSegment @@ -63,7 +63,7 @@ class DatasetRetrieverTool(DatasetRetrieverBaseTool): retrieval_model = dataset.retrieval_model if dataset.retrieval_model else default_retrieval_model if dataset.indexing_technique == "economy": # use keyword table query - documents = RetrievalService.retrieve(retrival_method='keyword_search', + documents = RetrievalService.retrieve(retrieval_method='keyword_search', dataset_id=dataset.id, query=query, top_k=self.top_k @@ -72,7 +72,7 @@ class DatasetRetrieverTool(DatasetRetrieverBaseTool): else: if self.top_k > 0: # retrieval source - documents = RetrievalService.retrieve(retrival_method=retrieval_model.get('search_method', 'semantic_search'), + documents = RetrievalService.retrieve(retrieval_method=retrieval_model.get('search_method', 'semantic_search'), dataset_id=dataset.id, query=query, top_k=self.top_k, diff --git a/api/core/tools/tool/dataset_retriever_tool.py b/api/core/tools/tool/dataset_retriever_tool.py index 60ea084bcc..e1f53c0338 100644 --- a/api/core/tools/tool/dataset_retriever_tool.py +++ b/api/core/tools/tool/dataset_retriever_tool.py @@ -18,7 +18,7 @@ from core.tools.tool.tool import Tool class DatasetRetrieverTool(Tool): - retrival_tool: DatasetRetrieverBaseTool + retrieval_tool: DatasetRetrieverBaseTool @staticmethod def get_dataset_tools(tenant_id: str, @@ -43,7 +43,7 @@ class DatasetRetrieverTool(Tool): # Agent only support SINGLE mode original_retriever_mode = retrieve_config.retrieve_strategy retrieve_config.retrieve_strategy = DatasetRetrieveConfigEntity.RetrieveStrategy.SINGLE - retrival_tools = feature.to_dataset_retriever_tool( + retrieval_tools = feature.to_dataset_retriever_tool( tenant_id=tenant_id, dataset_ids=dataset_ids, retrieve_config=retrieve_config, @@ -51,20 +51,23 @@ class DatasetRetrieverTool(Tool): invoke_from=invoke_from, hit_callback=hit_callback ) + if retrieval_tools is None or len(retrieval_tools) == 0: + return [] + # restore retrieve strategy retrieve_config.retrieve_strategy = original_retriever_mode - # convert retrival tools to Tools + # convert retrieval tools to Tools tools = [] - for retrival_tool in retrival_tools: + for retrieval_tool in retrieval_tools: tool = DatasetRetrieverTool( - retrival_tool=retrival_tool, - identity=ToolIdentity(provider='', author='', name=retrival_tool.name, label=I18nObject(en_US='', zh_Hans='')), + retrieval_tool=retrieval_tool, + identity=ToolIdentity(provider='', author='', name=retrieval_tool.name, label=I18nObject(en_US='', zh_Hans='')), parameters=[], is_team_authorization=True, description=ToolDescription( human=I18nObject(en_US='', zh_Hans=''), - llm=retrival_tool.description), + llm=retrieval_tool.description), runtime=DatasetRetrieverTool.Runtime() ) @@ -96,8 +99,7 @@ class DatasetRetrieverTool(Tool): yield self.create_text_message(text='please input query') else: # invoke dataset retriever tool - result = self.retrival_tool._run(query=query) - + result = self.retrieval_tool._run(query=query) yield self.create_text_message(text=result) def validate_credentials(self, credentials: dict[str, Any], parameters: dict[str, Any]) -> None: diff --git a/api/core/tools/utils/web_reader_tool.py b/api/core/tools/utils/web_reader_tool.py index a461328ae6..150941924d 100644 --- a/api/core/tools/utils/web_reader_tool.py +++ b/api/core/tools/utils/web_reader_tool.py @@ -189,8 +189,8 @@ def extract_text_blocks_as_plain_text(paragraph_html): def plain_text_leaf_node(element): - # Extract all text, stripped of any child HTML elements and normalise it - plain_text = normalise_text(element.get_text()) + # Extract all text, stripped of any child HTML elements and normalize it + plain_text = normalize_text(element.get_text()) if plain_text != "" and element.name == "li": plain_text = "* {}, ".format(plain_text) if plain_text == "": @@ -231,8 +231,8 @@ def plain_element(element, content_digests, node_indexes): # For leaf node elements, extract the text content, discarding any HTML tags # 1. Get element contents as text plain_text = element.get_text() - # 2. Normalise the extracted text string to a canonical representation - plain_text = normalise_text(plain_text) + # 2. Normalize the extracted text string to a canonical representation + plain_text = normalize_text(plain_text) # 3. Update element content to be plain text element.string = plain_text elif is_text(element): @@ -243,7 +243,7 @@ def plain_element(element, content_digests, node_indexes): element = type(element)("") else: plain_text = element.string - plain_text = normalise_text(plain_text) + plain_text = normalize_text(plain_text) element = type(element)(plain_text) else: # If not a leaf node or leaf type call recursively on child nodes, replacing @@ -267,12 +267,12 @@ def add_node_indexes(element, node_index="0"): return element -def normalise_text(text): - """Normalise unicode and whitespace.""" - # Normalise unicode first to try and standardise whitespace characters as much as possible before normalising them +def normalize_text(text): + """Normalize unicode and whitespace.""" + # Normalize unicode first to try and standardize whitespace characters as much as possible before normalizing them text = strip_control_characters(text) - text = normalise_unicode(text) - text = normalise_whitespace(text) + text = normalize_unicode(text) + text = normalize_whitespace(text) return text @@ -291,14 +291,14 @@ def strip_control_characters(text): return "".join(["" if (unicodedata.category(char) in control_chars) and (char not in retained_chars) else char for char in text]) -def normalise_unicode(text): - """Normalise unicode such that things that are visually equivalent map to the same unicode string where possible.""" +def normalize_unicode(text): + """Normalize unicode such that things that are visually equivalent map to the same unicode string where possible.""" normal_form = "NFKC" text = unicodedata.normalize(normal_form, text) return text -def normalise_whitespace(text): +def normalize_whitespace(text): """Replace runs of whitespace characters with a single space as this is what happens when HTML text is displayed.""" text = regex.sub(r"\s+", " ", text) # Remove leading and trailing whitespace diff --git a/api/core/workflow/entities/variable_pool.py b/api/core/workflow/entities/variable_pool.py index 8120b2ac78..27d0b672f6 100644 --- a/api/core/workflow/entities/variable_pool.py +++ b/api/core/workflow/entities/variable_pool.py @@ -31,7 +31,7 @@ class VariablePool: # 'files': [] # } - # Varaible dictionary is a dictionary for looking up variables by their selector. + # Variable dictionary is a dictionary for looking up variables by their selector. # The first element of the selector is the node id, it's the first-level key in the dictionary. # Other elements of the selector are the keys in the second-level dictionary. To get the key, we hash the # elements of the selector except the first one. diff --git a/api/core/workflow/nodes/http_request/http_request_node.py b/api/core/workflow/nodes/http_request/http_request_node.py index f6c8ea3c83..037a7a1848 100644 --- a/api/core/workflow/nodes/http_request/http_request_node.py +++ b/api/core/workflow/nodes/http_request/http_request_node.py @@ -19,9 +19,9 @@ from core.workflow.nodes.http_request.http_executor import HttpExecutor, HttpExe from models.workflow import WorkflowNodeExecutionStatus HTTP_REQUEST_DEFAULT_TIMEOUT = HttpRequestNodeTimeout( - connect=min(10, dify_config.HTTP_REQUEST_MAX_CONNECT_TIMEOUT), - read=min(60, dify_config.HTTP_REQUEST_MAX_READ_TIMEOUT), - write=min(20, dify_config.HTTP_REQUEST_MAX_WRITE_TIMEOUT), + connect=dify_config.HTTP_REQUEST_MAX_CONNECT_TIMEOUT, + read=dify_config.HTTP_REQUEST_MAX_READ_TIMEOUT, + write=dify_config.HTTP_REQUEST_MAX_WRITE_TIMEOUT, ) @@ -96,12 +96,9 @@ class HttpRequestNode(BaseNode): if timeout is None: return HTTP_REQUEST_DEFAULT_TIMEOUT - timeout.connect = min(timeout.connect or HTTP_REQUEST_DEFAULT_TIMEOUT.connect, - dify_config.HTTP_REQUEST_MAX_CONNECT_TIMEOUT) - timeout.read = min(timeout.read or HTTP_REQUEST_DEFAULT_TIMEOUT.read, - dify_config.HTTP_REQUEST_MAX_READ_TIMEOUT) - timeout.write = min(timeout.write or HTTP_REQUEST_DEFAULT_TIMEOUT.write, - dify_config.HTTP_REQUEST_MAX_WRITE_TIMEOUT) + timeout.connect = timeout.connect or HTTP_REQUEST_DEFAULT_TIMEOUT.connect + timeout.read = timeout.read or HTTP_REQUEST_DEFAULT_TIMEOUT.read + timeout.write = timeout.write or HTTP_REQUEST_DEFAULT_TIMEOUT.write return timeout @classmethod diff --git a/api/core/workflow/nodes/if_else/entities.py b/api/core/workflow/nodes/if_else/entities.py index bc6dce0d3b..7eb69b80df 100644 --- a/api/core/workflow/nodes/if_else/entities.py +++ b/api/core/workflow/nodes/if_else/entities.py @@ -12,7 +12,7 @@ class Condition(BaseModel): variable_selector: list[str] comparison_operator: Literal[ # for string or array - "contains", "not contains", "start with", "end with", "is", "is not", "empty", "not empty", + "contains", "not contains", "start with", "end with", "is", "is not", "empty", "not empty", "regex match", # for number "=", "≠", ">", "<", "≥", "≤", "null", "not null" ] diff --git a/api/core/workflow/nodes/if_else/if_else_node.py b/api/core/workflow/nodes/if_else/if_else_node.py index c6d235627f..2b253764b7 100644 --- a/api/core/workflow/nodes/if_else/if_else_node.py +++ b/api/core/workflow/nodes/if_else/if_else_node.py @@ -1,3 +1,4 @@ +import re from collections.abc import Sequence from typing import Optional, cast @@ -136,6 +137,8 @@ class IfElseNode(BaseNode): return self._assert_null(actual_value) elif comparison_operator == "not null": return self._assert_not_null(actual_value) + elif comparison_operator == "regex match": + return self._assert_regex_match(actual_value, expected_value) else: raise ValueError(f"Invalid comparison operator: {comparison_operator}") @@ -285,6 +288,16 @@ class IfElseNode(BaseNode): return True return False + def _assert_regex_match(self, actual_value: Optional[str], expected_value: str) -> bool: + """ + Assert empty + :param actual_value: actual value + :return: + """ + if actual_value is None: + return False + return re.search(expected_value, actual_value) is not None + def _assert_not_empty(self, actual_value: Optional[str]) -> bool: """ Assert not empty 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 01bf6e16e6..6c052c0d6b 100644 --- a/api/core/workflow/nodes/knowledge_retrieval/knowledge_retrieval_node.py +++ b/api/core/workflow/nodes/knowledge_retrieval/knowledge_retrieval_node.py @@ -11,7 +11,7 @@ from core.model_manager import ModelInstance, ModelManager from core.model_runtime.entities.model_entities import ModelFeature, ModelType from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel from core.rag.retrieval.dataset_retrieval import DatasetRetrieval -from core.rag.retrieval.retrival_methods import RetrievalMethod +from core.rag.retrieval.retrieval_methods import RetrievalMethod from core.workflow.entities.base_node_data_entities import BaseNodeData from core.workflow.entities.node_entities import NodeRunResult, NodeType from core.workflow.entities.variable_pool import VariablePool @@ -173,9 +173,13 @@ class KnowledgeRetrievalNode(BaseNode): context_list = [] if all_documents: document_score_list = {} + page_number_list = {} for item in all_documents: if item.metadata.get('score'): document_score_list[item.metadata['doc_id']] = item.metadata['score'] + # both 'page' and 'score' are metadata fields + if item.metadata.get('page'): + page_number_list[item.metadata['doc_id']] = item.metadata['page'] index_node_ids = [document.metadata['doc_id'] for document in all_documents] segments = DocumentSegment.query.filter( @@ -199,9 +203,9 @@ class KnowledgeRetrievalNode(BaseNode): Document.enabled == True, Document.archived == False, ).first() + resource_number = 1 if dataset and document: - source = { 'metadata': { '_source': 'knowledge', @@ -211,6 +215,7 @@ class KnowledgeRetrievalNode(BaseNode): 'document_id': document.id, 'document_name': document.name, 'document_data_source_type': document.data_source_type, + 'page': page_number_list.get(segment.index_node_id, None), 'segment_id': segment.id, 'retriever_from': 'workflow', 'score': document_score_list.get(segment.index_node_id, None), diff --git a/api/core/workflow/nodes/llm/llm_node.py b/api/core/workflow/nodes/llm/llm_node.py index eb8921b526..737b1af143 100644 --- a/api/core/workflow/nodes/llm/llm_node.py +++ b/api/core/workflow/nodes/llm/llm_node.py @@ -109,7 +109,9 @@ class LLMNode(BaseNode): 'prompts': PromptMessageUtil.prompt_messages_to_prompt_for_saving( model_mode=model_config.mode, prompt_messages=prompt_messages - ) + ), + 'model_provider': model_config.provider, + 'model_name': model_config.model, } # handle invoke result @@ -400,6 +402,7 @@ class LLMNode(BaseNode): if ('metadata' in context_dict and '_source' in context_dict['metadata'] and context_dict['metadata']['_source'] == 'knowledge'): metadata = context_dict.get('metadata', {}) + source = { 'position': metadata.get('position'), 'dataset_id': metadata.get('dataset_id'), @@ -415,6 +418,7 @@ class LLMNode(BaseNode): 'segment_position': metadata.get('segment_position'), 'index_node_hash': metadata.get('segment_index_node_hash'), 'content': context_dict.get('content'), + 'page': metadata.get('page'), } return source diff --git a/api/events/event_handlers/__init__.py b/api/events/event_handlers/__init__.py index 7ee7146d09..1d6ad35333 100644 --- a/api/events/event_handlers/__init__.py +++ b/api/events/event_handlers/__init__.py @@ -3,8 +3,8 @@ from .clean_when_document_deleted import handle from .create_document_index import handle from .create_installed_app_when_app_created import handle from .create_site_record_when_app_created import handle -from .deduct_quota_when_messaeg_created import handle +from .deduct_quota_when_message_created import handle from .delete_tool_parameters_cache_when_sync_draft_workflow import handle from .update_app_dataset_join_when_app_model_config_updated import handle from .update_app_dataset_join_when_app_published_workflow_updated import handle -from .update_provider_last_used_at_when_messaeg_created import handle +from .update_provider_last_used_at_when_message_created import handle diff --git a/api/events/event_handlers/deduct_quota_when_messaeg_created.py b/api/events/event_handlers/deduct_quota_when_message_created.py similarity index 100% rename from api/events/event_handlers/deduct_quota_when_messaeg_created.py rename to api/events/event_handlers/deduct_quota_when_message_created.py diff --git a/api/events/event_handlers/update_provider_last_used_at_when_messaeg_created.py b/api/events/event_handlers/update_provider_last_used_at_when_message_created.py similarity index 100% rename from api/events/event_handlers/update_provider_last_used_at_when_messaeg_created.py rename to api/events/event_handlers/update_provider_last_used_at_when_message_created.py diff --git a/api/extensions/ext_celery.py b/api/extensions/ext_celery.py index f5ec7c1759..0ff9f90847 100644 --- a/api/extensions/ext_celery.py +++ b/api/extensions/ext_celery.py @@ -10,11 +10,21 @@ def init_app(app: Flask) -> Celery: with app.app_context(): return self.run(*args, **kwargs) + broker_transport_options = {} + + if app.config.get("CELERY_USE_SENTINEL"): + broker_transport_options = { + "master_name": app.config.get("CELERY_SENTINEL_MASTER_NAME"), + "sentinel_kwargs": { + "socket_timeout": app.config.get("CELERY_SENTINEL_SOCKET_TIMEOUT", 0.1), + }, + } + celery_app = Celery( app.name, task_cls=FlaskTask, - broker=app.config["CELERY_BROKER_URL"], - backend=app.config["CELERY_BACKEND"], + broker=app.config.get("CELERY_BROKER_URL"), + backend=app.config.get("CELERY_BACKEND"), task_ignore_result=True, ) @@ -27,11 +37,12 @@ def init_app(app: Flask) -> Celery: } celery_app.conf.update( - result_backend=app.config["CELERY_RESULT_BACKEND"], + result_backend=app.config.get("CELERY_RESULT_BACKEND"), + broker_transport_options=broker_transport_options, broker_connection_retry_on_startup=True, ) - if app.config["BROKER_USE_SSL"]: + if app.config.get("BROKER_USE_SSL"): celery_app.conf.update( broker_use_ssl=ssl_options, # Add the SSL options to the broker configuration ) @@ -43,7 +54,7 @@ def init_app(app: Flask) -> Celery: "schedule.clean_embedding_cache_task", "schedule.clean_unused_datasets_task", ] - day = app.config["CELERY_BEAT_SCHEDULER_TIME"] + day = app.config.get("CELERY_BEAT_SCHEDULER_TIME") beat_schedule = { "clean_embedding_cache_task": { "task": "schedule.clean_embedding_cache_task.clean_embedding_cache_task", diff --git a/api/extensions/ext_redis.py b/api/extensions/ext_redis.py index d5fb162fd8..054769e7ff 100644 --- a/api/extensions/ext_redis.py +++ b/api/extensions/ext_redis.py @@ -1,26 +1,83 @@ import redis from redis.connection import Connection, SSLConnection +from redis.sentinel import Sentinel -redis_client = redis.Redis() + +class RedisClientWrapper(redis.Redis): + """ + A wrapper class for the Redis client that addresses the issue where the global + `redis_client` variable cannot be updated when a new Redis instance is returned + by Sentinel. + + This class allows for deferred initialization of the Redis client, enabling the + client to be re-initialized with a new instance when necessary. This is particularly + useful in scenarios where the Redis instance may change dynamically, such as during + a failover in a Sentinel-managed Redis setup. + + Attributes: + _client (redis.Redis): The actual Redis client instance. It remains None until + initialized with the `initialize` method. + + Methods: + initialize(client): Initializes the Redis client if it hasn't been initialized already. + __getattr__(item): Delegates attribute access to the Redis client, raising an error + if the client is not initialized. + """ + + def __init__(self): + self._client = None + + def initialize(self, client): + if self._client is None: + self._client = client + + def __getattr__(self, item): + if self._client is None: + raise RuntimeError("Redis client is not initialized. Call init_app first.") + return getattr(self._client, item) + + +redis_client = RedisClientWrapper() def init_app(app): + global redis_client connection_class = Connection if app.config.get("REDIS_USE_SSL"): connection_class = SSLConnection - redis_client.connection_pool = redis.ConnectionPool( - **{ - "host": app.config.get("REDIS_HOST"), - "port": app.config.get("REDIS_PORT"), - "username": app.config.get("REDIS_USERNAME"), - "password": app.config.get("REDIS_PASSWORD"), - "db": app.config.get("REDIS_DB"), - "encoding": "utf-8", - "encoding_errors": "strict", - "decode_responses": False, - }, - connection_class=connection_class, - ) + redis_params = { + "username": app.config.get("REDIS_USERNAME"), + "password": app.config.get("REDIS_PASSWORD"), + "db": app.config.get("REDIS_DB"), + "encoding": "utf-8", + "encoding_errors": "strict", + "decode_responses": False, + } + + if app.config.get("REDIS_USE_SENTINEL"): + sentinel_hosts = [ + (node.split(":")[0], int(node.split(":")[1])) for node in app.config.get("REDIS_SENTINELS").split(",") + ] + sentinel = Sentinel( + sentinel_hosts, + sentinel_kwargs={ + "socket_timeout": app.config.get("REDIS_SENTINEL_SOCKET_TIMEOUT", 0.1), + "username": app.config.get("REDIS_SENTINEL_USERNAME"), + "password": app.config.get("REDIS_SENTINEL_PASSWORD"), + }, + ) + master = sentinel.master_for(app.config.get("REDIS_SENTINEL_SERVICE_NAME"), **redis_params) + redis_client.initialize(master) + else: + redis_params.update( + { + "host": app.config.get("REDIS_HOST"), + "port": app.config.get("REDIS_PORT"), + "connection_class": connection_class, + } + ) + pool = redis.ConnectionPool(**redis_params) + redis_client.initialize(redis.Redis(connection_pool=pool)) app.extensions["redis"] = redis_client diff --git a/api/extensions/ext_storage.py b/api/extensions/ext_storage.py index e6c4352577..5ce18b7292 100644 --- a/api/extensions/ext_storage.py +++ b/api/extensions/ext_storage.py @@ -6,10 +6,12 @@ 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 class Storage: @@ -30,6 +32,10 @@ class Storage: 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) diff --git a/api/extensions/storage/aliyun_storage.py b/api/extensions/storage/aliyun_storage.py index b962cedc55..bee237fc17 100644 --- a/api/extensions/storage/aliyun_storage.py +++ b/api/extensions/storage/aliyun_storage.py @@ -15,6 +15,7 @@ class AliyunStorage(BaseStorage): app_config = self.app.config self.bucket_name = app_config.get("ALIYUN_OSS_BUCKET_NAME") + self.folder = app.config.get("ALIYUN_OSS_PATH") oss_auth_method = aliyun_s3.Auth region = None if app_config.get("ALIYUN_OSS_AUTH_VERSION") == "v4": @@ -30,15 +31,29 @@ class AliyunStorage(BaseStorage): ) def save(self, filename, data): + if not self.folder or self.folder.endswith("/"): + filename = self.folder + filename + else: + filename = self.folder + "/" + filename self.client.put_object(filename, data) def load_once(self, filename: str) -> bytes: + if not self.folder or self.folder.endswith("/"): + filename = self.folder + filename + else: + filename = self.folder + "/" + filename + with closing(self.client.get_object(filename)) as obj: data = obj.read() return data def load_stream(self, filename: str) -> Generator: def generate(filename: str = filename) -> Generator: + if not self.folder or self.folder.endswith("/"): + filename = self.folder + filename + else: + filename = self.folder + "/" + filename + with closing(self.client.get_object(filename)) as obj: while chunk := obj.read(4096): yield chunk @@ -46,10 +61,24 @@ class AliyunStorage(BaseStorage): return generate() def download(self, filename, target_filepath): + if not self.folder or self.folder.endswith("/"): + filename = self.folder + filename + else: + filename = self.folder + "/" + filename + self.client.get_object_to_file(filename, target_filepath) def exists(self, filename): + if not self.folder or self.folder.endswith("/"): + filename = self.folder + filename + else: + filename = self.folder + "/" + filename + return self.client.object_exists(filename) def delete(self, filename): + if not self.folder or self.folder.endswith("/"): + filename = self.folder + filename + else: + filename = self.folder + "/" + filename self.client.delete_object(filename) diff --git a/api/extensions/storage/huawei_storage.py b/api/extensions/storage/huawei_storage.py new file mode 100644 index 0000000000..269a008fba --- /dev/null +++ b/api/extensions/storage/huawei_storage.py @@ -0,0 +1,53 @@ +from collections.abc import Generator + +from flask import Flask +from obs import ObsClient + +from extensions.storage.base_storage import BaseStorage + + +class HuaweiStorage(BaseStorage): + """Implementation for huawei obs storage.""" + + def __init__(self, app: Flask): + super().__init__(app) + app_config = self.app.config + self.bucket_name = app_config.get("HUAWEI_OBS_BUCKET_NAME") + self.client = ObsClient( + access_key_id=app_config.get("HUAWEI_OBS_ACCESS_KEY"), + secret_access_key=app_config.get("HUAWEI_OBS_SECRET_KEY"), + server=app_config.get("HUAWEI_OBS_SERVER"), + ) + + def save(self, filename, data): + self.client.putObject(bucketName=self.bucket_name, objectKey=filename, content=data) + + def load_once(self, filename: str) -> bytes: + data = self.client.getObject(bucketName=self.bucket_name, objectKey=filename)["body"].response.read() + return data + + 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) + + return generate() + + def download(self, filename, target_filepath): + self.client.getObject(bucketName=self.bucket_name, objectKey=filename, downloadPath=target_filepath) + + def exists(self, filename): + res = self._get_meta(filename) + if res is None: + return False + return True + + def delete(self, filename): + self.client.deleteObject(bucketName=self.bucket_name, objectKey=filename) + + def _get_meta(self, filename): + res = self.client.getObjectMetadata(bucketName=self.bucket_name, objectKey=filename) + if res.status < 300: + return res + else: + return None diff --git a/api/extensions/storage/volcengine_storage.py b/api/extensions/storage/volcengine_storage.py new file mode 100644 index 0000000000..f74ad2ee6d --- /dev/null +++ b/api/extensions/storage/volcengine_storage.py @@ -0,0 +1,48 @@ +from collections.abc import Generator + +import tos +from flask import Flask + +from extensions.storage.base_storage import BaseStorage + + +class VolcengineStorage(BaseStorage): + """Implementation for Volcengine TOS storage.""" + + def __init__(self, app: Flask): + super().__init__(app) + app_config = self.app.config + self.bucket_name = app_config.get("VOLCENGINE_TOS_BUCKET_NAME") + self.client = tos.TosClientV2( + ak=app_config.get("VOLCENGINE_TOS_ACCESS_KEY"), + sk=app_config.get("VOLCENGINE_TOS_SECRET_KEY"), + endpoint=app_config.get("VOLCENGINE_TOS_ENDPOINT"), + region=app_config.get("VOLCENGINE_TOS_REGION"), + ) + + def save(self, filename, data): + self.client.put_object(bucket=self.bucket_name, key=filename, content=data) + + def load_once(self, filename: str) -> bytes: + data = self.client.get_object(bucket=self.bucket_name, key=filename).read() + return data + + def load_stream(self, filename: str) -> Generator: + def generate(filename: str = filename) -> Generator: + response = self.client.get_object(bucket=self.bucket_name, key=filename) + while chunk := response.read(4096): + yield chunk + + return generate() + + def download(self, filename, target_filepath): + self.client.get_object_to_file(bucket=self.bucket_name, key=filename, file_path=target_filepath) + + def exists(self, filename): + res = self.client.head_object(bucket=self.bucket_name, key=filename) + if res.status_code != 200: + return False + return True + + def delete(self, filename): + self.client.delete_object(bucket=self.bucket_name, key=filename) diff --git a/api/fields/app_fields.py b/api/fields/app_fields.py index 45fcb128ce..aa353a3cc1 100644 --- a/api/fields/app_fields.py +++ b/api/fields/app_fields.py @@ -58,6 +58,7 @@ app_detail_fields = { "model_config": fields.Nested(model_config_fields, attribute="app_model_config", allow_null=True), "workflow": fields.Nested(workflow_partial_fields, allow_null=True), "tracing": fields.Raw, + "use_icon_as_answer_icon": fields.Boolean, "created_by": fields.String, "created_at": TimestampField, "updated_by": fields.String, @@ -91,6 +92,7 @@ app_partial_fields = { "icon_url": AppIconUrlField, "model_config": fields.Nested(model_config_partial_fields, attribute="app_model_config", allow_null=True), "workflow": fields.Nested(workflow_partial_fields, allow_null=True), + "use_icon_as_answer_icon": fields.Boolean, "created_by": fields.String, "created_at": TimestampField, "updated_by": fields.String, @@ -140,6 +142,7 @@ site_fields = { "prompt_public": fields.Boolean, "app_base_url": fields.String, "show_workflow_steps": fields.Boolean, + "use_icon_as_answer_icon": fields.Boolean, "created_by": fields.String, "created_at": TimestampField, "updated_by": fields.String, @@ -161,6 +164,7 @@ app_detail_fields_with_site = { "workflow": fields.Nested(workflow_partial_fields, allow_null=True), "site": fields.Nested(site_fields), "api_base_url": fields.String, + "use_icon_as_answer_icon": fields.Boolean, "created_by": fields.String, "created_at": TimestampField, "updated_by": fields.String, @@ -184,4 +188,5 @@ app_site_fields = { "customize_token_strategy": fields.String, "prompt_public": fields.Boolean, "show_workflow_steps": fields.Boolean, + "use_icon_as_answer_icon": fields.Boolean, } diff --git a/api/fields/installed_app_fields.py b/api/fields/installed_app_fields.py index 9afc1b1a4a..e0b3e340f6 100644 --- a/api/fields/installed_app_fields.py +++ b/api/fields/installed_app_fields.py @@ -10,6 +10,7 @@ app_fields = { "icon": fields.String, "icon_background": fields.String, "icon_url": AppIconUrlField, + "use_icon_as_answer_icon": fields.Boolean, } installed_app_fields = { diff --git a/api/migrations/versions/2024_09_01_1255-030f4915f36a_add_use_icon_as_answer_icon_fields_for_.py b/api/migrations/versions/2024_09_01_1255-030f4915f36a_add_use_icon_as_answer_icon_fields_for_.py new file mode 100644 index 0000000000..4406d51ed0 --- /dev/null +++ b/api/migrations/versions/2024_09_01_1255-030f4915f36a_add_use_icon_as_answer_icon_fields_for_.py @@ -0,0 +1,45 @@ +"""add use_icon_as_answer_icon fields for app and site + +Revision ID: 030f4915f36a +Revises: d0187d6a88dd +Create Date: 2024-09-01 12:55:45.129687 + +""" + +import sqlalchemy as sa +from alembic import op + +import models as models + +# revision identifiers, used by Alembic. +revision = "030f4915f36a" +down_revision = "d0187d6a88dd" +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table("apps", schema=None) as batch_op: + batch_op.add_column( + sa.Column("use_icon_as_answer_icon", sa.Boolean(), server_default=sa.text("false"), nullable=False) + ) + + with op.batch_alter_table("sites", schema=None) as batch_op: + batch_op.add_column( + sa.Column("use_icon_as_answer_icon", sa.Boolean(), server_default=sa.text("false"), nullable=False) + ) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + + with op.batch_alter_table("sites", schema=None) as batch_op: + batch_op.drop_column("use_icon_as_answer_icon") + + with op.batch_alter_table("apps", schema=None) as batch_op: + batch_op.drop_column("use_icon_as_answer_icon") + + # ### end Alembic commands ### diff --git a/api/models/dataset.py b/api/models/dataset.py index 203031c7b9..bf3f12a2c5 100644 --- a/api/models/dataset.py +++ b/api/models/dataset.py @@ -14,7 +14,7 @@ from sqlalchemy import func from sqlalchemy.dialects.postgresql import JSONB from configs import dify_config -from core.rag.retrieval.retrival_methods import RetrievalMethod +from core.rag.retrieval.retrieval_methods import RetrievalMethod from extensions.ext_database import db from extensions.ext_storage import storage diff --git a/api/models/model.py b/api/models/model.py index 74ba4a7fd5..3eec2539d3 100644 --- a/api/models/model.py +++ b/api/models/model.py @@ -87,6 +87,7 @@ class App(db.Model): created_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) updated_by = db.Column(StringUUID, nullable=True) updated_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) + use_icon_as_answer_icon = db.Column(db.Boolean, nullable=False, server_default=db.text("false")) @property def desc_or_prompt(self): @@ -1118,6 +1119,7 @@ class Site(db.Model): copyright = db.Column(db.String(255)) privacy_policy = db.Column(db.String(255)) show_workflow_steps = db.Column(db.Boolean, nullable=False, server_default=db.text('true')) + use_icon_as_answer_icon = db.Column(db.Boolean, nullable=False, server_default=db.text("false")) custom_disclaimer = db.Column(db.String(255), nullable=True) customize_domain = db.Column(db.String(255)) customize_token_strategy = db.Column(db.String(255), nullable=False) diff --git a/api/poetry.lock b/api/poetry.lock index 7d26dbdc57..103423e5c7 100644 --- a/api/poetry.lock +++ b/api/poetry.lock @@ -364,27 +364,27 @@ alibabacloud-tea = ">=0.0.1" [[package]] name = "aliyun-python-sdk-core" -version = "2.15.1" +version = "2.15.2" description = "The core module of Aliyun Python SDK." optional = false python-versions = "*" files = [ - {file = "aliyun-python-sdk-core-2.15.1.tar.gz", hash = "sha256:518550d07f537cd3afac3b6c93b5c997ce3440e4d0c054e3acbdaa8261e90adf"}, + {file = "aliyun-python-sdk-core-2.15.2.tar.gz", hash = "sha256:54f66a53e193c61c5e16ea4505a0cab43543f8ad2ef22833f69c4d5e5151c17d"}, ] [package.dependencies] -cryptography = ">=2.6.0" +cryptography = ">=3.0.0" jmespath = ">=0.9.3,<1.0.0" [[package]] name = "aliyun-python-sdk-kms" -version = "2.16.4" +version = "2.16.5" description = "The kms module of Aliyun Python sdk." optional = false python-versions = "*" files = [ - {file = "aliyun-python-sdk-kms-2.16.4.tar.gz", hash = "sha256:0d5bb165c07b6a972939753a128507393f48011792ee0ec4f59b6021eabd9752"}, - {file = "aliyun_python_sdk_kms-2.16.4-py2.py3-none-any.whl", hash = "sha256:6d412663ef8c35dc3bb42be6a3ee76a9bc07acdadca6dd26815131062bedf4c5"}, + {file = "aliyun-python-sdk-kms-2.16.5.tar.gz", hash = "sha256:f328a8a19d83ecbb965ffce0ec1e9930755216d104638cd95ecd362753b813b3"}, + {file = "aliyun_python_sdk_kms-2.16.5-py2.py3-none-any.whl", hash = "sha256:24b6cdc4fd161d2942619479c8d050c63ea9cd22b044fe33b60bbb60153786f0"}, ] [package.dependencies] @@ -520,22 +520,22 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "23.2.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.7" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, + {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, ] [package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] +tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] [[package]] name = "authlib" @@ -553,13 +553,13 @@ cryptography = "*" [[package]] name = "azure-ai-inference" -version = "1.0.0b3" +version = "1.0.0b4" description = "Microsoft Azure Ai Inference Client Library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "azure-ai-inference-1.0.0b3.tar.gz", hash = "sha256:1e99dc74c3b335a457500311bbbadb348f54dc4c12252a93cb8ab78d6d217ff0"}, - {file = "azure_ai_inference-1.0.0b3-py3-none-any.whl", hash = "sha256:6734ca7334c809a170beb767f1f1455724ab3f006cb60045e42a833c0e764403"}, + {file = "azure-ai-inference-1.0.0b4.tar.gz", hash = "sha256:5464404bef337338d4af6eefde3af903400ddb8e5c9e6820f902303542fa0f72"}, + {file = "azure_ai_inference-1.0.0b4-py3-none-any.whl", hash = "sha256:e2c949f91845a8cd96cb9a61ffd432b5b0f4ce236b9be8c29d10f38e0a327412"}, ] [package.dependencies] @@ -1140,89 +1140,89 @@ zstd = ["zstandard (==0.22.0)"] [[package]] name = "certifi" -version = "2024.7.4" +version = "2024.8.30" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, ] [[package]] name = "cffi" -version = "1.17.0" +version = "1.17.1" description = "Foreign Function Interface for Python calling C code." optional = false python-versions = ">=3.8" files = [ - {file = "cffi-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f9338cc05451f1942d0d8203ec2c346c830f8e86469903d5126c1f0a13a2bcbb"}, - {file = "cffi-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0ce71725cacc9ebf839630772b07eeec220cbb5f03be1399e0457a1464f8e1a"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c815270206f983309915a6844fe994b2fa47e5d05c4c4cef267c3b30e34dbe42"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6bdcd415ba87846fd317bee0774e412e8792832e7805938987e4ede1d13046d"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a98748ed1a1df4ee1d6f927e151ed6c1a09d5ec21684de879c7ea6aa96f58f2"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0a048d4f6630113e54bb4b77e315e1ba32a5a31512c31a273807d0027a7e69ab"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24aa705a5f5bd3a8bcfa4d123f03413de5d86e497435693b638cbffb7d5d8a1b"}, - {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:856bf0924d24e7f93b8aee12a3a1095c34085600aa805693fb7f5d1962393206"}, - {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:4304d4416ff032ed50ad6bb87416d802e67139e31c0bde4628f36a47a3164bfa"}, - {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:331ad15c39c9fe9186ceaf87203a9ecf5ae0ba2538c9e898e3a6967e8ad3db6f"}, - {file = "cffi-1.17.0-cp310-cp310-win32.whl", hash = "sha256:669b29a9eca6146465cc574659058ed949748f0809a2582d1f1a324eb91054dc"}, - {file = "cffi-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:48b389b1fd5144603d61d752afd7167dfd205973a43151ae5045b35793232aa2"}, - {file = "cffi-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5d97162c196ce54af6700949ddf9409e9833ef1003b4741c2b39ef46f1d9720"}, - {file = "cffi-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ba5c243f4004c750836f81606a9fcb7841f8874ad8f3bf204ff5e56332b72b9"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb9333f58fc3a2296fb1d54576138d4cf5d496a2cc118422bd77835e6ae0b9cb"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:435a22d00ec7d7ea533db494da8581b05977f9c37338c80bc86314bec2619424"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1df34588123fcc88c872f5acb6f74ae59e9d182a2707097f9e28275ec26a12d"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df8bb0010fdd0a743b7542589223a2816bdde4d94bb5ad67884348fa2c1c67e8"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8b5b9712783415695663bd463990e2f00c6750562e6ad1d28e072a611c5f2a6"}, - {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ffef8fd58a36fb5f1196919638f73dd3ae0db1a878982b27a9a5a176ede4ba91"}, - {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e67d26532bfd8b7f7c05d5a766d6f437b362c1bf203a3a5ce3593a645e870b8"}, - {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45f7cd36186db767d803b1473b3c659d57a23b5fa491ad83c6d40f2af58e4dbb"}, - {file = "cffi-1.17.0-cp311-cp311-win32.whl", hash = "sha256:a9015f5b8af1bb6837a3fcb0cdf3b874fe3385ff6274e8b7925d81ccaec3c5c9"}, - {file = "cffi-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:b50aaac7d05c2c26dfd50c3321199f019ba76bb650e346a6ef3616306eed67b0"}, - {file = "cffi-1.17.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aec510255ce690d240f7cb23d7114f6b351c733a74c279a84def763660a2c3bc"}, - {file = "cffi-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2770bb0d5e3cc0e31e7318db06efcbcdb7b31bcb1a70086d3177692a02256f59"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db9a30ec064129d605d0f1aedc93e00894b9334ec74ba9c6bdd08147434b33eb"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a47eef975d2b8b721775a0fa286f50eab535b9d56c70a6e62842134cf7841195"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3e0992f23bbb0be00a921eae5363329253c3b86287db27092461c887b791e5e"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6107e445faf057c118d5050560695e46d272e5301feffda3c41849641222a828"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb862356ee9391dc5a0b3cbc00f416b48c1b9a52d252d898e5b7696a5f9fe150"}, - {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c1c13185b90bbd3f8b5963cd8ce7ad4ff441924c31e23c975cb150e27c2bf67a"}, - {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:17c6d6d3260c7f2d94f657e6872591fe8733872a86ed1345bda872cfc8c74885"}, - {file = "cffi-1.17.0-cp312-cp312-win32.whl", hash = "sha256:c3b8bd3133cd50f6b637bb4322822c94c5ce4bf0d724ed5ae70afce62187c492"}, - {file = "cffi-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:dca802c8db0720ce1c49cce1149ff7b06e91ba15fa84b1d59144fef1a1bc7ac2"}, - {file = "cffi-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6ce01337d23884b21c03869d2f68c5523d43174d4fc405490eb0091057943118"}, - {file = "cffi-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cab2eba3830bf4f6d91e2d6718e0e1c14a2f5ad1af68a89d24ace0c6b17cced7"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:14b9cbc8f7ac98a739558eb86fabc283d4d564dafed50216e7f7ee62d0d25377"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b00e7bcd71caa0282cbe3c90966f738e2db91e64092a877c3ff7f19a1628fdcb"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:41f4915e09218744d8bae14759f983e466ab69b178de38066f7579892ff2a555"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4760a68cab57bfaa628938e9c2971137e05ce48e762a9cb53b76c9b569f1204"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:011aff3524d578a9412c8b3cfaa50f2c0bd78e03eb7af7aa5e0df59b158efb2f"}, - {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:a003ac9edc22d99ae1286b0875c460351f4e101f8c9d9d2576e78d7e048f64e0"}, - {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ef9528915df81b8f4c7612b19b8628214c65c9b7f74db2e34a646a0a2a0da2d4"}, - {file = "cffi-1.17.0-cp313-cp313-win32.whl", hash = "sha256:70d2aa9fb00cf52034feac4b913181a6e10356019b18ef89bc7c12a283bf5f5a"}, - {file = "cffi-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:b7b6ea9e36d32582cda3465f54c4b454f62f23cb083ebc7a94e2ca6ef011c3a7"}, - {file = "cffi-1.17.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:964823b2fc77b55355999ade496c54dde161c621cb1f6eac61dc30ed1b63cd4c"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:516a405f174fd3b88829eabfe4bb296ac602d6a0f68e0d64d5ac9456194a5b7e"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dec6b307ce928e8e112a6bb9921a1cb00a0e14979bf28b98e084a4b8a742bd9b"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4094c7b464cf0a858e75cd14b03509e84789abf7b79f8537e6a72152109c76e"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2404f3de742f47cb62d023f0ba7c5a916c9c653d5b368cc966382ae4e57da401"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aa9d43b02a0c681f0bfbc12d476d47b2b2b6a3f9287f11ee42989a268a1833c"}, - {file = "cffi-1.17.0-cp38-cp38-win32.whl", hash = "sha256:0bb15e7acf8ab35ca8b24b90af52c8b391690ef5c4aec3d31f38f0d37d2cc499"}, - {file = "cffi-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:93a7350f6706b31f457c1457d3a3259ff9071a66f312ae64dc024f049055f72c"}, - {file = "cffi-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a2ddbac59dc3716bc79f27906c010406155031a1c801410f1bafff17ea304d2"}, - {file = "cffi-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6327b572f5770293fc062a7ec04160e89741e8552bf1c358d1a23eba68166759"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbc183e7bef690c9abe5ea67b7b60fdbca81aa8da43468287dae7b5c046107d4"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bdc0f1f610d067c70aa3737ed06e2726fd9d6f7bfee4a351f4c40b6831f4e82"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d872186c1617d143969defeadac5a904e6e374183e07977eedef9c07c8953bf"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d46ee4764b88b91f16661a8befc6bfb24806d885e27436fdc292ed7e6f6d058"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f76a90c345796c01d85e6332e81cab6d70de83b829cf1d9762d0a3da59c7932"}, - {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0e60821d312f99d3e1569202518dddf10ae547e799d75aef3bca3a2d9e8ee693"}, - {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:eb09b82377233b902d4c3fbeeb7ad731cdab579c6c6fda1f763cd779139e47c3"}, - {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:24658baf6224d8f280e827f0a50c46ad819ec8ba380a42448e24459daf809cf4"}, - {file = "cffi-1.17.0-cp39-cp39-win32.whl", hash = "sha256:0fdacad9e0d9fc23e519efd5ea24a70348305e8d7d85ecbb1a5fa66dc834e7fb"}, - {file = "cffi-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:7cbc78dc018596315d4e7841c8c3a7ae31cc4d638c9b627f87d52e8abaaf2d29"}, - {file = "cffi-1.17.0.tar.gz", hash = "sha256:f3157624b7558b914cb039fd1af735e5e8049a87c817cc215109ad1c8779df76"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, + {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, + {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, + {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, + {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, + {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, + {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, + {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, + {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, + {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, + {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, + {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, + {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, + {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, + {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, ] [package.dependencies] @@ -1416,6 +1416,17 @@ typer = ">=0.9.0" typing-extensions = ">=4.5.0" uvicorn = {version = ">=0.18.3", extras = ["standard"]} +[[package]] +name = "circuitbreaker" +version = "2.0.0" +description = "Python Circuit Breaker pattern implementation" +optional = false +python-versions = "*" +files = [ + {file = "circuitbreaker-2.0.0-py2.py3-none-any.whl", hash = "sha256:c8c6f044b616cd5066368734ce4488020392c962b4bd2869d406d883c36d9859"}, + {file = "circuitbreaker-2.0.0.tar.gz", hash = "sha256:28110761ca81a2accbd6b33186bc8c433e69b0933d85e89f280028dbb8c1dd14"}, +] + [[package]] name = "click" version = "8.1.7" @@ -1708,6 +1719,17 @@ lz4 = ["clickhouse-cityhash (>=1.0.2.1)", "lz4", "lz4 (<=3.0.1)"] numpy = ["numpy (>=1.12.0)", "pandas (>=0.24.0)"] zstd = ["clickhouse-cityhash (>=1.0.2.1)", "zstd"] +[[package]] +name = "cloudpickle" +version = "2.2.1" +description = "Extended pickling support for Python objects" +optional = false +python-versions = ">=3.6" +files = [ + {file = "cloudpickle-2.2.1-py3-none-any.whl", hash = "sha256:61f594d1f4c295fa5cd9014ceb3a1fc4a70b0de1164b94fbc2d854ccba056f9f"}, + {file = "cloudpickle-2.2.1.tar.gz", hash = "sha256:d89684b8de9e34a2a43b3460fbca07d09d6e25ce858df4d5a44240403b6178f5"}, +] + [[package]] name = "cloudscraper" version = "1.2.71" @@ -1774,66 +1796,87 @@ cron = ["capturer (>=2.4)"] [[package]] name = "contourpy" -version = "1.2.1" +version = "1.3.0" description = "Python library for calculating contours of 2D quadrilateral grids" optional = false python-versions = ">=3.9" files = [ - {file = "contourpy-1.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd7c23df857d488f418439686d3b10ae2fbf9bc256cd045b37a8c16575ea1040"}, - {file = "contourpy-1.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5b9eb0ca724a241683c9685a484da9d35c872fd42756574a7cfbf58af26677fd"}, - {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c75507d0a55378240f781599c30e7776674dbaf883a46d1c90f37e563453480"}, - {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11959f0ce4a6f7b76ec578576a0b61a28bdc0696194b6347ba3f1c53827178b9"}, - {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb3315a8a236ee19b6df481fc5f997436e8ade24a9f03dfdc6bd490fea20c6da"}, - {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39f3ecaf76cd98e802f094e0d4fbc6dc9c45a8d0c4d185f0f6c2234e14e5f75b"}, - {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:94b34f32646ca0414237168d68a9157cb3889f06b096612afdd296003fdd32fd"}, - {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:457499c79fa84593f22454bbd27670227874cd2ff5d6c84e60575c8b50a69619"}, - {file = "contourpy-1.2.1-cp310-cp310-win32.whl", hash = "sha256:ac58bdee53cbeba2ecad824fa8159493f0bf3b8ea4e93feb06c9a465d6c87da8"}, - {file = "contourpy-1.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:9cffe0f850e89d7c0012a1fb8730f75edd4320a0a731ed0c183904fe6ecfc3a9"}, - {file = "contourpy-1.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6022cecf8f44e36af10bd9118ca71f371078b4c168b6e0fab43d4a889985dbb5"}, - {file = "contourpy-1.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef5adb9a3b1d0c645ff694f9bca7702ec2c70f4d734f9922ea34de02294fdf72"}, - {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6150ffa5c767bc6332df27157d95442c379b7dce3a38dff89c0f39b63275696f"}, - {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c863140fafc615c14a4bf4efd0f4425c02230eb8ef02784c9a156461e62c965"}, - {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:00e5388f71c1a0610e6fe56b5c44ab7ba14165cdd6d695429c5cd94021e390b2"}, - {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4492d82b3bc7fbb7e3610747b159869468079fe149ec5c4d771fa1f614a14df"}, - {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49e70d111fee47284d9dd867c9bb9a7058a3c617274900780c43e38d90fe1205"}, - {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b59c0ffceff8d4d3996a45f2bb6f4c207f94684a96bf3d9728dbb77428dd8cb8"}, - {file = "contourpy-1.2.1-cp311-cp311-win32.whl", hash = "sha256:7b4182299f251060996af5249c286bae9361fa8c6a9cda5efc29fe8bfd6062ec"}, - {file = "contourpy-1.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2855c8b0b55958265e8b5888d6a615ba02883b225f2227461aa9127c578a4922"}, - {file = "contourpy-1.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:62828cada4a2b850dbef89c81f5a33741898b305db244904de418cc957ff05dc"}, - {file = "contourpy-1.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:309be79c0a354afff9ff7da4aaed7c3257e77edf6c1b448a779329431ee79d7e"}, - {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e785e0f2ef0d567099b9ff92cbfb958d71c2d5b9259981cd9bee81bd194c9a4"}, - {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cac0a8f71a041aa587410424ad46dfa6a11f6149ceb219ce7dd48f6b02b87a7"}, - {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af3f4485884750dddd9c25cb7e3915d83c2db92488b38ccb77dd594eac84c4a0"}, - {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ce6889abac9a42afd07a562c2d6d4b2b7134f83f18571d859b25624a331c90b"}, - {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a1eea9aecf761c661d096d39ed9026574de8adb2ae1c5bd7b33558af884fb2ce"}, - {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:187fa1d4c6acc06adb0fae5544c59898ad781409e61a926ac7e84b8f276dcef4"}, - {file = "contourpy-1.2.1-cp312-cp312-win32.whl", hash = "sha256:c2528d60e398c7c4c799d56f907664673a807635b857df18f7ae64d3e6ce2d9f"}, - {file = "contourpy-1.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:1a07fc092a4088ee952ddae19a2b2a85757b923217b7eed584fdf25f53a6e7ce"}, - {file = "contourpy-1.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bb6834cbd983b19f06908b45bfc2dad6ac9479ae04abe923a275b5f48f1a186b"}, - {file = "contourpy-1.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1d59e739ab0e3520e62a26c60707cc3ab0365d2f8fecea74bfe4de72dc56388f"}, - {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd3db01f59fdcbce5b22afad19e390260d6d0222f35a1023d9adc5690a889364"}, - {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a12a813949e5066148712a0626895c26b2578874e4cc63160bb007e6df3436fe"}, - {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe0ccca550bb8e5abc22f530ec0466136379c01321fd94f30a22231e8a48d985"}, - {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1d59258c3c67c865435d8fbeb35f8c59b8bef3d6f46c1f29f6123556af28445"}, - {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f32c38afb74bd98ce26de7cc74a67b40afb7b05aae7b42924ea990d51e4dac02"}, - {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d31a63bc6e6d87f77d71e1abbd7387ab817a66733734883d1fc0021ed9bfa083"}, - {file = "contourpy-1.2.1-cp39-cp39-win32.whl", hash = "sha256:ddcb8581510311e13421b1f544403c16e901c4e8f09083c881fab2be80ee31ba"}, - {file = "contourpy-1.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:10a37ae557aabf2509c79715cd20b62e4c7c28b8cd62dd7d99e5ed3ce28c3fd9"}, - {file = "contourpy-1.2.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a31f94983fecbac95e58388210427d68cd30fe8a36927980fab9c20062645609"}, - {file = "contourpy-1.2.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef2b055471c0eb466033760a521efb9d8a32b99ab907fc8358481a1dd29e3bd3"}, - {file = "contourpy-1.2.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b33d2bc4f69caedcd0a275329eb2198f560b325605810895627be5d4b876bf7f"}, - {file = "contourpy-1.2.1.tar.gz", hash = "sha256:4d8908b3bee1c889e547867ca4cdc54e5ab6be6d3e078556814a22457f49423c"}, + {file = "contourpy-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:880ea32e5c774634f9fcd46504bf9f080a41ad855f4fef54f5380f5133d343c7"}, + {file = "contourpy-1.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:76c905ef940a4474a6289c71d53122a4f77766eef23c03cd57016ce19d0f7b42"}, + {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92f8557cbb07415a4d6fa191f20fd9d2d9eb9c0b61d1b2f52a8926e43c6e9af7"}, + {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36f965570cff02b874773c49bfe85562b47030805d7d8360748f3eca570f4cab"}, + {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cacd81e2d4b6f89c9f8a5b69b86490152ff39afc58a95af002a398273e5ce589"}, + {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69375194457ad0fad3a839b9e29aa0b0ed53bb54db1bfb6c3ae43d111c31ce41"}, + {file = "contourpy-1.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a52040312b1a858b5e31ef28c2e865376a386c60c0e248370bbea2d3f3b760d"}, + {file = "contourpy-1.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3faeb2998e4fcb256542e8a926d08da08977f7f5e62cf733f3c211c2a5586223"}, + {file = "contourpy-1.3.0-cp310-cp310-win32.whl", hash = "sha256:36e0cff201bcb17a0a8ecc7f454fe078437fa6bda730e695a92f2d9932bd507f"}, + {file = "contourpy-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:87ddffef1dbe5e669b5c2440b643d3fdd8622a348fe1983fad7a0f0ccb1cd67b"}, + {file = "contourpy-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0fa4c02abe6c446ba70d96ece336e621efa4aecae43eaa9b030ae5fb92b309ad"}, + {file = "contourpy-1.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:834e0cfe17ba12f79963861e0f908556b2cedd52e1f75e6578801febcc6a9f49"}, + {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbc4c3217eee163fa3984fd1567632b48d6dfd29216da3ded3d7b844a8014a66"}, + {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4865cd1d419e0c7a7bf6de1777b185eebdc51470800a9f42b9e9decf17762081"}, + {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:303c252947ab4b14c08afeb52375b26781ccd6a5ccd81abcdfc1fafd14cf93c1"}, + {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637f674226be46f6ba372fd29d9523dd977a291f66ab2a74fbeb5530bb3f445d"}, + {file = "contourpy-1.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:76a896b2f195b57db25d6b44e7e03f221d32fe318d03ede41f8b4d9ba1bff53c"}, + {file = "contourpy-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e1fd23e9d01591bab45546c089ae89d926917a66dceb3abcf01f6105d927e2cb"}, + {file = "contourpy-1.3.0-cp311-cp311-win32.whl", hash = "sha256:d402880b84df3bec6eab53cd0cf802cae6a2ef9537e70cf75e91618a3801c20c"}, + {file = "contourpy-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:6cb6cc968059db9c62cb35fbf70248f40994dfcd7aa10444bbf8b3faeb7c2d67"}, + {file = "contourpy-1.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:570ef7cf892f0afbe5b2ee410c507ce12e15a5fa91017a0009f79f7d93a1268f"}, + {file = "contourpy-1.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:da84c537cb8b97d153e9fb208c221c45605f73147bd4cadd23bdae915042aad6"}, + {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0be4d8425bfa755e0fd76ee1e019636ccc7c29f77a7c86b4328a9eb6a26d0639"}, + {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c0da700bf58f6e0b65312d0a5e695179a71d0163957fa381bb3c1f72972537c"}, + {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb8b141bb00fa977d9122636b16aa67d37fd40a3d8b52dd837e536d64b9a4d06"}, + {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3634b5385c6716c258d0419c46d05c8aa7dc8cb70326c9a4fb66b69ad2b52e09"}, + {file = "contourpy-1.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0dce35502151b6bd35027ac39ba6e5a44be13a68f55735c3612c568cac3805fd"}, + {file = "contourpy-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:aea348f053c645100612b333adc5983d87be69acdc6d77d3169c090d3b01dc35"}, + {file = "contourpy-1.3.0-cp312-cp312-win32.whl", hash = "sha256:90f73a5116ad1ba7174341ef3ea5c3150ddf20b024b98fb0c3b29034752c8aeb"}, + {file = "contourpy-1.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:b11b39aea6be6764f84360fce6c82211a9db32a7c7de8fa6dd5397cf1d079c3b"}, + {file = "contourpy-1.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3e1c7fa44aaae40a2247e2e8e0627f4bea3dd257014764aa644f319a5f8600e3"}, + {file = "contourpy-1.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:364174c2a76057feef647c802652f00953b575723062560498dc7930fc9b1cb7"}, + {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32b238b3b3b649e09ce9aaf51f0c261d38644bdfa35cbaf7b263457850957a84"}, + {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d51fca85f9f7ad0b65b4b9fe800406d0d77017d7270d31ec3fb1cc07358fdea0"}, + {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:732896af21716b29ab3e988d4ce14bc5133733b85956316fb0c56355f398099b"}, + {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d73f659398a0904e125280836ae6f88ba9b178b2fed6884f3b1f95b989d2c8da"}, + {file = "contourpy-1.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c6c7c2408b7048082932cf4e641fa3b8ca848259212f51c8c59c45aa7ac18f14"}, + {file = "contourpy-1.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f317576606de89da6b7e0861cf6061f6146ead3528acabff9236458a6ba467f8"}, + {file = "contourpy-1.3.0-cp313-cp313-win32.whl", hash = "sha256:31cd3a85dbdf1fc002280c65caa7e2b5f65e4a973fcdf70dd2fdcb9868069294"}, + {file = "contourpy-1.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:4553c421929ec95fb07b3aaca0fae668b2eb5a5203d1217ca7c34c063c53d087"}, + {file = "contourpy-1.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:345af746d7766821d05d72cb8f3845dfd08dd137101a2cb9b24de277d716def8"}, + {file = "contourpy-1.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3bb3808858a9dc68f6f03d319acd5f1b8a337e6cdda197f02f4b8ff67ad2057b"}, + {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:420d39daa61aab1221567b42eecb01112908b2cab7f1b4106a52caaec8d36973"}, + {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4d63ee447261e963af02642ffcb864e5a2ee4cbfd78080657a9880b8b1868e18"}, + {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:167d6c890815e1dac9536dca00828b445d5d0df4d6a8c6adb4a7ec3166812fa8"}, + {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:710a26b3dc80c0e4febf04555de66f5fd17e9cf7170a7b08000601a10570bda6"}, + {file = "contourpy-1.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:75ee7cb1a14c617f34a51d11fa7524173e56551646828353c4af859c56b766e2"}, + {file = "contourpy-1.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:33c92cdae89ec5135d036e7218e69b0bb2851206077251f04a6c4e0e21f03927"}, + {file = "contourpy-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a11077e395f67ffc2c44ec2418cfebed032cd6da3022a94fc227b6faf8e2acb8"}, + {file = "contourpy-1.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e8134301d7e204c88ed7ab50028ba06c683000040ede1d617298611f9dc6240c"}, + {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e12968fdfd5bb45ffdf6192a590bd8ddd3ba9e58360b29683c6bb71a7b41edca"}, + {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fd2a0fc506eccaaa7595b7e1418951f213cf8255be2600f1ea1b61e46a60c55f"}, + {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4cfb5c62ce023dfc410d6059c936dcf96442ba40814aefbfa575425a3a7f19dc"}, + {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68a32389b06b82c2fdd68276148d7b9275b5f5cf13e5417e4252f6d1a34f72a2"}, + {file = "contourpy-1.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:94e848a6b83da10898cbf1311a815f770acc9b6a3f2d646f330d57eb4e87592e"}, + {file = "contourpy-1.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d78ab28a03c854a873787a0a42254a0ccb3cb133c672f645c9f9c8f3ae9d0800"}, + {file = "contourpy-1.3.0-cp39-cp39-win32.whl", hash = "sha256:81cb5ed4952aae6014bc9d0421dec7c5835c9c8c31cdf51910b708f548cf58e5"}, + {file = "contourpy-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:14e262f67bd7e6eb6880bc564dcda30b15e351a594657e55b7eec94b6ef72843"}, + {file = "contourpy-1.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fe41b41505a5a33aeaed2a613dccaeaa74e0e3ead6dd6fd3a118fb471644fd6c"}, + {file = "contourpy-1.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eca7e17a65f72a5133bdbec9ecf22401c62bcf4821361ef7811faee695799779"}, + {file = "contourpy-1.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1ec4dc6bf570f5b22ed0d7efba0dfa9c5b9e0431aeea7581aa217542d9e809a4"}, + {file = "contourpy-1.3.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:00ccd0dbaad6d804ab259820fa7cb0b8036bda0686ef844d24125d8287178ce0"}, + {file = "contourpy-1.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ca947601224119117f7c19c9cdf6b3ab54c5726ef1d906aa4a69dfb6dd58102"}, + {file = "contourpy-1.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c6ec93afeb848a0845a18989da3beca3eec2c0f852322efe21af1931147d12cb"}, + {file = "contourpy-1.3.0.tar.gz", hash = "sha256:7ffa0db17717a8ffb127efd0c95a4362d996b892c2904db72428d5b52e1938a4"}, ] [package.dependencies] -numpy = ">=1.20" +numpy = ">=1.23" [package.extras] bokeh = ["bokeh", "selenium"] docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] -mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.8.0)", "types-Pillow"] +mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.11.1)", "types-Pillow"] test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] -test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] +test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "wurlitzer"] [[package]] name = "cos-python-sdk-v5" @@ -1936,38 +1979,43 @@ files = [ [[package]] name = "cryptography" -version = "43.0.0" +version = "42.0.8" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-43.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:64c3f16e2a4fc51c0d06af28441881f98c5d91009b8caaff40cf3548089e9c74"}, - {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3dcdedae5c7710b9f97ac6bba7e1052b95c7083c9d0e9df96e02a1932e777895"}, - {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d9a1eca329405219b605fac09ecfc09ac09e595d6def650a437523fcd08dd22"}, - {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ea9e57f8ea880eeea38ab5abf9fbe39f923544d7884228ec67d666abd60f5a47"}, - {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9a8d6802e0825767476f62aafed40532bd435e8a5f7d23bd8b4f5fd04cc80ecf"}, - {file = "cryptography-43.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:cc70b4b581f28d0a254d006f26949245e3657d40d8857066c2ae22a61222ef55"}, - {file = "cryptography-43.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4a997df8c1c2aae1e1e5ac49c2e4f610ad037fc5a3aadc7b64e39dea42249431"}, - {file = "cryptography-43.0.0-cp37-abi3-win32.whl", hash = "sha256:6e2b11c55d260d03a8cf29ac9b5e0608d35f08077d8c087be96287f43af3ccdc"}, - {file = "cryptography-43.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:31e44a986ceccec3d0498e16f3d27b2ee5fdf69ce2ab89b52eaad1d2f33d8778"}, - {file = "cryptography-43.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:7b3f5fe74a5ca32d4d0f302ffe6680fcc5c28f8ef0dc0ae8f40c0f3a1b4fca66"}, - {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac1955ce000cb29ab40def14fd1bbfa7af2017cca696ee696925615cafd0dce5"}, - {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:299d3da8e00b7e2b54bb02ef58d73cd5f55fb31f33ebbf33bd00d9aa6807df7e"}, - {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ee0c405832ade84d4de74b9029bedb7b31200600fa524d218fc29bfa371e97f5"}, - {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cb013933d4c127349b3948aa8aaf2f12c0353ad0eccd715ca789c8a0f671646f"}, - {file = "cryptography-43.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fdcb265de28585de5b859ae13e3846a8e805268a823a12a4da2597f1f5afc9f0"}, - {file = "cryptography-43.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2905ccf93a8a2a416f3ec01b1a7911c3fe4073ef35640e7ee5296754e30b762b"}, - {file = "cryptography-43.0.0-cp39-abi3-win32.whl", hash = "sha256:47ca71115e545954e6c1d207dd13461ab81f4eccfcb1345eac874828b5e3eaaf"}, - {file = "cryptography-43.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:0663585d02f76929792470451a5ba64424acc3cd5227b03921dab0e2f27b1709"}, - {file = "cryptography-43.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2c6d112bf61c5ef44042c253e4859b3cbbb50df2f78fa8fae6747a7814484a70"}, - {file = "cryptography-43.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:844b6d608374e7d08f4f6e6f9f7b951f9256db41421917dfb2d003dde4cd6b66"}, - {file = "cryptography-43.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:51956cf8730665e2bdf8ddb8da0056f699c1a5715648c1b0144670c1ba00b48f"}, - {file = "cryptography-43.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:aae4d918f6b180a8ab8bf6511a419473d107df4dbb4225c7b48c5c9602c38c7f"}, - {file = "cryptography-43.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:232ce02943a579095a339ac4b390fbbe97f5b5d5d107f8a08260ea2768be8cc2"}, - {file = "cryptography-43.0.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5bcb8a5620008a8034d39bce21dc3e23735dfdb6a33a06974739bfa04f853947"}, - {file = "cryptography-43.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:08a24a7070b2b6804c1940ff0f910ff728932a9d0e80e7814234269f9d46d069"}, - {file = "cryptography-43.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e9c5266c432a1e23738d178e51c2c7a5e2ddf790f248be939448c0ba2021f9d1"}, - {file = "cryptography-43.0.0.tar.gz", hash = "sha256:b88075ada2d51aa9f18283532c9f60e72170041bba88d7f37e49cbb10275299e"}, + {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"}, + {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"}, + {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"}, + {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"}, + {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"}, + {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"}, + {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"}, + {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"}, + {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"}, + {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"}, + {file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"}, + {file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"}, + {file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"}, + {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"}, + {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"}, + {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"}, + {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"}, + {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"}, + {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"}, + {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"}, + {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"}, + {file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"}, + {file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"}, + {file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"}, + {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"}, + {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"}, + {file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"}, + {file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"}, + {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"}, + {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"}, + {file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"}, + {file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"}, ] [package.dependencies] @@ -1980,7 +2028,7 @@ nox = ["nox"] pep8test = ["check-sdist", "click", "mypy", "ruff"] sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "cryptography-vectors (==43.0.0)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] [[package]] @@ -2114,6 +2162,21 @@ wrapt = ">=1.10,<2" [package.extras] dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +[[package]] +name = "dill" +version = "0.3.8" +description = "serialize all of Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7"}, + {file = "dill-0.3.8.tar.gz", hash = "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca"}, +] + +[package.extras] +graph = ["objgraph (>=1.7.2)"] +profile = ["gprof2dot (>=2022.7.29)"] + [[package]] name = "distro" version = "1.9.0" @@ -2125,6 +2188,28 @@ files = [ {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"}, ] +[[package]] +name = "docker" +version = "7.1.0" +description = "A Python library for the Docker Engine API." +optional = false +python-versions = ">=3.8" +files = [ + {file = "docker-7.1.0-py3-none-any.whl", hash = "sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0"}, + {file = "docker-7.1.0.tar.gz", hash = "sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c"}, +] + +[package.dependencies] +pywin32 = {version = ">=304", markers = "sys_platform == \"win32\""} +requests = ">=2.26.0" +urllib3 = ">=1.26.0" + +[package.extras] +dev = ["coverage (==7.2.7)", "pytest (==7.4.2)", "pytest-cov (==4.1.0)", "pytest-timeout (==2.1.0)", "ruff (==0.1.8)"] +docs = ["myst-parser (==0.18.0)", "sphinx (==5.1.1)"] +ssh = ["paramiko (>=2.4.3)"] +websockets = ["websocket-client (>=1.3.0)"] + [[package]] name = "docstring-parser" version = "0.16" @@ -2211,13 +2296,13 @@ files = [ [[package]] name = "duckduckgo-search" -version = "6.2.10" +version = "6.2.11" 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.10-py3-none-any.whl", hash = "sha256:266c1528dcbc90931b7c800a2c1041a0cb447c83c485414d77a7e443be717ed6"}, - {file = "duckduckgo_search-6.2.10.tar.gz", hash = "sha256:53057368480ca496fc4e331a34648124711580cf43fbb65336eaa6fd2ee37cec"}, + {file = "duckduckgo_search-6.2.11-py3-none-any.whl", hash = "sha256:6fb7069b79e8928f487001de6859034ade19201bdcd257ec198802430e374bfe"}, + {file = "duckduckgo_search-6.2.11.tar.gz", hash = "sha256:6b6ef1b552c5e67f23e252025d2504caf6f9fc14f70e86c6dd512200f386c673"}, ] [package.dependencies] @@ -2304,6 +2389,19 @@ django = ["dj-database-url", "dj-email-url", "django-cache-url"] lint = ["flake8 (==4.0.1)", "flake8-bugbear (==21.9.2)", "mypy (==0.910)", "pre-commit (>=2.4,<3.0)"] tests = ["dj-database-url", "dj-email-url", "django-cache-url", "pytest"] +[[package]] +name = "esdk-obs-python" +version = "3.24.6.1" +description = "OBS Python SDK" +optional = false +python-versions = "*" +files = [ + {file = "esdk-obs-python-3.24.6.1.tar.gz", hash = "sha256:c45fed143e99d9256c8560c1d78f651eae0d2e809d16e962f8b286b773c33bf0"}, +] + +[package.dependencies] +pycryptodome = ">=3.10.1" + [[package]] name = "et-xmlfile" version = "1.1.0" @@ -2331,13 +2429,13 @@ test = ["pytest (>=6)"] [[package]] name = "fastapi" -version = "0.112.1" +version = "0.113.0" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" optional = false python-versions = ">=3.8" files = [ - {file = "fastapi-0.112.1-py3-none-any.whl", hash = "sha256:bcbd45817fc2a1cd5da09af66815b84ec0d3d634eb173d1ab468ae3103e183e4"}, - {file = "fastapi-0.112.1.tar.gz", hash = "sha256:b2537146f8c23389a7faa8b03d0bd38d4986e6983874557d95eed2acc46448ef"}, + {file = "fastapi-0.113.0-py3-none-any.whl", hash = "sha256:c8d364485b6361fb643d53920a18d58a696e189abcb901ec03b487e35774c476"}, + {file = "fastapi-0.113.0.tar.gz", hash = "sha256:b7cf9684dc154dfc93f8b718e5850577b529889096518df44defa41e73caf50f"}, ] [package.dependencies] @@ -2346,47 +2444,47 @@ starlette = ">=0.37.2,<0.39.0" typing-extensions = ">=4.8.0" [package.extras] -all = ["email_validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] -standard = ["email_validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "jinja2 (>=2.11.2)", "python-multipart (>=0.0.7)", "uvicorn[standard] (>=0.12.0)"] +all = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] +standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "jinja2 (>=2.11.2)", "python-multipart (>=0.0.7)", "uvicorn[standard] (>=0.12.0)"] [[package]] name = "fastavro" -version = "1.9.5" +version = "1.9.7" description = "Fast read/write of AVRO files" optional = false python-versions = ">=3.8" files = [ - {file = "fastavro-1.9.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:61253148e95dd2b6457247b441b7555074a55de17aef85f5165bfd5facf600fc"}, - {file = "fastavro-1.9.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b604935d671ad47d888efc92a106f98e9440874108b444ac10e28d643109c937"}, - {file = "fastavro-1.9.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0adbf4956fd53bd74c41e7855bb45ccce953e0eb0e44f5836d8d54ad843f9944"}, - {file = "fastavro-1.9.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:53d838e31457db8bf44460c244543f75ed307935d5fc1d93bc631cc7caef2082"}, - {file = "fastavro-1.9.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:07b6288e8681eede16ff077632c47395d4925c2f51545cd7a60f194454db2211"}, - {file = "fastavro-1.9.5-cp310-cp310-win_amd64.whl", hash = "sha256:ef08cf247fdfd61286ac0c41854f7194f2ad05088066a756423d7299b688d975"}, - {file = "fastavro-1.9.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c52d7bb69f617c90935a3e56feb2c34d4276819a5c477c466c6c08c224a10409"}, - {file = "fastavro-1.9.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85e05969956003df8fa4491614bc62fe40cec59e94d06e8aaa8d8256ee3aab82"}, - {file = "fastavro-1.9.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06e6df8527493a9f0d9a8778df82bab8b1aa6d80d1b004e5aec0a31dc4dc501c"}, - {file = "fastavro-1.9.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:27820da3b17bc01cebb6d1687c9d7254b16d149ef458871aaa207ed8950f3ae6"}, - {file = "fastavro-1.9.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:195a5b8e33eb89a1a9b63fa9dce7a77d41b3b0cd785bac6044df619f120361a2"}, - {file = "fastavro-1.9.5-cp311-cp311-win_amd64.whl", hash = "sha256:be612c109efb727bfd36d4d7ed28eb8e0506617b7dbe746463ebbf81e85eaa6b"}, - {file = "fastavro-1.9.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b133456c8975ec7d2a99e16a7e68e896e45c821b852675eac4ee25364b999c14"}, - {file = "fastavro-1.9.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf586373c3d1748cac849395aad70c198ee39295f92e7c22c75757b5c0300fbe"}, - {file = "fastavro-1.9.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:724ef192bc9c55d5b4c7df007f56a46a21809463499856349d4580a55e2b914c"}, - {file = "fastavro-1.9.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bfd11fe355a8f9c0416803afac298960eb4c603a23b1c74ff9c1d3e673ea7185"}, - {file = "fastavro-1.9.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9827d1654d7bcb118ef5efd3e5b2c9ab2a48d44dac5e8c6a2327bc3ac3caa828"}, - {file = "fastavro-1.9.5-cp312-cp312-win_amd64.whl", hash = "sha256:d84b69dca296667e6137ae7c9a96d060123adbc0c00532cc47012b64d38b47e9"}, - {file = "fastavro-1.9.5-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:fb744e9de40fb1dc75354098c8db7da7636cba50a40f7bef3b3fb20f8d189d88"}, - {file = "fastavro-1.9.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:240df8bacd13ff5487f2465604c007d686a566df5cbc01d0550684eaf8ff014a"}, - {file = "fastavro-1.9.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3bb35c25bbc3904e1c02333bc1ae0173e0a44aa37a8e95d07e681601246e1f1"}, - {file = "fastavro-1.9.5-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:b47a54a9700de3eabefd36dabfb237808acae47bc873cada6be6990ef6b165aa"}, - {file = "fastavro-1.9.5-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:48c7b5e6d2f3bf7917af301c275b05c5be3dd40bb04e80979c9e7a2ab31a00d1"}, - {file = "fastavro-1.9.5-cp38-cp38-win_amd64.whl", hash = "sha256:05d13f98d4e325be40387e27da9bd60239968862fe12769258225c62ec906f04"}, - {file = "fastavro-1.9.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5b47948eb196263f6111bf34e1cd08d55529d4ed46eb50c1bc8c7c30a8d18868"}, - {file = "fastavro-1.9.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85b7a66ad521298ad9373dfe1897a6ccfc38feab54a47b97922e213ae5ad8870"}, - {file = "fastavro-1.9.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44cb154f863ad80e41aea72a709b12e1533b8728c89b9b1348af91a6154ab2f5"}, - {file = "fastavro-1.9.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b5f7f2b1fe21231fd01f1a2a90e714ae267fe633cd7ce930c0aea33d1c9f4901"}, - {file = "fastavro-1.9.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:88fbbe16c61d90a89d78baeb5a34dc1c63a27b115adccdbd6b1fb6f787deacf2"}, - {file = "fastavro-1.9.5-cp39-cp39-win_amd64.whl", hash = "sha256:753f5eedeb5ca86004e23a9ce9b41c5f25eb64a876f95edcc33558090a7f3e4b"}, - {file = "fastavro-1.9.5.tar.gz", hash = "sha256:6419ebf45f88132a9945c51fe555d4f10bb97c236288ed01894f957c6f914553"}, + {file = "fastavro-1.9.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cc811fb4f7b5ae95f969cda910241ceacf82e53014c7c7224df6f6e0ca97f52f"}, + {file = "fastavro-1.9.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb8749e419a85f251bf1ac87d463311874972554d25d4a0b19f6bdc56036d7cf"}, + {file = "fastavro-1.9.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b2f9bafa167cb4d1c3dd17565cb5bf3d8c0759e42620280d1760f1e778e07fc"}, + {file = "fastavro-1.9.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e87d04b235b29f7774d226b120da2ca4e60b9e6fdf6747daef7f13f218b3517a"}, + {file = "fastavro-1.9.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b525c363e267ed11810aaad8fbdbd1c3bd8837d05f7360977d72a65ab8c6e1fa"}, + {file = "fastavro-1.9.7-cp310-cp310-win_amd64.whl", hash = "sha256:6312fa99deecc319820216b5e1b1bd2d7ebb7d6f221373c74acfddaee64e8e60"}, + {file = "fastavro-1.9.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ec8499dc276c2d2ef0a68c0f1ad11782b2b956a921790a36bf4c18df2b8d4020"}, + {file = "fastavro-1.9.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d9d96f98052615ab465c63ba8b76ed59baf2e3341b7b169058db104cbe2aa0"}, + {file = "fastavro-1.9.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:919f3549e07a8a8645a2146f23905955c35264ac809f6c2ac18142bc5b9b6022"}, + {file = "fastavro-1.9.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9de1fa832a4d9016724cd6facab8034dc90d820b71a5d57c7e9830ffe90f31e4"}, + {file = "fastavro-1.9.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1d09227d1f48f13281bd5ceac958650805aef9a4ef4f95810128c1f9be1df736"}, + {file = "fastavro-1.9.7-cp311-cp311-win_amd64.whl", hash = "sha256:2db993ae6cdc63e25eadf9f93c9e8036f9b097a3e61d19dca42536dcc5c4d8b3"}, + {file = "fastavro-1.9.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:4e1289b731214a7315884c74b2ec058b6e84380ce9b18b8af5d387e64b18fc44"}, + {file = "fastavro-1.9.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eac69666270a76a3a1d0444f39752061195e79e146271a568777048ffbd91a27"}, + {file = "fastavro-1.9.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9be089be8c00f68e343bbc64ca6d9a13e5e5b0ba8aa52bcb231a762484fb270e"}, + {file = "fastavro-1.9.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d576eccfd60a18ffa028259500df67d338b93562c6700e10ef68bbd88e499731"}, + {file = "fastavro-1.9.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ee9bf23c157bd7dcc91ea2c700fa3bd924d9ec198bb428ff0b47fa37fe160659"}, + {file = "fastavro-1.9.7-cp312-cp312-win_amd64.whl", hash = "sha256:b6b2ccdc78f6afc18c52e403ee68c00478da12142815c1bd8a00973138a166d0"}, + {file = "fastavro-1.9.7-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:7313def3aea3dacface0a8b83f6d66e49a311149aa925c89184a06c1ef99785d"}, + {file = "fastavro-1.9.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:536f5644737ad21d18af97d909dba099b9e7118c237be7e4bd087c7abde7e4f0"}, + {file = "fastavro-1.9.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2af559f30383b79cf7d020a6b644c42ffaed3595f775fe8f3d7f80b1c43dfdc5"}, + {file = "fastavro-1.9.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:edc28ab305e3c424de5ac5eb87b48d1e07eddb6aa08ef5948fcda33cc4d995ce"}, + {file = "fastavro-1.9.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:ec2e96bdabd58427fe683329b3d79f42c7b4f4ff6b3644664a345a655ac2c0a1"}, + {file = "fastavro-1.9.7-cp38-cp38-win_amd64.whl", hash = "sha256:3b683693c8a85ede496ebebe115be5d7870c150986e34a0442a20d88d7771224"}, + {file = "fastavro-1.9.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:58f76a5c9a312fbd37b84e49d08eb23094d36e10d43bc5df5187bc04af463feb"}, + {file = "fastavro-1.9.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56304401d2f4f69f5b498bdd1552c13ef9a644d522d5de0dc1d789cf82f47f73"}, + {file = "fastavro-1.9.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fcce036c6aa06269fc6a0428050fcb6255189997f5e1a728fc461e8b9d3e26b"}, + {file = "fastavro-1.9.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:17de68aae8c2525f5631d80f2b447a53395cdc49134f51b0329a5497277fc2d2"}, + {file = "fastavro-1.9.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7c911366c625d0a997eafe0aa83ffbc6fd00d8fd4543cb39a97c6f3b8120ea87"}, + {file = "fastavro-1.9.7-cp39-cp39-win_amd64.whl", hash = "sha256:912283ed48578a103f523817fdf0c19b1755cea9b4a6387b73c79ecb8f8f84fc"}, + {file = "fastavro-1.9.7.tar.gz", hash = "sha256:13e11c6cb28626da85290933027cd419ce3f9ab8e45410ef24ce6b89d20a1f6c"}, ] [package.extras] @@ -2491,13 +2589,13 @@ flask = "*" [[package]] name = "flask-cors" -version = "4.0.1" +version = "4.0.2" description = "A Flask extension adding a decorator for CORS support" optional = false python-versions = "*" files = [ - {file = "Flask_Cors-4.0.1-py2.py3-none-any.whl", hash = "sha256:f2a704e4458665580c074b714c4627dd5a306b333deb9074d0b1794dfa2fb677"}, - {file = "flask_cors-4.0.1.tar.gz", hash = "sha256:eeb69b342142fdbf4766ad99357a7f3876a2ceb77689dc10ff912aac06c389e4"}, + {file = "Flask_Cors-4.0.2-py2.py3-none-any.whl", hash = "sha256:38364faf1a7a5d0a55bd1d2e2f83ee9e359039182f5e6a029557e1f56d92c09a"}, + {file = "flask_cors-4.0.2.tar.gz", hash = "sha256:493b98e2d1e2f1a4720a7af25693ef2fe32fbafec09a2f72c59f3e475eda61d2"}, ] [package.dependencies] @@ -2793,13 +2891,13 @@ files = [ [[package]] name = "fsspec" -version = "2024.6.1" +version = "2024.9.0" description = "File-system specification" optional = false python-versions = ">=3.8" files = [ - {file = "fsspec-2024.6.1-py3-none-any.whl", hash = "sha256:3cb443f8bcd2efb31295a5b9fdb02aee81d8452c80d28f97a6d0959e6cee101e"}, - {file = "fsspec-2024.6.1.tar.gz", hash = "sha256:fad7d7e209dd4c1208e3bbfda706620e0da5142bebbd9c384afb95b07e798e49"}, + {file = "fsspec-2024.9.0-py3-none-any.whl", hash = "sha256:a0947d552d8a6efa72cc2c730b12c41d043509156966cca4fb157b0f2a0c574b"}, + {file = "fsspec-2024.9.0.tar.gz", hash = "sha256:4b0afb90c2f21832df142f292649035d80b421f60a9e1c027802e5a0da2b04e8"}, ] [package.extras] @@ -3199,79 +3297,38 @@ protobuf = ["protobuf (<5.0.0dev)"] [[package]] name = "google-crc32c" -version = "1.5.0" +version = "1.6.0" description = "A python wrapper of the C library 'Google CRC32C'" optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "google-crc32c-1.5.0.tar.gz", hash = "sha256:89284716bc6a5a415d4eaa11b1726d2d60a0cd12aadf5439828353662ede9dd7"}, - {file = "google_crc32c-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:596d1f98fc70232fcb6590c439f43b350cb762fb5d61ce7b0e9db4539654cc13"}, - {file = "google_crc32c-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:be82c3c8cfb15b30f36768797a640e800513793d6ae1724aaaafe5bf86f8f346"}, - {file = "google_crc32c-1.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:461665ff58895f508e2866824a47bdee72497b091c730071f2b7575d5762ab65"}, - {file = "google_crc32c-1.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2096eddb4e7c7bdae4bd69ad364e55e07b8316653234a56552d9c988bd2d61b"}, - {file = "google_crc32c-1.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:116a7c3c616dd14a3de8c64a965828b197e5f2d121fedd2f8c5585c547e87b02"}, - {file = "google_crc32c-1.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5829b792bf5822fd0a6f6eb34c5f81dd074f01d570ed7f36aa101d6fc7a0a6e4"}, - {file = "google_crc32c-1.5.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:64e52e2b3970bd891309c113b54cf0e4384762c934d5ae56e283f9a0afcd953e"}, - {file = "google_crc32c-1.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:02ebb8bf46c13e36998aeaad1de9b48f4caf545e91d14041270d9dca767b780c"}, - {file = "google_crc32c-1.5.0-cp310-cp310-win32.whl", hash = "sha256:2e920d506ec85eb4ba50cd4228c2bec05642894d4c73c59b3a2fe20346bd00ee"}, - {file = "google_crc32c-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:07eb3c611ce363c51a933bf6bd7f8e3878a51d124acfc89452a75120bc436289"}, - {file = "google_crc32c-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cae0274952c079886567f3f4f685bcaf5708f0a23a5f5216fdab71f81a6c0273"}, - {file = "google_crc32c-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1034d91442ead5a95b5aaef90dbfaca8633b0247d1e41621d1e9f9db88c36298"}, - {file = "google_crc32c-1.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c42c70cd1d362284289c6273adda4c6af8039a8ae12dc451dcd61cdabb8ab57"}, - {file = "google_crc32c-1.5.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8485b340a6a9e76c62a7dce3c98e5f102c9219f4cfbf896a00cf48caf078d438"}, - {file = "google_crc32c-1.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77e2fd3057c9d78e225fa0a2160f96b64a824de17840351b26825b0848022906"}, - {file = "google_crc32c-1.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f583edb943cf2e09c60441b910d6a20b4d9d626c75a36c8fcac01a6c96c01183"}, - {file = "google_crc32c-1.5.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:a1fd716e7a01f8e717490fbe2e431d2905ab8aa598b9b12f8d10abebb36b04dd"}, - {file = "google_crc32c-1.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:72218785ce41b9cfd2fc1d6a017dc1ff7acfc4c17d01053265c41a2c0cc39b8c"}, - {file = "google_crc32c-1.5.0-cp311-cp311-win32.whl", hash = "sha256:66741ef4ee08ea0b2cc3c86916ab66b6aef03768525627fd6a1b34968b4e3709"}, - {file = "google_crc32c-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:ba1eb1843304b1e5537e1fca632fa894d6f6deca8d6389636ee5b4797affb968"}, - {file = "google_crc32c-1.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:98cb4d057f285bd80d8778ebc4fde6b4d509ac3f331758fb1528b733215443ae"}, - {file = "google_crc32c-1.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd8536e902db7e365f49e7d9029283403974ccf29b13fc7028b97e2295b33556"}, - {file = "google_crc32c-1.5.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19e0a019d2c4dcc5e598cd4a4bc7b008546b0358bd322537c74ad47a5386884f"}, - {file = "google_crc32c-1.5.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02c65b9817512edc6a4ae7c7e987fea799d2e0ee40c53ec573a692bee24de876"}, - {file = "google_crc32c-1.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6ac08d24c1f16bd2bf5eca8eaf8304812f44af5cfe5062006ec676e7e1d50afc"}, - {file = "google_crc32c-1.5.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3359fc442a743e870f4588fcf5dcbc1bf929df1fad8fb9905cd94e5edb02e84c"}, - {file = "google_crc32c-1.5.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e986b206dae4476f41bcec1faa057851f3889503a70e1bdb2378d406223994a"}, - {file = "google_crc32c-1.5.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:de06adc872bcd8c2a4e0dc51250e9e65ef2ca91be023b9d13ebd67c2ba552e1e"}, - {file = "google_crc32c-1.5.0-cp37-cp37m-win32.whl", hash = "sha256:d3515f198eaa2f0ed49f8819d5732d70698c3fa37384146079b3799b97667a94"}, - {file = "google_crc32c-1.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:67b741654b851abafb7bc625b6d1cdd520a379074e64b6a128e3b688c3c04740"}, - {file = "google_crc32c-1.5.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c02ec1c5856179f171e032a31d6f8bf84e5a75c45c33b2e20a3de353b266ebd8"}, - {file = "google_crc32c-1.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:edfedb64740750e1a3b16152620220f51d58ff1b4abceb339ca92e934775c27a"}, - {file = "google_crc32c-1.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84e6e8cd997930fc66d5bb4fde61e2b62ba19d62b7abd7a69920406f9ecca946"}, - {file = "google_crc32c-1.5.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:024894d9d3cfbc5943f8f230e23950cd4906b2fe004c72e29b209420a1e6b05a"}, - {file = "google_crc32c-1.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:998679bf62b7fb599d2878aa3ed06b9ce688b8974893e7223c60db155f26bd8d"}, - {file = "google_crc32c-1.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:83c681c526a3439b5cf94f7420471705bbf96262f49a6fe546a6db5f687a3d4a"}, - {file = "google_crc32c-1.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4c6fdd4fccbec90cc8a01fc00773fcd5fa28db683c116ee3cb35cd5da9ef6c37"}, - {file = "google_crc32c-1.5.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5ae44e10a8e3407dbe138984f21e536583f2bba1be9491239f942c2464ac0894"}, - {file = "google_crc32c-1.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:37933ec6e693e51a5b07505bd05de57eee12f3e8c32b07da7e73669398e6630a"}, - {file = "google_crc32c-1.5.0-cp38-cp38-win32.whl", hash = "sha256:fe70e325aa68fa4b5edf7d1a4b6f691eb04bbccac0ace68e34820d283b5f80d4"}, - {file = "google_crc32c-1.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:74dea7751d98034887dbd821b7aae3e1d36eda111d6ca36c206c44478035709c"}, - {file = "google_crc32c-1.5.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c6c777a480337ac14f38564ac88ae82d4cd238bf293f0a22295b66eb89ffced7"}, - {file = "google_crc32c-1.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:759ce4851a4bb15ecabae28f4d2e18983c244eddd767f560165563bf9aefbc8d"}, - {file = "google_crc32c-1.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f13cae8cc389a440def0c8c52057f37359014ccbc9dc1f0827936bcd367c6100"}, - {file = "google_crc32c-1.5.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e560628513ed34759456a416bf86b54b2476c59144a9138165c9a1575801d0d9"}, - {file = "google_crc32c-1.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1674e4307fa3024fc897ca774e9c7562c957af85df55efe2988ed9056dc4e57"}, - {file = "google_crc32c-1.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:278d2ed7c16cfc075c91378c4f47924c0625f5fc84b2d50d921b18b7975bd210"}, - {file = "google_crc32c-1.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d5280312b9af0976231f9e317c20e4a61cd2f9629b7bfea6a693d1878a264ebd"}, - {file = "google_crc32c-1.5.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:8b87e1a59c38f275c0e3676fc2ab6d59eccecfd460be267ac360cc31f7bcde96"}, - {file = "google_crc32c-1.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7c074fece789b5034b9b1404a1f8208fc2d4c6ce9decdd16e8220c5a793e6f61"}, - {file = "google_crc32c-1.5.0-cp39-cp39-win32.whl", hash = "sha256:7f57f14606cd1dd0f0de396e1e53824c371e9544a822648cd76c034d209b559c"}, - {file = "google_crc32c-1.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:a2355cba1f4ad8b6988a4ca3feed5bff33f6af2d7f134852cf279c2aebfde541"}, - {file = "google_crc32c-1.5.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f314013e7dcd5cf45ab1945d92e713eec788166262ae8deb2cfacd53def27325"}, - {file = "google_crc32c-1.5.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b747a674c20a67343cb61d43fdd9207ce5da6a99f629c6e2541aa0e89215bcd"}, - {file = "google_crc32c-1.5.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8f24ed114432de109aa9fd317278518a5af2d31ac2ea6b952b2f7782b43da091"}, - {file = "google_crc32c-1.5.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8667b48e7a7ef66afba2c81e1094ef526388d35b873966d8a9a447974ed9178"}, - {file = "google_crc32c-1.5.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:1c7abdac90433b09bad6c43a43af253e688c9cfc1c86d332aed13f9a7c7f65e2"}, - {file = "google_crc32c-1.5.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6f998db4e71b645350b9ac28a2167e6632c239963ca9da411523bb439c5c514d"}, - {file = "google_crc32c-1.5.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c99616c853bb585301df6de07ca2cadad344fd1ada6d62bb30aec05219c45d2"}, - {file = "google_crc32c-1.5.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ad40e31093a4af319dadf503b2467ccdc8f67c72e4bcba97f8c10cb078207b5"}, - {file = "google_crc32c-1.5.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd67cf24a553339d5062eff51013780a00d6f97a39ca062781d06b3a73b15462"}, - {file = "google_crc32c-1.5.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:398af5e3ba9cf768787eef45c803ff9614cc3e22a5b2f7d7ae116df8b11e3314"}, - {file = "google_crc32c-1.5.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b1f8133c9a275df5613a451e73f36c2aea4fe13c5c8997e22cf355ebd7bd0728"}, - {file = "google_crc32c-1.5.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ba053c5f50430a3fcfd36f75aff9caeba0440b2d076afdb79a318d6ca245f88"}, - {file = "google_crc32c-1.5.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:272d3892a1e1a2dbc39cc5cde96834c236d5327e2122d3aaa19f6614531bb6eb"}, - {file = "google_crc32c-1.5.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:635f5d4dd18758a1fbd1049a8e8d2fee4ffed124462d837d1a02a0e009c3ab31"}, - {file = "google_crc32c-1.5.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c672d99a345849301784604bfeaeba4db0c7aae50b95be04dd651fd2a7310b93"}, + {file = "google_crc32c-1.6.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:5bcc90b34df28a4b38653c36bb5ada35671ad105c99cfe915fb5bed7ad6924aa"}, + {file = "google_crc32c-1.6.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:d9e9913f7bd69e093b81da4535ce27af842e7bf371cde42d1ae9e9bd382dc0e9"}, + {file = "google_crc32c-1.6.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a184243544811e4a50d345838a883733461e67578959ac59964e43cca2c791e7"}, + {file = "google_crc32c-1.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:236c87a46cdf06384f614e9092b82c05f81bd34b80248021f729396a78e55d7e"}, + {file = "google_crc32c-1.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebab974b1687509e5c973b5c4b8b146683e101e102e17a86bd196ecaa4d099fc"}, + {file = "google_crc32c-1.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:50cf2a96da226dcbff8671233ecf37bf6e95de98b2a2ebadbfdf455e6d05df42"}, + {file = "google_crc32c-1.6.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:f7a1fc29803712f80879b0806cb83ab24ce62fc8daf0569f2204a0cfd7f68ed4"}, + {file = "google_crc32c-1.6.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:40b05ab32a5067525670880eb5d169529089a26fe35dce8891127aeddc1950e8"}, + {file = "google_crc32c-1.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9e4b426c3702f3cd23b933436487eb34e01e00327fac20c9aebb68ccf34117d"}, + {file = "google_crc32c-1.6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51c4f54dd8c6dfeb58d1df5e4f7f97df8abf17a36626a217f169893d1d7f3e9f"}, + {file = "google_crc32c-1.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:bb8b3c75bd157010459b15222c3fd30577042a7060e29d42dabce449c087f2b3"}, + {file = "google_crc32c-1.6.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:ed767bf4ba90104c1216b68111613f0d5926fb3780660ea1198fc469af410e9d"}, + {file = "google_crc32c-1.6.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:62f6d4a29fea082ac4a3c9be5e415218255cf11684ac6ef5488eea0c9132689b"}, + {file = "google_crc32c-1.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c87d98c7c4a69066fd31701c4e10d178a648c2cac3452e62c6b24dc51f9fcc00"}, + {file = "google_crc32c-1.6.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd5e7d2445d1a958c266bfa5d04c39932dc54093fa391736dbfdb0f1929c1fb3"}, + {file = "google_crc32c-1.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:7aec8e88a3583515f9e0957fe4f5f6d8d4997e36d0f61624e70469771584c760"}, + {file = "google_crc32c-1.6.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:e2806553238cd076f0a55bddab37a532b53580e699ed8e5606d0de1f856b5205"}, + {file = "google_crc32c-1.6.0-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:bb0966e1c50d0ef5bc743312cc730b533491d60585a9a08f897274e57c3f70e0"}, + {file = "google_crc32c-1.6.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:386122eeaaa76951a8196310432c5b0ef3b53590ef4c317ec7588ec554fec5d2"}, + {file = "google_crc32c-1.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2952396dc604544ea7476b33fe87faedc24d666fb0c2d5ac971a2b9576ab871"}, + {file = "google_crc32c-1.6.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35834855408429cecf495cac67ccbab802de269e948e27478b1e47dfb6465e57"}, + {file = "google_crc32c-1.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:d8797406499f28b5ef791f339594b0b5fdedf54e203b5066675c406ba69d705c"}, + {file = "google_crc32c-1.6.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48abd62ca76a2cbe034542ed1b6aee851b6f28aaca4e6551b5599b6f3ef175cc"}, + {file = "google_crc32c-1.6.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18e311c64008f1f1379158158bb3f0c8d72635b9eb4f9545f8cf990c5668e59d"}, + {file = "google_crc32c-1.6.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05e2d8c9a2f853ff116db9706b4a27350587f341eda835f46db3c0a8c8ce2f24"}, + {file = "google_crc32c-1.6.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91ca8145b060679ec9176e6de4f89b07363d6805bd4760631ef254905503598d"}, + {file = "google_crc32c-1.6.0.tar.gz", hash = "sha256:6eceb6ad197656a1ff49ebfbbfa870678c75be4344feb35ac1edf694309413dc"}, ] [package.extras] @@ -3300,6 +3357,21 @@ typing-extensions = "*" [package.extras] dev = ["Pillow", "absl-py", "black", "ipython", "nose2", "pandas", "pytype", "pyyaml"] +[[package]] +name = "google-pasta" +version = "0.2.0" +description = "pasta is an AST-based Python refactoring library" +optional = false +python-versions = "*" +files = [ + {file = "google-pasta-0.2.0.tar.gz", hash = "sha256:c9f2c8dfc8f96d0d5808299920721be30c9eec37f2389f28904f454565c8a16e"}, + {file = "google_pasta-0.2.0-py2-none-any.whl", hash = "sha256:4612951da876b1a10fe3960d7226f0c7682cf901e16ac06e473b267a5afa8954"}, + {file = "google_pasta-0.2.0-py3-none-any.whl", hash = "sha256:b32482794a366b5366a32c92a9a9201b107821889935a02b3e51f6b432ea84ed"}, +] + +[package.dependencies] +six = "*" + [[package]] name = "google-resumable-media" version = "2.7.2" @@ -3425,61 +3497,61 @@ protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4 [[package]] name = "grpcio" -version = "1.63.0" +version = "1.66.1" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.8" files = [ - {file = "grpcio-1.63.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:2e93aca840c29d4ab5db93f94ed0a0ca899e241f2e8aec6334ab3575dc46125c"}, - {file = "grpcio-1.63.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:91b73d3f1340fefa1e1716c8c1ec9930c676d6b10a3513ab6c26004cb02d8b3f"}, - {file = "grpcio-1.63.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:b3afbd9d6827fa6f475a4f91db55e441113f6d3eb9b7ebb8fb806e5bb6d6bd0d"}, - {file = "grpcio-1.63.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8f3f6883ce54a7a5f47db43289a0a4c776487912de1a0e2cc83fdaec9685cc9f"}, - {file = "grpcio-1.63.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf8dae9cc0412cb86c8de5a8f3be395c5119a370f3ce2e69c8b7d46bb9872c8d"}, - {file = "grpcio-1.63.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:08e1559fd3b3b4468486b26b0af64a3904a8dbc78d8d936af9c1cf9636eb3e8b"}, - {file = "grpcio-1.63.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5c039ef01516039fa39da8a8a43a95b64e288f79f42a17e6c2904a02a319b357"}, - {file = "grpcio-1.63.0-cp310-cp310-win32.whl", hash = "sha256:ad2ac8903b2eae071055a927ef74121ed52d69468e91d9bcbd028bd0e554be6d"}, - {file = "grpcio-1.63.0-cp310-cp310-win_amd64.whl", hash = "sha256:b2e44f59316716532a993ca2966636df6fbe7be4ab6f099de6815570ebe4383a"}, - {file = "grpcio-1.63.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:f28f8b2db7b86c77916829d64ab21ff49a9d8289ea1564a2b2a3a8ed9ffcccd3"}, - {file = "grpcio-1.63.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:65bf975639a1f93bee63ca60d2e4951f1b543f498d581869922910a476ead2f5"}, - {file = "grpcio-1.63.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:b5194775fec7dc3dbd6a935102bb156cd2c35efe1685b0a46c67b927c74f0cfb"}, - {file = "grpcio-1.63.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e4cbb2100ee46d024c45920d16e888ee5d3cf47c66e316210bc236d5bebc42b3"}, - {file = "grpcio-1.63.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ff737cf29b5b801619f10e59b581869e32f400159e8b12d7a97e7e3bdeee6a2"}, - {file = "grpcio-1.63.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cd1e68776262dd44dedd7381b1a0ad09d9930ffb405f737d64f505eb7f77d6c7"}, - {file = "grpcio-1.63.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:93f45f27f516548e23e4ec3fbab21b060416007dbe768a111fc4611464cc773f"}, - {file = "grpcio-1.63.0-cp311-cp311-win32.whl", hash = "sha256:878b1d88d0137df60e6b09b74cdb73db123f9579232c8456f53e9abc4f62eb3c"}, - {file = "grpcio-1.63.0-cp311-cp311-win_amd64.whl", hash = "sha256:756fed02dacd24e8f488f295a913f250b56b98fb793f41d5b2de6c44fb762434"}, - {file = "grpcio-1.63.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:93a46794cc96c3a674cdfb59ef9ce84d46185fe9421baf2268ccb556f8f81f57"}, - {file = "grpcio-1.63.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a7b19dfc74d0be7032ca1eda0ed545e582ee46cd65c162f9e9fc6b26ef827dc6"}, - {file = "grpcio-1.63.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:8064d986d3a64ba21e498b9a376cbc5d6ab2e8ab0e288d39f266f0fca169b90d"}, - {file = "grpcio-1.63.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:219bb1848cd2c90348c79ed0a6b0ea51866bc7e72fa6e205e459fedab5770172"}, - {file = "grpcio-1.63.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2d60cd1d58817bc5985fae6168d8b5655c4981d448d0f5b6194bbcc038090d2"}, - {file = "grpcio-1.63.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9e350cb096e5c67832e9b6e018cf8a0d2a53b2a958f6251615173165269a91b0"}, - {file = "grpcio-1.63.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:56cdf96ff82e3cc90dbe8bac260352993f23e8e256e063c327b6cf9c88daf7a9"}, - {file = "grpcio-1.63.0-cp312-cp312-win32.whl", hash = "sha256:3a6d1f9ea965e750db7b4ee6f9fdef5fdf135abe8a249e75d84b0a3e0c668a1b"}, - {file = "grpcio-1.63.0-cp312-cp312-win_amd64.whl", hash = "sha256:d2497769895bb03efe3187fb1888fc20e98a5f18b3d14b606167dacda5789434"}, - {file = "grpcio-1.63.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:fdf348ae69c6ff484402cfdb14e18c1b0054ac2420079d575c53a60b9b2853ae"}, - {file = "grpcio-1.63.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a3abfe0b0f6798dedd2e9e92e881d9acd0fdb62ae27dcbbfa7654a57e24060c0"}, - {file = "grpcio-1.63.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:6ef0ad92873672a2a3767cb827b64741c363ebaa27e7f21659e4e31f4d750280"}, - {file = "grpcio-1.63.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b416252ac5588d9dfb8a30a191451adbf534e9ce5f56bb02cd193f12d8845b7f"}, - {file = "grpcio-1.63.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3b77eaefc74d7eb861d3ffbdf91b50a1bb1639514ebe764c47773b833fa2d91"}, - {file = "grpcio-1.63.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b005292369d9c1f80bf70c1db1c17c6c342da7576f1c689e8eee4fb0c256af85"}, - {file = "grpcio-1.63.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cdcda1156dcc41e042d1e899ba1f5c2e9f3cd7625b3d6ebfa619806a4c1aadda"}, - {file = "grpcio-1.63.0-cp38-cp38-win32.whl", hash = "sha256:01799e8649f9e94ba7db1aeb3452188048b0019dc37696b0f5ce212c87c560c3"}, - {file = "grpcio-1.63.0-cp38-cp38-win_amd64.whl", hash = "sha256:6a1a3642d76f887aa4009d92f71eb37809abceb3b7b5a1eec9c554a246f20e3a"}, - {file = "grpcio-1.63.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:75f701ff645858a2b16bc8c9fc68af215a8bb2d5a9b647448129de6e85d52bce"}, - {file = "grpcio-1.63.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cacdef0348a08e475a721967f48206a2254a1b26ee7637638d9e081761a5ba86"}, - {file = "grpcio-1.63.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:0697563d1d84d6985e40ec5ec596ff41b52abb3fd91ec240e8cb44a63b895094"}, - {file = "grpcio-1.63.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6426e1fb92d006e47476d42b8f240c1d916a6d4423c5258ccc5b105e43438f61"}, - {file = "grpcio-1.63.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e48cee31bc5f5a31fb2f3b573764bd563aaa5472342860edcc7039525b53e46a"}, - {file = "grpcio-1.63.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:50344663068041b34a992c19c600236e7abb42d6ec32567916b87b4c8b8833b3"}, - {file = "grpcio-1.63.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:259e11932230d70ef24a21b9fb5bb947eb4703f57865a404054400ee92f42f5d"}, - {file = "grpcio-1.63.0-cp39-cp39-win32.whl", hash = "sha256:a44624aad77bf8ca198c55af811fd28f2b3eaf0a50ec5b57b06c034416ef2d0a"}, - {file = "grpcio-1.63.0-cp39-cp39-win_amd64.whl", hash = "sha256:166e5c460e5d7d4656ff9e63b13e1f6029b122104c1633d5f37eaea348d7356d"}, - {file = "grpcio-1.63.0.tar.gz", hash = "sha256:f3023e14805c61bc439fb40ca545ac3d5740ce66120a678a3c6c2c55b70343d1"}, + {file = "grpcio-1.66.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:4877ba180591acdf127afe21ec1c7ff8a5ecf0fe2600f0d3c50e8c4a1cbc6492"}, + {file = "grpcio-1.66.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:3750c5a00bd644c75f4507f77a804d0189d97a107eb1481945a0cf3af3e7a5ac"}, + {file = "grpcio-1.66.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:a013c5fbb12bfb5f927444b477a26f1080755a931d5d362e6a9a720ca7dbae60"}, + {file = "grpcio-1.66.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b1b24c23d51a1e8790b25514157d43f0a4dce1ac12b3f0b8e9f66a5e2c4c132f"}, + {file = "grpcio-1.66.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7ffb8ea674d68de4cac6f57d2498fef477cef582f1fa849e9f844863af50083"}, + {file = "grpcio-1.66.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:307b1d538140f19ccbd3aed7a93d8f71103c5d525f3c96f8616111614b14bf2a"}, + {file = "grpcio-1.66.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1c17ebcec157cfb8dd445890a03e20caf6209a5bd4ac5b040ae9dbc59eef091d"}, + {file = "grpcio-1.66.1-cp310-cp310-win32.whl", hash = "sha256:ef82d361ed5849d34cf09105d00b94b6728d289d6b9235513cb2fcc79f7c432c"}, + {file = "grpcio-1.66.1-cp310-cp310-win_amd64.whl", hash = "sha256:292a846b92cdcd40ecca46e694997dd6b9be6c4c01a94a0dfb3fcb75d20da858"}, + {file = "grpcio-1.66.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:c30aeceeaff11cd5ddbc348f37c58bcb96da8d5aa93fed78ab329de5f37a0d7a"}, + {file = "grpcio-1.66.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8a1e224ce6f740dbb6b24c58f885422deebd7eb724aff0671a847f8951857c26"}, + {file = "grpcio-1.66.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:a66fe4dc35d2330c185cfbb42959f57ad36f257e0cc4557d11d9f0a3f14311df"}, + {file = "grpcio-1.66.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e3ba04659e4fce609de2658fe4dbf7d6ed21987a94460f5f92df7579fd5d0e22"}, + {file = "grpcio-1.66.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4573608e23f7e091acfbe3e84ac2045680b69751d8d67685ffa193a4429fedb1"}, + {file = "grpcio-1.66.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7e06aa1f764ec8265b19d8f00140b8c4b6ca179a6dc67aa9413867c47e1fb04e"}, + {file = "grpcio-1.66.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3885f037eb11f1cacc41f207b705f38a44b69478086f40608959bf5ad85826dd"}, + {file = "grpcio-1.66.1-cp311-cp311-win32.whl", hash = "sha256:97ae7edd3f3f91480e48ede5d3e7d431ad6005bfdbd65c1b56913799ec79e791"}, + {file = "grpcio-1.66.1-cp311-cp311-win_amd64.whl", hash = "sha256:cfd349de4158d797db2bd82d2020554a121674e98fbe6b15328456b3bf2495bb"}, + {file = "grpcio-1.66.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:a92c4f58c01c77205df6ff999faa008540475c39b835277fb8883b11cada127a"}, + {file = "grpcio-1.66.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:fdb14bad0835914f325349ed34a51940bc2ad965142eb3090081593c6e347be9"}, + {file = "grpcio-1.66.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:f03a5884c56256e08fd9e262e11b5cfacf1af96e2ce78dc095d2c41ccae2c80d"}, + {file = "grpcio-1.66.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ca2559692d8e7e245d456877a85ee41525f3ed425aa97eb7a70fc9a79df91a0"}, + {file = "grpcio-1.66.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84ca1be089fb4446490dd1135828bd42a7c7f8421e74fa581611f7afdf7ab761"}, + {file = "grpcio-1.66.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:d639c939ad7c440c7b2819a28d559179a4508783f7e5b991166f8d7a34b52815"}, + {file = "grpcio-1.66.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b9feb4e5ec8dc2d15709f4d5fc367794d69277f5d680baf1910fc9915c633524"}, + {file = "grpcio-1.66.1-cp312-cp312-win32.whl", hash = "sha256:7101db1bd4cd9b880294dec41a93fcdce465bdbb602cd8dc5bd2d6362b618759"}, + {file = "grpcio-1.66.1-cp312-cp312-win_amd64.whl", hash = "sha256:b0aa03d240b5539648d996cc60438f128c7f46050989e35b25f5c18286c86734"}, + {file = "grpcio-1.66.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:ecfe735e7a59e5a98208447293ff8580e9db1e890e232b8b292dc8bd15afc0d2"}, + {file = "grpcio-1.66.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:4825a3aa5648010842e1c9d35a082187746aa0cdbf1b7a2a930595a94fb10fce"}, + {file = "grpcio-1.66.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:f517fd7259fe823ef3bd21e508b653d5492e706e9f0ef82c16ce3347a8a5620c"}, + {file = "grpcio-1.66.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1fe60d0772831d96d263b53d83fb9a3d050a94b0e94b6d004a5ad111faa5b5b"}, + {file = "grpcio-1.66.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31a049daa428f928f21090403e5d18ea02670e3d5d172581670be006100db9ef"}, + {file = "grpcio-1.66.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6f914386e52cbdeb5d2a7ce3bf1fdfacbe9d818dd81b6099a05b741aaf3848bb"}, + {file = "grpcio-1.66.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bff2096bdba686019fb32d2dde45b95981f0d1490e054400f70fc9a8af34b49d"}, + {file = "grpcio-1.66.1-cp38-cp38-win32.whl", hash = "sha256:aa8ba945c96e73de29d25331b26f3e416e0c0f621e984a3ebdb2d0d0b596a3b3"}, + {file = "grpcio-1.66.1-cp38-cp38-win_amd64.whl", hash = "sha256:161d5c535c2bdf61b95080e7f0f017a1dfcb812bf54093e71e5562b16225b4ce"}, + {file = "grpcio-1.66.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:d0cd7050397b3609ea51727b1811e663ffda8bda39c6a5bb69525ef12414b503"}, + {file = "grpcio-1.66.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0e6c9b42ded5d02b6b1fea3a25f036a2236eeb75d0579bfd43c0018c88bf0a3e"}, + {file = "grpcio-1.66.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:c9f80f9fad93a8cf71c7f161778ba47fd730d13a343a46258065c4deb4b550c0"}, + {file = "grpcio-1.66.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5dd67ed9da78e5121efc5c510f0122a972216808d6de70953a740560c572eb44"}, + {file = "grpcio-1.66.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48b0d92d45ce3be2084b92fb5bae2f64c208fea8ceed7fccf6a7b524d3c4942e"}, + {file = "grpcio-1.66.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4d813316d1a752be6f5c4360c49f55b06d4fe212d7df03253dfdae90c8a402bb"}, + {file = "grpcio-1.66.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9c9bebc6627873ec27a70fc800f6083a13c70b23a5564788754b9ee52c5aef6c"}, + {file = "grpcio-1.66.1-cp39-cp39-win32.whl", hash = "sha256:30a1c2cf9390c894c90bbc70147f2372130ad189cffef161f0432d0157973f45"}, + {file = "grpcio-1.66.1-cp39-cp39-win_amd64.whl", hash = "sha256:17663598aadbedc3cacd7bbde432f541c8e07d2496564e22b214b22c7523dac8"}, + {file = "grpcio-1.66.1.tar.gz", hash = "sha256:35334f9c9745add3e357e3372756fd32d925bd52c41da97f4dfdafbde0bf0ee2"}, ] [package.extras] -protobuf = ["grpcio-tools (>=1.63.0)"] +protobuf = ["grpcio-tools (>=1.66.1)"] [[package]] name = "grpcio-status" @@ -3826,13 +3898,13 @@ test = ["Cython (>=0.29.24,<0.30.0)"] [[package]] name = "httpx" -version = "0.27.0" +version = "0.27.2" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"}, - {file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"}, + {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, + {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, ] [package.dependencies] @@ -3849,6 +3921,7 @@ brotli = ["brotli", "brotlicffi"] cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] +zstd = ["zstandard (>=0.18.0)"] [[package]] name = "huggingface-hub" @@ -3909,33 +3982,33 @@ files = [ [[package]] name = "idna" -version = "3.7" +version = "3.8" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, + {file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"}, + {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"}, ] [[package]] name = "importlib-metadata" -version = "8.0.0" +version = "6.11.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-8.0.0-py3-none-any.whl", hash = "sha256:15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f"}, - {file = "importlib_metadata-8.0.0.tar.gz", hash = "sha256:188bd24e4c346d3f0a933f275c2fec67050326a856b9a359881d7c2a697e8812"}, + {file = "importlib_metadata-6.11.0-py3-none-any.whl", hash = "sha256:f0afba6205ad8f8947c7d338b5342d5db2afbfd82f9cbef7879a9539cc12eb9b"}, + {file = "importlib_metadata-6.11.0.tar.gz", hash = "sha256:1231cf92d825c9e03cfc4da076a16de6422c863558229ea0b22b675657463443"}, ] [package.dependencies] zipp = ">=0.5" [package.extras] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] [[package]] name = "importlib-resources" @@ -4117,115 +4190,125 @@ files = [ [[package]] name = "kiwisolver" -version = "1.4.5" +version = "1.4.7" description = "A fast implementation of the Cassowary constraint solver" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af"}, - {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3"}, - {file = "kiwisolver-1.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b"}, - {file = "kiwisolver-1.4.5-cp310-cp310-win32.whl", hash = "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238"}, - {file = "kiwisolver-1.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276"}, - {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5"}, - {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90"}, - {file = "kiwisolver-1.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f"}, - {file = "kiwisolver-1.4.5-cp311-cp311-win32.whl", hash = "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac"}, - {file = "kiwisolver-1.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355"}, - {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a"}, - {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192"}, - {file = "kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a"}, - {file = "kiwisolver-1.4.5-cp312-cp312-win32.whl", hash = "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20"}, - {file = "kiwisolver-1.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a2b053a0ab7a3960c98725cfb0bf5b48ba82f64ec95fe06f1d06c99b552e130"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd32d6c13807e5c66a7cbb79f90b553642f296ae4518a60d8d76243b0ad2898"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59ec7b7c7e1a61061850d53aaf8e93db63dce0c936db1fda2658b70e4a1be709"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da4cfb373035def307905d05041c1d06d8936452fe89d464743ae7fb8371078b"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2400873bccc260b6ae184b2b8a4fec0e4082d30648eadb7c3d9a13405d861e89"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1b04139c4236a0f3aff534479b58f6f849a8b351e1314826c2d230849ed48985"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4e66e81a5779b65ac21764c295087de82235597a2293d18d943f8e9e32746265"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7931d8f1f67c4be9ba1dd9c451fb0eeca1a25b89e4d3f89e828fe12a519b782a"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b3f7e75f3015df442238cca659f8baa5f42ce2a8582727981cbfa15fee0ee205"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:bbf1d63eef84b2e8c89011b7f2235b1e0bf7dacc11cac9431fc6468e99ac77fb"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4c380469bd3f970ef677bf2bcba2b6b0b4d5c75e7a020fb863ef75084efad66f"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-win32.whl", hash = "sha256:9408acf3270c4b6baad483865191e3e582b638b1654a007c62e3efe96f09a9a3"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-win_amd64.whl", hash = "sha256:5b94529f9b2591b7af5f3e0e730a4e0a41ea174af35a4fd067775f9bdfeee01a"}, - {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:11c7de8f692fc99816e8ac50d1d1aef4f75126eefc33ac79aac02c099fd3db71"}, - {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:53abb58632235cd154176ced1ae8f0d29a6657aa1aa9decf50b899b755bc2b93"}, - {file = "kiwisolver-1.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88b9f257ca61b838b6f8094a62418421f87ac2a1069f7e896c36a7d86b5d4c29"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3195782b26fc03aa9c6913d5bad5aeb864bdc372924c093b0f1cebad603dd712"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc579bf0f502e54926519451b920e875f433aceb4624a3646b3252b5caa9e0b6"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a580c91d686376f0f7c295357595c5a026e6cbc3d77b7c36e290201e7c11ecb"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cfe6ab8da05c01ba6fbea630377b5da2cd9bcbc6338510116b01c1bc939a2c18"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d2e5a98f0ec99beb3c10e13b387f8db39106d53993f498b295f0c914328b1333"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a51a263952b1429e429ff236d2f5a21c5125437861baeed77f5e1cc2d2c7c6da"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3edd2fa14e68c9be82c5b16689e8d63d89fe927e56debd6e1dbce7a26a17f81b"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:74d1b44c6cfc897df648cc9fdaa09bc3e7679926e6f96df05775d4fb3946571c"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:76d9289ed3f7501012e05abb8358bbb129149dbd173f1f57a1bf1c22d19ab7cc"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:92dea1ffe3714fa8eb6a314d2b3c773208d865a0e0d35e713ec54eea08a66250"}, - {file = "kiwisolver-1.4.5-cp38-cp38-win32.whl", hash = "sha256:5c90ae8c8d32e472be041e76f9d2f2dbff4d0b0be8bd4041770eddb18cf49a4e"}, - {file = "kiwisolver-1.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:c7940c1dc63eb37a67721b10d703247552416f719c4188c54e04334321351ced"}, - {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9407b6a5f0d675e8a827ad8742e1d6b49d9c1a1da5d952a67d50ef5f4170b18d"}, - {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15568384086b6df3c65353820a4473575dbad192e35010f622c6ce3eebd57af9"}, - {file = "kiwisolver-1.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0dc9db8e79f0036e8173c466d21ef18e1befc02de8bf8aa8dc0813a6dc8a7046"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cdc8a402aaee9a798b50d8b827d7ecf75edc5fb35ea0f91f213ff927c15f4ff0"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6c3bd3cde54cafb87d74d8db50b909705c62b17c2099b8f2e25b461882e544ff"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:955e8513d07a283056b1396e9a57ceddbd272d9252c14f154d450d227606eb54"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:346f5343b9e3f00b8db8ba359350eb124b98c99efd0b408728ac6ebf38173958"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9098e0049e88c6a24ff64545cdfc50807818ba6c1b739cae221bbbcbc58aad3"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:00bd361b903dc4bbf4eb165f24d1acbee754fce22ded24c3d56eec268658a5cf"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7b8b454bac16428b22560d0a1cf0a09875339cab69df61d7805bf48919415901"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f1d072c2eb0ad60d4c183f3fb44ac6f73fb7a8f16a2694a91f988275cbf352f9"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:31a82d498054cac9f6d0b53d02bb85811185bcb477d4b60144f915f3b3126342"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6512cb89e334e4700febbffaaa52761b65b4f5a3cf33f960213d5656cea36a77"}, - {file = "kiwisolver-1.4.5-cp39-cp39-win32.whl", hash = "sha256:9db8ea4c388fdb0f780fe91346fd438657ea602d58348753d9fb265ce1bca67f"}, - {file = "kiwisolver-1.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:59415f46a37f7f2efeec758353dd2eae1b07640d8ca0f0c42548ec4125492635"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5c7b3b3a728dc6faf3fc372ef24f21d1e3cee2ac3e9596691d746e5a536de920"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:620ced262a86244e2be10a676b646f29c34537d0d9cc8eb26c08f53d98013390"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:378a214a1e3bbf5ac4a8708304318b4f890da88c9e6a07699c4ae7174c09a68d"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf7be1207676ac608a50cd08f102f6742dbfc70e8d60c4db1c6897f62f71523"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ba55dce0a9b8ff59495ddd050a0225d58bd0983d09f87cfe2b6aec4f2c1234e4"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fd32ea360bcbb92d28933fc05ed09bffcb1704ba3fc7942e81db0fd4f81a7892"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7139af55d1688f8b960ee9ad5adafc4ac17c1c473fe07133ac092310d76544"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dced8146011d2bc2e883f9bd68618b8247387f4bbec46d7392b3c3b032640126"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9bf3325c47b11b2e51bca0824ea217c7cd84491d8ac4eefd1e409705ef092bd"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5794cf59533bc3f1b1c821f7206a3617999db9fbefc345360aafe2e067514929"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e368f200bbc2e4f905b8e71eb38b3c04333bddaa6a2464a6355487b02bb7fb09"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5d706eba36b4c4d5bc6c6377bb6568098765e990cfc21ee16d13963fab7b3e7"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85267bd1aa8880a9c88a8cb71e18d3d64d2751a790e6ca6c27b8ccc724bcd5ad"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210ef2c3a1f03272649aff1ef992df2e724748918c4bc2d5a90352849eb40bea"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11d011a7574eb3b82bcc9c1a1d35c1d7075677fdd15de527d91b46bd35e935ee"}, - {file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"}, + {file = "kiwisolver-1.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8a9c83f75223d5e48b0bc9cb1bf2776cf01563e00ade8775ffe13b0b6e1af3a6"}, + {file = "kiwisolver-1.4.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:58370b1ffbd35407444d57057b57da5d6549d2d854fa30249771775c63b5fe17"}, + {file = "kiwisolver-1.4.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aa0abdf853e09aff551db11fce173e2177d00786c688203f52c87ad7fcd91ef9"}, + {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8d53103597a252fb3ab8b5845af04c7a26d5e7ea8122303dd7a021176a87e8b9"}, + {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:88f17c5ffa8e9462fb79f62746428dd57b46eb931698e42e990ad63103f35e6c"}, + {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a9ca9c710d598fd75ee5de59d5bda2684d9db36a9f50b6125eaea3969c2599"}, + {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f4d742cb7af1c28303a51b7a27aaee540e71bb8e24f68c736f6f2ffc82f2bf05"}, + {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e28c7fea2196bf4c2f8d46a0415c77a1c480cc0724722f23d7410ffe9842c407"}, + {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e968b84db54f9d42046cf154e02911e39c0435c9801681e3fc9ce8a3c4130278"}, + {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0c18ec74c0472de033e1bebb2911c3c310eef5649133dd0bedf2a169a1b269e5"}, + {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8f0ea6da6d393d8b2e187e6a5e3fb81f5862010a40c3945e2c6d12ae45cfb2ad"}, + {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:f106407dda69ae456dd1227966bf445b157ccc80ba0dff3802bb63f30b74e895"}, + {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:84ec80df401cfee1457063732d90022f93951944b5b58975d34ab56bb150dfb3"}, + {file = "kiwisolver-1.4.7-cp310-cp310-win32.whl", hash = "sha256:71bb308552200fb2c195e35ef05de12f0c878c07fc91c270eb3d6e41698c3bcc"}, + {file = "kiwisolver-1.4.7-cp310-cp310-win_amd64.whl", hash = "sha256:44756f9fd339de0fb6ee4f8c1696cfd19b2422e0d70b4cefc1cc7f1f64045a8c"}, + {file = "kiwisolver-1.4.7-cp310-cp310-win_arm64.whl", hash = "sha256:78a42513018c41c2ffd262eb676442315cbfe3c44eed82385c2ed043bc63210a"}, + {file = "kiwisolver-1.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d2b0e12a42fb4e72d509fc994713d099cbb15ebf1103545e8a45f14da2dfca54"}, + {file = "kiwisolver-1.4.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2a8781ac3edc42ea4b90bc23e7d37b665d89423818e26eb6df90698aa2287c95"}, + {file = "kiwisolver-1.4.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:46707a10836894b559e04b0fd143e343945c97fd170d69a2d26d640b4e297935"}, + {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef97b8df011141c9b0f6caf23b29379f87dd13183c978a30a3c546d2c47314cb"}, + {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab58c12a2cd0fc769089e6d38466c46d7f76aced0a1f54c77652446733d2d02"}, + {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:803b8e1459341c1bb56d1c5c010406d5edec8a0713a0945851290a7930679b51"}, + {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9a9e8a507420fe35992ee9ecb302dab68550dedc0da9e2880dd88071c5fb052"}, + {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18077b53dc3bb490e330669a99920c5e6a496889ae8c63b58fbc57c3d7f33a18"}, + {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6af936f79086a89b3680a280c47ea90b4df7047b5bdf3aa5c524bbedddb9e545"}, + {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:3abc5b19d24af4b77d1598a585b8a719beb8569a71568b66f4ebe1fb0449460b"}, + {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:933d4de052939d90afbe6e9d5273ae05fb836cc86c15b686edd4b3560cc0ee36"}, + {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:65e720d2ab2b53f1f72fb5da5fb477455905ce2c88aaa671ff0a447c2c80e8e3"}, + {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3bf1ed55088f214ba6427484c59553123fdd9b218a42bbc8c6496d6754b1e523"}, + {file = "kiwisolver-1.4.7-cp311-cp311-win32.whl", hash = "sha256:4c00336b9dd5ad96d0a558fd18a8b6f711b7449acce4c157e7343ba92dd0cf3d"}, + {file = "kiwisolver-1.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:929e294c1ac1e9f615c62a4e4313ca1823ba37326c164ec720a803287c4c499b"}, + {file = "kiwisolver-1.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:e33e8fbd440c917106b237ef1a2f1449dfbb9b6f6e1ce17c94cd6a1e0d438376"}, + {file = "kiwisolver-1.4.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:5360cc32706dab3931f738d3079652d20982511f7c0ac5711483e6eab08efff2"}, + {file = "kiwisolver-1.4.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:942216596dc64ddb25adb215c3c783215b23626f8d84e8eff8d6d45c3f29f75a"}, + {file = "kiwisolver-1.4.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:48b571ecd8bae15702e4f22d3ff6a0f13e54d3d00cd25216d5e7f658242065ee"}, + {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad42ba922c67c5f219097b28fae965e10045ddf145d2928bfac2eb2e17673640"}, + {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:612a10bdae23404a72941a0fc8fa2660c6ea1217c4ce0dbcab8a8f6543ea9e7f"}, + {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e838bba3a3bac0fe06d849d29772eb1afb9745a59710762e4ba3f4cb8424483"}, + {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22f499f6157236c19f4bbbd472fa55b063db77a16cd74d49afe28992dff8c258"}, + {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693902d433cf585133699972b6d7c42a8b9f8f826ebcaf0132ff55200afc599e"}, + {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4e77f2126c3e0b0d055f44513ed349038ac180371ed9b52fe96a32aa071a5107"}, + {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:657a05857bda581c3656bfc3b20e353c232e9193eb167766ad2dc58b56504948"}, + {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4bfa75a048c056a411f9705856abfc872558e33c055d80af6a380e3658766038"}, + {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:34ea1de54beef1c104422d210c47c7d2a4999bdecf42c7b5718fbe59a4cac383"}, + {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:90da3b5f694b85231cf93586dad5e90e2d71b9428f9aad96952c99055582f520"}, + {file = "kiwisolver-1.4.7-cp312-cp312-win32.whl", hash = "sha256:18e0cca3e008e17fe9b164b55735a325140a5a35faad8de92dd80265cd5eb80b"}, + {file = "kiwisolver-1.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:58cb20602b18f86f83a5c87d3ee1c766a79c0d452f8def86d925e6c60fbf7bfb"}, + {file = "kiwisolver-1.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:f5a8b53bdc0b3961f8b6125e198617c40aeed638b387913bf1ce78afb1b0be2a"}, + {file = "kiwisolver-1.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2e6039dcbe79a8e0f044f1c39db1986a1b8071051efba3ee4d74f5b365f5226e"}, + {file = "kiwisolver-1.4.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a1ecf0ac1c518487d9d23b1cd7139a6a65bc460cd101ab01f1be82ecf09794b6"}, + {file = "kiwisolver-1.4.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7ab9ccab2b5bd5702ab0803676a580fffa2aa178c2badc5557a84cc943fcf750"}, + {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f816dd2277f8d63d79f9c8473a79fe54047bc0467754962840782c575522224d"}, + {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf8bcc23ceb5a1b624572a1623b9f79d2c3b337c8c455405ef231933a10da379"}, + {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dea0bf229319828467d7fca8c7c189780aa9ff679c94539eed7532ebe33ed37c"}, + {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c06a4c7cf15ec739ce0e5971b26c93638730090add60e183530d70848ebdd34"}, + {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:913983ad2deb14e66d83c28b632fd35ba2b825031f2fa4ca29675e665dfecbe1"}, + {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5337ec7809bcd0f424c6b705ecf97941c46279cf5ed92311782c7c9c2026f07f"}, + {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c26ed10c4f6fa6ddb329a5120ba3b6db349ca192ae211e882970bfc9d91420b"}, + {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c619b101e6de2222c1fcb0531e1b17bbffbe54294bfba43ea0d411d428618c27"}, + {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:073a36c8273647592ea332e816e75ef8da5c303236ec0167196793eb1e34657a"}, + {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3ce6b2b0231bda412463e152fc18335ba32faf4e8c23a754ad50ffa70e4091ee"}, + {file = "kiwisolver-1.4.7-cp313-cp313-win32.whl", hash = "sha256:f4c9aee212bc89d4e13f58be11a56cc8036cabad119259d12ace14b34476fd07"}, + {file = "kiwisolver-1.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:8a3ec5aa8e38fc4c8af308917ce12c536f1c88452ce554027e55b22cbbfbff76"}, + {file = "kiwisolver-1.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:76c8094ac20ec259471ac53e774623eb62e6e1f56cd8690c67ce6ce4fcb05650"}, + {file = "kiwisolver-1.4.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5d5abf8f8ec1f4e22882273c423e16cae834c36856cac348cfbfa68e01c40f3a"}, + {file = "kiwisolver-1.4.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:aeb3531b196ef6f11776c21674dba836aeea9d5bd1cf630f869e3d90b16cfade"}, + {file = "kiwisolver-1.4.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b7d755065e4e866a8086c9bdada157133ff466476a2ad7861828e17b6026e22c"}, + {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08471d4d86cbaec61f86b217dd938a83d85e03785f51121e791a6e6689a3be95"}, + {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7bbfcb7165ce3d54a3dfbe731e470f65739c4c1f85bb1018ee912bae139e263b"}, + {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d34eb8494bea691a1a450141ebb5385e4b69d38bb8403b5146ad279f4b30fa3"}, + {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9242795d174daa40105c1d86aba618e8eab7bf96ba8c3ee614da8302a9f95503"}, + {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a0f64a48bb81af7450e641e3fe0b0394d7381e342805479178b3d335d60ca7cf"}, + {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8e045731a5416357638d1700927529e2b8ab304811671f665b225f8bf8d8f933"}, + {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:4322872d5772cae7369f8351da1edf255a604ea7087fe295411397d0cfd9655e"}, + {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:e1631290ee9271dffe3062d2634c3ecac02c83890ada077d225e081aca8aab89"}, + {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:edcfc407e4eb17e037bca59be0e85a2031a2ac87e4fed26d3e9df88b4165f92d"}, + {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:4d05d81ecb47d11e7f8932bd8b61b720bf0b41199358f3f5e36d38e28f0532c5"}, + {file = "kiwisolver-1.4.7-cp38-cp38-win32.whl", hash = "sha256:b38ac83d5f04b15e515fd86f312479d950d05ce2368d5413d46c088dda7de90a"}, + {file = "kiwisolver-1.4.7-cp38-cp38-win_amd64.whl", hash = "sha256:d83db7cde68459fc803052a55ace60bea2bae361fc3b7a6d5da07e11954e4b09"}, + {file = "kiwisolver-1.4.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3f9362ecfca44c863569d3d3c033dbe8ba452ff8eed6f6b5806382741a1334bd"}, + {file = "kiwisolver-1.4.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e8df2eb9b2bac43ef8b082e06f750350fbbaf2887534a5be97f6cf07b19d9583"}, + {file = "kiwisolver-1.4.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f32d6edbc638cde7652bd690c3e728b25332acbadd7cad670cc4a02558d9c417"}, + {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e2e6c39bd7b9372b0be21456caab138e8e69cc0fc1190a9dfa92bd45a1e6e904"}, + {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dda56c24d869b1193fcc763f1284b9126550eaf84b88bbc7256e15028f19188a"}, + {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79849239c39b5e1fd906556c474d9b0439ea6792b637511f3fe3a41158d89ca8"}, + {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5e3bc157fed2a4c02ec468de4ecd12a6e22818d4f09cde2c31ee3226ffbefab2"}, + {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3da53da805b71e41053dc670f9a820d1157aae77b6b944e08024d17bcd51ef88"}, + {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8705f17dfeb43139a692298cb6637ee2e59c0194538153e83e9ee0c75c2eddde"}, + {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:82a5c2f4b87c26bb1a0ef3d16b5c4753434633b83d365cc0ddf2770c93829e3c"}, + {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce8be0466f4c0d585cdb6c1e2ed07232221df101a4c6f28821d2aa754ca2d9e2"}, + {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:409afdfe1e2e90e6ee7fc896f3df9a7fec8e793e58bfa0d052c8a82f99c37abb"}, + {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5b9c3f4ee0b9a439d2415012bd1b1cc2df59e4d6a9939f4d669241d30b414327"}, + {file = "kiwisolver-1.4.7-cp39-cp39-win32.whl", hash = "sha256:a79ae34384df2b615eefca647a2873842ac3b596418032bef9a7283675962644"}, + {file = "kiwisolver-1.4.7-cp39-cp39-win_amd64.whl", hash = "sha256:cf0438b42121a66a3a667de17e779330fc0f20b0d97d59d2f2121e182b0505e4"}, + {file = "kiwisolver-1.4.7-cp39-cp39-win_arm64.whl", hash = "sha256:764202cc7e70f767dab49e8df52c7455e8de0df5d858fa801a11aa0d882ccf3f"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:94252291e3fe68001b1dd747b4c0b3be12582839b95ad4d1b641924d68fd4643"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5b7dfa3b546da08a9f622bb6becdb14b3e24aaa30adba66749d38f3cc7ea9706"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd3de6481f4ed8b734da5df134cd5a6a64fe32124fe83dde1e5b5f29fe30b1e6"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a91b5f9f1205845d488c928e8570dcb62b893372f63b8b6e98b863ebd2368ff2"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40fa14dbd66b8b8f470d5fc79c089a66185619d31645f9b0773b88b19f7223c4"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:eb542fe7933aa09d8d8f9d9097ef37532a7df6497819d16efe4359890a2f417a"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bfa1acfa0c54932d5607e19a2c24646fb4c1ae2694437789129cf099789a3b00"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:eee3ea935c3d227d49b4eb85660ff631556841f6e567f0f7bda972df6c2c9935"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f3160309af4396e0ed04db259c3ccbfdc3621b5559b5453075e5de555e1f3a1b"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a17f6a29cf8935e587cc8a4dbfc8368c55edc645283db0ce9801016f83526c2d"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10849fb2c1ecbfae45a693c070e0320a91b35dd4bcf58172c023b994283a124d"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:ac542bf38a8a4be2dc6b15248d36315ccc65f0743f7b1a76688ffb6b5129a5c2"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8b01aac285f91ca889c800042c35ad3b239e704b150cfd3382adfc9dcc780e39"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:48be928f59a1f5c8207154f935334d374e79f2b5d212826307d072595ad76a2e"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f37cfe618a117e50d8c240555331160d73d0411422b59b5ee217843d7b693608"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:599b5c873c63a1f6ed7eead644a8a380cfbdf5db91dcb6f85707aaab213b1674"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:801fa7802e5cfabe3ab0c81a34c323a319b097dfb5004be950482d882f3d7225"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:0c6c43471bc764fad4bc99c5c2d6d16a676b1abf844ca7c8702bdae92df01ee0"}, + {file = "kiwisolver-1.4.7.tar.gz", hash = "sha256:9893ff81bd7107f7b685d3017cc6583daadb4fc26e4a888350df530e41980a60"}, ] [[package]] @@ -4302,13 +4385,13 @@ six = "*" [[package]] name = "langfuse" -version = "2.44.0" +version = "2.46.3" description = "A client library for accessing langfuse" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langfuse-2.44.0-py3-none-any.whl", hash = "sha256:adb73400a6ad6d597cc95c31381c82f81face3d5fb69391181f224a26f7e8562"}, - {file = "langfuse-2.44.0.tar.gz", hash = "sha256:dfa5378ff7022ae9fe5b8b842c0365347c98f9ef2b772dcee6a93a45442de28c"}, + {file = "langfuse-2.46.3-py3-none-any.whl", hash = "sha256:59dcca4b13ea5f5c7f5a9344266116c3b8b998ae63274e4e9d0dabb51a47d361"}, + {file = "langfuse-2.46.3.tar.gz", hash = "sha256:a68c2dba630f53ccd473205164082ac1b29a1cbdb73500004daee72b5b522624"}, ] [package.dependencies] @@ -4316,7 +4399,7 @@ anyio = ">=4.4.0,<5.0.0" backoff = ">=1.10.0" httpx = ">=0.15.4,<1.0" idna = ">=3.7,<4.0" -packaging = ">=23.2,<24.0" +packaging = ">=23.2,<25.0" pydantic = ">=1.10.7,<3.0" wrapt = ">=1.14,<2.0" @@ -4327,13 +4410,13 @@ openai = ["openai (>=0.27.8)"] [[package]] name = "langsmith" -version = "0.1.101" +version = "0.1.115" 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.101-py3-none-any.whl", hash = "sha256:572e2c90709cda1ad837ac86cedda7295f69933f2124c658a92a35fb890477cc"}, - {file = "langsmith-0.1.101.tar.gz", hash = "sha256:caf4d95f314bb6cd3c4e0632eed821fd5cd5d0f18cb824772fce6d7a9113895b"}, + {file = "langsmith-0.1.115-py3-none-any.whl", hash = "sha256:04e35cfd4c2d4ff1ea10bb577ff43957b05ebb3d9eb4e06e200701f4a2b4ac9f"}, + {file = "langsmith-0.1.115.tar.gz", hash = "sha256:3b775377d858d32354f3ee0dd1ed637068cfe9a1f13e7b3bfa82db1615cdffc9"}, ] [package.dependencies] @@ -4909,6 +4992,22 @@ files = [ [package.extras] test = ["mypy (>=1.0)", "pytest (>=7.0.0)"] +[[package]] +name = "mock" +version = "4.0.3" +description = "Rolling backport of unittest.mock for all Pythons" +optional = false +python-versions = ">=3.6" +files = [ + {file = "mock-4.0.3-py3-none-any.whl", hash = "sha256:122fcb64ee37cfad5b3f48d7a7d51875d7031aaf3d8be7c42e2bee25044eee62"}, + {file = "mock-4.0.3.tar.gz", hash = "sha256:7d3fbbde18228f4ff2f1f119a45cdffa458b4c0dee32eb4d2bb2f82554bac7bc"}, +] + +[package.extras] +build = ["blurb", "twine", "wheel"] +docs = ["sphinx"] +test = ["pytest (<5.4)", "pytest-cov"] + [[package]] name = "monotonic" version = "1.6" @@ -5108,6 +5207,30 @@ files = [ {file = "multidict-6.0.5.tar.gz", hash = "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da"}, ] +[[package]] +name = "multiprocess" +version = "0.70.16" +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"}, +] + +[package.dependencies] +dill = ">=0.3.8" + [[package]] name = "multitasking" version = "0.0.11" @@ -5333,6 +5456,25 @@ rsa = ["cryptography (>=3.0.0)"] signals = ["blinker (>=1.4.0)"] signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] +[[package]] +name = "oci" +version = "2.133.0" +description = "Oracle Cloud Infrastructure Python SDK" +optional = false +python-versions = "*" +files = [ + {file = "oci-2.133.0-py3-none-any.whl", hash = "sha256:9706365481ca538c89b3a15e6b5c246801eccb06be831a7f21c40f2a2ee310a7"}, + {file = "oci-2.133.0.tar.gz", hash = "sha256:800418025bb98f587c65bbf89c6b6d61ef0f2249e0698d73439baf3251640b7f"}, +] + +[package.dependencies] +certifi = "*" +circuitbreaker = {version = ">=1.3.1,<3.0.0", markers = "python_version >= \"3.7\""} +cryptography = ">=3.2.1,<43.0.0" +pyOpenSSL = ">=17.5.0,<25.0.0" +python-dateutil = ">=2.5.3,<3.0.0" +pytz = ">=2016.10" + [[package]] name = "odfpy" version = "1.4.1" @@ -5362,36 +5504,36 @@ tests = ["pytest", "pytest-cov"] [[package]] name = "onnxruntime" -version = "1.19.0" +version = "1.19.2" description = "ONNX Runtime is a runtime accelerator for Machine Learning models" optional = false python-versions = "*" files = [ - {file = "onnxruntime-1.19.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:6ce22a98dfec7b646ae305f52d0ce14a189a758b02ea501860ca719f4b0ae04b"}, - {file = "onnxruntime-1.19.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:19019c72873f26927aa322c54cf2bf7312b23451b27451f39b88f57016c94f8b"}, - {file = "onnxruntime-1.19.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8eaa16df99171dc636e30108d15597aed8c4c2dd9dbfdd07cc464d57d73fb275"}, - {file = "onnxruntime-1.19.0-cp310-cp310-win32.whl", hash = "sha256:0eb0f8dbe596fd0f4737fe511fdbb17603853a7d204c5b2ca38d3c7808fc556b"}, - {file = "onnxruntime-1.19.0-cp310-cp310-win_amd64.whl", hash = "sha256:616092d54ba8023b7bc0a5f6d900a07a37cc1cfcc631873c15f8c1d6e9e184d4"}, - {file = "onnxruntime-1.19.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:a2b53b3c287cd933e5eb597273926e899082d8c84ab96e1b34035764a1627e17"}, - {file = "onnxruntime-1.19.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e94984663963e74fbb468bde9ec6f19dcf890b594b35e249c4dc8789d08993c5"}, - {file = "onnxruntime-1.19.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f379d1f050cfb55ce015d53727b78ee362febc065c38eed81512b22b757da73"}, - {file = "onnxruntime-1.19.0-cp311-cp311-win32.whl", hash = "sha256:4ccb48faea02503275ae7e79e351434fc43c294c4cb5c4d8bcb7479061396614"}, - {file = "onnxruntime-1.19.0-cp311-cp311-win_amd64.whl", hash = "sha256:9cdc8d311289a84e77722de68bd22b8adfb94eea26f4be6f9e017350faac8b18"}, - {file = "onnxruntime-1.19.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:1b59eaec1be9a8613c5fdeaafe67f73a062edce3ac03bbbdc9e2d98b58a30617"}, - {file = "onnxruntime-1.19.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be4144d014a4b25184e63ce7a463a2e7796e2f3df931fccc6a6aefa6f1365dc5"}, - {file = "onnxruntime-1.19.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:10d7e7d4ca7021ce7f29a66dbc6071addf2de5839135339bd855c6d9c2bba371"}, - {file = "onnxruntime-1.19.0-cp312-cp312-win32.whl", hash = "sha256:87f2c58b577a1fb31dc5d92b647ecc588fd5f1ea0c3ad4526f5f80a113357c8d"}, - {file = "onnxruntime-1.19.0-cp312-cp312-win_amd64.whl", hash = "sha256:8a1f50d49676d7b69566536ff039d9e4e95fc482a55673719f46528218ecbb94"}, - {file = "onnxruntime-1.19.0-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:71423c8c4b2d7a58956271534302ec72721c62a41efd0c4896343249b8399ab0"}, - {file = "onnxruntime-1.19.0-cp38-cp38-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9d63630d45e9498f96e75bbeb7fd4a56acb10155de0de4d0e18d1b6cbb0b358a"}, - {file = "onnxruntime-1.19.0-cp38-cp38-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3bfd15db1e8794d379a86c1a9116889f47f2cca40cc82208fc4f7e8c38e8522"}, - {file = "onnxruntime-1.19.0-cp38-cp38-win32.whl", hash = "sha256:3b098003b6b4cb37cc84942e5f1fe27f945dd857cbd2829c824c26b0ba4a247e"}, - {file = "onnxruntime-1.19.0-cp38-cp38-win_amd64.whl", hash = "sha256:cea067a6541d6787d903ee6843401c5b1332a266585160d9700f9f0939443886"}, - {file = "onnxruntime-1.19.0-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:c4fcff12dc5ca963c5f76b9822bb404578fa4a98c281e8c666b429192799a099"}, - {file = "onnxruntime-1.19.0-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f6dcad8a4db908fbe70b98c79cea1c8b6ac3316adf4ce93453136e33a524ac59"}, - {file = "onnxruntime-1.19.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4bc449907c6e8d99eee5ae5cc9c8fdef273d801dcd195393d3f9ab8ad3f49522"}, - {file = "onnxruntime-1.19.0-cp39-cp39-win32.whl", hash = "sha256:947febd48405afcf526e45ccff97ff23b15e530434705f734870d22ae7fcf236"}, - {file = "onnxruntime-1.19.0-cp39-cp39-win_amd64.whl", hash = "sha256:f60be47eff5ee77fd28a466b0fd41d7debc42a32179d1ddb21e05d6067d7b48b"}, + {file = "onnxruntime-1.19.2-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:84fa57369c06cadd3c2a538ae2a26d76d583e7c34bdecd5769d71ca5c0fc750e"}, + {file = "onnxruntime-1.19.2-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bdc471a66df0c1cdef774accef69e9f2ca168c851ab5e4f2f3341512c7ef4666"}, + {file = "onnxruntime-1.19.2-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e3a4ce906105d99ebbe817f536d50a91ed8a4d1592553f49b3c23c4be2560ae6"}, + {file = "onnxruntime-1.19.2-cp310-cp310-win32.whl", hash = "sha256:4b3d723cc154c8ddeb9f6d0a8c0d6243774c6b5930847cc83170bfe4678fafb3"}, + {file = "onnxruntime-1.19.2-cp310-cp310-win_amd64.whl", hash = "sha256:17ed7382d2c58d4b7354fb2b301ff30b9bf308a1c7eac9546449cd122d21cae5"}, + {file = "onnxruntime-1.19.2-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:d863e8acdc7232d705d49e41087e10b274c42f09e259016a46f32c34e06dc4fd"}, + {file = "onnxruntime-1.19.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c1dfe4f660a71b31caa81fc298a25f9612815215a47b286236e61d540350d7b6"}, + {file = "onnxruntime-1.19.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a36511dc07c5c964b916697e42e366fa43c48cdb3d3503578d78cef30417cb84"}, + {file = "onnxruntime-1.19.2-cp311-cp311-win32.whl", hash = "sha256:50cbb8dc69d6befad4746a69760e5b00cc3ff0a59c6c3fb27f8afa20e2cab7e7"}, + {file = "onnxruntime-1.19.2-cp311-cp311-win_amd64.whl", hash = "sha256:1c3e5d415b78337fa0b1b75291e9ea9fb2a4c1f148eb5811e7212fed02cfffa8"}, + {file = "onnxruntime-1.19.2-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:68e7051bef9cfefcbb858d2d2646536829894d72a4130c24019219442b1dd2ed"}, + {file = "onnxruntime-1.19.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d2d366fbcc205ce68a8a3bde2185fd15c604d9645888703785b61ef174265168"}, + {file = "onnxruntime-1.19.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:477b93df4db467e9cbf34051662a4b27c18e131fa1836e05974eae0d6e4cf29b"}, + {file = "onnxruntime-1.19.2-cp312-cp312-win32.whl", hash = "sha256:9a174073dc5608fad05f7cf7f320b52e8035e73d80b0a23c80f840e5a97c0147"}, + {file = "onnxruntime-1.19.2-cp312-cp312-win_amd64.whl", hash = "sha256:190103273ea4507638ffc31d66a980594b237874b65379e273125150eb044857"}, + {file = "onnxruntime-1.19.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:636bc1d4cc051d40bc52e1f9da87fbb9c57d9d47164695dfb1c41646ea51ea66"}, + {file = "onnxruntime-1.19.2-cp38-cp38-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5bd8b875757ea941cbcfe01582970cc299893d1b65bd56731e326a8333f638a3"}, + {file = "onnxruntime-1.19.2-cp38-cp38-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b2046fc9560f97947bbc1acbe4c6d48585ef0f12742744307d3364b131ac5778"}, + {file = "onnxruntime-1.19.2-cp38-cp38-win32.whl", hash = "sha256:31c12840b1cde4ac1f7d27d540c44e13e34f2345cf3642762d2a3333621abb6a"}, + {file = "onnxruntime-1.19.2-cp38-cp38-win_amd64.whl", hash = "sha256:016229660adea180e9a32ce218b95f8f84860a200f0f13b50070d7d90e92956c"}, + {file = "onnxruntime-1.19.2-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:006c8d326835c017a9e9f74c9c77ebb570a71174a1e89fe078b29a557d9c3848"}, + {file = "onnxruntime-1.19.2-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df2a94179a42d530b936f154615b54748239c2908ee44f0d722cb4df10670f68"}, + {file = "onnxruntime-1.19.2-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fae4b4de45894b9ce7ae418c5484cbf0341db6813effec01bb2216091c52f7fb"}, + {file = "onnxruntime-1.19.2-cp39-cp39-win32.whl", hash = "sha256:dc5430f473e8706fff837ae01323be9dcfddd3ea471c900a91fa7c9b807ec5d3"}, + {file = "onnxruntime-1.19.2-cp39-cp39-win_amd64.whl", hash = "sha256:38475e29a95c5f6c62c2c603d69fc7d4c6ccbf4df602bd567b86ae1138881c49"}, ] [package.dependencies] @@ -5524,42 +5666,42 @@ kerberos = ["requests-kerberos"] [[package]] name = "opentelemetry-api" -version = "1.26.0" +version = "1.27.0" description = "OpenTelemetry Python API" optional = false python-versions = ">=3.8" files = [ - {file = "opentelemetry_api-1.26.0-py3-none-any.whl", hash = "sha256:7d7ea33adf2ceda2dd680b18b1677e4152000b37ca76e679da71ff103b943064"}, - {file = "opentelemetry_api-1.26.0.tar.gz", hash = "sha256:2bd639e4bed5b18486fef0b5a520aaffde5a18fc225e808a1ac4df363f43a1ce"}, + {file = "opentelemetry_api-1.27.0-py3-none-any.whl", hash = "sha256:953d5871815e7c30c81b56d910c707588000fff7a3ca1c73e6531911d53065e7"}, + {file = "opentelemetry_api-1.27.0.tar.gz", hash = "sha256:ed673583eaa5f81b5ce5e86ef7cdaf622f88ef65f0b9aab40b843dcae5bef342"}, ] [package.dependencies] deprecated = ">=1.2.6" -importlib-metadata = ">=6.0,<=8.0.0" +importlib-metadata = ">=6.0,<=8.4.0" [[package]] name = "opentelemetry-exporter-otlp-proto-common" -version = "1.26.0" +version = "1.27.0" description = "OpenTelemetry Protobuf encoding" optional = false python-versions = ">=3.8" files = [ - {file = "opentelemetry_exporter_otlp_proto_common-1.26.0-py3-none-any.whl", hash = "sha256:ee4d8f8891a1b9c372abf8d109409e5b81947cf66423fd998e56880057afbc71"}, - {file = "opentelemetry_exporter_otlp_proto_common-1.26.0.tar.gz", hash = "sha256:bdbe50e2e22a1c71acaa0c8ba6efaadd58882e5a5978737a44a4c4b10d304c92"}, + {file = "opentelemetry_exporter_otlp_proto_common-1.27.0-py3-none-any.whl", hash = "sha256:675db7fffcb60946f3a5c43e17d1168a3307a94a930ecf8d2ea1f286f3d4f79a"}, + {file = "opentelemetry_exporter_otlp_proto_common-1.27.0.tar.gz", hash = "sha256:159d27cf49f359e3798c4c3eb8da6ef4020e292571bd8c5604a2a573231dd5c8"}, ] [package.dependencies] -opentelemetry-proto = "1.26.0" +opentelemetry-proto = "1.27.0" [[package]] name = "opentelemetry-exporter-otlp-proto-grpc" -version = "1.26.0" +version = "1.27.0" description = "OpenTelemetry Collector Protobuf over gRPC Exporter" optional = false python-versions = ">=3.8" files = [ - {file = "opentelemetry_exporter_otlp_proto_grpc-1.26.0-py3-none-any.whl", hash = "sha256:e2be5eff72ebcb010675b818e8d7c2e7d61ec451755b8de67a140bc49b9b0280"}, - {file = "opentelemetry_exporter_otlp_proto_grpc-1.26.0.tar.gz", hash = "sha256:a65b67a9a6b06ba1ec406114568e21afe88c1cdb29c464f2507d529eb906d8ae"}, + {file = "opentelemetry_exporter_otlp_proto_grpc-1.27.0-py3-none-any.whl", hash = "sha256:56b5bbd5d61aab05e300d9d62a6b3c134827bbd28d0b12f2649c2da368006c9e"}, + {file = "opentelemetry_exporter_otlp_proto_grpc-1.27.0.tar.gz", hash = "sha256:af6f72f76bcf425dfb5ad11c1a6d6eca2863b91e63575f89bb7b4b55099d968f"}, ] [package.dependencies] @@ -5567,19 +5709,19 @@ deprecated = ">=1.2.6" googleapis-common-protos = ">=1.52,<2.0" grpcio = ">=1.0.0,<2.0.0" opentelemetry-api = ">=1.15,<2.0" -opentelemetry-exporter-otlp-proto-common = "1.26.0" -opentelemetry-proto = "1.26.0" -opentelemetry-sdk = ">=1.26.0,<1.27.0" +opentelemetry-exporter-otlp-proto-common = "1.27.0" +opentelemetry-proto = "1.27.0" +opentelemetry-sdk = ">=1.27.0,<1.28.0" [[package]] name = "opentelemetry-instrumentation" -version = "0.47b0" +version = "0.48b0" description = "Instrumentation Tools & Auto Instrumentation for OpenTelemetry Python" optional = false python-versions = ">=3.8" files = [ - {file = "opentelemetry_instrumentation-0.47b0-py3-none-any.whl", hash = "sha256:88974ee52b1db08fc298334b51c19d47e53099c33740e48c4f084bd1afd052d5"}, - {file = "opentelemetry_instrumentation-0.47b0.tar.gz", hash = "sha256:96f9885e450c35e3f16a4f33145f2ebf620aea910c9fd74a392bbc0f807a350f"}, + {file = "opentelemetry_instrumentation-0.48b0-py3-none-any.whl", hash = "sha256:a69750dc4ba6a5c3eb67986a337185a25b739966d80479befe37b546fc870b44"}, + {file = "opentelemetry_instrumentation-0.48b0.tar.gz", hash = "sha256:94929685d906380743a71c3970f76b5f07476eea1834abd5dd9d17abfe23cc35"}, ] [package.dependencies] @@ -5589,55 +5731,55 @@ wrapt = ">=1.0.0,<2.0.0" [[package]] name = "opentelemetry-instrumentation-asgi" -version = "0.47b0" +version = "0.48b0" description = "ASGI instrumentation for OpenTelemetry" optional = false python-versions = ">=3.8" files = [ - {file = "opentelemetry_instrumentation_asgi-0.47b0-py3-none-any.whl", hash = "sha256:b798dc4957b3edc9dfecb47a4c05809036a4b762234c5071212fda39ead80ade"}, - {file = "opentelemetry_instrumentation_asgi-0.47b0.tar.gz", hash = "sha256:e78b7822c1bca0511e5e9610ec484b8994a81670375e570c76f06f69af7c506a"}, + {file = "opentelemetry_instrumentation_asgi-0.48b0-py3-none-any.whl", hash = "sha256:ddb1b5fc800ae66e85a4e2eca4d9ecd66367a8c7b556169d9e7b57e10676e44d"}, + {file = "opentelemetry_instrumentation_asgi-0.48b0.tar.gz", hash = "sha256:04c32174b23c7fa72ddfe192dad874954968a6a924608079af9952964ecdf785"}, ] [package.dependencies] asgiref = ">=3.0,<4.0" opentelemetry-api = ">=1.12,<2.0" -opentelemetry-instrumentation = "0.47b0" -opentelemetry-semantic-conventions = "0.47b0" -opentelemetry-util-http = "0.47b0" +opentelemetry-instrumentation = "0.48b0" +opentelemetry-semantic-conventions = "0.48b0" +opentelemetry-util-http = "0.48b0" [package.extras] instruments = ["asgiref (>=3.0,<4.0)"] [[package]] name = "opentelemetry-instrumentation-fastapi" -version = "0.47b0" +version = "0.48b0" description = "OpenTelemetry FastAPI Instrumentation" optional = false python-versions = ">=3.8" files = [ - {file = "opentelemetry_instrumentation_fastapi-0.47b0-py3-none-any.whl", hash = "sha256:5ac28dd401160b02e4f544a85a9e4f61a8cbe5b077ea0379d411615376a2bd21"}, - {file = "opentelemetry_instrumentation_fastapi-0.47b0.tar.gz", hash = "sha256:0c7c10b5d971e99a420678ffd16c5b1ea4f0db3b31b62faf305fbb03b4ebee36"}, + {file = "opentelemetry_instrumentation_fastapi-0.48b0-py3-none-any.whl", hash = "sha256:afeb820a59e139d3e5d96619600f11ce0187658b8ae9e3480857dd790bc024f2"}, + {file = "opentelemetry_instrumentation_fastapi-0.48b0.tar.gz", hash = "sha256:21a72563ea412c0b535815aeed75fc580240f1f02ebc72381cfab672648637a2"}, ] [package.dependencies] opentelemetry-api = ">=1.12,<2.0" -opentelemetry-instrumentation = "0.47b0" -opentelemetry-instrumentation-asgi = "0.47b0" -opentelemetry-semantic-conventions = "0.47b0" -opentelemetry-util-http = "0.47b0" +opentelemetry-instrumentation = "0.48b0" +opentelemetry-instrumentation-asgi = "0.48b0" +opentelemetry-semantic-conventions = "0.48b0" +opentelemetry-util-http = "0.48b0" [package.extras] -instruments = ["fastapi (>=0.58,<1.0)", "fastapi-slim (>=0.111.0,<0.112.0)"] +instruments = ["fastapi (>=0.58,<1.0)"] [[package]] name = "opentelemetry-proto" -version = "1.26.0" +version = "1.27.0" description = "OpenTelemetry Python Proto" optional = false python-versions = ">=3.8" files = [ - {file = "opentelemetry_proto-1.26.0-py3-none-any.whl", hash = "sha256:6c4d7b4d4d9c88543bcf8c28ae3f8f0448a753dc291c18c5390444c90b76a725"}, - {file = "opentelemetry_proto-1.26.0.tar.gz", hash = "sha256:c5c18796c0cab3751fc3b98dee53855835e90c0422924b484432ac852d93dc1e"}, + {file = "opentelemetry_proto-1.27.0-py3-none-any.whl", hash = "sha256:b133873de5581a50063e1e4b29cdcf0c5e253a8c2d8dc1229add20a4c3830ace"}, + {file = "opentelemetry_proto-1.27.0.tar.gz", hash = "sha256:33c9345d91dafd8a74fc3d7576c5a38f18b7fdf8d02983ac67485386132aedd6"}, ] [package.dependencies] @@ -5645,44 +5787,44 @@ protobuf = ">=3.19,<5.0" [[package]] name = "opentelemetry-sdk" -version = "1.26.0" +version = "1.27.0" description = "OpenTelemetry Python SDK" optional = false python-versions = ">=3.8" files = [ - {file = "opentelemetry_sdk-1.26.0-py3-none-any.whl", hash = "sha256:feb5056a84a88670c041ea0ded9921fca559efec03905dddeb3885525e0af897"}, - {file = "opentelemetry_sdk-1.26.0.tar.gz", hash = "sha256:c90d2868f8805619535c05562d699e2f4fb1f00dbd55a86dcefca4da6fa02f85"}, + {file = "opentelemetry_sdk-1.27.0-py3-none-any.whl", hash = "sha256:365f5e32f920faf0fd9e14fdfd92c086e317eaa5f860edba9cdc17a380d9197d"}, + {file = "opentelemetry_sdk-1.27.0.tar.gz", hash = "sha256:d525017dea0ccce9ba4e0245100ec46ecdc043f2d7b8315d56b19aff0904fa6f"}, ] [package.dependencies] -opentelemetry-api = "1.26.0" -opentelemetry-semantic-conventions = "0.47b0" +opentelemetry-api = "1.27.0" +opentelemetry-semantic-conventions = "0.48b0" typing-extensions = ">=3.7.4" [[package]] name = "opentelemetry-semantic-conventions" -version = "0.47b0" +version = "0.48b0" description = "OpenTelemetry Semantic Conventions" optional = false python-versions = ">=3.8" files = [ - {file = "opentelemetry_semantic_conventions-0.47b0-py3-none-any.whl", hash = "sha256:4ff9d595b85a59c1c1413f02bba320ce7ea6bf9e2ead2b0913c4395c7bbc1063"}, - {file = "opentelemetry_semantic_conventions-0.47b0.tar.gz", hash = "sha256:a8d57999bbe3495ffd4d510de26a97dadc1dace53e0275001b2c1b2f67992a7e"}, + {file = "opentelemetry_semantic_conventions-0.48b0-py3-none-any.whl", hash = "sha256:a0de9f45c413a8669788a38569c7e0a11ce6ce97861a628cca785deecdc32a1f"}, + {file = "opentelemetry_semantic_conventions-0.48b0.tar.gz", hash = "sha256:12d74983783b6878162208be57c9effcb89dc88691c64992d70bb89dc00daa1a"}, ] [package.dependencies] deprecated = ">=1.2.6" -opentelemetry-api = "1.26.0" +opentelemetry-api = "1.27.0" [[package]] name = "opentelemetry-util-http" -version = "0.47b0" +version = "0.48b0" description = "Web util for OpenTelemetry" optional = false python-versions = ">=3.8" files = [ - {file = "opentelemetry_util_http-0.47b0-py3-none-any.whl", hash = "sha256:3d3215e09c4a723b12da6d0233a31395aeb2bb33a64d7b15a1500690ba250f19"}, - {file = "opentelemetry_util_http-0.47b0.tar.gz", hash = "sha256:352a07664c18eef827eb8ddcbd64c64a7284a39dd1655e2f16f577eb046ccb32"}, + {file = "opentelemetry_util_http-0.48b0-py3-none-any.whl", hash = "sha256:76f598af93aab50328d2a69c786beaedc8b6a7770f7a818cc307eb353debfffb"}, + {file = "opentelemetry_util_http-0.48b0.tar.gz", hash = "sha256:60312015153580cc20f322e5cdc3d3ecad80a71743235bdb77716e742814623c"}, ] [[package]] @@ -5825,13 +5967,13 @@ files = [ [[package]] name = "packaging" -version = "23.2" +version = "24.1" description = "Core utilities for Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] [[package]] @@ -5916,6 +6058,23 @@ sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-d test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] xml = ["lxml (>=4.9.2)"] +[[package]] +name = "pathos" +version = "0.3.2" +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"}, +] + +[package.dependencies] +dill = ">=0.3.8" +multiprocess = ">=0.70.16" +pox = ">=0.3.4" +ppft = ">=1.7.6.8" + [[package]] name = "peewee" version = "3.17.6" @@ -6076,13 +6235,13 @@ type = ["mypy (>=1.8)"] [[package]] name = "plotly" -version = "5.23.0" +version = "5.24.0" description = "An open-source, interactive data visualization library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "plotly-5.23.0-py3-none-any.whl", hash = "sha256:76cbe78f75eddc10c56f5a4ee3e7ccaade7c0a57465546f02098c0caed6c2d1a"}, - {file = "plotly-5.23.0.tar.gz", hash = "sha256:89e57d003a116303a34de6700862391367dd564222ab71f8531df70279fc0193"}, + {file = "plotly-5.24.0-py3-none-any.whl", hash = "sha256:0e54efe52c8cef899f7daa41be9ed97dfb6be622613a2a8f56a86a0634b2b67e"}, + {file = "plotly-5.24.0.tar.gz", hash = "sha256:eae9f4f54448682442c92c1e97148e3ad0c52f0cf86306e1b76daba24add554a"}, ] [package.dependencies] @@ -6136,13 +6295,13 @@ tests = ["pytest (>=5.4.1)", "pytest-cov (>=2.8.1)", "pytest-mypy (>=0.8.0)", "p [[package]] name = "posthog" -version = "3.5.2" +version = "3.6.3" description = "Integrate PostHog into any python application." optional = false python-versions = "*" files = [ - {file = "posthog-3.5.2-py2.py3-none-any.whl", hash = "sha256:605b3d92369971cc99290b1fcc8534cbddac3726ef7972caa993454a5ecfb644"}, - {file = "posthog-3.5.2.tar.gz", hash = "sha256:a383a80c1f47e0243f5ce359e81e06e2e7b37eb39d1d6f8d01c3e64ed29df2ee"}, + {file = "posthog-3.6.3-py2.py3-none-any.whl", hash = "sha256:cdd6c5d8919fd6158bbc4103bccc7129c712d8104dc33828be02bada7b6320a4"}, + {file = "posthog-3.6.3.tar.gz", hash = "sha256:6e1104a20638eab2b5d9cde6b6202a2900d67436237b3ac3521614ec17686701"}, ] [package.dependencies] @@ -6155,7 +6314,32 @@ six = ">=1.5" [package.extras] dev = ["black", "flake8", "flake8-print", "isort", "pre-commit"] sentry = ["django", "sentry-sdk"] -test = ["coverage", "flake8", "freezegun (==0.3.15)", "mock (>=2.0.0)", "pylint", "pytest", "pytest-timeout"] +test = ["coverage", "django", "flake8", "freezegun (==0.3.15)", "mock (>=2.0.0)", "pylint", "pytest", "pytest-timeout"] + +[[package]] +name = "pox" +version = "0.3.4" +description = "utilities for filesystem exploration and automated builds" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pox-0.3.4-py3-none-any.whl", hash = "sha256:651b8ae8a7b341b7bfd267f67f63106daeb9805f1ac11f323d5280d2da93fdb6"}, + {file = "pox-0.3.4.tar.gz", hash = "sha256:16e6eca84f1bec3828210b06b052adf04cf2ab20c22fd6fbef5f78320c9a6fed"}, +] + +[[package]] +name = "ppft" +version = "1.7.6.8" +description = "distributed and parallel Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "ppft-1.7.6.8-py3-none-any.whl", hash = "sha256:de2dd4b1b080923dd9627fbdea52649fd741c752fce4f3cf37e26f785df23d9b"}, + {file = "ppft-1.7.6.8.tar.gz", hash = "sha256:76a429a7d7b74c4d743f6dba8351e58d62b6432ed65df9fe204790160dab996d"}, +] + +[package.extras] +dill = ["dill (>=0.3.8)"] [[package]] name = "primp" @@ -6692,18 +6876,18 @@ tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] [[package]] name = "pymilvus" -version = "2.4.5" +version = "2.4.6" description = "Python Sdk for Milvus" optional = false python-versions = ">=3.8" files = [ - {file = "pymilvus-2.4.5-py3-none-any.whl", hash = "sha256:dc4f2d1eac8db9cf3951de39566a1a244695760bb94d8310fbfc73d6d62bb267"}, - {file = "pymilvus-2.4.5.tar.gz", hash = "sha256:1a497fe9b41d6bf62b1d5e1c412960922dde1598576fcbb8818040c8af11149f"}, + {file = "pymilvus-2.4.6-py3-none-any.whl", hash = "sha256:b4c43472edc313b845d313be50610e19054e6954b2c5c3b515565c596c2d3d97"}, + {file = "pymilvus-2.4.6.tar.gz", hash = "sha256:6ac3eb91c92cc01bbe444fe83f895f02d7b2546d96ac67998630bf31ac074d66"}, ] [package.dependencies] environs = "<=9.5.0" -grpcio = ">=1.49.1,<=1.63.0" +grpcio = ">=1.49.1" milvus-lite = {version = ">=2.4.0,<2.5.0", markers = "sys_platform != \"win32\""} pandas = ">=1.2.4" protobuf = ">=3.20.0" @@ -6730,6 +6914,24 @@ files = [ ed25519 = ["PyNaCl (>=1.4.0)"] rsa = ["cryptography"] +[[package]] +name = "pyopenssl" +version = "24.2.1" +description = "Python wrapper module around the OpenSSL library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyOpenSSL-24.2.1-py3-none-any.whl", hash = "sha256:967d5719b12b243588573f39b0c677637145c7a1ffedcd495a487e58177fbb8d"}, + {file = "pyopenssl-24.2.1.tar.gz", hash = "sha256:4247f0dbe3748d560dcbb2ff3ea01af0f9a1a001ef5f7c4c647956ed8cbf0e95"}, +] + +[package.dependencies] +cryptography = ">=41.0.5,<44" + +[package.extras] +docs = ["sphinx (!=5.2.0,!=5.2.0.post0,!=7.2.5)", "sphinx-rtd-theme"] +test = ["pretend", "pytest (>=3.0.1)", "pytest-rerunfailures"] + [[package]] name = "pypandoc" version = "1.13" @@ -6743,13 +6945,13 @@ files = [ [[package]] name = "pyparsing" -version = "3.1.2" +version = "3.1.4" description = "pyparsing module - Classes and methods to define and execute parsing grammars" optional = false python-versions = ">=3.6.8" files = [ - {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, - {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, + {file = "pyparsing-3.1.4-py3-none-any.whl", hash = "sha256:a6a7ee4235a3f944aa1fa2249307708f893fe5717dc603503c6c7969c070fb7c"}, + {file = "pyparsing-3.1.4.tar.gz", hash = "sha256:f86ec8d1a83f11977c9a6ea7598e8c27fc5cddfa5b07ea2241edbbde1d7bc032"}, ] [package.extras] @@ -7264,119 +7466,119 @@ dev = ["pytest"] [[package]] name = "rapidfuzz" -version = "3.9.6" +version = "3.9.7" description = "rapid fuzzy string matching" optional = false python-versions = ">=3.8" files = [ - {file = "rapidfuzz-3.9.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a7ed0d0b9c85720f0ae33ac5efc8dc3f60c1489dad5c29d735fbdf2f66f0431f"}, - {file = "rapidfuzz-3.9.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f3deff6ab7017ed21b9aec5874a07ad13e6b2a688af055837f88b743c7bfd947"}, - {file = "rapidfuzz-3.9.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3f9fc060160507b2704f7d1491bd58453d69689b580cbc85289335b14fe8ca"}, - {file = "rapidfuzz-3.9.6-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e86c2b3827fa6169ad6e7d4b790ce02a20acefb8b78d92fa4249589bbc7a2c"}, - {file = "rapidfuzz-3.9.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f982e1aafb4bd8207a5e073b1efef9e68a984e91330e1bbf364f9ed157ed83f0"}, - {file = "rapidfuzz-3.9.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9196a51d0ec5eaaaf5bca54a85b7b1e666fc944c332f68e6427503af9fb8c49e"}, - {file = "rapidfuzz-3.9.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb5a514064e02585b1cc09da2fe406a6dc1a7e5f3e92dd4f27c53e5f1465ec81"}, - {file = "rapidfuzz-3.9.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e3a4244f65dbc3580b1275480118c3763f9dc29fc3dd96610560cb5e140a4d4a"}, - {file = "rapidfuzz-3.9.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:f6ebb910a702e41641e1e1dada3843bc11ba9107a33c98daef6945a885a40a07"}, - {file = "rapidfuzz-3.9.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:624fbe96115fb39addafa288d583b5493bc76dab1d34d0ebba9987d6871afdf9"}, - {file = "rapidfuzz-3.9.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1c59f1c1507b7a557cf3c410c76e91f097460da7d97e51c985343798e9df7a3c"}, - {file = "rapidfuzz-3.9.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f6f0256cb27b6a0fb2e1918477d1b56473cd04acfa245376a342e7c15806a396"}, - {file = "rapidfuzz-3.9.6-cp310-cp310-win32.whl", hash = "sha256:24d473d00d23a30a85802b502b417a7f5126019c3beec91a6739fe7b95388b24"}, - {file = "rapidfuzz-3.9.6-cp310-cp310-win_amd64.whl", hash = "sha256:248f6d2612e661e2b5f9a22bbd5862a1600e720da7bb6ad8a55bb1548cdfa423"}, - {file = "rapidfuzz-3.9.6-cp310-cp310-win_arm64.whl", hash = "sha256:e03fdf0e74f346ed7e798135df5f2a0fb8d6b96582b00ebef202dcf2171e1d1d"}, - {file = "rapidfuzz-3.9.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:52e4675f642fbc85632f691b67115a243cd4d2a47bdcc4a3d9a79e784518ff97"}, - {file = "rapidfuzz-3.9.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1f93a2f13038700bd245b927c46a2017db3dcd4d4ff94687d74b5123689b873b"}, - {file = "rapidfuzz-3.9.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b70500bca460264b8141d8040caee22e9cf0418c5388104ff0c73fb69ee28f"}, - {file = "rapidfuzz-3.9.6-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1e037fb89f714a220f68f902fc6300ab7a33349f3ce8ffae668c3b3a40b0b06"}, - {file = "rapidfuzz-3.9.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6792f66d59b86ccfad5e247f2912e255c85c575789acdbad8e7f561412ffed8a"}, - {file = "rapidfuzz-3.9.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:68d9cffe710b67f1969cf996983608cee4490521d96ea91d16bd7ea5dc80ea98"}, - {file = "rapidfuzz-3.9.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63daaeeea76da17fa0bbe7fb05cba8ed8064bb1a0edf8360636557f8b6511961"}, - {file = "rapidfuzz-3.9.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d214e063bffa13e3b771520b74f674b22d309b5720d4df9918ff3e0c0f037720"}, - {file = "rapidfuzz-3.9.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ed443a2062460f44c0346cb9d269b586496b808c2419bbd6057f54061c9b9c75"}, - {file = "rapidfuzz-3.9.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:5b0c9b227ee0076fb2d58301c505bb837a290ae99ee628beacdb719f0626d749"}, - {file = "rapidfuzz-3.9.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:82c9722b7dfaa71e8b61f8c89fed0482567fb69178e139fe4151fc71ed7df782"}, - {file = "rapidfuzz-3.9.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c18897c95c0a288347e29537b63608a8f63a5c3cb6da258ac46fcf89155e723e"}, - {file = "rapidfuzz-3.9.6-cp311-cp311-win32.whl", hash = "sha256:3e910cf08944da381159587709daaad9e59d8ff7bca1f788d15928f3c3d49c2a"}, - {file = "rapidfuzz-3.9.6-cp311-cp311-win_amd64.whl", hash = "sha256:59c4a61fab676d37329fc3a671618a461bfeef53a4d0b8b12e3bc24a14e166f8"}, - {file = "rapidfuzz-3.9.6-cp311-cp311-win_arm64.whl", hash = "sha256:8b4afea244102332973377fddbe54ce844d0916e1c67a5123432291717f32ffa"}, - {file = "rapidfuzz-3.9.6-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:70591b28b218fff351b88cdd7f2359a01a71f9f7f5a2e465ce3715ed4b3c422b"}, - {file = "rapidfuzz-3.9.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee2d8355c7343c631a03e57540ea06e8717c19ecf5ff64ea07e0498f7f161457"}, - {file = "rapidfuzz-3.9.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:708fb675de0f47b9635d1cc6fbbf80d52cb710d0a1abbfae5c84c46e3abbddc3"}, - {file = "rapidfuzz-3.9.6-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d66c247c2d3bb7a9b60567c395a15a929d0ebcc5f4ceedb55bfa202c38c6e0c"}, - {file = "rapidfuzz-3.9.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:15146301b32e6e3d2b7e8146db1a26747919d8b13690c7f83a4cb5dc111b3a08"}, - {file = "rapidfuzz-3.9.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7a03da59b6c7c97e657dd5cd4bcaab5fe4a2affd8193958d6f4d938bee36679"}, - {file = "rapidfuzz-3.9.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d2c2fe19e392dbc22695b6c3b2510527e2b774647e79936bbde49db7742d6f1"}, - {file = "rapidfuzz-3.9.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:91aaee4c94cb45930684f583ffc4e7c01a52b46610971cede33586cf8a04a12e"}, - {file = "rapidfuzz-3.9.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3f5702828c10768f9281180a7ff8597da1e5002803e1304e9519dd0f06d79a85"}, - {file = "rapidfuzz-3.9.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ccd1763b608fb4629a0b08f00b3c099d6395e67c14e619f6341b2c8429c2f310"}, - {file = "rapidfuzz-3.9.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc7a0d4b2cb166bc46d02c8c9f7551cde8e2f3c9789df3827309433ee9771163"}, - {file = "rapidfuzz-3.9.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7496f53d40560a58964207b52586783633f371683834a8f719d6d965d223a2eb"}, - {file = "rapidfuzz-3.9.6-cp312-cp312-win32.whl", hash = "sha256:5eb1a9272ca71bc72be5415c2fa8448a6302ea4578e181bb7da9db855b367df0"}, - {file = "rapidfuzz-3.9.6-cp312-cp312-win_amd64.whl", hash = "sha256:0d21fc3c0ca507a1180152a6dbd129ebaef48facde3f943db5c1055b6e6be56a"}, - {file = "rapidfuzz-3.9.6-cp312-cp312-win_arm64.whl", hash = "sha256:43bb27a57c29dc5fa754496ba6a1a508480d21ae99ac0d19597646c16407e9f3"}, - {file = "rapidfuzz-3.9.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:83a5ac6547a9d6eedaa212975cb8f2ce2aa07e6e30833b40e54a52b9f9999aa4"}, - {file = "rapidfuzz-3.9.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:10f06139142ecde67078ebc9a745965446132b998f9feebffd71acdf218acfcc"}, - {file = "rapidfuzz-3.9.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74720c3f24597f76c7c3e2c4abdff55f1664f4766ff5b28aeaa689f8ffba5fab"}, - {file = "rapidfuzz-3.9.6-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce2bce52b5c150878e558a0418c2b637fb3dbb6eb38e4eb27d24aa839920483e"}, - {file = "rapidfuzz-3.9.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1611199f178793ca9a060c99b284e11f6d7d124998191f1cace9a0245334d219"}, - {file = "rapidfuzz-3.9.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0308b2ad161daf502908a6e21a57c78ded0258eba9a8f5e2545e2dafca312507"}, - {file = "rapidfuzz-3.9.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3eda91832201b86e3b70835f91522587725bec329ec68f2f7faf5124091e5ca7"}, - {file = "rapidfuzz-3.9.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ece873c093aedd87fc07c2a7e333d52e458dc177016afa1edaf157e82b6914d8"}, - {file = "rapidfuzz-3.9.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d97d3c9d209d5c30172baea5966f2129e8a198fec4a1aeb2f92abb6e82a2edb1"}, - {file = "rapidfuzz-3.9.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:6c4550d0db4931f5ebe9f0678916d1b06f06f5a99ba0b8a48b9457fd8959a7d4"}, - {file = "rapidfuzz-3.9.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b6b8dd4af6324fc325d9483bec75ecf9be33e590928c9202d408e4eafff6a0a6"}, - {file = "rapidfuzz-3.9.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:16122ae448bc89e2bea9d81ce6cb0f751e4e07da39bd1e70b95cae2493857853"}, - {file = "rapidfuzz-3.9.6-cp313-cp313-win32.whl", hash = "sha256:71cc168c305a4445109cd0d4925406f6e66bcb48fde99a1835387c58af4ecfe9"}, - {file = "rapidfuzz-3.9.6-cp313-cp313-win_amd64.whl", hash = "sha256:59ee78f2ecd53fef8454909cda7400fe2cfcd820f62b8a5d4dfe930102268054"}, - {file = "rapidfuzz-3.9.6-cp313-cp313-win_arm64.whl", hash = "sha256:58b4ce83f223605c358ae37e7a2d19a41b96aa65b1fede99cc664c9053af89ac"}, - {file = "rapidfuzz-3.9.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9f469dbc9c4aeaac7dd005992af74b7dff94aa56a3ea063ce64e4b3e6736dd2f"}, - {file = "rapidfuzz-3.9.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a9ed7ad9adb68d0fe63a156fe752bbf5f1403ed66961551e749641af2874da92"}, - {file = "rapidfuzz-3.9.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39ffe48ffbeedf78d120ddfb9d583f2ca906712159a4e9c3c743c9f33e7b1775"}, - {file = "rapidfuzz-3.9.6-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8502ccdea9084d54b6f737d96a3b60a84e3afed9d016686dc979b49cdac71613"}, - {file = "rapidfuzz-3.9.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6a4bec4956e06b170ca896ba055d08d4c457dac745548172443982956a80e118"}, - {file = "rapidfuzz-3.9.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c0488b1c273be39e109ff885ccac0448b2fa74dea4c4dc676bcf756c15f16d6"}, - {file = "rapidfuzz-3.9.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0542c036cb6acf24edd2c9e0411a67d7ba71e29e4d3001a082466b86fc34ff30"}, - {file = "rapidfuzz-3.9.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:0a96b52c9f26857bf009e270dcd829381e7a634f7ddd585fa29b87d4c82146d9"}, - {file = "rapidfuzz-3.9.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:6edd3cd7c4aa8c68c716d349f531bd5011f2ca49ddade216bb4429460151559f"}, - {file = "rapidfuzz-3.9.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:50b2fb55d7ed58c66d49c9f954acd8fc4a3f0e9fd0ff708299bd8abb68238d0e"}, - {file = "rapidfuzz-3.9.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:32848dfe54391636b84cda1823fd23e5a6b1dbb8be0e9a1d80e4ee9903820994"}, - {file = "rapidfuzz-3.9.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:29146cb7a1bf69c87e928b31bffa54f066cb65639d073b36e1425f98cccdebc6"}, - {file = "rapidfuzz-3.9.6-cp38-cp38-win32.whl", hash = "sha256:aed13e5edacb0ecadcc304cc66e93e7e77ff24f059c9792ee602c0381808e10c"}, - {file = "rapidfuzz-3.9.6-cp38-cp38-win_amd64.whl", hash = "sha256:af440e36b828922256d0b4d79443bf2cbe5515fc4b0e9e96017ec789b36bb9fc"}, - {file = "rapidfuzz-3.9.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:efa674b407424553024522159296690d99d6e6b1192cafe99ca84592faff16b4"}, - {file = "rapidfuzz-3.9.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0b40ff76ee19b03ebf10a0a87938f86814996a822786c41c3312d251b7927849"}, - {file = "rapidfuzz-3.9.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16a6c7997cb5927ced6f617122eb116ba514ec6b6f60f4803e7925ef55158891"}, - {file = "rapidfuzz-3.9.6-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3f42504bdc8d770987fc3d99964766d42b2a03e4d5b0f891decdd256236bae0"}, - {file = "rapidfuzz-3.9.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9462aa2be9f60b540c19a083471fdf28e7cf6434f068b631525b5e6251b35e"}, - {file = "rapidfuzz-3.9.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1629698e68f47609a73bf9e73a6da3a4cac20bc710529215cbdf111ab603665b"}, - {file = "rapidfuzz-3.9.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68bc7621843d8e9a7fd1b1a32729465bf94b47b6fb307d906da168413331f8d6"}, - {file = "rapidfuzz-3.9.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c6254c50f15bc2fcc33cb93a95a81b702d9e6590f432a7f7822b8c7aba9ae288"}, - {file = "rapidfuzz-3.9.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:7e535a114fa575bc143e175e4ca386a467ec8c42909eff500f5f0f13dc84e3e0"}, - {file = "rapidfuzz-3.9.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d50acc0e9d67e4ba7a004a14c42d1b1e8b6ca1c515692746f4f8e7948c673167"}, - {file = "rapidfuzz-3.9.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:fa742ec60bec53c5a211632cf1d31b9eb5a3c80f1371a46a23ac25a1fa2ab209"}, - {file = "rapidfuzz-3.9.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c256fa95d29cbe5aa717db790b231a9a5b49e5983d50dc9df29d364a1db5e35b"}, - {file = "rapidfuzz-3.9.6-cp39-cp39-win32.whl", hash = "sha256:89acbf728b764421036c173a10ada436ecca22999851cdc01d0aa904c70d362d"}, - {file = "rapidfuzz-3.9.6-cp39-cp39-win_amd64.whl", hash = "sha256:c608fcba8b14d86c04cb56b203fed31a96e8a1ebb4ce99e7b70313c5bf8cf497"}, - {file = "rapidfuzz-3.9.6-cp39-cp39-win_arm64.whl", hash = "sha256:d41c00ded0e22e9dba88ff23ebe0dc9d2a5f21ba2f88e185ea7374461e61daa9"}, - {file = "rapidfuzz-3.9.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a65c2f63218ea2dedd56fc56361035e189ca123bd9c9ce63a9bef6f99540d681"}, - {file = "rapidfuzz-3.9.6-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:680dc78a5f889d3b89f74824b89fe357f49f88ad10d2c121e9c3ad37bac1e4eb"}, - {file = "rapidfuzz-3.9.6-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8ca862927a0b05bd825e46ddf82d0724ea44b07d898ef639386530bf9b40f15"}, - {file = "rapidfuzz-3.9.6-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2116fa1fbff21fa52cd46f3cfcb1e193ba1d65d81f8b6e123193451cd3d6c15e"}, - {file = "rapidfuzz-3.9.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4dcb7d9afd740370a897c15da61d3d57a8d54738d7c764a99cedb5f746d6a003"}, - {file = "rapidfuzz-3.9.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1a5bd6401bb489e14cbb5981c378d53ede850b7cc84b2464cad606149cc4e17d"}, - {file = "rapidfuzz-3.9.6-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:29fda70b9d03e29df6fc45cc27cbcc235534b1b0b2900e0a3ae0b43022aaeef5"}, - {file = "rapidfuzz-3.9.6-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:88144f5f52ae977df9352029488326afadd7a7f42c6779d486d1f82d43b2b1f2"}, - {file = "rapidfuzz-3.9.6-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:715aeaabafba2709b9dd91acb2a44bad59d60b4616ef90c08f4d4402a3bbca60"}, - {file = "rapidfuzz-3.9.6-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:af26ebd3714224fbf9bebbc27bdbac14f334c15f5d7043699cd694635050d6ca"}, - {file = "rapidfuzz-3.9.6-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:101bd2df438861a005ed47c032631b7857dfcdb17b82beeeb410307983aac61d"}, - {file = "rapidfuzz-3.9.6-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:2185e8e29809b97ad22a7f99281d1669a89bdf5fa1ef4ef1feca36924e675367"}, - {file = "rapidfuzz-3.9.6-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:9e53c72d08f0e9c6e4a369e52df5971f311305b4487690c62e8dd0846770260c"}, - {file = "rapidfuzz-3.9.6-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a0cb157162f0cdd62e538c7bd298ff669847fc43a96422811d5ab933f4c16c3a"}, - {file = "rapidfuzz-3.9.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bb5ff2bd48132ed5e7fbb8f619885facb2e023759f2519a448b2c18afe07e5d"}, - {file = "rapidfuzz-3.9.6-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6dc37f601865e8407e3a8037ffbc3afe0b0f837b2146f7632bd29d087385babe"}, - {file = "rapidfuzz-3.9.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a657eee4b94668faf1fa2703bdd803654303f7e468eb9ba10a664d867ed9e779"}, - {file = "rapidfuzz-3.9.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:51be6ab5b1d5bb32abd39718f2a5e3835502e026a8272d139ead295c224a6f5e"}, - {file = "rapidfuzz-3.9.6.tar.gz", hash = "sha256:5cf2a7d621e4515fee84722e93563bf77ff2cbe832a77a48b81f88f9e23b9e8d"}, + {file = "rapidfuzz-3.9.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ccf68e30b80e903f2309f90a438dbd640dd98e878eeb5ad361a288051ee5b75c"}, + {file = "rapidfuzz-3.9.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:696a79018ef989bf1c9abd9005841cee18005ccad4748bad8a4c274c47b6241a"}, + {file = "rapidfuzz-3.9.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4eebf6c93af0ae866c22b403a84747580bb5c10f0d7b51c82a87f25405d4dcb"}, + {file = "rapidfuzz-3.9.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e9125377fa3d21a8abd4fbdbcf1c27be73e8b1850f0b61b5b711364bf3b59db"}, + {file = "rapidfuzz-3.9.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c12d180b17a22d107c8747de9c68d0b9c1d15dcda5445ff9bf9f4ccfb67c3e16"}, + {file = "rapidfuzz-3.9.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c1318d42610c26dcd68bd3279a1bf9e3605377260867c9a8ed22eafc1bd93a7c"}, + {file = "rapidfuzz-3.9.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd5fa6e3c6e0333051c1f3a49f0807b3366f4131c8d6ac8c3e05fd0d0ce3755c"}, + {file = "rapidfuzz-3.9.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fcf79b686962d7bec458a0babc904cb4fa319808805e036b9d5a531ee6b9b835"}, + {file = "rapidfuzz-3.9.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8b01153c7466d0bad48fba77a303d5a768e66f24b763853469f47220b3de4661"}, + {file = "rapidfuzz-3.9.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:94baaeea0b4f8632a6da69348b1e741043eba18d4e3088d674d3f76586b6223d"}, + {file = "rapidfuzz-3.9.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6c5b32875646cb7f60c193ade99b2e4b124f19583492115293cd00f6fb198b17"}, + {file = "rapidfuzz-3.9.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:110b6294396bc0a447648627479c9320f095c2034c0537f687592e0f58622638"}, + {file = "rapidfuzz-3.9.7-cp310-cp310-win32.whl", hash = "sha256:3445a35c4c8d288f2b2011eb61bce1227c633ce85a3154e727170f37c0266bb2"}, + {file = "rapidfuzz-3.9.7-cp310-cp310-win_amd64.whl", hash = "sha256:0d1415a732ee75e74a90af12020b77a0b396b36c60afae1bde3208a78cd2c9fc"}, + {file = "rapidfuzz-3.9.7-cp310-cp310-win_arm64.whl", hash = "sha256:836f4d88b8bd0fff2ebe815dcaab8aa6c8d07d1d566a7e21dd137cf6fe11ed5b"}, + {file = "rapidfuzz-3.9.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d098ce6162eb5e48fceb0745455bc950af059df6113eec83e916c129fca11408"}, + {file = "rapidfuzz-3.9.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:048d55d36c02c6685a2b2741688503c3d15149694506655b6169dcfd3b6c2585"}, + {file = "rapidfuzz-3.9.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c33211cfff9aec425bb1bfedaf94afcf337063aa273754f22779d6dadebef4c2"}, + {file = "rapidfuzz-3.9.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e6d9db2fa4e9be171e9bb31cf2d2575574774966b43f5b951062bb2e67885852"}, + {file = "rapidfuzz-3.9.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d4e049d5ad61448c9a020d1061eba20944c4887d720c4069724beb6ea1692507"}, + {file = "rapidfuzz-3.9.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cfa74aac64c85898b93d9c80bb935a96bf64985e28d4ee0f1a3d1f3bf11a5106"}, + {file = "rapidfuzz-3.9.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:965693c2e9efd425b0f059f5be50ef830129f82892fa1858e220e424d9d0160f"}, + {file = "rapidfuzz-3.9.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8501000a5eb8037c4b56857724797fe5a8b01853c363de91c8d0d0ad56bef319"}, + {file = "rapidfuzz-3.9.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8d92c552c6b7577402afdd547dcf5d31ea6c8ae31ad03f78226e055cfa37f3c6"}, + {file = "rapidfuzz-3.9.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1ee2086f490cb501d86b7e386c1eb4e3a0ccbb0c99067089efaa8c79012c8952"}, + {file = "rapidfuzz-3.9.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:1de91e7fd7f525e10ea79a6e62c559d1b0278ec097ad83d9da378b6fab65a265"}, + {file = "rapidfuzz-3.9.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a4da514d13f4433e16960a17f05b67e0af30ac771719c9a9fb877e5004f74477"}, + {file = "rapidfuzz-3.9.7-cp311-cp311-win32.whl", hash = "sha256:a40184c67db8252593ec518e17fb8a6e86d7259dc9f2d6c0bf4ff4db8cf1ad4b"}, + {file = "rapidfuzz-3.9.7-cp311-cp311-win_amd64.whl", hash = "sha256:c4f28f1930b09a2c300357d8465b388cecb7e8b2f454a5d5425561710b7fd07f"}, + {file = "rapidfuzz-3.9.7-cp311-cp311-win_arm64.whl", hash = "sha256:675b75412a943bb83f1f53e2e54fd18c80ef15ed642dc6eb0382d1949419d904"}, + {file = "rapidfuzz-3.9.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1ef6a1a8f0b12f8722f595f15c62950c9a02d5abc64742561299ffd49f6c6944"}, + {file = "rapidfuzz-3.9.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:32532af1d70c6ec02ea5ac7ee2766dfff7c8ae8c761abfe8da9e527314e634e8"}, + {file = "rapidfuzz-3.9.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae1a38bade755aa9dd95a81cda949e1bf9cd92b79341ccc5e2189c9e7bdfc5ec"}, + {file = "rapidfuzz-3.9.7-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d73ee2df41224c87336448d279b5b6a3a75f36e41dd3dcf538c0c9cce36360d8"}, + {file = "rapidfuzz-3.9.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be3a1fc3e2ab3bdf93dc0c83c00acca8afd2a80602297d96cf4a0ba028333cdf"}, + {file = "rapidfuzz-3.9.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:603f48f621272a448ff58bb556feb4371252a02156593303391f5c3281dfaeac"}, + {file = "rapidfuzz-3.9.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:268f8e1ca50fc61c0736f3fe9d47891424adf62d96ed30196f30f4bd8216b41f"}, + {file = "rapidfuzz-3.9.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5f8bf3f0d02935751d8660abda6044821a861f6229f7d359f98bcdcc7e66c39b"}, + {file = "rapidfuzz-3.9.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b997ff3b39d4cee9fb025d6c46b0a24bd67595ce5a5b652a97fb3a9d60beb651"}, + {file = "rapidfuzz-3.9.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ca66676c8ef6557f9b81c5b2b519097817a7c776a6599b8d6fcc3e16edd216fe"}, + {file = "rapidfuzz-3.9.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:35d3044cb635ca6b1b2b7b67b3597bd19f34f1753b129eb6d2ae04cf98cd3945"}, + {file = "rapidfuzz-3.9.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5a93c9e60904cb76e7aefef67afffb8b37c4894f81415ed513db090f29d01101"}, + {file = "rapidfuzz-3.9.7-cp312-cp312-win32.whl", hash = "sha256:579d107102c0725f7c79b4e79f16d3cf4d7c9208f29c66b064fa1fd4641d5155"}, + {file = "rapidfuzz-3.9.7-cp312-cp312-win_amd64.whl", hash = "sha256:953b3780765c8846866faf891ee4290f6a41a6dacf4fbcd3926f78c9de412ca6"}, + {file = "rapidfuzz-3.9.7-cp312-cp312-win_arm64.whl", hash = "sha256:7c20c1474b068c4bd45bf2fd0ad548df284f74e9a14a68b06746c56e3aa8eb70"}, + {file = "rapidfuzz-3.9.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fde81b1da9a947f931711febe2e2bee694e891f6d3e6aa6bc02c1884702aea19"}, + {file = "rapidfuzz-3.9.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:47e92c155a14f44511ea8ebcc6bc1535a1fe8d0a7d67ad3cc47ba61606df7bcf"}, + {file = "rapidfuzz-3.9.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8772b745668260c5c4d069c678bbaa68812e6c69830f3771eaad521af7bc17f8"}, + {file = "rapidfuzz-3.9.7-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:578302828dd97ee2ba507d2f71d62164e28d2fc7bc73aad0d2d1d2afc021a5d5"}, + {file = "rapidfuzz-3.9.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc3e6081069eea61593f1d6839029da53d00c8c9b205c5534853eaa3f031085c"}, + {file = "rapidfuzz-3.9.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0b1c2d504eddf97bc0f2eba422c8915576dbf025062ceaca2d68aecd66324ad9"}, + {file = "rapidfuzz-3.9.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb76e5a21034f0307c51c5a2fc08856f698c53a4c593b17d291f7d6e9d09ca3"}, + {file = "rapidfuzz-3.9.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d4ba2318ef670ce505f42881a5d2af70f948124646947341a3c6ccb33cd70369"}, + {file = "rapidfuzz-3.9.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:057bb03f39e285047d7e9412e01ecf31bb2d42b9466a5409d715d587460dd59b"}, + {file = "rapidfuzz-3.9.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a8feac9006d5c9758438906f093befffc4290de75663dbb2098461df7c7d28dd"}, + {file = "rapidfuzz-3.9.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:95b8292383e717e10455f2c917df45032b611141e43d1adf70f71b1566136b11"}, + {file = "rapidfuzz-3.9.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e9fbf659537d246086d0297628b3795dc3e4a384101ecc01e5791c827b8d7345"}, + {file = "rapidfuzz-3.9.7-cp313-cp313-win32.whl", hash = "sha256:1dc516ac6d32027be2b0196bedf6d977ac26debd09ca182376322ad620460feb"}, + {file = "rapidfuzz-3.9.7-cp313-cp313-win_amd64.whl", hash = "sha256:b4f86e09d3064dca0b014cd48688964036a904a2d28048f00c8f4640796d06a8"}, + {file = "rapidfuzz-3.9.7-cp313-cp313-win_arm64.whl", hash = "sha256:19c64d8ddb2940b42a4567b23f1681af77f50a5ff6c9b8e85daba079c210716e"}, + {file = "rapidfuzz-3.9.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fbda3dd68d8b28ccb20ffb6f756fefd9b5ba570a772bedd7643ed441f5793308"}, + {file = "rapidfuzz-3.9.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2379e0b2578ad3ac7004f223251550f08bca873ff76c169b09410ec562ad78d8"}, + {file = "rapidfuzz-3.9.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d1eff95362f993b0276fd3839aee48625b09aac8938bb0c23b40d219cba5dc5"}, + {file = "rapidfuzz-3.9.7-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd9360e30041690912525a210e48a897b49b230768cc8af1c702e5395690464f"}, + {file = "rapidfuzz-3.9.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a93cd834b3c315ab437f0565ee3a2f42dd33768dc885ccbabf9710b131cf70d2"}, + {file = "rapidfuzz-3.9.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ff196996240db7075f62c7bc4506f40a3c80cd4ae3ab0e79ac6892283a90859"}, + {file = "rapidfuzz-3.9.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:948dcee7aaa1cd14358b2a7ef08bf0be42bf89049c3a906669874a715fc2c937"}, + {file = "rapidfuzz-3.9.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d95751f505a301af1aaf086c19f34536056d6c8efa91b2240de532a3db57b543"}, + {file = "rapidfuzz-3.9.7-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:90db86fa196eecf96cb6db09f1083912ea945c50c57188039392d810d0b784e1"}, + {file = "rapidfuzz-3.9.7-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:3171653212218a162540a3c8eb8ae7d3dcc8548540b69eaecaf3b47c14d89c90"}, + {file = "rapidfuzz-3.9.7-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:36dd6e820379c37a1ffefc8a52b648758e867cd9d78ee5b5dc0c9a6a10145378"}, + {file = "rapidfuzz-3.9.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7b702de95666a1f7d5c6b47eacadfe2d2794af3742d63d2134767d13e5d1c713"}, + {file = "rapidfuzz-3.9.7-cp38-cp38-win32.whl", hash = "sha256:9030e7238c0df51aed5c9c5ed8eee2bdd47a2ae788e562c1454af2851c3d1906"}, + {file = "rapidfuzz-3.9.7-cp38-cp38-win_amd64.whl", hash = "sha256:f847fb0fbfb72482b1c05c59cbb275c58a55b73708a7f77a83f8035ee3c86497"}, + {file = "rapidfuzz-3.9.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:97f2ce529d2a70a60c290f6ab269a2bbf1d3b47b9724dccc84339b85f7afb044"}, + {file = "rapidfuzz-3.9.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e2957fdad10bb83b1982b02deb3604a3f6911a5e545f518b59c741086f92d152"}, + {file = "rapidfuzz-3.9.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d5262383634626eb45c536017204b8163a03bc43bda880cf1bdd7885db9a163"}, + {file = "rapidfuzz-3.9.7-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:364587827d7cbd41afa0782adc2d2d19e3f07d355b0750a02a8e33ad27a9c368"}, + {file = "rapidfuzz-3.9.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ecc24af7f905f3d6efb371a01680116ffea8d64e266618fb9ad1602a9b4f7934"}, + {file = "rapidfuzz-3.9.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9dc86aa6b29d174713c5f4caac35ffb7f232e3e649113e8d13812b35ab078228"}, + {file = "rapidfuzz-3.9.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3dcfbe7266e74a707173a12a7b355a531f2dcfbdb32f09468e664330da14874"}, + {file = "rapidfuzz-3.9.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b23806fbdd6b510ba9ac93bb72d503066263b0fba44b71b835be9f063a84025f"}, + {file = "rapidfuzz-3.9.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:5551d68264c1bb6943f542da83a4dc8940ede52c5847ef158698799cc28d14f5"}, + {file = "rapidfuzz-3.9.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:13d8675a1fa7e2b19650ca7ef9a6ec01391d4bb12ab9e0793e8eb024538b4a34"}, + {file = "rapidfuzz-3.9.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9b6a5de507b9be6de688dae40143b656f7a93b10995fb8bd90deb555e7875c60"}, + {file = "rapidfuzz-3.9.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:111a20a3c090cf244d9406e60500b6c34b2375ba3a5009e2b38fd806fe38e337"}, + {file = "rapidfuzz-3.9.7-cp39-cp39-win32.whl", hash = "sha256:22589c0b8ccc6c391ce7f776c93a8c92c96ab8d34e1a19f1bd2b12a235332632"}, + {file = "rapidfuzz-3.9.7-cp39-cp39-win_amd64.whl", hash = "sha256:6f83221db5755b8f34222e40607d87f1176a8d5d4dbda4a55a0f0b67d588a69c"}, + {file = "rapidfuzz-3.9.7-cp39-cp39-win_arm64.whl", hash = "sha256:3665b92e788578c3bb334bd5b5fa7ee1a84bafd68be438e3110861d1578c63a0"}, + {file = "rapidfuzz-3.9.7-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:d7df9c2194c7ec930b33c991c55dbd0c10951bd25800c0b7a7b571994ebbced5"}, + {file = "rapidfuzz-3.9.7-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:68bd888eafd07b09585dcc8bc2716c5ecdb7eed62827470664d25588982b2873"}, + {file = "rapidfuzz-3.9.7-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1230e0f9026851a6a432beaa0ce575dda7b39fe689b576f99a0704fbb81fc9c"}, + {file = "rapidfuzz-3.9.7-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3b36e1c61b796ae1777f3e9e11fd39898b09d351c9384baf6e3b7e6191d8ced"}, + {file = "rapidfuzz-3.9.7-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9dba13d86806fcf3fe9c9919f58575e0090eadfb89c058bde02bcc7ab24e4548"}, + {file = "rapidfuzz-3.9.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1f1a33e84056b7892c721d84475d3bde49a145126bc4c6efe0d6d0d59cb31c29"}, + {file = "rapidfuzz-3.9.7-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3492c7a42b7fa9f0051d7fcce9893e95ed91c97c9ec7fb64346f3e070dd318ed"}, + {file = "rapidfuzz-3.9.7-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:ece45eb2af8b00f90d10f7419322e8804bd42fb1129026f9bfe712c37508b514"}, + {file = "rapidfuzz-3.9.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcd14cf4876f04b488f6e54a7abd3e9b31db5f5a6aba0ce90659917aaa8c088"}, + {file = "rapidfuzz-3.9.7-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:521c58c72ed8a612b25cda378ff10dee17e6deb4ee99a070b723519a345527b9"}, + {file = "rapidfuzz-3.9.7-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18669bb6cdf7d40738526d37e550df09ba065b5a7560f3d802287988b6cb63cf"}, + {file = "rapidfuzz-3.9.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7abe2dbae81120a64bb4f8d3fcafe9122f328c9f86d7f327f174187a5af4ed86"}, + {file = "rapidfuzz-3.9.7-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a3c0783910911f4f24655826d007c9f4360f08107410952c01ee3df98c713eb2"}, + {file = "rapidfuzz-3.9.7-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:03126f9a040ff21d2a110610bfd6b93b79377ce8b4121edcb791d61b7df6eec5"}, + {file = "rapidfuzz-3.9.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:591908240f4085e2ade5b685c6e8346e2ed44932cffeaac2fb32ddac95b55c7f"}, + {file = "rapidfuzz-3.9.7-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e9012d86c6397edbc9da4ac0132de7f8ee9d6ce857f4194d5684c4ddbcdd1c5c"}, + {file = "rapidfuzz-3.9.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df596ddd3db38aa513d4c0995611267b3946e7cbe5a8761b50e9306dfec720ee"}, + {file = "rapidfuzz-3.9.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3ed5adb752f4308fcc8f4fb6f8eb7aa4082f9d12676fda0a74fa5564242a8107"}, + {file = "rapidfuzz-3.9.7.tar.gz", hash = "sha256:f1c7296534c1afb6f495aa95871f14ccdc197c6db42965854e483100df313030"}, ] [package.extras] @@ -7629,13 +7831,13 @@ requests = "2.31.0" [[package]] name = "rich" -version = "13.7.1" +version = "13.8.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, - {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, + {file = "rich-13.8.0-py3-none-any.whl", hash = "sha256:2e85306a063b9492dffc86278197a60cbece75bcb766022f3436f567cae11bdc"}, + {file = "rich-13.8.0.tar.gz", hash = "sha256:a5ac1f1cd448ade0d59cc3356f7db7a7ccda2c8cbae9c7a90c28ff463d3e91f4"}, ] [package.dependencies] @@ -7773,29 +7975,29 @@ pyasn1 = ">=0.1.3" [[package]] name = "ruff" -version = "0.6.1" +version = "0.6.4" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.6.1-py3-none-linux_armv6l.whl", hash = "sha256:b4bb7de6a24169dc023f992718a9417380301b0c2da0fe85919f47264fb8add9"}, - {file = "ruff-0.6.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:45efaae53b360c81043e311cdec8a7696420b3d3e8935202c2846e7a97d4edae"}, - {file = "ruff-0.6.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:bc60c7d71b732c8fa73cf995efc0c836a2fd8b9810e115be8babb24ae87e0850"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c7477c3b9da822e2db0b4e0b59e61b8a23e87886e727b327e7dcaf06213c5cf"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a0af7ab3f86e3dc9f157a928e08e26c4b40707d0612b01cd577cc84b8905cc9"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:392688dbb50fecf1bf7126731c90c11a9df1c3a4cdc3f481b53e851da5634fa5"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5278d3e095ccc8c30430bcc9bc550f778790acc211865520f3041910a28d0024"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe6d5f65d6f276ee7a0fc50a0cecaccb362d30ef98a110f99cac1c7872df2f18"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2e0dd11e2ae553ee5c92a81731d88a9883af8db7408db47fc81887c1f8b672e"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d812615525a34ecfc07fd93f906ef5b93656be01dfae9a819e31caa6cfe758a1"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:faaa4060f4064c3b7aaaa27328080c932fa142786f8142aff095b42b6a2eb631"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:99d7ae0df47c62729d58765c593ea54c2546d5de213f2af2a19442d50a10cec9"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9eb18dfd7b613eec000e3738b3f0e4398bf0153cb80bfa3e351b3c1c2f6d7b15"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:c62bc04c6723a81e25e71715aa59489f15034d69bf641df88cb38bdc32fd1dbb"}, - {file = "ruff-0.6.1-py3-none-win32.whl", hash = "sha256:9fb4c4e8b83f19c9477a8745e56d2eeef07a7ff50b68a6998f7d9e2e3887bdc4"}, - {file = "ruff-0.6.1-py3-none-win_amd64.whl", hash = "sha256:c2ebfc8f51ef4aca05dad4552bbcf6fe8d1f75b2f6af546cc47cc1c1ca916b5b"}, - {file = "ruff-0.6.1-py3-none-win_arm64.whl", hash = "sha256:3bc81074971b0ffad1bd0c52284b22411f02a11a012082a76ac6da153536e014"}, - {file = "ruff-0.6.1.tar.gz", hash = "sha256:af3ffd8c6563acb8848d33cd19a69b9bfe943667f0419ca083f8ebe4224a3436"}, + {file = "ruff-0.6.4-py3-none-linux_armv6l.whl", hash = "sha256:c4b153fc152af51855458e79e835fb6b933032921756cec9af7d0ba2aa01a258"}, + {file = "ruff-0.6.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:bedff9e4f004dad5f7f76a9d39c4ca98af526c9b1695068198b3bda8c085ef60"}, + {file = "ruff-0.6.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d02a4127a86de23002e694d7ff19f905c51e338c72d8e09b56bfb60e1681724f"}, + {file = "ruff-0.6.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7862f42fc1a4aca1ea3ffe8a11f67819d183a5693b228f0bb3a531f5e40336fc"}, + {file = "ruff-0.6.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eebe4ff1967c838a1a9618a5a59a3b0a00406f8d7eefee97c70411fefc353617"}, + {file = "ruff-0.6.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:932063a03bac394866683e15710c25b8690ccdca1cf192b9a98260332ca93408"}, + {file = "ruff-0.6.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:50e30b437cebef547bd5c3edf9ce81343e5dd7c737cb36ccb4fe83573f3d392e"}, + {file = "ruff-0.6.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c44536df7b93a587de690e124b89bd47306fddd59398a0fb12afd6133c7b3818"}, + {file = "ruff-0.6.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ea086601b22dc5e7693a78f3fcfc460cceabfdf3bdc36dc898792aba48fbad6"}, + {file = "ruff-0.6.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b52387d3289ccd227b62102c24714ed75fbba0b16ecc69a923a37e3b5e0aaaa"}, + {file = "ruff-0.6.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0308610470fcc82969082fc83c76c0d362f562e2f0cdab0586516f03a4e06ec6"}, + {file = "ruff-0.6.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:803b96dea21795a6c9d5bfa9e96127cc9c31a1987802ca68f35e5c95aed3fc0d"}, + {file = "ruff-0.6.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:66dbfea86b663baab8fcae56c59f190caba9398df1488164e2df53e216248baa"}, + {file = "ruff-0.6.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:34d5efad480193c046c86608dbba2bccdc1c5fd11950fb271f8086e0c763a5d1"}, + {file = "ruff-0.6.4-py3-none-win32.whl", hash = "sha256:f0f8968feea5ce3777c0d8365653d5e91c40c31a81d95824ba61d871a11b8523"}, + {file = "ruff-0.6.4-py3-none-win_amd64.whl", hash = "sha256:549daccee5227282289390b0222d0fbee0275d1db6d514550d65420053021a58"}, + {file = "ruff-0.6.4-py3-none-win_arm64.whl", hash = "sha256:ac4b75e898ed189b3708c9ab3fc70b79a433219e1e87193b4f2b77251d058d14"}, + {file = "ruff-0.6.4.tar.gz", hash = "sha256:ac3b5bfbee99973f80aa1b7cbd1c9cbce200883bdd067300c22a6cc1c7fba212"}, ] [[package]] @@ -7817,121 +8019,121 @@ crt = ["botocore[crt] (>=1.33.2,<2.0a.0)"] [[package]] name = "safetensors" -version = "0.4.4" +version = "0.4.5" description = "" optional = false python-versions = ">=3.7" files = [ - {file = "safetensors-0.4.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2adb497ada13097f30e386e88c959c0fda855a5f6f98845710f5bb2c57e14f12"}, - {file = "safetensors-0.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7db7fdc2d71fd1444d85ca3f3d682ba2df7d61a637dfc6d80793f439eae264ab"}, - {file = "safetensors-0.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d4f0eed76b430f009fbefca1a0028ddb112891b03cb556d7440d5cd68eb89a9"}, - {file = "safetensors-0.4.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:57d216fab0b5c432aabf7170883d7c11671622bde8bd1436c46d633163a703f6"}, - {file = "safetensors-0.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7d9b76322e49c056bcc819f8bdca37a2daa5a6d42c07f30927b501088db03309"}, - {file = "safetensors-0.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:32f0d1f6243e90ee43bc6ee3e8c30ac5b09ca63f5dd35dbc985a1fc5208c451a"}, - {file = "safetensors-0.4.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44d464bdc384874601a177375028012a5f177f1505279f9456fea84bbc575c7f"}, - {file = "safetensors-0.4.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:63144e36209ad8e4e65384dbf2d52dd5b1866986079c00a72335402a38aacdc5"}, - {file = "safetensors-0.4.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:051d5ecd490af7245258000304b812825974d5e56f14a3ff7e1b8b2ba6dc2ed4"}, - {file = "safetensors-0.4.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:51bc8429d9376224cd3cf7e8ce4f208b4c930cd10e515b6ac6a72cbc3370f0d9"}, - {file = "safetensors-0.4.4-cp310-none-win32.whl", hash = "sha256:fb7b54830cee8cf9923d969e2df87ce20e625b1af2fd194222ab902d3adcc29c"}, - {file = "safetensors-0.4.4-cp310-none-win_amd64.whl", hash = "sha256:4b3e8aa8226d6560de8c2b9d5ff8555ea482599c670610758afdc97f3e021e9c"}, - {file = "safetensors-0.4.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:bbaa31f2cb49013818bde319232ccd72da62ee40f7d2aa532083eda5664e85ff"}, - {file = "safetensors-0.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9fdcb80f4e9fbb33b58e9bf95e7dbbedff505d1bcd1c05f7c7ce883632710006"}, - {file = "safetensors-0.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55c14c20be247b8a1aeaf3ab4476265e3ca83096bb8e09bb1a7aa806088def4f"}, - {file = "safetensors-0.4.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:949aaa1118660f992dbf0968487b3e3cfdad67f948658ab08c6b5762e90cc8b6"}, - {file = "safetensors-0.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c11a4ab7debc456326a2bac67f35ee0ac792bcf812c7562a4a28559a5c795e27"}, - {file = "safetensors-0.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0cea44bba5c5601b297bc8307e4075535b95163402e4906b2e9b82788a2a6df"}, - {file = "safetensors-0.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9d752c97f6bbe327352f76e5b86442d776abc789249fc5e72eacb49e6916482"}, - {file = "safetensors-0.4.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:03f2bb92e61b055ef6cc22883ad1ae898010a95730fa988c60a23800eb742c2c"}, - {file = "safetensors-0.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:87bf3f91a9328a941acc44eceffd4e1f5f89b030985b2966637e582157173b98"}, - {file = "safetensors-0.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:20d218ec2b6899d29d6895419a58b6e44cc5ff8f0cc29fac8d236a8978ab702e"}, - {file = "safetensors-0.4.4-cp311-none-win32.whl", hash = "sha256:8079486118919f600c603536e2490ca37b3dbd3280e3ad6eaacfe6264605ac8a"}, - {file = "safetensors-0.4.4-cp311-none-win_amd64.whl", hash = "sha256:2f8c2eb0615e2e64ee27d478c7c13f51e5329d7972d9e15528d3e4cfc4a08f0d"}, - {file = "safetensors-0.4.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:baec5675944b4a47749c93c01c73d826ef7d42d36ba8d0dba36336fa80c76426"}, - {file = "safetensors-0.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f15117b96866401825f3e94543145028a2947d19974429246ce59403f49e77c6"}, - {file = "safetensors-0.4.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a13a9caea485df164c51be4eb0c87f97f790b7c3213d635eba2314d959fe929"}, - {file = "safetensors-0.4.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6b54bc4ca5f9b9bba8cd4fb91c24b2446a86b5ae7f8975cf3b7a277353c3127c"}, - {file = "safetensors-0.4.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:08332c22e03b651c8eb7bf5fc2de90044f3672f43403b3d9ac7e7e0f4f76495e"}, - {file = "safetensors-0.4.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bb62841e839ee992c37bb75e75891c7f4904e772db3691c59daaca5b4ab960e1"}, - {file = "safetensors-0.4.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e5b927acc5f2f59547270b0309a46d983edc44be64e1ca27a7fcb0474d6cd67"}, - {file = "safetensors-0.4.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2a69c71b1ae98a8021a09a0b43363b0143b0ce74e7c0e83cacba691b62655fb8"}, - {file = "safetensors-0.4.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23654ad162c02a5636f0cd520a0310902c4421aab1d91a0b667722a4937cc445"}, - {file = "safetensors-0.4.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0677c109d949cf53756859160b955b2e75b0eefe952189c184d7be30ecf7e858"}, - {file = "safetensors-0.4.4-cp312-none-win32.whl", hash = "sha256:a51d0ddd4deb8871c6de15a772ef40b3dbd26a3c0451bb9e66bc76fc5a784e5b"}, - {file = "safetensors-0.4.4-cp312-none-win_amd64.whl", hash = "sha256:2d065059e75a798bc1933c293b68d04d79b586bb7f8c921e0ca1e82759d0dbb1"}, - {file = "safetensors-0.4.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:9d625692578dd40a112df30c02a1adf068027566abd8e6a74893bb13d441c150"}, - {file = "safetensors-0.4.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7cabcf39c81e5b988d0adefdaea2eb9b4fd9bd62d5ed6559988c62f36bfa9a89"}, - {file = "safetensors-0.4.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8359bef65f49d51476e9811d59c015f0ddae618ee0e44144f5595278c9f8268c"}, - {file = "safetensors-0.4.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1a32c662e7df9226fd850f054a3ead0e4213a96a70b5ce37b2d26ba27004e013"}, - {file = "safetensors-0.4.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c329a4dcc395364a1c0d2d1574d725fe81a840783dda64c31c5a60fc7d41472c"}, - {file = "safetensors-0.4.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:239ee093b1db877c9f8fe2d71331a97f3b9c7c0d3ab9f09c4851004a11f44b65"}, - {file = "safetensors-0.4.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd574145d930cf9405a64f9923600879a5ce51d9f315443a5f706374841327b6"}, - {file = "safetensors-0.4.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f6784eed29f9e036acb0b7769d9e78a0dc2c72c2d8ba7903005350d817e287a4"}, - {file = "safetensors-0.4.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:65a4a6072436bf0a4825b1c295d248cc17e5f4651e60ee62427a5bcaa8622a7a"}, - {file = "safetensors-0.4.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:df81e3407630de060ae8313da49509c3caa33b1a9415562284eaf3d0c7705f9f"}, - {file = "safetensors-0.4.4-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:e4a0f374200e8443d9746e947ebb346c40f83a3970e75a685ade0adbba5c48d9"}, - {file = "safetensors-0.4.4-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:181fb5f3dee78dae7fd7ec57d02e58f7936498d587c6b7c1c8049ef448c8d285"}, - {file = "safetensors-0.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb4ac1d8f6b65ec84ddfacd275079e89d9df7c92f95675ba96c4f790a64df6e"}, - {file = "safetensors-0.4.4-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:76897944cd9239e8a70955679b531b9a0619f76e25476e57ed373322d9c2075d"}, - {file = "safetensors-0.4.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2a9e9d1a27e51a0f69e761a3d581c3af46729ec1c988fa1f839e04743026ae35"}, - {file = "safetensors-0.4.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:005ef9fc0f47cb9821c40793eb029f712e97278dae84de91cb2b4809b856685d"}, - {file = "safetensors-0.4.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26987dac3752688c696c77c3576f951dbbdb8c57f0957a41fb6f933cf84c0b62"}, - {file = "safetensors-0.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c05270b290acd8d249739f40d272a64dd597d5a4b90f27d830e538bc2549303c"}, - {file = "safetensors-0.4.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:068d3a33711fc4d93659c825a04480ff5a3854e1d78632cdc8f37fee917e8a60"}, - {file = "safetensors-0.4.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:063421ef08ca1021feea8b46951251b90ae91f899234dd78297cbe7c1db73b99"}, - {file = "safetensors-0.4.4-cp37-none-win32.whl", hash = "sha256:d52f5d0615ea83fd853d4e1d8acf93cc2e0223ad4568ba1e1f6ca72e94ea7b9d"}, - {file = "safetensors-0.4.4-cp37-none-win_amd64.whl", hash = "sha256:88a5ac3280232d4ed8e994cbc03b46a1807ce0aa123867b40c4a41f226c61f94"}, - {file = "safetensors-0.4.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:3467ab511bfe3360967d7dc53b49f272d59309e57a067dd2405b4d35e7dcf9dc"}, - {file = "safetensors-0.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2ab4c96d922e53670ce25fbb9b63d5ea972e244de4fa1dd97b590d9fd66aacef"}, - {file = "safetensors-0.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87df18fce4440477c3ef1fd7ae17c704a69a74a77e705a12be135ee0651a0c2d"}, - {file = "safetensors-0.4.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e5fe345b2bc7d88587149ac11def1f629d2671c4c34f5df38aed0ba59dc37f8"}, - {file = "safetensors-0.4.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9f1a3e01dce3cd54060791e7e24588417c98b941baa5974700eeb0b8eb65b0a0"}, - {file = "safetensors-0.4.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c6bf35e9a8998d8339fd9a05ac4ce465a4d2a2956cc0d837b67c4642ed9e947"}, - {file = "safetensors-0.4.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:166c0c52f6488b8538b2a9f3fbc6aad61a7261e170698779b371e81b45f0440d"}, - {file = "safetensors-0.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:87e9903b8668a16ef02c08ba4ebc91e57a49c481e9b5866e31d798632805014b"}, - {file = "safetensors-0.4.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a9c421153aa23c323bd8483d4155b4eee82c9a50ac11cccd83539104a8279c64"}, - {file = "safetensors-0.4.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a4b8617499b2371c7353302c5116a7e0a3a12da66389ce53140e607d3bf7b3d3"}, - {file = "safetensors-0.4.4-cp38-none-win32.whl", hash = "sha256:c6280f5aeafa1731f0a3709463ab33d8e0624321593951aefada5472f0b313fd"}, - {file = "safetensors-0.4.4-cp38-none-win_amd64.whl", hash = "sha256:6ceed6247fc2d33b2a7b7d25d8a0fe645b68798856e0bc7a9800c5fd945eb80f"}, - {file = "safetensors-0.4.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:5cf6c6f6193797372adf50c91d0171743d16299491c75acad8650107dffa9269"}, - {file = "safetensors-0.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:419010156b914a3e5da4e4adf992bee050924d0fe423c4b329e523e2c14c3547"}, - {file = "safetensors-0.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88f6fd5a5c1302ce79993cc5feeadcc795a70f953c762544d01fb02b2db4ea33"}, - {file = "safetensors-0.4.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d468cffb82d90789696d5b4d8b6ab8843052cba58a15296691a7a3df55143cd2"}, - {file = "safetensors-0.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9353c2af2dd467333d4850a16edb66855e795561cd170685178f706c80d2c71e"}, - {file = "safetensors-0.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:83c155b4a33368d9b9c2543e78f2452090fb030c52401ca608ef16fa58c98353"}, - {file = "safetensors-0.4.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9850754c434e636ce3dc586f534bb23bcbd78940c304775bee9005bf610e98f1"}, - {file = "safetensors-0.4.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:275f500b4d26f67b6ec05629a4600645231bd75e4ed42087a7c1801bff04f4b3"}, - {file = "safetensors-0.4.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5c2308de665b7130cd0e40a2329278226e4cf083f7400c51ca7e19ccfb3886f3"}, - {file = "safetensors-0.4.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e06a9ebc8656e030ccfe44634f2a541b4b1801cd52e390a53ad8bacbd65f8518"}, - {file = "safetensors-0.4.4-cp39-none-win32.whl", hash = "sha256:ef73df487b7c14b477016947c92708c2d929e1dee2bacdd6fff5a82ed4539537"}, - {file = "safetensors-0.4.4-cp39-none-win_amd64.whl", hash = "sha256:83d054818a8d1198d8bd8bc3ea2aac112a2c19def2bf73758321976788706398"}, - {file = "safetensors-0.4.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:1d1f34c71371f0e034004a0b583284b45d233dd0b5f64a9125e16b8a01d15067"}, - {file = "safetensors-0.4.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1a8043a33d58bc9b30dfac90f75712134ca34733ec3d8267b1bd682afe7194f5"}, - {file = "safetensors-0.4.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8db8f0c59c84792c12661f8efa85de160f80efe16b87a9d5de91b93f9e0bce3c"}, - {file = "safetensors-0.4.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cfc1fc38e37630dd12d519bdec9dcd4b345aec9930bb9ce0ed04461f49e58b52"}, - {file = "safetensors-0.4.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e5c9d86d9b13b18aafa88303e2cd21e677f5da2a14c828d2c460fe513af2e9a5"}, - {file = "safetensors-0.4.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:43251d7f29a59120a26f5a0d9583b9e112999e500afabcfdcb91606d3c5c89e3"}, - {file = "safetensors-0.4.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:2c42e9b277513b81cf507e6121c7b432b3235f980cac04f39f435b7902857f91"}, - {file = "safetensors-0.4.4-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3daacc9a4e3f428a84dd56bf31f20b768eb0b204af891ed68e1f06db9edf546f"}, - {file = "safetensors-0.4.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:218bbb9b883596715fc9997bb42470bf9f21bb832c3b34c2bf744d6fa8f2bbba"}, - {file = "safetensors-0.4.4-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bd5efc26b39f7fc82d4ab1d86a7f0644c8e34f3699c33f85bfa9a717a030e1b"}, - {file = "safetensors-0.4.4-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:56ad9776b65d8743f86698a1973292c966cf3abff627efc44ed60e66cc538ddd"}, - {file = "safetensors-0.4.4-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:30f23e6253c5f43a809dea02dc28a9f5fa747735dc819f10c073fe1b605e97d4"}, - {file = "safetensors-0.4.4-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:5512078d00263de6cb04e9d26c9ae17611098f52357fea856213e38dc462f81f"}, - {file = "safetensors-0.4.4-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b96c3d9266439d17f35fc2173111d93afc1162f168e95aed122c1ca517b1f8f1"}, - {file = "safetensors-0.4.4-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:08d464aa72a9a13826946b4fb9094bb4b16554bbea2e069e20bd903289b6ced9"}, - {file = "safetensors-0.4.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:210160816d5a36cf41f48f38473b6f70d7bcb4b0527bedf0889cc0b4c3bb07db"}, - {file = "safetensors-0.4.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb276a53717f2bcfb6df0bcf284d8a12069002508d4c1ca715799226024ccd45"}, - {file = "safetensors-0.4.4-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a2c28c6487f17d8db0089e8b2cdc13de859366b94cc6cdc50e1b0a4147b56551"}, - {file = "safetensors-0.4.4-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:7915f0c60e4e6e65d90f136d85dd3b429ae9191c36b380e626064694563dbd9f"}, - {file = "safetensors-0.4.4-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:00eea99ae422fbfa0b46065acbc58b46bfafadfcec179d4b4a32d5c45006af6c"}, - {file = "safetensors-0.4.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bb1ed4fcb0b3c2f3ea2c5767434622fe5d660e5752f21ac2e8d737b1e5e480bb"}, - {file = "safetensors-0.4.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:73fc9a0a4343188bdb421783e600bfaf81d0793cd4cce6bafb3c2ed567a74cd5"}, - {file = "safetensors-0.4.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c37e6b714200824c73ca6eaf007382de76f39466a46e97558b8dc4cf643cfbf"}, - {file = "safetensors-0.4.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f75698c5c5c542417ac4956acfc420f7d4a2396adca63a015fd66641ea751759"}, - {file = "safetensors-0.4.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ca1a209157f242eb183e209040097118472e169f2e069bfbd40c303e24866543"}, - {file = "safetensors-0.4.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:177f2b60a058f92a3cec7a1786c9106c29eca8987ecdfb79ee88126e5f47fa31"}, - {file = "safetensors-0.4.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ee9622e84fe6e4cd4f020e5fda70d6206feff3157731df7151d457fdae18e541"}, - {file = "safetensors-0.4.4.tar.gz", hash = "sha256:5fe3e9b705250d0172ed4e100a811543108653fb2b66b9e702a088ad03772a07"}, + {file = "safetensors-0.4.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a63eaccd22243c67e4f2b1c3e258b257effc4acd78f3b9d397edc8cf8f1298a7"}, + {file = "safetensors-0.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:23fc9b4ec7b602915cbb4ec1a7c1ad96d2743c322f20ab709e2c35d1b66dad27"}, + {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6885016f34bef80ea1085b7e99b3c1f92cb1be78a49839203060f67b40aee761"}, + {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:133620f443450429322f238fda74d512c4008621227fccf2f8cf4a76206fea7c"}, + {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4fb3e0609ec12d2a77e882f07cced530b8262027f64b75d399f1504ffec0ba56"}, + {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0f1dd769f064adc33831f5e97ad07babbd728427f98e3e1db6902e369122737"}, + {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6d156bdb26732feada84f9388a9f135528c1ef5b05fae153da365ad4319c4c5"}, + {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9e347d77e2c77eb7624400ccd09bed69d35c0332f417ce8c048d404a096c593b"}, + {file = "safetensors-0.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9f556eea3aec1d3d955403159fe2123ddd68e880f83954ee9b4a3f2e15e716b6"}, + {file = "safetensors-0.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9483f42be3b6bc8ff77dd67302de8ae411c4db39f7224dec66b0eb95822e4163"}, + {file = "safetensors-0.4.5-cp310-none-win32.whl", hash = "sha256:7389129c03fadd1ccc37fd1ebbc773f2b031483b04700923c3511d2a939252cc"}, + {file = "safetensors-0.4.5-cp310-none-win_amd64.whl", hash = "sha256:e98ef5524f8b6620c8cdef97220c0b6a5c1cef69852fcd2f174bb96c2bb316b1"}, + {file = "safetensors-0.4.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:21f848d7aebd5954f92538552d6d75f7c1b4500f51664078b5b49720d180e47c"}, + {file = "safetensors-0.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bb07000b19d41e35eecef9a454f31a8b4718a185293f0d0b1c4b61d6e4487971"}, + {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09dedf7c2fda934ee68143202acff6e9e8eb0ddeeb4cfc24182bef999efa9f42"}, + {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:59b77e4b7a708988d84f26de3ebead61ef1659c73dcbc9946c18f3b1786d2688"}, + {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d3bc83e14d67adc2e9387e511097f254bd1b43c3020440e708858c684cbac68"}, + {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39371fc551c1072976073ab258c3119395294cf49cdc1f8476794627de3130df"}, + {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6c19feda32b931cae0acd42748a670bdf56bee6476a046af20181ad3fee4090"}, + {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a659467495de201e2f282063808a41170448c78bada1e62707b07a27b05e6943"}, + {file = "safetensors-0.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bad5e4b2476949bcd638a89f71b6916fa9a5cae5c1ae7eede337aca2100435c0"}, + {file = "safetensors-0.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a3a315a6d0054bc6889a17f5668a73f94f7fe55121ff59e0a199e3519c08565f"}, + {file = "safetensors-0.4.5-cp311-none-win32.whl", hash = "sha256:a01e232e6d3d5cf8b1667bc3b657a77bdab73f0743c26c1d3c5dd7ce86bd3a92"}, + {file = "safetensors-0.4.5-cp311-none-win_amd64.whl", hash = "sha256:cbd39cae1ad3e3ef6f63a6f07296b080c951f24cec60188378e43d3713000c04"}, + {file = "safetensors-0.4.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:473300314e026bd1043cef391bb16a8689453363381561b8a3e443870937cc1e"}, + {file = "safetensors-0.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:801183a0f76dc647f51a2d9141ad341f9665602a7899a693207a82fb102cc53e"}, + {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1524b54246e422ad6fb6aea1ac71edeeb77666efa67230e1faf6999df9b2e27f"}, + {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b3139098e3e8b2ad7afbca96d30ad29157b50c90861084e69fcb80dec7430461"}, + {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65573dc35be9059770808e276b017256fa30058802c29e1038eb1c00028502ea"}, + {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd33da8e9407559f8779c82a0448e2133737f922d71f884da27184549416bfed"}, + {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3685ce7ed036f916316b567152482b7e959dc754fcc4a8342333d222e05f407c"}, + {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dde2bf390d25f67908278d6f5d59e46211ef98e44108727084d4637ee70ab4f1"}, + {file = "safetensors-0.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7469d70d3de970b1698d47c11ebbf296a308702cbaae7fcb993944751cf985f4"}, + {file = "safetensors-0.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3a6ba28118636a130ccbb968bc33d4684c48678695dba2590169d5ab03a45646"}, + {file = "safetensors-0.4.5-cp312-none-win32.whl", hash = "sha256:c859c7ed90b0047f58ee27751c8e56951452ed36a67afee1b0a87847d065eec6"}, + {file = "safetensors-0.4.5-cp312-none-win_amd64.whl", hash = "sha256:b5a8810ad6a6f933fff6c276eae92c1da217b39b4d8b1bc1c0b8af2d270dc532"}, + {file = "safetensors-0.4.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:25e5f8e2e92a74f05b4ca55686234c32aac19927903792b30ee6d7bd5653d54e"}, + {file = "safetensors-0.4.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:81efb124b58af39fcd684254c645e35692fea81c51627259cdf6d67ff4458916"}, + {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:585f1703a518b437f5103aa9cf70e9bd437cb78eea9c51024329e4fb8a3e3679"}, + {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4b99fbf72e3faf0b2f5f16e5e3458b93b7d0a83984fe8d5364c60aa169f2da89"}, + {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b17b299ca9966ca983ecda1c0791a3f07f9ca6ab5ded8ef3d283fff45f6bcd5f"}, + {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:76ded72f69209c9780fdb23ea89e56d35c54ae6abcdec67ccb22af8e696e449a"}, + {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2783956926303dcfeb1de91a4d1204cd4089ab441e622e7caee0642281109db3"}, + {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d94581aab8c6b204def4d7320f07534d6ee34cd4855688004a4354e63b639a35"}, + {file = "safetensors-0.4.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:67e1e7cb8678bb1b37ac48ec0df04faf689e2f4e9e81e566b5c63d9f23748523"}, + {file = "safetensors-0.4.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:dbd280b07e6054ea68b0cb4b16ad9703e7d63cd6890f577cb98acc5354780142"}, + {file = "safetensors-0.4.5-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:77d9b228da8374c7262046a36c1f656ba32a93df6cc51cd4453af932011e77f1"}, + {file = "safetensors-0.4.5-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:500cac01d50b301ab7bb192353317035011c5ceeef0fca652f9f43c000bb7f8d"}, + {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75331c0c746f03158ded32465b7d0b0e24c5a22121743662a2393439c43a45cf"}, + {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:670e95fe34e0d591d0529e5e59fd9d3d72bc77b1444fcaa14dccda4f36b5a38b"}, + {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:098923e2574ff237c517d6e840acada8e5b311cb1fa226019105ed82e9c3b62f"}, + {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:13ca0902d2648775089fa6a0c8fc9e6390c5f8ee576517d33f9261656f851e3f"}, + {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f0032bedc869c56f8d26259fe39cd21c5199cd57f2228d817a0e23e8370af25"}, + {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f4b15f51b4f8f2a512341d9ce3475cacc19c5fdfc5db1f0e19449e75f95c7dc8"}, + {file = "safetensors-0.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f6594d130d0ad933d885c6a7b75c5183cb0e8450f799b80a39eae2b8508955eb"}, + {file = "safetensors-0.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:60c828a27e852ded2c85fc0f87bf1ec20e464c5cd4d56ff0e0711855cc2e17f8"}, + {file = "safetensors-0.4.5-cp37-none-win32.whl", hash = "sha256:6d3de65718b86c3eeaa8b73a9c3d123f9307a96bbd7be9698e21e76a56443af5"}, + {file = "safetensors-0.4.5-cp37-none-win_amd64.whl", hash = "sha256:5a2d68a523a4cefd791156a4174189a4114cf0bf9c50ceb89f261600f3b2b81a"}, + {file = "safetensors-0.4.5-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:e7a97058f96340850da0601a3309f3d29d6191b0702b2da201e54c6e3e44ccf0"}, + {file = "safetensors-0.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:63bfd425e25f5c733f572e2246e08a1c38bd6f2e027d3f7c87e2e43f228d1345"}, + {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3664ac565d0e809b0b929dae7ccd74e4d3273cd0c6d1220c6430035befb678e"}, + {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:313514b0b9b73ff4ddfb4edd71860696dbe3c1c9dc4d5cc13dbd74da283d2cbf"}, + {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31fa33ee326f750a2f2134a6174773c281d9a266ccd000bd4686d8021f1f3dac"}, + {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:09566792588d77b68abe53754c9f1308fadd35c9f87be939e22c623eaacbed6b"}, + {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309aaec9b66cbf07ad3a2e5cb8a03205663324fea024ba391594423d0f00d9fe"}, + {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:53946c5813b8f9e26103c5efff4a931cc45d874f45229edd68557ffb35ffb9f8"}, + {file = "safetensors-0.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:868f9df9e99ad1e7f38c52194063a982bc88fedc7d05096f4f8160403aaf4bd6"}, + {file = "safetensors-0.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9cc9449bd0b0bc538bd5e268221f0c5590bc5c14c1934a6ae359d44410dc68c4"}, + {file = "safetensors-0.4.5-cp38-none-win32.whl", hash = "sha256:83c4f13a9e687335c3928f615cd63a37e3f8ef072a3f2a0599fa09f863fb06a2"}, + {file = "safetensors-0.4.5-cp38-none-win_amd64.whl", hash = "sha256:b98d40a2ffa560653f6274e15b27b3544e8e3713a44627ce268f419f35c49478"}, + {file = "safetensors-0.4.5-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:cf727bb1281d66699bef5683b04d98c894a2803442c490a8d45cd365abfbdeb2"}, + {file = "safetensors-0.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:96f1d038c827cdc552d97e71f522e1049fef0542be575421f7684756a748e457"}, + {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:139fbee92570ecea774e6344fee908907db79646d00b12c535f66bc78bd5ea2c"}, + {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c36302c1c69eebb383775a89645a32b9d266878fab619819ce660309d6176c9b"}, + {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d641f5b8149ea98deb5ffcf604d764aad1de38a8285f86771ce1abf8e74c4891"}, + {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b4db6a61d968de73722b858038c616a1bebd4a86abe2688e46ca0cc2d17558f2"}, + {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b75a616e02f21b6f1d5785b20cecbab5e2bd3f6358a90e8925b813d557666ec1"}, + {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:788ee7d04cc0e0e7f944c52ff05f52a4415b312f5efd2ee66389fb7685ee030c"}, + {file = "safetensors-0.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:87bc42bd04fd9ca31396d3ca0433db0be1411b6b53ac5a32b7845a85d01ffc2e"}, + {file = "safetensors-0.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4037676c86365a721a8c9510323a51861d703b399b78a6b4486a54a65a975fca"}, + {file = "safetensors-0.4.5-cp39-none-win32.whl", hash = "sha256:1500418454529d0ed5c1564bda376c4ddff43f30fce9517d9bee7bcce5a8ef50"}, + {file = "safetensors-0.4.5-cp39-none-win_amd64.whl", hash = "sha256:9d1a94b9d793ed8fe35ab6d5cea28d540a46559bafc6aae98f30ee0867000cab"}, + {file = "safetensors-0.4.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:fdadf66b5a22ceb645d5435a0be7a0292ce59648ca1d46b352f13cff3ea80410"}, + {file = "safetensors-0.4.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d42ffd4c2259f31832cb17ff866c111684c87bd930892a1ba53fed28370c918c"}, + {file = "safetensors-0.4.5-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd8a1f6d2063a92cd04145c7fd9e31a1c7d85fbec20113a14b487563fdbc0597"}, + {file = "safetensors-0.4.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:951d2fcf1817f4fb0ef0b48f6696688a4e852a95922a042b3f96aaa67eedc920"}, + {file = "safetensors-0.4.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6ac85d9a8c1af0e3132371d9f2d134695a06a96993c2e2f0bbe25debb9e3f67a"}, + {file = "safetensors-0.4.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:e3cec4a29eb7fe8da0b1c7988bc3828183080439dd559f720414450de076fcab"}, + {file = "safetensors-0.4.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:21742b391b859e67b26c0b2ac37f52c9c0944a879a25ad2f9f9f3cd61e7fda8f"}, + {file = "safetensors-0.4.5-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c7db3006a4915151ce1913652e907cdede299b974641a83fbc092102ac41b644"}, + {file = "safetensors-0.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f68bf99ea970960a237f416ea394e266e0361895753df06e3e06e6ea7907d98b"}, + {file = "safetensors-0.4.5-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8158938cf3324172df024da511839d373c40fbfaa83e9abf467174b2910d7b4c"}, + {file = "safetensors-0.4.5-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:540ce6c4bf6b58cb0fd93fa5f143bc0ee341c93bb4f9287ccd92cf898cc1b0dd"}, + {file = "safetensors-0.4.5-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bfeaa1a699c6b9ed514bd15e6a91e74738b71125a9292159e3d6b7f0a53d2cde"}, + {file = "safetensors-0.4.5-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:01c8f00da537af711979e1b42a69a8ec9e1d7112f208e0e9b8a35d2c381085ef"}, + {file = "safetensors-0.4.5-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a0dd565f83b30f2ca79b5d35748d0d99dd4b3454f80e03dfb41f0038e3bdf180"}, + {file = "safetensors-0.4.5-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:023b6e5facda76989f4cba95a861b7e656b87e225f61811065d5c501f78cdb3f"}, + {file = "safetensors-0.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9633b663393d5796f0b60249549371e392b75a0b955c07e9c6f8708a87fc841f"}, + {file = "safetensors-0.4.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78dd8adfb48716233c45f676d6e48534d34b4bceb50162c13d1f0bdf6f78590a"}, + {file = "safetensors-0.4.5-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8e8deb16c4321d61ae72533b8451ec4a9af8656d1c61ff81aa49f966406e4b68"}, + {file = "safetensors-0.4.5-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:52452fa5999dc50c4decaf0c53aa28371f7f1e0fe5c2dd9129059fbe1e1599c7"}, + {file = "safetensors-0.4.5-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d5f23198821e227cfc52d50fa989813513db381255c6d100927b012f0cfec63d"}, + {file = "safetensors-0.4.5-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f4beb84b6073b1247a773141a6331117e35d07134b3bb0383003f39971d414bb"}, + {file = "safetensors-0.4.5-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:68814d599d25ed2fdd045ed54d370d1d03cf35e02dce56de44c651f828fb9b7b"}, + {file = "safetensors-0.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0b6453c54c57c1781292c46593f8a37254b8b99004c68d6c3ce229688931a22"}, + {file = "safetensors-0.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:adaa9c6dead67e2dd90d634f89131e43162012479d86e25618e821a03d1eb1dc"}, + {file = "safetensors-0.4.5-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73e7d408e9012cd17511b382b43547850969c7979efc2bc353f317abaf23c84c"}, + {file = "safetensors-0.4.5-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:775409ce0fcc58b10773fdb4221ed1eb007de10fe7adbdf8f5e8a56096b6f0bc"}, + {file = "safetensors-0.4.5-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:834001bed193e4440c4a3950a31059523ee5090605c907c66808664c932b549c"}, + {file = "safetensors-0.4.5.tar.gz", hash = "sha256:d73de19682deabb02524b3d5d1f8b3aaba94c72f1bbfc7911b9b9d5d391c0310"}, ] [package.extras] @@ -7947,6 +8149,84 @@ tensorflow = ["safetensors[numpy]", "tensorflow (>=2.11.0)"] testing = ["h5py (>=3.7.0)", "huggingface-hub (>=0.12.1)", "hypothesis (>=6.70.2)", "pytest (>=7.2.0)", "pytest-benchmark (>=4.0.0)", "safetensors[numpy]", "setuptools-rust (>=1.5.2)"] torch = ["safetensors[numpy]", "torch (>=1.10)"] +[[package]] +name = "sagemaker" +version = "2.231.0" +description = "Open source library for training and deploying models on Amazon SageMaker." +optional = false +python-versions = ">=3.8" +files = [ + {file = "sagemaker-2.231.0-py3-none-any.whl", hash = "sha256:5b6d84484a58c6ac8b22af42c6c5e0ea3c5f42d719345fe6aafba42f93635000"}, + {file = "sagemaker-2.231.0.tar.gz", hash = "sha256:d49ee9c35725832dd9810708938af723201b831e82924a3a6ac1c4260a3d8239"}, +] + +[package.dependencies] +attrs = ">=23.1.0,<24" +boto3 = ">=1.34.142,<2.0" +cloudpickle = "2.2.1" +docker = "*" +google-pasta = "*" +importlib-metadata = ">=1.4.0,<7.0" +jsonschema = "*" +numpy = ">=1.9.0,<2.0" +packaging = ">=20.0" +pandas = "*" +pathos = "*" +platformdirs = "*" +protobuf = ">=3.12,<5.0" +psutil = "*" +pyyaml = ">=6.0,<7.0" +requests = "*" +sagemaker-core = ">=1.0.0,<2.0.0" +schema = "*" +smdebug-rulesconfig = "1.0.1" +tblib = ">=1.7.0,<4" +tqdm = "*" +urllib3 = ">=1.26.8,<3.0.0" + +[package.extras] +all = ["accelerate (>=0.24.1,<=0.27.0)", "docker (>=5.0.2,<8.0.0)", "fastapi (>=0.111.0)", "nest-asyncio", "pyspark (==3.3.1)", "pyyaml (>=5.4.1,<7)", "sagemaker-feature-store-pyspark-3-3", "sagemaker-schema-inference-artifacts (>=0.0.5)", "scipy (==1.10.1)", "urllib3 (>=1.26.8,<3.0.0)", "uvicorn (>=0.30.1)"] +feature-processor = ["pyspark (==3.3.1)", "sagemaker-feature-store-pyspark-3-3"] +huggingface = ["accelerate (>=0.24.1,<=0.27.0)", "fastapi (>=0.111.0)", "nest-asyncio", "sagemaker-schema-inference-artifacts (>=0.0.5)", "uvicorn (>=0.30.1)"] +local = ["docker (>=5.0.2,<8.0.0)", "pyyaml (>=5.4.1,<7)", "urllib3 (>=1.26.8,<3.0.0)"] +scipy = ["scipy (==1.10.1)"] +test = ["accelerate (>=0.24.1,<=0.27.0)", "apache-airflow (==2.9.3)", "apache-airflow-providers-amazon (==7.2.1)", "attrs (>=23.1.0,<24)", "awslogs (==0.14.0)", "black (==24.3.0)", "build[virtualenv] (==1.2.1)", "cloudpickle (==2.2.1)", "contextlib2 (==21.6.0)", "coverage (>=5.2,<6.2)", "docker (>=5.0.2,<8.0.0)", "fabric (==2.6.0)", "fastapi (>=0.111.0)", "flake8 (==4.0.1)", "huggingface-hub (>=0.23.4)", "jinja2 (==3.1.4)", "mlflow (>=2.12.2,<2.13)", "mock (==4.0.3)", "nbformat (>=5.9,<6)", "nest-asyncio", "numpy (>=1.24.0)", "onnx (>=1.15.0)", "pandas (>=1.3.5,<1.5)", "pillow (>=10.0.1,<=11)", "pyspark (==3.3.1)", "pytest (==6.2.5)", "pytest-cov (==3.0.0)", "pytest-rerunfailures (==10.2)", "pytest-timeout (==2.1.0)", "pytest-xdist (==2.4.0)", "pyvis (==0.2.1)", "pyyaml (==6.0)", "pyyaml (>=5.4.1,<7)", "requests (==2.32.2)", "sagemaker-experiments (==0.1.35)", "sagemaker-feature-store-pyspark-3-3", "sagemaker-schema-inference-artifacts (>=0.0.5)", "schema (==0.7.5)", "scikit-learn (==1.3.0)", "scipy (==1.10.1)", "stopit (==1.1.2)", "tensorflow (>=2.1,<=2.16)", "tox (==3.24.5)", "tritonclient[http] (<2.37.0)", "urllib3 (>=1.26.8,<3.0.0)", "uvicorn (>=0.30.1)", "xgboost (>=1.6.2,<=1.7.6)"] + +[[package]] +name = "sagemaker-core" +version = "1.0.2" +description = "An python package for sagemaker core functionalities" +optional = false +python-versions = ">=3.8" +files = [ + {file = "sagemaker_core-1.0.2-py3-none-any.whl", hash = "sha256:ce8d38a4a32efa83e4bc037a8befc7e29f87cd3eaf99acc4472b607f75a0f45a"}, + {file = "sagemaker_core-1.0.2.tar.gz", hash = "sha256:8fb942aac5e7ed928dab512ffe6facf8c6bdd4595df63c59c0bd0795ea434f8d"}, +] + +[package.dependencies] +boto3 = ">=1.34.0,<2.0.0" +importlib-metadata = ">=1.4.0,<7.0" +jsonschema = "<5.0.0" +mock = ">4.0,<5.0" +platformdirs = ">=4.0.0,<5.0.0" +pydantic = ">=1.7.0,<3.0.0" +PyYAML = ">=6.0,<7.0" +rich = ">=13.0.0,<14.0.0" + +[package.extras] +codegen = ["black (>=24.3.0,<25.0.0)", "pandas (>=2.0.0,<3.0.0)", "pylint (>=3.0.0,<4.0.0)", "pytest (>=8.0.0,<9.0.0)"] + +[[package]] +name = "schema" +version = "0.7.7" +description = "Simple data validation library" +optional = false +python-versions = "*" +files = [ + {file = "schema-0.7.7-py2.py3-none-any.whl", hash = "sha256:5d976a5b50f36e74e2157b47097b60002bd4d42e65425fcc9c9befadb4255dde"}, + {file = "schema-0.7.7.tar.gz", hash = "sha256:7da553abd2958a19dc2547c388cde53398b39196175a9be59ea1caf5ab0a1807"}, +] + [[package]] name = "scikit-learn" version = "1.5.1" @@ -8094,19 +8374,23 @@ tornado = ["tornado (>=5)"] [[package]] name = "setuptools" -version = "73.0.1" +version = "74.1.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-73.0.1-py3-none-any.whl", hash = "sha256:b208925fcb9f7af924ed2dc04708ea89791e24bde0d3020b27df0e116088b34e"}, - {file = "setuptools-73.0.1.tar.gz", hash = "sha256:d59a3e788ab7e012ab2c4baed1b376da6366883ee20d7a5fc426816e3d7b1193"}, + {file = "setuptools-74.1.2-py3-none-any.whl", hash = "sha256:5f4c08aa4d3ebcb57a50c33b1b07e94315d7fc7230f7115e47fc99776c8ce308"}, + {file = "setuptools-74.1.2.tar.gz", hash = "sha256:95b40ed940a1c67eb70fc099094bd6e99c6ee7c23aa2306f4d2697ba7916f9c6"}, ] [package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] [[package]] name = "sgmllib3k" @@ -8215,6 +8499,17 @@ files = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] +[[package]] +name = "smdebug-rulesconfig" +version = "1.0.1" +description = "SMDebug RulesConfig" +optional = false +python-versions = ">=2.7" +files = [ + {file = "smdebug_rulesconfig-1.0.1-py2.py3-none-any.whl", hash = "sha256:104da3e6931ecf879dfc687ca4bbb3bee5ea2bc27f4478e9dbb3ee3655f1ae61"}, + {file = "smdebug_rulesconfig-1.0.1.tar.gz", hash = "sha256:7a19e6eb2e6bcfefbc07e4a86ef7a88f32495001a038bf28c7d8e77ab793fcd6"}, +] + [[package]] name = "sniffio" version = "1.3.1" @@ -8250,60 +8545,60 @@ files = [ [[package]] name = "sqlalchemy" -version = "2.0.32" +version = "2.0.34" description = "Database Abstraction Library" optional = false python-versions = ">=3.7" files = [ - {file = "SQLAlchemy-2.0.32-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0c9045ecc2e4db59bfc97b20516dfdf8e41d910ac6fb667ebd3a79ea54084619"}, - {file = "SQLAlchemy-2.0.32-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1467940318e4a860afd546ef61fefb98a14d935cd6817ed07a228c7f7c62f389"}, - {file = "SQLAlchemy-2.0.32-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5954463675cb15db8d4b521f3566a017c8789222b8316b1e6934c811018ee08b"}, - {file = "SQLAlchemy-2.0.32-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:167e7497035c303ae50651b351c28dc22a40bb98fbdb8468cdc971821b1ae533"}, - {file = "SQLAlchemy-2.0.32-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b27dfb676ac02529fb6e343b3a482303f16e6bc3a4d868b73935b8792edb52d0"}, - {file = "SQLAlchemy-2.0.32-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bf2360a5e0f7bd75fa80431bf8ebcfb920c9f885e7956c7efde89031695cafb8"}, - {file = "SQLAlchemy-2.0.32-cp310-cp310-win32.whl", hash = "sha256:306fe44e754a91cd9d600a6b070c1f2fadbb4a1a257b8781ccf33c7067fd3e4d"}, - {file = "SQLAlchemy-2.0.32-cp310-cp310-win_amd64.whl", hash = "sha256:99db65e6f3ab42e06c318f15c98f59a436f1c78179e6a6f40f529c8cc7100b22"}, - {file = "SQLAlchemy-2.0.32-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:21b053be28a8a414f2ddd401f1be8361e41032d2ef5884b2f31d31cb723e559f"}, - {file = "SQLAlchemy-2.0.32-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b178e875a7a25b5938b53b006598ee7645172fccafe1c291a706e93f48499ff5"}, - {file = "SQLAlchemy-2.0.32-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723a40ee2cc7ea653645bd4cf024326dea2076673fc9d3d33f20f6c81db83e1d"}, - {file = "SQLAlchemy-2.0.32-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:295ff8689544f7ee7e819529633d058bd458c1fd7f7e3eebd0f9268ebc56c2a0"}, - {file = "SQLAlchemy-2.0.32-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:49496b68cd190a147118af585173ee624114dfb2e0297558c460ad7495f9dfe2"}, - {file = "SQLAlchemy-2.0.32-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:acd9b73c5c15f0ec5ce18128b1fe9157ddd0044abc373e6ecd5ba376a7e5d961"}, - {file = "SQLAlchemy-2.0.32-cp311-cp311-win32.whl", hash = "sha256:9365a3da32dabd3e69e06b972b1ffb0c89668994c7e8e75ce21d3e5e69ddef28"}, - {file = "SQLAlchemy-2.0.32-cp311-cp311-win_amd64.whl", hash = "sha256:8bd63d051f4f313b102a2af1cbc8b80f061bf78f3d5bd0843ff70b5859e27924"}, - {file = "SQLAlchemy-2.0.32-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6bab3db192a0c35e3c9d1560eb8332463e29e5507dbd822e29a0a3c48c0a8d92"}, - {file = "SQLAlchemy-2.0.32-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:19d98f4f58b13900d8dec4ed09dd09ef292208ee44cc9c2fe01c1f0a2fe440e9"}, - {file = "SQLAlchemy-2.0.32-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd33c61513cb1b7371fd40cf221256456d26a56284e7d19d1f0b9f1eb7dd7e8"}, - {file = "SQLAlchemy-2.0.32-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d6ba0497c1d066dd004e0f02a92426ca2df20fac08728d03f67f6960271feec"}, - {file = "SQLAlchemy-2.0.32-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2b6be53e4fde0065524f1a0a7929b10e9280987b320716c1509478b712a7688c"}, - {file = "SQLAlchemy-2.0.32-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:916a798f62f410c0b80b63683c8061f5ebe237b0f4ad778739304253353bc1cb"}, - {file = "SQLAlchemy-2.0.32-cp312-cp312-win32.whl", hash = "sha256:31983018b74908ebc6c996a16ad3690301a23befb643093fcfe85efd292e384d"}, - {file = "SQLAlchemy-2.0.32-cp312-cp312-win_amd64.whl", hash = "sha256:4363ed245a6231f2e2957cccdda3c776265a75851f4753c60f3004b90e69bfeb"}, - {file = "SQLAlchemy-2.0.32-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b8afd5b26570bf41c35c0121801479958b4446751a3971fb9a480c1afd85558e"}, - {file = "SQLAlchemy-2.0.32-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c750987fc876813f27b60d619b987b057eb4896b81117f73bb8d9918c14f1cad"}, - {file = "SQLAlchemy-2.0.32-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ada0102afff4890f651ed91120c1120065663506b760da4e7823913ebd3258be"}, - {file = "SQLAlchemy-2.0.32-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:78c03d0f8a5ab4f3034c0e8482cfcc415a3ec6193491cfa1c643ed707d476f16"}, - {file = "SQLAlchemy-2.0.32-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:3bd1cae7519283ff525e64645ebd7a3e0283f3c038f461ecc1c7b040a0c932a1"}, - {file = "SQLAlchemy-2.0.32-cp37-cp37m-win32.whl", hash = "sha256:01438ebcdc566d58c93af0171c74ec28efe6a29184b773e378a385e6215389da"}, - {file = "SQLAlchemy-2.0.32-cp37-cp37m-win_amd64.whl", hash = "sha256:4979dc80fbbc9d2ef569e71e0896990bc94df2b9fdbd878290bd129b65ab579c"}, - {file = "SQLAlchemy-2.0.32-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c742be912f57586ac43af38b3848f7688863a403dfb220193a882ea60e1ec3a"}, - {file = "SQLAlchemy-2.0.32-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:62e23d0ac103bcf1c5555b6c88c114089587bc64d048fef5bbdb58dfd26f96da"}, - {file = "SQLAlchemy-2.0.32-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:251f0d1108aab8ea7b9aadbd07fb47fb8e3a5838dde34aa95a3349876b5a1f1d"}, - {file = "SQLAlchemy-2.0.32-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ef18a84e5116340e38eca3e7f9eeaaef62738891422e7c2a0b80feab165905f"}, - {file = "SQLAlchemy-2.0.32-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:3eb6a97a1d39976f360b10ff208c73afb6a4de86dd2a6212ddf65c4a6a2347d5"}, - {file = "SQLAlchemy-2.0.32-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0c1c9b673d21477cec17ab10bc4decb1322843ba35b481585facd88203754fc5"}, - {file = "SQLAlchemy-2.0.32-cp38-cp38-win32.whl", hash = "sha256:c41a2b9ca80ee555decc605bd3c4520cc6fef9abde8fd66b1cf65126a6922d65"}, - {file = "SQLAlchemy-2.0.32-cp38-cp38-win_amd64.whl", hash = "sha256:8a37e4d265033c897892279e8adf505c8b6b4075f2b40d77afb31f7185cd6ecd"}, - {file = "SQLAlchemy-2.0.32-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:52fec964fba2ef46476312a03ec8c425956b05c20220a1a03703537824b5e8e1"}, - {file = "SQLAlchemy-2.0.32-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:328429aecaba2aee3d71e11f2477c14eec5990fb6d0e884107935f7fb6001632"}, - {file = "SQLAlchemy-2.0.32-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85a01b5599e790e76ac3fe3aa2f26e1feba56270023d6afd5550ed63c68552b3"}, - {file = "SQLAlchemy-2.0.32-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aaf04784797dcdf4c0aa952c8d234fa01974c4729db55c45732520ce12dd95b4"}, - {file = "SQLAlchemy-2.0.32-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4488120becf9b71b3ac718f4138269a6be99a42fe023ec457896ba4f80749525"}, - {file = "SQLAlchemy-2.0.32-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:14e09e083a5796d513918a66f3d6aedbc131e39e80875afe81d98a03312889e6"}, - {file = "SQLAlchemy-2.0.32-cp39-cp39-win32.whl", hash = "sha256:0d322cc9c9b2154ba7e82f7bf25ecc7c36fbe2d82e2933b3642fc095a52cfc78"}, - {file = "SQLAlchemy-2.0.32-cp39-cp39-win_amd64.whl", hash = "sha256:7dd8583df2f98dea28b5cd53a1beac963f4f9d087888d75f22fcc93a07cf8d84"}, - {file = "SQLAlchemy-2.0.32-py3-none-any.whl", hash = "sha256:e567a8793a692451f706b363ccf3c45e056b67d90ead58c3bc9471af5d212202"}, - {file = "SQLAlchemy-2.0.32.tar.gz", hash = "sha256:c1b88cc8b02b6a5f0efb0345a03672d4c897dc7d92585176f88c67346f565ea8"}, + {file = "SQLAlchemy-2.0.34-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:95d0b2cf8791ab5fb9e3aa3d9a79a0d5d51f55b6357eecf532a120ba3b5524db"}, + {file = "SQLAlchemy-2.0.34-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:243f92596f4fd4c8bd30ab8e8dd5965afe226363d75cab2468f2c707f64cd83b"}, + {file = "SQLAlchemy-2.0.34-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ea54f7300553af0a2a7235e9b85f4204e1fc21848f917a3213b0e0818de9a24"}, + {file = "SQLAlchemy-2.0.34-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:173f5f122d2e1bff8fbd9f7811b7942bead1f5e9f371cdf9e670b327e6703ebd"}, + {file = "SQLAlchemy-2.0.34-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:196958cde924a00488e3e83ff917be3b73cd4ed8352bbc0f2989333176d1c54d"}, + {file = "SQLAlchemy-2.0.34-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bd90c221ed4e60ac9d476db967f436cfcecbd4ef744537c0f2d5291439848768"}, + {file = "SQLAlchemy-2.0.34-cp310-cp310-win32.whl", hash = "sha256:3166dfff2d16fe9be3241ee60ece6fcb01cf8e74dd7c5e0b64f8e19fab44911b"}, + {file = "SQLAlchemy-2.0.34-cp310-cp310-win_amd64.whl", hash = "sha256:6831a78bbd3c40f909b3e5233f87341f12d0b34a58f14115c9e94b4cdaf726d3"}, + {file = "SQLAlchemy-2.0.34-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7db3db284a0edaebe87f8f6642c2b2c27ed85c3e70064b84d1c9e4ec06d5d84"}, + {file = "SQLAlchemy-2.0.34-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:430093fce0efc7941d911d34f75a70084f12f6ca5c15d19595c18753edb7c33b"}, + {file = "SQLAlchemy-2.0.34-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79cb400c360c7c210097b147c16a9e4c14688a6402445ac848f296ade6283bbc"}, + {file = "SQLAlchemy-2.0.34-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb1b30f31a36c7f3fee848391ff77eebdd3af5750bf95fbf9b8b5323edfdb4ec"}, + {file = "SQLAlchemy-2.0.34-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8fddde2368e777ea2a4891a3fb4341e910a056be0bb15303bf1b92f073b80c02"}, + {file = "SQLAlchemy-2.0.34-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:80bd73ea335203b125cf1d8e50fef06be709619eb6ab9e7b891ea34b5baa2287"}, + {file = "SQLAlchemy-2.0.34-cp311-cp311-win32.whl", hash = "sha256:6daeb8382d0df526372abd9cb795c992e18eed25ef2c43afe518c73f8cccb721"}, + {file = "SQLAlchemy-2.0.34-cp311-cp311-win_amd64.whl", hash = "sha256:5bc08e75ed11693ecb648b7a0a4ed80da6d10845e44be0c98c03f2f880b68ff4"}, + {file = "SQLAlchemy-2.0.34-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:53e68b091492c8ed2bd0141e00ad3089bcc6bf0e6ec4142ad6505b4afe64163e"}, + {file = "SQLAlchemy-2.0.34-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bcd18441a49499bf5528deaa9dee1f5c01ca491fc2791b13604e8f972877f812"}, + {file = "SQLAlchemy-2.0.34-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:165bbe0b376541092bf49542bd9827b048357f4623486096fc9aaa6d4e7c59a2"}, + {file = "SQLAlchemy-2.0.34-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3330415cd387d2b88600e8e26b510d0370db9b7eaf984354a43e19c40df2e2b"}, + {file = "SQLAlchemy-2.0.34-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:97b850f73f8abbffb66ccbab6e55a195a0eb655e5dc74624d15cff4bfb35bd74"}, + {file = "SQLAlchemy-2.0.34-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7cee4c6917857fd6121ed84f56d1dc78eb1d0e87f845ab5a568aba73e78adf83"}, + {file = "SQLAlchemy-2.0.34-cp312-cp312-win32.whl", hash = "sha256:fbb034f565ecbe6c530dff948239377ba859420d146d5f62f0271407ffb8c580"}, + {file = "SQLAlchemy-2.0.34-cp312-cp312-win_amd64.whl", hash = "sha256:707c8f44931a4facd4149b52b75b80544a8d824162602b8cd2fe788207307f9a"}, + {file = "SQLAlchemy-2.0.34-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:24af3dc43568f3780b7e1e57c49b41d98b2d940c1fd2e62d65d3928b6f95f021"}, + {file = "SQLAlchemy-2.0.34-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e60ed6ef0a35c6b76b7640fe452d0e47acc832ccbb8475de549a5cc5f90c2c06"}, + {file = "SQLAlchemy-2.0.34-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:413c85cd0177c23e32dee6898c67a5f49296640041d98fddb2c40888fe4daa2e"}, + {file = "SQLAlchemy-2.0.34-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:25691f4adfb9d5e796fd48bf1432272f95f4bbe5f89c475a788f31232ea6afba"}, + {file = "SQLAlchemy-2.0.34-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:526ce723265643dbc4c7efb54f56648cc30e7abe20f387d763364b3ce7506c82"}, + {file = "SQLAlchemy-2.0.34-cp37-cp37m-win32.whl", hash = "sha256:13be2cc683b76977a700948411a94c67ad8faf542fa7da2a4b167f2244781cf3"}, + {file = "SQLAlchemy-2.0.34-cp37-cp37m-win_amd64.whl", hash = "sha256:e54ef33ea80d464c3dcfe881eb00ad5921b60f8115ea1a30d781653edc2fd6a2"}, + {file = "SQLAlchemy-2.0.34-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:43f28005141165edd11fbbf1541c920bd29e167b8bbc1fb410d4fe2269c1667a"}, + {file = "SQLAlchemy-2.0.34-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b68094b165a9e930aedef90725a8fcfafe9ef95370cbb54abc0464062dbf808f"}, + {file = "SQLAlchemy-2.0.34-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a1e03db964e9d32f112bae36f0cc1dcd1988d096cfd75d6a588a3c3def9ab2b"}, + {file = "SQLAlchemy-2.0.34-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:203d46bddeaa7982f9c3cc693e5bc93db476ab5de9d4b4640d5c99ff219bee8c"}, + {file = "SQLAlchemy-2.0.34-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ae92bebca3b1e6bd203494e5ef919a60fb6dfe4d9a47ed2453211d3bd451b9f5"}, + {file = "SQLAlchemy-2.0.34-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:9661268415f450c95f72f0ac1217cc6f10256f860eed85c2ae32e75b60278ad8"}, + {file = "SQLAlchemy-2.0.34-cp38-cp38-win32.whl", hash = "sha256:895184dfef8708e15f7516bd930bda7e50ead069280d2ce09ba11781b630a434"}, + {file = "SQLAlchemy-2.0.34-cp38-cp38-win_amd64.whl", hash = "sha256:6e7cde3a2221aa89247944cafb1b26616380e30c63e37ed19ff0bba5e968688d"}, + {file = "SQLAlchemy-2.0.34-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dbcdf987f3aceef9763b6d7b1fd3e4ee210ddd26cac421d78b3c206d07b2700b"}, + {file = "SQLAlchemy-2.0.34-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ce119fc4ce0d64124d37f66a6f2a584fddc3c5001755f8a49f1ca0a177ef9796"}, + {file = "SQLAlchemy-2.0.34-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a17d8fac6df9835d8e2b4c5523666e7051d0897a93756518a1fe101c7f47f2f0"}, + {file = "SQLAlchemy-2.0.34-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ebc11c54c6ecdd07bb4efbfa1554538982f5432dfb8456958b6d46b9f834bb7"}, + {file = "SQLAlchemy-2.0.34-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2e6965346fc1491a566e019a4a1d3dfc081ce7ac1a736536367ca305da6472a8"}, + {file = "SQLAlchemy-2.0.34-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:220574e78ad986aea8e81ac68821e47ea9202b7e44f251b7ed8c66d9ae3f4278"}, + {file = "SQLAlchemy-2.0.34-cp39-cp39-win32.whl", hash = "sha256:b75b00083e7fe6621ce13cfce9d4469c4774e55e8e9d38c305b37f13cf1e874c"}, + {file = "SQLAlchemy-2.0.34-cp39-cp39-win_amd64.whl", hash = "sha256:c29d03e0adf3cc1a8c3ec62d176824972ae29b67a66cbb18daff3062acc6faa8"}, + {file = "SQLAlchemy-2.0.34-py3-none-any.whl", hash = "sha256:7286c353ee6475613d8beff83167374006c6b3e3f0e6491bfe8ca610eb1dec0f"}, + {file = "sqlalchemy-2.0.34.tar.gz", hash = "sha256:10d8f36990dd929690666679b0f42235c159a7051534adb135728ee52828dd22"}, ] [package.dependencies] @@ -8352,13 +8647,13 @@ doc = ["sphinx"] [[package]] name = "starlette" -version = "0.38.2" +version = "0.38.4" description = "The little ASGI library that shines." optional = false python-versions = ">=3.8" files = [ - {file = "starlette-0.38.2-py3-none-any.whl", hash = "sha256:4ec6a59df6bbafdab5f567754481657f7ed90dc9d69b0c9ff017907dd54faeff"}, - {file = "starlette-0.38.2.tar.gz", hash = "sha256:c7c0441065252160993a1a37cf2a73bb64d271b17303e0b0c1eb7191cfb12d75"}, + {file = "starlette-0.38.4-py3-none-any.whl", hash = "sha256:526f53a77f0e43b85f583438aee1a940fd84f8fd610353e8b0c1a77ad8a87e76"}, + {file = "starlette-0.38.4.tar.gz", hash = "sha256:53a7439060304a208fea17ed407e998f46da5e5d9b1addfea3040094512a6379"}, ] [package.dependencies] @@ -8412,6 +8707,17 @@ files = [ [package.extras] widechars = ["wcwidth"] +[[package]] +name = "tblib" +version = "3.0.0" +description = "Traceback serialization library." +optional = false +python-versions = ">=3.8" +files = [ + {file = "tblib-3.0.0-py3-none-any.whl", hash = "sha256:80a6c77e59b55e83911e1e607c649836a69c103963c5f28a46cbeef44acf8129"}, + {file = "tblib-3.0.0.tar.gz", hash = "sha256:93622790a0a29e04f0346458face1e144dc4d32f493714c6c3dff82a4adb77e6"}, +] + [[package]] name = "tcvectordb" version = "1.3.2" @@ -8444,13 +8750,13 @@ test = ["pytest", "tornado (>=4.5)", "typeguard"] [[package]] name = "tencentcloud-sdk-python-common" -version = "3.0.1216" +version = "3.0.1226" description = "Tencent Cloud Common SDK for Python" optional = false python-versions = "*" files = [ - {file = "tencentcloud-sdk-python-common-3.0.1216.tar.gz", hash = "sha256:7ad83b100574068fe25439fe47fd27253ff1c730348a309567a7ff88eda63cf8"}, - {file = "tencentcloud_sdk_python_common-3.0.1216-py2.py3-none-any.whl", hash = "sha256:5e1cf9b685923d567d379f96a7008084006ad68793cfa0a0524e65dc59fd09d7"}, + {file = "tencentcloud-sdk-python-common-3.0.1226.tar.gz", hash = "sha256:8e126cdce6adffce6fa5a3b464f0a6e483af7c7f78939883823393c2c5e8fc62"}, + {file = "tencentcloud_sdk_python_common-3.0.1226-py2.py3-none-any.whl", hash = "sha256:6165481280147afa226c6bb91df4cd0c43c5230f566be3d3f9c45a826b1105c5"}, ] [package.dependencies] @@ -8458,17 +8764,17 @@ requests = ">=2.16.0" [[package]] name = "tencentcloud-sdk-python-hunyuan" -version = "3.0.1216" +version = "3.0.1226" description = "Tencent Cloud Hunyuan SDK for Python" optional = false python-versions = "*" files = [ - {file = "tencentcloud-sdk-python-hunyuan-3.0.1216.tar.gz", hash = "sha256:b295d67f97dba52ed358a1d9e061f94b1a4a87e45714efbf0987edab12642206"}, - {file = "tencentcloud_sdk_python_hunyuan-3.0.1216-py2.py3-none-any.whl", hash = "sha256:62d925b41424017929b532389061a076dca72dde455e85ec089947645010e691"}, + {file = "tencentcloud-sdk-python-hunyuan-3.0.1226.tar.gz", hash = "sha256:c9b9c3a373d967b691444bd590e3be1424aaab9f1ab30c57d98777113e2b7882"}, + {file = "tencentcloud_sdk_python_hunyuan-3.0.1226-py2.py3-none-any.whl", hash = "sha256:87a1d63f85c25b5ec6c07f16d813091411ea6f296a1bf7fb608a529852b38bbe"}, ] [package.dependencies] -tencentcloud-sdk-python-common = "3.0.1216" +tencentcloud-sdk-python-common = "3.0.1226" [[package]] name = "threadpoolctl" @@ -8730,6 +9036,23 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] +[[package]] +name = "tos" +version = "2.7.1" +description = "Volc TOS (Tinder Object Storage) SDK" +optional = false +python-versions = "*" +files = [ + {file = "tos-2.7.1.tar.gz", hash = "sha256:4bccdbff3cfd63eb44648bb44862903708c4b3e790f0dd55c96305baaeece805"}, +] + +[package.dependencies] +crcmod = ">=1.7" +Deprecated = ">=1.2.13,<2.0.0" +pytz = "*" +requests = ">=2.19.1,<3.dev0" +six = "*" + [[package]] name = "tqdm" version = "4.66.5" @@ -8837,13 +9160,13 @@ requests = ">=2.0.0" [[package]] name = "typer" -version = "0.12.4" +version = "0.12.5" description = "Typer, build great CLIs. Easy to code. Based on Python type hints." optional = false python-versions = ">=3.7" files = [ - {file = "typer-0.12.4-py3-none-any.whl", hash = "sha256:819aa03699f438397e876aa12b0d63766864ecba1b579092cc9fe35d886e34b6"}, - {file = "typer-0.12.4.tar.gz", hash = "sha256:c9c1613ed6a166162705b3347b8d10b661ccc5d95692654d0fb628118f2c34e6"}, + {file = "typer-0.12.5-py3-none-any.whl", hash = "sha256:62fe4e471711b147e3365034133904df3e235698399bc4de2b36c8579298d52b"}, + {file = "typer-0.12.5.tar.gz", hash = "sha256:f592f089bedcc8ec1b974125d64851029c3b1af145f04aca64d69410f0c9b722"}, ] [package.dependencies] @@ -8854,13 +9177,13 @@ typing-extensions = ">=3.7.4.3" [[package]] name = "types-requests" -version = "2.32.0.20240712" +version = "2.32.0.20240905" description = "Typing stubs for requests" optional = false python-versions = ">=3.8" files = [ - {file = "types-requests-2.32.0.20240712.tar.gz", hash = "sha256:90c079ff05e549f6bf50e02e910210b98b8ff1ebdd18e19c873cd237737c1358"}, - {file = "types_requests-2.32.0.20240712-py3-none-any.whl", hash = "sha256:f754283e152c752e46e70942fa2a146b5bc70393522257bb85bd1ef7e019dcc3"}, + {file = "types-requests-2.32.0.20240905.tar.gz", hash = "sha256:e97fd015a5ed982c9ddcd14cc4afba9d111e0e06b797c8f776d14602735e9bd6"}, + {file = "types_requests-2.32.0.20240905-py3-none-any.whl", hash = "sha256:f46ecb55f5e1a37a58be684cf3f013f166da27552732ef2469a0cc8e62a72881"}, ] [package.dependencies] @@ -9263,12 +9586,12 @@ files = [ [[package]] name = "volcengine-python-sdk" -version = "1.0.98" +version = "1.0.100" description = "Volcengine SDK for Python" optional = false python-versions = "*" files = [ - {file = "volcengine-python-sdk-1.0.98.tar.gz", hash = "sha256:1515e8d46cdcda387f9b45abbcaf0b04b982f7be68068de83f1e388281441784"}, + {file = "volcengine-python-sdk-1.0.100.tar.gz", hash = "sha256:cdc194fe3ce51adda6892d2ca1c43edba3300699321dc6c69119c59fc3b28932"}, ] [package.dependencies] @@ -9285,98 +9608,94 @@ ark = ["anyio (>=3.5.0,<5)", "cached-property", "httpx (>=0.23.0,<1)", "pydantic [[package]] name = "watchfiles" -version = "0.23.0" +version = "0.24.0" description = "Simple, modern and high performance file watching and code reload in python." optional = false python-versions = ">=3.8" files = [ - {file = "watchfiles-0.23.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:bee8ce357a05c20db04f46c22be2d1a2c6a8ed365b325d08af94358e0688eeb4"}, - {file = "watchfiles-0.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4ccd3011cc7ee2f789af9ebe04745436371d36afe610028921cab9f24bb2987b"}, - {file = "watchfiles-0.23.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb02d41c33be667e6135e6686f1bb76104c88a312a18faa0ef0262b5bf7f1a0f"}, - {file = "watchfiles-0.23.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7cf12ac34c444362f3261fb3ff548f0037ddd4c5bb85f66c4be30d2936beb3c5"}, - {file = "watchfiles-0.23.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0b2c25040a3c0ce0e66c7779cc045fdfbbb8d59e5aabfe033000b42fe44b53e"}, - {file = "watchfiles-0.23.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ecf2be4b9eece4f3da8ba5f244b9e51932ebc441c0867bd6af46a3d97eb068d6"}, - {file = "watchfiles-0.23.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40cb8fa00028908211eb9f8d47744dca21a4be6766672e1ff3280bee320436f1"}, - {file = "watchfiles-0.23.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f48c917ffd36ff9a5212614c2d0d585fa8b064ca7e66206fb5c095015bc8207"}, - {file = "watchfiles-0.23.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9d183e3888ada88185ab17064079c0db8c17e32023f5c278d7bf8014713b1b5b"}, - {file = "watchfiles-0.23.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9837edf328b2805346f91209b7e660f65fb0e9ca18b7459d075d58db082bf981"}, - {file = "watchfiles-0.23.0-cp310-none-win32.whl", hash = "sha256:296e0b29ab0276ca59d82d2da22cbbdb39a23eed94cca69aed274595fb3dfe42"}, - {file = "watchfiles-0.23.0-cp310-none-win_amd64.whl", hash = "sha256:4ea756e425ab2dfc8ef2a0cb87af8aa7ef7dfc6fc46c6f89bcf382121d4fff75"}, - {file = "watchfiles-0.23.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:e397b64f7aaf26915bf2ad0f1190f75c855d11eb111cc00f12f97430153c2eab"}, - {file = "watchfiles-0.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b4ac73b02ca1824ec0a7351588241fd3953748d3774694aa7ddb5e8e46aef3e3"}, - {file = "watchfiles-0.23.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:130a896d53b48a1cecccfa903f37a1d87dbb74295305f865a3e816452f6e49e4"}, - {file = "watchfiles-0.23.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c5e7803a65eb2d563c73230e9d693c6539e3c975ccfe62526cadde69f3fda0cf"}, - {file = "watchfiles-0.23.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1aa4cc85202956d1a65c88d18c7b687b8319dbe6b1aec8969784ef7a10e7d1a"}, - {file = "watchfiles-0.23.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87f889f6e58849ddb7c5d2cb19e2e074917ed1c6e3ceca50405775166492cca8"}, - {file = "watchfiles-0.23.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:37fd826dac84c6441615aa3f04077adcc5cac7194a021c9f0d69af20fb9fa788"}, - {file = "watchfiles-0.23.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee7db6e36e7a2c15923072e41ea24d9a0cf39658cb0637ecc9307b09d28827e1"}, - {file = "watchfiles-0.23.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2368c5371c17fdcb5a2ea71c5c9d49f9b128821bfee69503cc38eae00feb3220"}, - {file = "watchfiles-0.23.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:857af85d445b9ba9178db95658c219dbd77b71b8264e66836a6eba4fbf49c320"}, - {file = "watchfiles-0.23.0-cp311-none-win32.whl", hash = "sha256:1d636c8aeb28cdd04a4aa89030c4b48f8b2954d8483e5f989774fa441c0ed57b"}, - {file = "watchfiles-0.23.0-cp311-none-win_amd64.whl", hash = "sha256:46f1d8069a95885ca529645cdbb05aea5837d799965676e1b2b1f95a4206313e"}, - {file = "watchfiles-0.23.0-cp311-none-win_arm64.whl", hash = "sha256:e495ed2a7943503766c5d1ff05ae9212dc2ce1c0e30a80d4f0d84889298fa304"}, - {file = "watchfiles-0.23.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:1db691bad0243aed27c8354b12d60e8e266b75216ae99d33e927ff5238d270b5"}, - {file = "watchfiles-0.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:62d2b18cb1edaba311fbbfe83fb5e53a858ba37cacb01e69bc20553bb70911b8"}, - {file = "watchfiles-0.23.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e087e8fdf1270d000913c12e6eca44edd02aad3559b3e6b8ef00f0ce76e0636f"}, - {file = "watchfiles-0.23.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dd41d5c72417b87c00b1b635738f3c283e737d75c5fa5c3e1c60cd03eac3af77"}, - {file = "watchfiles-0.23.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e5f3ca0ff47940ce0a389457b35d6df601c317c1e1a9615981c474452f98de1"}, - {file = "watchfiles-0.23.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6991e3a78f642368b8b1b669327eb6751439f9f7eaaa625fae67dd6070ecfa0b"}, - {file = "watchfiles-0.23.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f7252f52a09f8fa5435dc82b6af79483118ce6bd51eb74e6269f05ee22a7b9f"}, - {file = "watchfiles-0.23.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e01bcb8d767c58865207a6c2f2792ad763a0fe1119fb0a430f444f5b02a5ea0"}, - {file = "watchfiles-0.23.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:8e56fbcdd27fce061854ddec99e015dd779cae186eb36b14471fc9ae713b118c"}, - {file = "watchfiles-0.23.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bd3e2d64500a6cad28bcd710ee6269fbeb2e5320525acd0cfab5f269ade68581"}, - {file = "watchfiles-0.23.0-cp312-none-win32.whl", hash = "sha256:eb99c954291b2fad0eff98b490aa641e128fbc4a03b11c8a0086de8b7077fb75"}, - {file = "watchfiles-0.23.0-cp312-none-win_amd64.whl", hash = "sha256:dccc858372a56080332ea89b78cfb18efb945da858fabeb67f5a44fa0bcb4ebb"}, - {file = "watchfiles-0.23.0-cp312-none-win_arm64.whl", hash = "sha256:6c21a5467f35c61eafb4e394303720893066897fca937bade5b4f5877d350ff8"}, - {file = "watchfiles-0.23.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:ba31c32f6b4dceeb2be04f717811565159617e28d61a60bb616b6442027fd4b9"}, - {file = "watchfiles-0.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:85042ab91814fca99cec4678fc063fb46df4cbb57b4835a1cc2cb7a51e10250e"}, - {file = "watchfiles-0.23.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24655e8c1c9c114005c3868a3d432c8aa595a786b8493500071e6a52f3d09217"}, - {file = "watchfiles-0.23.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6b1a950ab299a4a78fd6369a97b8763732bfb154fdb433356ec55a5bce9515c1"}, - {file = "watchfiles-0.23.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8d3c5cd327dd6ce0edfc94374fb5883d254fe78a5e9d9dfc237a1897dc73cd1"}, - {file = "watchfiles-0.23.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ff785af8bacdf0be863ec0c428e3288b817e82f3d0c1d652cd9c6d509020dd0"}, - {file = "watchfiles-0.23.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:02b7ba9d4557149410747353e7325010d48edcfe9d609a85cb450f17fd50dc3d"}, - {file = "watchfiles-0.23.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48a1b05c0afb2cd2f48c1ed2ae5487b116e34b93b13074ed3c22ad5c743109f0"}, - {file = "watchfiles-0.23.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:109a61763e7318d9f821b878589e71229f97366fa6a5c7720687d367f3ab9eef"}, - {file = "watchfiles-0.23.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:9f8e6bb5ac007d4a4027b25f09827ed78cbbd5b9700fd6c54429278dacce05d1"}, - {file = "watchfiles-0.23.0-cp313-none-win32.whl", hash = "sha256:f46c6f0aec8d02a52d97a583782d9af38c19a29900747eb048af358a9c1d8e5b"}, - {file = "watchfiles-0.23.0-cp313-none-win_amd64.whl", hash = "sha256:f449afbb971df5c6faeb0a27bca0427d7b600dd8f4a068492faec18023f0dcff"}, - {file = "watchfiles-0.23.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:2dddc2487d33e92f8b6222b5fb74ae2cfde5e8e6c44e0248d24ec23befdc5366"}, - {file = "watchfiles-0.23.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e75695cc952e825fa3e0684a7f4a302f9128721f13eedd8dbd3af2ba450932b8"}, - {file = "watchfiles-0.23.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2537ef60596511df79b91613a5bb499b63f46f01a11a81b0a2b0dedf645d0a9c"}, - {file = "watchfiles-0.23.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:20b423b58f5fdde704a226b598a2d78165fe29eb5621358fe57ea63f16f165c4"}, - {file = "watchfiles-0.23.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b98732ec893975455708d6fc9a6daab527fc8bbe65be354a3861f8c450a632a4"}, - {file = "watchfiles-0.23.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee1f5fcbf5bc33acc0be9dd31130bcba35d6d2302e4eceafafd7d9018c7755ab"}, - {file = "watchfiles-0.23.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8f195338a5a7b50a058522b39517c50238358d9ad8284fd92943643144c0c03"}, - {file = "watchfiles-0.23.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:524fcb8d59b0dbee2c9b32207084b67b2420f6431ed02c18bd191e6c575f5c48"}, - {file = "watchfiles-0.23.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0eff099a4df36afaa0eea7a913aa64dcf2cbd4e7a4f319a73012210af4d23810"}, - {file = "watchfiles-0.23.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a8323daae27ea290ba3350c70c836c0d2b0fb47897fa3b0ca6a5375b952b90d3"}, - {file = "watchfiles-0.23.0-cp38-none-win32.whl", hash = "sha256:aafea64a3ae698695975251f4254df2225e2624185a69534e7fe70581066bc1b"}, - {file = "watchfiles-0.23.0-cp38-none-win_amd64.whl", hash = "sha256:c846884b2e690ba62a51048a097acb6b5cd263d8bd91062cd6137e2880578472"}, - {file = "watchfiles-0.23.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a753993635eccf1ecb185dedcc69d220dab41804272f45e4aef0a67e790c3eb3"}, - {file = "watchfiles-0.23.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6bb91fa4d0b392f0f7e27c40981e46dda9eb0fbc84162c7fb478fe115944f491"}, - {file = "watchfiles-0.23.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1f67312efa3902a8e8496bfa9824d3bec096ff83c4669ea555c6bdd213aa516"}, - {file = "watchfiles-0.23.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7ca6b71dcc50d320c88fb2d88ecd63924934a8abc1673683a242a7ca7d39e781"}, - {file = "watchfiles-0.23.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2aec5c29915caf08771d2507da3ac08e8de24a50f746eb1ed295584ba1820330"}, - {file = "watchfiles-0.23.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1733b9bc2c8098c6bdb0ff7a3d7cb211753fecb7bd99bdd6df995621ee1a574b"}, - {file = "watchfiles-0.23.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:02ff5d7bd066c6a7673b17c8879cd8ee903078d184802a7ee851449c43521bdd"}, - {file = "watchfiles-0.23.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18e2de19801b0eaa4c5292a223effb7cfb43904cb742c5317a0ac686ed604765"}, - {file = "watchfiles-0.23.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8ada449e22198c31fb013ae7e9add887e8d2bd2335401abd3cbc55f8c5083647"}, - {file = "watchfiles-0.23.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3af1b05361e1cc497bf1be654a664750ae61f5739e4bb094a2be86ec8c6db9b6"}, - {file = "watchfiles-0.23.0-cp39-none-win32.whl", hash = "sha256:486bda18be5d25ab5d932699ceed918f68eb91f45d018b0343e3502e52866e5e"}, - {file = "watchfiles-0.23.0-cp39-none-win_amd64.whl", hash = "sha256:d2d42254b189a346249424fb9bb39182a19289a2409051ee432fb2926bad966a"}, - {file = "watchfiles-0.23.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6a9265cf87a5b70147bfb2fec14770ed5b11a5bb83353f0eee1c25a81af5abfe"}, - {file = "watchfiles-0.23.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9f02a259fcbbb5fcfe7a0805b1097ead5ba7a043e318eef1db59f93067f0b49b"}, - {file = "watchfiles-0.23.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ebaebb53b34690da0936c256c1cdb0914f24fb0e03da76d185806df9328abed"}, - {file = "watchfiles-0.23.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd257f98cff9c6cb39eee1a83c7c3183970d8a8d23e8cf4f47d9a21329285cee"}, - {file = "watchfiles-0.23.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:aba037c1310dd108411d27b3d5815998ef0e83573e47d4219f45753c710f969f"}, - {file = "watchfiles-0.23.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:a96ac14e184aa86dc43b8a22bb53854760a58b2966c2b41580de938e9bf26ed0"}, - {file = "watchfiles-0.23.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11698bb2ea5e991d10f1f4f83a39a02f91e44e4bd05f01b5c1ec04c9342bf63c"}, - {file = "watchfiles-0.23.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efadd40fca3a04063d40c4448c9303ce24dd6151dc162cfae4a2a060232ebdcb"}, - {file = "watchfiles-0.23.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:556347b0abb4224c5ec688fc58214162e92a500323f50182f994f3ad33385dcb"}, - {file = "watchfiles-0.23.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1cf7f486169986c4b9d34087f08ce56a35126600b6fef3028f19ca16d5889071"}, - {file = "watchfiles-0.23.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f18de0f82c62c4197bea5ecf4389288ac755896aac734bd2cc44004c56e4ac47"}, - {file = "watchfiles-0.23.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:532e1f2c491274d1333a814e4c5c2e8b92345d41b12dc806cf07aaff786beb66"}, - {file = "watchfiles-0.23.0.tar.gz", hash = "sha256:9338ade39ff24f8086bb005d16c29f8e9f19e55b18dcb04dfa26fcbc09da497b"}, + {file = "watchfiles-0.24.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:083dc77dbdeef09fa44bb0f4d1df571d2e12d8a8f985dccde71ac3ac9ac067a0"}, + {file = "watchfiles-0.24.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e94e98c7cb94cfa6e071d401ea3342767f28eb5a06a58fafdc0d2a4974f4f35c"}, + {file = "watchfiles-0.24.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82ae557a8c037c42a6ef26c494d0631cacca040934b101d001100ed93d43f361"}, + {file = "watchfiles-0.24.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:acbfa31e315a8f14fe33e3542cbcafc55703b8f5dcbb7c1eecd30f141df50db3"}, + {file = "watchfiles-0.24.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b74fdffce9dfcf2dc296dec8743e5b0332d15df19ae464f0e249aa871fc1c571"}, + {file = "watchfiles-0.24.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:449f43f49c8ddca87c6b3980c9284cab6bd1f5c9d9a2b00012adaaccd5e7decd"}, + {file = "watchfiles-0.24.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4abf4ad269856618f82dee296ac66b0cd1d71450fc3c98532d93798e73399b7a"}, + {file = "watchfiles-0.24.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f895d785eb6164678ff4bb5cc60c5996b3ee6df3edb28dcdeba86a13ea0465e"}, + {file = "watchfiles-0.24.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7ae3e208b31be8ce7f4c2c0034f33406dd24fbce3467f77223d10cd86778471c"}, + {file = "watchfiles-0.24.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2efec17819b0046dde35d13fb8ac7a3ad877af41ae4640f4109d9154ed30a188"}, + {file = "watchfiles-0.24.0-cp310-none-win32.whl", hash = "sha256:6bdcfa3cd6fdbdd1a068a52820f46a815401cbc2cb187dd006cb076675e7b735"}, + {file = "watchfiles-0.24.0-cp310-none-win_amd64.whl", hash = "sha256:54ca90a9ae6597ae6dc00e7ed0a040ef723f84ec517d3e7ce13e63e4bc82fa04"}, + {file = "watchfiles-0.24.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:bdcd5538e27f188dd3c804b4a8d5f52a7fc7f87e7fd6b374b8e36a4ca03db428"}, + {file = "watchfiles-0.24.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2dadf8a8014fde6addfd3c379e6ed1a981c8f0a48292d662e27cabfe4239c83c"}, + {file = "watchfiles-0.24.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6509ed3f467b79d95fc62a98229f79b1a60d1b93f101e1c61d10c95a46a84f43"}, + {file = "watchfiles-0.24.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8360f7314a070c30e4c976b183d1d8d1585a4a50c5cb603f431cebcbb4f66327"}, + {file = "watchfiles-0.24.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:316449aefacf40147a9efaf3bd7c9bdd35aaba9ac5d708bd1eb5763c9a02bef5"}, + {file = "watchfiles-0.24.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73bde715f940bea845a95247ea3e5eb17769ba1010efdc938ffcb967c634fa61"}, + {file = "watchfiles-0.24.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3770e260b18e7f4e576edca4c0a639f704088602e0bc921c5c2e721e3acb8d15"}, + {file = "watchfiles-0.24.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa0fd7248cf533c259e59dc593a60973a73e881162b1a2f73360547132742823"}, + {file = "watchfiles-0.24.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d7a2e3b7f5703ffbd500dabdefcbc9eafeff4b9444bbdd5d83d79eedf8428fab"}, + {file = "watchfiles-0.24.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d831ee0a50946d24a53821819b2327d5751b0c938b12c0653ea5be7dea9c82ec"}, + {file = "watchfiles-0.24.0-cp311-none-win32.whl", hash = "sha256:49d617df841a63b4445790a254013aea2120357ccacbed00253f9c2b5dc24e2d"}, + {file = "watchfiles-0.24.0-cp311-none-win_amd64.whl", hash = "sha256:d3dcb774e3568477275cc76554b5a565024b8ba3a0322f77c246bc7111c5bb9c"}, + {file = "watchfiles-0.24.0-cp311-none-win_arm64.whl", hash = "sha256:9301c689051a4857d5b10777da23fafb8e8e921bcf3abe6448a058d27fb67633"}, + {file = "watchfiles-0.24.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:7211b463695d1e995ca3feb38b69227e46dbd03947172585ecb0588f19b0d87a"}, + {file = "watchfiles-0.24.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4b8693502d1967b00f2fb82fc1e744df128ba22f530e15b763c8d82baee15370"}, + {file = "watchfiles-0.24.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdab9555053399318b953a1fe1f586e945bc8d635ce9d05e617fd9fe3a4687d6"}, + {file = "watchfiles-0.24.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:34e19e56d68b0dad5cff62273107cf5d9fbaf9d75c46277aa5d803b3ef8a9e9b"}, + {file = "watchfiles-0.24.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:41face41f036fee09eba33a5b53a73e9a43d5cb2c53dad8e61fa6c9f91b5a51e"}, + {file = "watchfiles-0.24.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5148c2f1ea043db13ce9b0c28456e18ecc8f14f41325aa624314095b6aa2e9ea"}, + {file = "watchfiles-0.24.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e4bd963a935aaf40b625c2499f3f4f6bbd0c3776f6d3bc7c853d04824ff1c9f"}, + {file = "watchfiles-0.24.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c79d7719d027b7a42817c5d96461a99b6a49979c143839fc37aa5748c322f234"}, + {file = "watchfiles-0.24.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:32aa53a9a63b7f01ed32e316e354e81e9da0e6267435c7243bf8ae0f10b428ef"}, + {file = "watchfiles-0.24.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ce72dba6a20e39a0c628258b5c308779b8697f7676c254a845715e2a1039b968"}, + {file = "watchfiles-0.24.0-cp312-none-win32.whl", hash = "sha256:d9018153cf57fc302a2a34cb7564870b859ed9a732d16b41a9b5cb2ebed2d444"}, + {file = "watchfiles-0.24.0-cp312-none-win_amd64.whl", hash = "sha256:551ec3ee2a3ac9cbcf48a4ec76e42c2ef938a7e905a35b42a1267fa4b1645896"}, + {file = "watchfiles-0.24.0-cp312-none-win_arm64.whl", hash = "sha256:b52a65e4ea43c6d149c5f8ddb0bef8d4a1e779b77591a458a893eb416624a418"}, + {file = "watchfiles-0.24.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3d2e3ab79a1771c530233cadfd277fcc762656d50836c77abb2e5e72b88e3a48"}, + {file = "watchfiles-0.24.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:327763da824817b38ad125dcd97595f942d720d32d879f6c4ddf843e3da3fe90"}, + {file = "watchfiles-0.24.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd82010f8ab451dabe36054a1622870166a67cf3fce894f68895db6f74bbdc94"}, + {file = "watchfiles-0.24.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d64ba08db72e5dfd5c33be1e1e687d5e4fcce09219e8aee893a4862034081d4e"}, + {file = "watchfiles-0.24.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1cf1f6dd7825053f3d98f6d33f6464ebdd9ee95acd74ba2c34e183086900a827"}, + {file = "watchfiles-0.24.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43e3e37c15a8b6fe00c1bce2473cfa8eb3484bbeecf3aefbf259227e487a03df"}, + {file = "watchfiles-0.24.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88bcd4d0fe1d8ff43675360a72def210ebad3f3f72cabfeac08d825d2639b4ab"}, + {file = "watchfiles-0.24.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:999928c6434372fde16c8f27143d3e97201160b48a614071261701615a2a156f"}, + {file = "watchfiles-0.24.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:30bbd525c3262fd9f4b1865cb8d88e21161366561cd7c9e1194819e0a33ea86b"}, + {file = "watchfiles-0.24.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:edf71b01dec9f766fb285b73930f95f730bb0943500ba0566ae234b5c1618c18"}, + {file = "watchfiles-0.24.0-cp313-none-win32.whl", hash = "sha256:f4c96283fca3ee09fb044f02156d9570d156698bc3734252175a38f0e8975f07"}, + {file = "watchfiles-0.24.0-cp313-none-win_amd64.whl", hash = "sha256:a974231b4fdd1bb7f62064a0565a6b107d27d21d9acb50c484d2cdba515b9366"}, + {file = "watchfiles-0.24.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:ee82c98bed9d97cd2f53bdb035e619309a098ea53ce525833e26b93f673bc318"}, + {file = "watchfiles-0.24.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fd92bbaa2ecdb7864b7600dcdb6f2f1db6e0346ed425fbd01085be04c63f0b05"}, + {file = "watchfiles-0.24.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f83df90191d67af5a831da3a33dd7628b02a95450e168785586ed51e6d28943c"}, + {file = "watchfiles-0.24.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fca9433a45f18b7c779d2bae7beeec4f740d28b788b117a48368d95a3233ed83"}, + {file = "watchfiles-0.24.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b995bfa6bf01a9e09b884077a6d37070464b529d8682d7691c2d3b540d357a0c"}, + {file = "watchfiles-0.24.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed9aba6e01ff6f2e8285e5aa4154e2970068fe0fc0998c4380d0e6278222269b"}, + {file = "watchfiles-0.24.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5171ef898299c657685306d8e1478a45e9303ddcd8ac5fed5bd52ad4ae0b69b"}, + {file = "watchfiles-0.24.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4933a508d2f78099162da473841c652ad0de892719043d3f07cc83b33dfd9d91"}, + {file = "watchfiles-0.24.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:95cf3b95ea665ab03f5a54765fa41abf0529dbaf372c3b83d91ad2cfa695779b"}, + {file = "watchfiles-0.24.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:01def80eb62bd5db99a798d5e1f5f940ca0a05986dcfae21d833af7a46f7ee22"}, + {file = "watchfiles-0.24.0-cp38-none-win32.whl", hash = "sha256:4d28cea3c976499475f5b7a2fec6b3a36208656963c1a856d328aeae056fc5c1"}, + {file = "watchfiles-0.24.0-cp38-none-win_amd64.whl", hash = "sha256:21ab23fdc1208086d99ad3f69c231ba265628014d4aed31d4e8746bd59e88cd1"}, + {file = "watchfiles-0.24.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b665caeeda58625c3946ad7308fbd88a086ee51ccb706307e5b1fa91556ac886"}, + {file = "watchfiles-0.24.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5c51749f3e4e269231510da426ce4a44beb98db2dce9097225c338f815b05d4f"}, + {file = "watchfiles-0.24.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82b2509f08761f29a0fdad35f7e1638b8ab1adfa2666d41b794090361fb8b855"}, + {file = "watchfiles-0.24.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a60e2bf9dc6afe7f743e7c9b149d1fdd6dbf35153c78fe3a14ae1a9aee3d98b"}, + {file = "watchfiles-0.24.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f7d9b87c4c55e3ea8881dfcbf6d61ea6775fffed1fedffaa60bd047d3c08c430"}, + {file = "watchfiles-0.24.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:78470906a6be5199524641f538bd2c56bb809cd4bf29a566a75051610bc982c3"}, + {file = "watchfiles-0.24.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:07cdef0c84c03375f4e24642ef8d8178e533596b229d32d2bbd69e5128ede02a"}, + {file = "watchfiles-0.24.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d337193bbf3e45171c8025e291530fb7548a93c45253897cd764a6a71c937ed9"}, + {file = "watchfiles-0.24.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ec39698c45b11d9694a1b635a70946a5bad066b593af863460a8e600f0dff1ca"}, + {file = "watchfiles-0.24.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2e28d91ef48eab0afb939fa446d8ebe77e2f7593f5f463fd2bb2b14132f95b6e"}, + {file = "watchfiles-0.24.0-cp39-none-win32.whl", hash = "sha256:7138eff8baa883aeaa074359daabb8b6c1e73ffe69d5accdc907d62e50b1c0da"}, + {file = "watchfiles-0.24.0-cp39-none-win_amd64.whl", hash = "sha256:b3ef2c69c655db63deb96b3c3e587084612f9b1fa983df5e0c3379d41307467f"}, + {file = "watchfiles-0.24.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:632676574429bee8c26be8af52af20e0c718cc7f5f67f3fb658c71928ccd4f7f"}, + {file = "watchfiles-0.24.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a2a9891723a735d3e2540651184be6fd5b96880c08ffe1a98bae5017e65b544b"}, + {file = "watchfiles-0.24.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7fa2bc0efef3e209a8199fd111b8969fe9db9c711acc46636686331eda7dd4"}, + {file = "watchfiles-0.24.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01550ccf1d0aed6ea375ef259706af76ad009ef5b0203a3a4cce0f6024f9b68a"}, + {file = "watchfiles-0.24.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:96619302d4374de5e2345b2b622dc481257a99431277662c30f606f3e22f42be"}, + {file = "watchfiles-0.24.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:85d5f0c7771dcc7a26c7a27145059b6bb0ce06e4e751ed76cdf123d7039b60b5"}, + {file = "watchfiles-0.24.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:951088d12d339690a92cef2ec5d3cfd957692834c72ffd570ea76a6790222777"}, + {file = "watchfiles-0.24.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49fb58bcaa343fedc6a9e91f90195b20ccb3135447dc9e4e2570c3a39565853e"}, + {file = "watchfiles-0.24.0.tar.gz", hash = "sha256:afb72325b74fa7a428c009c1b8be4b4d7c2afedafb2982827ef2156646df2fe1"}, ] [package.dependencies] @@ -9442,97 +9761,97 @@ test = ["websockets"] [[package]] name = "websockets" -version = "13.0" +version = "13.0.1" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" optional = false python-versions = ">=3.8" files = [ - {file = "websockets-13.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ad4fa707ff9e2ffee019e946257b5300a45137a58f41fbd9a4db8e684ab61528"}, - {file = "websockets-13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6fd757f313c13c34dae9f126d3ba4cf97175859c719e57c6a614b781c86b617e"}, - {file = "websockets-13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cbac2eb7ce0fac755fb983c9247c4a60c4019bcde4c0e4d167aeb17520cc7ef1"}, - {file = "websockets-13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4b83cf7354cbbc058e97b3e545dceb75b8d9cf17fd5a19db419c319ddbaaf7a"}, - {file = "websockets-13.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9202c0010c78fad1041e1c5285232b6508d3633f92825687549540a70e9e5901"}, - {file = "websockets-13.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e6566e79c8c7cbea75ec450f6e1828945fc5c9a4769ceb1c7b6e22470539712"}, - {file = "websockets-13.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e7fcad070dcd9ad37a09d89a4cbc2a5e3e45080b88977c0da87b3090f9f55ead"}, - {file = "websockets-13.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0a8f7d65358a25172db00c69bcc7df834155ee24229f560d035758fd6613111a"}, - {file = "websockets-13.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:63b702fb31e3f058f946ccdfa551f4d57a06f7729c369e8815eb18643099db37"}, - {file = "websockets-13.0-cp310-cp310-win32.whl", hash = "sha256:3a20cf14ba7b482c4a1924b5e061729afb89c890ca9ed44ac4127c6c5986e424"}, - {file = "websockets-13.0-cp310-cp310-win_amd64.whl", hash = "sha256:587245f0704d0bb675f919898d7473e8827a6d578e5a122a21756ca44b811ec8"}, - {file = "websockets-13.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:06df8306c241c235075d2ae77367038e701e53bc8c1bb4f6644f4f53aa6dedd0"}, - {file = "websockets-13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85a1f92a02f0b8c1bf02699731a70a8a74402bb3f82bee36e7768b19a8ed9709"}, - {file = "websockets-13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9ed02c604349068d46d87ef4c2012c112c791f2bec08671903a6bb2bd9c06784"}, - {file = "websockets-13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b89849171b590107f6724a7b0790736daead40926ddf47eadf998b4ff51d6414"}, - {file = "websockets-13.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:939a16849d71203628157a5e4a495da63967c744e1e32018e9b9e2689aca64d4"}, - {file = "websockets-13.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad818cdac37c0ad4c58e51cb4964eae4f18b43c4a83cb37170b0d90c31bd80cf"}, - {file = "websockets-13.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cbfe82a07596a044de78bb7a62519e71690c5812c26c5f1d4b877e64e4f46309"}, - {file = "websockets-13.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e07e76c49f39c5b45cbd7362b94f001ae209a3ea4905ae9a09cfd53b3c76373d"}, - {file = "websockets-13.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:372f46a0096cfda23c88f7e42349a33f8375e10912f712e6b496d3a9a557290f"}, - {file = "websockets-13.0-cp311-cp311-win32.whl", hash = "sha256:376a43a4fd96725f13450d3d2e98f4f36c3525c562ab53d9a98dd2950dca9a8a"}, - {file = "websockets-13.0-cp311-cp311-win_amd64.whl", hash = "sha256:2be1382a4daa61e2f3e2be3b3c86932a8db9d1f85297feb6e9df22f391f94452"}, - {file = "websockets-13.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b5407c34776b9b77bd89a5f95eb0a34aaf91889e3f911c63f13035220eb50107"}, - {file = "websockets-13.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4782ec789f059f888c1e8fdf94383d0e64b531cffebbf26dd55afd53ab487ca4"}, - {file = "websockets-13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c8feb8e19ef65c9994e652c5b0324abd657bedd0abeb946fb4f5163012c1e730"}, - {file = "websockets-13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f3d2e20c442b58dbac593cb1e02bc02d149a86056cc4126d977ad902472e3b"}, - {file = "websockets-13.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e39d393e0ab5b8bd01717cc26f2922026050188947ff54fe6a49dc489f7750b7"}, - {file = "websockets-13.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f661a4205741bdc88ac9c2b2ec003c72cee97e4acd156eb733662ff004ba429"}, - {file = "websockets-13.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:384129ad0490e06bab2b98c1da9b488acb35bb11e2464c728376c6f55f0d45f3"}, - {file = "websockets-13.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:df5c0eff91f61b8205a6c9f7b255ff390cdb77b61c7b41f79ca10afcbb22b6cb"}, - {file = "websockets-13.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:02cc9bb1a887dac0e08bf657c5d00aa3fac0d03215d35a599130c2034ae6663a"}, - {file = "websockets-13.0-cp312-cp312-win32.whl", hash = "sha256:d9726d2c9bd6aed8cb994d89b3910ca0079406edce3670886ec828a73e7bdd53"}, - {file = "websockets-13.0-cp312-cp312-win_amd64.whl", hash = "sha256:fa0839f35322f7b038d8adcf679e2698c3a483688cc92e3bd15ee4fb06669e9a"}, - {file = "websockets-13.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:da7e501e59857e8e3e9d10586139dc196b80445a591451ca9998aafba1af5278"}, - {file = "websockets-13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a00e1e587c655749afb5b135d8d3edcfe84ec6db864201e40a882e64168610b3"}, - {file = "websockets-13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a7fbf2a8fe7556a8f4e68cb3e736884af7bf93653e79f6219f17ebb75e97d8f0"}, - {file = "websockets-13.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ea9c9c7443a97ea4d84d3e4d42d0e8c4235834edae652993abcd2aff94affd7"}, - {file = "websockets-13.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35c2221b539b360203f3f9ad168e527bf16d903e385068ae842c186efb13d0ea"}, - {file = "websockets-13.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:358d37c5c431dd050ffb06b4b075505aae3f4f795d7fff9794e5ed96ce99b998"}, - {file = "websockets-13.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:038e7a0f1bfafc7bf52915ab3506b7a03d1e06381e9f60440c856e8918138151"}, - {file = "websockets-13.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fd038bc9e2c134847f1e0ce3191797fad110756e690c2fdd9702ed34e7a43abb"}, - {file = "websockets-13.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93b8c2008f372379fb6e5d2b3f7c9ec32f7b80316543fd3a5ace6610c5cde1b0"}, - {file = "websockets-13.0-cp313-cp313-win32.whl", hash = "sha256:851fd0afb3bc0b73f7c5b5858975d42769a5fdde5314f4ef2c106aec63100687"}, - {file = "websockets-13.0-cp313-cp313-win_amd64.whl", hash = "sha256:7d14901fdcf212804970c30ab9ee8f3f0212e620c7ea93079d6534863444fb4e"}, - {file = "websockets-13.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ae7a519a56a714f64c3445cabde9fc2fc927e7eae44f413eae187cddd9e54178"}, - {file = "websockets-13.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5575031472ca87302aeb2ce2c2349f4c6ea978c86a9d1289bc5d16058ad4c10a"}, - {file = "websockets-13.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9895df6cd0bfe79d09bcd1dbdc03862846f26fbd93797153de954306620c1d00"}, - {file = "websockets-13.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4de299c947a54fca9ce1c5fd4a08eb92ffce91961becb13bd9195f7c6e71b47"}, - {file = "websockets-13.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05c25f7b849702950b6fd0e233989bb73a0d2bc83faa3b7233313ca395205f6d"}, - {file = "websockets-13.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ede95125a30602b1691a4b1da88946bf27dae283cf30f22cd2cb8ca4b2e0d119"}, - {file = "websockets-13.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:addf0a16e4983280efed272d8cb3b2e05f0051755372461e7d966b80a6554e16"}, - {file = "websockets-13.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:06b3186e97bf9a33921fa60734d5ed90f2a9b407cce8d23c7333a0984049ef61"}, - {file = "websockets-13.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:eae368cac85adc4c7dc3b0d5f84ffcca609d658db6447387300478e44db70796"}, - {file = "websockets-13.0-cp38-cp38-win32.whl", hash = "sha256:337837ac788d955728b1ab01876d72b73da59819a3388e1c5e8e05c3999f1afa"}, - {file = "websockets-13.0-cp38-cp38-win_amd64.whl", hash = "sha256:f66e00e42f25ca7e91076366303e11c82572ca87cc5aae51e6e9c094f315ab41"}, - {file = "websockets-13.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:94c1c02721139fe9940b38d28fb15b4b782981d800d5f40f9966264fbf23dcc8"}, - {file = "websockets-13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bd4ba86513430513e2aa25a441bb538f6f83734dc368a2c5d18afdd39097aa33"}, - {file = "websockets-13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a1ab8f0e0cadc5be5f3f9fa11a663957fecbf483d434762c8dfb8aa44948944a"}, - {file = "websockets-13.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3670def5d3dfd5af6f6e2b3b243ea8f1f72d8da1ef927322f0703f85c90d9603"}, - {file = "websockets-13.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6058b6be92743358885ad6dcdecb378fde4a4c74d4dd16a089d07580c75a0e80"}, - {file = "websockets-13.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:516062a0a8ef5ecbfa4acbaec14b199fc070577834f9fe3d40800a99f92523ca"}, - {file = "websockets-13.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:da7e918d82e7bdfc6f66d31febe1b2e28a1ca3387315f918de26f5e367f61572"}, - {file = "websockets-13.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:9cc7f35dcb49a4e32db82a849fcc0714c4d4acc9d2273aded2d61f87d7f660b7"}, - {file = "websockets-13.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f5737c53eb2c8ed8f64b50d3dafd3c1dae739f78aa495a288421ac1b3de82717"}, - {file = "websockets-13.0-cp39-cp39-win32.whl", hash = "sha256:265e1f0d3f788ce8ef99dca591a1aec5263b26083ca0934467ad9a1d1181067c"}, - {file = "websockets-13.0-cp39-cp39-win_amd64.whl", hash = "sha256:4d70c89e3d3b347a7c4d3c33f8d323f0584c9ceb69b82c2ef8a174ca84ea3d4a"}, - {file = "websockets-13.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:602cbd010d8c21c8475f1798b705bb18567eb189c533ab5ef568bc3033fdf417"}, - {file = "websockets-13.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:bf8eb5dca4f484a60f5327b044e842e0d7f7cdbf02ea6dc4a4f811259f1f1f0b"}, - {file = "websockets-13.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89d795c1802d99a643bf689b277e8604c14b5af1bc0a31dade2cd7a678087212"}, - {file = "websockets-13.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:788bc841d250beccff67a20a5a53a15657a60111ef9c0c0a97fbdd614fae0fe2"}, - {file = "websockets-13.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7334752052532c156d28b8eaf3558137e115c7871ea82adff69b6d94a7bee273"}, - {file = "websockets-13.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7a1963302947332c3039e3f66209ec73b1626f8a0191649e0713c391e9f5b0d"}, - {file = "websockets-13.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2e1cf4e1eb84b4fd74a47688e8b0940c89a04ad9f6937afa43d468e71128cd68"}, - {file = "websockets-13.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:c026ee729c4ce55708a14b839ba35086dfae265fc12813b62d34ce33f4980c1c"}, - {file = "websockets-13.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5f9d23fbbf96eefde836d9692670bfc89e2d159f456d499c5efcf6a6281c1af"}, - {file = "websockets-13.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ad684cb7efce227d756bae3e8484f2e56aa128398753b54245efdfbd1108f2c"}, - {file = "websockets-13.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1e10b3fbed7be4a59831d3a939900e50fcd34d93716e433d4193a4d0d1d335d"}, - {file = "websockets-13.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d42a818e634f789350cd8fb413a3f5eec1cf0400a53d02062534c41519f5125c"}, - {file = "websockets-13.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e5ba5e9b332267d0f2c33ede390061850f1ac3ee6cd1bdcf4c5ea33ead971966"}, - {file = "websockets-13.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f9af457ed593e35f467140d8b61d425495b127744a9d65d45a366f8678449a23"}, - {file = "websockets-13.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcea3eb58c09c3a31cc83b45c06d5907f02ddaf10920aaa6443975310f699b95"}, - {file = "websockets-13.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c210d1460dc8d326ffdef9703c2f83269b7539a1690ad11ae04162bc1878d33d"}, - {file = "websockets-13.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b32f38bc81170fd56d0482d505b556e52bf9078b36819a8ba52624bd6667e39e"}, - {file = "websockets-13.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:81a11a1ddd5320429db47c04d35119c3e674d215173d87aaeb06ae80f6e9031f"}, - {file = "websockets-13.0-py3-none-any.whl", hash = "sha256:dbbac01e80aee253d44c4f098ab3cc17c822518519e869b284cfbb8cd16cc9de"}, - {file = "websockets-13.0.tar.gz", hash = "sha256:b7bf950234a482b7461afdb2ec99eee3548ec4d53f418c7990bb79c620476602"}, + {file = "websockets-13.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1841c9082a3ba4a05ea824cf6d99570a6a2d8849ef0db16e9c826acb28089e8f"}, + {file = "websockets-13.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c5870b4a11b77e4caa3937142b650fbbc0914a3e07a0cf3131f35c0587489c1c"}, + {file = "websockets-13.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f1d3d1f2eb79fe7b0fb02e599b2bf76a7619c79300fc55f0b5e2d382881d4f7f"}, + {file = "websockets-13.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15c7d62ee071fa94a2fc52c2b472fed4af258d43f9030479d9c4a2de885fd543"}, + {file = "websockets-13.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6724b554b70d6195ba19650fef5759ef11346f946c07dbbe390e039bcaa7cc3d"}, + {file = "websockets-13.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56a952fa2ae57a42ba7951e6b2605e08a24801a4931b5644dfc68939e041bc7f"}, + {file = "websockets-13.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:17118647c0ea14796364299e942c330d72acc4b248e07e639d34b75067b3cdd8"}, + {file = "websockets-13.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:64a11aae1de4c178fa653b07d90f2fb1a2ed31919a5ea2361a38760192e1858b"}, + {file = "websockets-13.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0617fd0b1d14309c7eab6ba5deae8a7179959861846cbc5cb528a7531c249448"}, + {file = "websockets-13.0.1-cp310-cp310-win32.whl", hash = "sha256:11f9976ecbc530248cf162e359a92f37b7b282de88d1d194f2167b5e7ad80ce3"}, + {file = "websockets-13.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:c3c493d0e5141ec055a7d6809a28ac2b88d5b878bb22df8c621ebe79a61123d0"}, + {file = "websockets-13.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:699ba9dd6a926f82a277063603fc8d586b89f4cb128efc353b749b641fcddda7"}, + {file = "websockets-13.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cf2fae6d85e5dc384bf846f8243ddaa9197f3a1a70044f59399af001fd1f51d4"}, + {file = "websockets-13.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:52aed6ef21a0f1a2a5e310fb5c42d7555e9c5855476bbd7173c3aa3d8a0302f2"}, + {file = "websockets-13.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8eb2b9a318542153674c6e377eb8cb9ca0fc011c04475110d3477862f15d29f0"}, + {file = "websockets-13.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5df891c86fe68b2c38da55b7aea7095beca105933c697d719f3f45f4220a5e0e"}, + {file = "websockets-13.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fac2d146ff30d9dd2fcf917e5d147db037a5c573f0446c564f16f1f94cf87462"}, + {file = "websockets-13.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b8ac5b46fd798bbbf2ac6620e0437c36a202b08e1f827832c4bf050da081b501"}, + {file = "websockets-13.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:46af561eba6f9b0848b2c9d2427086cabadf14e0abdd9fde9d72d447df268418"}, + {file = "websockets-13.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b5a06d7f60bc2fc378a333978470dfc4e1415ee52f5f0fce4f7853eb10c1e9df"}, + {file = "websockets-13.0.1-cp311-cp311-win32.whl", hash = "sha256:556e70e4f69be1082e6ef26dcb70efcd08d1850f5d6c5f4f2bcb4e397e68f01f"}, + {file = "websockets-13.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:67494e95d6565bf395476e9d040037ff69c8b3fa356a886b21d8422ad86ae075"}, + {file = "websockets-13.0.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f9c9e258e3d5efe199ec23903f5da0eeaad58cf6fccb3547b74fd4750e5ac47a"}, + {file = "websockets-13.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6b41a1b3b561f1cba8321fb32987552a024a8f67f0d05f06fcf29f0090a1b956"}, + {file = "websockets-13.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f73e676a46b0fe9426612ce8caeca54c9073191a77c3e9d5c94697aef99296af"}, + {file = "websockets-13.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f613289f4a94142f914aafad6c6c87903de78eae1e140fa769a7385fb232fdf"}, + {file = "websockets-13.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f52504023b1480d458adf496dc1c9e9811df4ba4752f0bc1f89ae92f4f07d0c"}, + {file = "websockets-13.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:139add0f98206cb74109faf3611b7783ceafc928529c62b389917a037d4cfdf4"}, + {file = "websockets-13.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:47236c13be337ef36546004ce8c5580f4b1150d9538b27bf8a5ad8edf23ccfab"}, + {file = "websockets-13.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c44ca9ade59b2e376612df34e837013e2b273e6c92d7ed6636d0556b6f4db93d"}, + {file = "websockets-13.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9bbc525f4be3e51b89b2a700f5746c2a6907d2e2ef4513a8daafc98198b92237"}, + {file = "websockets-13.0.1-cp312-cp312-win32.whl", hash = "sha256:3624fd8664f2577cf8de996db3250662e259bfbc870dd8ebdcf5d7c6ac0b5185"}, + {file = "websockets-13.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0513c727fb8adffa6d9bf4a4463b2bade0186cbd8c3604ae5540fae18a90cb99"}, + {file = "websockets-13.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1ee4cc030a4bdab482a37462dbf3ffb7e09334d01dd37d1063be1136a0d825fa"}, + {file = "websockets-13.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dbb0b697cc0655719522406c059eae233abaa3243821cfdfab1215d02ac10231"}, + {file = "websockets-13.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:acbebec8cb3d4df6e2488fbf34702cbc37fc39ac7abf9449392cefb3305562e9"}, + {file = "websockets-13.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63848cdb6fcc0bf09d4a155464c46c64ffdb5807ede4fb251da2c2692559ce75"}, + {file = "websockets-13.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:872afa52a9f4c414d6955c365b6588bc4401272c629ff8321a55f44e3f62b553"}, + {file = "websockets-13.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05e70fec7c54aad4d71eae8e8cab50525e899791fc389ec6f77b95312e4e9920"}, + {file = "websockets-13.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e82db3756ccb66266504f5a3de05ac6b32f287faacff72462612120074103329"}, + {file = "websockets-13.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4e85f46ce287f5c52438bb3703d86162263afccf034a5ef13dbe4318e98d86e7"}, + {file = "websockets-13.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f3fea72e4e6edb983908f0db373ae0732b275628901d909c382aae3b592589f2"}, + {file = "websockets-13.0.1-cp313-cp313-win32.whl", hash = "sha256:254ecf35572fca01a9f789a1d0f543898e222f7b69ecd7d5381d8d8047627bdb"}, + {file = "websockets-13.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:ca48914cdd9f2ccd94deab5bcb5ac98025a5ddce98881e5cce762854a5de330b"}, + {file = "websockets-13.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b74593e9acf18ea5469c3edaa6b27fa7ecf97b30e9dabd5a94c4c940637ab96e"}, + {file = "websockets-13.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:132511bfd42e77d152c919147078460c88a795af16b50e42a0bd14f0ad71ddd2"}, + {file = "websockets-13.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:165bedf13556f985a2aa064309baa01462aa79bf6112fbd068ae38993a0e1f1b"}, + {file = "websockets-13.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e801ca2f448850685417d723ec70298feff3ce4ff687c6f20922c7474b4746ae"}, + {file = "websockets-13.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30d3a1f041360f029765d8704eae606781e673e8918e6b2c792e0775de51352f"}, + {file = "websockets-13.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67648f5e50231b5a7f6d83b32f9c525e319f0ddc841be0de64f24928cd75a603"}, + {file = "websockets-13.0.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4f0426d51c8f0926a4879390f53c7f5a855e42d68df95fff6032c82c888b5f36"}, + {file = "websockets-13.0.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ef48e4137e8799998a343706531e656fdec6797b80efd029117edacb74b0a10a"}, + {file = "websockets-13.0.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:249aab278810bee585cd0d4de2f08cfd67eed4fc75bde623be163798ed4db2eb"}, + {file = "websockets-13.0.1-cp38-cp38-win32.whl", hash = "sha256:06c0a667e466fcb56a0886d924b5f29a7f0886199102f0a0e1c60a02a3751cb4"}, + {file = "websockets-13.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1f3cf6d6ec1142412d4535adabc6bd72a63f5f148c43fe559f06298bc21953c9"}, + {file = "websockets-13.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1fa082ea38d5de51dd409434edc27c0dcbd5fed2b09b9be982deb6f0508d25bc"}, + {file = "websockets-13.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4a365bcb7be554e6e1f9f3ed64016e67e2fa03d7b027a33e436aecf194febb63"}, + {file = "websockets-13.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:10a0dc7242215d794fb1918f69c6bb235f1f627aaf19e77f05336d147fce7c37"}, + {file = "websockets-13.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59197afd478545b1f73367620407b0083303569c5f2d043afe5363676f2697c9"}, + {file = "websockets-13.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d20516990d8ad557b5abeb48127b8b779b0b7e6771a265fa3e91767596d7d97"}, + {file = "websockets-13.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1a2e272d067030048e1fe41aa1ec8cfbbaabce733b3d634304fa2b19e5c897f"}, + {file = "websockets-13.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ad327ac80ba7ee61da85383ca8822ff808ab5ada0e4a030d66703cc025b021c4"}, + {file = "websockets-13.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:518f90e6dd089d34eaade01101fd8a990921c3ba18ebbe9b0165b46ebff947f0"}, + {file = "websockets-13.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:68264802399aed6fe9652e89761031acc734fc4c653137a5911c2bfa995d6d6d"}, + {file = "websockets-13.0.1-cp39-cp39-win32.whl", hash = "sha256:a5dc0c42ded1557cc7c3f0240b24129aefbad88af4f09346164349391dea8e58"}, + {file = "websockets-13.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:b448a0690ef43db5ef31b3a0d9aea79043882b4632cfc3eaab20105edecf6097"}, + {file = "websockets-13.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:faef9ec6354fe4f9a2c0bbb52fb1ff852effc897e2a4501e25eb3a47cb0a4f89"}, + {file = "websockets-13.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:03d3f9ba172e0a53e37fa4e636b86cc60c3ab2cfee4935e66ed1d7acaa4625ad"}, + {file = "websockets-13.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d450f5a7a35662a9b91a64aefa852f0c0308ee256122f5218a42f1d13577d71e"}, + {file = "websockets-13.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f55b36d17ac50aa8a171b771e15fbe1561217510c8768af3d546f56c7576cdc"}, + {file = "websockets-13.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14b9c006cac63772b31abbcd3e3abb6228233eec966bf062e89e7fa7ae0b7333"}, + {file = "websockets-13.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b79915a1179a91f6c5f04ece1e592e2e8a6bd245a0e45d12fd56b2b59e559a32"}, + {file = "websockets-13.0.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f40de079779acbcdbb6ed4c65af9f018f8b77c5ec4e17a4b737c05c2db554491"}, + {file = "websockets-13.0.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:80e4ba642fc87fa532bac07e5ed7e19d56940b6af6a8c61d4429be48718a380f"}, + {file = "websockets-13.0.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a02b0161c43cc9e0232711eff846569fad6ec836a7acab16b3cf97b2344c060"}, + {file = "websockets-13.0.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6aa74a45d4cdc028561a7d6ab3272c8b3018e23723100b12e58be9dfa5a24491"}, + {file = "websockets-13.0.1-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00fd961943b6c10ee6f0b1130753e50ac5dcd906130dcd77b0003c3ab797d026"}, + {file = "websockets-13.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d93572720d781331fb10d3da9ca1067817d84ad1e7c31466e9f5e59965618096"}, + {file = "websockets-13.0.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:71e6e5a3a3728886caee9ab8752e8113670936a193284be9d6ad2176a137f376"}, + {file = "websockets-13.0.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c4a6343e3b0714e80da0b0893543bf9a5b5fa71b846ae640e56e9abc6fbc4c83"}, + {file = "websockets-13.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a678532018e435396e37422a95e3ab87f75028ac79570ad11f5bf23cd2a7d8c"}, + {file = "websockets-13.0.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6716c087e4aa0b9260c4e579bb82e068f84faddb9bfba9906cb87726fa2e870"}, + {file = "websockets-13.0.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e33505534f3f673270dd67f81e73550b11de5b538c56fe04435d63c02c3f26b5"}, + {file = "websockets-13.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:acab3539a027a85d568c2573291e864333ec9d912675107d6efceb7e2be5d980"}, + {file = "websockets-13.0.1-py3-none-any.whl", hash = "sha256:b80f0c51681c517604152eb6a572f5a9378f877763231fddb883ba2f968e8817"}, + {file = "websockets-13.0.1.tar.gz", hash = "sha256:4d6ece65099411cfd9a48d13701d7438d9c34f479046b34c50ff60bb8834e43e"}, ] [[package]] @@ -9718,101 +10037,103 @@ files = [ [[package]] name = "yarl" -version = "1.9.4" +version = "1.9.11" description = "Yet another URL library" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"}, - {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2"}, - {file = "yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541"}, - {file = "yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d"}, - {file = "yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b"}, - {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099"}, - {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c"}, - {file = "yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98"}, - {file = "yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31"}, - {file = "yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1"}, - {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"}, - {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"}, - {file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"}, - {file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"}, - {file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"}, - {file = "yarl-1.9.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434"}, - {file = "yarl-1.9.4-cp37-cp37m-win32.whl", hash = "sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749"}, - {file = "yarl-1.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2"}, - {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be"}, - {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f"}, - {file = "yarl-1.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3"}, - {file = "yarl-1.9.4-cp38-cp38-win32.whl", hash = "sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece"}, - {file = "yarl-1.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b"}, - {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27"}, - {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1"}, - {file = "yarl-1.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0"}, - {file = "yarl-1.9.4-cp39-cp39-win32.whl", hash = "sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575"}, - {file = "yarl-1.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15"}, - {file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"}, - {file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"}, + {file = "yarl-1.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:79e08c691deae6fcac2fdde2e0515ac561dd3630d7c8adf7b1e786e22f1e193b"}, + {file = "yarl-1.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:752f4b5cf93268dc73c2ae994cc6d684b0dad5118bc87fbd965fd5d6dca20f45"}, + {file = "yarl-1.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:441049d3a449fb8756b0535be72c6a1a532938a33e1cf03523076700a5f87a01"}, + {file = "yarl-1.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3dfe17b4aed832c627319da22a33f27f282bd32633d6b145c726d519c89fbaf"}, + {file = "yarl-1.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:67abcb7df27952864440c9c85f1c549a4ad94afe44e2655f77d74b0d25895454"}, + {file = "yarl-1.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6de3fa29e76fd1518a80e6af4902c44f3b1b4d7fed28eb06913bba4727443de3"}, + {file = "yarl-1.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fee45b3bd4d8d5786472e056aa1359cc4dc9da68aded95a10cd7929a0ec661fe"}, + {file = "yarl-1.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c59b23886234abeba62087fd97d10fb6b905d9e36e2f3465d1886ce5c0ca30df"}, + {file = "yarl-1.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d93c612b2024ac25a3dc01341fd98fdd19c8c5e2011f3dcd084b3743cba8d756"}, + {file = "yarl-1.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4d368e3b9ecd50fa22017a20c49e356471af6ae91c4d788c6e9297e25ddf5a62"}, + {file = "yarl-1.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:5b593acd45cdd4cf6664d342ceacedf25cd95263b83b964fddd6c78930ea5211"}, + {file = "yarl-1.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:224f8186c220ff00079e64bf193909829144d4e5174bb58665ef0da8bf6955c4"}, + {file = "yarl-1.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:91c478741d7563a12162f7a2db96c0d23d93b0521563f1f1f0ece46ea1702d33"}, + {file = "yarl-1.9.11-cp310-cp310-win32.whl", hash = "sha256:1cdb8f5bb0534986776a43df84031da7ff04ac0cf87cb22ae8a6368231949c40"}, + {file = "yarl-1.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:498439af143b43a2b2314451ffd0295410aa0dcbdac5ee18fc8633da4670b605"}, + {file = "yarl-1.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9e290de5db4fd4859b4ed57cddfe793fcb218504e65781854a8ac283ab8d5518"}, + {file = "yarl-1.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e5f50a2e26cc2b89186f04c97e0ec0ba107ae41f1262ad16832d46849864f914"}, + {file = "yarl-1.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b4a0e724a28d7447e4d549c8f40779f90e20147e94bf949d490402eee09845c6"}, + {file = "yarl-1.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85333d38a4fa5997fa2ff6fd169be66626d814b34fa35ec669e8c914ca50a097"}, + {file = "yarl-1.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ff184002ee72e4b247240e35d5dce4c2d9a0e81fdbef715dde79ab4718aa541"}, + {file = "yarl-1.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:675004040f847c0284827f44a1fa92d8baf425632cc93e7e0aa38408774b07c1"}, + {file = "yarl-1.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b30703a7ade2b53f02e09a30685b70cd54f65ed314a8d9af08670c9a5391af1b"}, + {file = "yarl-1.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7230007ab67d43cf19200ec15bc6b654e6b85c402f545a6fc565d254d34ff754"}, + {file = "yarl-1.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8c2cf0c7ad745e1c6530fe6521dfb19ca43338239dfcc7da165d0ef2332c0882"}, + {file = "yarl-1.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4567cc08f479ad80fb07ed0c9e1bcb363a4f6e3483a490a39d57d1419bf1c4c7"}, + {file = "yarl-1.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:95adc179a02949c4560ef40f8f650a008380766eb253d74232eb9c024747c111"}, + {file = "yarl-1.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:755ae9cff06c429632d750aa8206f08df2e3d422ca67be79567aadbe74ae64cc"}, + {file = "yarl-1.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:94f71d54c5faf715e92c8434b4a0b968c4d1043469954d228fc031d51086f143"}, + {file = "yarl-1.9.11-cp311-cp311-win32.whl", hash = "sha256:4ae079573efeaa54e5978ce86b77f4175cd32f42afcaf9bfb8a0677e91f84e4e"}, + {file = "yarl-1.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:9fae7ec5c9a4fe22abb995804e6ce87067dfaf7e940272b79328ce37c8f22097"}, + {file = "yarl-1.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:614fa50fd0db41b79f426939a413d216cdc7bab8d8c8a25844798d286a999c5a"}, + {file = "yarl-1.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ff64f575d71eacb5a4d6f0696bfe991993d979423ea2241f23ab19ff63f0f9d1"}, + {file = "yarl-1.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5c23f6dc3d7126b4c64b80aa186ac2bb65ab104a8372c4454e462fb074197bc6"}, + {file = "yarl-1.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8f847cc092c2b85d22e527f91ea83a6cf51533e727e2461557a47a859f96734"}, + {file = "yarl-1.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:63a5dc2866791236779d99d7a422611d22bb3a3d50935bafa4e017ea13e51469"}, + {file = "yarl-1.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c335342d482e66254ae94b1231b1532790afb754f89e2e0c646f7f19d09740aa"}, + {file = "yarl-1.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4a8c3dedd081cca134a21179aebe58b6e426e8d1e0202da9d1cafa56e01af3c"}, + {file = "yarl-1.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:504d19320c92532cabc3495fb7ed6bb599f3c2bfb45fed432049bf4693dbd6d0"}, + {file = "yarl-1.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b2a8e5eb18181060197e3d5db7e78f818432725c0759bc1e5a9d603d9246389"}, + {file = "yarl-1.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f568d70b7187f4002b6b500c0996c37674a25ce44b20716faebe5fdb8bd356e7"}, + {file = "yarl-1.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:735b285ea46ca7e86ad261a462a071d0968aade44e1a3ea2b7d4f3d63b5aab12"}, + {file = "yarl-1.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2d1c81c3b92bef0c1c180048e43a5a85754a61b4f69d6f84df8e4bd615bef25d"}, + {file = "yarl-1.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8d6e1c1562b53bd26efd38e886fc13863b8d904d559426777990171020c478a9"}, + {file = "yarl-1.9.11-cp312-cp312-win32.whl", hash = "sha256:aeba4aaa59cb709edb824fa88a27cbbff4e0095aaf77212b652989276c493c00"}, + {file = "yarl-1.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:569309a3efb8369ff5d32edb2a0520ebaf810c3059f11d34477418c90aa878fd"}, + {file = "yarl-1.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:4915818ac850c3b0413e953af34398775b7a337babe1e4d15f68c8f5c4872553"}, + {file = "yarl-1.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ef9610b2f5a73707d4d8bac040f0115ca848e510e3b1f45ca53e97f609b54130"}, + {file = "yarl-1.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:47c0a3dc8076a8dd159de10628dea04215bc7ddaa46c5775bf96066a0a18f82b"}, + {file = "yarl-1.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:545f2fbfa0c723b446e9298b5beba0999ff82ce2c126110759e8dac29b5deaf4"}, + {file = "yarl-1.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9137975a4ccc163ad5d7a75aad966e6e4e95dedee08d7995eab896a639a0bce2"}, + {file = "yarl-1.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0b0c70c451d2a86f8408abced5b7498423e2487543acf6fcf618b03f6e669b0a"}, + {file = "yarl-1.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce2bd986b1e44528677c237b74d59f215c8bfcdf2d69442aa10f62fd6ab2951c"}, + {file = "yarl-1.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8d7b717f77846a9631046899c6cc730ea469c0e2fb252ccff1cc119950dbc296"}, + {file = "yarl-1.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3a26a24bbd19241283d601173cea1e5b93dec361a223394e18a1e8e5b0ef20bd"}, + {file = "yarl-1.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c189bf01af155ac9882e128d9f3b3ad68a1f2c2f51404afad7201305df4e12b1"}, + {file = "yarl-1.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0cbcc2c54084b2bda4109415631db017cf2960f74f9e8fd1698e1400e4f8aae2"}, + {file = "yarl-1.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:30f201bc65941a4aa59c1236783efe89049ec5549dafc8cd2b63cc179d3767b0"}, + {file = "yarl-1.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:922ba3b74f0958a0b5b9c14ff1ef12714a381760c08018f2b9827632783a590c"}, + {file = "yarl-1.9.11-cp313-cp313-win32.whl", hash = "sha256:17107b4b8c43e66befdcbe543fff2f9c93f7a3a9f8e3a9c9ac42bffeba0e8828"}, + {file = "yarl-1.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:0324506afab4f2e176a93cb08b8abcb8b009e1f324e6cbced999a8f5dd9ddb76"}, + {file = "yarl-1.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:4e4f820fde9437bb47297194f43d29086433e6467fa28fe9876366ad357bd7bb"}, + {file = "yarl-1.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:dfa9b9d5c9c0dbe69670f5695264452f5e40947590ec3a38cfddc9640ae8ff89"}, + {file = "yarl-1.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e700eb26635ce665c018c8cfea058baff9b843ed0cc77aa61849d807bb82a64c"}, + {file = "yarl-1.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c305c1bdf10869b5e51facf50bd5b15892884aeae81962ae4ba061fc11217103"}, + {file = "yarl-1.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c5b7b307140231ea4f7aad5b69355aba2a67f2d7bc34271cffa3c9c324d35b27"}, + {file = "yarl-1.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a744bdeda6c86cf3025c94eb0e01ccabe949cf385cd75b6576a3ac9669404b68"}, + {file = "yarl-1.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e8ed183c7a8f75e40068333fc185566472a8f6c77a750cf7541e11810576ea5"}, + {file = "yarl-1.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c1db9a4384694b5d20bdd9cb53f033b0831ac816416ab176c8d0997835015d22"}, + {file = "yarl-1.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:70194da6e99713250aa3f335a7fa246b36adf53672a2bcd0ddaa375d04e53dc0"}, + {file = "yarl-1.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ddad5cfcda729e22422bb1c85520bdf2770ce6d975600573ac9017fe882f4b7e"}, + {file = "yarl-1.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ca35996e0a4bed28fa0640d9512d37952f6b50dea583bcc167d4f0b1e112ac7f"}, + {file = "yarl-1.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:61ec0e80970b21a8f3c4b97fa6c6d181c6c6a135dbc7b4a601a78add3feeb209"}, + {file = "yarl-1.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:9636e4519f6c7558fdccf8f91e6e3b98df2340dc505c4cc3286986d33f2096c2"}, + {file = "yarl-1.9.11-cp38-cp38-win32.whl", hash = "sha256:58081cea14b8feda57c7ce447520e9d0a96c4d010cce54373d789c13242d7083"}, + {file = "yarl-1.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:7d2dee7d6485807c0f64dd5eab9262b7c0b34f760e502243dd83ec09d647d5e1"}, + {file = "yarl-1.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d65ad67f981e93ea11f87815f67d086c4f33da4800cf2106d650dd8a0b79dda4"}, + {file = "yarl-1.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:752c0d33b4aacdb147871d0754b88f53922c6dc2aff033096516b3d5f0c02a0f"}, + {file = "yarl-1.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:54cc24be98d7f4ff355ca2e725a577e19909788c0db6beead67a0dda70bd3f82"}, + {file = "yarl-1.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c82126817492bb2ebc946e74af1ffa10aacaca81bee360858477f96124be39a"}, + {file = "yarl-1.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8503989860d7ac10c85cb5b607fec003a45049cf7a5b4b72451e87893c6bb990"}, + {file = "yarl-1.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:475e09a67f8b09720192a170ad9021b7abf7827ffd4f3a83826317a705be06b7"}, + {file = "yarl-1.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afcac5bda602b74ff701e1f683feccd8cce0d5a21dbc68db81bf9bd8fd93ba56"}, + {file = "yarl-1.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aaeffcb84faceb2923a94a8a9aaa972745d3c728ab54dd011530cc30a3d5d0c1"}, + {file = "yarl-1.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:51a6f770ac86477cd5c553f88a77a06fe1f6f3b643b053fcc7902ab55d6cbe14"}, + {file = "yarl-1.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3fcd056cb7dff3aea5b1ee1b425b0fbaa2fbf6a1c6003e88caf524f01de5f395"}, + {file = "yarl-1.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:21e56c30e39a1833e4e3fd0112dde98c2abcbc4c39b077e6105c76bb63d2aa04"}, + {file = "yarl-1.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:0a205ec6349879f5e75dddfb63e069a24f726df5330b92ce76c4752a436aac01"}, + {file = "yarl-1.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a5706821e1cf3c70dfea223e4e0958ea354f4e2af9420a1bd45c6b547297fb97"}, + {file = "yarl-1.9.11-cp39-cp39-win32.whl", hash = "sha256:cc295969f8c2172b5d013c0871dccfec7a0e1186cf961e7ea575d47b4d5cbd32"}, + {file = "yarl-1.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:55a67dd29367ce7c08a0541bb602ec0a2c10d46c86b94830a1a665f7fd093dfa"}, + {file = "yarl-1.9.11-py3-none-any.whl", hash = "sha256:c6f6c87665a9e18a635f0545ea541d9640617832af2317d4f5ad389686b4ed3d"}, + {file = "yarl-1.9.11.tar.gz", hash = "sha256:c7548a90cb72b67652e2cd6ae80e2683ee08fde663104528ac7df12d8ef271d2"}, ] [package.dependencies] @@ -9821,13 +10142,13 @@ multidict = ">=4.0" [[package]] name = "yfinance" -version = "0.2.41" +version = "0.2.43" description = "Download market data from Yahoo! Finance API" optional = false python-versions = "*" files = [ - {file = "yfinance-0.2.41-py2.py3-none-any.whl", hash = "sha256:2ed7b453cb8568773eb2dbb4d87cc37ff02e5d133f7723ec3e219ab0b86b56d8"}, - {file = "yfinance-0.2.41.tar.gz", hash = "sha256:f94409a1ed4d596b9da8d2dbb498faaabfcf593d5870e1412e17669a212bb345"}, + {file = "yfinance-0.2.43-py2.py3-none-any.whl", hash = "sha256:11b4f5515b17450bd3bdcdc26b299aeeaea7ff9cb63d0fa0a865f460c0c7618f"}, + {file = "yfinance-0.2.43.tar.gz", hash = "sha256:32404597f325a2a2c2708aceb8d552088dd26891ac0e6018f6c5f3f2f61055f0"}, ] [package.dependencies] @@ -9866,18 +10187,22 @@ requests = "*" [[package]] name = "zipp" -version = "3.20.0" +version = "3.20.1" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.20.0-py3-none-any.whl", hash = "sha256:58da6168be89f0be59beb194da1250516fdaa062ccebd30127ac65d30045e10d"}, - {file = "zipp-3.20.0.tar.gz", hash = "sha256:0145e43d89664cfe1a2e533adc75adafed82fe2da404b4bbb6b026c0157bdb31"}, + {file = "zipp-3.20.1-py3-none-any.whl", hash = "sha256:9960cd8967c8f85a56f920d5d507274e74f9ff813a0ab8889a5b5be2daf44064"}, + {file = "zipp-3.20.1.tar.gz", hash = "sha256:c22b14cc4763c5a5b04134207736c107db42e9d3ef2d9779d465f5f1bcba572b"}, ] [package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +type = ["pytest-mypy"] [[package]] name = "zope-event" @@ -9899,45 +10224,45 @@ test = ["zope.testrunner"] [[package]] name = "zope-interface" -version = "7.0.1" +version = "7.0.3" description = "Interfaces for Python" optional = false python-versions = ">=3.8" files = [ - {file = "zope.interface-7.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ec4e87e6fdc511a535254daa122c20e11959ce043b4e3425494b237692a34f1c"}, - {file = "zope.interface-7.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:51d5713e8e38f2d3ec26e0dfdca398ed0c20abda2eb49ffc15a15a23eb8e5f6d"}, - {file = "zope.interface-7.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea8d51e5eb29e57d34744369cd08267637aa5a0fefc9b5d33775ab7ff2ebf2e3"}, - {file = "zope.interface-7.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:55bbcc74dc0c7ab489c315c28b61d7a1d03cf938cc99cc58092eb065f120c3a5"}, - {file = "zope.interface-7.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10ebac566dd0cec66f942dc759d46a994a2b3ba7179420f0e2130f88f8a5f400"}, - {file = "zope.interface-7.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:7039e624bcb820f77cc2ff3d1adcce531932990eee16121077eb51d9c76b6c14"}, - {file = "zope.interface-7.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:03bd5c0db82237bbc47833a8b25f1cc090646e212f86b601903d79d7e6b37031"}, - {file = "zope.interface-7.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3f52050c6a10d4a039ec6f2c58e5b3ade5cc570d16cf9d102711e6b8413c90e6"}, - {file = "zope.interface-7.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:af0b33f04677b57843d529b9257a475d2865403300b48c67654c40abac2f9f24"}, - {file = "zope.interface-7.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:696c2a381fc7876b3056711717dba5eddd07c2c9e5ccd50da54029a1293b6e43"}, - {file = "zope.interface-7.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f89a420cf5a6f2aa7849dd59e1ff0e477f562d97cf8d6a1ee03461e1eec39887"}, - {file = "zope.interface-7.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:b59deb0ddc7b431e41d720c00f99d68b52cb9bd1d5605a085dc18f502fe9c47f"}, - {file = "zope.interface-7.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:52f5253cca1b35eaeefa51abd366b87f48f8714097c99b131ba61f3fdbbb58e7"}, - {file = "zope.interface-7.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:88d108d004e0df25224de77ce349a7e73494ea2cb194031f7c9687e68a88ec9b"}, - {file = "zope.interface-7.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c203d82069ba31e1f3bc7ba530b2461ec86366cd4bfc9b95ec6ce58b1b559c34"}, - {file = "zope.interface-7.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f3495462bc0438b76536a0e10d765b168ae636092082531b88340dc40dcd118"}, - {file = "zope.interface-7.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:192b7a792e3145ed880ff6b1a206fdb783697cfdb4915083bfca7065ec845e60"}, - {file = "zope.interface-7.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:400d06c9ec8dbcc96f56e79376297e7be07a315605c9a2208720da263d44d76f"}, - {file = "zope.interface-7.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c1dff87b30fd150c61367d0e2cdc49bb55f8b9fd2a303560bbc24b951573ae1"}, - {file = "zope.interface-7.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f749ca804648d00eda62fe1098f229b082dfca930d8bad8386e572a6eafa7525"}, - {file = "zope.interface-7.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ec212037becf6d2f705b7ed4538d56980b1e7bba237df0d8995cbbed29961dc"}, - {file = "zope.interface-7.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d33cb526efdc235a2531433fc1287fcb80d807d5b401f9b801b78bf22df560dd"}, - {file = "zope.interface-7.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b419f2144e1762ab845f20316f1df36b15431f2622ebae8a6d5f7e8e712b413c"}, - {file = "zope.interface-7.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03f1452d5d1f279184d5bdb663a3dc39902d9320eceb63276240791e849054b6"}, - {file = "zope.interface-7.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ba4b3638d014918b918aa90a9c8370bd74a03abf8fcf9deb353b3a461a59a84"}, - {file = "zope.interface-7.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc0615351221926a36a0fbcb2520fb52e0b23e8c22a43754d9cb8f21358c33c0"}, - {file = "zope.interface-7.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:ce6cbb852fb8f2f9bb7b9cdca44e2e37bce783b5f4c167ff82cb5f5128163c8f"}, - {file = "zope.interface-7.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5566fd9271c89ad03d81b0831c37d46ae5e2ed211122c998637130159a120cf1"}, - {file = "zope.interface-7.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:da0cef4d7e3f19c3bd1d71658d6900321af0492fee36ec01b550a10924cffb9c"}, - {file = "zope.interface-7.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f32ca483e6ade23c7caaee9d5ee5d550cf4146e9b68d2fb6c68bac183aa41c37"}, - {file = "zope.interface-7.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da21e7eec49252df34d426c2ee9cf0361c923026d37c24728b0fa4cc0599fd03"}, - {file = "zope.interface-7.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a8195b99e650e6f329ce4e5eb22d448bdfef0406404080812bc96e2a05674cb"}, - {file = "zope.interface-7.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:19c829d52e921b9fe0b2c0c6a8f9a2508c49678ee1be598f87d143335b6a35dc"}, - {file = "zope.interface-7.0.1.tar.gz", hash = "sha256:f0f5fda7cbf890371a59ab1d06512da4f2c89a6ea194e595808123c863c38eff"}, + {file = "zope.interface-7.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9b9369671a20b8d039b8e5a1a33abd12e089e319a3383b4cc0bf5c67bd05fe7b"}, + {file = "zope.interface-7.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:db6237e8fa91ea4f34d7e2d16d74741187e9105a63bbb5686c61fea04cdbacca"}, + {file = "zope.interface-7.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53d678bb1c3b784edbfb0adeebfeea6bf479f54da082854406a8f295d36f8386"}, + {file = "zope.interface-7.0.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3aa8fcbb0d3c2be1bfd013a0f0acd636f6ed570c287743ae2bbd467ee967154d"}, + {file = "zope.interface-7.0.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6195c3c03fef9f87c0dbee0b3b6451df6e056322463cf35bca9a088e564a3c58"}, + {file = "zope.interface-7.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:11fa1382c3efb34abf16becff8cb214b0b2e3144057c90611621f2d186b7e1b7"}, + {file = "zope.interface-7.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:af94e429f9d57b36e71ef4e6865182090648aada0cb2d397ae2b3f7fc478493a"}, + {file = "zope.interface-7.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dd647fcd765030638577fe6984284e0ebba1a1008244c8a38824be096e37fe3"}, + {file = "zope.interface-7.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bee1b722077d08721005e8da493ef3adf0b7908e0cd85cc7dc836ac117d6f32"}, + {file = "zope.interface-7.0.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2545d6d7aac425d528cd9bf0d9e55fcd47ab7fd15f41a64b1c4bf4c6b24946dc"}, + {file = "zope.interface-7.0.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d04b11ea47c9c369d66340dbe51e9031df2a0de97d68f442305ed7625ad6493"}, + {file = "zope.interface-7.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:064ade95cb54c840647205987c7b557f75d2b2f7d1a84bfab4cf81822ef6e7d1"}, + {file = "zope.interface-7.0.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3fcdc76d0cde1c09c37b7c6b0f8beba2d857d8417b055d4f47df9c34ec518bdd"}, + {file = "zope.interface-7.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3d4b91821305c8d8f6e6207639abcbdaf186db682e521af7855d0bea3047c8ca"}, + {file = "zope.interface-7.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35062d93bc49bd9b191331c897a96155ffdad10744ab812485b6bad5b588d7e4"}, + {file = "zope.interface-7.0.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c96b3e6b0d4f6ddfec4e947130ec30bd2c7b19db6aa633777e46c8eecf1d6afd"}, + {file = "zope.interface-7.0.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e0c151a6c204f3830237c59ee4770cc346868a7a1af6925e5e38650141a7f05"}, + {file = "zope.interface-7.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:3de1d553ce72868b77a7e9d598c9bff6d3816ad2b4cc81c04f9d8914603814f3"}, + {file = "zope.interface-7.0.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab985c566a99cc5f73bc2741d93f1ed24a2cc9da3890144d37b9582965aff996"}, + {file = "zope.interface-7.0.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d976fa7b5faf5396eb18ce6c132c98e05504b52b60784e3401f4ef0b2e66709b"}, + {file = "zope.interface-7.0.3-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a207c6b2c58def5011768140861a73f5240f4f39800625072ba84e76c9da0b"}, + {file = "zope.interface-7.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:382d31d1e68877061daaa6499468e9eb38eb7625d4369b1615ac08d3860fe896"}, + {file = "zope.interface-7.0.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2c4316a30e216f51acbd9fb318aa5af2e362b716596d82cbb92f9101c8f8d2e7"}, + {file = "zope.interface-7.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01e6e58078ad2799130c14a1d34ec89044ada0e1495329d72ee0407b9ae5100d"}, + {file = "zope.interface-7.0.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:799ef7a444aebbad5a145c3b34bff012b54453cddbde3332d47ca07225792ea4"}, + {file = "zope.interface-7.0.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3b7ce6d46fb0e60897d62d1ff370790ce50a57d40a651db91a3dde74f73b738"}, + {file = "zope.interface-7.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:f418c88f09c3ba159b95a9d1cfcdbe58f208443abb1f3109f4b9b12fd60b187c"}, + {file = "zope.interface-7.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:84f8794bd59ca7d09d8fce43ae1b571be22f52748169d01a13d3ece8394d8b5b"}, + {file = "zope.interface-7.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7d92920416f31786bc1b2f34cc4fc4263a35a407425319572cbf96b51e835cd3"}, + {file = "zope.interface-7.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95e5913ec718010dc0e7c215d79a9683b4990e7026828eedfda5268e74e73e11"}, + {file = "zope.interface-7.0.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1eeeb92cb7d95c45e726e3c1afe7707919370addae7ed14f614e22217a536958"}, + {file = "zope.interface-7.0.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecd32f30f40bfd8511b17666895831a51b532e93fc106bfa97f366589d3e4e0e"}, + {file = "zope.interface-7.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:5112c530fa8aa2108a3196b9c2f078f5738c1c37cfc716970edc0df0414acda8"}, + {file = "zope.interface-7.0.3.tar.gz", hash = "sha256:cd2690d4b08ec9eaf47a85914fe513062b20da78d10d6d789a792c0b20307fb1"}, ] [package.dependencies] @@ -10063,4 +10388,4 @@ cffi = ["cffi (>=1.11)"] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.13" -content-hash = "e4c00268514d26bd07c6b72925e0e3b4558ec972895d252e60e9571e3ac38895" +content-hash = "2dbff415c3c9ca95c8dcfb59fc088ce2c0d00037c44f386a34c87c98e1d8b942" diff --git a/api/pyproject.toml b/api/pyproject.toml index f1d5e213ae..69d1fc4ee0 100644 --- a/api/pyproject.toml +++ b/api/pyproject.toml @@ -6,8 +6,6 @@ requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" [tool.ruff] -exclude = [ -] line-length = 120 [tool.ruff.lint] @@ -115,12 +113,14 @@ azure-identity = "1.16.1" azure-storage-blob = "12.13.0" beautifulsoup4 = "4.12.2" boto3 = "1.34.148" +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" @@ -191,6 +191,8 @@ zhipuai = "1.0.7" 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" [tool.poetry.group.indriect.dependencies] kaleido = "0.2.1" rank-bm25 = "~0.2.2" diff --git a/api/services/app_dsl_service.py b/api/services/app_dsl_service.py index a2aa15ed4b..895855a9c8 100644 --- a/api/services/app_dsl_service.py +++ b/api/services/app_dsl_service.py @@ -87,6 +87,7 @@ class AppDslService: icon_background = ( args.get("icon_background") if args.get("icon_background") else app_data.get("icon_background") ) + use_icon_as_answer_icon = app_data.get("use_icon_as_answer_icon", False) # import dsl and create app app_mode = AppMode.value_of(app_data.get("mode")) @@ -101,6 +102,7 @@ class AppDslService: icon_type=icon_type, icon=icon, icon_background=icon_background, + use_icon_as_answer_icon=use_icon_as_answer_icon, ) elif app_mode in [AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.COMPLETION]: app = cls._import_and_create_new_model_config_based_app( @@ -113,6 +115,7 @@ class AppDslService: icon_type=icon_type, icon=icon, icon_background=icon_background, + use_icon_as_answer_icon=use_icon_as_answer_icon, ) else: raise ValueError("Invalid app mode") @@ -171,6 +174,7 @@ class AppDslService: "icon": "🤖" if app_model.icon_type == "image" else app_model.icon, "icon_background": "#FFEAD5" if app_model.icon_type == "image" else app_model.icon_background, "description": app_model.description, + "use_icon_as_answer_icon": app_model.use_icon_as_answer_icon, }, } @@ -218,6 +222,7 @@ class AppDslService: icon_type: str, icon: str, icon_background: str, + use_icon_as_answer_icon: bool, ) -> App: """ Import app dsl and create new workflow based app @@ -231,6 +236,7 @@ class AppDslService: :param icon_type: app icon type, "emoji" or "image" :param icon: app icon :param icon_background: app icon background + :param use_icon_as_answer_icon: use app icon as answer icon """ if not workflow_data: raise ValueError("Missing workflow in data argument " "when app mode is advanced-chat or workflow") @@ -244,6 +250,7 @@ class AppDslService: icon_type=icon_type, icon=icon, icon_background=icon_background, + use_icon_as_answer_icon=use_icon_as_answer_icon, ) # init draft workflow @@ -316,6 +323,7 @@ class AppDslService: icon_type: str, icon: str, icon_background: str, + use_icon_as_answer_icon: bool, ) -> App: """ Import app dsl and create new model config based app @@ -341,6 +349,7 @@ class AppDslService: icon_type=icon_type, icon=icon, icon_background=icon_background, + use_icon_as_answer_icon=use_icon_as_answer_icon, ) app_model_config = AppModelConfig() @@ -369,6 +378,7 @@ class AppDslService: icon_type: str, icon: str, icon_background: str, + use_icon_as_answer_icon: bool, ) -> App: """ Create new app @@ -381,6 +391,7 @@ class AppDslService: :param icon_type: app icon type, "emoji" or "image" :param icon: app icon :param icon_background: app icon background + :param use_icon_as_answer_icon: use app icon as answer icon """ app = App( tenant_id=tenant_id, @@ -392,6 +403,7 @@ class AppDslService: icon_background=icon_background, enable_site=True, enable_api=True, + use_icon_as_answer_icon=use_icon_as_answer_icon, created_by=account.id, updated_by=account.id, ) diff --git a/api/services/app_service.py b/api/services/app_service.py index 462613fb7d..1dacfea246 100644 --- a/api/services/app_service.py +++ b/api/services/app_service.py @@ -221,6 +221,7 @@ class AppService: app.icon_type = args.get("icon_type", "emoji") app.icon = args.get("icon") app.icon_background = args.get("icon_background") + app.use_icon_as_answer_icon = args.get("use_icon_as_answer_icon", False) app.updated_by = current_user.id app.updated_at = datetime.now(timezone.utc).replace(tzinfo=None) db.session.commit() diff --git a/api/services/dataset_service.py b/api/services/dataset_service.py index d10df3f600..cce0874cf4 100644 --- a/api/services/dataset_service.py +++ b/api/services/dataset_service.py @@ -15,7 +15,7 @@ from core.model_manager import ModelManager from core.model_runtime.entities.model_entities import ModelType from core.rag.datasource.keyword.keyword_factory import Keyword from core.rag.models.document import Document as RAGDocument -from core.rag.retrieval.retrival_methods import RetrievalMethod +from core.rag.retrieval.retrieval_methods import RetrievalMethod from events.dataset_event import dataset_was_deleted from events.document_event import document_was_deleted from extensions.ext_database import db @@ -1054,16 +1054,11 @@ class DocumentService: DocumentService.check_documents_upload_quota(count, features) - embedding_model = None dataset_collection_binding_id = None retrieval_model = None if document_data["indexing_technique"] == "high_quality": - model_manager = ModelManager() - embedding_model = model_manager.get_default_model_instance( - tenant_id=current_user.current_tenant_id, model_type=ModelType.TEXT_EMBEDDING - ) dataset_collection_binding = DatasetCollectionBindingService.get_dataset_collection_binding( - embedding_model.provider, embedding_model.model + document_data["embedding_model_provider"], document_data["embedding_model"] ) dataset_collection_binding_id = dataset_collection_binding.id if document_data.get("retrieval_model"): @@ -1082,10 +1077,10 @@ class DocumentService: tenant_id=tenant_id, name="", data_source_type=document_data["data_source"]["type"], - indexing_technique=document_data["indexing_technique"], + indexing_technique=document_data.get("indexing_technique", "high_quality"), created_by=account.id, - embedding_model=embedding_model.model if embedding_model else None, - embedding_model_provider=embedding_model.provider if embedding_model else None, + embedding_model=document_data.get("embedding_model"), + embedding_model_provider=document_data.get("embedding_model_provider"), collection_binding_id=dataset_collection_binding_id, retrieval_model=retrieval_model, ) diff --git a/api/services/hit_testing_service.py b/api/services/hit_testing_service.py index db99064814..2f911f5036 100644 --- a/api/services/hit_testing_service.py +++ b/api/services/hit_testing_service.py @@ -3,7 +3,7 @@ import time from core.rag.datasource.retrieval_service import RetrievalService from core.rag.models.document import Document -from core.rag.retrieval.retrival_methods import RetrievalMethod +from core.rag.retrieval.retrieval_methods import RetrievalMethod from extensions.ext_database import db from models.account import Account from models.dataset import Dataset, DatasetQuery, DocumentSegment @@ -36,7 +36,7 @@ class HitTestingService: retrieval_model = dataset.retrieval_model if dataset.retrieval_model else default_retrieval_model all_documents = RetrievalService.retrieve( - retrival_method=retrieval_model.get("search_method", "semantic_search"), + retrieval_method=retrieval_model.get("search_method", "semantic_search"), dataset_id=dataset.id, query=cls.escape_query_for_search(query), top_k=retrieval_model.get("top_k", 2), diff --git a/api/services/ops_service.py b/api/services/ops_service.py index 35aa6817e1..1e7935d299 100644 --- a/api/services/ops_service.py +++ b/api/services/ops_service.py @@ -32,7 +32,15 @@ class OpsService: "project_key" not in decrypt_tracing_config or not decrypt_tracing_config.get("project_key") ): project_key = OpsTraceManager.get_trace_config_project_key(decrypt_tracing_config, tracing_provider) - new_decrypt_tracing_config.update({"project_key": project_key}) + new_decrypt_tracing_config.update( + {"project_url": "{host}/project/{key}".format(host=decrypt_tracing_config.get("host"), key=project_key)} + ) + + if tracing_provider == "langsmith" and ( + "project_url" not in decrypt_tracing_config or not decrypt_tracing_config.get("project_url") + ): + project_url = OpsTraceManager.get_trace_config_project_url(decrypt_tracing_config, tracing_provider) + new_decrypt_tracing_config.update({"project_url": project_url}) trace_config_data.tracing_config = new_decrypt_tracing_config return trace_config_data.to_dict() @@ -62,8 +70,14 @@ class OpsService: if not OpsTraceManager.check_trace_config_is_effective(tracing_config, tracing_provider): return {"error": "Invalid Credentials"} - # get project key - project_key = OpsTraceManager.get_trace_config_project_key(tracing_config, tracing_provider) + # get project url + if tracing_provider == "langfuse": + project_key = OpsTraceManager.get_trace_config_project_key(tracing_config, tracing_provider) + project_url = "{host}/project/{key}".format(host=tracing_config.get("host"), key=project_key) + elif tracing_provider == "langsmith": + project_url = OpsTraceManager.get_trace_config_project_url(tracing_config, tracing_provider) + else: + project_url = None # check if trace config already exists trace_config_data: TraceAppConfig = ( @@ -78,8 +92,8 @@ class OpsService: # get tenant id tenant_id = db.session.query(App).filter(App.id == app_id).first().tenant_id tracing_config = OpsTraceManager.encrypt_tracing_config(tenant_id, tracing_provider, tracing_config) - if tracing_provider == "langfuse" and project_key: - tracing_config["project_key"] = project_key + if project_url: + tracing_config["project_url"] = project_url trace_config_data = TraceAppConfig( app_id=app_id, tracing_provider=tracing_provider, diff --git a/api/tasks/mail_invite_member_task.py b/api/tasks/mail_invite_member_task.py index 4ef6e29994..c7dfb9bf60 100644 --- a/api/tasks/mail_invite_member_task.py +++ b/api/tasks/mail_invite_member_task.py @@ -19,7 +19,7 @@ def send_invite_member_mail_task(language: str, to: str, token: str, inviter_nam :param inviter_name :param workspace_name - Usage: send_invite_member_mail_task.delay(langauge, to, token, inviter_name, workspace_name) + Usage: send_invite_member_mail_task.delay(language, to, token, inviter_name, workspace_name) """ if not mail.is_inited(): return diff --git a/api/tasks/sync_website_document_indexing_task.py b/api/tasks/sync_website_document_indexing_task.py index 99fb66e1f3..1d2a338c83 100644 --- a/api/tasks/sync_website_document_indexing_task.py +++ b/api/tasks/sync_website_document_indexing_task.py @@ -20,7 +20,7 @@ def sync_website_document_indexing_task(dataset_id: str, document_id: str): :param dataset_id: :param document_id: - Usage: sunc_website_document_indexing_task.delay(dataset_id, document_id) + Usage: sync_website_document_indexing_task.delay(dataset_id, document_id) """ start_at = time.perf_counter() diff --git a/api/tests/integration_tests/model_runtime/__mock/fishaudio.py b/api/tests/integration_tests/model_runtime/__mock/fishaudio.py new file mode 100644 index 0000000000..bec3babeaf --- /dev/null +++ b/api/tests/integration_tests/model_runtime/__mock/fishaudio.py @@ -0,0 +1,82 @@ +import os +from collections.abc import Callable +from typing import Literal + +import httpx +import pytest +from _pytest.monkeypatch import MonkeyPatch + + +def mock_get(*args, **kwargs): + if kwargs.get("headers", {}).get("Authorization") != "Bearer test": + raise httpx.HTTPStatusError( + "Invalid API key", + request=httpx.Request("GET", ""), + response=httpx.Response(401), + ) + + return httpx.Response( + 200, + json={ + "items": [ + {"title": "Model 1", "_id": "model1"}, + {"title": "Model 2", "_id": "model2"}, + ] + }, + request=httpx.Request("GET", ""), + ) + + +def mock_stream(*args, **kwargs): + class MockStreamResponse: + def __init__(self): + self.status_code = 200 + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + pass + + def iter_bytes(self): + yield b"Mocked audio data" + + return MockStreamResponse() + + +def mock_fishaudio( + monkeypatch: MonkeyPatch, + methods: list[Literal["list-models", "tts"]], +) -> Callable[[], None]: + """ + mock fishaudio module + + :param monkeypatch: pytest monkeypatch fixture + :return: unpatch function + """ + + def unpatch() -> None: + monkeypatch.undo() + + if "list-models" in methods: + monkeypatch.setattr(httpx, "get", mock_get) + + if "tts" in methods: + monkeypatch.setattr(httpx, "stream", mock_stream) + + return unpatch + + +MOCK = os.getenv("MOCK_SWITCH", "false").lower() == "true" + + +@pytest.fixture +def setup_fishaudio_mock(request, monkeypatch): + methods = request.param if hasattr(request, "param") else [] + if MOCK: + unpatch = mock_fishaudio(monkeypatch, methods=methods) + + yield + + if MOCK: + unpatch() diff --git a/api/tests/integration_tests/model_runtime/baichuan/test_llm.py b/api/tests/integration_tests/model_runtime/baichuan/test_llm.py index ad58610287..fe7fe96891 100644 --- a/api/tests/integration_tests/model_runtime/baichuan/test_llm.py +++ b/api/tests/integration_tests/model_runtime/baichuan/test_llm.py @@ -8,11 +8,11 @@ from core.model_runtime.entities.llm_entities import LLMResult, LLMResultChunk, from core.model_runtime.entities.message_entities import AssistantPromptMessage, SystemPromptMessage, UserPromptMessage from core.model_runtime.entities.model_entities import AIModelEntity from core.model_runtime.errors.validate import CredentialsValidateFailedError -from core.model_runtime.model_providers.baichuan.llm.llm import BaichuanLarguageModel +from core.model_runtime.model_providers.baichuan.llm.llm import BaichuanLanguageModel def test_predefined_models(): - model = BaichuanLarguageModel() + model = BaichuanLanguageModel() model_schemas = model.predefined_models() assert len(model_schemas) >= 1 assert isinstance(model_schemas[0], AIModelEntity) @@ -20,7 +20,7 @@ def test_predefined_models(): def test_validate_credentials_for_chat_model(): sleep(3) - model = BaichuanLarguageModel() + model = BaichuanLanguageModel() with pytest.raises(CredentialsValidateFailedError): model.validate_credentials( @@ -38,7 +38,7 @@ def test_validate_credentials_for_chat_model(): def test_invoke_model(): sleep(3) - model = BaichuanLarguageModel() + model = BaichuanLanguageModel() response = model.invoke( model="baichuan2-turbo", @@ -64,7 +64,7 @@ def test_invoke_model(): def test_invoke_model_with_system_message(): sleep(3) - model = BaichuanLarguageModel() + model = BaichuanLanguageModel() response = model.invoke( model="baichuan2-turbo", @@ -93,7 +93,7 @@ def test_invoke_model_with_system_message(): def test_invoke_stream_model(): sleep(3) - model = BaichuanLarguageModel() + model = BaichuanLanguageModel() response = model.invoke( model="baichuan2-turbo", @@ -122,7 +122,7 @@ def test_invoke_stream_model(): def test_invoke_with_search(): sleep(3) - model = BaichuanLarguageModel() + model = BaichuanLanguageModel() response = model.invoke( model="baichuan2-turbo", @@ -156,7 +156,7 @@ def test_invoke_with_search(): def test_get_num_tokens(): sleep(3) - model = BaichuanLarguageModel() + model = BaichuanLanguageModel() response = model.get_num_tokens( model="baichuan2-turbo", diff --git a/api/tests/integration_tests/model_runtime/fishaudio/__init__.py b/api/tests/integration_tests/model_runtime/fishaudio/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/tests/integration_tests/model_runtime/fishaudio/test_provider.py b/api/tests/integration_tests/model_runtime/fishaudio/test_provider.py new file mode 100644 index 0000000000..3526574b61 --- /dev/null +++ b/api/tests/integration_tests/model_runtime/fishaudio/test_provider.py @@ -0,0 +1,33 @@ +import os + +import httpx +import pytest + +from core.model_runtime.errors.validate import CredentialsValidateFailedError +from core.model_runtime.model_providers.fishaudio.fishaudio import FishAudioProvider +from tests.integration_tests.model_runtime.__mock.fishaudio import setup_fishaudio_mock + + +@pytest.mark.parametrize("setup_fishaudio_mock", [["list-models"]], indirect=True) +def test_validate_provider_credentials(setup_fishaudio_mock): + print("-----", httpx.get) + provider = FishAudioProvider() + + with pytest.raises(CredentialsValidateFailedError): + provider.validate_provider_credentials( + credentials={ + "api_key": "bad_api_key", + "api_base": os.environ.get("FISH_AUDIO_API_BASE", "https://api.fish.audio"), + "use_public_models": "false", + "latency": "normal", + } + ) + + provider.validate_provider_credentials( + credentials={ + "api_key": os.environ.get("FISH_AUDIO_API_KEY", "test"), + "api_base": os.environ.get("FISH_AUDIO_API_BASE", "https://api.fish.audio"), + "use_public_models": "false", + "latency": "normal", + } + ) diff --git a/api/tests/integration_tests/model_runtime/fishaudio/test_tts.py b/api/tests/integration_tests/model_runtime/fishaudio/test_tts.py new file mode 100644 index 0000000000..f61fee28b9 --- /dev/null +++ b/api/tests/integration_tests/model_runtime/fishaudio/test_tts.py @@ -0,0 +1,32 @@ +import os + +import pytest + +from core.model_runtime.model_providers.fishaudio.tts.tts import ( + FishAudioText2SpeechModel, +) +from tests.integration_tests.model_runtime.__mock.fishaudio import setup_fishaudio_mock + + +@pytest.mark.parametrize("setup_fishaudio_mock", [["tts"]], indirect=True) +def test_invoke_model(setup_fishaudio_mock): + model = FishAudioText2SpeechModel() + + result = model.invoke( + model="tts-default", + tenant_id="test", + credentials={ + "api_key": os.environ.get("FISH_AUDIO_API_KEY", "test"), + "api_base": os.environ.get("FISH_AUDIO_API_BASE", "https://api.fish.audio"), + "use_public_models": "false", + "latency": "normal", + }, + content_text="Hello, world!", + voice="03397b4c4be74759b72533b663fbd001", + ) + + content = b"" + for chunk in result: + content += chunk + + assert content != b"" diff --git a/api/tests/integration_tests/model_runtime/google/test_llm.py b/api/tests/integration_tests/model_runtime/google/test_llm.py index 4d9d490a87..34d08f270a 100644 --- a/api/tests/integration_tests/model_runtime/google/test_llm.py +++ b/api/tests/integration_tests/model_runtime/google/test_llm.py @@ -155,7 +155,7 @@ def test_invoke_chat_model_with_vision_multi_pics(setup_google_mock): user="abc-123", ) - print(f"resultz: {result.message.content}") + print(f"result: {result.message.content}") assert isinstance(result, LLMResult) assert len(result.message.content) > 0 diff --git a/api/tests/integration_tests/model_runtime/oci/__init__.py b/api/tests/integration_tests/model_runtime/oci/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/tests/integration_tests/model_runtime/oci/test_llm.py b/api/tests/integration_tests/model_runtime/oci/test_llm.py new file mode 100644 index 0000000000..531f26a32e --- /dev/null +++ b/api/tests/integration_tests/model_runtime/oci/test_llm.py @@ -0,0 +1,130 @@ +import os +from collections.abc import Generator + +import pytest + +from core.model_runtime.entities.llm_entities import LLMResult, LLMResultChunk, LLMResultChunkDelta +from core.model_runtime.entities.message_entities import ( + AssistantPromptMessage, + PromptMessageTool, + SystemPromptMessage, + TextPromptMessageContent, + UserPromptMessage, +) +from core.model_runtime.errors.validate import CredentialsValidateFailedError +from core.model_runtime.model_providers.oci.llm.llm import OCILargeLanguageModel + + +def test_validate_credentials(): + model = OCILargeLanguageModel() + + with pytest.raises(CredentialsValidateFailedError): + model.validate_credentials( + model="cohere.command-r-plus", + credentials={"oci_config_content": "invalid_key", "oci_key_content": "invalid_key"}, + ) + + model.validate_credentials( + model="cohere.command-r-plus", + credentials={ + "oci_config_content": os.environ.get("OCI_CONFIG_CONTENT"), + "oci_key_content": os.environ.get("OCI_KEY_CONTENT"), + }, + ) + + +def test_invoke_model(): + model = OCILargeLanguageModel() + + response = model.invoke( + model="cohere.command-r-plus", + credentials={ + "oci_config_content": os.environ.get("OCI_CONFIG_CONTENT"), + "oci_key_content": os.environ.get("OCI_KEY_CONTENT"), + }, + prompt_messages=[UserPromptMessage(content="Hi")], + model_parameters={"temperature": 0.5, "max_tokens": 10}, + stop=["How"], + stream=False, + user="abc-123", + ) + + assert isinstance(response, LLMResult) + assert len(response.message.content) > 0 + + +def test_invoke_stream_model(): + model = OCILargeLanguageModel() + + response = model.invoke( + model="meta.llama-3-70b-instruct", + credentials={ + "oci_config_content": os.environ.get("OCI_CONFIG_CONTENT"), + "oci_key_content": os.environ.get("OCI_KEY_CONTENT"), + }, + prompt_messages=[UserPromptMessage(content="Hi")], + model_parameters={"temperature": 0.5, "max_tokens": 100, "seed": 1234}, + stream=True, + user="abc-123", + ) + + assert isinstance(response, Generator) + + for chunk in response: + assert isinstance(chunk, LLMResultChunk) + assert isinstance(chunk.delta, LLMResultChunkDelta) + assert isinstance(chunk.delta.message, AssistantPromptMessage) + assert len(chunk.delta.message.content) > 0 if chunk.delta.finish_reason is None else True + + +def test_invoke_model_with_function(): + model = OCILargeLanguageModel() + + response = model.invoke( + model="cohere.command-r-plus", + credentials={ + "oci_config_content": os.environ.get("OCI_CONFIG_CONTENT"), + "oci_key_content": os.environ.get("OCI_KEY_CONTENT"), + }, + prompt_messages=[UserPromptMessage(content="Hi")], + model_parameters={"temperature": 0.5, "max_tokens": 100, "seed": 1234}, + stream=False, + user="abc-123", + tools=[ + PromptMessageTool( + name="get_current_weather", + description="Get the current weather in a given location", + parameters={ + "type": "object", + "properties": { + "location": {"type": "string", "description": "The city and state e.g. San Francisco, CA"}, + "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}, + }, + "required": ["location"], + }, + ) + ], + ) + + assert isinstance(response, LLMResult) + assert len(response.message.content) > 0 + + +def test_get_num_tokens(): + model = OCILargeLanguageModel() + + num_tokens = model.get_num_tokens( + model="cohere.command-r-plus", + credentials={ + "oci_config_content": os.environ.get("OCI_CONFIG_CONTENT"), + "oci_key_content": os.environ.get("OCI_KEY_CONTENT"), + }, + prompt_messages=[ + SystemPromptMessage( + content="You are a helpful AI assistant.", + ), + UserPromptMessage(content="Hello World!"), + ], + ) + + assert num_tokens == 18 diff --git a/api/tests/integration_tests/model_runtime/oci/test_provider.py b/api/tests/integration_tests/model_runtime/oci/test_provider.py new file mode 100644 index 0000000000..2c7107c7cc --- /dev/null +++ b/api/tests/integration_tests/model_runtime/oci/test_provider.py @@ -0,0 +1,20 @@ +import os + +import pytest + +from core.model_runtime.errors.validate import CredentialsValidateFailedError +from core.model_runtime.model_providers.oci.oci import OCIGENAIProvider + + +def test_validate_provider_credentials(): + provider = OCIGENAIProvider() + + with pytest.raises(CredentialsValidateFailedError): + provider.validate_provider_credentials(credentials={}) + + provider.validate_provider_credentials( + credentials={ + "oci_config_content": os.environ.get("OCI_CONFIG_CONTENT"), + "oci_key_content": os.environ.get("OCI_KEY_CONTENT"), + } + ) diff --git a/api/tests/integration_tests/model_runtime/oci/test_text_embedding.py b/api/tests/integration_tests/model_runtime/oci/test_text_embedding.py new file mode 100644 index 0000000000..032c5c681a --- /dev/null +++ b/api/tests/integration_tests/model_runtime/oci/test_text_embedding.py @@ -0,0 +1,58 @@ +import os + +import pytest + +from core.model_runtime.entities.text_embedding_entities import TextEmbeddingResult +from core.model_runtime.errors.validate import CredentialsValidateFailedError +from core.model_runtime.model_providers.oci.text_embedding.text_embedding import OCITextEmbeddingModel + + +def test_validate_credentials(): + model = OCITextEmbeddingModel() + + with pytest.raises(CredentialsValidateFailedError): + model.validate_credentials( + model="cohere.embed-multilingual-v3.0", + credentials={"oci_config_content": "invalid_key", "oci_key_content": "invalid_key"}, + ) + + model.validate_credentials( + model="cohere.embed-multilingual-v3.0", + credentials={ + "oci_config_content": os.environ.get("OCI_CONFIG_CONTENT"), + "oci_key_content": os.environ.get("OCI_KEY_CONTENT"), + }, + ) + + +def test_invoke_model(): + model = OCITextEmbeddingModel() + + result = model.invoke( + model="cohere.embed-multilingual-v3.0", + credentials={ + "oci_config_content": os.environ.get("OCI_CONFIG_CONTENT"), + "oci_key_content": os.environ.get("OCI_KEY_CONTENT"), + }, + texts=["hello", "world", " ".join(["long_text"] * 100), " ".join(["another_long_text"] * 100)], + user="abc-123", + ) + + assert isinstance(result, TextEmbeddingResult) + assert len(result.embeddings) == 4 + # assert result.usage.total_tokens == 811 + + +def test_get_num_tokens(): + model = OCITextEmbeddingModel() + + num_tokens = model.get_num_tokens( + model="cohere.embed-multilingual-v3.0", + credentials={ + "oci_config_content": os.environ.get("OCI_CONFIG_CONTENT"), + "oci_key_content": os.environ.get("OCI_KEY_CONTENT"), + }, + texts=["hello", "world"], + ) + + assert num_tokens == 2 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 48d1ae323d..7db59fddef 100644 --- a/api/tests/integration_tests/model_runtime/xinference/test_llm.py +++ b/api/tests/integration_tests/model_runtime/xinference/test_llm.py @@ -109,7 +109,7 @@ def test_invoke_stream_chat_model(setup_openai_mock, setup_xinference_mock): """ - Funtion calling of xinference does not support stream mode currently + Function calling of xinference does not support stream mode currently """ # def test_invoke_stream_chat_model_with_functions(): # model = XinferenceAILargeLanguageModel() diff --git a/api/tests/integration_tests/vdb/milvus/test_milvus.py b/api/tests/integration_tests/vdb/milvus/test_milvus.py index 7b5f19ea62..c99739a863 100644 --- a/api/tests/integration_tests/vdb/milvus/test_milvus.py +++ b/api/tests/integration_tests/vdb/milvus/test_milvus.py @@ -12,8 +12,7 @@ class MilvusVectorTest(AbstractVectorTest): self.vector = MilvusVector( collection_name=self.collection_name, config=MilvusConfig( - host="localhost", - port=19530, + uri="http://localhost:19530", user="root", password="Milvus", ), diff --git a/api/tests/integration_tests/vdb/pgvecto_rs/test_pgvecto_rs.py b/api/tests/integration_tests/vdb/pgvecto_rs/test_pgvecto_rs.py index 6b33217d15..6497f47deb 100644 --- a/api/tests/integration_tests/vdb/pgvecto_rs/test_pgvecto_rs.py +++ b/api/tests/integration_tests/vdb/pgvecto_rs/test_pgvecto_rs.py @@ -31,5 +31,5 @@ class PGVectoRSVectorTest(AbstractVectorTest): assert len(ids) == 1 -def test_pgvecot_rs(setup_mock_redis): +def test_pgvecto_rs(setup_mock_redis): PGVectoRSVectorTest().run_all_tests() diff --git a/api/tests/unit_tests/configs/test_dify_config.py b/api/tests/unit_tests/configs/test_dify_config.py index fb415483dd..3f639ccacc 100644 --- a/api/tests/unit_tests/configs/test_dify_config.py +++ b/api/tests/unit_tests/configs/test_dify_config.py @@ -19,6 +19,7 @@ def example_env_file(tmp_path, monkeypatch) -> str: """ CONSOLE_API_URL=https://example.com CONSOLE_WEB_URL=https://example.com + HTTP_REQUEST_MAX_WRITE_TIMEOUT=30 """ ) ) @@ -48,6 +49,12 @@ def test_dify_config(example_env_file): assert config.API_COMPRESSION_ENABLED is False assert config.SENTRY_TRACES_SAMPLE_RATE == 1.0 + # annotated field with default value + assert config.HTTP_REQUEST_MAX_READ_TIMEOUT == 60 + + # annotated field with configured value + assert config.HTTP_REQUEST_MAX_WRITE_TIMEOUT == 30 + # NOTE: If there is a `.env` file in your Workspace, this test might not succeed as expected. # This is due to `pymilvus` loading all the variables from the `.env` file into `os.environ`. diff --git a/api/tests/unit_tests/core/rag/datasource/vdb/milvus/test_milvus.py b/api/tests/unit_tests/core/rag/datasource/vdb/milvus/test_milvus.py index 8d735cae86..bd414c88f4 100644 --- a/api/tests/unit_tests/core/rag/datasource/vdb/milvus/test_milvus.py +++ b/api/tests/unit_tests/core/rag/datasource/vdb/milvus/test_milvus.py @@ -5,7 +5,7 @@ from core.rag.datasource.vdb.milvus.milvus_vector import MilvusConfig def test_default_value(): - valid_config = {"host": "localhost", "port": 19530, "user": "root", "password": "Milvus"} + valid_config = {"uri": "http://localhost:19530", "user": "root", "password": "Milvus"} for key in valid_config: config = valid_config.copy() @@ -15,5 +15,4 @@ def test_default_value(): assert e.value.errors()[0]["msg"] == f"Value error, config MILVUS_{key.upper()} is required" config = MilvusConfig(**valid_config) - assert config.secure is False assert config.database == "default" diff --git a/docker-legacy/docker-compose.yaml b/docker-legacy/docker-compose.yaml index 1f23dc84e0..bc42d4b8f7 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.7.2 + image: langgenius/dify-api:0.7.3 restart: always environment: # Startup mode, 'api' starts the API server. @@ -128,16 +128,14 @@ services: # The Qdrant server gRPC mode PORT. QDRANT_GRPC_PORT: 6334 # Milvus configuration Only available when VECTOR_STORE is `milvus`. - # The milvus host. - MILVUS_HOST: 127.0.0.1 - # The milvus host. - MILVUS_PORT: 19530 + # The milvus uri. + MILVUS_URI: http://127.0.0.1:19530 + # The milvus token. + MILVUS_TOKEN: '' # The milvus username. MILVUS_USER: root # The milvus password. MILVUS_PASSWORD: Milvus - # The milvus tls switch. - MILVUS_SECURE: 'false' # relyt configurations RELYT_HOST: db RELYT_PORT: 5432 @@ -229,7 +227,7 @@ services: # worker service # The Celery worker for processing the queue. worker: - image: langgenius/dify-api:0.7.2 + image: langgenius/dify-api:0.7.3 restart: always environment: CONSOLE_WEB_URL: '' @@ -308,16 +306,14 @@ services: # The Qdrant server gRPC mode PORT. QDRANT_GRPC_PORT: 6334 # Milvus configuration Only available when VECTOR_STORE is `milvus`. - # The milvus host. - MILVUS_HOST: 127.0.0.1 - # The milvus host. - MILVUS_PORT: 19530 + # The milvus uri. + MILVUS_URI: http://127.0.0.1:19530 + # The milvus token. + MILVUS_PORT: '' # The milvus username. MILVUS_USER: root # The milvus password. MILVUS_PASSWORD: Milvus - # The milvus tls switch. - MILVUS_SECURE: 'false' # Mail configuration, support: resend MAIL_TYPE: '' # default send from email address, if not specified @@ -400,7 +396,7 @@ services: # Frontend web application. web: - image: langgenius/dify-web:0.7.2 + image: langgenius/dify-web:0.7.3 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/.env.example b/docker/.env.example index 7233c4e671..ca24c667f6 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -214,6 +214,18 @@ REDIS_USERNAME= REDIS_PASSWORD=difyai123456 REDIS_USE_SSL=false +# Whether to use Redis Sentinel mode. +# If set to true, the application will automatically discover and connect to the master node through Sentinel. +REDIS_USE_SENTINEL=false + +# List of Redis Sentinel nodes. If Sentinel mode is enabled, provide at least one Sentinel IP and port. +# Format: `:,:,:` +REDIS_SENTINELS= +REDIS_SENTINEL_SERVICE_NAME= +REDIS_SENTINEL_USERNAME= +REDIS_SENTINEL_PASSWORD= +REDIS_SENTINEL_SOCKET_TIMEOUT=0.1 + # ------------------------------ # Celery Configuration # ------------------------------ @@ -221,9 +233,16 @@ REDIS_USE_SSL=false # Use redis as the broker, and redis db 1 for celery broker. # Format as follows: `redis://:@:/` # Example: redis://:difyai123456@redis:6379/1 +# If use Redis Sentinel, format as follows: `sentinel://:@:/` +# Example: sentinel://localhost:26379/1;sentinel://localhost:26380/1;sentinel://localhost:26381/1 CELERY_BROKER_URL=redis://:difyai123456@redis:6379/1 BROKER_USE_SSL=false +# If you are using Redis Sentinel for high availability, configure the following settings. +CELERY_USE_SENTINEL=false +CELERY_SENTINEL_MASTER_NAME= +CELERY_SENTINEL_SOCKET_TIMEOUT=0.1 + # ------------------------------ # CORS Configuration # Used to set the front-end cross-domain access policy. @@ -242,7 +261,7 @@ CONSOLE_CORS_ALLOW_ORIGINS=* # ------------------------------ # The type of storage to use for storing user files. -# Supported values are `local` and `s3` and `azure-blob` and `google-storage` and `tencent-cos`, +# Supported values are `local` and `s3` and `azure-blob` and `google-storage` and `tencent-cos` and `huawei-obs` # Default: `local` STORAGE_TYPE=local @@ -285,6 +304,8 @@ ALIYUN_OSS_SECRET_KEY=your-secret-key ALIYUN_OSS_ENDPOINT=https://oss-ap-southeast-1-internal.aliyuncs.com ALIYUN_OSS_REGION=ap-southeast-1 ALIYUN_OSS_AUTH_VERSION=v4 +# Don't start with '/'. OSS doesn't support leading slash in object names. +ALIYUN_OSS_PATH=your-path # Tencent COS Configuration # The name of the Tencent COS bucket to use for storing files. @@ -298,6 +319,28 @@ TENCENT_COS_REGION=your-region # The scheme of the Tencent COS service. TENCENT_COS_SCHEME=your-scheme +# Huawei OBS Configuration +# The name of the Huawei OBS bucket to use for storing files. +HUAWEI_OBS_BUCKET_NAME=your-bucket-name +# The secret key to use for authenticating with the Huawei OBS service. +HUAWEI_OBS_SECRET_KEY=your-secret-key +# The access key to use for authenticating with the Huawei OBS service. +HUAWEI_OBS_ACCESS_KEY=your-access-key +# The server url of the HUAWEI OBS service. +HUAWEI_OBS_SERVER=your-server-url + +# Volcengine TOS Configuration +# The name of the Volcengine TOS bucket to use for storing files. +VOLCENGINE_TOS_BUCKET_NAME=your-bucket-name +# The secret key to use for authenticating with the Volcengine TOS service. +VOLCENGINE_TOS_SECRET_KEY=your-secret-key +# The access key to use for authenticating with the Volcengine TOS service. +VOLCENGINE_TOS_ACCESS_KEY=your-access-key +# The endpoint of the Volcengine TOS service. +VOLCENGINE_TOS_ENDPOINT=your-server-url +# The region of the Volcengine TOS service. +VOLCENGINE_TOS_REGION=your-region + # ------------------------------ # Vector Database Configuration # ------------------------------ @@ -323,16 +366,14 @@ QDRANT_GRPC_ENABLED=false QDRANT_GRPC_PORT=6334 # Milvus configuration Only available when VECTOR_STORE is `milvus`. -# The milvus host. -MILVUS_HOST=127.0.0.1 -# The milvus host. -MILVUS_PORT=19530 +# The milvus uri. +MILVUS_URI=http://127.0.0.1:19530 +# The milvus token. +MILVUS_TOKEN= # The milvus username. MILVUS_USER=root # The milvus password. MILVUS_PASSWORD=Milvus -# The milvus tls switch. -MILVUS_SECURE=false # MyScale configuration, only available when VECTOR_STORE is `myscale` # For multi-language support, please set MYSCALE_FTS_PARAMS with referring to: diff --git a/docker/README.md b/docker/README.md index 1223a58024..7ce3f9bd75 100644 --- a/docker/README.md +++ b/docker/README.md @@ -83,7 +83,7 @@ The `.env.example` file provided in the Docker setup is extensive and covers a w 7. **Vector Database Configuration**: - `VECTOR_STORE`: Type of vector database (e.g., `weaviate`, `milvus`). - - Specific settings for each vector store like `WEAVIATE_ENDPOINT`, `MILVUS_HOST`. + - Specific settings for each vector store like `WEAVIATE_ENDPOINT`, `MILVUS_URI`. 8. **CORS Configuration**: - `WEB_API_CORS_ALLOW_ORIGINS`, `CONSOLE_CORS_ALLOW_ORIGINS`: Settings for cross-origin resource sharing. diff --git a/docker/docker-compose.middleware.yaml b/docker/docker-compose.middleware.yaml index 9a4c40448b..dbfc1ea531 100644 --- a/docker/docker-compose.middleware.yaml +++ b/docker/docker-compose.middleware.yaml @@ -19,6 +19,11 @@ services: - ./volumes/db/data:/var/lib/postgresql/data ports: - "${EXPOSE_POSTGRES_PORT:-5432}:5432" + healthcheck: + test: [ "CMD", "pg_isready" ] + interval: 1s + timeout: 3s + retries: 30 # The redis cache. redis: @@ -31,10 +36,12 @@ services: command: redis-server --requirepass difyai123456 ports: - "${EXPOSE_REDIS_PORT:-6379}:6379" + healthcheck: + test: [ "CMD", "redis-cli", "ping" ] # The DifySandbox sandbox: - image: langgenius/dify-sandbox:0.2.6 + image: langgenius/dify-sandbox:0.2.7 restart: always environment: # The DifySandbox configurations @@ -49,6 +56,8 @@ services: SANDBOX_PORT: ${SANDBOX_PORT:-8194} volumes: - ./volumes/sandbox/dependencies:/dependencies + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:8194/health" ] networks: - ssrf_proxy_network diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index a319d6b45a..aca87a6f8f 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -42,8 +42,17 @@ x-shared-env: &shared-api-worker-env REDIS_PASSWORD: ${REDIS_PASSWORD:-difyai123456} REDIS_USE_SSL: ${REDIS_USE_SSL:-false} REDIS_DB: 0 + REDIS_USE_SENTINEL: ${REDIS_USE_SENTINEL:-false} + REDIS_SENTINELS: ${REDIS_SENTINELS:-} + REDIS_SENTINEL_SERVICE_NAME: ${REDIS_SENTINEL_SERVICE_NAME:-} + REDIS_SENTINEL_USERNAME: ${REDIS_SENTINEL_USERNAME:-} + REDIS_SENTINEL_PASSWORD: ${REDIS_SENTINEL_PASSWORD:-} + REDIS_SENTINEL_SOCKET_TIMEOUT: ${REDIS_SENTINEL_SOCKET_TIMEOUT:-} CELERY_BROKER_URL: ${CELERY_BROKER_URL:-redis://:difyai123456@redis:6379/1} BROKER_USE_SSL: ${BROKER_USE_SSL:-false} + CELERY_USE_SENTINEL: ${CELERY_USE_SENTINEL:-false} + CELERY_SENTINEL_MASTER_NAME: ${CELERY_SENTINEL_MASTER_NAME:-} + CELERY_SENTINEL_SOCKET_TIMEOUT: ${CELERY_SENTINEL_SOCKET_TIMEOUT:-} WEB_API_CORS_ALLOW_ORIGINS: ${WEB_API_CORS_ALLOW_ORIGINS:-*} CONSOLE_CORS_ALLOW_ORIGINS: ${CONSOLE_CORS_ALLOW_ORIGINS:-*} STORAGE_TYPE: ${STORAGE_TYPE:-local} @@ -66,16 +75,26 @@ x-shared-env: &shared-api-worker-env ALIYUN_OSS_ENDPOINT: ${ALIYUN_OSS_ENDPOINT:-} ALIYUN_OSS_REGION: ${ALIYUN_OSS_REGION:-} ALIYUN_OSS_AUTH_VERSION: ${ALIYUN_OSS_AUTH_VERSION:-v4} + ALIYUN_OSS_PATHS: ${ALIYUN_OSS_PATH:-} TENCENT_COS_BUCKET_NAME: ${TENCENT_COS_BUCKET_NAME:-} TENCENT_COS_SECRET_KEY: ${TENCENT_COS_SECRET_KEY:-} TENCENT_COS_SECRET_ID: ${TENCENT_COS_SECRET_ID:-} TENCENT_COS_REGION: ${TENCENT_COS_REGION:-} TENCENT_COS_SCHEME: ${TENCENT_COS_SCHEME:-} + HUAWEI_OBS_BUCKET_NAME: ${HUAWEI_OBS_BUCKET_NAME:-} + HUAWEI_OBS_SECRET_KEY: ${HUAWEI_OBS_SECRET_KEY:-} + HUAWEI_OBS_ACCESS_KEY: ${HUAWEI_OBS_ACCESS_KEY:-} + HUAWEI_OBS_SERVER: ${HUAWEI_OBS_SERVER:-} OCI_ENDPOINT: ${OCI_ENDPOINT:-} OCI_BUCKET_NAME: ${OCI_BUCKET_NAME:-} OCI_ACCESS_KEY: ${OCI_ACCESS_KEY:-} OCI_SECRET_KEY: ${OCI_SECRET_KEY:-} OCI_REGION: ${OCI_REGION:-} + VOLCENGINE_TOS_BUCKET_NAME: ${VOLCENGINE_TOS_BUCKET_NAME:-} + VOLCENGINE_TOS_SECRET_KEY: ${VOLCENGINE_TOS_SECRET_KEY:-} + VOLCENGINE_TOS_ACCESS_KEY: ${VOLCENGINE_TOS_ACCESS_KEY:-} + VOLCENGINE_TOS_ENDPOINT: ${VOLCENGINE_TOS_ENDPOINT:-} + VOLCENGINE_TOS_REGION: ${VOLCENGINE_TOS_REGION:-} VECTOR_STORE: ${VECTOR_STORE:-weaviate} WEAVIATE_ENDPOINT: ${WEAVIATE_ENDPOINT:-http://weaviate:8080} WEAVIATE_API_KEY: ${WEAVIATE_API_KEY:-WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih} @@ -84,11 +103,10 @@ x-shared-env: &shared-api-worker-env QDRANT_CLIENT_TIMEOUT: ${QDRANT_CLIENT_TIMEOUT:-20} QDRANT_GRPC_ENABLED: ${QDRANT_GRPC_ENABLED:-false} QDRANT_GRPC_PORT: ${QDRANT_GRPC_PORT:-6334} - MILVUS_HOST: ${MILVUS_HOST:-127.0.0.1} - MILVUS_PORT: ${MILVUS_PORT:-19530} + MILVUS_URI: ${MILVUS_URI:-http://127.0.0.1:19530} + MILVUS_TOKEN: ${MILVUS_TOKEN:-} MILVUS_USER: ${MILVUS_USER:-root} MILVUS_PASSWORD: ${MILVUS_PASSWORD:-Milvus} - MILVUS_SECURE: ${MILVUS_SECURE:-false} MYSCALE_HOST: ${MYSCALE_HOST:-myscale} MYSCALE_PORT: ${MYSCALE_PORT:-8123} MYSCALE_USER: ${MYSCALE_USER:-default} @@ -190,7 +208,7 @@ x-shared-env: &shared-api-worker-env services: # API service api: - image: langgenius/dify-api:0.7.2 + image: langgenius/dify-api:0.7.3 restart: always environment: # Use the shared environment variables. @@ -210,7 +228,7 @@ services: # worker service # The Celery worker for processing the queue. worker: - image: langgenius/dify-api:0.7.2 + image: langgenius/dify-api:0.7.3 restart: always environment: # Use the shared environment variables. @@ -229,7 +247,7 @@ services: # Frontend web application. web: - image: langgenius/dify-web:0.7.2 + image: langgenius/dify-web:0.7.3 restart: always environment: CONSOLE_API_URL: ${CONSOLE_API_URL:-} @@ -274,7 +292,7 @@ services: # The DifySandbox sandbox: - image: langgenius/dify-sandbox:0.2.6 + image: langgenius/dify-sandbox:0.2.7 restart: always environment: # The DifySandbox configurations @@ -289,6 +307,8 @@ services: SANDBOX_PORT: ${SANDBOX_PORT:-8194} volumes: - ./volumes/sandbox/dependencies:/dependencies + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:8194/health" ] networks: - ssrf_proxy_network @@ -331,7 +351,7 @@ services: - CERTBOT_DOMAIN=${CERTBOT_DOMAIN} - CERTBOT_OPTIONS=${CERTBOT_OPTIONS:-} entrypoint: [ "/docker-entrypoint.sh" ] - command: ["tail", "-f", "/dev/null"] + command: [ "tail", "-f", "/dev/null" ] # The nginx reverse proxy. # used for reverse proxying the API service and Web service. @@ -377,7 +397,7 @@ services: weaviate: image: semitechnologies/weaviate:1.19.0 profiles: - - '' + - "" - weaviate restart: always volumes: @@ -473,13 +493,13 @@ services: - oracle restart: always volumes: - - type: volume - source: oradata + - source: oradata + type: volume target: /opt/oracle/oradata - ./startupscripts:/opt/oracle/scripts/startup environment: - - ORACLE_PWD=${ORACLE_PWD:-Dify123456} - - ORACLE_CHARACTERSET=${ORACLE_CHARACTERSET:-AL32UTF8} + ORACLE_PWD: ${ORACLE_PWD:-Dify123456} + ORACLE_CHARACTERSET: ${ORACLE_CHARACTERSET:-AL32UTF8} # Milvus vector database services etcd: @@ -488,10 +508,10 @@ services: profiles: - milvus environment: - - ETCD_AUTO_COMPACTION_MODE=${ETCD_AUTO_COMPACTION_MODE:-revision} - - ETCD_AUTO_COMPACTION_RETENTION=${ETCD_AUTO_COMPACTION_RETENTION:-1000} - - ETCD_QUOTA_BACKEND_BYTES=${ETCD_QUOTA_BACKEND_BYTES:-4294967296} - - ETCD_SNAPSHOT_COUNT=${ETCD_SNAPSHOT_COUNT:-50000} + ETCD_AUTO_COMPACTION_MODE: ${ETCD_AUTO_COMPACTION_MODE:-revision} + ETCD_AUTO_COMPACTION_RETENTION: ${ETCD_AUTO_COMPACTION_RETENTION:-1000} + ETCD_QUOTA_BACKEND_BYTES: ${ETCD_QUOTA_BACKEND_BYTES:-4294967296} + ETCD_SNAPSHOT_COUNT: ${ETCD_SNAPSHOT_COUNT:-50000} volumes: - ./volumes/milvus/etcd:/etcd command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd @@ -541,8 +561,11 @@ services: timeout: 20s retries: 3 depends_on: - - "etcd" - - "minio" + - etcd + - minio + ports: + - 19530:19530 + - 9091:9091 networks: - milvus @@ -553,10 +576,10 @@ services: profiles: - opensearch environment: - - discovery.type=${OPENSEARCH_DISCOVERY_TYPE:-single-node} - - bootstrap.memory_lock=${OPENSEARCH_BOOTSTRAP_MEMORY_LOCK:-true} - - OPENSEARCH_JAVA_OPTS=-Xms${OPENSEARCH_JAVA_OPTS_MIN:-512m} -Xmx${OPENSEARCH_JAVA_OPTS_MAX:-1024m} - - OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_INITIAL_ADMIN_PASSWORD:-Qazwsxedc!@#123} + discovery.type: ${OPENSEARCH_DISCOVERY_TYPE:-single-node} + bootstrap.memory_lock: ${OPENSEARCH_BOOTSTRAP_MEMORY_LOCK:-true} + OPENSEARCH_JAVA_OPTS: -Xms${OPENSEARCH_JAVA_OPTS_MIN:-512m} -Xmx${OPENSEARCH_JAVA_OPTS_MAX:-1024m} + OPENSEARCH_INITIAL_ADMIN_PASSWORD: ${OPENSEARCH_INITIAL_ADMIN_PASSWORD:-Qazwsxedc!@#123} ulimits: memlock: soft: ${OPENSEARCH_MEMLOCK_SOFT:--1} @@ -596,7 +619,7 @@ services: - ./volumes/myscale/log:/var/log/clickhouse-server - ./volumes/myscale/config/users.d/custom_users_config.xml:/etc/clickhouse-server/users.d/custom_users_config.xml ports: - - "${MYSCALE_PORT:-8123}:${MYSCALE_PORT:-8123}" + - ${MYSCALE_PORT:-8123}:${MYSCALE_PORT:-8123} # https://www.elastic.co/guide/en/elasticsearch/reference/current/settings.html # https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#docker-prod-prerequisites @@ -609,18 +632,18 @@ services: volumes: - dify_es01_data:/usr/share/elasticsearch/data environment: - - ELASTIC_PASSWORD=${ELASTICSEARCH_PASSWORD:-elastic} - - cluster.name=dify-es-cluster - - node.name=dify-es0 - - discovery.type=single-node - - xpack.license.self_generated.type=trial - - xpack.security.enabled=true - - xpack.security.enrollment.enabled=false - - xpack.security.http.ssl.enabled=false + ELASTIC_PASSWORD: ${ELASTICSEARCH_PASSWORD:-elastic} + cluster.name: dify-es-cluster + node.name: dify-es0 + discovery.type: single-node + xpack.license.self_generated.type: trial + xpack.security.enabled: "true" + xpack.security.enrollment.enabled: "false" + xpack.security.http.ssl.enabled: "false" ports: - ${ELASTICSEARCH_PORT:-9200}:9200 healthcheck: - test: ["CMD", "curl", "-s", "http://localhost:9200/_cluster/health?pretty"] + test: [ "CMD", "curl", "-s", "http://localhost:9200/_cluster/health?pretty" ] interval: 30s timeout: 10s retries: 50 @@ -636,15 +659,15 @@ services: - elasticsearch restart: always environment: - - XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY=d1a66dfd-c4d3-4a0a-8290-2abcb83ab3aa - - NO_PROXY=localhost,127.0.0.1,elasticsearch,kibana - - XPACK_SECURITY_ENABLED=true - - XPACK_SECURITY_ENROLLMENT_ENABLED=false - - XPACK_SECURITY_HTTP_SSL_ENABLED=false - - XPACK_FLEET_ISAIRGAPPED=true - - I18N_LOCALE=zh-CN - - SERVER_PORT=5601 - - ELASTICSEARCH_HOSTS="http://elasticsearch:9200" + XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY: d1a66dfd-c4d3-4a0a-8290-2abcb83ab3aa + NO_PROXY: localhost,127.0.0.1,elasticsearch,kibana + XPACK_SECURITY_ENABLED: "true" + XPACK_SECURITY_ENROLLMENT_ENABLED: "false" + XPACK_SECURITY_HTTP_SSL_ENABLED: "false" + XPACK_FLEET_ISAIRGAPPED: "true" + I18N_LOCALE: zh-CN + SERVER_PORT: "5601" + ELASTICSEARCH_HOSTS: http://elasticsearch:9200 ports: - ${KIBANA_PORT:-5601}:5601 healthcheck: diff --git a/docker/startupscripts/init.sh b/docker/startupscripts/init.sh index ee7600850a..c6e6e1966f 100755 --- a/docker/startupscripts/init.sh +++ b/docker/startupscripts/init.sh @@ -1,13 +1,13 @@ #!/usr/bin/env bash -DB_INITIALISED="/opt/oracle/oradata/dbinit" -#[ -f ${DB_INITIALISED} ] && exit -#touch ${DB_INITIALISED} -if [ -f ${DB_INITIALISED} ]; then +DB_INITIALIZED="/opt/oracle/oradata/dbinit" +#[ -f ${DB_INITIALIZED} ] && exit +#touch ${DB_INITIALIZED} +if [ -f ${DB_INITIALIZED} ]; then echo 'File exists. Standards for have been Init' exit else - echo 'File does not exist. Standards for first time Strart up this DB' + echo 'File does not exist. Standards for first time Start up this DB' "$ORACLE_HOME"/bin/sqlplus -s "/ as sysdba" @"/opt/oracle/scripts/startup/init_user.script"; - touch ${DB_INITIALISED} + touch ${DB_INITIALIZED} fi diff --git a/sdks/nodejs-client/README.md b/sdks/nodejs-client/README.md index 50303b4867..37b5ca2d0a 100644 --- a/sdks/nodejs-client/README.md +++ b/sdks/nodejs-client/README.md @@ -18,7 +18,7 @@ const query = 'Please tell me a short story in 10 words or less.' const remote_url_files = [{ type: 'image', transfer_method: 'remote_url', - url: 'your_url_addresss' + url: 'your_url_address' }] // Create a completion client diff --git a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout.tsx b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout.tsx index 8723420d84..e728749b85 100644 --- a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout.tsx +++ b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout.tsx @@ -108,7 +108,7 @@ const AppDetailLayout: FC = (props) => { useEffect(() => { setAppDetail() fetchAppDetail({ url: '/apps', id: appId }).then((res) => { - // redirections + // redirection if ((res.mode === 'workflow' || res.mode === 'advanced-chat') && (pathname).endsWith('configuration')) { router.replace(`/app/${appId}/workflow`) } diff --git a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/provider-panel.tsx b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/provider-panel.tsx index b908322a92..6e5046ecf8 100644 --- a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/provider-panel.tsx +++ b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/provider-panel.tsx @@ -48,9 +48,10 @@ const ProviderPanel: FC = ({ e.preventDefault() e.stopPropagation() - const url = `${config?.host}/project/${config?.project_key}` - window.open(url, '_blank', 'noopener,noreferrer') - }, []) + const url = config?.project_url + if (url) + window.open(url, '_blank', 'noopener,noreferrer') + }, [config?.project_url]) const handleChosen = useCallback((e: React.MouseEvent) => { e.stopPropagation() diff --git a/web/app/(commonLayout)/apps/AppCard.tsx b/web/app/(commonLayout)/apps/AppCard.tsx index bc7308a711..1ffb132cf8 100644 --- a/web/app/(commonLayout)/apps/AppCard.tsx +++ b/web/app/(commonLayout)/apps/AppCard.tsx @@ -21,7 +21,7 @@ import Divider from '@/app/components/base/divider' import { getRedirection } from '@/utils/app-redirection' import { useProviderContext } from '@/context/provider-context' import { NEED_REFRESH_APP_LIST_KEY } from '@/config' -import { AiText, ChatBot, CuteRobote } from '@/app/components/base/icons/src/vender/solid/communication' +import { AiText, ChatBot, CuteRobot } from '@/app/components/base/icons/src/vender/solid/communication' import { Route } from '@/app/components/base/icons/src/vender/solid/mapsAndTravel' import type { CreateAppModalProps } from '@/app/components/explore/create-app-modal' import EditAppModal from '@/app/components/explore/create-app-modal' @@ -79,6 +79,7 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => { icon, icon_background, description, + use_icon_as_answer_icon, }) => { try { await updateAppInfo({ @@ -88,6 +89,7 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => { icon, icon_background, description, + use_icon_as_answer_icon, }) setShowEditModal(false) notify({ @@ -255,7 +257,7 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => { e.preventDefault() getRedirection(isCurrentWorkspaceEditor, app, push) }} - className='group flex col-span-1 bg-white border-2 border-solid border-transparent rounded-xl shadow-sm min-h-[160px] flex flex-col transition-all duration-200 ease-in-out cursor-pointer hover:shadow-lg' + className='relative group col-span-1 bg-white border-2 border-solid border-transparent rounded-xl shadow-sm flex flex-col transition-all duration-200 ease-in-out cursor-pointer hover:shadow-lg' >
@@ -271,7 +273,7 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => { )} {app.mode === 'agent-chat' && ( - + )} {app.mode === 'chat' && ( @@ -297,17 +299,16 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
-
- {app.description} +
+
+ {app.description} +
{isCurrentWorkspaceEditor && ( @@ -371,6 +372,8 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => { appIconBackground={app.icon_background} appIconUrl={app.icon_url} appDescription={app.description} + appMode={app.mode} + appUseIconAsAnswerIcon={app.use_icon_as_answer_icon} show={showEditModal} onConfirm={onEdit} onHide={() => setShowEditModal(false)} diff --git a/web/app/(commonLayout)/apps/Apps.tsx b/web/app/(commonLayout)/apps/Apps.tsx index c16512bd50..132096c6b4 100644 --- a/web/app/(commonLayout)/apps/Apps.tsx +++ b/web/app/(commonLayout)/apps/Apps.tsx @@ -139,7 +139,7 @@ const Apps = () => {
- {/* desscription */} + {/* description */} {appDetail.description && (
{appDetail.description}
)} @@ -423,6 +425,8 @@ const AppInfo = ({ expand }: IAppInfoProps) => { appIconBackground={appDetail.icon_background} appIconUrl={appDetail.icon_url} appDescription={appDetail.description} + appMode={appDetail.mode} + appUseIconAsAnswerIcon={appDetail.use_icon_as_answer_icon} show={showEditModal} onConfirm={onEdit} onHide={() => setShowEditModal(false)} diff --git a/web/app/components/app/annotation/index.tsx b/web/app/components/app/annotation/index.tsx index 0f54f5bfc3..c66aaef6ce 100644 --- a/web/app/components/app/annotation/index.tsx +++ b/web/app/components/app/annotation/index.tsx @@ -232,8 +232,8 @@ const Annotation: FC = ({ middlePagesSiblingCount={1} setCurrentPage={setCurrPage} totalPages={Math.ceil(total / APP_PAGE_LIMIT)} - truncableClassName="w-8 px-0.5 text-center" - truncableText="..." + truncatableClassName="w-8 px-0.5 text-center" + truncatableText="..." > = ({ middlePagesSiblingCount={1} setCurrentPage={setCurrPage} totalPages={Math.ceil(total / APP_PAGE_LIMIT)} - truncableClassName="w-8 px-0.5 text-center" - truncableText="..." + truncatableClassName="w-8 px-0.5 text-center" + truncatableText="..." > state.appDetail) + const [publishedTime, setPublishedTime] = useState(publishedAt) const { app_base_url: appBaseURL = '', access_token: accessToken = '' } = appDetail?.site ?? {} const appMode = (appDetail?.mode !== 'completion' && appDetail?.mode !== 'workflow') ? 'chat' : appDetail.mode const appURL = `${appBaseURL}/${appMode}/${accessToken}` @@ -76,6 +77,7 @@ const AppPublisher = ({ try { await onPublish?.(modelAndParameter) setPublished(true) + setPublishedTime(Date.now()) } catch (e) { setPublished(false) @@ -131,13 +133,13 @@ const AppPublisher = ({
- {publishedAt ? t('workflow.common.latestPublished') : t('workflow.common.currentDraftUnpublished')} + {publishedTime ? t('workflow.common.latestPublished') : t('workflow.common.currentDraftUnpublished')}
- {publishedAt + {publishedTime ? (
- {t('workflow.common.publishedAt')} {formatTimeFromNow(publishedAt)} + {t('workflow.common.publishedAt')} {formatTimeFromNow(publishedTime)}
- }>{t('workflow.common.runApp')} + }>{t('workflow.common.runApp')} {appDetail?.mode === 'workflow' ? ( } > @@ -199,16 +201,16 @@ const AppPublisher = ({ setEmbeddingModalOpen(true) handleTrigger() }} - disabled={!publishedAt} + disabled={!publishedTime} icon={} > {t('workflow.common.embedIntoSite')} )} - }>{t('workflow.common.accessAPIReference')} + }>{t('workflow.common.accessAPIReference')} {appDetail?.mode === 'workflow' && ( = ({ {isShowConfirmAddVar && ( v.name)} - onConfrim={handleAutoAdd(true)} + onConfirm={handleAutoAdd(true)} onCancel={handleAutoAdd(false)} onHide={hideConfirmAddVar} /> diff --git a/web/app/components/app/configuration/config-prompt/confirm-add-var/index.tsx b/web/app/components/app/configuration/config-prompt/confirm-add-var/index.tsx index f08f2ffc69..922f8bb36a 100644 --- a/web/app/components/app/configuration/config-prompt/confirm-add-var/index.tsx +++ b/web/app/components/app/configuration/config-prompt/confirm-add-var/index.tsx @@ -7,7 +7,7 @@ import Button from '@/app/components/base/button' export type IConfirmAddVarProps = { varNameArr: string[] - onConfrim: () => void + onConfirm: () => void onCancel: () => void onHide: () => void } @@ -22,7 +22,7 @@ const VarIcon = ( const ConfirmAddVar: FC = ({ varNameArr, - onConfrim, + onConfirm, onCancel, // onHide, }) => { @@ -63,7 +63,7 @@ const ConfirmAddVar: FC = ({
- +
diff --git a/web/app/components/app/configuration/config-prompt/conversation-histroy/edit-modal.tsx b/web/app/components/app/configuration/config-prompt/conversation-history/edit-modal.tsx similarity index 100% rename from web/app/components/app/configuration/config-prompt/conversation-histroy/edit-modal.tsx rename to web/app/components/app/configuration/config-prompt/conversation-history/edit-modal.tsx diff --git a/web/app/components/app/configuration/config-prompt/conversation-histroy/history-panel.tsx b/web/app/components/app/configuration/config-prompt/conversation-history/history-panel.tsx similarity index 100% rename from web/app/components/app/configuration/config-prompt/conversation-histroy/history-panel.tsx rename to web/app/components/app/configuration/config-prompt/conversation-history/history-panel.tsx diff --git a/web/app/components/app/configuration/config-prompt/simple-prompt-input.tsx b/web/app/components/app/configuration/config-prompt/simple-prompt-input.tsx index 69e01a8e22..d7bfe8534e 100644 --- a/web/app/components/app/configuration/config-prompt/simple-prompt-input.tsx +++ b/web/app/components/app/configuration/config-prompt/simple-prompt-input.tsx @@ -33,7 +33,7 @@ export type ISimplePromptInput = { promptTemplate: string promptVariables: PromptVariable[] readonly?: boolean - onChange?: (promp: string, promptVariables: PromptVariable[]) => void + onChange?: (prompt: string, promptVariables: PromptVariable[]) => void noTitle?: boolean gradientBorder?: boolean editorHeight?: number @@ -239,7 +239,7 @@ const Prompt: FC = ({ {isShowConfirmAddVar && ( v.name)} - onConfrim={handleAutoAdd(true)} + onConfirm={handleAutoAdd(true)} onCancel={handleAutoAdd(false)} onHide={hideConfirmAddVar} /> diff --git a/web/app/components/app/configuration/config-var/config-modal/index.tsx b/web/app/components/app/configuration/config-var/config-modal/index.tsx index 3296c77fb2..606280653e 100644 --- a/web/app/components/app/configuration/config-var/config-modal/index.tsx +++ b/web/app/components/app/configuration/config-var/config-modal/index.tsx @@ -47,7 +47,7 @@ const ConfigModal: FC = ({ if (!isValid) { Toast.notify({ type: 'error', - message: t(`appDebug.varKeyError.${errorMessageKey}`, { key: t('appDebug.variableConig.varName') }), + message: t(`appDebug.varKeyError.${errorMessageKey}`, { key: t('appDebug.variableConfig.varName') }), }) return false } @@ -101,7 +101,7 @@ const ConfigModal: FC = ({ // } if (!tempPayload.label) { - Toast.notify({ type: 'error', message: t('appDebug.variableConig.errorMsg.labelNameRequired') }) + Toast.notify({ type: 'error', message: t('appDebug.variableConfig.errorMsg.labelNameRequired') }) return } if (isStringInput || type === InputVarType.number) { @@ -109,7 +109,7 @@ const ConfigModal: FC = ({ } else { if (options?.length === 0) { - Toast.notify({ type: 'error', message: t('appDebug.variableConig.errorMsg.atLeastOneOption') }) + Toast.notify({ type: 'error', message: t('appDebug.variableConfig.errorMsg.atLeastOneOption') }) return } const obj: Record = {} @@ -122,7 +122,7 @@ const ConfigModal: FC = ({ obj[o] = true }) if (hasRepeatedItem) { - Toast.notify({ type: 'error', message: t('appDebug.variableConig.errorMsg.optionRepeat') }) + Toast.notify({ type: 'error', message: t('appDebug.variableConfig.errorMsg.optionRepeat') }) return } onConfirm(tempPayload, moreInfo) @@ -131,14 +131,14 @@ const ConfigModal: FC = ({ return (
- +
handlePayloadChange('type')(InputVarType.textInput)} /> handlePayloadChange('type')(InputVarType.paragraph)} /> @@ -147,39 +147,39 @@ const ConfigModal: FC = ({
- + handlePayloadChange('variable')(e.target.value)} onBlur={handleVarKeyBlur} - placeholder={t('appDebug.variableConig.inputPlaceholder')!} + placeholder={t('appDebug.variableConfig.inputPlaceholder')!} /> - + handlePayloadChange('label')(e.target.value)} - placeholder={t('appDebug.variableConig.inputPlaceholder')!} + placeholder={t('appDebug.variableConfig.inputPlaceholder')!} /> {isStringInput && ( - + )} {type === InputVarType.select && ( - + )} - +
diff --git a/web/app/components/app/configuration/config-var/config-select/index.tsx b/web/app/components/app/configuration/config-var/config-select/index.tsx index e23c7330b1..449cb8b12f 100644 --- a/web/app/components/app/configuration/config-var/config-select/index.tsx +++ b/web/app/components/app/configuration/config-var/config-select/index.tsx @@ -77,7 +77,7 @@ const ConfigSelect: FC = ({ onClick={() => { onChange([...options, '']) }} className='flex items-center h-9 px-3 gap-2 rounded-lg cursor-pointer text-gray-400 bg-gray-100'> -
{t('appDebug.variableConig.addOption')}
+
{t('appDebug.variableConfig.addOption')}
) diff --git a/web/app/components/app/configuration/config-var/index.tsx b/web/app/components/app/configuration/config-var/index.tsx index 802528e0af..fc165571c4 100644 --- a/web/app/components/app/configuration/config-var/index.tsx +++ b/web/app/components/app/configuration/config-var/index.tsx @@ -88,7 +88,6 @@ const ConfigVar: FC = ({ promptVariables, readonly, onPromptVar } as InputVar })() const updatePromptVariableItem = (payload: InputVar) => { - console.log(payload) const newPromptVariables = produce(promptVariables, (draft) => { const { variable, label, type, ...rest } = payload draft[currIndex] = { diff --git a/web/app/components/app/configuration/config-var/select-type-item/index.tsx b/web/app/components/app/configuration/config-var/select-type-item/index.tsx index bb5e700d11..c76aed1a10 100644 --- a/web/app/components/app/configuration/config-var/select-type-item/index.tsx +++ b/web/app/components/app/configuration/config-var/select-type-item/index.tsx @@ -18,7 +18,7 @@ const SelectTypeItem: FC = ({ onClick, }) => { const { t } = useTranslation() - const typeName = t(`appDebug.variableConig.${type}`) + const typeName = t(`appDebug.variableConfig.${type}`) return (
= ({
- - - - + + + +
- +
diff --git a/web/app/components/app/configuration/config/agent/agent-setting/index.tsx b/web/app/components/app/configuration/config/agent/agent-setting/index.tsx index b295a4e709..959336457f 100644 --- a/web/app/components/app/configuration/config/agent/agent-setting/index.tsx +++ b/web/app/components/app/configuration/config/agent/agent-setting/index.tsx @@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next' import { RiCloseLine } from '@remixicon/react' import ItemPanel from './item-panel' import Button from '@/app/components/base/button' -import { CuteRobote } from '@/app/components/base/icons/src/vender/solid/communication' +import { CuteRobot } from '@/app/components/base/icons/src/vender/solid/communication' import { Unblur } from '@/app/components/base/icons/src/vender/solid/education' import Slider from '@/app/components/base/slider' import type { AgentConfig } from '@/models/debug' @@ -65,7 +65,7 @@ const AgentSetting: FC = ({ + } name={t('appDebug.agent.agentMode')} description={t('appDebug.agent.agentModeDes')} diff --git a/web/app/components/app/configuration/config/assistant-type-picker/index.tsx b/web/app/components/app/configuration/config/assistant-type-picker/index.tsx index 6bdf678f85..336d736e3b 100644 --- a/web/app/components/app/configuration/config/assistant-type-picker/index.tsx +++ b/web/app/components/app/configuration/config/assistant-type-picker/index.tsx @@ -12,7 +12,7 @@ import { } from '@/app/components/base/portal-to-follow-elem' import { BubbleText } from '@/app/components/base/icons/src/vender/solid/education' import Radio from '@/app/components/base/radio/ui' -import { CuteRobote } from '@/app/components/base/icons/src/vender/solid/communication' +import { CuteRobot } from '@/app/components/base/icons/src/vender/solid/communication' import { Settings04 } from '@/app/components/base/icons/src/vender/line/general' import { ArrowUpRight } from '@/app/components/base/icons/src/vender/line/arrows' import type { AgentConfig } from '@/models/debug' @@ -117,7 +117,7 @@ const AssistantTypePicker: FC = ({ > setOpen(v => !v)}>
- {isAgent ? : } + {isAgent ? : }
{t(`appDebug.assistantType.${isAgent ? 'agentAssistant' : 'chatAssistant'}.name`)}
@@ -135,7 +135,7 @@ const AssistantTypePicker: FC = ({ onClick={handleChange} /> void }) { - const [tempshowOpeningStatement, setTempShowOpeningStatement] = React.useState(!!introduction) + const [tempShowOpeningStatement, setTempShowOpeningStatement] = React.useState(!!introduction) useEffect(() => { // wait to api data back if (introduction) @@ -48,7 +48,7 @@ function useFeature({ // }, [moreLikeThis]) const featureConfig = { - openingStatement: tempshowOpeningStatement, + openingStatement: tempShowOpeningStatement, moreLikeThis, suggestedQuestionsAfterAnswer, speechToText, diff --git a/web/app/components/app/configuration/config/index.tsx b/web/app/components/app/configuration/config/index.tsx index b8bedba20b..12551f508e 100644 --- a/web/app/components/app/configuration/config/index.tsx +++ b/web/app/components/app/configuration/config/index.tsx @@ -7,9 +7,9 @@ import { useBoolean, useScroll } from 'ahooks' import { useFormattingChangedDispatcher } from '../debug/hooks' import DatasetConfig from '../dataset-config' import ChatGroup from '../features/chat-group' -import ExperienceEnchanceGroup from '../features/experience-enchance-group' +import ExperienceEnhanceGroup from '../features/experience-enhance-group' import Toolbox from '../toolbox' -import HistoryPanel from '../config-prompt/conversation-histroy/history-panel' +import HistoryPanel from '../config-prompt/conversation-history/history-panel' import ConfigVision from '../config-vision' import useAnnotationConfig from '../toolbox/annotation/use-annotation-config' import AddFeatureBtn from './feature/add-feature-btn' @@ -254,7 +254,7 @@ const Config: FC = () => { /> )} - {/* ChatConifig */} + {/* ChatConfig */} { hasChatConfig && ( { {/* Text Generation config */}{ hasCompletionConfig && ( - diff --git a/web/app/components/app/configuration/dataset-config/params-config/config-content.tsx b/web/app/components/app/configuration/dataset-config/params-config/config-content.tsx index 7f55649dab..91cae54bb8 100644 --- a/web/app/components/app/configuration/dataset-config/params-config/config-content.tsx +++ b/web/app/components/app/configuration/dataset-config/params-config/config-content.tsx @@ -1,20 +1,12 @@ 'use client' -import { memo, useMemo } from 'react' +import { memo, useEffect, useMemo } from 'react' import type { FC } from 'react' import { useTranslation } from 'react-i18next' -import { - RiAlertFill, -} from '@remixicon/react' import WeightedScore from './weighted-score' import TopKItem from '@/app/components/base/param-item/top-k-item' import ScoreThresholdItem from '@/app/components/base/param-item/score-threshold-item' -import RadioCard from '@/app/components/base/radio-card/simple' import { RETRIEVE_TYPE } from '@/types/app' -import { - MultiPathRetrieval, - NTo1Retrieval, -} from '@/app/components/base/icons/src/public/common' import type { DatasetConfigs, } from '@/models/debug' @@ -31,7 +23,6 @@ import { RerankingModeEnum } from '@/models/datasets' import cn from '@/utils/classnames' import { useSelectedDatasetsMode } from '@/app/components/workflow/nodes/knowledge-retrieval/hooks' import Switch from '@/app/components/base/switch' -import { useGetLanguage } from '@/context/i18n' type Props = { datasetConfigs: DatasetConfigs @@ -43,11 +34,6 @@ type Props = { selectedDatasets?: DataSet[] } -const LEGACY_LINK_MAP = { - en_US: 'https://docs.dify.ai/guides/knowledge-base/integrate-knowledge-within-application', - zh_Hans: 'https://docs.dify.ai/v/zh-hans/guides/knowledge-base/integrate_knowledge_within_application', -} as Record - const ConfigContent: FC = ({ datasetConfigs, onChange, @@ -58,15 +44,18 @@ const ConfigContent: FC = ({ selectedDatasets = [], }) => { const { t } = useTranslation() - const language = useGetLanguage() const selectedDatasetsMode = useSelectedDatasetsMode(selectedDatasets) const type = datasetConfigs.retrieval_model - const setType = (value: RETRIEVE_TYPE) => { - onChange({ - ...datasetConfigs, - retrieval_model: value, - }, true) - } + + useEffect(() => { + if (type === RETRIEVE_TYPE.oneWay) { + onChange({ + ...datasetConfigs, + retrieval_model: RETRIEVE_TYPE.multiWay, + }, isInWorkflow) + } + }, [type]) + const { modelList: rerankModelList, defaultModel: rerankDefaultModel, @@ -166,63 +155,21 @@ const ConfigContent: FC = ({ return (
{t('dataset.retrievalSettings')}
-
- } - title={( -
- {t('appDebug.datasetConfig.retrieveOneWay.title')} - - {t('dataset.nTo1RetrievalLegacy')} -
- )} - > -
legacy
- -
- )} - description={t('appDebug.datasetConfig.retrieveOneWay.description')} - isChosen={type === RETRIEVE_TYPE.oneWay} - onChosen={() => { setType(RETRIEVE_TYPE.oneWay) }} - extra={( -
- -
- {t('dataset.nTo1RetrievalLegacyLinkText')} - - {t('dataset.nTo1RetrievalLegacyLink')} - -
-
- )} - /> - } - title={t('appDebug.datasetConfig.retrieveMultiWay.title')} - description={t('appDebug.datasetConfig.retrieveMultiWay.description')} - isChosen={type === RETRIEVE_TYPE.multiWay} - onChosen={() => { setType(RETRIEVE_TYPE.multiWay) }} - /> +
+ {t('dataset.defaultRetrievalTip')}
{type === RETRIEVE_TYPE.multiWay && ( <> -
-
- {t('dataset.rerankSettings')} +
+
+ {t('dataset.rerankSettings')} +
+
{ selectedDatasetsMode.inconsistentEmbeddingModel && ( -
+
{t('dataset.inconsistentEmbeddingModelTip')}
) @@ -230,7 +177,7 @@ const ConfigContent: FC = ({ { selectedDatasetsMode.mixtureHighQualityAndEconomic && ( -
+
{t('dataset.mixtureHighQualityAndEconomicTip')}
) diff --git a/web/app/components/app/configuration/dataset-config/params-config/index.tsx b/web/app/components/app/configuration/dataset-config/params-config/index.tsx index 5cb76e32b2..656cbfea65 100644 --- a/web/app/components/app/configuration/dataset-config/params-config/index.tsx +++ b/web/app/components/app/configuration/dataset-config/params-config/index.tsx @@ -70,13 +70,13 @@ const ParamsConfig = ({ const { defaultModel: rerankDefaultModel, - currentModel: isRerankDefaultModelVaild, + currentModel: isRerankDefaultModelValid, } = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.rerank) const isValid = () => { let errMsg = '' if (tempDataSetConfigs.retrieval_model === RETRIEVE_TYPE.multiWay) { - if (!tempDataSetConfigs.reranking_model?.reranking_model_name && (!rerankDefaultModel && isRerankDefaultModelVaild)) + if (!tempDataSetConfigs.reranking_model?.reranking_model_name && (!rerankDefaultModel && isRerankDefaultModelValid)) errMsg = t('appDebug.datasetConfig.rerankModelRequired') } if (errMsg) { diff --git a/web/app/components/app/configuration/dataset-config/select-dataset/index.tsx b/web/app/components/app/configuration/dataset-config/select-dataset/index.tsx index f9117a51c3..4493755ba0 100644 --- a/web/app/components/app/configuration/dataset-config/select-dataset/index.tsx +++ b/web/app/components/app/configuration/dataset-config/select-dataset/index.tsx @@ -135,7 +135,7 @@ const SelectDataSet: FC = ({
{item.name}
{!item.embedding_available && ( - {t('dataset.unavailable')} + {t('dataset.unavailable')} )}
{ 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 eec5979dd5..65858ce8cf 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 @@ -51,7 +51,7 @@ const SettingsModal: FC = ({ const { modelList: rerankModelList, defaultModel: rerankDefaultModel, - currentModel: isRerankDefaultModelVaild, + currentModel: isRerankDefaultModelValid, } = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.rerank) const { t } = useTranslation() const { notify } = useToastContext() @@ -83,7 +83,7 @@ const SettingsModal: FC = ({ if ( !isReRankModelSelected({ rerankDefaultModel, - isRerankDefaultModelVaild: !!isRerankDefaultModelVaild, + isRerankDefaultModelValid: !!isRerankDefaultModelValid, rerankModelList, retrievalConfig, indexMethod, diff --git a/web/app/components/app/configuration/debug/debug-with-multiple-model/chat-item.tsx b/web/app/components/app/configuration/debug/debug-with-multiple-model/chat-item.tsx index e79cdf4793..d4a1560324 100644 --- a/web/app/components/app/configuration/debug/debug-with-multiple-model/chat-item.tsx +++ b/web/app/components/app/configuration/debug/debug-with-multiple-model/chat-item.tsx @@ -89,7 +89,7 @@ const ChatItem: FC = ({ `apps/${appId}/chat-messages`, data, { - onGetConvesationMessages: (conversationId, getAbortController) => fetchConversationMessages(appId, conversationId, getAbortController), + onGetConversationMessages: (conversationId, getAbortController) => fetchConversationMessages(appId, conversationId, getAbortController), onGetSuggestedQuestions: (responseItemId, getAbortController) => fetchSuggestedQuestions(appId, responseItemId, getAbortController), }, ) diff --git a/web/app/components/app/configuration/debug/debug-with-single-model/index.tsx b/web/app/components/app/configuration/debug/debug-with-single-model/index.tsx index ea15c1a4ce..0f09a23242 100644 --- a/web/app/components/app/configuration/debug/debug-with-single-model/index.tsx +++ b/web/app/components/app/configuration/debug/debug-with-single-model/index.tsx @@ -94,7 +94,7 @@ const DebugWithSingleModel = forwardRef fetchConversationMessages(appId, conversationId, getAbortController), + onGetConversationMessages: (conversationId, getAbortController) => fetchConversationMessages(appId, conversationId, getAbortController), onGetSuggestedQuestions: (responseItemId, getAbortController) => fetchSuggestedQuestions(appId, responseItemId, getAbortController), }, ) diff --git a/web/app/components/app/configuration/features/chat-group/opening-statement/index.tsx b/web/app/components/app/configuration/features/chat-group/opening-statement/index.tsx index d007225bda..e652579cfc 100644 --- a/web/app/components/app/configuration/features/chat-group/opening-statement/index.tsx +++ b/web/app/components/app/configuration/features/chat-group/opening-statement/index.tsx @@ -227,7 +227,7 @@ const OpeningStatement: FC = ({ onClick={() => { setTempSuggestedQuestions([...tempSuggestedQuestions, '']) }} className='mt-1 flex items-center h-9 px-3 gap-2 rounded-lg cursor-pointer text-gray-400 bg-gray-100 hover:bg-gray-200'> -
{t('appDebug.variableConig.addOption')}
+
{t('appDebug.variableConfig.addOption')}
)}
@@ -287,7 +287,7 @@ const OpeningStatement: FC = ({ {isShowConfirmAddVar && ( diff --git a/web/app/components/app/configuration/features/experience-enchance-group/index.tsx b/web/app/components/app/configuration/features/experience-enhance-group/index.tsx similarity index 88% rename from web/app/components/app/configuration/features/experience-enchance-group/index.tsx rename to web/app/components/app/configuration/features/experience-enhance-group/index.tsx index 6902a17468..4a629a6b0e 100644 --- a/web/app/components/app/configuration/features/experience-enchance-group/index.tsx +++ b/web/app/components/app/configuration/features/experience-enhance-group/index.tsx @@ -16,7 +16,7 @@ type ExperienceGroupProps = { isShowMoreLike: boolean } -const ExperienceEnchanceGroup: FC = ({ +const ExperienceEnhanceGroup: FC = ({ isShowTextToSpeech, isShowMoreLike, }) => { @@ -40,4 +40,4 @@ const ExperienceEnchanceGroup: FC = ({
) } -export default React.memo(ExperienceEnchanceGroup) +export default React.memo(ExperienceEnhanceGroup) diff --git a/web/app/components/app/configuration/features/experience-enchance-group/more-like-this/index.tsx b/web/app/components/app/configuration/features/experience-enhance-group/more-like-this/index.tsx similarity index 100% rename from web/app/components/app/configuration/features/experience-enchance-group/more-like-this/index.tsx rename to web/app/components/app/configuration/features/experience-enhance-group/more-like-this/index.tsx diff --git a/web/app/components/app/configuration/index.tsx b/web/app/components/app/configuration/index.tsx index 432accb0d2..357dc84b7a 100644 --- a/web/app/components/app/configuration/index.tsx +++ b/web/app/components/app/configuration/index.tsx @@ -14,7 +14,7 @@ import Loading from '../../base/loading' import AppPublisher from '../app-publisher' import AgentSettingButton from './config/agent-setting-button' import useAdvancedPromptConfig from './hooks/use-advanced-prompt-config' -import EditHistoryModal from './config-prompt/conversation-histroy/edit-modal' +import EditHistoryModal from './config-prompt/conversation-history/edit-modal' import { useDebugWithSingleOrMultipleModel, useFormattingChangedDispatcher, diff --git a/web/app/components/app/configuration/toolbox/moderation/moderation-setting-modal.tsx b/web/app/components/app/configuration/toolbox/moderation/moderation-setting-modal.tsx index 64b2dd222a..589eb42ab3 100644 --- a/web/app/components/app/configuration/toolbox/moderation/moderation-setting-modal.tsx +++ b/web/app/components/app/configuration/toolbox/moderation/moderation-setting-modal.tsx @@ -64,7 +64,7 @@ const ModerationSettingModal: FC = ({ const systemOpenaiProviderQuota = systemOpenaiProviderEnabled ? openaiProvider?.system_configuration.quota_configurations.find(item => item.quota_type === openaiProvider.system_configuration.current_quota_type) : undefined const systemOpenaiProviderCanUse = systemOpenaiProviderQuota?.is_valid const customOpenaiProvidersCanUse = openaiProvider?.custom_configuration.status === CustomConfigurationStatusEnum.active - const openaiProviderConfiged = customOpenaiProvidersCanUse || systemOpenaiProviderCanUse + const isOpenAIProviderConfigured = customOpenaiProvidersCanUse || systemOpenaiProviderCanUse const providers: Provider[] = [ { key: 'openai_moderation', @@ -190,7 +190,7 @@ const ModerationSettingModal: FC = ({ } const handleSave = () => { - if (localeData.type === 'openai_moderation' && !openaiProviderConfiged) + if (localeData.type === 'openai_moderation' && !isOpenAIProviderConfigured) return if (!localeData.config?.inputs_config?.enabled && !localeData.config?.outputs_config?.enabled) { @@ -254,7 +254,7 @@ const ModerationSettingModal: FC = ({ className={` flex items-center px-3 py-2 rounded-lg text-sm text-gray-900 cursor-pointer ${localeData.type === provider.key ? 'bg-white border-[1.5px] border-primary-400 shadow-sm' : 'border border-gray-100 bg-gray-25'} - ${localeData.type === 'openai_moderation' && provider.key === 'openai_moderation' && !openaiProviderConfiged && 'opacity-50'} + ${localeData.type === 'openai_moderation' && provider.key === 'openai_moderation' && !isOpenAIProviderConfigured && 'opacity-50'} `} onClick={() => handleDataTypeChange(provider.key)} > @@ -267,7 +267,7 @@ const ModerationSettingModal: FC = ({ } { - !isLoading && !openaiProviderConfiged && localeData.type === 'openai_moderation' && ( + !isLoading && !isOpenAIProviderConfigured && localeData.type === 'openai_moderation' && (
@@ -361,7 +361,7 @@ const ModerationSettingModal: FC = ({ diff --git a/web/app/components/app/configuration/tools/external-data-tool-modal.tsx b/web/app/components/app/configuration/tools/external-data-tool-modal.tsx index 3187990609..2785f435e4 100644 --- a/web/app/components/app/configuration/tools/external-data-tool-modal.tsx +++ b/web/app/components/app/configuration/tools/external-data-tool-modal.tsx @@ -172,12 +172,12 @@ const ExternalDataToolModal: FC = ({ } } - const formatedData = formatData(localeData) + const formattedData = formatData(localeData) - if (onValidateBeforeSave && !onValidateBeforeSave(formatedData)) + if (onValidateBeforeSave && !onValidateBeforeSave(formattedData)) return - onSave(formatData(formatedData)) + onSave(formatData(formattedData)) } const action = data.type ? t('common.operation.edit') : t('common.operation.add') @@ -189,7 +189,7 @@ const ExternalDataToolModal: FC = ({ className='!p-8 !pb-6 !max-w-none !w-[640px]' >
- {`${action} ${t('appDebug.variableConig.apiBasedVar')}`} + {`${action} ${t('appDebug.variableConfig.apiBasedVar')}`}
diff --git a/web/app/components/app/create-app-modal/index.tsx b/web/app/components/app/create-app-modal/index.tsx index 5fb0d7ef3f..d503e71918 100644 --- a/web/app/components/app/create-app-modal/index.tsx +++ b/web/app/components/app/create-app-modal/index.tsx @@ -21,7 +21,7 @@ import Modal from '@/app/components/base/modal' import Button from '@/app/components/base/button' import AppIcon from '@/app/components/base/app-icon' import AppsFull from '@/app/components/billing/apps-full-in-dialog' -import { AiText, ChatBot, CuteRobote } from '@/app/components/base/icons/src/vender/solid/communication' +import { AiText, ChatBot, CuteRobot } from '@/app/components/base/icons/src/vender/solid/communication' import { Route } from '@/app/components/base/icons/src/vender/solid/mapsAndTravel' import Tooltip from '@/app/components/base/tooltip' import { NEED_REFRESH_APP_LIST_KEY } from '@/config' @@ -158,7 +158,7 @@ const CreateAppModal = ({ show, onSuccess, onClose }: CreateAppDialogProps) => { setShowChatBotType(false) }} > - +
{t('app.types.agent')}
diff --git a/web/app/components/app/log/index.tsx b/web/app/components/app/log/index.tsx index dd6ebd08f0..77fcb6fcf9 100644 --- a/web/app/components/app/log/index.tsx +++ b/web/app/components/app/log/index.tsx @@ -119,8 +119,8 @@ const Logs: FC = ({ appDetail }) => { middlePagesSiblingCount={1} setCurrentPage={setCurrPage} totalPages={Math.ceil(total / APP_PAGE_LIMIT)} - truncableClassName="w-8 px-0.5 text-center" - truncableText="..." + truncatableClassName="w-8 px-0.5 text-center" + truncatableText="..." > => { + const handleFeedback = async (mid: string, { rating }: FeedbackType): Promise => { try { await updateLogMessageFeedbacks({ url: `/apps/${appId}/feedbacks`, body: { message_id: mid, rating } }) conversationDetailMutate() @@ -586,7 +586,7 @@ const ChatConversationDetailComp: FC<{ appId?: string; conversationId?: string } const { notify } = useContext(ToastContext) const { t } = useTranslation() - const handleFeedback = async (mid: string, { rating }: Feedbacktype): Promise => { + const handleFeedback = async (mid: string, { rating }: FeedbackType): Promise => { try { await updateLogMessageFeedbacks({ url: `/apps/${appId}/feedbacks`, body: { message_id: mid, rating } }) notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') }) diff --git a/web/app/components/app/overview/settings/index.tsx b/web/app/components/app/overview/settings/index.tsx index 02eff06c0a..a501d06ce4 100644 --- a/web/app/components/app/overview/settings/index.tsx +++ b/web/app/components/app/overview/settings/index.tsx @@ -43,6 +43,7 @@ export type ConfigParams = { icon: string icon_background?: string show_workflow_steps: boolean + use_icon_as_answer_icon: boolean enable_sso?: boolean } @@ -72,6 +73,7 @@ const SettingsModal: FC = ({ custom_disclaimer, default_language, show_workflow_steps, + use_icon_as_answer_icon, } = appInfo.site const [inputInfo, setInputInfo] = useState({ title, @@ -82,6 +84,7 @@ const SettingsModal: FC = ({ privacyPolicy: privacy_policy, customDisclaimer: custom_disclaimer, show_workflow_steps, + use_icon_as_answer_icon, enable_sso: appInfo.enable_sso, }) const [language, setLanguage] = useState(default_language) @@ -94,6 +97,7 @@ const SettingsModal: FC = ({ ? { type: 'image', url: icon_url!, fileId: icon } : { type: 'emoji', icon, background: icon_background! }, ) + const isChatBot = appInfo.mode === 'chat' || appInfo.mode === 'advanced-chat' || appInfo.mode === 'agent-chat' useEffect(() => { setInputInfo({ @@ -105,6 +109,7 @@ const SettingsModal: FC = ({ privacyPolicy: privacy_policy, customDisclaimer: custom_disclaimer, show_workflow_steps, + use_icon_as_answer_icon, enable_sso: appInfo.enable_sso, }) setLanguage(default_language) @@ -157,6 +162,7 @@ const SettingsModal: FC = ({ icon: appIcon.type === 'emoji' ? appIcon.icon : appIcon.fileId, icon_background: appIcon.type === 'emoji' ? appIcon.background : undefined, show_workflow_steps: inputInfo.show_workflow_steps, + use_icon_as_answer_icon: inputInfo.use_icon_as_answer_icon, enable_sso: inputInfo.enable_sso, } await onSave?.(params) @@ -209,6 +215,18 @@ const SettingsModal: FC = ({ onChange={onChange('desc')} placeholder={t(`${prefixSettings}.webDescPlaceholder`) as string} /> + {isChatBot && ( +
+
+
{t('app.answerIcon.title')}
+ setInputInfo({ ...inputInfo, use_icon_as_answer_icon: v })} + /> +
+

{t('app.answerIcon.description')}

+
+ )}
{t(`${prefixSettings}.language`)}
item.supported)} diff --git a/web/app/components/app/text-generate/item/index.tsx b/web/app/components/app/text-generate/item/index.tsx index 9794967d9d..e3bd8eadc5 100644 --- a/web/app/components/app/text-generate/item/index.tsx +++ b/web/app/components/app/text-generate/item/index.tsx @@ -16,13 +16,13 @@ import { Markdown } from '@/app/components/base/markdown' import Loading from '@/app/components/base/loading' import Toast from '@/app/components/base/toast' import AudioBtn from '@/app/components/base/audio-btn' -import type { Feedbacktype } from '@/app/components/base/chat/chat/type' +import type { FeedbackType } from '@/app/components/base/chat/chat/type' import { fetchMoreLikeThis, updateFeedback } from '@/service/share' import { File02 } from '@/app/components/base/icons/src/vender/line/files' import { Bookmark } from '@/app/components/base/icons/src/vender/line/general' import { Stars02 } from '@/app/components/base/icons/src/vender/line/weather' import { RefreshCcw01 } from '@/app/components/base/icons/src/vender/line/arrows' -import { fetchTextGenerationMessge } from '@/service/debug' +import { fetchTextGenerationMessage } from '@/service/debug' import AnnotationCtrlBtn from '@/app/components/app/configuration/toolbox/annotation/annotation-ctrl-btn' import EditReplyModal from '@/app/components/app/annotation/edit-annotation-modal' import { useStore as useAppStore } from '@/app/components/app/store' @@ -47,8 +47,8 @@ export type IGenerationItemProps = { isInWebApp?: boolean moreLikeThis?: boolean depth?: number - feedback?: Feedbacktype - onFeedback?: (feedback: Feedbacktype) => void + feedback?: FeedbackType + onFeedback?: (feedback: FeedbackType) => void onSave?: (messageId: string) => void isMobile?: boolean isInstalledApp: boolean @@ -125,7 +125,7 @@ const GenerationItem: FC = ({ const [completionRes, setCompletionRes] = useState('') const [childMessageId, setChildMessageId] = useState(null) const hasChild = !!childMessageId - const [childFeedback, setChildFeedback] = useState({ + const [childFeedback, setChildFeedback] = useState({ rating: null, }) const { @@ -135,7 +135,7 @@ const GenerationItem: FC = ({ const setCurrentLogItem = useAppStore(s => s.setCurrentLogItem) const setShowPromptLogModal = useAppStore(s => s.setShowPromptLogModal) - const handleFeedback = async (childFeedback: Feedbacktype) => { + const handleFeedback = async (childFeedback: FeedbackType) => { await updateFeedback({ url: `/messages/${childMessageId}/feedbacks`, body: { rating: childFeedback.rating } }, isInstalledApp, installedAppId) setChildFeedback(childFeedback) } @@ -205,7 +205,7 @@ const GenerationItem: FC = ({ }, [isLoading]) const handleOpenLogModal = async () => { - const data = await fetchTextGenerationMessge({ + const data = await fetchTextGenerationMessage({ appId: params.appId as string, messageId: messageId!, }) diff --git a/web/app/components/app/type-selector/index.tsx b/web/app/components/app/type-selector/index.tsx index 2bd4f8d082..a09e189f50 100644 --- a/web/app/components/app/type-selector/index.tsx +++ b/web/app/components/app/type-selector/index.tsx @@ -9,7 +9,7 @@ import { } from '@/app/components/base/portal-to-follow-elem' import { Check, DotsGrid } from '@/app/components/base/icons/src/vender/line/general' import { XCircle } from '@/app/components/base/icons/src/vender/solid/general' -import { ChatBot, CuteRobote } from '@/app/components/base/icons/src/vender/solid/communication' +import { ChatBot, CuteRobot } from '@/app/components/base/icons/src/vender/solid/communication' import { Route } from '@/app/components/base/icons/src/vender/solid/mapsAndTravel' export type AppSelectorProps = { value: string @@ -65,7 +65,7 @@ const AppTypeSelector = ({ value, onChange }: AppSelectorProps) => { {value === 'agent' && ( <>
- +
{t('app.typeSelector.agent')}
{ @@ -106,7 +106,7 @@ const AppTypeSelector = ({ value, onChange }: AppSelectorProps) => { onChange('agent') setOpen(false) }}> - +
{t('app.typeSelector.agent')}
{value === 'agent' && }
diff --git a/web/app/components/app/workflow-log/index.tsx b/web/app/components/app/workflow-log/index.tsx index 303c2069b2..b7e20f0a0b 100644 --- a/web/app/components/app/workflow-log/index.tsx +++ b/web/app/components/app/workflow-log/index.tsx @@ -93,8 +93,8 @@ const Logs: FC = ({ appDetail }) => { middlePagesSiblingCount={1} setCurrentPage={setCurrPage} totalPages={Math.ceil(total / APP_PAGE_LIMIT)} - truncableClassName="w-8 px-0.5 text-center" - truncableText="..." + truncatableClassName="w-8 px-0.5 text-center" + truncatableText="..." > = ({ onClick={() => switchTab('TRACING')} >{t('runLog.tracing')}
- {/* panel detal */} + {/* panel detail */}
{loading && (
diff --git a/web/app/components/base/answer-icon/index.tsx b/web/app/components/base/answer-icon/index.tsx new file mode 100644 index 0000000000..8c6363e05c --- /dev/null +++ b/web/app/components/base/answer-icon/index.tsx @@ -0,0 +1,47 @@ +'use client' + +import type { FC } from 'react' +import { init } from 'emoji-mart' +import data from '@emoji-mart/data' +import classNames from '@/utils/classnames' +import type { AppIconType } from '@/types/app' + +init({ data }) + +export type AnswerIconProps = { + iconType?: AppIconType | null + icon?: string | null + background?: string | null + imageUrl?: string | null +} + +const AnswerIcon: FC = ({ + iconType, + icon, + background, + imageUrl, +}) => { + const wrapperClassName = classNames( + 'flex', + 'items-center', + 'justify-center', + 'w-full', + 'h-full', + 'rounded-full', + 'border-[0.5px]', + 'border-black/5', + 'text-xl', + ) + const isValidImageIcon = iconType === 'image' && imageUrl + return
+ {isValidImageIcon + ? answer icon + : (icon && icon !== '') ? : + } +
+} + +export default AnswerIcon diff --git a/web/app/components/base/app-unavailable.tsx b/web/app/components/base/app-unavailable.tsx index c5ea7be0b9..b8b42108a9 100644 --- a/web/app/components/base/app-unavailable.tsx +++ b/web/app/components/base/app-unavailable.tsx @@ -22,7 +22,7 @@ const AppUnavailable: FC = ({ style={{ borderRight: '1px solid rgba(0,0,0,.3)', }}>{code} -
{unknownReason || (isUnknownReason ? t('share.common.appUnkonwError') : t('share.common.appUnavailable'))}
+
{unknownReason || (isUnknownReason ? t('share.common.appUnknownError') : t('share.common.appUnavailable'))}
) } diff --git a/web/app/components/base/audio-gallery/AudioPlayer.module.css b/web/app/components/base/audio-gallery/AudioPlayer.module.css new file mode 100644 index 0000000000..6c070e107c --- /dev/null +++ b/web/app/components/base/audio-gallery/AudioPlayer.module.css @@ -0,0 +1,119 @@ +.audioPlayer { + display: flex; + flex-direction: row; + align-items: center; + background-color: #ffffff; + border-radius: 10px; + padding: 8px; + min-width: 240px; + max-width: 420px; + max-height: 40px; + backdrop-filter: blur(5px); + border: 1px solid rgba(16, 24, 40, 0.08); + box-shadow: 0 1px 2px rgba(9, 9, 11, 0.05); + gap: 8px; +} + +.playButton { + display: inline-flex; + width: 16px; + height: 16px; + border-radius: 50%; + background-color: #296DFF; + color: white; + border: none; + cursor: pointer; + align-items: center; + justify-content: center; + transition: background-color 0.1s; + flex-shrink: 0; +} + +.playButton:hover { + background-color: #3367d6; +} + +.playButton:disabled { + background-color: #bdbdbf; +} + +.audioControls { + flex-grow: 1; + +} + +.progressBarContainer { + height: 32px; + display: flex; + align-items: center; + justify-content: center; +} + +.waveform { + position: relative; + display: flex; + cursor: pointer; + height: 24px; + width: 100%; + flex-grow: 1; + align-items: center; + justify-content: center; +} + +.progressBar { + position: absolute; + top: 0; + left: 0; + opacity: 0.5; + border-radius: 2px; + flex: none; + order: 55; + flex-grow: 0; + height: 100%; + background-color: rgba(66, 133, 244, 0.3); + pointer-events: none; +} + +.timeDisplay { + /* position: absolute; */ + color: #296DFF; + border-radius: 2px; + order: 0; + height: 100%; + width: 50px; + display: inline-flex; + align-items: center; + justify-content: center; +} + +/* .currentTime { + position: absolute; + bottom: calc(100% + 5px); + transform: translateX(-50%); + background-color: rgba(255,255,255,.8); + padding: 2px 4px; + border-radius:10px; + box-shadow: 0 1px 5px rgba(0, 0, 0, 0.08); +} */ + +.duration { + background-color: rgba(255, 255, 255, 0.8); + padding: 2px 4px; + border-radius: 10px; +} + +.source_unavailable { + border: none; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + position: absolute; + color: #bdbdbf; +} + +.playButton svg path, +.playButton svg rect{ + fill:currentColor; +} diff --git a/web/app/components/base/audio-gallery/AudioPlayer.tsx b/web/app/components/base/audio-gallery/AudioPlayer.tsx new file mode 100644 index 0000000000..c482981e8a --- /dev/null +++ b/web/app/components/base/audio-gallery/AudioPlayer.tsx @@ -0,0 +1,320 @@ +import React, { useCallback, useEffect, useRef, useState } from 'react' +import { t } from 'i18next' +import styles from './AudioPlayer.module.css' +import Toast from '@/app/components/base/toast' + +type AudioPlayerProps = { + src: string +} + +const AudioPlayer: React.FC = ({ src }) => { + const [isPlaying, setIsPlaying] = useState(false) + const [currentTime, setCurrentTime] = useState(0) + const [duration, setDuration] = useState(0) + const [waveformData, setWaveformData] = useState([]) + const [bufferedTime, setBufferedTime] = useState(0) + const audioRef = useRef(null) + const canvasRef = useRef(null) + const [hasStartedPlaying, setHasStartedPlaying] = useState(false) + const [hoverTime, setHoverTime] = useState(0) + const [isAudioAvailable, setIsAudioAvailable] = useState(true) + + useEffect(() => { + const audio = audioRef.current + if (!audio) + return + + const handleError = () => { + setIsAudioAvailable(false) + } + + const setAudioData = () => { + setDuration(audio.duration) + } + + const setAudioTime = () => { + setCurrentTime(audio.currentTime) + } + + const handleProgress = () => { + if (audio.buffered.length > 0) + setBufferedTime(audio.buffered.end(audio.buffered.length - 1)) + } + + const handleEnded = () => { + setIsPlaying(false) + } + + audio.addEventListener('loadedmetadata', setAudioData) + audio.addEventListener('timeupdate', setAudioTime) + audio.addEventListener('progress', handleProgress) + audio.addEventListener('ended', handleEnded) + audio.addEventListener('error', handleError) + + // Preload audio metadata + audio.load() + + // Delayed generation of waveform data + // eslint-disable-next-line @typescript-eslint/no-use-before-define + const timer = setTimeout(() => generateWaveformData(src), 1000) + + return () => { + audio.removeEventListener('loadedmetadata', setAudioData) + audio.removeEventListener('timeupdate', setAudioTime) + audio.removeEventListener('progress', handleProgress) + audio.removeEventListener('ended', handleEnded) + audio.removeEventListener('error', handleError) + clearTimeout(timer) + } + }, [src]) + + const generateWaveformData = async (audioSrc: string) => { + if (!window.AudioContext && !(window as any).webkitAudioContext) { + setIsAudioAvailable(false) + Toast.notify({ + type: 'error', + message: 'Web Audio API is not supported in this browser', + }) + return null + } + + const url = new URL(src) + const isHttp = url.protocol === 'http:' || url.protocol === 'https:' + if (!isHttp) { + setIsAudioAvailable(false) + return null + } + + const audioContext = new (window.AudioContext || (window as any).webkitAudioContext)() + const samples = 70 + + try { + const response = await fetch(audioSrc, { mode: 'cors' }) + if (!response || !response.ok) { + setIsAudioAvailable(false) + return null + } + + const arrayBuffer = await response.arrayBuffer() + const audioBuffer = await audioContext.decodeAudioData(arrayBuffer) + const channelData = audioBuffer.getChannelData(0) + const blockSize = Math.floor(channelData.length / samples) + const waveformData: number[] = [] + + for (let i = 0; i < samples; i++) { + let sum = 0 + for (let j = 0; j < blockSize; j++) + sum += Math.abs(channelData[i * blockSize + j]) + + // Apply nonlinear scaling to enhance small amplitudes + waveformData.push((sum / blockSize) * 5) + } + + // Normalized waveform data + const maxAmplitude = Math.max(...waveformData) + const normalizedWaveform = waveformData.map(amp => amp / maxAmplitude) + + setWaveformData(normalizedWaveform) + setIsAudioAvailable(true) + } + catch (error) { + const waveform: number[] = [] + let prevValue = Math.random() + + for (let i = 0; i < samples; i++) { + const targetValue = Math.random() + const interpolatedValue = prevValue + (targetValue - prevValue) * 0.3 + waveform.push(interpolatedValue) + prevValue = interpolatedValue + } + + const maxAmplitude = Math.max(...waveform) + const randomWaveform = waveform.map(amp => amp / maxAmplitude) + + setWaveformData(randomWaveform) + setIsAudioAvailable(true) + } + finally { + await audioContext.close() + } + } + + const togglePlay = useCallback(() => { + const audio = audioRef.current + if (audio && isAudioAvailable) { + if (isPlaying) { + setHasStartedPlaying(false) + audio.pause() + } + else { + setHasStartedPlaying(true) + audio.play().catch(error => console.error('Error playing audio:', error)) + } + + setIsPlaying(!isPlaying) + } + else { + Toast.notify({ + type: 'error', + message: 'Audio element not found', + }) + setIsAudioAvailable(false) + } + }, [isAudioAvailable, isPlaying]) + + const handleCanvasInteraction = useCallback((e: React.MouseEvent | React.TouchEvent) => { + e.preventDefault() + + const getClientX = (event: React.MouseEvent | React.TouchEvent): number => { + if ('touches' in event) + return event.touches[0].clientX + return event.clientX + } + + const updateProgress = (clientX: number) => { + const canvas = canvasRef.current + const audio = audioRef.current + if (!canvas || !audio) + return + + const rect = canvas.getBoundingClientRect() + const percent = Math.min(Math.max(0, clientX - rect.left), rect.width) / rect.width + const newTime = percent * duration + + // Removes the buffer check, allowing drag to any location + audio.currentTime = newTime + setCurrentTime(newTime) + + if (!isPlaying) { + setIsPlaying(true) + audio.play().catch((error) => { + Toast.notify({ + type: 'error', + message: `Error playing audio: ${error}`, + }) + setIsPlaying(false) + }) + } + } + + updateProgress(getClientX(e)) + }, [duration, isPlaying]) + + const formatTime = (time: number) => { + const minutes = Math.floor(time / 60) + const seconds = Math.floor(time % 60) + return `${minutes}:${seconds.toString().padStart(2, '0')}` + } + + const drawWaveform = useCallback(() => { + const canvas = canvasRef.current + if (!canvas) + return + + const ctx = canvas.getContext('2d') + if (!ctx) + return + + const width = canvas.width + const height = canvas.height + const data = waveformData + + ctx.clearRect(0, 0, width, height) + + const barWidth = width / data.length + const playedWidth = (currentTime / duration) * width + const cornerRadius = 2 + + // Draw waveform bars + data.forEach((value, index) => { + let color + + if (index * barWidth <= playedWidth) + color = '#296DFF' + else if ((index * barWidth / width) * duration <= hoverTime) + color = 'rgba(21,90,239,.40)' + else + color = 'rgba(21,90,239,.20)' + + const barHeight = value * height + const rectX = index * barWidth + const rectY = (height - barHeight) / 2 + const rectWidth = barWidth * 0.5 + const rectHeight = barHeight + + ctx.lineWidth = 1 + ctx.fillStyle = color + if (ctx.roundRect) { + ctx.beginPath() + ctx.roundRect(rectX, rectY, rectWidth, rectHeight, cornerRadius) + ctx.fill() + } + else { + ctx.fillRect(rectX, rectY, rectWidth, rectHeight) + } + }) + }, [currentTime, duration, hoverTime, waveformData]) + + useEffect(() => { + drawWaveform() + }, [drawWaveform, bufferedTime, hasStartedPlaying]) + + const handleMouseMove = useCallback((e: React.MouseEvent) => { + const canvas = canvasRef.current + const audio = audioRef.current + if (!canvas || !audio) + return + + const rect = canvas.getBoundingClientRect() + const percent = Math.min(Math.max(0, e.clientX - rect.left), rect.width) / rect.width + const time = percent * duration + + // Check if the hovered position is within a buffered range before updating hoverTime + for (let i = 0; i < audio.buffered.length; i++) { + if (time >= audio.buffered.start(i) && time <= audio.buffered.end(i)) { + setHoverTime(time) + break + } + } + }, [duration]) + + return ( +
+
+ ) +} + +export default AudioPlayer diff --git a/web/app/components/base/audio-gallery/index.tsx b/web/app/components/base/audio-gallery/index.tsx new file mode 100644 index 0000000000..6e11d43164 --- /dev/null +++ b/web/app/components/base/audio-gallery/index.tsx @@ -0,0 +1,12 @@ +import React from 'react' +import AudioPlayer from './AudioPlayer' + +type Props = { + srcs: string[] +} + +const AudioGallery: React.FC = ({ srcs }) => { + return (<>
{srcs.map((src, index) => ())}) +} + +export default React.memo(AudioGallery) diff --git a/web/app/components/base/block-input/index.tsx b/web/app/components/base/block-input/index.tsx index 79ff646bd1..43c14de4c9 100644 --- a/web/app/components/base/block-input/index.tsx +++ b/web/app/components/base/block-input/index.tsx @@ -53,7 +53,7 @@ const BlockInput: FC = ({ const [isEditing, setIsEditing] = useState(false) useEffect(() => { if (isEditing && contentEditableRef.current) { - // TODO: Focus at the click positon + // TODO: Focus at the click position if (currentValue) contentEditableRef.current.setSelectionRange(currentValue.length, currentValue.length) @@ -119,7 +119,7 @@ const BlockInput: FC = ({ onBlur={() => { blur() setIsEditing(false) - // click confirm also make blur. Then outter value is change. So below code has problem. + // click confirm also make blur. Then outer value is change. So below code has problem. // setTimeout(() => { // handleCancel() // }, 1000) diff --git a/web/app/components/base/chat/chat-with-history/chat-wrapper.tsx b/web/app/components/base/chat/chat-with-history/chat-wrapper.tsx index 8eda66c52a..5a7bf1f17e 100644 --- a/web/app/components/base/chat/chat-with-history/chat-wrapper.tsx +++ b/web/app/components/base/chat/chat-with-history/chat-wrapper.tsx @@ -13,6 +13,7 @@ import { getUrl, stopChatMessageResponding, } from '@/service/share' +import AnswerIcon from '@/app/components/base/answer-icon' const ChatWrapper = () => { const { @@ -128,21 +129,31 @@ const ChatWrapper = () => { isMobile, ]) + const answerIcon = (appData?.site && appData.site.use_icon_as_answer_icon) + ? + : null + return ( diff --git a/web/app/components/base/chat/chat-with-history/config-panel/index.tsx b/web/app/components/base/chat/chat-with-history/config-panel/index.tsx index 05f253290f..c864a3925d 100644 --- a/web/app/components/base/chat/chat-with-history/config-panel/index.tsx +++ b/web/app/components/base/chat/chat-with-history/config-panel/index.tsx @@ -152,7 +152,7 @@ const ConfigPanel = () => { : (
- {t('share.chat.powerBy')} + {t('share.chat.poweredBy')} { customConfig?.replace_webapp_logo ? logo diff --git a/web/app/components/base/chat/chat-with-history/hooks.tsx b/web/app/components/base/chat/chat-with-history/hooks.tsx index 624cc53a18..1e05cc39ef 100644 --- a/web/app/components/base/chat/chat-with-history/hooks.tsx +++ b/web/app/components/base/chat/chat-with-history/hooks.tsx @@ -65,6 +65,7 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => { prompt_public: false, copyright: '', show_workflow_steps: true, + use_icon_as_answer_icon: app.use_icon_as_answer_icon, }, plan: 'basic', } as AppData @@ -216,12 +217,12 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => { }, [newConversation]) const currentConversationItem = useMemo(() => { - let coversationItem = conversationList.find(item => item.id === currentConversationId) + let conversationItem = conversationList.find(item => item.id === currentConversationId) - if (!coversationItem && pinnedConversationList.length) - coversationItem = pinnedConversationList.find(item => item.id === currentConversationId) + if (!conversationItem && pinnedConversationList.length) + conversationItem = pinnedConversationList.find(item => item.id === currentConversationId) - return coversationItem + return conversationItem }, [conversationList, currentConversationId, pinnedConversationList]) const { notify } = useToastContext() diff --git a/web/app/components/base/chat/chat/answer/index.tsx b/web/app/components/base/chat/chat/answer/index.tsx index 78a0842595..270cd553c2 100644 --- a/web/app/components/base/chat/chat/answer/index.tsx +++ b/web/app/components/base/chat/chat/answer/index.tsx @@ -22,6 +22,7 @@ import Citation from '@/app/components/base/chat/chat/citation' import { EditTitle } from '@/app/components/app/annotation/edit-annotation-modal/edit-item' import type { Emoji } from '@/app/components/tools/types' import type { AppData } from '@/models/share' +import AnswerIcon from '@/app/components/base/answer-icon' type AnswerProps = { item: ChatItem @@ -89,11 +90,7 @@ const Answer: FC = ({
{ - answerIcon || ( -
- 🤖 -
- ) + answerIcon || } { responding && ( diff --git a/web/app/components/base/chat/chat/citation/index.tsx b/web/app/components/base/chat/chat/citation/index.tsx index 4bed9638d3..2ca7b80ae7 100644 --- a/web/app/components/base/chat/chat/citation/index.tsx +++ b/web/app/components/base/chat/chat/citation/index.tsx @@ -24,7 +24,7 @@ const Citation: FC = ({ }) => { const { t } = useTranslation() const elesRef = useRef([]) - const [limitNumberInOneLine, setlimitNumberInOneLine] = useState(0) + const [limitNumberInOneLine, setLimitNumberInOneLine] = useState(0) const [showMore, setShowMore] = useState(false) const resources = useMemo(() => data.reduce((prev: Resources[], next) => { const documentId = next.document_id @@ -57,14 +57,14 @@ const Citation: FC = ({ totalWidth -= elesRef.current[i].clientWidth if (totalWidth + 34 > containerWidth!) - setlimitNumberInOneLine(i - 1) + setLimitNumberInOneLine(i - 1) else - setlimitNumberInOneLine(i) + setLimitNumberInOneLine(i) break } else { - setlimitNumberInOneLine(i + 1) + setLimitNumberInOneLine(i + 1) } } } diff --git a/web/app/components/base/chat/chat/citation/popup.tsx b/web/app/components/base/chat/chat/citation/popup.tsx index d039d98e6b..b61bf623fe 100644 --- a/web/app/components/base/chat/chat/citation/popup.tsx +++ b/web/app/components/base/chat/chat/citation/popup.tsx @@ -53,72 +53,74 @@ const Popup: FC = ({
-
+
{data.documentName}
-
- { - data.sources.map((source, index) => ( - -
-
-
- -
- {source.segment_position || index + 1} +
+
+ { + data.sources.map((source, index) => ( + +
+
+
+ +
+ {source.segment_position || index + 1} +
+ { + showHitInfo && ( + + {t('common.chat.citation.linkToDataset')} + + + ) + }
+
{source.content}
{ showHitInfo && ( - - {t('common.chat.citation.linkToDataset')} - - +
+ } + /> + } + /> + } + /> + { + source.score && ( + + ) + } +
) }
-
{source.content}
{ - showHitInfo && ( -
- } - /> - } - /> - } - /> - { - source.score && ( - - ) - } -
+ index !== data.sources.length - 1 && ( +
) } -
- { - index !== data.sources.length - 1 && ( -
- ) - } - - )) - } + + )) + } +
diff --git a/web/app/components/base/chat/chat/hooks.ts b/web/app/components/base/chat/chat/hooks.ts index a70b1c2ed0..e6638b8eed 100644 --- a/web/app/components/base/chat/chat/hooks.ts +++ b/web/app/components/base/chat/chat/hooks.ts @@ -26,7 +26,7 @@ import { AudioPlayerManager } from '@/app/components/base/audio-btn/audio.player type GetAbortController = (abortController: AbortController) => void type SendCallback = { - onGetConvesationMessages?: (conversationId: string, getAbortController: GetAbortController) => Promise + onGetConversationMessages?: (conversationId: string, getAbortController: GetAbortController) => Promise onGetSuggestedQuestions?: (responseItemId: string, getAbortController: GetAbortController) => Promise onConversationComplete?: (conversationId: string) => void isPublicAPI?: boolean @@ -198,7 +198,7 @@ export const useChat = ( url: string, data: any, { - onGetConvesationMessages, + onGetConversationMessages, onGetSuggestedQuestions, onConversationComplete, isPublicAPI, @@ -324,8 +324,8 @@ export const useChat = ( if (onConversationComplete) onConversationComplete(conversationId.current) - if (conversationId.current && !hasStopResponded.current && onGetConvesationMessages) { - const { data }: any = await onGetConvesationMessages( + if (conversationId.current && !hasStopResponded.current && onGetConversationMessages) { + const { data }: any = await onGetConversationMessages( conversationId.current, newAbortController => conversationMessagesAbortControllerRef.current = newAbortController, ) @@ -372,11 +372,16 @@ export const useChat = ( handleUpdateChatList(newChatList) } if (config?.suggested_questions_after_answer?.enabled && !hasStopResponded.current && onGetSuggestedQuestions) { - const { data }: any = await onGetSuggestedQuestions( - responseItem.id, - newAbortController => suggestedQuestionsAbortControllerRef.current = newAbortController, - ) - setSuggestQuestions(data) + try { + const { data }: any = await onGetSuggestedQuestions( + responseItem.id, + newAbortController => suggestedQuestionsAbortControllerRef.current = newAbortController, + ) + setSuggestQuestions(data) + } + catch (e) { + setSuggestQuestions([]) + } } }, onFile(file) { diff --git a/web/app/components/base/chat/chat/index.tsx b/web/app/components/base/chat/chat/index.tsx index c5d9af45c2..7540cd873b 100644 --- a/web/app/components/base/chat/chat/index.tsx +++ b/web/app/components/base/chat/chat/index.tsx @@ -106,7 +106,7 @@ const Chat: FC = ({ const chatFooterInnerRef = useRef(null) const userScrolledRef = useRef(false) - const handleScrolltoBottom = useCallback(() => { + const handleScrollToBottom = useCallback(() => { if (chatContainerRef.current && !userScrolledRef.current) chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight }, []) @@ -123,14 +123,14 @@ const Chat: FC = ({ }, []) useEffect(() => { - handleScrolltoBottom() + handleScrollToBottom() handleWindowResize() - }, [handleScrolltoBottom, handleWindowResize]) + }, [handleScrollToBottom, handleWindowResize]) useEffect(() => { if (chatContainerRef.current) { requestAnimationFrame(() => { - handleScrolltoBottom() + handleScrollToBottom() handleWindowResize() }) } @@ -148,7 +148,7 @@ const Chat: FC = ({ const { blockSize } = entry.borderBoxSize[0] chatContainerRef.current!.style.paddingBottom = `${blockSize}px` - handleScrolltoBottom() + handleScrollToBottom() } }) @@ -158,7 +158,7 @@ const Chat: FC = ({ resizeObserver.disconnect() } } - }, [handleScrolltoBottom]) + }, [handleScrollToBottom]) useEffect(() => { const chatContainer = chatContainerRef.current @@ -192,12 +192,12 @@ const Chat: FC = ({
{chatNode}
{ chatList.map((item, index) => { diff --git a/web/app/components/base/chat/chat/loading-anim/index.tsx b/web/app/components/base/chat/chat/loading-anim/index.tsx index 09f8a54789..dd43ef9c14 100644 --- a/web/app/components/base/chat/chat/loading-anim/index.tsx +++ b/web/app/components/base/chat/chat/loading-anim/index.tsx @@ -3,15 +3,15 @@ import type { FC } from 'react' import React from 'react' import s from './style.module.css' -export type ILoaidingAnimProps = { +export type ILoadingAnimProps = { type: 'text' | 'avatar' } -const LoaidingAnim: FC = ({ +const LoadingAnim: FC = ({ type, }) => { return (
) } -export default React.memo(LoaidingAnim) +export default React.memo(LoadingAnim) diff --git a/web/app/components/base/chat/chat/type.ts b/web/app/components/base/chat/chat/type.ts index 16ccff4d4d..b2cb18011c 100644 --- a/web/app/components/base/chat/chat/type.ts +++ b/web/app/components/base/chat/chat/type.ts @@ -8,14 +8,14 @@ export type MessageMore = { latency: number | string } -export type Feedbacktype = { +export type FeedbackType = { rating: MessageRating content?: string | null } export type FeedbackFunc = ( messageId: string, - feedback: Feedbacktype + feedback: FeedbackType ) => Promise export type SubmitAnnotationFunc = ( messageId: string, @@ -71,11 +71,11 @@ export type IChatItem = { /** * The user feedback result of this message */ - feedback?: Feedbacktype + feedback?: FeedbackType /** * The admin feedback result of this message */ - adminFeedback?: Feedbacktype + adminFeedback?: FeedbackType /** * Whether to hide the feedback area */ diff --git a/web/app/components/base/chat/embedded-chatbot/chat-wrapper.tsx b/web/app/components/base/chat/embedded-chatbot/chat-wrapper.tsx index 68646a17db..48ee411058 100644 --- a/web/app/components/base/chat/embedded-chatbot/chat-wrapper.tsx +++ b/web/app/components/base/chat/embedded-chatbot/chat-wrapper.tsx @@ -14,7 +14,8 @@ import { getUrl, stopChatMessageResponding, } from '@/service/share' -import LogoAvatar from '@/app/components/base/logo/logo-embeded-chat-avatar' +import LogoAvatar from '@/app/components/base/logo/logo-embedded-chat-avatar' +import AnswerIcon from '@/app/components/base/answer-icon' const ChatWrapper = () => { const { @@ -98,7 +99,7 @@ const ChatWrapper = () => { return ( <> {!currentConversationId && ( -
+
{ return null }, [currentConversationId, inputsForms, isMobile]) + const answerIcon = isDify() + ? + : (appData?.site && appData.site.use_icon_as_answer_icon) + ? + : null + return ( : null} + answerIcon={answerIcon} hideProcessDetail themeBuilder={themeBuilder} /> diff --git a/web/app/components/base/chat/embedded-chatbot/config-panel/index.tsx b/web/app/components/base/chat/embedded-chatbot/config-panel/index.tsx index df5d12ef14..2cc46cadf8 100644 --- a/web/app/components/base/chat/embedded-chatbot/config-panel/index.tsx +++ b/web/app/components/base/chat/embedded-chatbot/config-panel/index.tsx @@ -160,7 +160,7 @@ const ConfigPanel = () => { : (
- {t('share.chat.powerBy')} + {t('share.chat.poweredBy')} { customConfig?.replace_webapp_logo ? logo diff --git a/web/app/components/base/chat/embedded-chatbot/index.tsx b/web/app/components/base/chat/embedded-chatbot/index.tsx index 480adaae2d..407c0de6d8 100644 --- a/web/app/components/base/chat/embedded-chatbot/index.tsx +++ b/web/app/components/base/chat/embedded-chatbot/index.tsx @@ -17,7 +17,7 @@ import { checkOrSetAccessToken } from '@/app/components/share/utils' import AppUnavailable from '@/app/components/base/app-unavailable' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import Loading from '@/app/components/base/loading' -import LogoHeader from '@/app/components/base/logo/logo-embeded-chat-header' +import LogoHeader from '@/app/components/base/logo/logo-embedded-chat-header' import Header from '@/app/components/base/chat/embedded-chatbot/header' import ConfigPanel from '@/app/components/base/chat/embedded-chatbot/config-panel' import ChatWrapper from '@/app/components/base/chat/embedded-chatbot/chat-wrapper' diff --git a/web/app/components/base/chat/types.ts b/web/app/components/base/chat/types.ts index baffe42843..21277fec57 100644 --- a/web/app/components/base/chat/types.ts +++ b/web/app/components/base/chat/types.ts @@ -22,7 +22,7 @@ export type UserInputForm = { } export type UserInputFormTextInput = { - 'text-inpput': UserInputForm & { + 'text-input': UserInputForm & { max_length: number } } diff --git a/web/app/components/base/features/feature-panel/moderation/moderation-setting-modal.tsx b/web/app/components/base/features/feature-panel/moderation/moderation-setting-modal.tsx index 9acc51b5f3..635506c053 100644 --- a/web/app/components/base/features/feature-panel/moderation/moderation-setting-modal.tsx +++ b/web/app/components/base/features/feature-panel/moderation/moderation-setting-modal.tsx @@ -67,7 +67,7 @@ const ModerationSettingModal: FC = ({ const systemOpenaiProviderQuota = systemOpenaiProviderEnabled ? openaiProvider?.system_configuration.quota_configurations.find(item => item.quota_type === openaiProvider.system_configuration.current_quota_type) : undefined const systemOpenaiProviderCanUse = systemOpenaiProviderQuota?.is_valid const customOpenaiProvidersCanUse = openaiProvider?.custom_configuration.status === CustomConfigurationStatusEnum.active - const openaiProviderConfiged = customOpenaiProvidersCanUse || systemOpenaiProviderCanUse + const isOpenAIProviderConfigured = customOpenaiProvidersCanUse || systemOpenaiProviderCanUse const providers: Provider[] = [ { key: 'openai_moderation', @@ -193,7 +193,7 @@ const ModerationSettingModal: FC = ({ } const handleSave = () => { - if (localeData.type === 'openai_moderation' && !openaiProviderConfiged) + if (localeData.type === 'openai_moderation' && !isOpenAIProviderConfigured) return if (!localeData.config?.inputs_config?.enabled && !localeData.config?.outputs_config?.enabled) { @@ -257,7 +257,7 @@ const ModerationSettingModal: FC = ({ className={` flex items-center px-3 py-2 rounded-lg text-sm text-gray-900 cursor-pointer ${localeData.type === provider.key ? 'bg-white border-[1.5px] border-primary-400 shadow-sm' : 'border border-gray-100 bg-gray-25'} - ${localeData.type === 'openai_moderation' && provider.key === 'openai_moderation' && !openaiProviderConfiged && 'opacity-50'} + ${localeData.type === 'openai_moderation' && provider.key === 'openai_moderation' && !isOpenAIProviderConfigured && 'opacity-50'} `} onClick={() => handleDataTypeChange(provider.key)} > @@ -270,7 +270,7 @@ const ModerationSettingModal: FC = ({ }
{ - !isLoading && !openaiProviderConfiged && localeData.type === 'openai_moderation' && ( + !isLoading && !isOpenAIProviderConfigured && localeData.type === 'openai_moderation' && (
@@ -364,7 +364,7 @@ const ModerationSettingModal: FC = ({ diff --git a/web/app/components/base/features/feature-panel/opening-statement/index.tsx b/web/app/components/base/features/feature-panel/opening-statement/index.tsx index 54bf8bd937..b039165c9e 100644 --- a/web/app/components/base/features/feature-panel/opening-statement/index.tsx +++ b/web/app/components/base/features/feature-panel/opening-statement/index.tsx @@ -248,7 +248,7 @@ const OpeningStatement: FC = ({ onClick={() => { setTempSuggestedQuestions([...tempSuggestedQuestions, '']) }} className='mt-1 flex items-center h-9 px-3 gap-2 rounded-lg cursor-pointer text-gray-400 bg-gray-100 hover:bg-gray-200'> -
{t('appDebug.variableConig.addOption')}
+
{t('appDebug.variableConfig.addOption')}
)}
@@ -308,7 +308,7 @@ const OpeningStatement: FC = ({ {isShowConfirmAddVar && ( diff --git a/web/app/components/base/file-icon/index.tsx b/web/app/components/base/file-icon/index.tsx index 874637ca7a..21e48b3dd4 100644 --- a/web/app/components/base/file-icon/index.tsx +++ b/web/app/components/base/file-icon/index.tsx @@ -8,7 +8,7 @@ import { Md, Pdf, Txt, - Unknow, + Unknown, Xlsx, } from '@/app/components/base/icons/src/public/files' import { Notion } from '@/app/components/base/icons/src/public/common' @@ -47,7 +47,7 @@ const FileIcon: FC = ({ case 'notion': return default: - return + return } } diff --git a/web/app/components/base/icons/assets/vender/solid/communication/cute-robote.svg b/web/app/components/base/icons/assets/vender/solid/communication/cute-robote.svg index 5eb7476085..8fa74ce264 100644 --- a/web/app/components/base/icons/assets/vender/solid/communication/cute-robote.svg +++ b/web/app/components/base/icons/assets/vender/solid/communication/cute-robote.svg @@ -1,5 +1,5 @@ - + diff --git a/web/app/components/base/icons/src/public/files/Unknow.json b/web/app/components/base/icons/src/public/files/Unknown.json similarity index 99% rename from web/app/components/base/icons/src/public/files/Unknow.json rename to web/app/components/base/icons/src/public/files/Unknown.json index 33067fa96f..c39df990d0 100644 --- a/web/app/components/base/icons/src/public/files/Unknow.json +++ b/web/app/components/base/icons/src/public/files/Unknown.json @@ -195,5 +195,5 @@ } ] }, - "name": "Unknow" + "name": "Unknown" } \ No newline at end of file diff --git a/web/app/components/base/icons/src/public/files/Unknow.tsx b/web/app/components/base/icons/src/public/files/Unknown.tsx similarity index 87% rename from web/app/components/base/icons/src/public/files/Unknow.tsx rename to web/app/components/base/icons/src/public/files/Unknown.tsx index ce84d344bf..de909ed65e 100644 --- a/web/app/components/base/icons/src/public/files/Unknow.tsx +++ b/web/app/components/base/icons/src/public/files/Unknown.tsx @@ -2,7 +2,7 @@ // DON NOT EDIT IT MANUALLY import * as React from 'react' -import data from './Unknow.json' +import data from './Unknown.json' import IconBase from '@/app/components/base/icons/IconBase' import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' @@ -11,6 +11,6 @@ const Icon = React.forwardRef, Omit ) -Icon.displayName = 'Unknow' +Icon.displayName = 'Unknown' export default Icon diff --git a/web/app/components/base/icons/src/public/files/index.ts b/web/app/components/base/icons/src/public/files/index.ts index 2814c4ae39..f38c28cbdb 100644 --- a/web/app/components/base/icons/src/public/files/index.ts +++ b/web/app/components/base/icons/src/public/files/index.ts @@ -6,6 +6,6 @@ export { default as Json } from './Json' export { default as Md } from './Md' export { default as Pdf } from './Pdf' export { default as Txt } from './Txt' -export { default as Unknow } from './Unknow' +export { default as Unknown } from './Unknown' export { default as Xlsx } from './Xlsx' export { default as Yaml } from './Yaml' diff --git a/web/app/components/base/icons/src/vender/solid/communication/CuteRobote.json b/web/app/components/base/icons/src/vender/solid/communication/CuteRobot.json similarity index 96% rename from web/app/components/base/icons/src/vender/solid/communication/CuteRobote.json rename to web/app/components/base/icons/src/vender/solid/communication/CuteRobot.json index f8c92c3174..5b36575f56 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/CuteRobote.json +++ b/web/app/components/base/icons/src/vender/solid/communication/CuteRobot.json @@ -15,7 +15,7 @@ "type": "element", "name": "g", "attributes": { - "id": "cute-robote" + "id": "cute-robot" }, "children": [ { @@ -34,5 +34,5 @@ } ] }, - "name": "CuteRobote" + "name": "CuteRobot" } \ No newline at end of file diff --git a/web/app/components/base/icons/src/vender/solid/communication/CuteRobote.tsx b/web/app/components/base/icons/src/vender/solid/communication/CuteRobot.tsx similarity index 86% rename from web/app/components/base/icons/src/vender/solid/communication/CuteRobote.tsx rename to web/app/components/base/icons/src/vender/solid/communication/CuteRobot.tsx index d416fb5b66..49994048b7 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/CuteRobote.tsx +++ b/web/app/components/base/icons/src/vender/solid/communication/CuteRobot.tsx @@ -2,7 +2,7 @@ // DON NOT EDIT IT MANUALLY import * as React from 'react' -import data from './CuteRobote.json' +import data from './CuteRobot.json' import IconBase from '@/app/components/base/icons/IconBase' import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' @@ -11,6 +11,6 @@ const Icon = React.forwardRef, Omit ) -Icon.displayName = 'CuteRobote' +Icon.displayName = 'CuteRobot' export default Icon diff --git a/web/app/components/base/icons/src/vender/solid/communication/index.ts b/web/app/components/base/icons/src/vender/solid/communication/index.ts index 854953c116..673de27463 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/index.ts +++ b/web/app/components/base/icons/src/vender/solid/communication/index.ts @@ -1,6 +1,6 @@ export { default as AiText } from './AiText' export { default as ChatBot } from './ChatBot' -export { default as CuteRobote } from './CuteRobote' +export { default as CuteRobot } from './CuteRobot' export { default as EditList } from './EditList' export { default as MessageDotsCircle } from './MessageDotsCircle' export { default as MessageFast } from './MessageFast' diff --git a/web/app/components/base/image-uploader/audio-preview.tsx b/web/app/components/base/image-uploader/audio-preview.tsx new file mode 100644 index 0000000000..24ede8aa43 --- /dev/null +++ b/web/app/components/base/image-uploader/audio-preview.tsx @@ -0,0 +1,38 @@ +import type { FC } from 'react' +import { createPortal } from 'react-dom' +import { RiCloseLine } from '@remixicon/react' + +type AudioPreviewProps = { + url: string + title: string + onCancel: () => void +} +const AudioPreview: FC = ({ + url, + title, + onCancel, +}) => { + return createPortal( +
e.stopPropagation()}> +
+ +
+
+ +
+
+ , + document.body, + ) +} + +export default AudioPreview diff --git a/web/app/components/base/image-uploader/hooks.ts b/web/app/components/base/image-uploader/hooks.ts index bb929f4a40..41074000a2 100644 --- a/web/app/components/base/image-uploader/hooks.ts +++ b/web/app/components/base/image-uploader/hooks.ts @@ -199,7 +199,7 @@ export const useClipboardUploader = ({ visionConfig, onUpload, files }: useClipb const handleClipboardPaste = useCallback((e: ClipboardEvent) => { // reserve native text copy behavior const file = e.clipboardData?.files[0] - // when copyed file, prevent default action + // when copied file, prevent default action if (file) { e.preventDefault() handleLocalFileUpload(file) diff --git a/web/app/components/base/image-uploader/image-preview.tsx b/web/app/components/base/image-uploader/image-preview.tsx index 5b33832a14..41f29fda2e 100644 --- a/web/app/components/base/image-uploader/image-preview.tsx +++ b/web/app/components/base/image-uploader/image-preview.tsx @@ -1,19 +1,43 @@ import type { FC } from 'react' +import { useRef } from 'react' +import { t } from 'i18next' import { createPortal } from 'react-dom' -import { RiCloseLine } from '@remixicon/react' +import { RiCloseLine, RiExternalLinkLine } from '@remixicon/react' +import Tooltip from '@/app/components/base/tooltip' +import { randomString } from '@/utils' type ImagePreviewProps = { url: string + title: string onCancel: () => void } const ImagePreview: FC = ({ url, + title, onCancel, }) => { + const selector = useRef(`copy-tooltip-${randomString(4)}`) + + const openInNewTab = () => { + // Open in a new window, considering the case when the page is inside an iframe + if (url.startsWith('http')) { + window.open(url, '_blank') + } + else if (url.startsWith('data:image')) { + // Base64 image + const win = window.open() + win?.document.write(`${title}`) + } + else { + console.error('Unable to open image', url) + } + } + return createPortal(
e.stopPropagation()}> + {/* eslint-disable-next-line @next/next/no-img-element */} preview image @@ -23,6 +47,18 @@ const ImagePreview: FC = ({ >
+ +
+ +
+
, document.body, ) diff --git a/web/app/components/base/image-uploader/video-preview.tsx b/web/app/components/base/image-uploader/video-preview.tsx new file mode 100644 index 0000000000..15291412eb --- /dev/null +++ b/web/app/components/base/image-uploader/video-preview.tsx @@ -0,0 +1,38 @@ +import type { FC } from 'react' +import { createPortal } from 'react-dom' +import { RiCloseLine } from '@remixicon/react' + +type VideoPreviewProps = { + url: string + title: string + onCancel: () => void +} +const VideoPreview: FC = ({ + url, + title, + onCancel, +}) => { + return createPortal( +
e.stopPropagation()}> +
+ +
+
+ +
+
+ , + document.body, + ) +} + +export default VideoPreview diff --git a/web/app/components/base/logo/logo-embedded-chat-avatar.tsx b/web/app/components/base/logo/logo-embedded-chat-avatar.tsx new file mode 100644 index 0000000000..7fd94827eb --- /dev/null +++ b/web/app/components/base/logo/logo-embedded-chat-avatar.tsx @@ -0,0 +1,18 @@ +import type { FC } from 'react' + +type LogoEmbeddedChatAvatarProps = { + className?: string +} +const LogoEmbeddedChatAvatar: FC = ({ + className, +}) => { + return ( + logo + ) +} + +export default LogoEmbeddedChatAvatar diff --git a/web/app/components/base/logo/logo-embedded-chat-header.tsx b/web/app/components/base/logo/logo-embedded-chat-header.tsx new file mode 100644 index 0000000000..976ce0c77a --- /dev/null +++ b/web/app/components/base/logo/logo-embedded-chat-header.tsx @@ -0,0 +1,19 @@ +import type { FC } from 'react' + +type LogoEmbeddedChatHeaderProps = { + className?: string +} + +const LogoEmbeddedChatHeader: FC = ({ + className, +}) => { + return ( + logo + ) +} + +export default LogoEmbeddedChatHeader diff --git a/web/app/components/base/logo/logo-embeded-chat-avatar.tsx b/web/app/components/base/logo/logo-embeded-chat-avatar.tsx deleted file mode 100644 index c5880e7bf6..0000000000 --- a/web/app/components/base/logo/logo-embeded-chat-avatar.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import type { FC } from 'react' - -type LogoEmbededChatAvatarProps = { - className?: string -} -const LogoEmbededChatAvatar: FC = ({ - className, -}) => { - return ( - logo - ) -} - -export default LogoEmbededChatAvatar diff --git a/web/app/components/base/logo/logo-embeded-chat-header.tsx b/web/app/components/base/logo/logo-embeded-chat-header.tsx deleted file mode 100644 index f979d501c2..0000000000 --- a/web/app/components/base/logo/logo-embeded-chat-header.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import type { FC } from 'react' - -type LogoEmbededChatHeaderProps = { - className?: string -} -const LogoEmbededChatHeader: FC = ({ - className, -}) => { - return ( - logo - ) -} - -export default LogoEmbededChatHeader diff --git a/web/app/components/base/markdown.tsx b/web/app/components/base/markdown.tsx index af4b13ff70..11bcd84e18 100644 --- a/web/app/components/base/markdown.tsx +++ b/web/app/components/base/markdown.tsx @@ -8,13 +8,16 @@ import RemarkGfm from 'remark-gfm' import SyntaxHighlighter from 'react-syntax-highlighter' import { atelierHeathLight } from 'react-syntax-highlighter/dist/esm/styles/hljs' import type { RefObject } from 'react' -import { memo, useEffect, useMemo, useRef, useState } from 'react' +import { Component, memo, useEffect, useMemo, useRef, useState } from 'react' import type { CodeComponent } from 'react-markdown/lib/ast-to-react' import cn from '@/utils/classnames' import CopyBtn from '@/app/components/base/copy-btn' import SVGBtn from '@/app/components/base/svg' import Flowchart from '@/app/components/base/mermaid' import ImageGallery from '@/app/components/base/image-gallery' +import { useChatContext } from '@/app/components/base/chat/chat/context' +import VideoGallery from '@/app/components/base/video-gallery' +import AudioGallery from '@/app/components/base/audio-gallery' // Available language https://github.com/react-syntax-highlighter/react-syntax-highlighter/blob/master/AVAILABLE_LANGUAGES_HLJS.MD const capitalizationLanguageNameMap: Record = { @@ -33,6 +36,10 @@ const capitalizationLanguageNameMap: Record = { markdown: 'MarkDown', makefile: 'MakeFile', echarts: 'ECharts', + shell: 'Shell', + powershell: 'PowerShell', + json: 'JSON', + latex: 'Latex', } const getCorrectCapitalizationLanguageName = (language: string) => { if (!language) @@ -65,6 +72,7 @@ export function PreCode(props: { children: any }) { ) } +// eslint-disable-next-line unused-imports/no-unused-vars const useLazyLoad = (ref: RefObject): boolean => { const [isIntersecting, setIntersecting] = useState(false) @@ -104,7 +112,7 @@ const CodeBlock: CodeComponent = memo(({ inline, className, children, ...props } const match = /language-(\w+)/.exec(className || '') const language = match?.[1] const languageShowName = getCorrectCapitalizationLanguageName(language || '') - let chartData = JSON.parse(String('{"title":{"text":"Something went wrong."}}').replace(/\n$/, '')) + let chartData = JSON.parse(String('{"title":{"text":"ECharts error - Wrong JSON format."}}').replace(/\n$/, '')) if (language === 'echarts') { try { chartData = JSON.parse(String(children).replace(/\n$/, '')) @@ -126,12 +134,7 @@ const CodeBlock: CodeComponent = memo(({ inline, className, children, ...props } >
{languageShowName}
- {language === 'mermaid' - && - } + {language === 'mermaid' && } ) : ( (language === 'echarts') - ? (
-
) +
) : ( { + const srcs = node.children.filter(child => 'properties' in child).map(child => (child as any).properties.src) + if (srcs.length === 0) + return null + return +}) +VideoBlock.displayName = 'VideoBlock' + +const AudioBlock: CodeComponent = memo(({ node }) => { + const srcs = node.children.filter(child => 'properties' in child).map(child => (child as any).properties.src) + if (srcs.length === 0) + return null + return +}) +AudioBlock.displayName = 'AudioBlock' + +const Paragraph = (paragraph: any) => { + const { node }: any = paragraph + const children_node = node.children + if (children_node && children_node[0] && 'tagName' in children_node[0] && children_node[0].tagName === 'img') { + return ( + <> + +
{paragraph.children.slice(1)}
+ + ) + } + return
{paragraph.children}
+} + +const Img = ({ src }: any) => { + return () +} + +const Link = ({ node, ...props }: any) => { + if (node.properties?.href && node.properties.href?.toString().startsWith('abbr')) { + // eslint-disable-next-line react-hooks/rules-of-hooks + const { onSend } = useChatContext() + const hidden_text = decodeURIComponent(node.properties.href.toString().split('abbr:')[1]) + + return onSend?.(hidden_text)} title={node.children[0]?.value}>{node.children[0]?.value} + } + else { + return {node.children[0] ? node.children[0]?.value : 'Download'} + } +} + export function Markdown(props: { content: string; className?: string }) { const latexContent = preprocessLaTeX(props.content) return (
{ + return (tree) => { + const iterate = (node: any) => { + if (node.type === 'element' && !node.properties?.src && node.properties?.ref && node.properties.ref.startsWith('{') && node.properties.ref.endsWith('}')) + delete node.properties.ref + + if (node.children) + node.children.forEach(iterate) + } + tree.children.forEach(iterate) + } + }, ]} components={{ code: CodeBlock, - img({ src }) { - return ( - - ) - }, - p: (paragraph) => { - const { node }: any = paragraph - if (node.children[0].tagName === 'img') { - const image = node.children[0] - - return ( - <> - -

{paragraph.children.slice(1)}

- - ) - } - return

{paragraph.children}

- }, + img: Img, + video: VideoBlock, + audio: AudioBlock, + a: Link, + p: Paragraph, }} linkTarget='_blank' > @@ -211,3 +260,25 @@ export function Markdown(props: { content: string; className?: string }) {
) } + +// **Add an ECharts runtime error handler +// Avoid error #7832 (Crash when ECharts accesses undefined objects) +// This can happen when a component attempts to access an undefined object that references an unregistered map, causing the program to crash. + +export default class ErrorBoundary extends Component { + constructor(props) { + super(props) + this.state = { hasError: false } + } + + componentDidCatch(error, errorInfo) { + this.setState({ hasError: true }) + console.error(error, errorInfo) + } + + render() { + if (this.state.hasError) + return
Oops! ECharts reported a runtime error.
(see the browser console for more information)
+ return this.props.children + } +} diff --git a/web/app/components/base/notion-page-selector/base.tsx b/web/app/components/base/notion-page-selector/base.tsx index 63aff09a93..e3b321b120 100644 --- a/web/app/components/base/notion-page-selector/base.tsx +++ b/web/app/components/base/notion-page-selector/base.tsx @@ -72,7 +72,7 @@ const NotionPageSelector = ({ const handleSelectWorkspace = useCallback((workspaceId: string) => { setCurrentWorkspaceId(workspaceId) }, []) - const handleSelecPages = (newSelectedPagesId: Set) => { + const handleSelectPages = (newSelectedPagesId: Set) => { const selectedPages = Array.from(newSelectedPagesId).map(pageId => getPagesMapAndSelectedPagesId[0][pageId]) setSelectedPagesId(new Set(Array.from(newSelectedPagesId))) @@ -117,7 +117,7 @@ const NotionPageSelector = ({ searchValue={searchValue} list={currentWorkspace?.pages || []} pagesMap={getPagesMapAndSelectedPagesId[0]} - onSelect={handleSelecPages} + onSelect={handleSelectPages} canPreview={canPreview} previewPageId={previewPageId} onPreview={handlePreviewPage} diff --git a/web/app/components/base/notion-page-selector/page-selector/index.tsx b/web/app/components/base/notion-page-selector/page-selector/index.tsx index b61fa34567..8f398790e7 100644 --- a/web/app/components/base/notion-page-selector/page-selector/index.tsx +++ b/web/app/components/base/notion-page-selector/page-selector/index.tsx @@ -22,13 +22,13 @@ type PageSelectorProps = { type NotionPageTreeItem = { children: Set descendants: Set - deepth: number + depth: number ancestors: string[] } & DataSourceNotionPage type NotionPageTreeMap = Record type NotionPageItem = { expand: boolean - deepth: number + depth: number } & DataSourceNotionPage const recursivePushInParentDescendants = ( @@ -51,7 +51,7 @@ const recursivePushInParentDescendants = ( ...pagesMap[parentId], children, descendants, - deepth: 0, + depth: 0, ancestors: [], } } @@ -60,7 +60,7 @@ const recursivePushInParentDescendants = ( listTreeMap[parentId].descendants.add(pageId) listTreeMap[parentId].descendants.add(leafItem.page_id) } - leafItem.deepth++ + leafItem.depth++ leafItem.ancestors.unshift(listTreeMap[parentId].page_name) if (listTreeMap[parentId].parent_id !== 'root') @@ -95,7 +95,7 @@ const ItemComponent = ({ index, style, data }: ListChildComponentProps<{ return (
handleToggle(index)} /> ) @@ -106,7 +106,7 @@ const ItemComponent = ({ index, style, data }: ListChildComponentProps<{ ) } return ( -
+
) } @@ -185,7 +185,7 @@ const PageSelector = ({ return { ...item, expand: false, - deepth: 0, + depth: 0, } })) } @@ -195,7 +195,7 @@ const PageSelector = ({ return { ...item, expand: false, - deepth: 0, + depth: 0, } }) const currentDataList = searchValue ? searchDataList : dataList @@ -205,7 +205,7 @@ const PageSelector = ({ return list.reduce((prev: NotionPageTreeMap, next: DataSourceNotionPage) => { const pageId = next.page_id if (!prev[pageId]) - prev[pageId] = { ...next, children: new Set(), descendants: new Set(), deepth: 0, ancestors: [] } + prev[pageId] = { ...next, children: new Set(), descendants: new Set(), depth: 0, ancestors: [] } recursivePushInParentDescendants(pagesMap, prev, prev[pageId], prev[pageId]) return prev @@ -233,7 +233,7 @@ const PageSelector = ({ ...childrenIds.map(item => ({ ...pagesMap[item], expand: false, - deepth: listMapWithChildrenAndDescendants[item].deepth, + depth: listMapWithChildrenAndDescendants[item].depth, })), ...dataList.slice(index + 1)] } diff --git a/web/app/components/base/pagination/index.tsx b/web/app/components/base/pagination/index.tsx index 98b1e266ae..f8c5684b55 100644 --- a/web/app/components/base/pagination/index.tsx +++ b/web/app/components/base/pagination/index.tsx @@ -23,8 +23,8 @@ const CustomizedPagination: FC = ({ current, onChange, total, limit = 10 middlePagesSiblingCount={1} setCurrentPage={onChange} totalPages={totalPages} - truncableClassName="w-8 px-0.5 text-center" - truncableText="..." + truncatableClassName="w-8 px-0.5 text-center" + truncatableText="..." > ) => [RefObject, boolean] -export const useSelectOrDelete: UseSelectOrDeleteHanlder = (nodeKey: string, command?: LexicalCommand) => { +export type UseSelectOrDeleteHandler = (nodeKey: string, command?: LexicalCommand) => [RefObject, boolean] +export const useSelectOrDelete: UseSelectOrDeleteHandler = (nodeKey: string, command?: LexicalCommand) => { const ref = useRef(null) const [editor] = useLexicalComposerContext() const [isSelected, setSelected, clearSelection] = useLexicalNodeSelection(nodeKey) diff --git a/web/app/components/base/search-input/index.tsx b/web/app/components/base/search-input/index.tsx index a85bc2db8a..4b3821da5a 100644 --- a/web/app/components/base/search-input/index.tsx +++ b/web/app/components/base/search-input/index.tsx @@ -25,9 +25,9 @@ const SearchInput: FC = ({ return (
diff --git a/web/app/components/base/select/locale.tsx b/web/app/components/base/select/locale.tsx index 3066364316..8b89c66950 100644 --- a/web/app/components/base/select/locale.tsx +++ b/web/app/components/base/select/locale.tsx @@ -77,7 +77,7 @@ export function InputSelect({
- + {item?.name}
diff --git a/web/app/components/base/slider/index.tsx b/web/app/components/base/slider/index.tsx index 18ef3a7a29..2b8f181633 100644 --- a/web/app/components/base/slider/index.tsx +++ b/web/app/components/base/slider/index.tsx @@ -32,7 +32,7 @@ const Slider: React.FC = ({ max={max || 100} step={step || 1} className={cn('relative slider', className)} - thumbClassName={cn('absolute top-[-9px] w-2 h-5 border-[0.5px] border-components-silder-knob-border rounded-[3px] bg-components-silder-knob shadow-sm focus:outline-none', !disabled && 'cursor-pointer', thumbClassName)} + thumbClassName={cn('absolute top-[-9px] w-2 h-5 border-[0.5px] border-components-slider-knob-border rounded-[3px] bg-components-slider-knob shadow-sm focus:outline-none', !disabled && 'cursor-pointer', thumbClassName)} trackClassName={cn('h-0.5 rounded-full slider-track', trackClassName)} onChange={onChange} /> diff --git a/web/app/components/base/slider/style.css b/web/app/components/base/slider/style.css index 6b4394ed93..e215a9914e 100644 --- a/web/app/components/base/slider/style.css +++ b/web/app/components/base/slider/style.css @@ -3,9 +3,9 @@ } .slider-track { - background-color: var(--color-components-silder-range); + background-color: var(--color-components-slider-range); } .slider-track-1 { - background-color: var(--color-components-silder-track); + background-color: var(--color-components-slider-track); } \ No newline at end of file diff --git a/web/app/components/base/tag-input/index.tsx b/web/app/components/base/tag-input/index.tsx index 7eab355a0d..404fd89f38 100644 --- a/web/app/components/base/tag-input/index.tsx +++ b/web/app/components/base/tag-input/index.tsx @@ -46,16 +46,16 @@ const TagInput: FC = ({ if (isSpecialMode) e.preventDefault() - const valueTrimed = value.trim() - if (!valueTrimed || (items.find(item => item === valueTrimed))) + const valueTrimmed = value.trim() + if (!valueTrimmed || (items.find(item => item === valueTrimmed))) return - if (valueTrimed.length > 20) { + if (valueTrimmed.length > 20) { notify({ type: 'error', message: t('datasetDocuments.segment.keywordError') }) return } - onChange([...items, valueTrimed]) + onChange([...items, valueTrimmed]) setTimeout(() => { setValue('') }) diff --git a/web/app/components/base/text-generation/types.ts b/web/app/components/base/text-generation/types.ts index 82a4177592..1e2c04f6e8 100644 --- a/web/app/components/base/text-generation/types.ts +++ b/web/app/components/base/text-generation/types.ts @@ -15,7 +15,7 @@ export type UserInputForm = { } export type UserInputFormTextInput = { - 'text-inpput': UserInputForm & { + 'text-input': UserInputForm & { max_length: number } } diff --git a/web/app/components/base/video-gallery/VideoPlayer.module.css b/web/app/components/base/video-gallery/VideoPlayer.module.css new file mode 100644 index 0000000000..04c4a367d6 --- /dev/null +++ b/web/app/components/base/video-gallery/VideoPlayer.module.css @@ -0,0 +1,188 @@ +.videoPlayer { + position: relative; + width: 100%; + max-width: 800px; + margin: 0 auto; + border-radius: 8px; + overflow: hidden; +} + +.video { + width: 100%; + display: block; +} + +.controls { + position: absolute; + bottom: 0; + left: 0; + right: 0; + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + justify-content: flex-end; + transition: opacity 0.3s ease; +} + +.controls.hidden { + opacity: 0; +} + +.controls.visible { + opacity: 1; +} + +.overlay { + background: linear-gradient(to top, rgba(0, 0, 0, 0.7) 0%, transparent 100%); + padding: 20px; + display: flex; + flex-direction: column; +} + +.progressBarContainer { + width: 100%; + margin-bottom: 10px; +} + +.controlsContent { + display: flex; + justify-content: space-between; + align-items: center; +} + +.leftControls, .rightControls { + display: flex; + align-items: center; +} + +.playPauseButton, .muteButton, .fullscreenButton { + background: none; + border: none; + color: white; + cursor: pointer; + padding: 4px; + margin-right: 10px; + display: flex; + align-items: center; + justify-content: center; +} + +.playPauseButton:hover, .muteButton:hover, .fullscreenButton:hover { + background-color: rgba(255, 255, 255, 0.1); + border-radius: 50%; +} + +.time { + color: white; + font-size: 14px; + margin-left: 8px; +} + +.volumeControl { + display: flex; + align-items: center; + margin-right: 16px; +} + +.volumeSlider { + width: 60px; + height: 4px; + background: rgba(255, 255, 255, 0.3); + border-radius: 2px; + cursor: pointer; + margin-left: 12px; + position: relative; +} + +.volumeLevel { + position: absolute; + top: 0; + left: 0; + height: 100%; + background: #ffffff; + border-radius: 2px; +} + +.progressBar { + position: relative; + width: 100%; + height: 4px; + background: rgba(255, 255, 255, 0.3); + cursor: pointer; + border-radius: 2px; + overflow: visible; + transition: height 0.2s ease; +} + +.progressBar:hover { + height: 6px; +} + +.progress { + height: 100%; + background: #ffffff; + transition: width 0.1s ease-in-out; +} + +.hoverTimeIndicator { + position: absolute; + bottom: 100%; + transform: translateX(-50%); + background-color: rgba(0, 0, 0, 0.7); + color: white; + padding: 4px 8px; + border-radius: 4px; + font-size: 12px; + pointer-events: none; + white-space: nowrap; + margin-bottom: 8px; +} + +.hoverTimeIndicator::after { + content: ''; + position: absolute; + top: 100%; + left: 50%; + margin-left: -4px; + border-width: 4px; + border-style: solid; + border-color: rgba(0, 0, 0, 0.7) transparent transparent transparent; +} + +.controls.smallSize .controlsContent { + justify-content: space-between; +} + +.controls.smallSize .leftControls, +.controls.smallSize .rightControls { + flex: 0 0 auto; + display: flex; + align-items: center; +} + +.controls.smallSize .rightControls { + justify-content: flex-end; +} + +.controls.smallSize .progressBarContainer { + margin-bottom: 4px; +} + +.controls.smallSize .playPauseButton, +.controls.smallSize .muteButton, +.controls.smallSize .fullscreenButton { + padding: 2px; + margin-right: 4px; +} + +.controls.smallSize .playPauseButton svg, +.controls.smallSize .muteButton svg, +.controls.smallSize .fullscreenButton svg { + width: 16px; + height: 16px; +} + +.controls.smallSize .muteButton { + order: -1; +} diff --git a/web/app/components/base/video-gallery/VideoPlayer.tsx b/web/app/components/base/video-gallery/VideoPlayer.tsx new file mode 100644 index 0000000000..d7c86a1af9 --- /dev/null +++ b/web/app/components/base/video-gallery/VideoPlayer.tsx @@ -0,0 +1,278 @@ +import React, { useCallback, useEffect, useRef, useState } from 'react' +import styles from './VideoPlayer.module.css' + +type VideoPlayerProps = { + src: string +} + +const PlayIcon = () => ( + + + +) + +const PauseIcon = () => ( + + + +) + +const MuteIcon = () => ( + + + +) + +const UnmuteIcon = () => ( + + + +) + +const FullscreenIcon = () => ( + + + +) + +const VideoPlayer: React.FC = ({ src }) => { + const [isPlaying, setIsPlaying] = useState(false) + const [currentTime, setCurrentTime] = useState(0) + const [duration, setDuration] = useState(0) + const [isMuted, setIsMuted] = useState(false) + const [volume, setVolume] = useState(1) + const [isDragging, setIsDragging] = useState(false) + const [isControlsVisible, setIsControlsVisible] = useState(true) + const [hoverTime, setHoverTime] = useState(null) + const videoRef = useRef(null) + const progressRef = useRef(null) + const volumeRef = useRef(null) + const controlsTimeoutRef = useRef(null) + const [isSmallSize, setIsSmallSize] = useState(false) + const containerRef = useRef(null) + + useEffect(() => { + const video = videoRef.current + if (!video) + return + + const setVideoData = () => { + setDuration(video.duration) + setVolume(video.volume) + } + + const setVideoTime = () => { + setCurrentTime(video.currentTime) + } + + const handleEnded = () => { + setIsPlaying(false) + } + + video.addEventListener('loadedmetadata', setVideoData) + video.addEventListener('timeupdate', setVideoTime) + video.addEventListener('ended', handleEnded) + + return () => { + video.removeEventListener('loadedmetadata', setVideoData) + video.removeEventListener('timeupdate', setVideoTime) + video.removeEventListener('ended', handleEnded) + } + }, [src]) + + useEffect(() => { + return () => { + if (controlsTimeoutRef.current) + clearTimeout(controlsTimeoutRef.current) + } + }, []) + + const showControls = useCallback(() => { + setIsControlsVisible(true) + if (controlsTimeoutRef.current) + clearTimeout(controlsTimeoutRef.current) + + controlsTimeoutRef.current = setTimeout(() => setIsControlsVisible(false), 3000) + }, []) + + const togglePlayPause = useCallback(() => { + const video = videoRef.current + if (video) { + if (isPlaying) + video.pause() + else video.play().catch(error => console.error('Error playing video:', error)) + setIsPlaying(!isPlaying) + } + }, [isPlaying]) + + const toggleMute = useCallback(() => { + const video = videoRef.current + if (video) { + const newMutedState = !video.muted + video.muted = newMutedState + setIsMuted(newMutedState) + setVolume(newMutedState ? 0 : (video.volume > 0 ? video.volume : 1)) + video.volume = newMutedState ? 0 : (video.volume > 0 ? video.volume : 1) + } + }, []) + + const toggleFullscreen = useCallback(() => { + const video = videoRef.current + if (video) { + if (document.fullscreenElement) + document.exitFullscreen() + else video.requestFullscreen() + } + }, []) + + const formatTime = (time: number) => { + const minutes = Math.floor(time / 60) + const seconds = Math.floor(time % 60) + return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}` + } + + const updateVideoProgress = useCallback((clientX: number) => { + const progressBar = progressRef.current + const video = videoRef.current + if (progressBar && video) { + const rect = progressBar.getBoundingClientRect() + const pos = (clientX - rect.left) / rect.width + const newTime = pos * video.duration + if (newTime >= 0 && newTime <= video.duration) { + setHoverTime(newTime) + if (isDragging) + video.currentTime = newTime + } + } + }, [isDragging]) + + const handleMouseMove = useCallback((e: React.MouseEvent) => { + updateVideoProgress(e.clientX) + }, [updateVideoProgress]) + + const handleMouseLeave = useCallback(() => { + if (!isDragging) + setHoverTime(null) + }, [isDragging]) + + const handleMouseDown = useCallback((e: React.MouseEvent) => { + e.preventDefault() + setIsDragging(true) + updateVideoProgress(e.clientX) + }, [updateVideoProgress]) + + useEffect(() => { + const handleGlobalMouseMove = (e: MouseEvent) => { + if (isDragging) + updateVideoProgress(e.clientX) + } + + const handleGlobalMouseUp = () => { + setIsDragging(false) + setHoverTime(null) + } + + if (isDragging) { + document.addEventListener('mousemove', handleGlobalMouseMove) + document.addEventListener('mouseup', handleGlobalMouseUp) + } + + return () => { + document.removeEventListener('mousemove', handleGlobalMouseMove) + document.removeEventListener('mouseup', handleGlobalMouseUp) + } + }, [isDragging, updateVideoProgress]) + + const checkSize = useCallback(() => { + if (containerRef.current) + setIsSmallSize(containerRef.current.offsetWidth < 400) + }, []) + + useEffect(() => { + checkSize() + window.addEventListener('resize', checkSize) + return () => window.removeEventListener('resize', checkSize) + }, [checkSize]) + + const handleVolumeChange = useCallback((e: React.MouseEvent) => { + const volumeBar = volumeRef.current + const video = videoRef.current + if (volumeBar && video) { + const rect = volumeBar.getBoundingClientRect() + const newVolume = (e.clientX - rect.left) / rect.width + const clampedVolume = Math.max(0, Math.min(1, newVolume)) + video.volume = clampedVolume + setVolume(clampedVolume) + setIsMuted(clampedVolume === 0) + } + }, []) + + return ( +
+
) diff --git a/web/app/components/browser-initor.tsx b/web/app/components/browser-initor.tsx index 711ff62a94..939ddd567d 100644 --- a/web/app/components/browser-initor.tsx +++ b/web/app/components/browser-initor.tsx @@ -43,10 +43,10 @@ Object.defineProperty(globalThis, 'sessionStorage', { value: sessionStorage, }) -const BrowerInitor = ({ +const BrowserInitor = ({ children, }: { children: React.ReactElement }) => { return children } -export default BrowerInitor +export default BrowserInitor diff --git a/web/app/components/datasets/common/check-rerank-model.ts b/web/app/components/datasets/common/check-rerank-model.ts index 42810e4bf0..581c2bb69a 100644 --- a/web/app/components/datasets/common/check-rerank-model.ts +++ b/web/app/components/datasets/common/check-rerank-model.ts @@ -7,13 +7,13 @@ import { RerankingModeEnum } from '@/models/datasets' export const isReRankModelSelected = ({ rerankDefaultModel, - isRerankDefaultModelVaild, + isRerankDefaultModelValid, retrievalConfig, rerankModelList, indexMethod, }: { rerankDefaultModel?: DefaultModelResponse - isRerankDefaultModelVaild: boolean + isRerankDefaultModelValid: boolean retrievalConfig: RetrievalConfig rerankModelList: Model[] indexMethod?: string @@ -25,7 +25,7 @@ export const isReRankModelSelected = ({ return provider?.models.find(({ model }) => model === retrievalConfig.reranking_model?.reranking_model_name) } - if (isRerankDefaultModelVaild) + if (isRerankDefaultModelValid) return !!rerankDefaultModel return false diff --git a/web/app/components/datasets/common/retrieval-method-config/index.tsx b/web/app/components/datasets/common/retrieval-method-config/index.tsx index 1e407b62e1..20d93568ad 100644 --- a/web/app/components/datasets/common/retrieval-method-config/index.tsx +++ b/web/app/components/datasets/common/retrieval-method-config/index.tsx @@ -11,6 +11,11 @@ import { FileSearch02 } from '@/app/components/base/icons/src/vender/solid/files import { useProviderContext } from '@/context/provider-context' import { useDefaultModel } from '@/app/components/header/account-setting/model-provider-page/hooks' import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' +import { + DEFAULT_WEIGHTED_SCORE, + RerankingModeEnum, + WeightedScoreEnum, +} from '@/models/datasets' type Props = { value: RetrievalConfig @@ -32,6 +37,18 @@ const RetrievalMethodConfig: FC = ({ reranking_provider_name: rerankDefaultModel?.provider.provider || '', reranking_model_name: rerankDefaultModel?.model || '', }, + reranking_mode: passValue.reranking_mode || (rerankDefaultModel ? RerankingModeEnum.RerankingModel : RerankingModeEnum.WeightedScore), + weights: passValue.weights || { + weight_type: WeightedScoreEnum.Customized, + vector_setting: { + vector_weight: DEFAULT_WEIGHTED_SCORE.other.semantic, + embedding_provider_name: '', + embedding_model_name: '', + }, + keyword_setting: { + keyword_weight: DEFAULT_WEIGHTED_SCORE.other.keyword, + }, + }, } } return passValue diff --git a/web/app/components/datasets/create/assets/unknow.svg b/web/app/components/datasets/create/assets/unknown.svg similarity index 100% rename from web/app/components/datasets/create/assets/unknow.svg rename to web/app/components/datasets/create/assets/unknown.svg diff --git a/web/app/components/datasets/create/embedding-process/index.module.css b/web/app/components/datasets/create/embedding-process/index.module.css index a15b1310b4..1ebb006b54 100644 --- a/web/app/components/datasets/create/embedding-process/index.module.css +++ b/web/app/components/datasets/create/embedding-process/index.module.css @@ -83,7 +83,7 @@ .fileIcon { @apply w-4 h-4 mr-1 bg-center bg-no-repeat; - background-image: url(../assets/unknow.svg); + background-image: url(../assets/unknown.svg); background-size: 16px; } .fileIcon.csv { diff --git a/web/app/components/datasets/create/embedding-process/index.tsx b/web/app/components/datasets/create/embedding-process/index.tsx index 574dd083c7..7786582085 100644 --- a/web/app/components/datasets/create/embedding-process/index.tsx +++ b/web/app/components/datasets/create/embedding-process/index.tsx @@ -13,8 +13,7 @@ import cn from '@/utils/classnames' import { FieldInfo } from '@/app/components/datasets/documents/detail/metadata' import Button from '@/app/components/base/button' import type { FullDocumentDetail, IndexingStatusResponse, ProcessRuleResponse } from '@/models/datasets' -import { formatNumber } from '@/utils/format' -import { fetchIndexingStatusBatch as doFetchIndexingStatus, fetchIndexingEstimateBatch, fetchProcessRule } from '@/service/datasets' +import { fetchIndexingStatusBatch as doFetchIndexingStatus, fetchProcessRule } from '@/service/datasets' import { DataSourceType } from '@/models/datasets' import NotionIcon from '@/app/components/base/notion-icon' import PriorityLabel from '@/app/components/billing/priority-label' @@ -142,14 +141,6 @@ const EmbeddingProcess: FC = ({ datasetId, batchId, documents = [], index }, apiParams => fetchProcessRule(omit(apiParams, 'action')), { revalidateOnFocus: false, }) - // get cost - const { data: indexingEstimateDetail } = useSWR({ - action: 'fetchIndexingEstimateBatch', - datasetId, - batchId, - }, apiParams => fetchIndexingEstimateBatch(omit(apiParams, 'action')), { - revalidateOnFocus: false, - }) const router = useRouter() const navToDocumentList = () => { @@ -190,28 +181,11 @@ const EmbeddingProcess: FC = ({ datasetId, batchId, documents = [], index return ( <> -
+
{isEmbedding && t('datasetDocuments.embedding.processing')} {isEmbeddingCompleted && t('datasetDocuments.embedding.completed')}
-
- {indexingType === 'high_quality' && ( -
-
- {t('datasetDocuments.embedding.highQuality')} · {t('datasetDocuments.embedding.estimate')} - {formatNumber(indexingEstimateDetail?.tokens || 0)}tokens - (${formatNumber(indexingEstimateDetail?.total_price || 0)}) -
- )} - {indexingType === 'economy' && ( -
-
- {t('datasetDocuments.embedding.economy')} · {t('datasetDocuments.embedding.estimate')} - 0tokens -
- )} -
{ enableBilling && plan.type !== Plan.team && ( diff --git a/web/app/components/datasets/create/empty-dataset-creation-modal/index.tsx b/web/app/components/datasets/create/empty-dataset-creation-modal/index.tsx index c490d50b88..23c3f0314a 100644 --- a/web/app/components/datasets/create/empty-dataset-creation-modal/index.tsx +++ b/web/app/components/datasets/create/empty-dataset-creation-modal/index.tsx @@ -32,7 +32,7 @@ const EmptyDatasetCreationModal = ({ return } if (inputValue.length > 40) { - notify({ type: 'error', message: t('datasetCreation.stepOne.modal.nameLengthInvaild') }) + notify({ type: 'error', message: t('datasetCreation.stepOne.modal.nameLengthInvalid') }) return } try { diff --git a/web/app/components/datasets/create/file-uploader/index.module.css b/web/app/components/datasets/create/file-uploader/index.module.css index d141815c5a..bf5b7dcaf5 100644 --- a/web/app/components/datasets/create/file-uploader/index.module.css +++ b/web/app/components/datasets/create/file-uploader/index.module.css @@ -104,7 +104,7 @@ .fileIcon { @apply shrink-0 w-6 h-6 mr-2 bg-center bg-no-repeat; - background-image: url(../assets/unknow.svg); + background-image: url(../assets/unknown.svg); background-size: 24px; } diff --git a/web/app/components/datasets/create/step-two/index.module.css b/web/app/components/datasets/create/step-two/index.module.css index 24a62c8e3c..f89d6d67ea 100644 --- a/web/app/components/datasets/create/step-two/index.module.css +++ b/web/app/components/datasets/create/step-two/index.module.css @@ -30,7 +30,7 @@ } .indexItem { - min-height: 146px; + min-height: 126px; } .indexItem .disableMask { @@ -121,10 +121,6 @@ @apply pb-1; } -.radioItem.indexItem .typeHeader .tip { - @apply pb-3; -} - .radioItem .typeIcon { position: absolute; top: 18px; @@ -264,7 +260,7 @@ } .input { - @apply inline-flex h-9 w-full py-1 px-2 rounded-lg text-xs leading-normal; + @apply inline-flex h-9 w-full py-1 px-2 pr-14 rounded-lg text-xs leading-normal; @apply bg-gray-100 caret-primary-600 hover:bg-gray-100 focus:ring-1 focus:ring-inset focus:ring-gray-200 focus-visible:outline-none focus:bg-white placeholder:text-gray-400; } diff --git a/web/app/components/datasets/create/step-two/index.tsx b/web/app/components/datasets/create/step-two/index.tsx index 10b378d8c5..15332b944d 100644 --- a/web/app/components/datasets/create/step-two/index.tsx +++ b/web/app/components/datasets/create/step-two/index.tsx @@ -14,7 +14,7 @@ import PreviewItem, { PreviewType } from './preview-item' import LanguageSelect from './language-select' import s from './index.module.css' import cn from '@/utils/classnames' -import type { CrawlOptions, CrawlResultItem, CreateDocumentReq, CustomFile, FileIndexingEstimateResponse, FullDocumentDetail, IndexingEstimateParams, IndexingEstimateResponse, NotionInfo, PreProcessingRule, ProcessRule, Rules, createDocumentResponse } from '@/models/datasets' +import type { CrawlOptions, CrawlResultItem, CreateDocumentReq, CustomFile, FileIndexingEstimateResponse, FullDocumentDetail, IndexingEstimateParams, NotionInfo, PreProcessingRule, ProcessRule, Rules, createDocumentResponse } from '@/models/datasets' import { createDocument, createFirstDocument, @@ -41,8 +41,10 @@ import { IS_CE_EDITION } from '@/config' import { RETRIEVE_METHOD } from '@/types/app' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import Tooltip from '@/app/components/base/tooltip' -import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks' +import { useDefaultModel, useModelList, useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks' import { LanguagesSupported } from '@/i18n/language' +import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector' +import type { DefaultModel } from '@/app/components/header/account-setting/model-provider-page/declarations' import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' import { Globe01 } from '@/app/components/base/icons/src/vender/line/mapsAndTravel' @@ -109,7 +111,7 @@ const StepTwo = ({ const [previewScrolled, setPreviewScrolled] = useState(false) const [segmentationType, setSegmentationType] = useState(SegmentType.AUTO) const [segmentIdentifier, setSegmentIdentifier] = useState('\\n') - const [max, setMax] = useState(500) + const [max, setMax] = useState(5000) // default chunk length const [overlap, setOverlap] = useState(50) const [rules, setRules] = useState([]) const [defaultConfig, setDefaultConfig] = useState() @@ -131,7 +133,6 @@ const StepTwo = ({ const [showPreview, { setTrue: setShowPreview, setFalse: hidePreview }] = useBoolean() const [customFileIndexingEstimate, setCustomFileIndexingEstimate] = useState(null) const [automaticFileIndexingEstimate, setAutomaticFileIndexingEstimate] = useState(null) - const [estimateTokes, setEstimateTokes] = useState | null>(null) const fileIndexingEstimate = (() => { return segmentationType === SegmentType.AUTO ? automaticFileIndexingEstimate : customFileIndexingEstimate @@ -192,13 +193,10 @@ const StepTwo = ({ const fetchFileIndexingEstimate = async (docForm = DocForm.TEXT) => { // eslint-disable-next-line @typescript-eslint/no-use-before-define const res = await didFetchFileIndexingEstimate(getFileIndexingEstimateParams(docForm)!) - if (segmentationType === SegmentType.CUSTOM) { + if (segmentationType === SegmentType.CUSTOM) setCustomFileIndexingEstimate(res) - } - else { + else setAutomaticFileIndexingEstimate(res) - indexType === IndexingType.QUALIFIED && setEstimateTokes({ tokens: res.tokens, total_price: res.total_price }) - } } const confirmChangeCustomConfig = () => { @@ -308,8 +306,21 @@ const StepTwo = ({ const { modelList: rerankModelList, defaultModel: rerankDefaultModel, - currentModel: isRerankDefaultModelVaild, + currentModel: isRerankDefaultModelValid, } = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.rerank) + const { data: embeddingModelList } = useModelList(ModelTypeEnum.textEmbedding) + const { data: defaultEmbeddingModel } = useDefaultModel(ModelTypeEnum.textEmbedding) + const [embeddingModel, setEmbeddingModel] = useState( + currentDataset?.embedding_model + ? { + provider: currentDataset.embedding_model_provider, + model: currentDataset.embedding_model, + } + : { + provider: defaultEmbeddingModel?.provider.provider || '', + model: defaultEmbeddingModel?.model || '', + }, + ) const getCreationParams = () => { let params if (segmentationType === SegmentType.CUSTOM && overlap > max) { @@ -324,6 +335,8 @@ const StepTwo = ({ process_rule: getProcessRule(), // eslint-disable-next-line @typescript-eslint/no-use-before-define retrieval_model: retrievalConfig, // Readonly. If want to changed, just go to settings page. + embedding_model: embeddingModel.model, // Readonly + embedding_model_provider: embeddingModel.provider, // Readonly } as CreateDocumentReq } else { // create @@ -331,7 +344,7 @@ const StepTwo = ({ if ( !isReRankModelSelected({ rerankDefaultModel, - isRerankDefaultModelVaild: !!isRerankDefaultModelVaild, + isRerankDefaultModelValid: !!isRerankDefaultModelValid, rerankModelList, // eslint-disable-next-line @typescript-eslint/no-use-before-define retrievalConfig, @@ -360,6 +373,8 @@ const StepTwo = ({ doc_language: docLanguage, retrieval_model: postRetrievalConfig, + embedding_model: embeddingModel.model, + embedding_model_provider: embeddingModel.provider, } as CreateDocumentReq if (dataSourceType === DataSourceType.FILE) { params.data_source.info_list.file_info_list = { @@ -613,14 +628,17 @@ const StepTwo = ({
{t('datasetCreation.stepTwo.maxLength')}
- setMax(parseInt(e.target.value.replace(/^0+/, ''), 10))} - /> +
+ setMax(parseInt(e.target.value.replace(/^0+/, ''), 10))} + /> +
Tokens
+
@@ -635,14 +653,17 @@ const StepTwo = ({ } />
- setOverlap(parseInt(e.target.value.replace(/^0+/, ''), 10))} - /> +
+ setOverlap(parseInt(e.target.value.replace(/^0+/, ''), 10))} + /> +
Tokens
+
@@ -675,7 +696,7 @@ const StepTwo = ({ !isAPIKeySet && s.disabled, !hasSetIndexType && indexType === IndexingType.QUALIFIED && s.active, hasSetIndexType && s.disabled, - hasSetIndexType && '!w-full', + hasSetIndexType && '!w-full !min-h-[96px]', )} onClick={() => { if (isAPIKeySet) @@ -690,16 +711,6 @@ const StepTwo = ({ {!hasSetIndexType && {t('datasetCreation.stepTwo.recommend')}}
{t('datasetCreation.stepTwo.qualifiedTip')}
-
{t('datasetCreation.stepTwo.emstimateCost')}
- { - estimateTokes - ? ( -
{formatNumber(estimateTokes.tokens)} tokens(${formatNumber(estimateTokes.total_price)})
- ) - : ( -
{t('datasetCreation.stepTwo.calculating')}
- ) - }
{!isAPIKeySet && (
@@ -717,7 +728,7 @@ const StepTwo = ({ s.indexItem, !hasSetIndexType && indexType === IndexingType.ECONOMICAL && s.active, hasSetIndexType && s.disabled, - hasSetIndexType && '!w-full', + hasSetIndexType && '!w-full !min-h-[96px]', )} onClick={changeToEconomicalType} > @@ -726,15 +737,13 @@ const StepTwo = ({
{t('datasetCreation.stepTwo.economical')}
{t('datasetCreation.stepTwo.economicalTip')}
-
{t('datasetCreation.stepTwo.emstimateCost')}
-
0 tokens
)}
- {hasSetIndexType && ( + {hasSetIndexType && indexType === IndexingType.ECONOMICAL && (
- {t('datasetCreation.stepTwo.indexSettedTip')} + {t('datasetCreation.stepTwo.indexSettingTip')} {t('datasetCreation.stepTwo.datasetSettingLink')}
)} @@ -767,12 +776,32 @@ const StepTwo = ({ )}
)} + {/* Embedding model */} + {indexType === IndexingType.QUALIFIED && ( +
+
{t('datasetSettings.form.embeddingModel')}
+ { + setEmbeddingModel(model) + }} + /> + {!!datasetId && ( +
+ {t('datasetCreation.stepTwo.indexSettingTip')} + {t('datasetCreation.stepTwo.datasetSettingLink')} +
+ )} +
+ )} {/* Retrieval Method Config */}
{!datasetId ? (
- {t('datasetSettings.form.retrievalSetting.title')} +
{t('datasetSettings.form.retrievalSetting.title')}
{t('datasetSettings.form.retrievalSetting.learnMore')} {t('datasetSettings.form.retrievalSetting.longDescription')} @@ -861,7 +890,7 @@ const StepTwo = ({
-
{t('datasetCreation.stepTwo.emstimateSegment')}
+
{t('datasetCreation.stepTwo.estimateSegment')}
{ fileIndexingEstimate diff --git a/web/app/components/datasets/create/step-two/preview-item/index.tsx b/web/app/components/datasets/create/step-two/preview-item/index.tsx index fdec6c734d..56102b6540 100644 --- a/web/app/components/datasets/create/step-two/preview-item/index.tsx +++ b/web/app/components/datasets/create/step-two/preview-item/index.tsx @@ -41,14 +41,14 @@ const PreviewItem: FC = ({ const charNums = type === PreviewType.TEXT ? (content || '').length : (qa?.answer || '').length + (qa?.question || '').length - const formatedIndex = (() => String(index).padStart(3, '0'))() + const formattedIndex = (() => String(index).padStart(3, '0'))() return (
{sharpIcon} - {formatedIndex} + {formattedIndex}
{textIcon} diff --git a/web/app/components/datasets/create/steps-nav-bar/index.tsx b/web/app/components/datasets/create/steps-nav-bar/index.tsx index 70724a308c..b676f3ace4 100644 --- a/web/app/components/datasets/create/steps-nav-bar/index.tsx +++ b/web/app/components/datasets/create/steps-nav-bar/index.tsx @@ -49,7 +49,7 @@ const StepsNavBar = ({ key={item} className={cn(s.stepItem, s[`step${item}`], step === item && s.active, step > item && s.done, isMobile && 'px-0')} > -
{item}
+
{step > item ? '' : item}
{isMobile ? '' : t(STEP_T_MAP[item])}
))} diff --git a/web/app/components/datasets/documents/detail/completed/index.tsx b/web/app/components/datasets/documents/detail/completed/index.tsx index 195b75b0a2..0251dfa54e 100644 --- a/web/app/components/datasets/documents/detail/completed/index.tsx +++ b/web/app/components/datasets/documents/detail/completed/index.tsx @@ -24,7 +24,7 @@ import { ToastContext } from '@/app/components/base/toast' import type { Item } from '@/app/components/base/select' import { SimpleSelect } from '@/app/components/base/select' import { deleteSegment, disableSegment, enableSegment, fetchSegments, updateSegment } from '@/service/datasets' -import type { SegmentDetailModel, SegmentUpdator, SegmentsQuery, SegmentsResponse } from '@/models/datasets' +import type { SegmentDetailModel, SegmentUpdater, SegmentsQuery, SegmentsResponse } from '@/models/datasets' import { asyncRunSafe } from '@/utils' import type { CommonResponse } from '@/models/common' import AutoHeightTextarea from '@/app/components/base/auto-height-textarea/common' @@ -322,7 +322,7 @@ const Completed: FC = ({ } const handleUpdateSegment = async (segmentId: string, question: string, answer: string, keywords: string[]) => { - const params: SegmentUpdator = { content: '' } + const params: SegmentUpdater = { content: '' } if (docForm === 'qa_model') { if (!question.trim()) return notify({ type: 'error', message: t('datasetDocuments.segment.questionEmpty') }) diff --git a/web/app/components/datasets/documents/detail/embedding/index.tsx b/web/app/components/datasets/documents/detail/embedding/index.tsx index 79b031549a..1bc6c91c2a 100644 --- a/web/app/components/datasets/documents/detail/embedding/index.tsx +++ b/web/app/components/datasets/documents/detail/embedding/index.tsx @@ -18,9 +18,7 @@ import { ToastContext } from '@/app/components/base/toast' import type { FullDocumentDetail, ProcessRuleResponse } from '@/models/datasets' import type { CommonResponse } from '@/models/common' import { asyncRunSafe, sleep } from '@/utils' -import { formatNumber } from '@/utils/format' -import { fetchIndexingStatus as doFetchIndexingStatus, fetchIndexingEstimate, fetchProcessRule, pauseDocIndexing, resumeDocIndexing } from '@/service/datasets' -import DatasetDetailContext from '@/context/dataset-detail' +import { fetchIndexingStatus as doFetchIndexingStatus, fetchProcessRule, pauseDocIndexing, resumeDocIndexing } from '@/service/datasets' import StopEmbeddingModal from '@/app/components/datasets/create/stop-embedding-modal' type Props = { @@ -108,16 +106,14 @@ const RuleDetail: FC<{ sourceData?: ProcessRuleResponse; docName?: string }> = (
} -const EmbeddingDetail: FC = ({ detail, stopPosition = 'top', datasetId: dstId, documentId: docId, indexingType, detailUpdate }) => { +const EmbeddingDetail: FC = ({ detail, stopPosition = 'top', datasetId: dstId, documentId: docId, detailUpdate }) => { const onTop = stopPosition === 'top' const { t } = useTranslation() const { notify } = useContext(ToastContext) const { datasetId = '', documentId = '' } = useContext(DocumentContext) - const { indexingTechnique } = useContext(DatasetDetailContext) const localDatasetId = dstId ?? datasetId const localDocumentId = docId ?? documentId - const localIndexingTechnique = indexingType ?? indexingTechnique const [indexingStatusDetail, setIndexingStatusDetail] = useState(null) const fetchIndexingStatus = async () => { @@ -160,14 +156,6 @@ const EmbeddingDetail: FC = ({ detail, stopPosition = 'top', datasetId: d } }, [startQueryStatus, stopQueryStatus]) - const { data: indexingEstimateDetail, error: indexingEstimateErr } = useSWR({ - action: 'fetchIndexingEstimate', - datasetId: localDatasetId, - documentId: localDocumentId, - }, apiParams => fetchIndexingEstimate(omit(apiParams, 'action')), { - revalidateOnFocus: false, - }) - const { data: ruleDetail, error: ruleError } = useSWR({ action: 'fetchProcessRule', params: { documentId: localDocumentId }, @@ -250,21 +238,6 @@ const EmbeddingDetail: FC = ({ detail, stopPosition = 'top', datasetId: d
{t('datasetDocuments.embedding.segments')} {indexingStatusDetail?.completed_segments}/{indexingStatusDetail?.total_segments} · {percent}%
- {localIndexingTechnique === 'high_quaility' && ( -
-
- {t('datasetDocuments.embedding.highQuality')} · {t('datasetDocuments.embedding.estimate')} - {formatNumber(indexingEstimateDetail?.tokens || 0)}tokens - (${formatNumber(indexingEstimateDetail?.total_price || 0)}) -
- )} - {localIndexingTechnique === 'economy' && ( -
-
- {t('datasetDocuments.embedding.economy')} · {t('datasetDocuments.embedding.estimate')} - 0tokens -
- )}
{!onTop && ( diff --git a/web/app/components/datasets/documents/detail/embedding/style.module.css b/web/app/components/datasets/documents/detail/embedding/style.module.css index 6dc1a5e80b..c24444ac12 100644 --- a/web/app/components/datasets/documents/detail/embedding/style.module.css +++ b/web/app/components/datasets/documents/detail/embedding/style.module.css @@ -31,7 +31,7 @@ @apply rounded-r-md; } .progressData { - @apply w-full flex justify-between items-center text-xs text-gray-700; + @apply w-full flex items-center text-xs text-gray-700; } .previewTip { @apply pb-1 pt-12 text-gray-900 text-sm font-medium; diff --git a/web/app/components/datasets/documents/detail/new-segment-modal.tsx b/web/app/components/datasets/documents/detail/new-segment-modal.tsx index 24e0ba3cdc..dae9cf19fb 100644 --- a/web/app/components/datasets/documents/detail/new-segment-modal.tsx +++ b/web/app/components/datasets/documents/detail/new-segment-modal.tsx @@ -9,7 +9,7 @@ import Button from '@/app/components/base/button' import AutoHeightTextarea from '@/app/components/base/auto-height-textarea/common' import { Hash02 } from '@/app/components/base/icons/src/vender/line/general' import { ToastContext } from '@/app/components/base/toast' -import type { SegmentUpdator } from '@/models/datasets' +import type { SegmentUpdater } from '@/models/datasets' import { addSegment } from '@/service/datasets' import TagInput from '@/app/components/base/tag-input' @@ -42,7 +42,7 @@ const NewSegmentModal: FC = ({ } const handleSave = async () => { - const params: SegmentUpdator = { content: '' } + const params: SegmentUpdater = { content: '' } if (docForm === 'qa_model') { if (!question.trim()) return notify({ type: 'error', message: t('datasetDocuments.segment.questionEmpty') }) diff --git a/web/app/components/datasets/documents/index.tsx b/web/app/components/datasets/documents/index.tsx index 32c045eccd..81b85c8220 100644 --- a/web/app/components/datasets/documents/index.tsx +++ b/web/app/components/datasets/documents/index.tsx @@ -4,8 +4,9 @@ import React, { useMemo, useState } from 'react' import useSWR from 'swr' import { useTranslation } from 'react-i18next' import { useRouter } from 'next/navigation' -import { debounce, groupBy, omit } from 'lodash-es' +import { groupBy, omit } from 'lodash-es' import { PlusIcon } from '@heroicons/react/24/solid' +import { useDebounce } from 'ahooks' import List from './list' import s from './style.module.css' import Loading from '@/app/components/base/loading' @@ -87,9 +88,11 @@ const Documents: FC = ({ datasetId }) => { const isDataSourceFile = dataset?.data_source_type === DataSourceType.FILE const embeddingAvailable = !!dataset?.embedding_available + const debouncedSearchValue = useDebounce(searchValue, { wait: 500 }) + const query = useMemo(() => { - return { page: currPage + 1, limit, keyword: searchValue, fetch: isDataSourceNotion ? true : '' } - }, [searchValue, currPage, isDataSourceNotion]) + return { page: currPage + 1, limit, keyword: debouncedSearchValue, fetch: isDataSourceNotion ? true : '' } + }, [currPage, debouncedSearchValue, isDataSourceNotion]) const { data: documentsRes, error, mutate } = useSWR( { @@ -106,15 +109,15 @@ const Documents: FC = ({ datasetId }) => { let percent = 0 const documentsData = documentsRes?.data?.map((documentItem) => { const { indexing_status, completed_segments, total_segments } = documentItem - const isEmbeddinged = indexing_status === 'completed' || indexing_status === 'paused' || indexing_status === 'error' + const isEmbedded = indexing_status === 'completed' || indexing_status === 'paused' || indexing_status === 'error' - if (isEmbeddinged) + if (isEmbedded) completedNum++ const completedCount = completed_segments || 0 const totalCount = total_segments || 0 if (totalCount === 0 && completedCount === 0) { - percent = isEmbeddinged ? 100 : 0 + percent = isEmbedded ? 100 : 0 } else { const per = Math.round(completedCount * 100 / totalCount) @@ -204,7 +207,7 @@ const Documents: FC = ({ datasetId }) => { showLeftIcon wrapperClassName='!w-[200px]' className='!h-8 !text-[13px]' - onChange={debounce(e => setSearchValue(e.target.value), 500)} + onChange={e => setSearchValue(e.target.value)} value={searchValue} />
diff --git a/web/app/components/datasets/hit-testing/modify-retrieval-modal.tsx b/web/app/components/datasets/hit-testing/modify-retrieval-modal.tsx index be5c1be2e7..999f1cdf0d 100644 --- a/web/app/components/datasets/hit-testing/modify-retrieval-modal.tsx +++ b/web/app/components/datasets/hit-testing/modify-retrieval-modal.tsx @@ -39,14 +39,14 @@ const ModifyRetrievalModal: FC = ({ const { modelList: rerankModelList, defaultModel: rerankDefaultModel, - currentModel: isRerankDefaultModelVaild, + currentModel: isRerankDefaultModelValid, } = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.rerank) const handleSave = () => { if ( !isReRankModelSelected({ rerankDefaultModel, - isRerankDefaultModelVaild: !!isRerankDefaultModelVaild, + isRerankDefaultModelValid: !!isRerankDefaultModelValid, rerankModelList, retrievalConfig, indexMethod, diff --git a/web/app/components/datasets/settings/form/index.tsx b/web/app/components/datasets/settings/form/index.tsx index 404a8ed6a0..0f6bdd0a59 100644 --- a/web/app/components/datasets/settings/form/index.tsx +++ b/web/app/components/datasets/settings/form/index.tsx @@ -73,7 +73,7 @@ const Form = () => { const { modelList: rerankModelList, defaultModel: rerankDefaultModel, - currentModel: isRerankDefaultModelVaild, + currentModel: isRerankDefaultModelValid, } = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.rerank) const { data: embeddingModelList } = useModelList(ModelTypeEnum.textEmbedding) @@ -99,7 +99,7 @@ const Form = () => { if ( !isReRankModelSelected({ rerankDefaultModel, - isRerankDefaultModelVaild: !!isRerankDefaultModelVaild, + isRerankDefaultModelValid: !!isRerankDefaultModelValid, rerankModelList, retrievalConfig, indexMethod, diff --git a/web/app/components/develop/template/template_advanced_chat.en.mdx b/web/app/components/develop/template/template_advanced_chat.en.mdx index 6487ac79d7..655b6efce1 100644 --- a/web/app/components/develop/template/template_advanced_chat.en.mdx +++ b/web/app/components/develop/template/template_advanced_chat.en.mdx @@ -3,7 +3,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from # Advanced Chat App API -Chat applications support session persistence, allowing previous chat history to be used as context for responses. This can be applicable for chatbots, customer service AI, etc. +Chat applications support session persistence, allowing previous chat history to be used as context for responses. This can be applicable for chatbot, customer service AI, etc.
### Base URL @@ -60,7 +60,7 @@ Chat applications support session persistence, allowing previous chat history to Should be uniquely defined by the developer within the application. - Converation ID, to continue the conversation based on previous chat records, it is necessary to pass the previous message's conversation_id. + Conversation ID, to continue the conversation based on previous chat records, it is necessary to pass the previous message's conversation_id. File list, suitable for inputting files (images) combined with text understanding and answering questions, available only when the model supports Vision capability. @@ -239,7 +239,7 @@ Chat applications support session persistence, allowing previous chat history to "message_id": "9da23599-e713-473b-982c-4328d4f5c78a", "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", "mode": "chat", - "answer": "iPhone 13 Pro Max specs are listed heere:...", + "answer": "iPhone 13 Pro Max specs are listed here:...", "metadata": { "usage": { "prompt_tokens": 1033, @@ -732,7 +732,7 @@ Chat applications support session persistence, allowing previous chat history to ```bash {{ title: 'cURL' }} - curl -X DELETE '${props.appDetail.api_base_url}/conversations/{convsation_id}' \ + curl -X DELETE '${props.appDetail.api_base_url}/conversations/{conversation_id}' \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --header 'Authorization: Bearer {api_key}' \ diff --git a/web/app/components/develop/template/template_advanced_chat.zh.mdx b/web/app/components/develop/template/template_advanced_chat.zh.mdx index 33551509e5..2aa42fbb19 100755 --- a/web/app/components/develop/template/template_advanced_chat.zh.mdx +++ b/web/app/components/develop/template/template_advanced_chat.zh.mdx @@ -250,7 +250,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx' "message_id": "9da23599-e713-473b-982c-4328d4f5c78a", "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", "mode": "chat", - "answer": "iPhone 13 Pro Max specs are listed heere:...", + "answer": "iPhone 13 Pro Max specs are listed here:...", "metadata": { "usage": { "prompt_tokens": 1033, @@ -767,7 +767,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx' ```bash {{ title: 'cURL' }} - curl -X DELETE '${props.appDetail.api_base_url}/conversations/{convsation_id}' \ + curl -X DELETE '${props.appDetail.api_base_url}/conversations/{conversation_id}' \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --header 'Authorization: Bearer {api_key}' \ diff --git a/web/app/components/develop/template/template_chat.en.mdx b/web/app/components/develop/template/template_chat.en.mdx index 07840640f4..d6dfbaaaf9 100644 --- a/web/app/components/develop/template/template_chat.en.mdx +++ b/web/app/components/develop/template/template_chat.en.mdx @@ -3,7 +3,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from # Chat App API -Chat applications support session persistence, allowing previous chat history to be used as context for responses. This can be applicable for chatbots, customer service AI, etc. +Chat applications support session persistence, allowing previous chat history to be used as context for responses. This can be applicable for chatbot, customer service AI, etc.
### Base URL @@ -61,7 +61,7 @@ Chat applications support session persistence, allowing previous chat history to Should be uniquely defined by the developer within the application. - Converation ID, to continue the conversation based on previous chat records, it is necessary to pass the previous message's conversation_id. + Conversation ID, to continue the conversation based on previous chat records, it is necessary to pass the previous message's conversation_id. File list, suitable for inputting files (images) combined with text understanding and answering questions, available only when the model supports Vision capability. @@ -200,7 +200,7 @@ Chat applications support session persistence, allowing previous chat history to "message_id": "9da23599-e713-473b-982c-4328d4f5c78a", "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", "mode": "chat", - "answer": "iPhone 13 Pro Max specs are listed heere:...", + "answer": "iPhone 13 Pro Max specs are listed here:...", "metadata": { "usage": { "prompt_tokens": 1033, @@ -534,7 +534,7 @@ Chat applications support session persistence, allowing previous chat history to - `id` (string) ID - `type` (string) File type, image for images - `url` (string) Preview image URL - - `belongs_to` (string) belongs to,user orassistant + - `belongs_to` (string) belongs to,user or assistant - `agent_thoughts` (array[object]) Agent thought(Empty if it's a Basic Assistant) - `id` (string) Agent thought ID, every iteration has a unique agent thought ID - `message_id` (string) Unique message ID @@ -772,7 +772,7 @@ Chat applications support session persistence, allowing previous chat history to ```bash {{ title: 'cURL' }} - curl -X DELETE '${props.appDetail.api_base_url}/conversations/{convsation_id}' \ + curl -X DELETE '${props.appDetail.api_base_url}/conversations/{conversation_id}' \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --header 'Authorization: Bearer {api_key}' \ diff --git a/web/app/components/develop/template/template_chat.zh.mdx b/web/app/components/develop/template/template_chat.zh.mdx index 727d884c1a..a91da81a1c 100644 --- a/web/app/components/develop/template/template_chat.zh.mdx +++ b/web/app/components/develop/template/template_chat.zh.mdx @@ -213,7 +213,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx' "message_id": "9da23599-e713-473b-982c-4328d4f5c78a", "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2", "mode": "chat", - "answer": "iPhone 13 Pro Max specs are listed heere:...", + "answer": "iPhone 13 Pro Max specs are listed here:...", "metadata": { "usage": { "prompt_tokens": 1033, @@ -786,7 +786,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx' ```bash {{ title: 'cURL' }} - curl -X DELETE '${props.appDetail.api_base_url}/conversations/{convsation_id}' \ + curl -X DELETE '${props.appDetail.api_base_url}/conversations/{conversation_id}' \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --header 'Authorization: Bearer {api_key}' \ diff --git a/web/app/components/explore/app-card/index.tsx b/web/app/components/explore/app-card/index.tsx index 3d666fdb1a..b1ea4a95bf 100644 --- a/web/app/components/explore/app-card/index.tsx +++ b/web/app/components/explore/app-card/index.tsx @@ -5,7 +5,7 @@ import Button from '../../base/button' import cn from '@/utils/classnames' import type { App } from '@/models/explore' import AppIcon from '@/app/components/base/app-icon' -import { AiText, ChatBot, CuteRobote } from '@/app/components/base/icons/src/vender/solid/communication' +import { AiText, ChatBot, CuteRobot } from '@/app/components/base/icons/src/vender/solid/communication' import { Route } from '@/app/components/base/icons/src/vender/solid/mapsAndTravel' export type AppCardProps = { app: App @@ -23,7 +23,7 @@ const AppCard = ({ const { t } = useTranslation() const { app: appBasicInfo } = app return ( -
+
)} {appBasicInfo.mode === 'agent-chat' && ( - + )} {appBasicInfo.mode === 'chat' && ( @@ -64,9 +64,13 @@ const AppCard = ({
-
{app.description}
+
+
+ {app.description} +
+
{isExplore && canCreate && ( -
+
)} {!isExplore && ( -
+
+ {/* answer icon */} + {isEditModal && (appMode === 'chat' || appMode === 'advanced-chat' || appMode === 'agent-chat') && ( +
+
+
{t('app.answerIcon.title')}
+ setUseIconAsAnswerIcon(v)} + /> +
+

{t('app.answerIcon.descriptionInExplore')}

+
+ )} {!isEditModal && isAppsFull && }
diff --git a/web/app/components/header/account-dropdown/index.tsx b/web/app/components/header/account-dropdown/index.tsx index 2298bff82d..03157ed7cb 100644 --- a/web/app/components/header/account-dropdown/index.tsx +++ b/web/app/components/header/account-dropdown/index.tsx @@ -22,11 +22,11 @@ import { LanguagesSupported } from '@/i18n/language' import { useProviderContext } from '@/context/provider-context' import { Plan } from '@/app/components/billing/type' -export type IAppSelecotr = { +export type IAppSelector = { isMobile: boolean } -export default function AppSelector({ isMobile }: IAppSelecotr) { +export default function AppSelector({ isMobile }: IAppSelector) { const itemClassName = ` flex items-center w-full h-9 px-3 text-gray-700 text-[14px] rounded-lg font-normal hover:bg-gray-50 cursor-pointer @@ -125,7 +125,7 @@ export default function AppSelector({ isMobile }: IAppSelecotr) { className={classNames(itemClassName, 'group justify-between')} href='https://github.com/langgenius/dify/discussions/categories/feedbacks' target='_blank' rel='noopener noreferrer'> -
{t('common.userProfile.roadmapAndFeedback')}
+
{t('common.userProfile.communityFeedback')}
@@ -149,6 +149,15 @@ export default function AppSelector({ isMobile }: IAppSelecotr) { + + +
{t('common.userProfile.roadmap')}
+ + +
{ document?.body?.getAttribute('data-public-site-about') !== 'hide' && ( diff --git a/web/app/components/header/account-setting/account-page/index.tsx b/web/app/components/header/account-setting/account-page/index.tsx index ce7f7e7e22..eecd275b35 100644 --- a/web/app/components/header/account-setting/account-page/index.tsx +++ b/web/app/components/header/account-setting/account-page/index.tsx @@ -90,7 +90,7 @@ export default function AccountPage() { setPassword('') setConfirmPassword('') } - const handleSavePassowrd = async () => { + const handleSavePassword = async () => { if (!valid()) return try { @@ -235,7 +235,7 @@ export default function AccountPage() { diff --git a/web/app/components/header/account-setting/members-page/index.tsx b/web/app/components/header/account-setting/members-page/index.tsx index 711e772684..e09e4bbc0d 100644 --- a/web/app/components/header/account-setting/members-page/index.tsx +++ b/web/app/components/header/account-setting/members-page/index.tsx @@ -15,7 +15,7 @@ import I18n from '@/context/i18n' import { useAppContext } from '@/context/app-context' import Avatar from '@/app/components/base/avatar' import type { InvitationResult } from '@/models/common' -import LogoEmbededChatHeader from '@/app/components/base/logo/logo-embeded-chat-header' +import LogoEmbeddedChatHeader from '@/app/components/base/logo/logo-embedded-chat-header' import { useProviderContext } from '@/context/provider-context' import { Plan } from '@/app/components/billing/type' import UpgradeBtn from '@/app/components/billing/upgrade-btn' @@ -49,7 +49,7 @@ const MembersPage = () => { <>
- +
{currentWorkspace?.name}
{enableBilling && ( diff --git a/web/app/components/header/account-setting/members-page/invited-modal/index.tsx b/web/app/components/header/account-setting/members-page/invited-modal/index.tsx index 7af19b06c3..fc64d46b06 100644 --- a/web/app/components/header/account-setting/members-page/invited-modal/index.tsx +++ b/web/app/components/header/account-setting/members-page/invited-modal/index.tsx @@ -11,8 +11,8 @@ import { IS_CE_EDITION } from '@/config' import type { InvitationResult } from '@/models/common' import Tooltip from '@/app/components/base/tooltip' -export type SuccessInvationResult = Extract -export type FailedInvationResult = Extract +export type SuccessInvitationResult = Extract +export type FailedInvitationResult = Extract type IInvitedModalProps = { invitationResults: InvitationResult[] @@ -24,8 +24,8 @@ const InvitedModal = ({ }: IInvitedModalProps) => { const { t } = useTranslation() - const successInvationResults = useMemo(() => invitationResults?.filter(item => item.status === 'success') as SuccessInvationResult[], [invitationResults]) - const failedInvationResults = useMemo(() => invitationResults?.filter(item => item.status !== 'success') as FailedInvationResult[], [invitationResults]) + const successInvitationResults = useMemo(() => invitationResults?.filter(item => item.status === 'success') as SuccessInvitationResult[], [invitationResults]) + const failedInvitationResults = useMemo(() => invitationResults?.filter(item => item.status !== 'success') as FailedInvitationResult[], [invitationResults]) return (
@@ -49,20 +49,20 @@ const InvitedModal = ({
{t('common.members.invitationSentTip')}
{ - !!successInvationResults.length + !!successInvitationResults.length && <>
{t('common.members.invitationLink')}
- {successInvationResults.map(item => + {successInvitationResults.map(item => )} } { - !!failedInvationResults.length + !!failedInvitationResults.length && <> -
{t('common.members.failedinvitationEmails')}
+
{t('common.members.failedInvitationEmails')}
{ - failedInvationResults.map(item => + failedInvitationResults.map(item =>
{ const { modelProviders: providers } = useProviderContext() const setShowModelModal = useModalContextSelector(state => state.setShowModelModal) const defaultModelNotConfigured = !textGenerationDefaultModel && !embeddingsDefaultModel && !speech2textDefaultModel && !rerankDefaultModel && !ttsDefaultModel - const [configedProviders, notConfigedProviders] = useMemo(() => { - const configedProviders: ModelProvider[] = [] - const notConfigedProviders: ModelProvider[] = [] + const [configuredProviders, notConfiguredProviders] = useMemo(() => { + const configuredProviders: ModelProvider[] = [] + const notConfiguredProviders: ModelProvider[] = [] providers.forEach((provider) => { if ( @@ -47,12 +47,12 @@ const ModelProviderPage = () => { && provider.system_configuration.quota_configurations.find(item => item.quota_type === provider.system_configuration.current_quota_type) ) ) - configedProviders.push(provider) + configuredProviders.push(provider) else - notConfigedProviders.push(provider) + notConfiguredProviders.push(provider) }) - return [configedProviders, notConfigedProviders] + return [configuredProviders, notConfiguredProviders] }, [providers]) const handleOpenModal = ( @@ -110,10 +110,10 @@ const ModelProviderPage = () => { />
{ - !!configedProviders?.length && ( + !!configuredProviders?.length && (
{ - configedProviders?.map(provider => ( + configuredProviders?.map(provider => ( { ) } { - !!notConfigedProviders?.length && ( + !!notConfiguredProviders?.length && ( <>
+ {t('common.modelProvider.addMoreModelProvider')} @@ -133,7 +133,7 @@ const ModelProviderPage = () => {
{ - notConfigedProviders?.map(provider => ( + notConfiguredProviders?.map(provider => ( = ({ onChange({ ...value, [key]: val, ...shouldClearVariable }) } - // convert tooltip '\n' to
- const renderTooltipContent = (content: string) => { - return content.split('\n').map((line, index, array) => ( - - {line} - {index < array.length - 1 &&
} -
- )) - } - const renderField = (formSchema: CredentialFormSchema) => { const tooltip = formSchema.tooltip const tooltipContent = (tooltip && ( - - - {renderTooltipContent(tooltip[language] || tooltip.en_US)} -
- } > - - + + + {tooltip[language] || tooltip.en_US} +
} + triggerClassName='w-4 h-4' + /> )) if (formSchema.type === FormTypeEnum.textInput || formSchema.type === FormTypeEnum.secretInput || formSchema.type === FormTypeEnum.textNumber) { const { @@ -103,10 +91,10 @@ const Form: FC = ({ if (show_on.length && !show_on.every(showOnItem => value[showOnItem.variable] === showOnItem.value)) return null - const disabed = readonly || (isEditMode && (variable === '__model_type' || variable === '__model_name')) + const disabled = readonly || (isEditMode && (variable === '__model_type' || variable === '__model_name')) return (
-
+
{label[language] || label.en_US} { required && ( @@ -116,12 +104,12 @@ const Form: FC = ({ {tooltipContent}
handleFormChange(variable, val)} validated={validatedSuccess} placeholder={placeholder?.[language] || placeholder?.en_US} - disabled={disabed} + disabled={disabled} type={formSchema.type === FormTypeEnum.textNumber ? 'number' : 'text'} {...(formSchema.type === FormTypeEnum.textNumber ? { min: (formSchema as CredentialFormSchemaNumberInput).min, max: (formSchema as CredentialFormSchemaNumberInput).max } : {})} /> @@ -143,11 +131,11 @@ const Form: FC = ({ if (show_on.length && !show_on.every(showOnItem => value[showOnItem.variable] === showOnItem.value)) return null - const disabed = isEditMode && (variable === '__model_type' || variable === '__model_name') + const disabled = isEditMode && (variable === '__model_type' || variable === '__model_name') return (
-
+
{label[language] || label.en_US} { required && ( @@ -168,7 +156,7 @@ const Form: FC = ({ className={` flex items-center px-3 py-2 rounded-lg border border-gray-100 bg-gray-25 cursor-pointer ${value[variable] === option.value && 'bg-white border-[1.5px] border-primary-400 shadow-sm'} - ${disabed && '!cursor-not-allowed opacity-60'} + ${disabled && '!cursor-not-allowed opacity-60'} `} onClick={() => handleFormChange(variable, option.value)} key={`${variable}-${option.value}`} @@ -203,7 +191,7 @@ const Form: FC = ({ return (
-
+
{label[language] || label.en_US} { @@ -247,7 +235,7 @@ const Form: FC = ({
- {label[language] || label.en_US} + {label[language] || label.en_US} { required && ( * diff --git a/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/parameter-item.tsx b/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/parameter-item.tsx index e60ef418ed..376a08c120 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/parameter-item.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/parameter-item.tsx @@ -127,12 +127,10 @@ const ParameterItem: FC = ({ && !isNullOrUndefined(parameterRule.min) && !isNullOrUndefined(parameterRule.max) - if (parameterRule.type === 'int' || parameterRule.type === 'float') { + if (parameterRule.type === 'int') { let step = 100 if (parameterRule.max) { - if (parameterRule.max < 10) - step = 0.1 - else if (parameterRule.max < 100) + if (parameterRule.max < 100) step = 1 else if (parameterRule.max < 1000) step = 10 @@ -164,6 +162,31 @@ const ParameterItem: FC = ({ ) } + if (parameterRule.type === 'float') { + return ( + <> + {numberInputWithSlide && } + + + ) + } + if (parameterRule.type === 'boolean') { return ( = ({ const customConfig = provider.custom_configuration const systemConfig = provider.system_configuration const priorityUseType = provider.preferred_provider_type - const customConfiged = customConfig.status === CustomConfigurationStatusEnum.active + const isCustomConfigured = customConfig.status === CustomConfigurationStatusEnum.active const configurateMethods = provider.configurate_methods const handleChangePriority = async (key: PreferredProviderTypeEnum) => { @@ -69,7 +69,7 @@ const CredentialPanel: FC = ({
API-KEY - +
{ - systemConfig.enabled && customConfiged && ( + systemConfig.enabled && isCustomConfigured && ( = ({ ) } { - systemConfig.enabled && customConfiged && !provider.provider_credential_schema && ( + systemConfig.enabled && isCustomConfigured && !provider.provider_credential_schema && (
{ const { t } = useTranslation() const selectedSegment = useSelectedLayoutSegment() - const actived = selectedSegment === 'explore' + const activated = selectedSegment === 'explore' return ( { - actived + activated ? : } diff --git a/web/app/components/header/nav/index.tsx b/web/app/components/header/nav/index.tsx index 1ea36c5123..bfb4324320 100644 --- a/web/app/components/header/nav/index.tsx +++ b/web/app/components/header/nav/index.tsx @@ -34,21 +34,21 @@ const Nav = ({ const setAppDetail = useAppStore(state => state.setAppDetail) const [hovered, setHovered] = useState(false) const segment = useSelectedLayoutSegment() - const isActived = Array.isArray(activeSegment) ? activeSegment.includes(segment!) : segment === activeSegment + const isActivated = Array.isArray(activeSegment) ? activeSegment.includes(segment!) : segment === activeSegment return (
setAppDetail()} className={classNames(` flex items-center h-7 px-2.5 cursor-pointer rounded-[10px] - ${isActived ? 'text-components-main-nav-nav-button-text-active' : 'text-components-main-nav-nav-button-text'} - ${curNav && isActived && 'hover:bg-components-main-nav-nav-button-bg-active-hover'} + ${isActivated ? 'text-components-main-nav-nav-button-text-active' : 'text-components-main-nav-nav-button-text'} + ${curNav && isActivated && 'hover:bg-components-main-nav-nav-button-bg-active-hover'} `)} onMouseEnter={() => setHovered(true)} onMouseLeave={() => setHovered(false)} @@ -57,7 +57,7 @@ const Nav = ({ { (hovered && curNav) ? - : isActived + : isActivated ? activeIcon : icon } @@ -66,7 +66,7 @@ const Nav = ({
{ - curNav && isActived && ( + curNav && isActivated && ( <>
/
)} {nav.mode === 'agent-chat' && ( - + )} {nav.mode === 'chat' && ( diff --git a/web/app/components/header/tools-nav/index.tsx b/web/app/components/header/tools-nav/index.tsx index 5184f5e5ce..096a552229 100644 --- a/web/app/components/header/tools-nav/index.tsx +++ b/web/app/components/header/tools-nav/index.tsx @@ -17,16 +17,16 @@ const ToolsNav = ({ }: ToolsNavProps) => { const { t } = useTranslation() const selectedSegment = useSelectedLayoutSegment() - const actived = selectedSegment === 'tools' + const activated = selectedSegment === 'tools' return ( { - actived + activated ? : } diff --git a/web/app/components/share/text-generation/index.tsx b/web/app/components/share/text-generation/index.tsx index dd6efa86fa..a2f6864242 100644 --- a/web/app/components/share/text-generation/index.tsx +++ b/web/app/components/share/text-generation/index.tsx @@ -163,8 +163,8 @@ const TextGeneration: FC = ({ } const allSuccessTaskList = allTaskList.filter(task => task.status === TaskStatus.completed) const allFailedTaskList = allTaskList.filter(task => task.status === TaskStatus.failed) - const allTaskFinished = allTaskList.every(task => task.status === TaskStatus.completed) - const allTaskRuned = allTaskList.every(task => [TaskStatus.completed, TaskStatus.failed].includes(task.status)) + const allTasksFinished = allTaskList.every(task => task.status === TaskStatus.completed) + const allTasksRun = allTaskList.every(task => [TaskStatus.completed, TaskStatus.failed].includes(task.status)) const [batchCompletionRes, doSetBatchCompletionRes] = useState>({}) const batchCompletionResRef = useRef>({}) const setBatchCompletionRes = (res: Record) => { @@ -286,7 +286,7 @@ const TextGeneration: FC = ({ const handleRunBatch = (data: string[][]) => { if (!checkBatchInputs(data)) return - if (!allTaskFinished) { + if (!allTasksFinished) { notify({ type: 'info', message: t('appDebug.errorMessage.waitForBatchResponse') }) return } @@ -318,17 +318,17 @@ const TextGeneration: FC = ({ showResSidebar() } const handleCompleted = (completionRes: string, taskId?: number, isSuccess?: boolean) => { - const allTasklistLatest = getLatestTaskList() + const allTaskListLatest = getLatestTaskList() const batchCompletionResLatest = getBatchCompletionRes() - const pendingTaskList = allTasklistLatest.filter(task => task.status === TaskStatus.pending) - const hadRunedTaskNum = 1 + allTasklistLatest.filter(task => [TaskStatus.completed, TaskStatus.failed].includes(task.status)).length - const needToAddNextGroupTask = (getCurrGroupNum() !== hadRunedTaskNum) && pendingTaskList.length > 0 && (hadRunedTaskNum % GROUP_SIZE === 0 || (allTasklistLatest.length - hadRunedTaskNum < GROUP_SIZE)) + const pendingTaskList = allTaskListLatest.filter(task => task.status === TaskStatus.pending) + const runTasksCount = 1 + allTaskListLatest.filter(task => [TaskStatus.completed, TaskStatus.failed].includes(task.status)).length + const needToAddNextGroupTask = (getCurrGroupNum() !== runTasksCount) && pendingTaskList.length > 0 && (runTasksCount % GROUP_SIZE === 0 || (allTaskListLatest.length - runTasksCount < GROUP_SIZE)) // avoid add many task at the same time if (needToAddNextGroupTask) - setCurrGroupNum(hadRunedTaskNum) + setCurrGroupNum(runTasksCount) const nextPendingTaskIds = needToAddNextGroupTask ? pendingTaskList.slice(0, GROUP_SIZE).map(item => item.id) : [] - const newAllTaskList = allTasklistLatest.map((item) => { + const newAllTaskList = allTaskListLatest.map((item) => { if (item.id === taskId) { return { ...item, @@ -393,7 +393,7 @@ const TextGeneration: FC = ({ }) const prompt_variables = userInputsFormToPromptVariables(user_input_form) setPromptConfig({ - prompt_template: '', // placeholder for feture + prompt_template: '', // placeholder for future prompt_variables, } as PromptConfig) setMoreLikeThisConfig(more_like_this) @@ -587,7 +587,7 @@ const TextGeneration: FC = ({ isRight: true, extra: savedMessages.length > 0 ? ( -
+
{savedMessages.length}
) @@ -614,7 +614,7 @@ const TextGeneration: FC = ({
diff --git a/web/app/components/share/text-generation/result/content.tsx b/web/app/components/share/text-generation/result/content.tsx index 17cce0fae5..4e39db42c8 100644 --- a/web/app/components/share/text-generation/result/content.tsx +++ b/web/app/components/share/text-generation/result/content.tsx @@ -1,14 +1,14 @@ import type { FC } from 'react' import React from 'react' import Header from './header' -import type { Feedbacktype } from '@/app/components/base/chat/chat/type' +import type { FeedbackType } from '@/app/components/base/chat/chat/type' import { format } from '@/service/base' export type IResultProps = { content: string showFeedback: boolean - feedback: Feedbacktype - onFeedback: (feedback: Feedbacktype) => void + feedback: FeedbackType + onFeedback: (feedback: FeedbackType) => void } const Result: FC = ({ content, diff --git a/web/app/components/share/text-generation/result/header.tsx b/web/app/components/share/text-generation/result/header.tsx index bd5c317153..0233b098d0 100644 --- a/web/app/components/share/text-generation/result/header.tsx +++ b/web/app/components/share/text-generation/result/header.tsx @@ -4,7 +4,7 @@ import React from 'react' import { useTranslation } from 'react-i18next' import { ClipboardDocumentIcon, HandThumbDownIcon, HandThumbUpIcon } from '@heroicons/react/24/outline' import copy from 'copy-to-clipboard' -import type { Feedbacktype } from '@/app/components/base/chat/chat/type' +import type { FeedbackType } from '@/app/components/base/chat/chat/type' import Button from '@/app/components/base/button' import Toast from '@/app/components/base/toast' import Tooltip from '@/app/components/base/tooltip' @@ -12,8 +12,8 @@ import Tooltip from '@/app/components/base/tooltip' type IResultHeaderProps = { result: string showFeedback: boolean - feedback: Feedbacktype - onFeedback: (feedback: Feedbacktype) => void + feedback: FeedbackType + onFeedback: (feedback: FeedbackType) => void } const Header: FC = ({ diff --git a/web/app/components/share/text-generation/result/index.tsx b/web/app/components/share/text-generation/result/index.tsx index caa2f9183e..021a98d4d3 100644 --- a/web/app/components/share/text-generation/result/index.tsx +++ b/web/app/components/share/text-generation/result/index.tsx @@ -9,7 +9,7 @@ import TextGenerationRes from '@/app/components/app/text-generate/item' import NoData from '@/app/components/share/text-generation/no-data' import Toast from '@/app/components/base/toast' import { sendCompletionMessage, sendWorkflowMessage, updateFeedback } from '@/service/share' -import type { Feedbacktype } from '@/app/components/base/chat/chat/type' +import type { FeedbackType } from '@/app/components/base/chat/chat/type' import Loading from '@/app/components/base/loading' import type { PromptConfig } from '@/models/debug' import type { InstalledApp } from '@/models/explore' @@ -83,23 +83,23 @@ const Result: FC = ({ doSetCompletionRes(res) } const getCompletionRes = () => completionResRef.current - const [workflowProcessData, doSetWorkflowProccessData] = useState() + const [workflowProcessData, doSetWorkflowProcessData] = useState() const workflowProcessDataRef = useRef() - const setWorkflowProccessData = (data: WorkflowProcess) => { + const setWorkflowProcessData = (data: WorkflowProcess) => { workflowProcessDataRef.current = data - doSetWorkflowProccessData(data) + doSetWorkflowProcessData(data) } - const getWorkflowProccessData = () => workflowProcessDataRef.current + const getWorkflowProcessData = () => workflowProcessDataRef.current const { notify } = Toast const isNoData = !completionRes const [messageId, setMessageId] = useState(null) - const [feedback, setFeedback] = useState({ + const [feedback, setFeedback] = useState({ rating: null, }) - const handleFeedback = async (feedback: Feedbacktype) => { + const handleFeedback = async (feedback: FeedbackType) => { await updateFeedback({ url: `/messages/${messageId}/feedbacks`, body: { rating: feedback.rating } }, isInstalledApp, installedAppInfo?.id) setFeedback(feedback) } @@ -203,7 +203,7 @@ const Result: FC = ({ { onWorkflowStarted: ({ workflow_run_id }) => { tempMessageId = workflow_run_id - setWorkflowProccessData({ + setWorkflowProcessData({ status: WorkflowRunningStatus.Running, tracing: [], expand: false, @@ -211,7 +211,7 @@ const Result: FC = ({ }) }, onIterationStart: ({ data }) => { - setWorkflowProccessData(produce(getWorkflowProccessData()!, (draft) => { + setWorkflowProcessData(produce(getWorkflowProcessData()!, (draft) => { draft.expand = true draft.tracing!.push({ ...data, @@ -224,7 +224,7 @@ const Result: FC = ({ onIterationNext: () => { }, onIterationFinish: ({ data }) => { - setWorkflowProccessData(produce(getWorkflowProccessData()!, (draft) => { + setWorkflowProcessData(produce(getWorkflowProcessData()!, (draft) => { draft.expand = true // const iteration = draft.tracing![draft.tracing!.length - 1] draft.tracing![draft.tracing!.length - 1] = { @@ -238,7 +238,7 @@ const Result: FC = ({ if (isInIteration) return - setWorkflowProccessData(produce(getWorkflowProccessData()!, (draft) => { + setWorkflowProcessData(produce(getWorkflowProcessData()!, (draft) => { draft.expand = true draft.tracing!.push({ ...data, @@ -251,7 +251,7 @@ const Result: FC = ({ if (isInIteration) return - setWorkflowProccessData(produce(getWorkflowProccessData()!, (draft) => { + setWorkflowProcessData(produce(getWorkflowProcessData()!, (draft) => { const currentIndex = draft.tracing!.findIndex(trace => trace.node_id === data.node_id) if (currentIndex > -1 && draft.tracing) { draft.tracing[currentIndex] = { @@ -269,7 +269,7 @@ const Result: FC = ({ return if (data.error) { notify({ type: 'error', message: data.error }) - setWorkflowProccessData(produce(getWorkflowProccessData()!, (draft) => { + setWorkflowProcessData(produce(getWorkflowProcessData()!, (draft) => { draft.status = WorkflowRunningStatus.Failed })) setRespondingFalse() @@ -277,7 +277,7 @@ const Result: FC = ({ isEnd = true return } - setWorkflowProccessData(produce(getWorkflowProccessData()!, (draft) => { + setWorkflowProcessData(produce(getWorkflowProcessData()!, (draft) => { draft.status = WorkflowRunningStatus.Succeeded })) if (!data.outputs) { @@ -287,7 +287,7 @@ const Result: FC = ({ setCompletionRes(data.outputs) const isStringOutput = Object.keys(data.outputs).length === 1 && typeof data.outputs[Object.keys(data.outputs)[0]] === 'string' if (isStringOutput) { - setWorkflowProccessData(produce(getWorkflowProccessData()!, (draft) => { + setWorkflowProcessData(produce(getWorkflowProcessData()!, (draft) => { draft.resultText = data.outputs[Object.keys(data.outputs)[0]] })) } @@ -299,13 +299,13 @@ const Result: FC = ({ }, onTextChunk: (params) => { const { data: { text } } = params - setWorkflowProccessData(produce(getWorkflowProccessData()!, (draft) => { + setWorkflowProcessData(produce(getWorkflowProcessData()!, (draft) => { draft.resultText += text })) }, onTextReplace: (params) => { const { data: { text } } = params - setWorkflowProccessData(produce(getWorkflowProccessData()!, (draft) => { + setWorkflowProcessData(produce(getWorkflowProcessData()!, (draft) => { draft.resultText = text })) }, diff --git a/web/app/components/tools/add-tool-modal/category.tsx b/web/app/components/tools/add-tool-modal/category.tsx index cc2c325410..a18c30ad54 100644 --- a/web/app/components/tools/add-tool-modal/category.tsx +++ b/web/app/components/tools/add-tool-modal/category.tsx @@ -17,7 +17,7 @@ type Props = { const Icon = ({ svgString, active }: { svgString: string; active: boolean }) => { const svgRef = useRef(null) - const SVGParsor = (svg: string) => { + const SVGParser = (svg: string) => { if (!svg) return null const parser = new DOMParser() @@ -25,7 +25,7 @@ const Icon = ({ svgString, active }: { svgString: string; active: boolean }) => return doc.documentElement } useMount(() => { - const svgElement = SVGParsor(svgString) + const svgElement = SVGParser(svgString) if (svgRef.current && svgElement) svgRef.current.appendChild(svgElement) }) diff --git a/web/app/components/workflow/custom-edge.tsx b/web/app/components/workflow/custom-edge.tsx index 5e945790d8..68e2ef945e 100644 --- a/web/app/components/workflow/custom-edge.tsx +++ b/web/app/components/workflow/custom-edge.tsx @@ -79,7 +79,7 @@ const CustomEdge = ({ id={id} path={edgePath} style={{ - stroke: (selected || data?._connectedNodeIsHovering || data?._runned) ? '#2970FF' : '#D0D5DD', + stroke: (selected || data?._connectedNodeIsHovering || data?._run) ? '#2970FF' : '#D0D5DD', strokeWidth: 2, }} /> diff --git a/web/app/components/workflow/header/checklist.tsx b/web/app/components/workflow/header/checklist.tsx index 7de9cfa2f4..6a9a6a6b9f 100644 --- a/web/app/components/workflow/header/checklist.tsx +++ b/web/app/components/workflow/header/checklist.tsx @@ -125,7 +125,7 @@ const WorkflowChecklist = ({
- {t('workflow.common.needConnecttip')} + {t('workflow.common.needConnectTip')}
) diff --git a/web/app/components/workflow/header/view-history.tsx b/web/app/components/workflow/header/view-history.tsx index 06eebfd329..a18ddad65d 100644 --- a/web/app/components/workflow/header/view-history.tsx +++ b/web/app/components/workflow/header/view-history.tsx @@ -32,7 +32,7 @@ import { } from '@/app/components/base/icons/src/vender/line/time' import { AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback' import { - fetcChatRunHistory, + fetchChatRunHistory, fetchWorkflowRunHistory, } from '@/service/workflow' import Loading from '@/app/components/base/loading' @@ -67,7 +67,7 @@ const ViewHistory = ({ const historyWorkflowData = useStore(s => s.historyWorkflowData) const { handleBackupDraft } = useWorkflowRun() const { data: runList, isLoading: runListLoading } = useSWR((appDetail && !isChatMode && open) ? `/apps/${appDetail.id}/workflow-runs` : null, fetchWorkflowRunHistory) - const { data: chatList, isLoading: chatListLoading } = useSWR((appDetail && isChatMode && open) ? `/apps/${appDetail.id}/advanced-chat/workflow-runs` : null, fetcChatRunHistory) + const { data: chatList, isLoading: chatListLoading } = useSWR((appDetail && isChatMode && open) ? `/apps/${appDetail.id}/advanced-chat/workflow-runs` : null, fetchChatRunHistory) const data = isChatMode ? chatList : runList const isLoading = isChatMode ? chatListLoading : runListLoading diff --git a/web/app/components/workflow/hooks/use-checklist.ts b/web/app/components/workflow/hooks/use-checklist.ts index 7f45769acd..36201ddfef 100644 --- a/web/app/components/workflow/hooks/use-checklist.ts +++ b/web/app/components/workflow/hooks/use-checklist.ts @@ -138,7 +138,7 @@ export const useChecklistBeforePublish = () => { } if (!validNodes.find(n => n.id === node.id)) { - notify({ type: 'error', message: `[${node.data.title}] ${t('workflow.common.needConnecttip')}` }) + notify({ type: 'error', message: `[${node.data.title}] ${t('workflow.common.needConnectTip')}` }) return false } } diff --git a/web/app/components/workflow/hooks/use-edges-interactions.ts b/web/app/components/workflow/hooks/use-edges-interactions.ts index bc3fb0e8bf..a97b65134f 100644 --- a/web/app/components/workflow/hooks/use-edges-interactions.ts +++ b/web/app/components/workflow/hooks/use-edges-interactions.ts @@ -155,7 +155,7 @@ export const useEdgesInteractions = () => { const newEdges = produce(edges, (draft) => { draft.forEach((edge) => { - edge.data._runned = false + edge.data._run = false }) }) setEdges(newEdges) diff --git a/web/app/components/workflow/hooks/use-workflow-interactions.ts b/web/app/components/workflow/hooks/use-workflow-interactions.ts index 47b8a30a5a..b39a3d8014 100644 --- a/web/app/components/workflow/hooks/use-workflow-interactions.ts +++ b/web/app/components/workflow/hooks/use-workflow-interactions.ts @@ -10,7 +10,7 @@ import { CUSTOM_NODE, DSL_EXPORT_CHECK, WORKFLOW_DATA_UPDATE, } from '../constants' -import type { Node, WorkflowDataUpdator } from '../types' +import type { Node, WorkflowDataUpdater } from '../types' import { ControlMode } from '../types' import { getLayoutByDagre, @@ -208,7 +208,7 @@ export const useWorkflowUpdate = () => { const workflowStore = useWorkflowStore() const { eventEmitter } = useEventEmitterContextContext() - const handleUpdateWorkflowCanvas = useCallback((payload: WorkflowDataUpdator) => { + const handleUpdateWorkflowCanvas = useCallback((payload: WorkflowDataUpdater) => { const { nodes, edges, @@ -236,7 +236,7 @@ export const useWorkflowUpdate = () => { } = workflowStore.getState() setIsSyncingWorkflowDraft(true) fetchWorkflowDraft(`/apps/${appId}/workflows/draft`).then((response) => { - handleUpdateWorkflowCanvas(response.graph as WorkflowDataUpdator) + handleUpdateWorkflowCanvas(response.graph as WorkflowDataUpdater) setSyncWorkflowDraftHash(response.hash) setEnvSecrets((response.environment_variables || []).filter(env => env.value_type === 'secret').reduce((acc, env) => { acc[env.id] = env.value diff --git a/web/app/components/workflow/hooks/use-workflow-run.ts b/web/app/components/workflow/hooks/use-workflow-run.ts index 96f6557fe0..a872aee398 100644 --- a/web/app/components/workflow/hooks/use-workflow-run.ts +++ b/web/app/components/workflow/hooks/use-workflow-run.ts @@ -186,7 +186,7 @@ export const useWorkflowRun = () => { draft.forEach((edge) => { edge.data = { ...edge.data, - _runned: false, + _run: false, } }) }) @@ -292,7 +292,7 @@ export const useWorkflowRun = () => { const edge = draft.find(edge => edge.target === data.node_id && edge.source === prevNodeId) if (edge) - edge.data = { ...edge.data, _runned: true } as any + edge.data = { ...edge.data, _run: true } as any }) setEdges(newEdges) } @@ -398,7 +398,7 @@ export const useWorkflowRun = () => { const edge = draft.find(edge => edge.target === data.node_id && edge.source === prevNodeId) if (edge) - edge.data = { ...edge.data, _runned: true } as any + edge.data = { ...edge.data, _run: true } as any }) setEdges(newEdges) diff --git a/web/app/components/workflow/nodes/_base/components/before-run-form/form-item.tsx b/web/app/components/workflow/nodes/_base/components/before-run-form/form-item.tsx index cde437c4c5..603368a4b3 100644 --- a/web/app/components/workflow/nodes/_base/components/before-run-form/form-item.tsx +++ b/web/app/components/workflow/nodes/_base/components/before-run-form/form-item.tsx @@ -104,7 +104,7 @@ const FormItem: FC = ({ type="text" value={value || ''} onChange={e => onChange(e.target.value)} - placeholder={t('appDebug.variableConig.inputPlaceholder')!} + placeholder={t('appDebug.variableConfig.inputPlaceholder')!} autoFocus={autoFocus} /> ) @@ -117,7 +117,7 @@ const FormItem: FC = ({ type="number" value={value || ''} onChange={e => onChange(e.target.value)} - placeholder={t('appDebug.variableConig.inputPlaceholder')!} + placeholder={t('appDebug.variableConfig.inputPlaceholder')!} autoFocus={autoFocus} /> ) @@ -129,7 +129,7 @@ const FormItem: FC = ({ className="w-full px-3 py-1 text-sm leading-[18px] text-gray-900 border-0 rounded-lg grow h-[120px] bg-gray-50 focus:outline-none focus:ring-1 focus:ring-inset focus:ring-gray-200" value={value || ''} onChange={e => onChange(e.target.value)} - placeholder={t('appDebug.variableConig.inputPlaceholder')!} + placeholder={t('appDebug.variableConfig.inputPlaceholder')!} autoFocus={autoFocus} /> ) @@ -207,7 +207,7 @@ const FormItem: FC = ({ key={index} isInNode value={item} - title={{t('appDebug.variableConig.content')} {index + 1} } + title={{t('appDebug.variableConfig.content')} {index + 1} } onChange={handleArrayItemChange(index)} headerRight={ (value as any).length > 1 diff --git a/web/app/components/workflow/nodes/_base/components/next-step/line.tsx b/web/app/components/workflow/nodes/_base/components/next-step/line.tsx index ccf4e8d730..b06a02c158 100644 --- a/web/app/components/workflow/nodes/_base/components/next-step/line.tsx +++ b/web/app/components/workflow/nodes/_base/components/next-step/line.tsx @@ -20,14 +20,14 @@ const Line = ({ d='M0,18 L24,18' strokeWidth={1} fill='none' - className='stroke-divider-soild' + className='stroke-divider-solid' /> ) @@ -38,7 +38,7 @@ const Line = ({ d={`M0,18 Q12,18 12,28 L12,${index * 48 + 18 - 10} Q12,${index * 48 + 18} 24,${index * 48 + 18}`} strokeWidth={1} fill='none' - className='stroke-divider-soild' + className='stroke-divider-solid' /> ) } @@ -47,7 +47,7 @@ const Line = ({ y={index * 48 + 18 - 2} width={1} height={4} - className='fill-divider-soild-alt' + className='fill-divider-solid-alt' /> )) diff --git a/web/app/components/workflow/nodes/_base/hooks/use-resize-panel.ts b/web/app/components/workflow/nodes/_base/hooks/use-resize-panel.ts index 1a521cd58f..f2259a02cf 100644 --- a/web/app/components/workflow/nodes/_base/hooks/use-resize-panel.ts +++ b/web/app/components/workflow/nodes/_base/hooks/use-resize-panel.ts @@ -5,7 +5,7 @@ import { useState, } from 'react' -export type UseResizePanelPrarams = { +export type UseResizePanelParams = { direction?: 'horizontal' | 'vertical' | 'both' triggerDirection?: 'top' | 'right' | 'bottom' | 'left' | 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' minWidth?: number @@ -15,7 +15,7 @@ export type UseResizePanelPrarams = { onResized?: (width: number, height: number) => void onResize?: (width: number, height: number) => void } -export const useResizePanel = (params?: UseResizePanelPrarams) => { +export const useResizePanel = (params?: UseResizePanelParams) => { const { direction = 'both', triggerDirection = 'bottom-right', diff --git a/web/app/components/workflow/nodes/if-else/types.ts b/web/app/components/workflow/nodes/if-else/types.ts index 693dce1784..e67bee2fdc 100644 --- a/web/app/components/workflow/nodes/if-else/types.ts +++ b/web/app/components/workflow/nodes/if-else/types.ts @@ -28,6 +28,7 @@ export enum ComparisonOperator { lessThanOrEqual = '≤', isNull = 'is null', isNotNull = 'is not null', + regexMatch = 'regex match', } export type Condition = { diff --git a/web/app/components/workflow/nodes/if-else/utils.ts b/web/app/components/workflow/nodes/if-else/utils.ts index ffb6758bba..b71a3a57ca 100644 --- a/web/app/components/workflow/nodes/if-else/utils.ts +++ b/web/app/components/workflow/nodes/if-else/utils.ts @@ -30,6 +30,7 @@ export const getOperators = (type?: VarType) => { ComparisonOperator.isNot, ComparisonOperator.empty, ComparisonOperator.notEmpty, + ComparisonOperator.regexMatch, ] case VarType.number: return [ diff --git a/web/app/components/workflow/nodes/knowledge-retrieval/components/retrieval-config.tsx b/web/app/components/workflow/nodes/knowledge-retrieval/components/retrieval-config.tsx index ebe9d2151e..b335b62e33 100644 --- a/web/app/components/workflow/nodes/knowledge-retrieval/components/retrieval-config.tsx +++ b/web/app/components/workflow/nodes/knowledge-retrieval/components/retrieval-config.tsx @@ -70,7 +70,7 @@ const RetrievalConfig: FC = ({ } onMultipleRetrievalConfigChange({ top_k: configs.top_k, - score_threshold: configs.score_threshold_enabled ? (configs.score_threshold || DATASET_DEFAULT.score_threshold) : null, + score_threshold: configs.score_threshold_enabled ? (configs.score_threshold ?? DATASET_DEFAULT.score_threshold) : null, reranking_model: payload.retrieval_mode === RETRIEVE_TYPE.oneWay ? undefined : (!configs.reranking_model?.reranking_provider_name diff --git a/web/app/components/workflow/nodes/llm/default.ts b/web/app/components/workflow/nodes/llm/default.ts index 803add6f00..d7597942e5 100644 --- a/web/app/components/workflow/nodes/llm/default.ts +++ b/web/app/components/workflow/nodes/llm/default.ts @@ -44,7 +44,7 @@ const nodeDefault: NodeDefault = { if (!errorMessages && !payload.memory) { const isChatModel = payload.model.mode === 'chat' - const isPromptyEmpty = isChatModel + const isPromptEmpty = isChatModel ? !(payload.prompt_template as PromptItem[]).some((t) => { if (t.edition_type === EditionType.jinja2) return t.jinja2_text !== '' @@ -52,7 +52,7 @@ const nodeDefault: NodeDefault = { return t.text !== '' }) : ((payload.prompt_template as PromptItem).edition_type === EditionType.jinja2 ? (payload.prompt_template as PromptItem).jinja2_text === '' : (payload.prompt_template as PromptItem).text === '') - if (isPromptyEmpty) + if (isPromptEmpty) errorMessages = t(`${i18nPrefix}.fieldRequired`, { field: t('workflow.nodes.llm.prompt') }) } diff --git a/web/app/components/workflow/nodes/parameter-extractor/components/extract-parameter/update.tsx b/web/app/components/workflow/nodes/parameter-extractor/components/extract-parameter/update.tsx index 2ac331558b..081a683234 100644 --- a/web/app/components/workflow/nodes/parameter-extractor/components/extract-parameter/update.tsx +++ b/web/app/components/workflow/nodes/parameter-extractor/components/extract-parameter/update.tsx @@ -99,7 +99,7 @@ const AddExtractParameter: FC = ({ if (!param.name) errMessage = t(`${errorI18nPrefix}.fieldRequired`, { field: t(`${i18nPrefix}.addExtractParameterContent.name`) }) if (!errMessage && param.type === ParamType.select && (!param.options || param.options.length === 0)) - errMessage = t(`${errorI18nPrefix}.fieldRequired`, { field: t('appDebug.variableConig.options') }) + errMessage = t(`${errorI18nPrefix}.fieldRequired`, { field: t('appDebug.variableConfig.options') }) if (!errMessage && !param.description) errMessage = t(`${errorI18nPrefix}.fieldRequired`, { field: t(`${i18nPrefix}.addExtractParameterContent.description`) }) @@ -160,7 +160,7 @@ const AddExtractParameter: FC = ({ /> {param.type === ParamType.select && ( - + )} diff --git a/web/app/components/workflow/panel/chat-record/index.tsx b/web/app/components/workflow/panel/chat-record/index.tsx index 2ab3165c14..afd20b7358 100644 --- a/web/app/components/workflow/panel/chat-record/index.tsx +++ b/web/app/components/workflow/panel/chat-record/index.tsx @@ -103,9 +103,9 @@ const ChatRecord = () => { } as any} chatList={chatMessageList} chatContainerClassName='px-4' - chatContainerInnerClassName='pt-6' + chatContainerInnerClassName='pt-6 w-full max-w-full mx-auto' chatFooterClassName='px-4 rounded-b-2xl' - chatFooterInnerClassName='pb-4' + chatFooterInnerClassName='pb-4 w-full max-w-full mx-auto' chatNode={} noChatInput allToolIcons={{}} diff --git a/web/app/components/workflow/panel/debug-and-preview/chat-wrapper.tsx b/web/app/components/workflow/panel/debug-and-preview/chat-wrapper.tsx index 4655940037..e7639ddc79 100644 --- a/web/app/components/workflow/panel/debug-and-preview/chat-wrapper.tsx +++ b/web/app/components/workflow/panel/debug-and-preview/chat-wrapper.tsx @@ -103,9 +103,9 @@ const ChatWrapper = forwardRef(({ showConv chatList={chatList} isResponding={isResponding} chatContainerClassName='px-3' - chatContainerInnerClassName='pt-6' + chatContainerInnerClassName='pt-6 w-full max-w-full mx-auto' chatFooterClassName='px-4 rounded-bl-2xl' - chatFooterInnerClassName='pb-4' + chatFooterInnerClassName='pb-4 w-full max-w-full mx-auto' onSend={doSend} onStopResponding={handleStop} chatNode={( diff --git a/web/app/components/workflow/panel/debug-and-preview/hooks.ts b/web/app/components/workflow/panel/debug-and-preview/hooks.ts index 155d2a84ac..54d3915a13 100644 --- a/web/app/components/workflow/panel/debug-and-preview/hooks.ts +++ b/web/app/components/workflow/panel/debug-and-preview/hooks.ts @@ -248,11 +248,16 @@ export const useChat = ( } if (config?.suggested_questions_after_answer?.enabled && !hasStopResponded.current && onGetSuggestedQuestions) { - const { data }: any = await onGetSuggestedQuestions( - responseItem.id, - newAbortController => suggestedQuestionsAbortControllerRef.current = newAbortController, - ) - setSuggestQuestions(data) + try { + const { data }: any = await onGetSuggestedQuestions( + responseItem.id, + newAbortController => suggestedQuestionsAbortControllerRef.current = newAbortController, + ) + setSuggestQuestions(data) + } + catch (error) { + setSuggestQuestions([]) + } } }, onMessageEnd: (messageEnd) => { diff --git a/web/app/components/workflow/panel/debug-and-preview/index.tsx b/web/app/components/workflow/panel/debug-and-preview/index.tsx index 29fc48f896..8e1c489098 100644 --- a/web/app/components/workflow/panel/debug-and-preview/index.tsx +++ b/web/app/components/workflow/panel/debug-and-preview/index.tsx @@ -88,7 +88,6 @@ const DebugAndPreview = () => { - {expanded &&
}
)}
diff --git a/web/app/components/workflow/panel/record.tsx b/web/app/components/workflow/panel/record.tsx index 079dd2cc86..d79f1a9439 100644 --- a/web/app/components/workflow/panel/record.tsx +++ b/web/app/components/workflow/panel/record.tsx @@ -1,5 +1,5 @@ import { memo, useCallback } from 'react' -import type { WorkflowDataUpdator } from '../types' +import type { WorkflowDataUpdater } from '../types' import Run from '../run' import { useStore } from '../store' import { useWorkflowUpdate } from '../hooks' @@ -9,7 +9,7 @@ const Record = () => { const { handleUpdateWorkflowCanvas } = useWorkflowUpdate() const handleResultCallback = useCallback((res: any) => { - const graph: WorkflowDataUpdator = res.graph + const graph: WorkflowDataUpdater = res.graph handleUpdateWorkflowCanvas({ nodes: graph.nodes, edges: graph.edges, diff --git a/web/app/components/workflow/run/index.tsx b/web/app/components/workflow/run/index.tsx index 702ce06e1c..b9b77fc4a3 100644 --- a/web/app/components/workflow/run/index.tsx +++ b/web/app/components/workflow/run/index.tsx @@ -134,12 +134,12 @@ const RunPanel: FC = ({ hideResult, activeTab = 'RESULT', runID, getRe getData(appDetail.id, runID) }, [appDetail, runID]) - const [height, setHieght] = useState(0) + const [height, setHeight] = useState(0) const ref = useRef(null) const adjustResultHeight = () => { if (ref.current) - setHieght(ref.current?.clientHeight - 16 - 16 - 2 - 1) + setHeight(ref.current?.clientHeight - 16 - 16 - 2 - 1) } useEffect(() => { @@ -197,7 +197,7 @@ const RunPanel: FC = ({ hideResult, activeTab = 'RESULT', runID, getRe onClick={() => switchTab('TRACING')} >{t('runLog.tracing')}
- {/* panel detal */} + {/* panel detail */}
{loading && (
diff --git a/web/app/components/workflow/types.ts b/web/app/components/workflow/types.ts index 034376fed5..12957aa0dd 100644 --- a/web/app/components/workflow/types.ts +++ b/web/app/components/workflow/types.ts @@ -69,7 +69,7 @@ export type CommonEdgeType = { _hovering?: boolean _connectedNodeIsHovering?: boolean _connectedNodeIsSelected?: boolean - _runned?: boolean + _run?: boolean _isBundled?: boolean isInIteration?: boolean iteration_id?: string @@ -86,7 +86,7 @@ export type NodePanelProps = { } export type Edge = ReactFlowEdge -export type WorkflowDataUpdator = { +export type WorkflowDataUpdater = { nodes: Node[] edges: Edge[] viewport: Viewport diff --git a/web/app/components/workflow/utils.ts b/web/app/components/workflow/utils.ts index 0d07b2e568..e73485f546 100644 --- a/web/app/components/workflow/utils.ts +++ b/web/app/components/workflow/utils.ts @@ -34,18 +34,18 @@ const WHITE = 'WHITE' const GRAY = 'GRAY' const BLACK = 'BLACK' -const isCyclicUtil = (nodeId: string, color: Record, adjaList: Record, stack: string[]) => { +const isCyclicUtil = (nodeId: string, color: Record, adjList: Record, stack: string[]) => { color[nodeId] = GRAY stack.push(nodeId) - for (let i = 0; i < adjaList[nodeId].length; ++i) { - const childId = adjaList[nodeId][i] + for (let i = 0; i < adjList[nodeId].length; ++i) { + const childId = adjList[nodeId][i] if (color[childId] === GRAY) { stack.push(childId) return true } - if (color[childId] === WHITE && isCyclicUtil(childId, color, adjaList, stack)) + if (color[childId] === WHITE && isCyclicUtil(childId, color, adjList, stack)) return true } color[nodeId] = BLACK @@ -55,21 +55,21 @@ const isCyclicUtil = (nodeId: string, color: Record, adjaList: R } const getCycleEdges = (nodes: Node[], edges: Edge[]) => { - const adjaList: Record = {} + const adjList: Record = {} const color: Record = {} const stack: string[] = [] for (const node of nodes) { color[node.id] = WHITE - adjaList[node.id] = [] + adjList[node.id] = [] } for (const edge of edges) - adjaList[edge.source]?.push(edge.target) + adjList[edge.source]?.push(edge.target) for (let i = 0; i < nodes.length; i++) { if (color[nodes[i].id] === WHITE) - isCyclicUtil(nodes[i].id, color, adjaList, stack) + isCyclicUtil(nodes[i].id, color, adjList, stack) } const cycleEdges = [] diff --git a/web/app/layout.tsx b/web/app/layout.tsx index 9acc131029..008fdefa0b 100644 --- a/web/app/layout.tsx +++ b/web/app/layout.tsx @@ -1,6 +1,6 @@ import type { Viewport } from 'next' import I18nServer from './components/i18n-server' -import BrowerInitor from './components/browser-initor' +import BrowserInitor from './components/browser-initor' import SentryInitor from './components/sentry-initor' import Topbar from './components/base/topbar' import { getLocaleOnServer } from '@/i18n/server' @@ -45,11 +45,11 @@ const LocaleLayout = ({ data-public-site-about={process.env.NEXT_PUBLIC_SITE_ABOUT} > - + {children} - + ) diff --git a/web/app/signin/oneMoreStep.tsx b/web/app/signin/oneMoreStep.tsx index 42a797b4d6..a4324517a5 100644 --- a/web/app/signin/oneMoreStep.tsx +++ b/web/app/signin/oneMoreStep.tsx @@ -97,7 +97,7 @@ const OneMoreStep = () => { } needsDelay > - {t('login.donthave')} + {t('login.dontHave')}
diff --git a/web/config/index.ts b/web/config/index.ts index bb100473b1..71edf8f939 100644 --- a/web/config/index.ts +++ b/web/config/index.ts @@ -103,16 +103,16 @@ export const DEFAULT_PARAGRAPH_VALUE_MAX_LEN = 1000 export const zhRegex = /^[\u4E00-\u9FA5]$/m export const emojiRegex = /^[\uD800-\uDBFF][\uDC00-\uDFFF]$/m export const emailRegex = /^[\w.!#$%&'*+\-/=?^{|}~]+@([\w-]+\.)+[\w-]{2,}$/m -const MAX_ZN_VAR_NAME_LENGHT = 8 -const MAX_EN_VAR_VALUE_LENGHT = 30 +const MAX_ZN_VAR_NAME_LENGTH = 8 +const MAX_EN_VAR_VALUE_LENGTH = 30 export const getMaxVarNameLength = (value: string) => { if (zhRegex.test(value)) - return MAX_ZN_VAR_NAME_LENGHT + return MAX_ZN_VAR_NAME_LENGTH - return MAX_EN_VAR_VALUE_LENGHT + return MAX_EN_VAR_VALUE_LENGTH } -export const MAX_VAR_KEY_LENGHT = 30 +export const MAX_VAR_KEY_LENGTH = 30 export const MAX_PROMPT_MESSAGE_LENGTH = 10 diff --git a/web/hooks/use-moderate.ts b/web/hooks/use-moderate.ts index 0e2908ff66..11b078fbd9 100644 --- a/web/hooks/use-moderate.ts +++ b/web/hooks/use-moderate.ts @@ -13,14 +13,14 @@ export const useModerate = ( content: string, stop: boolean, moderationService: (text: string) => ReturnType, - seperateLength = 50, + separateLength = 50, ) => { const moderatedContentMap = useRef>(new Map()) const moderatingIndex = useRef([]) const [contentArr, setContentArr] = useState([]) const handleModerate = () => { - const stringArr = splitStringByLength(content, seperateLength) + const stringArr = splitStringByLength(content, separateLength) const lastIndex = stringArr.length - 1 stringArr.forEach((item, index) => { diff --git a/web/i18n/auto-gen-i18n.js b/web/i18n/auto-gen-i18n.js new file mode 100644 index 0000000000..c51bc53af3 --- /dev/null +++ b/web/i18n/auto-gen-i18n.js @@ -0,0 +1,82 @@ +/* eslint-disable no-eval */ +const fs = require('node:fs') +const path = require('node:path') +const transpile = require('typescript').transpile +const magicast = require('magicast') +const { parseModule, generateCode, loadFile } = magicast +const bingTranslate = require('bing-translate-api') +const { translate } = bingTranslate +const data = require('./languages.json') + +const targetLanguage = 'en-US' +// https://github.com/plainheart/bing-translate-api/blob/master/src/met/lang.json +const languageKeyMap = data.languages.reduce((map, language) => { + if (language.supported) { + if (language.value === 'zh-Hans' || language.value === 'zh-Hant') + map[language.value] = language.value + else + map[language.value] = language.value.split('-')[0] + } + + return map +}, {}) + +async function translateMissingKeyDeeply(sourceObj, targetObject, toLanguage) { + await Promise.all(Object.keys(sourceObj).map(async (key) => { + if (targetObject[key] === undefined) { + if (typeof sourceObj[key] === 'object') { + targetObject[key] = {} + await translateMissingKeyDeeply(sourceObj[key], targetObject[key], toLanguage) + } + else { + const { translation } = await translate(sourceObj[key], null, languageKeyMap[toLanguage]) + targetObject[key] = translation + // console.log(translation) + } + } + else if (typeof sourceObj[key] === 'object') { + targetObject[key] = targetObject[key] || {} + await translateMissingKeyDeeply(sourceObj[key], targetObject[key], toLanguage) + } + })) +} + +async function autoGenTrans(fileName, toGenLanguage) { + const fullKeyFilePath = path.join(__dirname, targetLanguage, `${fileName}.ts`) + const toGenLanguageFilePath = path.join(__dirname, toGenLanguage, `${fileName}.ts`) + const fullKeyContent = eval(transpile(fs.readFileSync(fullKeyFilePath, 'utf8'))) + // To keep object format and format it for magicast to work: const translation = { ... } => export default {...} + const readContent = await loadFile(toGenLanguageFilePath) + const { code: toGenContent } = generateCode(readContent) + const mod = await parseModule(`export default ${toGenContent.replace('export default translation', '').replace('const translation = ', '')}`) + const toGenOutPut = mod.exports.default + + await translateMissingKeyDeeply(fullKeyContent, toGenOutPut, toGenLanguage) + const { code } = generateCode(mod) + const res = `const translation =${code.replace('export default', '')} + +export default translation +`.replace(/,\n\n/g, ',\n').replace('};', '}') + + fs.writeFileSync(toGenLanguageFilePath, res) +} + +async function main() { + // const fileName = 'workflow' + // Promise.all(Object.keys(languageKeyMap).map(async (toLanguage) => { + // await autoGenTrans(fileName, toLanguage) + // })) + + const files = fs + .readdirSync(path.join(__dirname, targetLanguage)) + .map(file => file.replace(/\.ts/, '')) + .filter(f => f !== 'app-debug') // ast parse error in app-debug + + await Promise.all(files.map(async (file) => { + await Promise.all(Object.keys(languageKeyMap).map(async (language) => { + await autoGenTrans(file, language) + })) + })) +} + +main() diff --git a/web/i18n/script.js b/web/i18n/check-i18n.js similarity index 98% rename from web/i18n/script.js rename to web/i18n/check-i18n.js index 5af8f466ff..fbe1bbd2ef 100644 --- a/web/i18n/script.js +++ b/web/i18n/check-i18n.js @@ -27,6 +27,7 @@ async function getKeysFromLanuage(language) { // console.log(camelCaseFileName) const content = fs.readFileSync(filePath, 'utf8') const translation = eval(transpile(content)) + // console.log(translation) const keys = Object.keys(translation) const nestedKeys = [] const iterateKeys = (obj, prefix = '') => { diff --git a/web/i18n/de-DE/app-annotation.ts b/web/i18n/de-DE/app-annotation.ts index 8b96da2752..ef2fa1f236 100644 --- a/web/i18n/de-DE/app-annotation.ts +++ b/web/i18n/de-DE/app-annotation.ts @@ -1,87 +1,87 @@ -const translation = { - title: 'Anmerkungen', - name: 'Antwort Anmerkung', - editBy: 'Antwort bearbeitet von {{author}}', - noData: { - title: 'Keine Anmerkungen', - description: 'Sie können Anmerkungen während des App-Debuggings bearbeiten oder hier Anmerkungen in großen Mengen importieren für eine hochwertige Antwort.', - }, - table: { - header: { - question: 'Frage', - answer: 'Antwort', - createdAt: 'erstellt am', - hits: 'Treffer', - actions: 'Aktionen', - addAnnotation: 'Anmerkung hinzufügen', - bulkImport: 'Massenimport', - bulkExport: 'Massenexport', - clearAll: 'Alle Anmerkungen löschen', - }, - }, - editModal: { - title: 'Antwort Anmerkung bearbeiten', - queryName: 'Benutzeranfrage', - answerName: 'Geschichtenerzähler Bot', - yourAnswer: 'Ihre Antwort', - answerPlaceholder: 'Geben Sie hier Ihre Antwort ein', - yourQuery: 'Ihre Anfrage', - queryPlaceholder: 'Geben Sie hier Ihre Anfrage ein', - removeThisCache: 'Diese Anmerkung entfernen', - createdAt: 'Erstellt am', - }, - addModal: { - title: 'Antwort Anmerkung hinzufügen', - queryName: 'Frage', - answerName: 'Antwort', - answerPlaceholder: 'Antwort hier eingeben', - queryPlaceholder: 'Anfrage hier eingeben', - createNext: 'Eine weitere annotierte Antwort hinzufügen', - }, - batchModal: { - title: 'Massenimport', - csvUploadTitle: 'Ziehen Sie Ihre CSV-Datei hierher oder ', - browse: 'durchsuchen', - tip: 'Die CSV-Datei muss der folgenden Struktur entsprechen:', - question: 'Frage', - answer: 'Antwort', - contentTitle: 'Inhaltsabschnitt', - content: 'Inhalt', - template: 'Laden Sie die Vorlage hier herunter', - cancel: 'Abbrechen', - run: 'Batch ausführen', - runError: 'Batch-Ausführung fehlgeschlagen', - processing: 'In Batch-Verarbeitung', - completed: 'Import abgeschlossen', - error: 'Importfehler', - ok: 'OK', - }, - errorMessage: { - answerRequired: 'Antwort erforderlich', - queryRequired: 'Frage erforderlich', - }, - viewModal: { - annotatedResponse: 'Antwort Anmerkung', - hitHistory: 'Trefferhistorie', - hit: 'Treffer', - hits: 'Treffer', - noHitHistory: 'Keine Trefferhistorie', - }, - hitHistoryTable: { - query: 'Anfrage', - match: 'Übereinstimmung', - response: 'Antwort', - source: 'Quelle', - score: 'Punktzahl', - time: 'Zeit', - }, - initSetup: { - title: 'Initialeinrichtung Antwort Anmerkung', - configTitle: 'Einrichtung Antwort Anmerkung', - confirmBtn: 'Speichern & Aktivieren', - configConfirmBtn: 'Speichern', - }, - embeddingModelSwitchTip: 'Anmerkungstext-Vektorisierungsmodell, das Wechseln von Modellen wird neu eingebettet, was zusätzliche Kosten verursacht.', -} - -export default translation +const translation = { + title: 'Anmerkungen', + name: 'Antwort Anmerkung', + editBy: 'Antwort bearbeitet von {{author}}', + noData: { + title: 'Keine Anmerkungen', + description: 'Sie können Anmerkungen während des App-Debuggings bearbeiten oder hier Anmerkungen in großen Mengen importieren für eine hochwertige Antwort.', + }, + table: { + header: { + question: 'Frage', + answer: 'Antwort', + createdAt: 'erstellt am', + hits: 'Treffer', + actions: 'Aktionen', + addAnnotation: 'Anmerkung hinzufügen', + bulkImport: 'Massenimport', + bulkExport: 'Massenexport', + clearAll: 'Alle Anmerkungen löschen', + }, + }, + editModal: { + title: 'Antwort Anmerkung bearbeiten', + queryName: 'Benutzeranfrage', + answerName: 'Geschichtenerzähler Bot', + yourAnswer: 'Ihre Antwort', + answerPlaceholder: 'Geben Sie hier Ihre Antwort ein', + yourQuery: 'Ihre Anfrage', + queryPlaceholder: 'Geben Sie hier Ihre Anfrage ein', + removeThisCache: 'Diese Anmerkung entfernen', + createdAt: 'Erstellt am', + }, + addModal: { + title: 'Antwort Anmerkung hinzufügen', + queryName: 'Frage', + answerName: 'Antwort', + answerPlaceholder: 'Antwort hier eingeben', + queryPlaceholder: 'Anfrage hier eingeben', + createNext: 'Eine weitere annotierte Antwort hinzufügen', + }, + batchModal: { + title: 'Massenimport', + csvUploadTitle: 'Ziehen Sie Ihre CSV-Datei hierher oder ', + browse: 'durchsuchen', + tip: 'Die CSV-Datei muss der folgenden Struktur entsprechen:', + question: 'Frage', + answer: 'Antwort', + contentTitle: 'Inhaltsabschnitt', + content: 'Inhalt', + template: 'Laden Sie die Vorlage hier herunter', + cancel: 'Abbrechen', + run: 'Batch ausführen', + runError: 'Batch-Ausführung fehlgeschlagen', + processing: 'In Batch-Verarbeitung', + completed: 'Import abgeschlossen', + error: 'Importfehler', + ok: 'OK', + }, + errorMessage: { + answerRequired: 'Antwort erforderlich', + queryRequired: 'Frage erforderlich', + }, + viewModal: { + annotatedResponse: 'Antwort Anmerkung', + hitHistory: 'Trefferhistorie', + hit: 'Treffer', + hits: 'Treffer', + noHitHistory: 'Keine Trefferhistorie', + }, + hitHistoryTable: { + query: 'Anfrage', + match: 'Übereinstimmung', + response: 'Antwort', + source: 'Quelle', + score: 'Punktzahl', + time: 'Zeit', + }, + initSetup: { + title: 'Initialeinrichtung Antwort Anmerkung', + configTitle: 'Einrichtung Antwort Anmerkung', + confirmBtn: 'Speichern & Aktivieren', + configConfirmBtn: 'Speichern', + }, + embeddingModelSwitchTip: 'Anmerkungstext-Vektorisierungsmodell, das Wechseln von Modellen wird neu eingebettet, was zusätzliche Kosten verursacht.', +} + +export default translation diff --git a/web/i18n/de-DE/app-api.ts b/web/i18n/de-DE/app-api.ts index 91f4589963..84e0989095 100644 --- a/web/i18n/de-DE/app-api.ts +++ b/web/i18n/de-DE/app-api.ts @@ -1,82 +1,83 @@ -const translation = { - apiServer: 'API Server', - apiKey: 'API Schlüssel', - status: 'Status', - disabled: 'Deaktiviert', - ok: 'In Betrieb', - copy: 'Kopieren', - copied: 'Kopiert', - play: 'Abspielen', - pause: 'Pause', - playing: 'Wiedergabe', - merMaind: { - rerender: 'Neu rendern', - }, - never: 'Nie', - apiKeyModal: { - apiSecretKey: 'API Geheimschlüssel', - apiSecretKeyTips: 'Um Missbrauch der API zu verhindern, schützen Sie Ihren API Schlüssel. Vermeiden Sie es, ihn als Klartext im Frontend-Code zu verwenden. :)', - createNewSecretKey: 'Neuen Geheimschlüssel erstellen', - secretKey: 'Geheimschlüssel', - created: 'ERSTELLT', - lastUsed: 'ZULETZT VERWENDET', - generateTips: 'Bewahren Sie diesen Schlüssel an einem sicheren und zugänglichen Ort auf.', - }, - actionMsg: { - deleteConfirmTitle: 'Diesen Geheimschlüssel löschen?', - deleteConfirmTips: 'Diese Aktion kann nicht rückgängig gemacht werden.', - ok: 'OK', - }, - completionMode: { - title: 'Completion App API', - info: 'Für die Erzeugung von hochwertigem Text, wie z.B. Artikel, Zusammenfassungen und Übersetzungen, verwenden Sie die Completion-Messages API mit Benutzereingaben. Die Texterzeugung basiert auf den Modellparametern und Vorlagen für Aufforderungen in Dify Prompt Engineering.', - createCompletionApi: 'Completion Nachricht erstellen', - createCompletionApiTip: 'Erstellen Sie eine Completion Nachricht, um den Frage-Antwort-Modus zu unterstützen.', - inputsTips: '(Optional) Geben Sie Benutzereingabefelder als Schlüssel-Wert-Paare an, die Variablen in Prompt Eng. entsprechen. Schlüssel ist der Variablenname, Wert ist der Parameterwert. Wenn der Feldtyp Select ist, muss der übermittelte Wert eine der voreingestellten Optionen sein.', - queryTips: 'Textinhalt der Benutzereingabe.', - blocking: 'Blockierender Typ, wartet auf die Fertigstellung der Ausführung und gibt Ergebnisse zurück. (Anfragen können unterbrochen werden, wenn der Prozess lang ist)', - streaming: 'Streaming Rückgaben. Implementierung der Streaming-Rückgabe basierend auf SSE (Server-Sent Events).', - messageFeedbackApi: 'Nachrichtenfeedback (Like)', - messageFeedbackApiTip: 'Bewerten Sie empfangene Nachrichten im Namen der Endbenutzer mit Likes oder Dislikes. Diese Daten sind auf der Seite Logs & Annotations sichtbar und werden für zukünftige Modellanpassungen verwendet.', - messageIDTip: 'Nachrichten-ID', - ratingTip: 'like oder dislike, null ist rückgängig machen', - parametersApi: 'Anwendungsparameterinformationen abrufen', - parametersApiTip: 'Abrufen konfigurierter Eingabeparameter, einschließlich Variablennamen, Feldnamen, Typen und Standardwerten. Typischerweise verwendet, um diese Felder in einem Formular anzuzeigen oder Standardwerte nach dem Laden des Clients auszufüllen.', - }, - chatMode: { - title: 'Chat App API', - info: 'Für vielseitige Gesprächsanwendungen im Q&A-Format rufen Sie die chat-messages API auf, um einen Dialog zu initiieren. Führen Sie laufende Gespräche fort, indem Sie die zurückgegebene conversation_id übergeben. Antwortparameter und -vorlagen hängen von den Einstellungen in Dify Prompt Eng. ab.', - createChatApi: 'Chatnachricht erstellen', - createChatApiTip: 'Eine neue Konversationsnachricht erstellen oder einen bestehenden Dialog fortsetzen.', - inputsTips: '(Optional) Geben Sie Benutzereingabefelder als Schlüssel-Wert-Paare an, die Variablen in Prompt Eng. entsprechen. Schlüssel ist der Variablenname, Wert ist der Parameterwert. Wenn der Feldtyp Select ist, muss der übermittelte Wert eine der voreingestellten Optionen sein.', - queryTips: 'Inhalt der Benutzereingabe/Frage', - blocking: 'Blockierender Typ, wartet auf die Fertigstellung der Ausführung und gibt Ergebnisse zurück. (Anfragen können unterbrochen werden, wenn der Prozess lang ist)', - streaming: 'Streaming Rückgaben. Implementierung der Streaming-Rückgabe basierend auf SSE (Server-Sent Events).', - conversationIdTip: '(Optional) Konversations-ID: für erstmalige Konversation leer lassen; conversation_id aus dem Kontext übergeben, um den Dialog fortzusetzen.', - messageFeedbackApi: 'Nachrichtenfeedback des Endbenutzers, like', - messageFeedbackApiTip: 'Bewerten Sie empfangene Nachrichten im Namen der Endbenutzer mit Likes oder Dislikes. Diese Daten sind auf der Seite Logs & Annotations sichtbar und werden für zukünftige Modellanpassungen verwendet.', - messageIDTip: 'Nachrichten-ID', - ratingTip: 'like oder dislike, null ist rückgängig machen', - chatMsgHistoryApi: 'Chatverlaufsnachricht abrufen', - chatMsgHistoryApiTip: 'Die erste Seite gibt die neuesten `limit` Einträge in umgekehrter Reihenfolge zurück.', - chatMsgHistoryConversationIdTip: 'Konversations-ID', - chatMsgHistoryFirstId: 'ID des ersten Chat-Datensatzes auf der aktuellen Seite. Standardmäßig keiner.', - chatMsgHistoryLimit: 'Wie viele Chats in einer Anfrage zurückgegeben werden', - conversationsListApi: 'Konversationsliste abrufen', - conversationsListApiTip: 'Ruft die Sitzungsliste des aktuellen Benutzers ab. Standardmäßig werden die letzten 20 Sitzungen zurückgegeben.', - conversationsListFirstIdTip: 'Die ID des letzten Datensatzes auf der aktuellen Seite, standardmäßig keine.', - conversationsListLimitTip: 'Wie viele Chats in einer Anfrage zurückgegeben werden', - conversationRenamingApi: 'Konversation umbenennen', - conversationRenamingApiTip: 'Konversationen umbenennen; der Name wird in Mehrsitzungs-Client-Schnittstellen angezeigt.', - conversationRenamingNameTip: 'Neuer Name', - parametersApi: 'Anwendungsparameterinformationen abrufen', - parametersApiTip: 'Abrufen konfigurierter Eingabeparameter, einschließlich Variablennamen, Feldnamen, Typen und Standardwerten. Typischerweise verwendet, um diese Felder in einem Formular anzuzeigen oder Standardwerte nach dem Laden des Clients auszufüllen.', - }, - develop: { - requestBody: 'Anfragekörper', - pathParams: 'Pfadparameter', - query: 'Anfrage', - }, -} - +const translation = { + apiServer: 'API Server', + apiKey: 'API Schlüssel', + status: 'Status', + disabled: 'Deaktiviert', + ok: 'In Betrieb', + copy: 'Kopieren', + copied: 'Kopiert', + play: 'Abspielen', + pause: 'Pause', + playing: 'Wiedergabe', + merMaid: { + rerender: 'Neu rendern', + }, + never: 'Nie', + apiKeyModal: { + apiSecretKey: 'API Geheimschlüssel', + apiSecretKeyTips: 'Um Missbrauch der API zu verhindern, schützen Sie Ihren API Schlüssel. Vermeiden Sie es, ihn als Klartext im Frontend-Code zu verwenden. :)', + createNewSecretKey: 'Neuen Geheimschlüssel erstellen', + secretKey: 'Geheimschlüssel', + created: 'ERSTELLT', + lastUsed: 'ZULETZT VERWENDET', + generateTips: 'Bewahren Sie diesen Schlüssel an einem sicheren und zugänglichen Ort auf.', + }, + actionMsg: { + deleteConfirmTitle: 'Diesen Geheimschlüssel löschen?', + deleteConfirmTips: 'Diese Aktion kann nicht rückgängig gemacht werden.', + ok: 'OK', + }, + completionMode: { + title: 'Completion App API', + info: 'Für die Erzeugung von hochwertigem Text, wie z.B. Artikel, Zusammenfassungen und Übersetzungen, verwenden Sie die Completion-Messages API mit Benutzereingaben. Die Texterzeugung basiert auf den Modellparametern und Vorlagen für Aufforderungen in Dify Prompt Engineering.', + createCompletionApi: 'Completion Nachricht erstellen', + createCompletionApiTip: 'Erstellen Sie eine Completion Nachricht, um den Frage-Antwort-Modus zu unterstützen.', + inputsTips: '(Optional) Geben Sie Benutzereingabefelder als Schlüssel-Wert-Paare an, die Variablen in Prompt Eng. entsprechen. Schlüssel ist der Variablenname, Wert ist der Parameterwert. Wenn der Feldtyp Select ist, muss der übermittelte Wert eine der voreingestellten Optionen sein.', + queryTips: 'Textinhalt der Benutzereingabe.', + blocking: 'Blockierender Typ, wartet auf die Fertigstellung der Ausführung und gibt Ergebnisse zurück. (Anfragen können unterbrochen werden, wenn der Prozess lang ist)', + streaming: 'Streaming Rückgaben. Implementierung der Streaming-Rückgabe basierend auf SSE (Server-Sent Events).', + messageFeedbackApi: 'Nachrichtenfeedback (Like)', + messageFeedbackApiTip: 'Bewerten Sie empfangene Nachrichten im Namen der Endbenutzer mit Likes oder Dislikes. Diese Daten sind auf der Seite Logs & Annotations sichtbar und werden für zukünftige Modellanpassungen verwendet.', + messageIDTip: 'Nachrichten-ID', + ratingTip: 'like oder dislike, null ist rückgängig machen', + parametersApi: 'Anwendungsparameterinformationen abrufen', + parametersApiTip: 'Abrufen konfigurierter Eingabeparameter, einschließlich Variablennamen, Feldnamen, Typen und Standardwerten. Typischerweise verwendet, um diese Felder in einem Formular anzuzeigen oder Standardwerte nach dem Laden des Clients auszufüllen.', + }, + chatMode: { + title: 'Chat App API', + info: 'Für vielseitige Gesprächsanwendungen im Q&A-Format rufen Sie die chat-messages API auf, um einen Dialog zu initiieren. Führen Sie laufende Gespräche fort, indem Sie die zurückgegebene conversation_id übergeben. Antwortparameter und -vorlagen hängen von den Einstellungen in Dify Prompt Eng. ab.', + createChatApi: 'Chatnachricht erstellen', + createChatApiTip: 'Eine neue Konversationsnachricht erstellen oder einen bestehenden Dialog fortsetzen.', + inputsTips: '(Optional) Geben Sie Benutzereingabefelder als Schlüssel-Wert-Paare an, die Variablen in Prompt Eng. entsprechen. Schlüssel ist der Variablenname, Wert ist der Parameterwert. Wenn der Feldtyp Select ist, muss der übermittelte Wert eine der voreingestellten Optionen sein.', + queryTips: 'Inhalt der Benutzereingabe/Frage', + blocking: 'Blockierender Typ, wartet auf die Fertigstellung der Ausführung und gibt Ergebnisse zurück. (Anfragen können unterbrochen werden, wenn der Prozess lang ist)', + streaming: 'Streaming Rückgaben. Implementierung der Streaming-Rückgabe basierend auf SSE (Server-Sent Events).', + conversationIdTip: '(Optional) Konversations-ID: für erstmalige Konversation leer lassen; conversation_id aus dem Kontext übergeben, um den Dialog fortzusetzen.', + messageFeedbackApi: 'Nachrichtenfeedback des Endbenutzers, like', + messageFeedbackApiTip: 'Bewerten Sie empfangene Nachrichten im Namen der Endbenutzer mit Likes oder Dislikes. Diese Daten sind auf der Seite Logs & Annotations sichtbar und werden für zukünftige Modellanpassungen verwendet.', + messageIDTip: 'Nachrichten-ID', + ratingTip: 'like oder dislike, null ist rückgängig machen', + chatMsgHistoryApi: 'Chatverlaufsnachricht abrufen', + chatMsgHistoryApiTip: 'Die erste Seite gibt die neuesten `limit` Einträge in umgekehrter Reihenfolge zurück.', + chatMsgHistoryConversationIdTip: 'Konversations-ID', + chatMsgHistoryFirstId: 'ID des ersten Chat-Datensatzes auf der aktuellen Seite. Standardmäßig keiner.', + chatMsgHistoryLimit: 'Wie viele Chats in einer Anfrage zurückgegeben werden', + conversationsListApi: 'Konversationsliste abrufen', + conversationsListApiTip: 'Ruft die Sitzungsliste des aktuellen Benutzers ab. Standardmäßig werden die letzten 20 Sitzungen zurückgegeben.', + conversationsListFirstIdTip: 'Die ID des letzten Datensatzes auf der aktuellen Seite, standardmäßig keine.', + conversationsListLimitTip: 'Wie viele Chats in einer Anfrage zurückgegeben werden', + conversationRenamingApi: 'Konversation umbenennen', + conversationRenamingApiTip: 'Konversationen umbenennen; der Name wird in Mehrsitzungs-Client-Schnittstellen angezeigt.', + conversationRenamingNameTip: 'Neuer Name', + parametersApi: 'Anwendungsparameterinformationen abrufen', + parametersApiTip: 'Abrufen konfigurierter Eingabeparameter, einschließlich Variablennamen, Feldnamen, Typen und Standardwerten. Typischerweise verwendet, um diese Felder in einem Formular anzuzeigen oder Standardwerte nach dem Laden des Clients auszufüllen.', + }, + develop: { + requestBody: 'Anfragekörper', + pathParams: 'Pfadparameter', + query: 'Anfrage', + }, + loading: 'Laden', +} + export default translation diff --git a/web/i18n/de-DE/app-debug.ts b/web/i18n/de-DE/app-debug.ts index acb3f53904..c00c799519 100644 --- a/web/i18n/de-DE/app-debug.ts +++ b/web/i18n/de-DE/app-debug.ts @@ -248,7 +248,7 @@ const translation = { historyNoBeEmpty: 'Konversationsverlauf muss im Prompt gesetzt sein', queryNoBeEmpty: 'Anfrage muss im Prompt gesetzt sein', }, - variableConig: { + variableConfig: { modalTitle: 'Feldeinstellungen', description: 'Einstellung für Variable {{varName}}', fieldType: 'Feldtyp', diff --git a/web/i18n/de-DE/app-log.ts b/web/i18n/de-DE/app-log.ts index 667a23e8aa..0a0e740578 100644 --- a/web/i18n/de-DE/app-log.ts +++ b/web/i18n/de-DE/app-log.ts @@ -1,89 +1,95 @@ -const translation = { - title: 'Protokolle', - description: 'Die Protokolle zeichnen den Betriebsstatus der Anwendung auf, einschließlich Benutzereingaben und KI-Antworten.', - dateTimeFormat: 'MM/DD/YYYY hh:mm A', - table: { - header: { - updatedTime: 'Aktualisierungszeit', - time: 'Erstellungszeit', - endUser: 'Endbenutzer oder Konto', - input: 'Eingabe', - output: 'Ausgabe', - summary: 'Titel', - messageCount: 'Nachrichtenzahl', - userRate: 'Benutzerbewertung', - adminRate: 'Op. Bewertung', - }, - pagination: { - previous: 'Vorherige', - next: 'Nächste', - }, - empty: { - noChat: 'Noch keine Konversation', - noOutput: 'Keine Ausgabe', - element: { - title: 'Ist da jemand?', - content: 'Beobachten und annotieren Sie hier die Interaktionen zwischen Endbenutzern und KI-Anwendungen, um die Genauigkeit der KI kontinuierlich zu verbessern. Sie können versuchen, die Web-App selbst zu teilen oder zu testen, und dann zu dieser Seite zurückkehren.', - }, - }, - }, - detail: { - time: 'Zeit', - conversationId: 'Konversations-ID', - promptTemplate: 'Prompt-Vorlage', - promptTemplateBeforeChat: 'Prompt-Vorlage vor dem Chat · Als Systemnachricht', - annotationTip: 'Verbesserungen markiert von {{user}}', - timeConsuming: '', - second: 's', - tokenCost: 'Verbrauchte Token', - loading: 'lädt', - operation: { - like: 'gefällt mir', - dislike: 'gefällt mir nicht', - addAnnotation: 'Verbesserung hinzufügen', - editAnnotation: 'Verbesserung bearbeiten', - annotationPlaceholder: 'Geben Sie die erwartete Antwort ein, die Sie möchten, dass die KI antwortet, welche für die Feinabstimmung des Modells und die kontinuierliche Verbesserung der Qualität der Textgenerierung in Zukunft verwendet werden kann.', - }, - variables: 'Variablen', - uploadImages: 'Hochgeladene Bilder', - }, - filter: { - period: { - today: 'Heute', - last7days: 'Letzte 7 Tage', - last4weeks: 'Letzte 4 Wochen', - last3months: 'Letzte 3 Monate', - last12months: 'Letzte 12 Monate', - monthToDate: 'Monat bis heute', - quarterToDate: 'Quartal bis heute', - yearToDate: 'Jahr bis heute', - allTime: 'Gesamte Zeit', - }, - annotation: { - all: 'Alle', - annotated: 'Markierte Verbesserungen ({{count}} Elemente)', - not_annotated: 'Nicht annotiert', - }, - sortBy: 'Sortieren nach:', - descending: 'absteigend', - ascending: 'aufsteigend', - }, - workflowTitle: 'Workflow-Protokolle', - workflowSubtitle: 'Das Protokoll hat den Vorgang von Automate aufgezeichnet.', - runDetail: { - title: 'Konversationsprotokoll', - workflowTitle: 'Protokolldetail', - }, - promptLog: 'Prompt-Protokoll', - agentLog: 'Agentenprotokoll', - viewLog: 'Protokoll anzeigen', - agentLogDetail: { - agentMode: 'Agentenmodus', - toolUsed: 'Verwendetes Werkzeug', - iterations: 'Iterationen', - iteration: 'Iteration', - finalProcessing: 'Endverarbeitung', - }, -} - -export default translation +const translation = { + title: 'Protokolle', + description: 'Die Protokolle zeichnen den Betriebsstatus der Anwendung auf, einschließlich Benutzereingaben und KI-Antworten.', + dateTimeFormat: 'MM/DD/YYYY hh:mm A', + table: { + header: { + updatedTime: 'Aktualisierungszeit', + time: 'Erstellungszeit', + endUser: 'Endbenutzer oder Konto', + input: 'Eingabe', + output: 'Ausgabe', + summary: 'Titel', + messageCount: 'Nachrichtenzahl', + userRate: 'Benutzerbewertung', + adminRate: 'Op. Bewertung', + user: 'Endbenutzer oder Konto', + status: 'STATUS', + runtime: 'LAUFZEIT', + version: 'VERSION', + tokens: 'TOKEN', + startTime: 'STARTZEIT', + }, + pagination: { + previous: 'Vorherige', + next: 'Nächste', + }, + empty: { + noChat: 'Noch keine Konversation', + noOutput: 'Keine Ausgabe', + element: { + title: 'Ist da jemand?', + content: 'Beobachten und annotieren Sie hier die Interaktionen zwischen Endbenutzern und KI-Anwendungen, um die Genauigkeit der KI kontinuierlich zu verbessern. Sie können versuchen, die Web-App selbst zu teilen oder zu testen, und dann zu dieser Seite zurückkehren.', + }, + }, + }, + detail: { + time: 'Zeit', + conversationId: 'Konversations-ID', + promptTemplate: 'Prompt-Vorlage', + promptTemplateBeforeChat: 'Prompt-Vorlage vor dem Chat · Als Systemnachricht', + annotationTip: 'Verbesserungen markiert von {{user}}', + timeConsuming: '', + second: 's', + tokenCost: 'Verbrauchte Token', + loading: 'lädt', + operation: { + like: 'gefällt mir', + dislike: 'gefällt mir nicht', + addAnnotation: 'Verbesserung hinzufügen', + editAnnotation: 'Verbesserung bearbeiten', + annotationPlaceholder: 'Geben Sie die erwartete Antwort ein, die Sie möchten, dass die KI antwortet, welche für die Feinabstimmung des Modells und die kontinuierliche Verbesserung der Qualität der Textgenerierung in Zukunft verwendet werden kann.', + }, + variables: 'Variablen', + uploadImages: 'Hochgeladene Bilder', + }, + filter: { + period: { + today: 'Heute', + last7days: 'Letzte 7 Tage', + last4weeks: 'Letzte 4 Wochen', + last3months: 'Letzte 3 Monate', + last12months: 'Letzte 12 Monate', + monthToDate: 'Monat bis heute', + quarterToDate: 'Quartal bis heute', + yearToDate: 'Jahr bis heute', + allTime: 'Gesamte Zeit', + }, + annotation: { + all: 'Alle', + annotated: 'Markierte Verbesserungen ({{count}} Elemente)', + not_annotated: 'Nicht annotiert', + }, + sortBy: 'Sortieren nach:', + descending: 'absteigend', + ascending: 'aufsteigend', + }, + workflowTitle: 'Workflow-Protokolle', + workflowSubtitle: 'Das Protokoll hat den Vorgang von Automate aufgezeichnet.', + runDetail: { + title: 'Konversationsprotokoll', + workflowTitle: 'Protokolldetail', + }, + promptLog: 'Prompt-Protokoll', + agentLog: 'Agentenprotokoll', + viewLog: 'Protokoll anzeigen', + agentLogDetail: { + agentMode: 'Agentenmodus', + toolUsed: 'Verwendetes Werkzeug', + iterations: 'Iterationen', + iteration: 'Iteration', + finalProcessing: 'Endverarbeitung', + }, +} + +export default translation diff --git a/web/i18n/de-DE/app-overview.ts b/web/i18n/de-DE/app-overview.ts index 99100cf868..a44baec82e 100644 --- a/web/i18n/de-DE/app-overview.ts +++ b/web/i18n/de-DE/app-overview.ts @@ -48,6 +48,8 @@ const translation = { title: 'Workflow-Schritte', show: 'Anzeigen', hide: 'Verbergen', + subTitle: 'Details zum Arbeitsablauf', + showDesc: 'Ein- oder Ausblenden von Workflow-Details in der WebApp', }, chatColorTheme: 'Chat-Farbschema', chatColorThemeDesc: 'Legen Sie das Farbschema des Chatbots fest', @@ -64,6 +66,12 @@ const translation = { customDisclaimerPlaceholder: 'Geben Sie den benutzerdefinierten Haftungsausschluss-Text ein', customDisclaimerTip: 'Der ben userdefinierte Haftungsausschluss-Text wird auf der Clientseite angezeigt und bietet zusätzliche Informationen über die Anwendung', }, + sso: { + title: 'WebApp-SSO', + description: 'Alle Benutzer müssen sich mit SSO anmelden, bevor sie WebApp verwenden können', + label: 'SSO-Authentifizierung', + tooltip: 'Wenden Sie sich an den Administrator, um WebApp-SSO zu aktivieren', + }, }, embedded: { entry: 'Eingebettet', @@ -119,7 +127,11 @@ const translation = { tokenPS: 'Token/s', totalMessages: { title: 'Gesamtnachrichten', - explanation: 'Tägliche AI-Interaktionszählung; Prompt-Engineering/Debugging ausgenommen.', + explanation: 'Tägliche Anzahl der KI-Interaktionen.', + }, + totalConversations: { + title: 'Gesamte Konversationen', + explanation: 'Tägliche Anzahl der KI-Konversationen; Prompt-Engineering/Debugging ausgeschlossen.', }, activeUsers: { title: 'Aktive Benutzer', @@ -146,6 +158,10 @@ const translation = { title: 'Token-Ausgabegeschwindigkeit', explanation: 'Misst die Leistung des LLM. Zählt die Token-Ausgabegeschwindigkeit des LLM vom Beginn der Anfrage bis zum Abschluss der Ausgabe.', }, + avgUserInteractions: { + explanation: 'Spiegelt die tägliche Nutzungshäufigkeit der Benutzer wider. Diese Metrik spiegelt die Bindung der Benutzer wider.', + title: 'Durchschnittliche Benutzerinteraktionen', + }, }, } diff --git a/web/i18n/de-DE/app.ts b/web/i18n/de-DE/app.ts index 55caff2284..4fc61f8ee0 100644 --- a/web/i18n/de-DE/app.ts +++ b/web/i18n/de-DE/app.ts @@ -1,107 +1,145 @@ -const translation = { - createApp: 'Neue App erstellen', - types: { - all: 'Alle', - assistant: 'Assistent', - completion: 'Vervollständigung', - }, - modes: { - completion: 'Textgenerator', - chat: 'Basisassistent', - }, - createFromConfigFile: 'App aus Konfigurationsdatei erstellen', - deleteAppConfirmTitle: 'Diese App löschen?', - deleteAppConfirmContent: - 'Das Löschen der App ist unwiderruflich. Nutzer werden keinen Zugang mehr zu Ihrer App haben, und alle Prompt-Konfigurationen und Logs werden dauerhaft gelöscht.', - appDeleted: 'App gelöscht', - appDeleteFailed: 'Löschen der App fehlgeschlagen', - join: 'Treten Sie der Gemeinschaft bei', - communityIntro: - 'Diskutieren Sie mit Teammitgliedern, Mitwirkenden und Entwicklern auf verschiedenen Kanälen.', - roadmap: 'Sehen Sie unseren Fahrplan', - appNamePlaceholder: 'Bitte geben Sie den Namen der App ein', - newApp: { - startToCreate: 'Lassen Sie uns mit Ihrer neuen App beginnen', - captionName: 'App-Symbol & Name', - captionAppType: 'Welchen Typ von App möchten Sie erstellen?', - previewDemo: 'Vorschau-Demo', - chatApp: 'Assistent', - chatAppIntro: - 'Ich möchte eine Chat-basierte Anwendung bauen. Diese App verwendet ein Frage-Antwort-Format und ermöglicht mehrere Runden kontinuierlicher Konversation.', - agentAssistant: 'Neuer Agentenassistent', - completeApp: 'Textgenerator', - completeAppIntro: - 'Ich möchte eine Anwendung erstellen, die hochwertigen Text basierend auf Aufforderungen generiert, wie z.B. das Erstellen von Artikeln, Zusammenfassungen, Übersetzungen und mehr.', - showTemplates: 'Ich möchte aus einer Vorlage wählen', - hideTemplates: 'Zurück zur Modusauswahl', - Create: 'Erstellen', - Cancel: 'Abbrechen', - nameNotEmpty: 'Name darf nicht leer sein', - appTemplateNotSelected: 'Bitte wählen Sie eine Vorlage', - appTypeRequired: 'Bitte wählen Sie einen App-Typ', - appCreated: 'App erstellt', - appCreateFailed: 'Erstellen der App fehlgeschlagen', - }, - editApp: 'App bearbeiten', - editAppTitle: 'App-Informationen bearbeiten', - editDone: 'App-Informationen wurden aktualisiert', - editFailed: 'Aktualisierung der App-Informationen fehlgeschlagen', - iconPicker: { - ok: 'OK', - cancel: 'Abbrechen', - emoji: 'Emoji', - image: 'Bild', - }, - switch: 'Zu Workflow-Orchestrierung wechseln', - switchTipStart: 'Eine neue App-Kopie wird für Sie erstellt, und die neue Kopie wird zur Workflow-Orchestrierung wechseln. Die neue Kopie wird ', - switchTip: 'nicht erlauben', - switchTipEnd: ' zur Basis-Orchestrierung zurückzuwechseln.', - switchLabel: 'Die zu erstellende App-Kopie', - removeOriginal: 'Ursprüngliche App löschen', - switchStart: 'Wechsel starten', - typeSelector: { - all: 'ALLE Typen', - chatbot: 'Chatbot', - agent: 'Agent', - workflow: 'Workflow', - completion: 'Vervollständigung', - }, - tracing: { - title: 'Anwendungsleistung nachverfolgen', - description: 'Konfiguration eines Drittanbieter-LLMOps-Anbieters und Nachverfolgung der Anwendungsleistung.', - config: 'Konfigurieren', - collapse: 'Einklappen', - expand: 'Ausklappen', - tracing: 'Nachverfolgung', - disabled: 'Deaktiviert', - disabledTip: 'Bitte zuerst den Anbieter konfigurieren', - enabled: 'In Betrieb', - tracingDescription: 'Erfassung des vollständigen Kontexts der Anwendungsausführung, einschließlich LLM-Aufrufe, Kontext, Prompts, HTTP-Anfragen und mehr, auf einer Nachverfolgungsplattform von Drittanbietern.', - configProviderTitle: { - configured: 'Konfiguriert', - notConfigured: 'Anbieter konfigurieren, um Nachverfolgung zu aktivieren', - moreProvider: 'Weitere Anbieter', - }, - langsmith: { - title: 'LangSmith', - description: 'Eine All-in-One-Entwicklerplattform für jeden Schritt des LLM-gesteuerten Anwendungslebenszyklus.', - }, - langfuse: { - title: 'Langfuse', - description: 'Traces, Bewertungen, Prompt-Management und Metriken zum Debuggen und Verbessern Ihrer LLM-Anwendung.', - }, - inUse: 'In Verwendung', - configProvider: { - title: 'Konfigurieren ', - placeholder: 'Geben Sie Ihren {{key}} ein', - project: 'Projekt', - publicKey: 'Öffentlicher Schlüssel', - secretKey: 'Geheimer Schlüssel', - viewDocsLink: '{{key}}-Dokumentation ansehen', - removeConfirmTitle: '{{key}}-Konfiguration entfernen?', - removeConfirmContent: 'Die aktuelle Konfiguration wird verwendet. Das Entfernen wird die Nachverfolgungsfunktion ausschalten.', - }, - }, -} - -export default translation +const translation = { + createApp: 'Neue App erstellen', + types: { + all: 'Alle', + assistant: 'Assistent', + completion: 'Vervollständigung', + workflow: 'Arbeitsablauf', + agent: 'Agent', + chatbot: 'Chatbot', + }, + modes: { + completion: 'Textgenerator', + chat: 'Basisassistent', + }, + createFromConfigFile: 'App aus Konfigurationsdatei erstellen', + deleteAppConfirmTitle: 'Diese App löschen?', + deleteAppConfirmContent: + 'Das Löschen der App ist unwiderruflich. Nutzer werden keinen Zugang mehr zu Ihrer App haben, und alle Prompt-Konfigurationen und Logs werden dauerhaft gelöscht.', + appDeleted: 'App gelöscht', + appDeleteFailed: 'Löschen der App fehlgeschlagen', + join: 'Treten Sie der Gemeinschaft bei', + communityIntro: + 'Diskutieren Sie mit Teammitgliedern, Mitwirkenden und Entwicklern auf verschiedenen Kanälen.', + roadmap: 'Sehen Sie unseren Fahrplan', + appNamePlaceholder: 'Bitte geben Sie den Namen der App ein', + newApp: { + startToCreate: 'Lassen Sie uns mit Ihrer neuen App beginnen', + captionName: 'App-Symbol & Name', + captionAppType: 'Welchen Typ von App möchten Sie erstellen?', + previewDemo: 'Vorschau-Demo', + chatApp: 'Assistent', + chatAppIntro: + 'Ich möchte eine Chat-basierte Anwendung bauen. Diese App verwendet ein Frage-Antwort-Format und ermöglicht mehrere Runden kontinuierlicher Konversation.', + agentAssistant: 'Neuer Agentenassistent', + completeApp: 'Textgenerator', + completeAppIntro: + 'Ich möchte eine Anwendung erstellen, die hochwertigen Text basierend auf Aufforderungen generiert, wie z.B. das Erstellen von Artikeln, Zusammenfassungen, Übersetzungen und mehr.', + showTemplates: 'Ich möchte aus einer Vorlage wählen', + hideTemplates: 'Zurück zur Modusauswahl', + Create: 'Erstellen', + Cancel: 'Abbrechen', + nameNotEmpty: 'Name darf nicht leer sein', + appTemplateNotSelected: 'Bitte wählen Sie eine Vorlage', + appTypeRequired: 'Bitte wählen Sie einen App-Typ', + appCreated: 'App erstellt', + appCreateFailed: 'Erstellen der App fehlgeschlagen', + basic: 'Grundlegend', + chatbotType: 'Chatbot-Orchestrierungsmethode', + workflowDescription: 'Erstellen Sie eine Anwendung, die qualitativ hochwertigen Text auf der Grundlage von Workflow-Orchestrierungen mit einem hohen Maß an Anpassung generiert. Es ist für erfahrene Benutzer geeignet.', + advancedFor: 'Für Fortgeschrittene', + startFromTemplate: 'Aus Vorlage erstellen', + appNamePlaceholder: 'Geben Sie Ihrer App einen Namen', + startFromBlank: 'Aus Leer erstellen', + basicTip: 'Für Anfänger können Sie später zu Chatflow wechseln', + basicDescription: 'Basic Orchestrate ermöglicht die Orchestrierung einer Chatbot-App mit einfachen Einstellungen, ohne die Möglichkeit, integrierte Eingabeaufforderungen zu ändern. Es ist für Anfänger geeignet.', + workflowWarning: 'Derzeit in der Beta-Phase', + advancedDescription: 'Workflow Orchestrate orchestriert Chatbots in Form von Workflows und bietet ein hohes Maß an Individualisierung, einschließlich der Möglichkeit, integrierte Eingabeaufforderungen zu bearbeiten. Es ist für erfahrene Benutzer geeignet.', + basicFor: 'FÜR ANFÄNGER', + completionWarning: 'Diese Art von App wird nicht mehr unterstützt.', + chatbotDescription: 'Erstellen Sie eine chatbasierte Anwendung. Diese App verwendet ein Frage-und-Antwort-Format, das mehrere Runden kontinuierlicher Konversation ermöglicht.', + captionDescription: 'Beschreibung', + advanced: 'Chatflow', + useTemplate: 'Diese Vorlage verwenden', + agentDescription: 'Erstellen Sie einen intelligenten Agenten, der autonom Werkzeuge auswählen kann, um die Aufgaben zu erledigen', + completionDescription: 'Erstellen Sie eine Anwendung, die qualitativ hochwertigen Text auf der Grundlage von Eingabeaufforderungen generiert, z. B. zum Generieren von Artikeln, Zusammenfassungen, Übersetzungen und mehr.', + appDescriptionPlaceholder: 'Geben Sie die Beschreibung der App ein', + }, + editApp: 'App bearbeiten', + editAppTitle: 'App-Informationen bearbeiten', + editDone: 'App-Informationen wurden aktualisiert', + editFailed: 'Aktualisierung der App-Informationen fehlgeschlagen', + iconPicker: { + ok: 'OK', + cancel: 'Abbrechen', + emoji: 'Emoji', + image: 'Bild', + }, + switch: 'Zu Workflow-Orchestrierung wechseln', + switchTipStart: 'Eine neue App-Kopie wird für Sie erstellt, und die neue Kopie wird zur Workflow-Orchestrierung wechseln. Die neue Kopie wird ', + switchTip: 'nicht erlauben', + switchTipEnd: ' zur Basis-Orchestrierung zurückzuwechseln.', + switchLabel: 'Die zu erstellende App-Kopie', + removeOriginal: 'Ursprüngliche App löschen', + switchStart: 'Wechsel starten', + typeSelector: { + all: 'ALLE Typen', + chatbot: 'Chatbot', + agent: 'Agent', + workflow: 'Workflow', + completion: 'Vervollständigung', + }, + tracing: { + title: 'Anwendungsleistung nachverfolgen', + description: 'Konfiguration eines Drittanbieter-LLMOps-Anbieters und Nachverfolgung der Anwendungsleistung.', + config: 'Konfigurieren', + collapse: 'Einklappen', + expand: 'Ausklappen', + tracing: 'Nachverfolgung', + disabled: 'Deaktiviert', + disabledTip: 'Bitte zuerst den Anbieter konfigurieren', + enabled: 'In Betrieb', + tracingDescription: 'Erfassung des vollständigen Kontexts der Anwendungsausführung, einschließlich LLM-Aufrufe, Kontext, Prompts, HTTP-Anfragen und mehr, auf einer Nachverfolgungsplattform von Drittanbietern.', + configProviderTitle: { + configured: 'Konfiguriert', + notConfigured: 'Anbieter konfigurieren, um Nachverfolgung zu aktivieren', + moreProvider: 'Weitere Anbieter', + }, + langsmith: { + title: 'LangSmith', + description: 'Eine All-in-One-Entwicklerplattform für jeden Schritt des LLM-gesteuerten Anwendungslebenszyklus.', + }, + langfuse: { + title: 'Langfuse', + description: 'Traces, Bewertungen, Prompt-Management und Metriken zum Debuggen und Verbessern Ihrer LLM-Anwendung.', + }, + inUse: 'In Verwendung', + configProvider: { + title: 'Konfigurieren ', + placeholder: 'Geben Sie Ihren {{key}} ein', + project: 'Projekt', + publicKey: 'Öffentlicher Schlüssel', + secretKey: 'Geheimer Schlüssel', + viewDocsLink: '{{key}}-Dokumentation ansehen', + removeConfirmTitle: '{{key}}-Konfiguration entfernen?', + removeConfirmContent: 'Die aktuelle Konfiguration wird verwendet. Das Entfernen wird die Nachverfolgungsfunktion ausschalten.', + }, + view: 'Ansehen', + }, + answerIcon: { + descriptionInExplore: 'Gibt an, ob das WebApp-Symbol zum Ersetzen 🤖 in Explore verwendet werden soll', + title: 'Verwenden Sie das WebApp-Symbol, um es zu ersetzen 🤖', + description: 'Gibt an, ob das WebApp-Symbol zum Ersetzen 🤖 in der freigegebenen Anwendung verwendet werden soll', + }, + importFromDSLUrlPlaceholder: 'DSL-Link hier einfügen', + duplicate: 'Duplikat', + importFromDSL: 'Import von DSL', + importDSL: 'DSL-Datei importieren', + importFromDSLUrl: 'Von URL', + exportFailed: 'Fehler beim Exportieren von DSL.', + importFromDSLFile: 'Aus DSL-Datei', + export: 'DSL exportieren', + duplicateTitle: 'App duplizieren', +} + +export default translation diff --git a/web/i18n/de-DE/billing.ts b/web/i18n/de-DE/billing.ts index ccb35675c8..7eae078ad2 100644 --- a/web/i18n/de-DE/billing.ts +++ b/web/i18n/de-DE/billing.ts @@ -1,115 +1,118 @@ -const translation = { - currentPlan: 'Aktueller Tarif', - upgradeBtn: { - plain: 'Tarif Upgraden', - encourage: 'Jetzt Upgraden', - encourageShort: 'Upgraden', - }, - viewBilling: 'Abrechnung und Abonnements verwalten', - buyPermissionDeniedTip: 'Bitte kontaktieren Sie Ihren Unternehmensadministrator, um zu abonnieren', - plansCommon: { - title: 'Wählen Sie einen Tarif, der zu Ihnen passt', - yearlyTip: 'Erhalten Sie 2 Monate kostenlos durch jährliches Abonnieren!', - mostPopular: 'Am beliebtesten', - planRange: { - monthly: 'Monatlich', - yearly: 'Jährlich', - }, - month: 'Monat', - year: 'Jahr', - save: 'Sparen ', - free: 'Kostenlos', - currentPlan: 'Aktueller Tarif', - contractSales: 'Vertrieb kontaktieren', - contractOwner: 'Teammanager kontaktieren', - startForFree: 'Kostenlos starten', - getStartedWith: 'Beginnen Sie mit ', - contactSales: 'Vertrieb kontaktieren', - talkToSales: 'Mit dem Vertrieb sprechen', - modelProviders: 'Modellanbieter', - teamMembers: 'Teammitglieder', - buildApps: 'Apps bauen', - vectorSpace: 'Vektorraum', - vectorSpaceBillingTooltip: 'Jedes 1MB kann ungefähr 1,2 Millionen Zeichen an vektorisierten Daten speichern (geschätzt mit OpenAI Embeddings, variiert je nach Modell).', - vectorSpaceTooltip: 'Vektorraum ist das Langzeitspeichersystem, das erforderlich ist, damit LLMs Ihre Daten verstehen können.', - documentsUploadQuota: 'Dokumenten-Upload-Kontingent', - documentProcessingPriority: 'Priorität der Dokumentenverarbeitung', - documentProcessingPriorityTip: 'Für eine höhere Dokumentenverarbeitungspriorität, bitte Ihren Tarif upgraden.', - documentProcessingPriorityUpgrade: 'Mehr Daten mit höherer Genauigkeit bei schnelleren Geschwindigkeiten verarbeiten.', - priority: { - 'standard': 'Standard', - 'priority': 'Priorität', - 'top-priority': 'Höchste Priorität', - }, - logsHistory: 'Protokollverlauf', - customTools: 'Benutzerdefinierte Werkzeuge', - unavailable: 'Nicht verfügbar', - days: 'Tage', - unlimited: 'Unbegrenzt', - support: 'Support', - supportItems: { - communityForums: 'Community-Foren', - emailSupport: 'E-Mail-Support', - priorityEmail: 'Priorisierter E-Mail- und Chat-Support', - logoChange: 'Logo-Änderung', - SSOAuthentication: 'SSO-Authentifizierung', - personalizedSupport: 'Persönlicher Support', - dedicatedAPISupport: 'Dedizierter API-Support', - customIntegration: 'Benutzerdefinierte Integration und Support', - ragAPIRequest: 'RAG-API-Anfragen', - bulkUpload: 'Massenupload von Dokumenten', - agentMode: 'Agentenmodus', - workflow: 'Workflow', - }, - comingSoon: 'Demnächst', - member: 'Mitglied', - memberAfter: 'Mitglied', - messageRequest: { - title: 'Nachrichtenguthaben', - tooltip: 'Nachrichtenaufrufkontingente für verschiedene Tarife unter Verwendung von OpenAI-Modellen (außer gpt4).Nachrichten über dem Limit verwenden Ihren OpenAI-API-Schlüssel.', - }, - annotatedResponse: { - title: 'Kontingentgrenzen für Annotationen', - tooltip: 'Manuelle Bearbeitung und Annotation von Antworten bieten anpassbare, hochwertige Frage-Antwort-Fähigkeiten für Apps. (Nur anwendbar in Chat-Apps)', - }, - ragAPIRequestTooltip: 'Bezieht sich auf die Anzahl der API-Aufrufe, die nur die Wissensdatenbankverarbeitungsfähigkeiten von Dify aufrufen.', - receiptInfo: 'Nur der Teaminhaber und der Teamadministrator können abonnieren und Abrechnungsinformationen einsehen', - }, - plans: { - sandbox: { - name: 'Sandbox', - description: '200 mal GPT kostenlos testen', - includesTitle: 'Beinhaltet:', - }, - professional: { - name: 'Professionell', - description: 'Für Einzelpersonen und kleine Teams, um mehr Leistung erschwinglich freizuschalten.', - includesTitle: 'Alles im kostenlosen Tarif, plus:', - }, - team: { - name: 'Team', - description: 'Zusammenarbeiten ohne Grenzen und Top-Leistung genießen.', - includesTitle: 'Alles im Professionell-Tarif, plus:', - }, - enterprise: { - name: 'Unternehmen', - description: 'Erhalten Sie volle Fähigkeiten und Unterstützung für großangelegte, missionskritische Systeme.', - includesTitle: 'Alles im Team-Tarif, plus:', - }, - }, - vectorSpace: { - fullTip: 'Vektorraum ist voll.', - fullSolution: 'Upgraden Sie Ihren Tarif, um mehr Speicherplatz zu erhalten.', - }, - apps: { - fullTipLine1: 'Upgraden Sie Ihren Tarif, um', - fullTipLine2: 'mehr Apps zu bauen.', - }, - annotatedResponse: { - fullTipLine1: 'Upgraden Sie Ihren Tarif, um', - fullTipLine2: 'mehr Konversationen zu annotieren.', - quotaTitle: 'Kontingent für Annotation-Antworten', - }, -} - -export default translation +const translation = { + currentPlan: 'Aktueller Tarif', + upgradeBtn: { + plain: 'Tarif Upgraden', + encourage: 'Jetzt Upgraden', + encourageShort: 'Upgraden', + }, + viewBilling: 'Abrechnung und Abonnements verwalten', + buyPermissionDeniedTip: 'Bitte kontaktieren Sie Ihren Unternehmensadministrator, um zu abonnieren', + plansCommon: { + title: 'Wählen Sie einen Tarif, der zu Ihnen passt', + yearlyTip: 'Erhalten Sie 2 Monate kostenlos durch jährliches Abonnieren!', + mostPopular: 'Am beliebtesten', + planRange: { + monthly: 'Monatlich', + yearly: 'Jährlich', + }, + month: 'Monat', + year: 'Jahr', + save: 'Sparen ', + free: 'Kostenlos', + currentPlan: 'Aktueller Tarif', + contractSales: 'Vertrieb kontaktieren', + contractOwner: 'Teammanager kontaktieren', + startForFree: 'Kostenlos starten', + getStartedWith: 'Beginnen Sie mit ', + contactSales: 'Vertrieb kontaktieren', + talkToSales: 'Mit dem Vertrieb sprechen', + modelProviders: 'Modellanbieter', + teamMembers: 'Teammitglieder', + buildApps: 'Apps bauen', + vectorSpace: 'Vektorraum', + vectorSpaceBillingTooltip: 'Jedes 1MB kann ungefähr 1,2 Millionen Zeichen an vektorisierten Daten speichern (geschätzt mit OpenAI Embeddings, variiert je nach Modell).', + vectorSpaceTooltip: 'Vektorraum ist das Langzeitspeichersystem, das erforderlich ist, damit LLMs Ihre Daten verstehen können.', + documentsUploadQuota: 'Dokumenten-Upload-Kontingent', + documentProcessingPriority: 'Priorität der Dokumentenverarbeitung', + documentProcessingPriorityTip: 'Für eine höhere Dokumentenverarbeitungspriorität, bitte Ihren Tarif upgraden.', + documentProcessingPriorityUpgrade: 'Mehr Daten mit höherer Genauigkeit bei schnelleren Geschwindigkeiten verarbeiten.', + priority: { + 'standard': 'Standard', + 'priority': 'Priorität', + 'top-priority': 'Höchste Priorität', + }, + logsHistory: 'Protokollverlauf', + customTools: 'Benutzerdefinierte Werkzeuge', + unavailable: 'Nicht verfügbar', + days: 'Tage', + unlimited: 'Unbegrenzt', + support: 'Support', + supportItems: { + communityForums: 'Community-Foren', + emailSupport: 'E-Mail-Support', + priorityEmail: 'Priorisierter E-Mail- und Chat-Support', + logoChange: 'Logo-Änderung', + SSOAuthentication: 'SSO-Authentifizierung', + personalizedSupport: 'Persönlicher Support', + dedicatedAPISupport: 'Dedizierter API-Support', + customIntegration: 'Benutzerdefinierte Integration und Support', + ragAPIRequest: 'RAG-API-Anfragen', + bulkUpload: 'Massenupload von Dokumenten', + agentMode: 'Agentenmodus', + workflow: 'Workflow', + llmLoadingBalancing: 'LLM-Lastausgleich', + llmLoadingBalancingTooltip: 'Fügen Sie Modellen mehrere API-Schlüssel hinzu, um die API-Ratenlimits effektiv zu umgehen.', + }, + comingSoon: 'Demnächst', + member: 'Mitglied', + memberAfter: 'Mitglied', + messageRequest: { + title: 'Nachrichtenguthaben', + tooltip: 'Nachrichtenaufrufkontingente für verschiedene Tarife unter Verwendung von OpenAI-Modellen (außer gpt4).Nachrichten über dem Limit verwenden Ihren OpenAI-API-Schlüssel.', + }, + annotatedResponse: { + title: 'Kontingentgrenzen für Annotationen', + tooltip: 'Manuelle Bearbeitung und Annotation von Antworten bieten anpassbare, hochwertige Frage-Antwort-Fähigkeiten für Apps. (Nur anwendbar in Chat-Apps)', + }, + ragAPIRequestTooltip: 'Bezieht sich auf die Anzahl der API-Aufrufe, die nur die Wissensdatenbankverarbeitungsfähigkeiten von Dify aufrufen.', + receiptInfo: 'Nur der Teaminhaber und der Teamadministrator können abonnieren und Abrechnungsinformationen einsehen', + annotationQuota: 'Kontingent für Anmerkungen', + }, + plans: { + sandbox: { + name: 'Sandbox', + description: '200 mal GPT kostenlos testen', + includesTitle: 'Beinhaltet:', + }, + professional: { + name: 'Professionell', + description: 'Für Einzelpersonen und kleine Teams, um mehr Leistung erschwinglich freizuschalten.', + includesTitle: 'Alles im kostenlosen Tarif, plus:', + }, + team: { + name: 'Team', + description: 'Zusammenarbeiten ohne Grenzen und Top-Leistung genießen.', + includesTitle: 'Alles im Professionell-Tarif, plus:', + }, + enterprise: { + name: 'Unternehmen', + description: 'Erhalten Sie volle Fähigkeiten und Unterstützung für großangelegte, missionskritische Systeme.', + includesTitle: 'Alles im Team-Tarif, plus:', + }, + }, + vectorSpace: { + fullTip: 'Vektorraum ist voll.', + fullSolution: 'Upgraden Sie Ihren Tarif, um mehr Speicherplatz zu erhalten.', + }, + apps: { + fullTipLine1: 'Upgraden Sie Ihren Tarif, um', + fullTipLine2: 'mehr Apps zu bauen.', + }, + annotatedResponse: { + fullTipLine1: 'Upgraden Sie Ihren Tarif, um', + fullTipLine2: 'mehr Konversationen zu annotieren.', + quotaTitle: 'Kontingent für Annotation-Antworten', + }, +} + +export default translation diff --git a/web/i18n/de-DE/common.ts b/web/i18n/de-DE/common.ts index 9a66d5b175..6ea06bc8b1 100644 --- a/web/i18n/de-DE/common.ts +++ b/web/i18n/de-DE/common.ts @@ -37,6 +37,7 @@ const translation = { params: 'Parameter', duplicate: 'Duplikat', rename: 'Umbenennen', + audioSourceUnavailable: 'AudioSource ist nicht verfügbar', }, placeholder: { input: 'Bitte eingeben', @@ -128,7 +129,8 @@ const translation = { workspace: 'Arbeitsbereich', createWorkspace: 'Arbeitsbereich erstellen', helpCenter: 'Hilfe', - roadmapAndFeedback: 'Feedback', + communityFeedback: 'Rückmeldung', + roadmap: 'Fahrplan', community: 'Gemeinschaft', about: 'Über', logout: 'Abmelden', @@ -190,16 +192,21 @@ const translation = { invitationSent: 'Einladung gesendet', invitationSentTip: 'Einladung gesendet, und sie können sich bei Dify anmelden, um auf Ihre Teamdaten zuzugreifen.', invitationLink: 'Einladungslink', - failedinvitationEmails: 'Die folgenden Benutzer wurden nicht erfolgreich eingeladen', + failedInvitationEmails: 'Die folgenden Benutzer wurden nicht erfolgreich eingeladen', ok: 'OK', removeFromTeam: 'Vom Team entfernen', removeFromTeamTip: 'Wird den Teamzugang entfernen', setAdmin: 'Als Administrator einstellen', setMember: 'Als normales Mitglied einstellen', setEditor: 'Als Editor einstellen', - disinvite: 'Einladung widerrufen', + disInvite: 'Einladung widerrufen', deleteMember: 'Mitglied löschen', you: '(Du)', + setBuilder: 'Als Builder festlegen', + datasetOperator: 'Wissensadministrator', + datasetOperatorTip: 'Kann die Wissensdatenbank nur verwalten', + builder: 'Bauherr', + builderTip: 'Kann eigene Apps erstellen und bearbeiten', }, integrations: { connected: 'Verbunden', @@ -346,6 +353,22 @@ const translation = { quotaTip: 'Verbleibende verfügbare kostenlose Token', loadPresets: 'Voreinstellungen laden', parameters: 'PARAMETER', + loadBalancingHeadline: 'Lastenausgleich', + apiKey: 'API-SCHLÜSSEL', + editConfig: 'Konfiguration bearbeiten', + loadBalancing: 'Lastenausgleich', + addConfig: 'Konfiguration hinzufügen', + configLoadBalancing: 'Lastenausgleich für die Konfiguration', + providerManagedDescription: 'Verwenden Sie den einzelnen Satz von Anmeldeinformationen, der vom Modellanbieter bereitgestellt wird.', + loadBalancingDescription: 'Reduzieren Sie den Druck mit mehreren Sätzen von Anmeldeinformationen.', + modelHasBeenDeprecated: 'Dieses Modell ist veraltet', + loadBalancingLeastKeyWarning: 'Um den Lastausgleich zu aktivieren, müssen mindestens 2 Schlüssel aktiviert sein.', + providerManaged: 'Vom Anbieter verwaltet', + apiKeyStatusNormal: 'APIKey-Status ist normal', + upgradeForLoadBalancing: 'Aktualisieren Sie Ihren Plan, um den Lastenausgleich zu aktivieren.', + defaultConfig: 'Standardkonfiguration', + apiKeyRateLimit: 'Ratenlimit wurde erreicht, verfügbar nach {{seconds}}s', + loadBalancingInfo: 'Standardmäßig wird für den Lastenausgleich die Round-Robin-Strategie verwendet. Wenn die Ratenbegrenzung ausgelöst wird, wird eine Abklingzeit von 1 Minute angewendet.', }, dataSource: { add: 'Eine Datenquelle hinzufügen', @@ -369,6 +392,15 @@ const translation = { preview: 'VORSCHAU', }, }, + website: { + inactive: 'Inaktiv', + description: 'Importieren Sie Inhalte von Websites mit dem Webcrawler.', + title: 'Website', + configuredCrawlers: 'Konfigurierte Crawler', + active: 'Aktiv', + with: 'Mit', + }, + configure: 'Konfigurieren', }, plugin: { serpapi: { @@ -417,6 +449,7 @@ const translation = { promptEng: 'Orchestrieren', apiAccess: 'API-Zugriff', logAndAnn: 'Protokolle & Ank.', + logs: 'Baumstämme', }, environment: { testing: 'TESTEN', @@ -498,6 +531,10 @@ const translation = { add: 'Neue Variable', addTool: 'Neues Werkzeug', }, + outputToolDisabledItem: { + desc: 'Variablen einfügen', + title: 'Variablen', + }, }, query: { item: { @@ -532,6 +569,10 @@ const translation = { created: 'Tag erfolgreich erstellt', failed: 'Tag-Erstellung fehlgeschlagen', }, + errorMsg: { + fieldRequired: '{{field}} ist erforderlich', + urlError: 'Die URL sollte mit http:// oder https:// beginnen', + }, } export default translation diff --git a/web/i18n/de-DE/custom.ts b/web/i18n/de-DE/custom.ts index c24ebca696..2f4cabd67d 100644 --- a/web/i18n/de-DE/custom.ts +++ b/web/i18n/de-DE/custom.ts @@ -1,30 +1,30 @@ -const translation = { - custom: 'Anpassung', - upgradeTip: { - prefix: 'Erweitere deinen Plan auf', - suffix: 'um deine Marke anzupassen.', - }, - webapp: { - title: 'WebApp Marke anpassen', - removeBrand: 'Entferne Powered by Dify', - changeLogo: 'Ändere Powered by Markenbild', - changeLogoTip: 'SVG oder PNG Format mit einer Mindestgröße von 40x40px', - }, - app: { - title: 'App Kopfzeilen Marke anpassen', - changeLogoTip: 'SVG oder PNG Format mit einer Mindestgröße von 80x80px', - }, - upload: 'Hochladen', - uploading: 'Lade hoch', - uploadedFail: 'Bild-Upload fehlgeschlagen, bitte erneut hochladen.', - change: 'Ändern', - apply: 'Anwenden', - restore: 'Standardeinstellungen wiederherstellen', - customize: { - contactUs: ' kontaktiere uns ', - prefix: 'Um das Markenlogo innerhalb der App anzupassen, bitte', - suffix: 'um auf die Enterprise-Edition zu upgraden.', - }, -} - -export default translation +const translation = { + custom: 'Anpassung', + upgradeTip: { + prefix: 'Erweitere deinen Plan auf', + suffix: 'um deine Marke anzupassen.', + }, + webapp: { + title: 'WebApp Marke anpassen', + removeBrand: 'Entferne Powered by Dify', + changeLogo: 'Ändere Powered by Markenbild', + changeLogoTip: 'SVG oder PNG Format mit einer Mindestgröße von 40x40px', + }, + app: { + title: 'App Kopfzeilen Marke anpassen', + changeLogoTip: 'SVG oder PNG Format mit einer Mindestgröße von 80x80px', + }, + upload: 'Hochladen', + uploading: 'Lade hoch', + uploadedFail: 'Bild-Upload fehlgeschlagen, bitte erneut hochladen.', + change: 'Ändern', + apply: 'Anwenden', + restore: 'Standardeinstellungen wiederherstellen', + customize: { + contactUs: ' kontaktiere uns ', + prefix: 'Um das Markenlogo innerhalb der App anzupassen, bitte', + suffix: 'um auf die Enterprise-Edition zu upgraden.', + }, +} + +export default translation diff --git a/web/i18n/de-DE/dataset-creation.ts b/web/i18n/de-DE/dataset-creation.ts index 8727457759..8b27395049 100644 --- a/web/i18n/de-DE/dataset-creation.ts +++ b/web/i18n/de-DE/dataset-creation.ts @@ -1,130 +1,161 @@ -const translation = { - steps: { - header: { - creation: 'Wissen erstellen', - update: 'Daten hinzufügen', - }, - one: 'Datenquelle wählen', - two: 'Textvorverarbeitung und Bereinigung', - three: 'Ausführen und beenden', - }, - error: { - unavailable: 'Dieses Wissen ist nicht verfügbar', - }, - stepOne: { - filePreview: 'Dateivorschau', - pagePreview: 'Seitenvorschau', - dataSourceType: { - file: 'Import aus Textdatei', - notion: 'Synchronisation aus Notion', - web: 'Synchronisation von Webseite', - }, - uploader: { - title: 'Textdatei hochladen', - button: 'Datei hierher ziehen oder', - browse: 'Durchsuchen', - tip: 'Unterstützt {{supportTypes}}. Maximal {{size}}MB pro Datei.', - validation: { - typeError: 'Dateityp nicht unterstützt', - size: 'Datei zu groß. Maximum ist {{size}}MB', - count: 'Mehrere Dateien nicht unterstützt', - filesNumber: 'Sie haben das Limit für die Stapelverarbeitung von {{filesNumber}} erreicht.', - }, - cancel: 'Abbrechen', - change: 'Ändern', - failed: 'Hochladen fehlgeschlagen', - }, - notionSyncTitle: 'Notion ist nicht verbunden', - notionSyncTip: 'Um mit Notion zu synchronisieren, muss zuerst eine Verbindung zu Notion hergestellt werden.', - connect: 'Verbinden gehen', - button: 'weiter', - emptyDatasetCreation: 'Ich möchte ein leeres Wissen erstellen', - modal: { - title: 'Ein leeres Wissen erstellen', - tip: 'Ein leeres Wissen enthält keine Dokumente, und Sie können jederzeit Dokumente hochladen.', - input: 'Wissensname', - placeholder: 'Bitte eingeben', - nameNotEmpty: 'Name darf nicht leer sein', - nameLengthInvaild: 'Name muss zwischen 1 bis 40 Zeichen lang sein', - cancelButton: 'Abbrechen', - confirmButton: 'Erstellen', - failed: 'Erstellung fehlgeschlagen', - }, - }, - stepTwo: { - segmentation: 'Chunk-Einstellungen', - auto: 'Automatisch', - autoDescription: 'Stellt Chunk- und Vorverarbeitungsregeln automatisch ein. Unbekannten Benutzern wird dies empfohlen.', - custom: 'Benutzerdefiniert', - customDescription: 'Chunk-Regeln, Chunk-Länge und Vorverarbeitungsregeln usw. anpassen.', - separator: 'Segmentidentifikator', - separatorPlaceholder: 'Zum Beispiel Neuer Absatz (\\\\n) oder spezieller Separator (wie "***")', - maxLength: 'Maximale Chunk-Länge', - overlap: 'Chunk-Überlappung', - overlapTip: 'Die Einstellung der Chunk-Überlappung kann die semantische Relevanz zwischen ihnen aufrechterhalten und so die Abrufeffekt verbessern. Es wird empfohlen, 10%-25% der maximalen Chunk-Größe einzustellen.', - overlapCheck: 'Chunk-Überlappung sollte nicht größer als maximale Chunk-Länge sein', - rules: 'Textvorverarbeitungsregeln', - removeExtraSpaces: 'Mehrfache Leerzeichen, Zeilenumbrüche und Tabulatoren ersetzen', - removeUrlEmails: 'Alle URLs und E-Mail-Adressen löschen', - removeStopwords: 'Stopwörter wie "ein", "eine", "der" entfernen', - preview: 'Bestätigen & Vorschau', - reset: 'Zurücksetzen', - indexMode: 'Indexmodus', - qualified: 'Hohe Qualität', - recommend: 'Empfehlen', - qualifiedTip: 'Ruft standardmäßige Systemeinbettungsschnittstelle für die Verarbeitung auf, um höhere Genauigkeit bei Benutzerabfragen zu bieten.', - warning: 'Bitte zuerst den API-Schlüssel des Modellanbieters einrichten.', - click: 'Zu den Einstellungen gehen', - economical: 'Ökonomisch', - economicalTip: 'Verwendet Offline-Vektor-Engines, Schlagwortindizes usw., um die Genauigkeit ohne Tokenverbrauch zu reduzieren', - QATitle: 'Segmentierung im Frage-und-Antwort-Format', - QATip: 'Diese Option zu aktivieren, wird mehr Tokens verbrauchen', - QALanguage: 'Segmentierung verwenden', - emstimateCost: 'Schätzung', - emstimateSegment: 'Geschätzte Chunks', - segmentCount: 'Chunks', - calculating: 'Berechnung...', - fileSource: 'Dokumente vorverarbeiten', - notionSource: 'Seiten vorverarbeiten', - other: 'und weitere ', - fileUnit: ' Dateien', - notionUnit: ' Seiten', - previousStep: 'Vorheriger Schritt', - nextStep: 'Speichern & Verarbeiten', - save: 'Speichern & Verarbeiten', - cancel: 'Abbrechen', - sideTipTitle: 'Warum segmentieren und vorverarbeiten?', - sideTipP1: 'Bei der Verarbeitung von Textdaten sind Segmentierung und Bereinigung zwei wichtige Vorverarbeitungsschritte.', - sideTipP2: 'Segmentierung teilt langen Text in Absätze, damit Modelle ihn besser verstehen können. Dies verbessert die Qualität und Relevanz der Modellergebnisse.', - sideTipP3: 'Bereinigung entfernt unnötige Zeichen und Formate, macht das Wissen sauberer und leichter zu parsen.', - sideTipP4: 'Richtige Segmentierung und Bereinigung verbessern die Modellleistung und liefern genauere und wertvollere Ergebnisse.', - previewTitle: 'Vorschau', - previewTitleButton: 'Vorschau', - previewButton: 'Umschalten zum Frage-und-Antwort-Format', - previewSwitchTipStart: 'Die aktuelle Chunk-Vorschau ist im Textformat, ein Wechsel zur Vorschau im Frage-und-Antwort-Format wird', - previewSwitchTipEnd: ' zusätzliche Tokens verbrauchen', - characters: 'Zeichen', - indexSettedTip: 'Um die Indexmethode zu ändern, bitte gehen Sie zu den ', - retrivalSettedTip: 'Um die Indexmethode zu ändern, bitte gehen Sie zu den ', - datasetSettingLink: 'Wissenseinstellungen.', - }, - stepThree: { - creationTitle: '🎉 Wissen erstellt', - creationContent: 'Wir haben das Wissen automatisch benannt, Sie können es jederzeit ändern', - label: 'Wissensname', - additionTitle: '🎉 Dokument hochgeladen', - additionP1: 'Das Dokument wurde zum Wissen hinzugefügt', - additionP2: ', Sie können es in der Dokumentenliste des Wissens finden.', - stop: 'Verarbeitung stoppen', - resume: 'Verarbeitung fortsetzen', - navTo: 'Zum Dokument gehen', - sideTipTitle: 'Was kommt als Nächstes', - sideTipContent: 'Nachdem das Dokument indiziert wurde, kann das Wissen in die Anwendung als Kontext integriert werden, Sie finden die Kontexteinstellung auf der Seite zur Eingabeaufforderungen-Orchestrierung. Sie können es auch als unabhängiges ChatGPT-Indexierungsplugin zur Veröffentlichung erstellen.', - modelTitle: 'Sind Sie sicher, dass Sie die Einbettung stoppen möchten?', - modelContent: 'Wenn Sie die Verarbeitung später fortsetzen möchten, werden Sie dort weitermachen, wo Sie aufgehört haben.', - modelButtonConfirm: 'Bestätigen', - modelButtonCancel: 'Abbrechen', - }, -} - -export default translation +const translation = { + steps: { + header: { + creation: 'Wissen erstellen', + update: 'Daten hinzufügen', + }, + one: 'Datenquelle wählen', + two: 'Textvorverarbeitung und Bereinigung', + three: 'Ausführen und beenden', + }, + error: { + unavailable: 'Dieses Wissen ist nicht verfügbar', + }, + stepOne: { + filePreview: 'Dateivorschau', + pagePreview: 'Seitenvorschau', + dataSourceType: { + file: 'Import aus Textdatei', + notion: 'Synchronisation aus Notion', + web: 'Synchronisation von Webseite', + }, + uploader: { + title: 'Textdatei hochladen', + button: 'Datei hierher ziehen oder', + browse: 'Durchsuchen', + tip: 'Unterstützt {{supportTypes}}. Maximal {{size}}MB pro Datei.', + validation: { + typeError: 'Dateityp nicht unterstützt', + size: 'Datei zu groß. Maximum ist {{size}}MB', + count: 'Mehrere Dateien nicht unterstützt', + filesNumber: 'Sie haben das Limit für die Stapelverarbeitung von {{filesNumber}} erreicht.', + }, + cancel: 'Abbrechen', + change: 'Ändern', + failed: 'Hochladen fehlgeschlagen', + }, + notionSyncTitle: 'Notion ist nicht verbunden', + notionSyncTip: 'Um mit Notion zu synchronisieren, muss zuerst eine Verbindung zu Notion hergestellt werden.', + connect: 'Verbinden gehen', + button: 'weiter', + emptyDatasetCreation: 'Ich möchte ein leeres Wissen erstellen', + modal: { + title: 'Ein leeres Wissen erstellen', + tip: 'Ein leeres Wissen enthält keine Dokumente, und Sie können jederzeit Dokumente hochladen.', + input: 'Wissensname', + placeholder: 'Bitte eingeben', + nameNotEmpty: 'Name darf nicht leer sein', + nameLengthInvalid: 'Name muss zwischen 1 bis 40 Zeichen lang sein', + cancelButton: 'Abbrechen', + confirmButton: 'Erstellen', + failed: 'Erstellung fehlgeschlagen', + }, + website: { + preview: 'Vorschau', + totalPageScraped: 'Gesamtzahl der gescrapten Seiten:', + fireCrawlNotConfigured: 'Firecrawl ist nicht konfiguriert', + options: 'Optionen', + excludePaths: 'Pfade ausschließen', + limit: 'Grenze', + exceptionErrorTitle: 'Beim Ausführen des Firecrawl-Auftrags ist eine Ausnahme aufgetreten:', + selectAll: 'Alles auswählen', + includeOnlyPaths: 'Nur Pfade einschließen', + run: 'Laufen', + firecrawlDoc: 'Firecrawl-Dokumente', + configure: 'Konfigurieren', + fireCrawlNotConfiguredDescription: 'Konfigurieren Sie Firecrawl mit dem API-Schlüssel, um es zu verwenden.', + maxDepth: 'Maximale Tiefe', + unknownError: 'Unbekannter Fehler', + resetAll: 'Alles zurücksetzen', + extractOnlyMainContent: 'Extrahieren Sie nur den Hauptinhalt (keine Kopf-, Navigations- und Fußzeilen usw.)', + firecrawlDocLink: 'https://docs.dify.ai/guides/knowledge-base/sync-from-website', + firecrawlTitle: 'Extrahieren von Webinhalten mit 🔥Firecrawl', + maxDepthTooltip: 'Maximale Tiefe für das Crawlen relativ zur eingegebenen URL. Tiefe 0 kratzt nur die Seite der eingegebenen URL, Tiefe 1 kratzt die URL und alles nach der eingegebenen URL + ein / und so weiter.', + crawlSubPage: 'Unterseiten crawlen', + scrapTimeInfo: 'Insgesamt {{{total}} Seiten innerhalb von {{time}}s gescrapt', + }, + }, + stepTwo: { + segmentation: 'Chunk-Einstellungen', + auto: 'Automatisch', + autoDescription: 'Stellt Chunk- und Vorverarbeitungsregeln automatisch ein. Unbekannten Benutzern wird dies empfohlen.', + custom: 'Benutzerdefiniert', + customDescription: 'Chunk-Regeln, Chunk-Länge und Vorverarbeitungsregeln usw. anpassen.', + separator: 'Segmentidentifikator', + separatorPlaceholder: 'Zum Beispiel Neuer Absatz (\\\\n) oder spezieller Separator (wie "***")', + maxLength: 'Maximale Chunk-Länge', + overlap: 'Chunk-Überlappung', + overlapTip: 'Die Einstellung der Chunk-Überlappung kann die semantische Relevanz zwischen ihnen aufrechterhalten und so die Abrufeffekt verbessern. Es wird empfohlen, 10%-25% der maximalen Chunk-Größe einzustellen.', + overlapCheck: 'Chunk-Überlappung sollte nicht größer als maximale Chunk-Länge sein', + rules: 'Textvorverarbeitungsregeln', + removeExtraSpaces: 'Mehrfache Leerzeichen, Zeilenumbrüche und Tabulatoren ersetzen', + removeUrlEmails: 'Alle URLs und E-Mail-Adressen löschen', + removeStopwords: 'Stopwörter wie "ein", "eine", "der" entfernen', + preview: 'Bestätigen & Vorschau', + reset: 'Zurücksetzen', + indexMode: 'Indexmodus', + qualified: 'Hohe Qualität', + recommend: 'Empfehlen', + qualifiedTip: 'Ruft standardmäßige Systemeinbettungsschnittstelle für die Verarbeitung auf, um höhere Genauigkeit bei Benutzerabfragen zu bieten.', + warning: 'Bitte zuerst den API-Schlüssel des Modellanbieters einrichten.', + click: 'Zu den Einstellungen gehen', + economical: 'Ökonomisch', + economicalTip: 'Verwendet Offline-Vektor-Engines, Schlagwortindizes usw., um die Genauigkeit ohne Tokenverbrauch zu reduzieren', + QATitle: 'Segmentierung im Frage-und-Antwort-Format', + QATip: 'Diese Option zu aktivieren, wird mehr Tokens verbrauchen', + QALanguage: 'Segmentierung verwenden', + estimateCost: 'Schätzung', + estimateSegment: 'Geschätzte Chunks', + segmentCount: 'Chunks', + calculating: 'Berechnung...', + fileSource: 'Dokumente vorverarbeiten', + notionSource: 'Seiten vorverarbeiten', + other: 'und weitere ', + fileUnit: ' Dateien', + notionUnit: ' Seiten', + previousStep: 'Vorheriger Schritt', + nextStep: 'Speichern & Verarbeiten', + save: 'Speichern & Verarbeiten', + cancel: 'Abbrechen', + sideTipTitle: 'Warum segmentieren und vorverarbeiten?', + sideTipP1: 'Bei der Verarbeitung von Textdaten sind Segmentierung und Bereinigung zwei wichtige Vorverarbeitungsschritte.', + sideTipP2: 'Segmentierung teilt langen Text in Absätze, damit Modelle ihn besser verstehen können. Dies verbessert die Qualität und Relevanz der Modellergebnisse.', + sideTipP3: 'Bereinigung entfernt unnötige Zeichen und Formate, macht das Wissen sauberer und leichter zu parsen.', + sideTipP4: 'Richtige Segmentierung und Bereinigung verbessern die Modellleistung und liefern genauere und wertvollere Ergebnisse.', + previewTitle: 'Vorschau', + previewTitleButton: 'Vorschau', + previewButton: 'Umschalten zum Frage-und-Antwort-Format', + previewSwitchTipStart: 'Die aktuelle Chunk-Vorschau ist im Textformat, ein Wechsel zur Vorschau im Frage-und-Antwort-Format wird', + previewSwitchTipEnd: ' zusätzliche Tokens verbrauchen', + characters: 'Zeichen', + indexSettingTip: 'Um die Indexmethode zu ändern, bitte gehen Sie zu den ', + retrievalSettingTip: 'Um die Indexmethode zu ändern, bitte gehen Sie zu den ', + datasetSettingLink: 'Wissenseinstellungen.', + websiteSource: 'Preprocess-Website', + webpageUnit: 'Seiten', + }, + stepThree: { + creationTitle: '🎉 Wissen erstellt', + creationContent: 'Wir haben das Wissen automatisch benannt, Sie können es jederzeit ändern', + label: 'Wissensname', + additionTitle: '🎉 Dokument hochgeladen', + additionP1: 'Das Dokument wurde zum Wissen hinzugefügt', + additionP2: ', Sie können es in der Dokumentenliste des Wissens finden.', + stop: 'Verarbeitung stoppen', + resume: 'Verarbeitung fortsetzen', + navTo: 'Zum Dokument gehen', + sideTipTitle: 'Was kommt als Nächstes', + sideTipContent: 'Nachdem das Dokument indiziert wurde, kann das Wissen in die Anwendung als Kontext integriert werden, Sie finden die Kontexteinstellung auf der Seite zur Eingabeaufforderungen-Orchestrierung. Sie können es auch als unabhängiges ChatGPT-Indexierungsplugin zur Veröffentlichung erstellen.', + modelTitle: 'Sind Sie sicher, dass Sie die Einbettung stoppen möchten?', + modelContent: 'Wenn Sie die Verarbeitung später fortsetzen möchten, werden Sie dort weitermachen, wo Sie aufgehört haben.', + modelButtonConfirm: 'Bestätigen', + modelButtonCancel: 'Abbrechen', + }, + firecrawl: { + apiKeyPlaceholder: 'API-Schlüssel von firecrawl.dev', + configFirecrawl: 'Konfigurieren von 🔥Firecrawl', + getApiKeyLinkText: 'Holen Sie sich Ihren API-Schlüssel von firecrawl.dev', + }, +} + +export default translation diff --git a/web/i18n/de-DE/dataset-documents.ts b/web/i18n/de-DE/dataset-documents.ts index e72f808392..114a73544d 100644 --- a/web/i18n/de-DE/dataset-documents.ts +++ b/web/i18n/de-DE/dataset-documents.ts @@ -1,349 +1,352 @@ -const translation = { - list: { - title: 'Dokumente', - desc: 'Alle Dateien des Wissens werden hier angezeigt, und das gesamte Wissen kann mit Dify-Zitaten verknüpft oder über das Chat-Plugin indiziert werden.', - addFile: 'Datei hinzufügen', - addPages: 'Seiten hinzufügen', - table: { - header: { - fileName: 'DATEINAME', - words: 'WÖRTER', - hitCount: 'SUCHANFRAGEN', - uploadTime: 'HOCHLADEZEIT', - status: 'STATUS', - action: 'AKTION', - }, - }, - action: { - uploadFile: 'Neue Datei hochladen', - settings: 'Segment-Einstellungen', - addButton: 'Chunk hinzufügen', - add: 'Einen Chunk hinzufügen', - batchAdd: 'Batch hinzufügen', - archive: 'Archivieren', - unarchive: 'Archivierung aufheben', - delete: 'Löschen', - enableWarning: 'Archivierte Datei kann nicht aktiviert werden', - sync: 'Synchronisieren', - }, - index: { - enable: 'Aktivieren', - disable: 'Deaktivieren', - all: 'Alle', - enableTip: 'Die Datei kann indiziert werden', - disableTip: 'Die Datei kann nicht indiziert werden', - }, - status: { - queuing: 'In Warteschlange', - indexing: 'Indizierung', - paused: 'Pausiert', - error: 'Fehler', - available: 'Verfügbar', - enabled: 'Aktiviert', - disabled: 'Deaktiviert', - archived: 'Archiviert', - }, - empty: { - title: 'Es gibt noch keine Dokumentation', - upload: { - tip: 'Sie können Dateien hochladen, von der Website oder von Web-Apps wie Notion, GitHub usw. synchronisieren.', - }, - sync: { - tip: 'Dify wird periodisch Dateien von Ihrem Notion herunterladen und die Verarbeitung abschließen.', - }, - }, - delete: { - title: 'Sind Sie sicher, dass Sie löschen möchten?', - content: 'Wenn Sie die Verarbeitung später fortsetzen müssen, werden Sie dort weitermachen, wo Sie aufgehört haben', - }, - batchModal: { - title: 'Chunks in Batch hinzufügen', - csvUploadTitle: 'Ziehen Sie Ihre CSV-Datei hierher oder ', - browse: 'durchsuchen', - tip: 'Die CSV-Datei muss der folgenden Struktur entsprechen:', - question: 'Frage', - answer: 'Antwort', - contentTitle: 'Chunk-Inhalt', - content: 'Inhalt', - template: 'Laden Sie die Vorlage hier herunter', - cancel: 'Abbrechen', - run: 'Batch ausführen', - runError: 'Batch-Ausführung fehlgeschlagen', - processing: 'In Batch-Verarbeitung', - completed: 'Import abgeschlossen', - error: 'Importfehler', - ok: 'OK', - }, - }, - metadata: { - title: 'Metadaten', - desc: 'Das Kennzeichnen von Metadaten für Dokumente ermöglicht es der KI, sie rechtzeitig zu erreichen und die Quelle der Referenzen für die Benutzer offenzulegen.', - dateTimeFormat: 'MMMM D, YYYY hh:mm A', - docTypeSelectTitle: 'Bitte wählen Sie einen Dokumenttyp', - docTypeChangeTitle: 'Dokumenttyp ändern', - docTypeSelectWarning: - 'Wenn der Dokumenttyp geändert wird, werden die jetzt ausgefüllten Metadaten nicht mehr erhalten bleiben', - firstMetaAction: 'Los geht\'s', - placeholder: { - add: 'Hinzufügen ', - select: 'Auswählen ', - }, - source: { - upload_file: 'Datei hochladen', - notion: 'Von Notion synchronisieren', - github: 'Von Github synchronisieren', - }, - type: { - book: 'Buch', - webPage: 'Webseite', - paper: 'Aufsatz', - socialMediaPost: 'Social Media Beitrag', - personalDocument: 'Persönliches Dokument', - businessDocument: 'Geschäftsdokument', - IMChat: 'IM Chat', - wikipediaEntry: 'Wikipedia-Eintrag', - notion: 'Von Notion synchronisieren', - github: 'Von Github synchronisieren', - technicalParameters: 'Technische Parameter', - }, - field: { - processRule: { - processDoc: 'Dokument verarbeiten', - segmentRule: 'Chunk-Regel', - segmentLength: 'Chunk-Länge', - processClean: 'Textverarbeitung bereinigen', - }, - book: { - title: 'Titel', - language: 'Sprache', - author: 'Autor', - publisher: 'Verlag', - publicationDate: 'Veröffentlichungsdatum', - ISBN: 'ISBN', - category: 'Kategorie', - }, - webPage: { - title: 'Titel', - url: 'URL', - language: 'Sprache', - authorPublisher: 'Autor/Verlag', - publishDate: 'Veröffentlichungsdatum', - topicsKeywords: 'Themen/Schlüsselwörter', - description: 'Beschreibung', - }, - paper: { - title: 'Titel', - language: 'Sprache', - author: 'Autor', - publishDate: 'Veröffentlichungsdatum', - journalConferenceName: 'Zeitschrift/Konferenzname', - volumeIssuePage: 'Band/Ausgabe/Seite', - DOI: 'DOI', - topicsKeywords: 'Themen/Schlüsselwörter', - abstract: 'Zusammenfassung', - }, - socialMediaPost: { - platform: 'Plattform', - authorUsername: 'Autor/Benutzername', - publishDate: 'Veröffentlichungsdatum', - postURL: 'Beitrags-URL', - topicsTags: 'Themen/Tags', - }, - personalDocument: { - title: 'Titel', - author: 'Autor', - creationDate: 'Erstellungsdatum', - lastModifiedDate: 'Letztes Änderungsdatum', - documentType: 'Dokumenttyp', - tagsCategory: 'Tags/Kategorie', - }, - businessDocument: { - title: 'Titel', - author: 'Autor', - creationDate: 'Erstellungsdatum', - lastModifiedDate: 'Letztes Änderungsdatum', - documentType: 'Dokumenttyp', - departmentTeam: 'Abteilung/Team', - }, - IMChat: { - chatPlatform: 'Chat-Plattform', - chatPartiesGroupName: 'Chat-Parteien/Gruppenname', - participants: 'Teilnehmer', - startDate: 'Startdatum', - endDate: 'Enddatum', - topicsKeywords: 'Themen/Schlüsselwörter', - fileType: 'Dateityp', - }, - wikipediaEntry: { - title: 'Titel', - language: 'Sprache', - webpageURL: 'Webseiten-URL', - editorContributor: 'Editor/Beitragender', - lastEditDate: 'Letztes Bearbeitungsdatum', - summaryIntroduction: 'Zusammenfassung/Einführung', - }, - notion: { - title: 'Titel', - language: 'Sprache', - author: 'Autor', - createdTime: 'Erstellungszeit', - lastModifiedTime: 'Letzte Änderungszeit', - url: 'URL', - tag: 'Tag', - description: 'Beschreibung', - }, - github: { - repoName: 'Repository-Name', - repoDesc: 'Repository-Beschreibung', - repoOwner: 'Repository-Eigentümer', - fileName: 'Dateiname', - filePath: 'Dateipfad', - programmingLang: 'Programmiersprache', - url: 'URL', - license: 'Lizenz', - lastCommitTime: 'Letzte Commit-Zeit', - lastCommitAuthor: 'Letzter Commit-Autor', - }, - originInfo: { - originalFilename: 'Originaldateiname', - originalFileSize: 'Originaldateigröße', - uploadDate: 'Hochladedatum', - lastUpdateDate: 'Letztes Änderungsdatum', - source: 'Quelle', - }, - technicalParameters: { - segmentSpecification: 'Chunk-Spezifikation', - segmentLength: 'Chunk-Länge', - avgParagraphLength: 'Durchschn. Absatzlänge', - paragraphs: 'Absätze', - hitCount: 'Abrufanzahl', - embeddingTime: 'Einbettungszeit', - embeddedSpend: 'Einbettungsausgaben', - }, - }, - languageMap: { - zh: 'Chinesisch', - en: 'Englisch', - es: 'Spanisch', - fr: 'Französisch', - de: 'Deutsch', - ja: 'Japanisch', - ko: 'Koreanisch', - ru: 'Russisch', - ar: 'Arabisch', - pt: 'Portugiesisch', - it: 'Italienisch', - nl: 'Niederländisch', - pl: 'Polnisch', - sv: 'Schwedisch', - tr: 'Türkisch', - he: 'Hebräisch', - hi: 'Hindi', - da: 'Dänisch', - fi: 'Finnisch', - no: 'Norwegisch', - hu: 'Ungarisch', - el: 'Griechisch', - cs: 'Tschechisch', - th: 'Thai', - id: 'Indonesisch', - }, - categoryMap: { - book: { - fiction: 'Fiktion', - biography: 'Biografie', - history: 'Geschichte', - science: 'Wissenschaft', - technology: 'Technologie', - education: 'Bildung', - philosophy: 'Philosophie', - religion: 'Religion', - socialSciences: 'Sozialwissenschaften', - art: 'Kunst', - travel: 'Reisen', - health: 'Gesundheit', - selfHelp: 'Selbsthilfe', - businessEconomics: 'Wirtschaft', - cooking: 'Kochen', - childrenYoungAdults: 'Kinder & Jugendliche', - comicsGraphicNovels: 'Comics & Grafische Romane', - poetry: 'Poesie', - drama: 'Drama', - other: 'Andere', - }, - personalDoc: { - notes: 'Notizen', - blogDraft: 'Blog-Entwurf', - diary: 'Tagebuch', - researchReport: 'Forschungsbericht', - bookExcerpt: 'Buchauszug', - schedule: 'Zeitplan', - list: 'Liste', - projectOverview: 'Projektübersicht', - photoCollection: 'Fotosammlung', - creativeWriting: 'Kreatives Schreiben', - codeSnippet: 'Code-Snippet', - designDraft: 'Design-Entwurf', - personalResume: 'Persönlicher Lebenslauf', - other: 'Andere', - }, - businessDoc: { - meetingMinutes: 'Protokolle', - researchReport: 'Forschungsbericht', - proposal: 'Vorschlag', - employeeHandbook: 'Mitarbeiterhandbuch', - trainingMaterials: 'Schulungsmaterialien', - requirementsDocument: 'Anforderungsdokumentation', - designDocument: 'Design-Dokument', - productSpecification: 'Produktspezifikation', - financialReport: 'Finanzbericht', - marketAnalysis: 'Marktanalyse', - projectPlan: 'Projektplan', - teamStructure: 'Teamstruktur', - policiesProcedures: 'Richtlinien & Verfahren', - contractsAgreements: 'Verträge & Vereinbarungen', - emailCorrespondence: 'E-Mail-Korrespondenz', - other: 'Andere', - }, - }, - }, - embedding: { - processing: 'Einbettungsverarbeitung...', - paused: 'Einbettung pausiert', - completed: 'Einbettung abgeschlossen', - error: 'Einbettungsfehler', - docName: 'Dokument vorbereiten', - mode: 'Segmentierungsregel', - segmentLength: 'Chunk-Länge', - textCleaning: 'Textvordefinition und -bereinigung', - segments: 'Absätze', - highQuality: 'Hochwertiger Modus', - economy: 'Wirtschaftlicher Modus', - estimate: 'Geschätzter Verbrauch', - stop: 'Verarbeitung stoppen', - resume: 'Verarbeitung fortsetzen', - automatic: 'Automatisch', - custom: 'Benutzerdefiniert', - previewTip: 'Absatzvorschau ist nach Abschluss der Einbettung verfügbar', - }, - segment: { - paragraphs: 'Absätze', - keywords: 'Schlüsselwörter', - addKeyWord: 'Schlüsselwort hinzufügen', - keywordError: 'Die maximale Länge des Schlüsselworts beträgt 20', - characters: 'Zeichen', - hitCount: 'Abrufanzahl', - vectorHash: 'Vektor-Hash: ', - questionPlaceholder: 'Frage hier hinzufügen', - questionEmpty: 'Frage darf nicht leer sein', - answerPlaceholder: 'Antwort hier hinzufügen', - answerEmpty: 'Antwort darf nicht leer sein', - contentPlaceholder: 'Inhalt hier hinzufügen', - contentEmpty: 'Inhalt darf nicht leer sein', - newTextSegment: 'Neues Textsegment', - newQaSegment: 'Neues Q&A-Segment', - delete: 'Diesen Chunk löschen?', - }, -} - -export default translation +const translation = { + list: { + title: 'Dokumente', + desc: 'Alle Dateien des Wissens werden hier angezeigt, und das gesamte Wissen kann mit Dify-Zitaten verknüpft oder über das Chat-Plugin indiziert werden.', + addFile: 'Datei hinzufügen', + addPages: 'Seiten hinzufügen', + table: { + header: { + fileName: 'DATEINAME', + words: 'WÖRTER', + hitCount: 'SUCHANFRAGEN', + uploadTime: 'HOCHLADEZEIT', + status: 'STATUS', + action: 'AKTION', + }, + name: 'Name', + rename: 'Umbenennen', + }, + action: { + uploadFile: 'Neue Datei hochladen', + settings: 'Segment-Einstellungen', + addButton: 'Chunk hinzufügen', + add: 'Einen Chunk hinzufügen', + batchAdd: 'Batch hinzufügen', + archive: 'Archivieren', + unarchive: 'Archivierung aufheben', + delete: 'Löschen', + enableWarning: 'Archivierte Datei kann nicht aktiviert werden', + sync: 'Synchronisieren', + }, + index: { + enable: 'Aktivieren', + disable: 'Deaktivieren', + all: 'Alle', + enableTip: 'Die Datei kann indiziert werden', + disableTip: 'Die Datei kann nicht indiziert werden', + }, + status: { + queuing: 'In Warteschlange', + indexing: 'Indizierung', + paused: 'Pausiert', + error: 'Fehler', + available: 'Verfügbar', + enabled: 'Aktiviert', + disabled: 'Deaktiviert', + archived: 'Archiviert', + }, + empty: { + title: 'Es gibt noch keine Dokumentation', + upload: { + tip: 'Sie können Dateien hochladen, von der Website oder von Web-Apps wie Notion, GitHub usw. synchronisieren.', + }, + sync: { + tip: 'Dify wird periodisch Dateien von Ihrem Notion herunterladen und die Verarbeitung abschließen.', + }, + }, + delete: { + title: 'Sind Sie sicher, dass Sie löschen möchten?', + content: 'Wenn Sie die Verarbeitung später fortsetzen müssen, werden Sie dort weitermachen, wo Sie aufgehört haben', + }, + batchModal: { + title: 'Chunks in Batch hinzufügen', + csvUploadTitle: 'Ziehen Sie Ihre CSV-Datei hierher oder ', + browse: 'durchsuchen', + tip: 'Die CSV-Datei muss der folgenden Struktur entsprechen:', + question: 'Frage', + answer: 'Antwort', + contentTitle: 'Chunk-Inhalt', + content: 'Inhalt', + template: 'Laden Sie die Vorlage hier herunter', + cancel: 'Abbrechen', + run: 'Batch ausführen', + runError: 'Batch-Ausführung fehlgeschlagen', + processing: 'In Batch-Verarbeitung', + completed: 'Import abgeschlossen', + error: 'Importfehler', + ok: 'OK', + }, + addUrl: 'URL hinzufügen', + }, + metadata: { + title: 'Metadaten', + desc: 'Das Kennzeichnen von Metadaten für Dokumente ermöglicht es der KI, sie rechtzeitig zu erreichen und die Quelle der Referenzen für die Benutzer offenzulegen.', + dateTimeFormat: 'MMMM D, YYYY hh:mm A', + docTypeSelectTitle: 'Bitte wählen Sie einen Dokumenttyp', + docTypeChangeTitle: 'Dokumenttyp ändern', + docTypeSelectWarning: + 'Wenn der Dokumenttyp geändert wird, werden die jetzt ausgefüllten Metadaten nicht mehr erhalten bleiben', + firstMetaAction: 'Los geht\'s', + placeholder: { + add: 'Hinzufügen ', + select: 'Auswählen ', + }, + source: { + upload_file: 'Datei hochladen', + notion: 'Von Notion synchronisieren', + github: 'Von Github synchronisieren', + }, + type: { + book: 'Buch', + webPage: 'Webseite', + paper: 'Aufsatz', + socialMediaPost: 'Social Media Beitrag', + personalDocument: 'Persönliches Dokument', + businessDocument: 'Geschäftsdokument', + IMChat: 'IM Chat', + wikipediaEntry: 'Wikipedia-Eintrag', + notion: 'Von Notion synchronisieren', + github: 'Von Github synchronisieren', + technicalParameters: 'Technische Parameter', + }, + field: { + processRule: { + processDoc: 'Dokument verarbeiten', + segmentRule: 'Chunk-Regel', + segmentLength: 'Chunk-Länge', + processClean: 'Textverarbeitung bereinigen', + }, + book: { + title: 'Titel', + language: 'Sprache', + author: 'Autor', + publisher: 'Verlag', + publicationDate: 'Veröffentlichungsdatum', + ISBN: 'ISBN', + category: 'Kategorie', + }, + webPage: { + title: 'Titel', + url: 'URL', + language: 'Sprache', + authorPublisher: 'Autor/Verlag', + publishDate: 'Veröffentlichungsdatum', + topicsKeywords: 'Themen/Schlüsselwörter', + description: 'Beschreibung', + }, + paper: { + title: 'Titel', + language: 'Sprache', + author: 'Autor', + publishDate: 'Veröffentlichungsdatum', + journalConferenceName: 'Zeitschrift/Konferenzname', + volumeIssuePage: 'Band/Ausgabe/Seite', + DOI: 'DOI', + topicsKeywords: 'Themen/Schlüsselwörter', + abstract: 'Zusammenfassung', + }, + socialMediaPost: { + platform: 'Plattform', + authorUsername: 'Autor/Benutzername', + publishDate: 'Veröffentlichungsdatum', + postURL: 'Beitrags-URL', + topicsTags: 'Themen/Tags', + }, + personalDocument: { + title: 'Titel', + author: 'Autor', + creationDate: 'Erstellungsdatum', + lastModifiedDate: 'Letztes Änderungsdatum', + documentType: 'Dokumenttyp', + tagsCategory: 'Tags/Kategorie', + }, + businessDocument: { + title: 'Titel', + author: 'Autor', + creationDate: 'Erstellungsdatum', + lastModifiedDate: 'Letztes Änderungsdatum', + documentType: 'Dokumenttyp', + departmentTeam: 'Abteilung/Team', + }, + IMChat: { + chatPlatform: 'Chat-Plattform', + chatPartiesGroupName: 'Chat-Parteien/Gruppenname', + participants: 'Teilnehmer', + startDate: 'Startdatum', + endDate: 'Enddatum', + topicsKeywords: 'Themen/Schlüsselwörter', + fileType: 'Dateityp', + }, + wikipediaEntry: { + title: 'Titel', + language: 'Sprache', + webpageURL: 'Webseiten-URL', + editorContributor: 'Editor/Beitragender', + lastEditDate: 'Letztes Bearbeitungsdatum', + summaryIntroduction: 'Zusammenfassung/Einführung', + }, + notion: { + title: 'Titel', + language: 'Sprache', + author: 'Autor', + createdTime: 'Erstellungszeit', + lastModifiedTime: 'Letzte Änderungszeit', + url: 'URL', + tag: 'Tag', + description: 'Beschreibung', + }, + github: { + repoName: 'Repository-Name', + repoDesc: 'Repository-Beschreibung', + repoOwner: 'Repository-Eigentümer', + fileName: 'Dateiname', + filePath: 'Dateipfad', + programmingLang: 'Programmiersprache', + url: 'URL', + license: 'Lizenz', + lastCommitTime: 'Letzte Commit-Zeit', + lastCommitAuthor: 'Letzter Commit-Autor', + }, + originInfo: { + originalFilename: 'Originaldateiname', + originalFileSize: 'Originaldateigröße', + uploadDate: 'Hochladedatum', + lastUpdateDate: 'Letztes Änderungsdatum', + source: 'Quelle', + }, + technicalParameters: { + segmentSpecification: 'Chunk-Spezifikation', + segmentLength: 'Chunk-Länge', + avgParagraphLength: 'Durchschn. Absatzlänge', + paragraphs: 'Absätze', + hitCount: 'Abrufanzahl', + embeddingTime: 'Einbettungszeit', + embeddedSpend: 'Einbettungsausgaben', + }, + }, + languageMap: { + zh: 'Chinesisch', + en: 'Englisch', + es: 'Spanisch', + fr: 'Französisch', + de: 'Deutsch', + ja: 'Japanisch', + ko: 'Koreanisch', + ru: 'Russisch', + ar: 'Arabisch', + pt: 'Portugiesisch', + it: 'Italienisch', + nl: 'Niederländisch', + pl: 'Polnisch', + sv: 'Schwedisch', + tr: 'Türkisch', + he: 'Hebräisch', + hi: 'Hindi', + da: 'Dänisch', + fi: 'Finnisch', + no: 'Norwegisch', + hu: 'Ungarisch', + el: 'Griechisch', + cs: 'Tschechisch', + th: 'Thai', + id: 'Indonesisch', + }, + categoryMap: { + book: { + fiction: 'Fiktion', + biography: 'Biografie', + history: 'Geschichte', + science: 'Wissenschaft', + technology: 'Technologie', + education: 'Bildung', + philosophy: 'Philosophie', + religion: 'Religion', + socialSciences: 'Sozialwissenschaften', + art: 'Kunst', + travel: 'Reisen', + health: 'Gesundheit', + selfHelp: 'Selbsthilfe', + businessEconomics: 'Wirtschaft', + cooking: 'Kochen', + childrenYoungAdults: 'Kinder & Jugendliche', + comicsGraphicNovels: 'Comics & Grafische Romane', + poetry: 'Poesie', + drama: 'Drama', + other: 'Andere', + }, + personalDoc: { + notes: 'Notizen', + blogDraft: 'Blog-Entwurf', + diary: 'Tagebuch', + researchReport: 'Forschungsbericht', + bookExcerpt: 'Buchauszug', + schedule: 'Zeitplan', + list: 'Liste', + projectOverview: 'Projektübersicht', + photoCollection: 'Fotosammlung', + creativeWriting: 'Kreatives Schreiben', + codeSnippet: 'Code-Snippet', + designDraft: 'Design-Entwurf', + personalResume: 'Persönlicher Lebenslauf', + other: 'Andere', + }, + businessDoc: { + meetingMinutes: 'Protokolle', + researchReport: 'Forschungsbericht', + proposal: 'Vorschlag', + employeeHandbook: 'Mitarbeiterhandbuch', + trainingMaterials: 'Schulungsmaterialien', + requirementsDocument: 'Anforderungsdokumentation', + designDocument: 'Design-Dokument', + productSpecification: 'Produktspezifikation', + financialReport: 'Finanzbericht', + marketAnalysis: 'Marktanalyse', + projectPlan: 'Projektplan', + teamStructure: 'Teamstruktur', + policiesProcedures: 'Richtlinien & Verfahren', + contractsAgreements: 'Verträge & Vereinbarungen', + emailCorrespondence: 'E-Mail-Korrespondenz', + other: 'Andere', + }, + }, + }, + embedding: { + processing: 'Einbettungsverarbeitung...', + paused: 'Einbettung pausiert', + completed: 'Einbettung abgeschlossen', + error: 'Einbettungsfehler', + docName: 'Dokument vorbereiten', + mode: 'Segmentierungsregel', + segmentLength: 'Chunk-Länge', + textCleaning: 'Textvordefinition und -bereinigung', + segments: 'Absätze', + highQuality: 'Hochwertiger Modus', + economy: 'Wirtschaftlicher Modus', + estimate: 'Geschätzter Verbrauch', + stop: 'Verarbeitung stoppen', + resume: 'Verarbeitung fortsetzen', + automatic: 'Automatisch', + custom: 'Benutzerdefiniert', + previewTip: 'Absatzvorschau ist nach Abschluss der Einbettung verfügbar', + }, + segment: { + paragraphs: 'Absätze', + keywords: 'Schlüsselwörter', + addKeyWord: 'Schlüsselwort hinzufügen', + keywordError: 'Die maximale Länge des Schlüsselworts beträgt 20', + characters: 'Zeichen', + hitCount: 'Abrufanzahl', + vectorHash: 'Vektor-Hash: ', + questionPlaceholder: 'Frage hier hinzufügen', + questionEmpty: 'Frage darf nicht leer sein', + answerPlaceholder: 'Antwort hier hinzufügen', + answerEmpty: 'Antwort darf nicht leer sein', + contentPlaceholder: 'Inhalt hier hinzufügen', + contentEmpty: 'Inhalt darf nicht leer sein', + newTextSegment: 'Neues Textsegment', + newQaSegment: 'Neues Q&A-Segment', + delete: 'Diesen Chunk löschen?', + }, +} + +export default translation diff --git a/web/i18n/de-DE/dataset-hit-testing.ts b/web/i18n/de-DE/dataset-hit-testing.ts index 89f90a57a7..baf88016b3 100644 --- a/web/i18n/de-DE/dataset-hit-testing.ts +++ b/web/i18n/de-DE/dataset-hit-testing.ts @@ -1,28 +1,28 @@ -const translation = { - title: 'Abruf-Test', - desc: 'Testen Sie die Treffereffektivität des Wissens anhand des gegebenen Abfragetextes.', - dateTimeFormat: 'MM/TT/JJJJ hh:mm A', - recents: 'Kürzlich', - table: { - header: { - source: 'Quelle', - text: 'Text', - time: 'Zeit', - }, - }, - input: { - title: 'Quelltext', - placeholder: 'Bitte geben Sie einen Text ein, ein kurzer aussagekräftiger Satz wird empfohlen.', - countWarning: 'Bis zu 200 Zeichen.', - indexWarning: 'Nur Wissen hoher Qualität.', - testing: 'Testen', - }, - hit: { - title: 'ABRUFPARAGRAFEN', - emptyTip: 'Ergebnisse des Abruf-Tests werden hier angezeigt', - }, - noRecentTip: 'Keine kürzlichen Abfrageergebnisse hier', - viewChart: 'VEKTORDIAGRAMM ansehen', -} - -export default translation +const translation = { + title: 'Abruf-Test', + desc: 'Testen Sie die Treffereffektivität des Wissens anhand des gegebenen Abfragetextes.', + dateTimeFormat: 'MM/TT/JJJJ hh:mm A', + recents: 'Kürzlich', + table: { + header: { + source: 'Quelle', + text: 'Text', + time: 'Zeit', + }, + }, + input: { + title: 'Quelltext', + placeholder: 'Bitte geben Sie einen Text ein, ein kurzer aussagekräftiger Satz wird empfohlen.', + countWarning: 'Bis zu 200 Zeichen.', + indexWarning: 'Nur Wissen hoher Qualität.', + testing: 'Testen', + }, + hit: { + title: 'ABRUFPARAGRAFEN', + emptyTip: 'Ergebnisse des Abruf-Tests werden hier angezeigt', + }, + noRecentTip: 'Keine kürzlichen Abfrageergebnisse hier', + viewChart: 'VEKTORDIAGRAMM ansehen', +} + +export default translation diff --git a/web/i18n/de-DE/dataset-settings.ts b/web/i18n/de-DE/dataset-settings.ts index c986334f15..b29e778075 100644 --- a/web/i18n/de-DE/dataset-settings.ts +++ b/web/i18n/de-DE/dataset-settings.ts @@ -1,33 +1,35 @@ -const translation = { - title: 'Wissenseinstellungen', - desc: 'Hier können Sie die Eigenschaften und Arbeitsweisen des Wissens anpassen.', - form: { - name: 'Wissensname', - namePlaceholder: 'Bitte geben Sie den Namen des Wissens ein', - nameError: 'Name darf nicht leer sein', - desc: 'Wissensbeschreibung', - descInfo: 'Bitte schreiben Sie eine klare textuelle Beschreibung, um den Inhalt des Wissens zu umreißen. Diese Beschreibung wird als Grundlage für die Auswahl aus mehreren Wissensdatenbanken zur Inferenz verwendet.', - descPlaceholder: 'Beschreiben Sie, was in diesem Wissen enthalten ist. Eine detaillierte Beschreibung ermöglicht es der KI, zeitnah auf den Inhalt des Wissens zuzugreifen. Wenn leer, verwendet Dify die Standard-Treffstrategie.', - descWrite: 'Erfahren Sie, wie man eine gute Wissensbeschreibung schreibt.', - permissions: 'Berechtigungen', - permissionsOnlyMe: 'Nur ich', - permissionsAllMember: 'Alle Teammitglieder', - indexMethod: 'Indexierungsmethode', - indexMethodHighQuality: 'Hohe Qualität', - indexMethodHighQualityTip: 'Den Embedding-Modell zur Verarbeitung aufrufen, um bei Benutzeranfragen eine höhere Genauigkeit zu bieten.', - indexMethodEconomy: 'Ökonomisch', - indexMethodEconomyTip: 'Verwendet Offline-Vektor-Engines, Schlagwortindizes usw., um die Genauigkeit ohne Tokenverbrauch zu reduzieren', - embeddingModel: 'Einbettungsmodell', - embeddingModelTip: 'Ändern Sie das eingebettete Modell, bitte gehen Sie zu ', - embeddingModelTipLink: 'Einstellungen', - retrievalSetting: { - title: 'Abrufeinstellung', - learnMore: 'Mehr erfahren', - description: ' über die Abrufmethode.', - longDescription: ' über die Abrufmethode, dies kann jederzeit in den Wissenseinstellungen geändert werden.', - }, - save: 'Speichern', - }, -} - -export default translation +const translation = { + title: 'Wissenseinstellungen', + desc: 'Hier können Sie die Eigenschaften und Arbeitsweisen des Wissens anpassen.', + form: { + name: 'Wissensname', + namePlaceholder: 'Bitte geben Sie den Namen des Wissens ein', + nameError: 'Name darf nicht leer sein', + desc: 'Wissensbeschreibung', + descInfo: 'Bitte schreiben Sie eine klare textuelle Beschreibung, um den Inhalt des Wissens zu umreißen. Diese Beschreibung wird als Grundlage für die Auswahl aus mehreren Wissensdatenbanken zur Inferenz verwendet.', + descPlaceholder: 'Beschreiben Sie, was in diesem Wissen enthalten ist. Eine detaillierte Beschreibung ermöglicht es der KI, zeitnah auf den Inhalt des Wissens zuzugreifen. Wenn leer, verwendet Dify die Standard-Treffstrategie.', + descWrite: 'Erfahren Sie, wie man eine gute Wissensbeschreibung schreibt.', + permissions: 'Berechtigungen', + permissionsOnlyMe: 'Nur ich', + permissionsAllMember: 'Alle Teammitglieder', + indexMethod: 'Indexierungsmethode', + indexMethodHighQuality: 'Hohe Qualität', + indexMethodHighQualityTip: 'Den Embedding-Modell zur Verarbeitung aufrufen, um bei Benutzeranfragen eine höhere Genauigkeit zu bieten.', + indexMethodEconomy: 'Ökonomisch', + indexMethodEconomyTip: 'Verwendet Offline-Vektor-Engines, Schlagwortindizes usw., um die Genauigkeit ohne Tokenverbrauch zu reduzieren', + embeddingModel: 'Einbettungsmodell', + embeddingModelTip: 'Ändern Sie das eingebettete Modell, bitte gehen Sie zu ', + embeddingModelTipLink: 'Einstellungen', + retrievalSetting: { + title: 'Abrufeinstellung', + learnMore: 'Mehr erfahren', + description: ' über die Abrufmethode.', + longDescription: ' über die Abrufmethode, dies kann jederzeit in den Wissenseinstellungen geändert werden.', + }, + save: 'Speichern', + permissionsInvitedMembers: 'Teilweise Teammitglieder', + me: '(Sie)', + }, +} + +export default translation diff --git a/web/i18n/de-DE/dataset.ts b/web/i18n/de-DE/dataset.ts index c6586ceee8..6462e56ded 100644 --- a/web/i18n/de-DE/dataset.ts +++ b/web/i18n/de-DE/dataset.ts @@ -1,76 +1,77 @@ -const translation = { - knowledge: 'Wissen', - documentCount: ' Dokumente', - wordCount: ' k Wörter', - appCount: ' verknüpfte Apps', - createDataset: 'Wissen erstellen', - createDatasetIntro: 'Importiere deine eigenen Textdaten oder schreibe Daten in Echtzeit über Webhook für die LLM-Kontextverbesserung.', - deleteDatasetConfirmTitle: 'Dieses Wissen löschen?', - deleteDatasetConfirmContent: - 'Das Löschen des Wissens ist unwiderruflich. Benutzer werden nicht mehr auf Ihr Wissen zugreifen können und alle Eingabeaufforderungen, Konfigurationen und Protokolle werden dauerhaft gelöscht.', - datasetUsedByApp: 'Das Wissen wird von einigen Apps verwendet. Apps werden dieses Wissen nicht mehr nutzen können, und alle Prompt-Konfigurationen und Protokolle werden dauerhaft gelöscht.', - datasetDeleted: 'Wissen gelöscht', - datasetDeleteFailed: 'Löschen des Wissens fehlgeschlagen', - didYouKnow: 'Wusstest du schon?', - intro1: 'Das Wissen kann in die Dify-Anwendung ', - intro2: 'als Kontext', - intro3: ',', - intro4: 'oder es ', - intro5: 'kann erstellt werden', - intro6: ' als ein eigenständiges ChatGPT-Index-Plugin zum Veröffentlichen', - unavailable: 'Nicht verfügbar', - unavailableTip: 'Einbettungsmodell ist nicht verfügbar, das Standard-Einbettungsmodell muss konfiguriert werden', - datasets: 'WISSEN', - datasetsApi: 'API', - retrieval: { - semantic_search: { - title: 'Vektorsuche', - description: 'Erzeuge Abfrage-Einbettungen und suche nach dem Textstück, das seiner Vektorrepräsentation am ähnlichsten ist.', - }, - full_text_search: { - title: 'Volltextsuche', - description: 'Indiziere alle Begriffe im Dokument, sodass Benutzer jeden Begriff suchen und den relevanten Textabschnitt finden können, der diese Begriffe enthält.', - }, - hybrid_search: { - title: 'Hybridsuche', - description: 'Führe Volltextsuche und Vektorsuchen gleichzeitig aus, ordne neu, um die beste Übereinstimmung für die Abfrage des Benutzers auszuwählen. Konfiguration des Rerank-Modell-APIs ist notwendig.', - recommend: 'Empfehlen', - }, - invertedIndex: { - title: 'Invertierter Index', - description: 'Ein invertierter Index ist eine Struktur, die für effiziente Abfragen verwendet wird. Organisiert nach Begriffen, zeigt jeder Begriff auf Dokumente oder Webseiten, die ihn enthalten.', - }, - change: 'Ändern', - changeRetrievalMethod: 'Abfragemethode ändern', - }, - docsFailedNotice: 'Dokumente konnten nicht indiziert werden', - retry: 'Wiederholen', - indexingTechnique: { - high_quality: 'HQ', - economy: 'ECO', - }, - indexingMethod: { - semantic_search: 'VEKTOR', - full_text_search: 'VOLLTEXT', - hybrid_search: 'HYBRID', - invertedIndex: 'INVERTIERT', - }, - mixtureHighQualityAndEconomicTip: 'Für die Mischung von hochwertigen und wirtschaftlichen Wissensbasen ist das Rerank-Modell erforderlich.', - inconsistentEmbeddingModelTip: 'Das Rerank-Modell ist erforderlich, wenn die Embedding-Modelle der ausgewählten Wissensbasen inkonsistent sind.', - retrievalSettings: 'Abrufeinstellungen', - rerankSettings: 'Rerank-Einstellungen', - weightedScore: { - title: 'Gewichtete Bewertung', - description: 'Durch Anpassung der zugewiesenen Gewichte bestimmt diese Rerank-Strategie, ob semantische oder Schlüsselwort-Übereinstimmung priorisiert werden soll.', - semanticFirst: 'Semantik zuerst', - keywordFirst: 'Schlüsselwort zuerst', - customized: 'Angepasst', - semantic: 'Semantisch', - keyword: 'Schlüsselwort', - }, - nTo1RetrievalLegacy: 'N-zu-1-Abruf wird ab September offiziell eingestellt. Es wird empfohlen, den neuesten Multi-Pfad-Abruf zu verwenden, um bessere Ergebnisse zu erzielen.', - nTo1RetrievalLegacyLink: 'Mehr erfahren', - nTo1RetrievalLegacyLinkText: 'N-zu-1-Abruf wird im September offiziell eingestellt.', -} - -export default translation +const translation = { + knowledge: 'Wissen', + documentCount: ' Dokumente', + wordCount: ' k Wörter', + appCount: ' verknüpfte Apps', + createDataset: 'Wissen erstellen', + createDatasetIntro: 'Importiere deine eigenen Textdaten oder schreibe Daten in Echtzeit über Webhook für die LLM-Kontextverbesserung.', + deleteDatasetConfirmTitle: 'Dieses Wissen löschen?', + deleteDatasetConfirmContent: + 'Das Löschen des Wissens ist unwiderruflich. Benutzer werden nicht mehr auf Ihr Wissen zugreifen können und alle Eingabeaufforderungen, Konfigurationen und Protokolle werden dauerhaft gelöscht.', + datasetUsedByApp: 'Das Wissen wird von einigen Apps verwendet. Apps werden dieses Wissen nicht mehr nutzen können, und alle Prompt-Konfigurationen und Protokolle werden dauerhaft gelöscht.', + datasetDeleted: 'Wissen gelöscht', + datasetDeleteFailed: 'Löschen des Wissens fehlgeschlagen', + didYouKnow: 'Wusstest du schon?', + intro1: 'Das Wissen kann in die Dify-Anwendung ', + intro2: 'als Kontext', + intro3: ',', + intro4: 'oder es ', + intro5: 'kann erstellt werden', + intro6: ' als ein eigenständiges ChatGPT-Index-Plugin zum Veröffentlichen', + unavailable: 'Nicht verfügbar', + unavailableTip: 'Einbettungsmodell ist nicht verfügbar, das Standard-Einbettungsmodell muss konfiguriert werden', + datasets: 'WISSEN', + datasetsApi: 'API', + retrieval: { + semantic_search: { + title: 'Vektorsuche', + description: 'Erzeuge Abfrage-Einbettungen und suche nach dem Textstück, das seiner Vektorrepräsentation am ähnlichsten ist.', + }, + full_text_search: { + title: 'Volltextsuche', + description: 'Indiziere alle Begriffe im Dokument, sodass Benutzer jeden Begriff suchen und den relevanten Textabschnitt finden können, der diese Begriffe enthält.', + }, + hybrid_search: { + title: 'Hybridsuche', + description: 'Führe Volltextsuche und Vektorsuchen gleichzeitig aus, ordne neu, um die beste Übereinstimmung für die Abfrage des Benutzers auszuwählen. Konfiguration des Rerank-Modell-APIs ist notwendig.', + recommend: 'Empfehlen', + }, + invertedIndex: { + title: 'Invertierter Index', + description: 'Ein invertierter Index ist eine Struktur, die für effiziente Abfragen verwendet wird. Organisiert nach Begriffen, zeigt jeder Begriff auf Dokumente oder Webseiten, die ihn enthalten.', + }, + change: 'Ändern', + changeRetrievalMethod: 'Abfragemethode ändern', + }, + docsFailedNotice: 'Dokumente konnten nicht indiziert werden', + retry: 'Wiederholen', + indexingTechnique: { + high_quality: 'HQ', + economy: 'ECO', + }, + indexingMethod: { + semantic_search: 'VEKTOR', + full_text_search: 'VOLLTEXT', + hybrid_search: 'HYBRID', + invertedIndex: 'INVERTIERT', + }, + mixtureHighQualityAndEconomicTip: 'Für die Mischung von hochwertigen und wirtschaftlichen Wissensbasen ist das Rerank-Modell erforderlich.', + inconsistentEmbeddingModelTip: 'Das Rerank-Modell ist erforderlich, wenn die Embedding-Modelle der ausgewählten Wissensbasen inkonsistent sind.', + retrievalSettings: 'Abrufeinstellungen', + rerankSettings: 'Rerank-Einstellungen', + weightedScore: { + title: 'Gewichtete Bewertung', + description: 'Durch Anpassung der zugewiesenen Gewichte bestimmt diese Rerank-Strategie, ob semantische oder Schlüsselwort-Übereinstimmung priorisiert werden soll.', + semanticFirst: 'Semantik zuerst', + keywordFirst: 'Schlüsselwort zuerst', + customized: 'Angepasst', + semantic: 'Semantisch', + keyword: 'Schlüsselwort', + }, + nTo1RetrievalLegacy: 'N-zu-1-Abruf wird ab September offiziell eingestellt. Es wird empfohlen, den neuesten Multi-Pfad-Abruf zu verwenden, um bessere Ergebnisse zu erzielen.', + nTo1RetrievalLegacyLink: 'Mehr erfahren', + nTo1RetrievalLegacyLinkText: 'N-zu-1-Abruf wird im September offiziell eingestellt.', + defaultRetrievalTip: 'Standardmäßig wird der Multi-Path-Abruf verwendet. Das Wissen wird aus mehreren Wissensdatenbanken abgerufen und dann neu eingestuft.', +} + +export default translation diff --git a/web/i18n/de-DE/explore.ts b/web/i18n/de-DE/explore.ts index 02fc90f89c..1e6f8c80d7 100644 --- a/web/i18n/de-DE/explore.ts +++ b/web/i18n/de-DE/explore.ts @@ -1,41 +1,41 @@ -const translation = { - title: 'Entdecken', - sidebar: { - discovery: 'Entdeckung', - chat: 'Chat', - workspace: 'Arbeitsbereich', - action: { - pin: 'Anheften', - unpin: 'Lösen', - rename: 'Umbenennen', - delete: 'Löschen', - }, - delete: { - title: 'App löschen', - content: 'Sind Sie sicher, dass Sie diese App löschen möchten?', - }, - }, - apps: { - title: 'Apps von Dify erkunden', - description: 'Nutzen Sie diese Vorlagen-Apps sofort oder passen Sie Ihre eigenen Apps basierend auf den Vorlagen an.', - allCategories: 'Alle Kategorien', - }, - appCard: { - addToWorkspace: 'Zum Arbeitsbereich hinzufügen', - customize: 'Anpassen', - }, - appCustomize: { - title: 'App aus {{name}} erstellen', - subTitle: 'App-Symbol & Name', - nameRequired: 'App-Name ist erforderlich', - }, - category: { - Assistant: 'Assistent', - Writing: 'Schreiben', - Translate: 'Übersetzen', - Programming: 'Programmieren', - HR: 'Personalwesen', - }, -} - -export default translation +const translation = { + title: 'Entdecken', + sidebar: { + discovery: 'Entdeckung', + chat: 'Chat', + workspace: 'Arbeitsbereich', + action: { + pin: 'Anheften', + unpin: 'Lösen', + rename: 'Umbenennen', + delete: 'Löschen', + }, + delete: { + title: 'App löschen', + content: 'Sind Sie sicher, dass Sie diese App löschen möchten?', + }, + }, + apps: { + title: 'Apps von Dify erkunden', + description: 'Nutzen Sie diese Vorlagen-Apps sofort oder passen Sie Ihre eigenen Apps basierend auf den Vorlagen an.', + allCategories: 'Alle Kategorien', + }, + appCard: { + addToWorkspace: 'Zum Arbeitsbereich hinzufügen', + customize: 'Anpassen', + }, + appCustomize: { + title: 'App aus {{name}} erstellen', + subTitle: 'App-Symbol & Name', + nameRequired: 'App-Name ist erforderlich', + }, + category: { + Assistant: 'Assistent', + Writing: 'Schreiben', + Translate: 'Übersetzen', + Programming: 'Programmieren', + HR: 'Personalwesen', + }, +} + +export default translation diff --git a/web/i18n/de-DE/login.ts b/web/i18n/de-DE/login.ts index f932f92976..4597228463 100644 --- a/web/i18n/de-DE/login.ts +++ b/web/i18n/de-DE/login.ts @@ -31,7 +31,7 @@ const translation = { pp: 'Datenschutzbestimmungen', tosDesc: 'Mit der Anmeldung stimmst du unseren', goToInit: 'Wenn du das Konto noch nicht initialisiert hast, gehe bitte zur Initialisierungsseite', - donthave: 'Hast du nicht?', + dontHave: 'Hast du nicht?', invalidInvitationCode: 'Ungültiger Einladungscode', accountAlreadyInited: 'Konto bereits initialisiert', forgotPassword: 'Passwort vergessen?', @@ -53,6 +53,7 @@ const translation = { nameEmpty: 'Name wird benötigt', passwordEmpty: 'Passwort wird benötigt', passwordInvalid: 'Das Passwort muss Buchstaben und Zahlen enthalten und länger als 8 Zeichen sein', + passwordLengthInValid: 'Das Passwort muss mindestens 8 Zeichen lang sein', }, license: { tip: 'Bevor du mit Dify Community Edition beginnst, lies die', @@ -68,6 +69,7 @@ const translation = { activated: 'Jetzt anmelden', adminInitPassword: 'Admin-Initialpasswort', validate: 'Validieren', + sso: 'Mit SSO fortfahren', } export default translation diff --git a/web/i18n/de-DE/run-log.ts b/web/i18n/de-DE/run-log.ts index 7c0257b513..5f7610c68d 100644 --- a/web/i18n/de-DE/run-log.ts +++ b/web/i18n/de-DE/run-log.ts @@ -23,6 +23,7 @@ const translation = { tipLeft: 'Bitte gehen Sie zum ', Link: 'Detailpanel', tipRight: 'ansehen.', + link: 'Gruppe Detail', }, } diff --git a/web/i18n/de-DE/share-app.ts b/web/i18n/de-DE/share-app.ts index 6a35b959a5..5ea67dd08f 100644 --- a/web/i18n/de-DE/share-app.ts +++ b/web/i18n/de-DE/share-app.ts @@ -1,74 +1,74 @@ -const translation = { - common: { - welcome: '', - appUnavailable: 'App ist nicht verfügbar', - appUnkonwError: 'App ist nicht verfügbar', - }, - chat: { - newChat: 'Neuer Chat', - pinnedTitle: 'Angeheftet', - unpinnedTitle: 'Chats', - newChatDefaultName: 'Neues Gespräch', - resetChat: 'Gespräch zurücksetzen', - powerBy: 'Bereitgestellt von', - prompt: 'Aufforderung', - privatePromptConfigTitle: 'Konversationseinstellungen', - publicPromptConfigTitle: 'Anfängliche Aufforderung', - configStatusDes: 'Vor dem Start können Sie die Konversationseinstellungen ändern', - configDisabled: - 'Voreinstellungen der vorherigen Sitzung wurden für diese Sitzung verwendet.', - startChat: 'Chat starten', - privacyPolicyLeft: - 'Bitte lesen Sie die ', - privacyPolicyMiddle: - 'Datenschutzrichtlinien', - privacyPolicyRight: - ', die vom App-Entwickler bereitgestellt wurden.', - deleteConversation: { - title: 'Konversation löschen', - content: 'Sind Sie sicher, dass Sie diese Konversation löschen möchten?', - }, - tryToSolve: 'Versuchen zu lösen', - temporarySystemIssue: 'Entschuldigung, vorübergehendes Systemproblem.', - }, - generation: { - tabs: { - create: 'Einmal ausführen', - batch: 'Stapelverarbeitung', - saved: 'Gespeichert', - }, - savedNoData: { - title: 'Sie haben noch kein Ergebnis gespeichert!', - description: 'Beginnen Sie mit der Inhaltserstellung und finden Sie hier Ihre gespeicherten Ergebnisse.', - startCreateContent: 'Beginnen Sie mit der Inhaltserstellung', - }, - title: 'KI-Vervollständigung', - queryTitle: 'Abfrageinhalt', - completionResult: 'Vervollständigungsergebnis', - queryPlaceholder: 'Schreiben Sie Ihren Abfrageinhalt...', - run: 'Ausführen', - copy: 'Kopieren', - resultTitle: 'KI-Vervollständigung', - noData: 'KI wird Ihnen hier geben, was Sie möchten.', - csvUploadTitle: 'Ziehen Sie Ihre CSV-Datei hierher oder ', - browse: 'durchsuchen', - csvStructureTitle: 'Die CSV-Datei muss der folgenden Struktur entsprechen:', - downloadTemplate: 'Laden Sie die Vorlage hier herunter', - field: 'Feld', - batchFailed: { - info: '{{num}} fehlgeschlagene Ausführungen', - retry: 'Wiederholen', - outputPlaceholder: 'Kein Ausgabeanhalt', - }, - errorMsg: { - empty: 'Bitte geben Sie Inhalte in die hochgeladene Datei ein.', - fileStructNotMatch: 'Die hochgeladene CSV-Datei entspricht nicht der Struktur.', - emptyLine: 'Zeile {{rowIndex}} ist leer', - invalidLine: 'Zeile {{rowIndex}}: {{varName}} Wert darf nicht leer sein', - moreThanMaxLengthLine: 'Zeile {{rowIndex}}: {{varName}} Wert darf nicht mehr als {{maxLength}} Zeichen sein', - atLeastOne: 'Bitte geben Sie mindestens eine Zeile in die hochgeladene Datei ein.', - }, - }, -} - -export default translation +const translation = { + common: { + welcome: '', + appUnavailable: 'App ist nicht verfügbar', + appUnknownError: 'App ist nicht verfügbar', + }, + chat: { + newChat: 'Neuer Chat', + pinnedTitle: 'Angeheftet', + unpinnedTitle: 'Chats', + newChatDefaultName: 'Neues Gespräch', + resetChat: 'Gespräch zurücksetzen', + poweredBy: 'Bereitgestellt von', + prompt: 'Aufforderung', + privatePromptConfigTitle: 'Konversationseinstellungen', + publicPromptConfigTitle: 'Anfängliche Aufforderung', + configStatusDes: 'Vor dem Start können Sie die Konversationseinstellungen ändern', + configDisabled: + 'Voreinstellungen der vorherigen Sitzung wurden für diese Sitzung verwendet.', + startChat: 'Chat starten', + privacyPolicyLeft: + 'Bitte lesen Sie die ', + privacyPolicyMiddle: + 'Datenschutzrichtlinien', + privacyPolicyRight: + ', die vom App-Entwickler bereitgestellt wurden.', + deleteConversation: { + title: 'Konversation löschen', + content: 'Sind Sie sicher, dass Sie diese Konversation löschen möchten?', + }, + tryToSolve: 'Versuchen zu lösen', + temporarySystemIssue: 'Entschuldigung, vorübergehendes Systemproblem.', + }, + generation: { + tabs: { + create: 'Einmal ausführen', + batch: 'Stapelverarbeitung', + saved: 'Gespeichert', + }, + savedNoData: { + title: 'Sie haben noch kein Ergebnis gespeichert!', + description: 'Beginnen Sie mit der Inhaltserstellung und finden Sie hier Ihre gespeicherten Ergebnisse.', + startCreateContent: 'Beginnen Sie mit der Inhaltserstellung', + }, + title: 'KI-Vervollständigung', + queryTitle: 'Abfrageinhalt', + completionResult: 'Vervollständigungsergebnis', + queryPlaceholder: 'Schreiben Sie Ihren Abfrageinhalt...', + run: 'Ausführen', + copy: 'Kopieren', + resultTitle: 'KI-Vervollständigung', + noData: 'KI wird Ihnen hier geben, was Sie möchten.', + csvUploadTitle: 'Ziehen Sie Ihre CSV-Datei hierher oder ', + browse: 'durchsuchen', + csvStructureTitle: 'Die CSV-Datei muss der folgenden Struktur entsprechen:', + downloadTemplate: 'Laden Sie die Vorlage hier herunter', + field: 'Feld', + batchFailed: { + info: '{{num}} fehlgeschlagene Ausführungen', + retry: 'Wiederholen', + outputPlaceholder: 'Kein Ausgabeanhalt', + }, + errorMsg: { + empty: 'Bitte geben Sie Inhalte in die hochgeladene Datei ein.', + fileStructNotMatch: 'Die hochgeladene CSV-Datei entspricht nicht der Struktur.', + emptyLine: 'Zeile {{rowIndex}} ist leer', + invalidLine: 'Zeile {{rowIndex}}: {{varName}} Wert darf nicht leer sein', + moreThanMaxLengthLine: 'Zeile {{rowIndex}}: {{varName}} Wert darf nicht mehr als {{maxLength}} Zeichen sein', + atLeastOne: 'Bitte geben Sie mindestens eine Zeile in die hochgeladene Datei ein.', + }, + }, +} + +export default translation diff --git a/web/i18n/de-DE/tools.ts b/web/i18n/de-DE/tools.ts index a45d0da1b1..3be01b8350 100644 --- a/web/i18n/de-DE/tools.ts +++ b/web/i18n/de-DE/tools.ts @@ -1,119 +1,153 @@ -const translation = { - title: 'Werkzeuge', - createCustomTool: 'Eigenes Werkzeug erstellen', - type: { - all: 'Alle', - builtIn: 'Integriert', - custom: 'Benutzerdefiniert', - }, - contribute: { - line1: 'Ich interessiere mich dafür, ', - line2: 'Werkzeuge zu Dify beizutragen.', - viewGuide: 'Leitfaden anzeigen', - }, - author: 'Von', - auth: { - unauthorized: 'Zur Autorisierung', - authorized: 'Autorisiert', - setup: 'Autorisierung einrichten, um zu nutzen', - setupModalTitle: 'Autorisierung einrichten', - setupModalTitleDescription: 'Nach der Konfiguration der Anmeldeinformationen können alle Mitglieder im Arbeitsbereich dieses Werkzeug beim Orchestrieren von Anwendungen nutzen.', - }, - includeToolNum: '{{num}} Werkzeuge inkludiert', - addTool: 'Werkzeug hinzufügen', - createTool: { - title: 'Eigenes Werkzeug erstellen', - editAction: 'Konfigurieren', - editTitle: 'Eigenes Werkzeug bearbeiten', - name: 'Name', - toolNamePlaceHolder: 'Geben Sie den Werkzeugnamen ein', - schema: 'Schema', - schemaPlaceHolder: 'Geben Sie hier Ihr OpenAPI-Schema ein', - viewSchemaSpec: 'Die OpenAPI-Swagger-Spezifikation anzeigen', - importFromUrl: 'Von URL importieren', - importFromUrlPlaceHolder: 'https://...', - urlError: 'Bitte geben Sie eine gültige URL ein', - examples: 'Beispiele', - exampleOptions: { - json: 'Wetter(JSON)', - yaml: 'Pet Store(YAML)', - blankTemplate: 'Leere Vorlage', - }, - availableTools: { - title: 'Verfügbare Werkzeuge', - name: 'Name', - description: 'Beschreibung', - method: 'Methode', - path: 'Pfad', - action: 'Aktionen', - test: 'Test', - }, - authMethod: { - title: 'Autorisierungsmethode', - type: 'Autorisierungstyp', - keyTooltip: 'Http Header Key, Sie können es bei "Authorization" belassen, wenn Sie nicht wissen, was es ist, oder auf einen benutzerdefinierten Wert setzen', - types: { - none: 'Keine', - api_key: 'API-Key', - apiKeyPlaceholder: 'HTTP-Headername für API-Key', - apiValuePlaceholder: 'API-Key eingeben', - }, - key: 'Schlüssel', - value: 'Wert', - }, - authHeaderPrefix: { - title: 'Auth-Typ', - types: { - basic: 'Basic', - bearer: 'Bearer', - custom: 'Benutzerdefiniert', - }, - }, - privacyPolicy: 'Datenschutzrichtlinie', - privacyPolicyPlaceholder: 'Bitte Datenschutzrichtlinie eingeben', - customDisclaimer: 'Benutzer Haftungsausschluss', - customDisclaimerPlaceholder: 'Bitte benutzerdefinierten Haftungsausschluss eingeben', - deleteToolConfirmTitle: 'Löschen Sie dieses Werkzeug?', - deleteToolConfirmContent: 'Das Löschen des Werkzeugs ist irreversibel. Benutzer können Ihr Werkzeug nicht mehr verwenden.', - }, - test: { - title: 'Test', - parametersValue: 'Parameter & Wert', - parameters: 'Parameter', - value: 'Wert', - testResult: 'Testergebnisse', - testResultPlaceholder: 'Testergebnis wird hier angezeigt', - }, - thought: { - using: 'Nutzung', - used: 'Genutzt', - requestTitle: 'Anfrage an', - responseTitle: 'Antwort von', - }, - setBuiltInTools: { - info: 'Info', - setting: 'Einstellung', - toolDescription: 'Werkzeugbeschreibung', - parameters: 'Parameter', - string: 'Zeichenkette', - number: 'Nummer', - required: 'Erforderlich', - infoAndSetting: 'Info & Einstellungen', - }, - noCustomTool: { - title: 'Keine benutzerdefinierten Werkzeuge!', - content: 'Fügen Sie hier Ihre benutzerdefinierten Werkzeuge hinzu und verwalten Sie sie, um KI-Apps zu erstellen.', - createTool: 'Werkzeug erstellen', - }, - noSearchRes: { - title: 'Leider keine Ergebnisse!', - content: 'Wir konnten keine Werkzeuge finden, die Ihrer Suche entsprechen.', - reset: 'Suche zurücksetzen', - }, - builtInPromptTitle: 'Aufforderung', - toolRemoved: 'Werkzeug entfernt', - notAuthorized: 'Werkzeug nicht autorisiert', - howToGet: 'Wie erhält man', -} - -export default translation +const translation = { + title: 'Werkzeuge', + createCustomTool: 'Eigenes Werkzeug erstellen', + type: { + all: 'Alle', + builtIn: 'Integriert', + custom: 'Benutzerdefiniert', + workflow: 'Arbeitsablauf', + }, + contribute: { + line1: 'Ich interessiere mich dafür, ', + line2: 'Werkzeuge zu Dify beizutragen.', + viewGuide: 'Leitfaden anzeigen', + }, + author: 'Von', + auth: { + unauthorized: 'Zur Autorisierung', + authorized: 'Autorisiert', + setup: 'Autorisierung einrichten, um zu nutzen', + setupModalTitle: 'Autorisierung einrichten', + setupModalTitleDescription: 'Nach der Konfiguration der Anmeldeinformationen können alle Mitglieder im Arbeitsbereich dieses Werkzeug beim Orchestrieren von Anwendungen nutzen.', + }, + includeToolNum: '{{num}} Werkzeuge inkludiert', + addTool: 'Werkzeug hinzufügen', + createTool: { + title: 'Eigenes Werkzeug erstellen', + editAction: 'Konfigurieren', + editTitle: 'Eigenes Werkzeug bearbeiten', + name: 'Name', + toolNamePlaceHolder: 'Geben Sie den Werkzeugnamen ein', + schema: 'Schema', + schemaPlaceHolder: 'Geben Sie hier Ihr OpenAPI-Schema ein', + viewSchemaSpec: 'Die OpenAPI-Swagger-Spezifikation anzeigen', + importFromUrl: 'Von URL importieren', + importFromUrlPlaceHolder: 'https://...', + urlError: 'Bitte geben Sie eine gültige URL ein', + examples: 'Beispiele', + exampleOptions: { + json: 'Wetter(JSON)', + yaml: 'Pet Store(YAML)', + blankTemplate: 'Leere Vorlage', + }, + availableTools: { + title: 'Verfügbare Werkzeuge', + name: 'Name', + description: 'Beschreibung', + method: 'Methode', + path: 'Pfad', + action: 'Aktionen', + test: 'Test', + }, + authMethod: { + title: 'Autorisierungsmethode', + type: 'Autorisierungstyp', + keyTooltip: 'Http Header Key, Sie können es bei "Authorization" belassen, wenn Sie nicht wissen, was es ist, oder auf einen benutzerdefinierten Wert setzen', + types: { + none: 'Keine', + api_key: 'API-Key', + apiKeyPlaceholder: 'HTTP-Headername für API-Key', + apiValuePlaceholder: 'API-Key eingeben', + }, + key: 'Schlüssel', + value: 'Wert', + }, + authHeaderPrefix: { + title: 'Auth-Typ', + types: { + basic: 'Basic', + bearer: 'Bearer', + custom: 'Benutzerdefiniert', + }, + }, + privacyPolicy: 'Datenschutzrichtlinie', + privacyPolicyPlaceholder: 'Bitte Datenschutzrichtlinie eingeben', + customDisclaimer: 'Benutzer Haftungsausschluss', + customDisclaimerPlaceholder: 'Bitte benutzerdefinierten Haftungsausschluss eingeben', + deleteToolConfirmTitle: 'Löschen Sie dieses Werkzeug?', + deleteToolConfirmContent: 'Das Löschen des Werkzeugs ist irreversibel. Benutzer können Ihr Werkzeug nicht mehr verwenden.', + toolInput: { + description: 'Beschreibung', + methodParameterTip: 'LLM-Füllungen während der Inferenz', + method: 'Methode', + methodParameter: 'Parameter', + label: 'Schilder', + required: 'Erforderlich', + methodSetting: 'Einstellung', + name: 'Name', + title: 'Werkzeug-Eingabe', + methodSettingTip: 'Der Benutzer füllt die Werkzeugkonfiguration aus', + descriptionPlaceholder: 'Beschreibung der Bedeutung des Parameters', + labelPlaceholder: 'Tags auswählen(optional)', + }, + description: 'Beschreibung', + confirmTip: 'Apps, die dieses Tool verwenden, sind davon betroffen', + nameForToolCallTip: 'Unterstützt nur Zahlen, Buchstaben und Unterstriche.', + nameForToolCall: 'Name des Werkzeugaufrufs', + confirmTitle: 'Bestätigen, um zu speichern?', + nameForToolCallPlaceHolder: 'Wird für die Maschinenerkennung verwendet, z. B. getCurrentWeather, list_pets', + descriptionPlaceholder: 'Kurze Beschreibung des Zwecks des Werkzeugs, z. B. um die Temperatur für einen bestimmten Ort zu ermitteln.', + }, + test: { + title: 'Test', + parametersValue: 'Parameter & Wert', + parameters: 'Parameter', + value: 'Wert', + testResult: 'Testergebnisse', + testResultPlaceholder: 'Testergebnis wird hier angezeigt', + }, + thought: { + using: 'Nutzung', + used: 'Genutzt', + requestTitle: 'Anfrage an', + responseTitle: 'Antwort von', + }, + setBuiltInTools: { + info: 'Info', + setting: 'Einstellung', + toolDescription: 'Werkzeugbeschreibung', + parameters: 'Parameter', + string: 'Zeichenkette', + number: 'Nummer', + required: 'Erforderlich', + infoAndSetting: 'Info & Einstellungen', + }, + noCustomTool: { + title: 'Keine benutzerdefinierten Werkzeuge!', + content: 'Fügen Sie hier Ihre benutzerdefinierten Werkzeuge hinzu und verwalten Sie sie, um KI-Apps zu erstellen.', + createTool: 'Werkzeug erstellen', + }, + noSearchRes: { + title: 'Leider keine Ergebnisse!', + content: 'Wir konnten keine Werkzeuge finden, die Ihrer Suche entsprechen.', + reset: 'Suche zurücksetzen', + }, + builtInPromptTitle: 'Aufforderung', + toolRemoved: 'Werkzeug entfernt', + notAuthorized: 'Werkzeug nicht autorisiert', + howToGet: 'Wie erhält man', + addToolModal: { + added: 'zugefügt', + manageInTools: 'Verwalten in Tools', + add: 'hinzufügen', + category: 'Kategorie', + emptyTitle: 'Kein Workflow-Tool verfügbar', + type: 'Art', + emptyTip: 'Gehen Sie zu "Workflow -> Als Tool veröffentlichen"', + }, + toolNameUsageTip: 'Name des Tool-Aufrufs für die Argumentation und Aufforderung des Agenten', + customToolTip: 'Erfahren Sie mehr über benutzerdefinierte Dify-Tools', + openInStudio: 'In Studio öffnen', +} + +export default translation diff --git a/web/i18n/de-DE/workflow.ts b/web/i18n/de-DE/workflow.ts index c1ef1d408e..2762c01a8d 100644 --- a/web/i18n/de-DE/workflow.ts +++ b/web/i18n/de-DE/workflow.ts @@ -36,7 +36,7 @@ const translation = { searchVar: 'Variable suchen', variableNamePlaceholder: 'Variablenname', setVarValuePlaceholder: 'Variable setzen', - needConnecttip: 'Dieser Schritt ist mit nichts verbunden', + needConnectTip: 'Dieser Schritt ist mit nichts verbunden', maxTreeDepth: 'Maximales Limit von {{depth}} Knoten pro Ast', needEndNode: 'Der Endblock muss hinzugefügt werden', needAnswerNode: 'Der Antwortblock muss hinzugefügt werden', @@ -69,6 +69,14 @@ const translation = { manageInTools: 'In den Tools verwalten', workflowAsToolTip: 'Nach dem Workflow-Update ist eine Neukonfiguration des Tools erforderlich.', viewDetailInTracingPanel: 'Details anzeigen', + importDSL: 'DSL importieren', + importFailure: 'Fehler beim Import', + syncingData: 'Synchronisieren von Daten, nur wenige Sekunden.', + chooseDSL: 'Wählen Sie eine DSL(yml)-Datei', + importSuccess: 'Erfolg beim Import', + importDSLTip: 'Der aktuelle Entwurf wird überschrieben. Exportieren Sie den Workflow vor dem Import als Backup.', + overwriteAndImport: 'Überschreiben und Importieren', + backupCurrentDraft: 'Aktuellen Entwurf sichern', }, env: { envPanelTitle: 'Umgebungsvariablen', @@ -178,6 +186,7 @@ const translation = { 'transform': 'Transformieren', 'utilities': 'Dienstprogramme', 'noResult': 'Kein Ergebnis gefunden', + 'searchTool': 'Suchwerkzeug', }, blocks: { 'start': 'Start', @@ -403,10 +412,12 @@ const translation = { 'not empty': 'ist nicht leer', 'null': 'ist null', 'not null': 'ist nicht null', + 'regex match': 'Regex-Übereinstimmung', }, enterValue: 'Wert eingeben', addCondition: 'Bedingung hinzufügen', conditionNotSetup: 'Bedingung NICHT eingerichtet', + selectVariable: 'Variable auswählen...', }, variableAssigner: { title: 'Variablen zuweisen', @@ -502,6 +513,25 @@ const translation = { iteration_other: '{{count}} Iterationen', currentIteration: 'Aktuelle Iteration', }, + note: { + editor: { + strikethrough: 'Durchgestrichen', + large: 'Groß', + bulletList: 'Aufzählung', + italic: 'Kursiv', + small: 'Klein', + bold: 'Kühn', + placeholder: 'Schreiben Sie Ihre Notiz...', + openLink: 'Offen', + showAuthor: 'Autor anzeigen', + medium: 'Mittel', + unlink: 'Trennen', + link: 'Verbinden', + enterUrl: 'URL eingeben...', + invalidUrl: 'Ungültige URL', + }, + addNote: 'Notiz hinzufügen', + }, }, tracing: { stopBy: 'Gestoppt von {{user}}', diff --git a/web/i18n/en-US/app-api.ts b/web/i18n/en-US/app-api.ts index f36708c1d0..631faeee9a 100644 --- a/web/i18n/en-US/app-api.ts +++ b/web/i18n/en-US/app-api.ts @@ -10,7 +10,7 @@ const translation = { pause: 'Pause', playing: 'Playing', loading: 'Loading', - merMaind: { + merMaid: { rerender: 'Redo Rerender', }, never: 'Never', diff --git a/web/i18n/en-US/app-debug.ts b/web/i18n/en-US/app-debug.ts index 86c5f720c3..b1f3f33cd8 100644 --- a/web/i18n/en-US/app-debug.ts +++ b/web/i18n/en-US/app-debug.ts @@ -301,7 +301,7 @@ const translation = { historyNoBeEmpty: 'Conversation history must be set in the prompt', queryNoBeEmpty: 'Query must be set in the prompt', }, - variableConig: { + variableConfig: { 'addModalTitle': 'Add Input Field', 'editModalTitle': 'Edit Input Field', 'description': 'Setting for variable {{varName}}', diff --git a/web/i18n/en-US/app.ts b/web/i18n/en-US/app.ts index 90724098de..3377a9b2f3 100644 --- a/web/i18n/en-US/app.ts +++ b/web/i18n/en-US/app.ts @@ -77,13 +77,18 @@ const translation = { emoji: 'Emoji', image: 'Image', }, + answerIcon: { + title: 'Use WebApp icon to replace 🤖', + description: 'Whether to use the WebApp icon to replace 🤖 in the shared application', + descriptionInExplore: 'Whether to use the WebApp icon to replace 🤖 in Explore', + }, switch: 'Switch to Workflow Orchestrate', switchTipStart: 'A new app copy will be created for you, and the new copy will switch to Workflow Orchestrate. The new copy will ', switchTip: 'not allow', switchTipEnd: ' switching back to Basic Orchestrate.', switchLabel: 'The app copy to be created', removeOriginal: 'Delete the original app', - switchStart: 'Start swtich', + switchStart: 'Start switch', typeSelector: { all: 'ALL Types', chatbot: 'Chatbot', diff --git a/web/i18n/en-US/common.ts b/web/i18n/en-US/common.ts index 87dab5cb71..23e301485a 100644 --- a/web/i18n/en-US/common.ts +++ b/web/i18n/en-US/common.ts @@ -37,6 +37,7 @@ const translation = { params: 'Params', duplicate: 'Duplicate', rename: 'Rename', + audioSourceUnavailable: 'AudioSource is unavailable', }, errorMsg: { fieldRequired: '{{field}} is required', @@ -132,7 +133,8 @@ const translation = { workspace: 'Workspace', createWorkspace: 'Create Workspace', helpCenter: 'Help', - roadmapAndFeedback: 'Feedback', + communityFeedback: 'Feedback', + roadmap: 'Roadmap', community: 'Community', about: 'About', logout: 'Log out', @@ -198,7 +200,7 @@ const translation = { invitationSent: 'Invitation sent', invitationSentTip: 'Invitation sent, and they can sign in to Dify to access your team data.', invitationLink: 'Invitation Link', - failedinvitationEmails: 'Below users were not invited successfully', + failedInvitationEmails: 'Below users were not invited successfully', ok: 'OK', removeFromTeam: 'Remove from team', removeFromTeamTip: 'Will remove team access', @@ -206,7 +208,7 @@ const translation = { setMember: 'Set to ordinary member', setBuilder: 'Set as builder', setEditor: 'Set as editor', - disinvite: 'Cancel the invitation', + disInvite: 'Cancel the invitation', deleteMember: 'Delete Member', you: '(You)', }, @@ -390,7 +392,7 @@ const translation = { selector: { pageSelected: 'Pages Selected', searchPages: 'Search pages...', - noSearchResult: 'No search resluts', + noSearchResult: 'No search results', addPages: 'Add pages', preview: 'PREVIEW', }, diff --git a/web/i18n/en-US/dataset-creation.ts b/web/i18n/en-US/dataset-creation.ts index 1ead19f7e6..40463593f9 100644 --- a/web/i18n/en-US/dataset-creation.ts +++ b/web/i18n/en-US/dataset-creation.ts @@ -50,7 +50,7 @@ const translation = { input: 'Knowledge name', placeholder: 'Please input', nameNotEmpty: 'Name cannot be empty', - nameLengthInvaild: 'Name must be between 1 to 40 characters', + nameLengthInvalid: 'Name must be between 1 to 40 characters', cancelButton: 'Cancel', confirmButton: 'Create', failed: 'Creation failed', @@ -86,12 +86,12 @@ const translation = { autoDescription: 'Automatically set chunk and preprocessing rules. Unfamiliar users are recommended to select this.', custom: 'Custom', customDescription: 'Customize chunks rules, chunks length, and preprocessing rules, etc.', - separator: 'Segment identifier', + separator: 'Delimiter', separatorPlaceholder: 'For example, newline (\\\\n) or special separator (such as "***")', maxLength: 'Maximum chunk length', overlap: 'Chunk overlap', overlapTip: 'Setting the chunk overlap can maintain the semantic relevance between them, enhancing the retrieve effect. It is recommended to set 10%-25% of the maximum chunk size.', - overlapCheck: 'chunk overlap should not bigger than maximun chunk length', + overlapCheck: 'chunk overlap should not bigger than maximum chunk length', rules: 'Text preprocessing rules', removeExtraSpaces: 'Replace consecutive spaces, newlines and tabs', removeUrlEmails: 'Delete all URLs and email addresses', @@ -109,8 +109,8 @@ const translation = { QATitle: 'Segmenting in Question & Answer format', QATip: 'Enable this option will consume more tokens', QALanguage: 'Segment using', - emstimateCost: 'Estimation', - emstimateSegment: 'Estimated chunks', + estimateCost: 'Estimation', + estimateSegment: 'Estimated chunks', segmentCount: 'chunks', calculating: 'Calculating...', fileSource: 'Preprocess documents', @@ -135,8 +135,8 @@ const translation = { previewSwitchTipStart: 'The current chunk preview is in text format, switching to a question-and-answer format preview will', previewSwitchTipEnd: ' consume additional tokens', characters: 'characters', - indexSettedTip: 'To change the index method, please go to the ', - retrivalSettedTip: 'To change the index method, please go to the ', + indexSettingTip: 'To change the index method & embedding model, please go to the ', + retrievalSettingTip: 'To change the retrieval setting, please go to the ', datasetSettingLink: 'Knowledge settings.', }, stepThree: { diff --git a/web/i18n/en-US/dataset.ts b/web/i18n/en-US/dataset.ts index e6914b4a00..a15efe5dc0 100644 --- a/web/i18n/en-US/dataset.ts +++ b/web/i18n/en-US/dataset.ts @@ -55,6 +55,7 @@ const translation = { hybrid_search: 'HYBRID', invertedIndex: 'INVERTED', }, + defaultRetrievalTip: 'Multi-path retrieval is used by default. Knowledge is retrieved from multiple knowledge bases and then re-ranked.', mixtureHighQualityAndEconomicTip: 'The Rerank model is required for mixture of high quality and economical knowledge bases.', inconsistentEmbeddingModelTip: 'The Rerank model is required if the Embedding models of the selected knowledge bases are inconsistent.', retrievalSettings: 'Retrieval Setting', diff --git a/web/i18n/en-US/login.ts b/web/i18n/en-US/login.ts index 2cb6ecb785..03b0d27ed5 100644 --- a/web/i18n/en-US/login.ts +++ b/web/i18n/en-US/login.ts @@ -32,7 +32,7 @@ const translation = { pp: 'Privacy Policy', tosDesc: 'By signing up, you agree to our', goToInit: 'If you have not initialized the account, please go to the initialization page', - donthave: 'Don\'t have?', + dontHave: 'Don\'t have?', invalidInvitationCode: 'Invalid invitation code', accountAlreadyInited: 'Account already initialized', forgotPassword: 'Forgot your password?', diff --git a/web/i18n/en-US/share-app.ts b/web/i18n/en-US/share-app.ts index f66e923561..b5a219c998 100644 --- a/web/i18n/en-US/share-app.ts +++ b/web/i18n/en-US/share-app.ts @@ -2,7 +2,7 @@ const translation = { common: { welcome: '', appUnavailable: 'App is unavailable', - appUnkonwError: 'App is unavailable', + appUnknownError: 'App is unavailable', }, chat: { newChat: 'New chat', @@ -10,7 +10,7 @@ const translation = { unpinnedTitle: 'Chats', newChatDefaultName: 'New conversation', resetChat: 'Reset conversation', - powerBy: 'Powered by', + poweredBy: 'Powered by', prompt: 'Prompt', privatePromptConfigTitle: 'Conversation settings', publicPromptConfigTitle: 'Initial Prompt', diff --git a/web/i18n/en-US/workflow.ts b/web/i18n/en-US/workflow.ts index e0613a110f..0d924ba16c 100644 --- a/web/i18n/en-US/workflow.ts +++ b/web/i18n/en-US/workflow.ts @@ -36,7 +36,7 @@ const translation = { searchVar: 'Search variable', variableNamePlaceholder: 'Variable name', setVarValuePlaceholder: 'Set variable', - needConnecttip: 'This step is not connected to anything', + needConnectTip: 'This step is not connected to anything', maxTreeDepth: 'Maximum limit of {{depth}} nodes per branch', needEndNode: 'The End block must be added', needAnswerNode: 'The Answer block must be added', @@ -412,6 +412,7 @@ const translation = { 'not empty': 'is not empty', 'null': 'is null', 'not null': 'is not null', + 'regex match': 'regex match', }, enterValue: 'Enter value', addCondition: 'Add Condition', diff --git a/web/i18n/es-ES/app-api.ts b/web/i18n/es-ES/app-api.ts index 5d2bc078e3..1474e5fb1d 100644 --- a/web/i18n/es-ES/app-api.ts +++ b/web/i18n/es-ES/app-api.ts @@ -10,7 +10,7 @@ const translation = { pause: 'Pausa', playing: 'Reproduciendo', loading: 'Cargando', - merMaind: { + merMaid: { rerender: 'Rehacer Rerender', }, never: 'Nunca', diff --git a/web/i18n/es-ES/app-debug.ts b/web/i18n/es-ES/app-debug.ts index 68088c26a6..ab5b82e7d1 100644 --- a/web/i18n/es-ES/app-debug.ts +++ b/web/i18n/es-ES/app-debug.ts @@ -259,7 +259,7 @@ const translation = { historyNoBeEmpty: 'El historial de conversaciones debe establecerse en la indicación', queryNoBeEmpty: 'La consulta debe establecerse en la indicación', }, - variableConig: { + variableConfig: { 'addModalTitle': 'Agregar Campo de Entrada', 'editModalTitle': 'Editar Campo de Entrada', 'description': 'Configuración para la variable {{varName}}', diff --git a/web/i18n/es-ES/app-overview.ts b/web/i18n/es-ES/app-overview.ts index f3aaf1f737..8beb7545dc 100644 --- a/web/i18n/es-ES/app-overview.ts +++ b/web/i18n/es-ES/app-overview.ts @@ -48,6 +48,8 @@ const translation = { title: 'Pasos del flujo de trabajo', show: 'Mostrar', hide: 'Ocultar', + subTitle: 'Detalles del flujo de trabajo', + showDesc: 'Mostrar u ocultar detalles del flujo de trabajo en WebApp', }, chatColorTheme: 'Tema de color del chat', chatColorThemeDesc: 'Establece el tema de color del chatbot', @@ -64,6 +66,12 @@ const translation = { customDisclaimerPlaceholder: 'Ingresa el texto de descargo de responsabilidad personalizado', customDisclaimerTip: 'El texto de descargo de responsabilidad personalizado se mostrará en el lado del cliente, proporcionando información adicional sobre la aplicación', }, + sso: { + description: 'Todos los usuarios deben iniciar sesión con SSO antes de usar WebApp', + tooltip: 'Póngase en contacto con el administrador para habilitar el inicio de sesión único de WebApp', + label: 'Autenticación SSO', + title: 'WebApp SSO', + }, }, embedded: { entry: 'Incrustado', @@ -119,7 +127,11 @@ const translation = { tokenPS: 'Token/s', totalMessages: { title: 'Mensajes totales', - explanation: 'Recuento diario de interacciones de IA; excluye la ingeniería/depuración de prompts.', + explanation: 'Recuento diario de interacciones con IA.', + }, + totalConversations: { + title: 'Conversaciones totales', + explanation: 'Recuento diario de conversaciones con IA; ingeniería/depuración de prompts excluida.', }, activeUsers: { title: 'Usuarios activos', diff --git a/web/i18n/es-ES/app.ts b/web/i18n/es-ES/app.ts index 739439ff58..b29f8d36e4 100644 --- a/web/i18n/es-ES/app.ts +++ b/web/i18n/es-ES/app.ts @@ -122,7 +122,17 @@ const translation = { removeConfirmTitle: '¿Eliminar la configuración de {{key}}?', removeConfirmContent: 'La configuración actual está en uso, eliminarla desactivará la función de rastreo.', }, + view: 'Vista', }, + answerIcon: { + title: 'Usar el icono de la aplicación web para reemplazar 🤖', + descriptionInExplore: 'Si se debe usar el icono de la aplicación web para reemplazarlo 🤖 en Explore', + description: 'Si se va a usar el icono de la aplicación web para reemplazarlo 🤖 en la aplicación compartida', + }, + importFromDSLUrl: 'URL de origen', + importFromDSLUrlPlaceholder: 'Pegar enlace DSL aquí', + importFromDSL: 'Importar desde DSL', + importFromDSLFile: 'Desde el archivo DSL', } export default translation diff --git a/web/i18n/es-ES/common.ts b/web/i18n/es-ES/common.ts index fc37775263..2ba907361f 100644 --- a/web/i18n/es-ES/common.ts +++ b/web/i18n/es-ES/common.ts @@ -37,6 +37,7 @@ const translation = { params: 'Parámetros', duplicate: 'Duplicar', rename: 'Renombrar', + audioSourceUnavailable: 'AudioSource no está disponible', }, errorMsg: { fieldRequired: '{{field}} es requerido', @@ -132,7 +133,8 @@ const translation = { workspace: 'Espacio de trabajo', createWorkspace: 'Crear espacio de trabajo', helpCenter: 'Ayuda', - roadmapAndFeedback: 'Comentarios', + communityFeedback: 'Comentarios', + roadmap: 'Hoja de ruta', community: 'Comunidad', about: 'Acerca de', logout: 'Cerrar sesión', @@ -198,7 +200,7 @@ const translation = { invitationSent: 'Invitación enviada', invitationSentTip: 'Invitación enviada, y pueden iniciar sesión en Dify para acceder a tus datos del equipo.', invitationLink: 'Enlace de invitación', - failedinvitationEmails: 'Los siguientes usuarios no fueron invitados exitosamente', + failedInvitationEmails: 'Los siguientes usuarios no fueron invitados exitosamente', ok: 'OK', removeFromTeam: 'Eliminar del equipo', removeFromTeamTip: 'Se eliminará el acceso al equipo', @@ -206,7 +208,7 @@ const translation = { setMember: 'Establecer como miembro ordinario', setBuilder: 'Establecer como constructor', setEditor: 'Establecer como editor', - disinvite: 'Cancelar la invitación', + disInvite: 'Cancelar la invitación', deleteMember: 'Eliminar miembro', you: '(Tú)', }, diff --git a/web/i18n/es-ES/dataset-creation.ts b/web/i18n/es-ES/dataset-creation.ts index 66b8e9b302..132c9cbb9b 100644 --- a/web/i18n/es-ES/dataset-creation.ts +++ b/web/i18n/es-ES/dataset-creation.ts @@ -50,7 +50,7 @@ const translation = { input: 'Nombre del conocimiento', placeholder: 'Por favor ingresa', nameNotEmpty: 'El nombre no puede estar vacío', - nameLengthInvaild: 'El nombre debe tener entre 1 y 40 caracteres', + nameLengthInvalid: 'El nombre debe tener entre 1 y 40 caracteres', cancelButton: 'Cancelar', confirmButton: 'Crear', failed: 'Error al crear', @@ -109,8 +109,8 @@ const translation = { QATitle: 'Segmentación en formato de pregunta y respuesta', QATip: 'Habilitar esta opción consumirá más tokens', QALanguage: 'Segmentar usando', - emstimateCost: 'Estimación', - emstimateSegment: 'Fragmentos estimados', + estimateCost: 'Estimación', + estimateSegment: 'Fragmentos estimados', segmentCount: 'fragmentos', calculating: 'Calculando...', fileSource: 'Preprocesar documentos', @@ -135,8 +135,8 @@ const translation = { previewSwitchTipStart: 'La vista previa actual del fragmento está en formato de texto, cambiar a una vista previa en formato de pregunta y respuesta', previewSwitchTipEnd: ' consumirá tokens adicionales', characters: 'caracteres', - indexSettedTip: 'Para cambiar el método de índice, por favor ve a la ', - retrivalSettedTip: 'Para cambiar el método de índice, por favor ve a la ', + indexSettingTip: 'Para cambiar el método de índice, por favor ve a la ', + retrievalSettingTip: 'Para cambiar el método de índice, por favor ve a la ', datasetSettingLink: 'configuración del conocimiento.', }, stepThree: { diff --git a/web/i18n/es-ES/dataset.ts b/web/i18n/es-ES/dataset.ts index e4fc362efa..4eefb621d2 100644 --- a/web/i18n/es-ES/dataset.ts +++ b/web/i18n/es-ES/dataset.ts @@ -71,6 +71,7 @@ const translation = { nTo1RetrievalLegacy: 'La recuperación N-a-1 será oficialmente obsoleta a partir de septiembre. Se recomienda utilizar la última recuperación de múltiples rutas para obtener mejores resultados.', nTo1RetrievalLegacyLink: 'Más información', nTo1RetrievalLegacyLinkText: 'La recuperación N-a-1 será oficialmente obsoleta en septiembre.', + defaultRetrievalTip: 'De forma predeterminada, se utiliza la recuperación de varias rutas. El conocimiento se recupera de múltiples bases de conocimiento y luego se vuelve a clasificar.', } export default translation diff --git a/web/i18n/es-ES/login.ts b/web/i18n/es-ES/login.ts index dc12cfc32f..e56161895e 100644 --- a/web/i18n/es-ES/login.ts +++ b/web/i18n/es-ES/login.ts @@ -32,7 +32,7 @@ const translation = { pp: 'Política de privacidad', tosDesc: 'Al registrarte, aceptas nuestros', goToInit: 'Si no has inicializado la cuenta, por favor ve a la página de inicialización', - donthave: '¿No tienes?', + dontHave: '¿No tienes?', invalidInvitationCode: 'Código de invitación inválido', accountAlreadyInited: 'La cuenta ya está inicializada', forgotPassword: '¿Olvidaste tu contraseña?', diff --git a/web/i18n/es-ES/share-app.ts b/web/i18n/es-ES/share-app.ts index 2e436c4327..b1ac171389 100644 --- a/web/i18n/es-ES/share-app.ts +++ b/web/i18n/es-ES/share-app.ts @@ -2,7 +2,7 @@ const translation = { common: { welcome: '', appUnavailable: 'La aplicación no está disponible', - appUnkonwError: 'La aplicación no está disponible', + appUnknownError: 'La aplicación no está disponible', }, chat: { newChat: 'Nuevo chat', @@ -10,7 +10,7 @@ const translation = { unpinnedTitle: 'Chats', newChatDefaultName: 'Nueva conversación', resetChat: 'Reiniciar conversación', - powerBy: 'Desarrollado por', + poweredBy: 'Desarrollado por', prompt: 'Indicación', privatePromptConfigTitle: 'Configuración de la conversación', publicPromptConfigTitle: 'Indicación inicial', diff --git a/web/i18n/es-ES/workflow.ts b/web/i18n/es-ES/workflow.ts index 38f2ad68b1..7db2b48687 100644 --- a/web/i18n/es-ES/workflow.ts +++ b/web/i18n/es-ES/workflow.ts @@ -36,7 +36,7 @@ const translation = { searchVar: 'Buscar variable', variableNamePlaceholder: 'Nombre de la variable', setVarValuePlaceholder: 'Establecer variable', - needConnecttip: 'Este paso no está conectado a nada', + needConnectTip: 'Este paso no está conectado a nada', maxTreeDepth: 'Límite máximo de {{depth}} nodos por rama', needEndNode: 'Debe agregarse el bloque de Fin', needAnswerNode: 'Debe agregarse el bloque de Respuesta', @@ -186,6 +186,7 @@ const translation = { 'transform': 'Transformar', 'utilities': 'Utilidades', 'noResult': 'No se encontraron coincidencias', + 'searchTool': 'Herramienta de búsqueda', }, blocks: { 'start': 'Inicio', @@ -411,10 +412,12 @@ const translation = { 'not empty': 'no está vacío', 'null': 'es nulo', 'not null': 'no es nulo', + 'regex match': 'Coincidencia de expresiones regulares', }, enterValue: 'Ingresa un valor', addCondition: 'Agregar condición', conditionNotSetup: 'Condición NO configurada', + selectVariable: 'Seleccionar variable...', }, variableAssigner: { title: 'Asignar variables', @@ -533,6 +536,9 @@ const translation = { stopBy: 'Detenido por {{user}}', }, }, + tracing: { + stopBy: 'Pásate por {{usuario}}', + }, } export default translation diff --git a/web/i18n/fa-IR/app-api.ts b/web/i18n/fa-IR/app-api.ts index 0548ef2a2b..7f65481fcf 100644 --- a/web/i18n/fa-IR/app-api.ts +++ b/web/i18n/fa-IR/app-api.ts @@ -10,7 +10,7 @@ const translation = { pause: 'مکث', playing: 'در حال پخش', loading: 'در حال بارگذاری', - merMaind: { + merMaid: { rerender: 'بازسازی مجدد', }, never: 'هرگز', diff --git a/web/i18n/fa-IR/app-debug.ts b/web/i18n/fa-IR/app-debug.ts index 1ce222581d..00891f3b17 100644 --- a/web/i18n/fa-IR/app-debug.ts +++ b/web/i18n/fa-IR/app-debug.ts @@ -294,7 +294,7 @@ const translation = { historyNoBeEmpty: 'تاریخچه مکالمه باید در پرس و جو تنظیم شود', queryNoBeEmpty: 'پرس و جو باید در پرس و جو تنظیم شود', }, - variableConig: { + variableConfig: { 'addModalTitle': 'افزودن فیلد ورودی', 'editModalTitle': 'ویرایش فیلد ورودی', 'description': 'تنظیم برای متغیر {{varName}}', diff --git a/web/i18n/fa-IR/app-overview.ts b/web/i18n/fa-IR/app-overview.ts index 1bbd7a0283..8a0057fb82 100644 --- a/web/i18n/fa-IR/app-overview.ts +++ b/web/i18n/fa-IR/app-overview.ts @@ -48,6 +48,8 @@ const translation = { title: 'مراحل کاری', show: 'نمایش', hide: 'مخفی کردن', + showDesc: 'نمایش یا پنهان کردن جزئیات گردش کار در WebApp', + subTitle: 'جزئیات گردش کار', }, chatColorTheme: 'تم رنگی چت', chatColorThemeDesc: 'تم رنگی چت‌بات را تنظیم کنید', @@ -64,6 +66,12 @@ const translation = { customDisclaimerPlaceholder: 'متن سلب مسئولیت سفارشی را وارد کنید', customDisclaimerTip: 'متن سلب مسئولیت سفارشی در سمت مشتری نمایش داده می‌شود و اطلاعات بیشتری درباره برنامه ارائه می‌دهد', }, + sso: { + title: 'WebApp SSO', + label: 'احراز هویت SSO', + description: 'همه کاربران باید قبل از استفاده از WebApp با SSO وارد شوند', + tooltip: 'برای فعال کردن WebApp SSO با سرپرست تماس بگیرید', + }, }, embedded: { entry: 'جاسازی شده', @@ -119,7 +127,11 @@ const translation = { tokenPS: 'توکن/ثانیه', totalMessages: { title: 'کل پیام‌ها', - explanation: 'تعداد تعاملات روزانه با AI؛ مهندسی/اشکال‌زدایی دستورات مستثنی هستند.', + explanation: 'تعداد تعاملات روزانه با هوش مصنوعی.', + }, + totalConversations: { + title: 'کل مکالمات', + explanation: 'تعداد مکالمات روزانه با هوش مصنوعی؛ مهندسی/اشکال‌زدایی پرامپت مستثنی است.', }, activeUsers: { title: 'کاربران فعال', diff --git a/web/i18n/fa-IR/app.ts b/web/i18n/fa-IR/app.ts index b9dd179809..9283b04287 100644 --- a/web/i18n/fa-IR/app.ts +++ b/web/i18n/fa-IR/app.ts @@ -126,6 +126,12 @@ const translation = { removeConfirmTitle: 'حذف پیکربندی {{key}}؟', removeConfirmContent: 'پیکربندی فعلی در حال استفاده است، حذف آن ویژگی ردیابی را غیرفعال خواهد کرد.', }, + view: 'مشاهده', + }, + answerIcon: { + descriptionInExplore: 'آیا از نماد WebApp برای جایگزینی 🤖 در Explore استفاده کنیم یا خیر', + description: 'آیا از نماد WebApp برای جایگزینی 🤖 در برنامه مشترک استفاده کنیم یا خیر', + title: 'از نماد WebApp برای جایگزینی 🤖 استفاده کنید', }, } diff --git a/web/i18n/fa-IR/common.ts b/web/i18n/fa-IR/common.ts index e4417bcbcc..c75ab11a63 100644 --- a/web/i18n/fa-IR/common.ts +++ b/web/i18n/fa-IR/common.ts @@ -37,6 +37,7 @@ const translation = { params: 'پارامترها', duplicate: 'تکرار', rename: 'تغییر نام', + audioSourceUnavailable: 'منبع صوتی در دسترس نیست', }, errorMsg: { fieldRequired: '{{field}} الزامی است', @@ -132,7 +133,8 @@ const translation = { workspace: 'فضای کاری', createWorkspace: 'ایجاد فضای کاری', helpCenter: 'راهنما', - roadmapAndFeedback: 'بازخورد', + communityFeedback: 'بازخورد', + roadmap: 'نقشه راه', community: 'انجمن', about: 'درباره', logout: 'خروج', @@ -198,7 +200,7 @@ const translation = { invitationSent: 'دعوت‌نامه ارسال شد', invitationSentTip: 'دعوت‌نامه ارسال شد و آنها می‌توانند وارد Dify شوند تا به داده‌های تیم شما دسترسی پیدا کنند.', invitationLink: 'لینک دعوت', - failedinvitationEmails: 'کاربران زیر با موفقیت دعوت نشدند', + failedInvitationEmails: 'کاربران زیر با موفقیت دعوت نشدند', ok: 'تایید', removeFromTeam: 'حذف از تیم', removeFromTeamTip: 'دسترسی تیم را حذف می‌کند', @@ -206,7 +208,7 @@ const translation = { setMember: 'تنظیم به عنوان عضو عادی', setBuilder: 'تنظیم به عنوان سازنده', setEditor: 'تنظیم به عنوان ویرایشگر', - disinvite: 'لغو دعوت', + disInvite: 'لغو دعوت', deleteMember: 'حذف عضو', you: '(شما)', }, diff --git a/web/i18n/fa-IR/dataset-creation.ts b/web/i18n/fa-IR/dataset-creation.ts index f8483af140..e6e6ad5bfb 100644 --- a/web/i18n/fa-IR/dataset-creation.ts +++ b/web/i18n/fa-IR/dataset-creation.ts @@ -50,7 +50,7 @@ const translation = { input: 'نام دانش', placeholder: 'لطفاً وارد کنید', nameNotEmpty: 'نام نمیتواند خالی باشد', - nameLengthInvaild: 'نام باید بین 1 تا 40 کاراکتر باشد', + nameLengthInvalid: 'نام باید بین 1 تا 40 کاراکتر باشد', cancelButton: 'لغو', confirmButton: 'ایجاد', failed: 'ایجاد ناموفق بود', @@ -109,8 +109,8 @@ const translation = { QATitle: 'بخشبندی در قالب پرسش و پاسخ', QATip: 'فعال کردن این گزینه توکنهای بیشتری مصرف خواهد کرد', QALanguage: 'بخشبندی با استفاده از', - emstimateCost: 'برآورد', - emstimateSegment: 'بخشهای برآورد شده', + estimateCost: 'برآورد', + estimateSegment: 'بخشهای برآورد شده', segmentCount: 'بخشها', calculating: 'در حال محاسبه...', fileSource: 'پیشپردازش اسناد', @@ -135,8 +135,8 @@ const translation = { previewSwitchTipStart: 'پیشنمایش بخش فعلی در قالب متن است، تغییر به پیشنمایش قالب پرسش و پاسخ', previewSwitchTipEnd: ' توکنهای اضافی مصرف خواهد کرد', characters: 'کاراکترها', - indexSettedTip: 'برای تغییر روش شاخص، لطفاً به', - retrivalSettedTip: 'برای تغییر روش شاخص، لطفاً به', + indexSettingTip: 'برای تغییر روش شاخص، لطفاً به', + retrievalSettingTip: 'برای تغییر روش شاخص، لطفاً به', datasetSettingLink: 'تنظیمات دانش بروید.', }, stepThree: { diff --git a/web/i18n/fa-IR/dataset.ts b/web/i18n/fa-IR/dataset.ts index 30036dc68f..e3b9d70e07 100644 --- a/web/i18n/fa-IR/dataset.ts +++ b/web/i18n/fa-IR/dataset.ts @@ -71,6 +71,7 @@ const translation = { nTo1RetrievalLegacy: 'بازیابی N-to-1 از سپتامبر به طور رسمی منسوخ خواهد شد. توصیه می‌شود از بازیابی چند مسیر جدید استفاده کنید تا نتایج بهتری بدست آورید.', nTo1RetrievalLegacyLink: 'بیشتر بدانید', nTo1RetrievalLegacyLinkText: ' بازیابی N-to-1 از سپتامبر به طور رسمی منسوخ خواهد شد.', + defaultRetrievalTip: 'بازیابی چند مسیره به طور پیش فرض استفاده می شود. دانش از چندین پایگاه دانش بازیابی می شود و سپس دوباره رتبه بندی می شود.', } export default translation diff --git a/web/i18n/fa-IR/login.ts b/web/i18n/fa-IR/login.ts index 8912561efe..4ac06c866d 100644 --- a/web/i18n/fa-IR/login.ts +++ b/web/i18n/fa-IR/login.ts @@ -32,7 +32,7 @@ const translation = { pp: 'سیاست حفظ حریم خصوصی', tosDesc: 'با ثبت نام، شما با شرایط ما موافقت می‌کنید', goToInit: 'اگر حساب را اولیه نکرده‌اید، لطفاً به صفحه اولیه‌سازی بروید', - donthave: 'ندارید؟', + dontHave: 'ندارید؟', invalidInvitationCode: 'کد دعوت نامعتبر است', accountAlreadyInited: 'حساب قبلاً اولیه شده است', forgotPassword: 'رمز عبور خود را فراموش کرده‌اید؟', diff --git a/web/i18n/fa-IR/share-app.ts b/web/i18n/fa-IR/share-app.ts index b74c893e6e..f3f1360a92 100644 --- a/web/i18n/fa-IR/share-app.ts +++ b/web/i18n/fa-IR/share-app.ts @@ -2,7 +2,7 @@ const translation = { common: { welcome: '', appUnavailable: 'اپ در دسترس نیست', - appUnkonwError: 'اپ در دسترس نیست', + appUnknownError: 'اپ در دسترس نیست', }, chat: { newChat: 'چت جدید', @@ -10,7 +10,7 @@ const translation = { unpinnedTitle: 'چت‌ها', newChatDefaultName: 'مکالمه جدید', resetChat: 'بازنشانی مکالمه', - powerBy: 'قدرت‌گرفته از', + poweredBy: 'قدرت‌گرفته از', prompt: 'پیشنهاد', privatePromptConfigTitle: 'تنظیمات مکالمه', publicPromptConfigTitle: 'پیشنهاد اولیه', diff --git a/web/i18n/fa-IR/workflow.ts b/web/i18n/fa-IR/workflow.ts index 6dc326e829..da2d439a36 100644 --- a/web/i18n/fa-IR/workflow.ts +++ b/web/i18n/fa-IR/workflow.ts @@ -36,7 +36,7 @@ const translation = { searchVar: 'جستجوی متغیر', variableNamePlaceholder: 'نام متغیر', setVarValuePlaceholder: 'تنظیم متغیر', - needConnecttip: 'این مرحله به هیچ چیزی متصل نیست', + needConnectTip: 'این مرحله به هیچ چیزی متصل نیست', maxTreeDepth: 'حداکثر عمق {{depth}} نود در هر شاخه', needEndNode: 'بلوک پایان باید اضافه شود', needAnswerNode: 'بلوک پاسخ باید اضافه شود', @@ -186,6 +186,7 @@ const translation = { 'transform': 'تبدیل', 'utilities': 'ابزارهای کاربردی', 'noResult': 'نتیجه‌ای پیدا نشد', + 'searchTool': 'ابزار جستجو', }, blocks: { 'start': 'شروع', @@ -411,6 +412,7 @@ const translation = { 'not empty': 'خالی نیست', 'null': 'خالی', 'not null': 'خالی نیست', + 'regex match': 'مسابقه regex', }, enterValue: 'مقدار را وارد کنید', addCondition: 'افزودن شرط', diff --git a/web/i18n/fr-FR/app-api.ts b/web/i18n/fr-FR/app-api.ts index c214e0a9c9..af3f752f98 100644 --- a/web/i18n/fr-FR/app-api.ts +++ b/web/i18n/fr-FR/app-api.ts @@ -9,7 +9,7 @@ const translation = { play: 'Jouer', pause: 'Pause', playing: 'Jouant', - merMaind: { + merMaid: { rerender: 'Refaire Rerendu', }, never: 'Jamais', @@ -77,6 +77,7 @@ const translation = { pathParams: 'Params de chemin', query: 'Requête', }, + loading: 'Chargement', } export default translation diff --git a/web/i18n/fr-FR/app-debug.ts b/web/i18n/fr-FR/app-debug.ts index b71d251956..2fd863742b 100644 --- a/web/i18n/fr-FR/app-debug.ts +++ b/web/i18n/fr-FR/app-debug.ts @@ -248,7 +248,7 @@ const translation = { historyNoBeEmpty: 'L\'historique de la conversation doit être défini dans le prompt', queryNoBeEmpty: 'La requête doit être définie dans le prompt', }, - variableConig: { + variableConfig: { 'addModalTitle': 'Add Input Field', 'editModalTitle': 'Edit Input Field', 'description': 'Setting for variable {{varName}}', diff --git a/web/i18n/fr-FR/app-overview.ts b/web/i18n/fr-FR/app-overview.ts index 23032f9897..26d538e903 100644 --- a/web/i18n/fr-FR/app-overview.ts +++ b/web/i18n/fr-FR/app-overview.ts @@ -48,6 +48,8 @@ const translation = { title: 'Étapes du workflow', show: 'Afficher', hide: 'Masquer', + showDesc: 'Afficher ou masquer les détails du flux de travail dans WebApp', + subTitle: 'Détails du flux de travail', }, chatColorTheme: 'Thème de couleur du chatbot', chatColorThemeDesc: 'Définir le thème de couleur du chatbot', @@ -64,6 +66,12 @@ const translation = { customDisclaimerPlaceholder: 'Entrez le texte de la clause de non-responsabilité personnalisée', customDisclaimerTip: 'Le texte de la clause de non-responsabilité personnalisée sera affiché côté client, fournissant des informations supplémentaires sur l\'application', }, + sso: { + label: 'Authentification SSO', + title: 'WebApp SSO', + tooltip: 'Contactez l’administrateur pour activer l’authentification unique WebApp', + description: 'Tous les utilisateurs doivent se connecter avec l’authentification unique avant d’utiliser WebApp', + }, }, embedded: { entry: 'Intégré', @@ -119,7 +127,11 @@ const translation = { tokenPS: 'Token/s', totalMessages: { title: 'Total des messages', - explanation: 'Nombre d\'interactions quotidiennes avec l\'IA ; l\'ingénierie/le débogage des prompts sont exclus.', + explanation: 'Nombre d\'interactions quotidiennes avec l\'IA.', + }, + totalConversations: { + title: 'Conversations totales', + explanation: 'Nombre de conversations quotidiennes avec l\'IA ; ingénierie/débogage des prompts exclus.', }, activeUsers: { title: 'Utilisateurs actifs', diff --git a/web/i18n/fr-FR/app.ts b/web/i18n/fr-FR/app.ts index fab9b98f99..55966f6966 100644 --- a/web/i18n/fr-FR/app.ts +++ b/web/i18n/fr-FR/app.ts @@ -122,7 +122,17 @@ const translation = { removeConfirmTitle: 'Supprimer la configuration de {{key}} ?', removeConfirmContent: 'La configuration actuelle est en cours d\'utilisation, sa suppression désactivera la fonction de Traçage.', }, + view: 'Vue', }, + answerIcon: { + description: 'S’il faut utiliser l’icône WebApp pour remplacer 🤖 dans l’application partagée', + title: 'Utiliser l’icône WebApp pour remplacer 🤖', + descriptionInExplore: 'Utilisation de l’icône WebApp pour remplacer 🤖 dans Explore', + }, + importFromDSLUrlPlaceholder: 'Collez le lien DSL ici', + importFromDSL: 'Importation à partir d’une DSL', + importFromDSLUrl: 'À partir de l’URL', + importFromDSLFile: 'À partir d’un fichier DSL', } export default translation diff --git a/web/i18n/fr-FR/billing.ts b/web/i18n/fr-FR/billing.ts index 09c8ca43a8..2bcdfd5b23 100644 --- a/web/i18n/fr-FR/billing.ts +++ b/web/i18n/fr-FR/billing.ts @@ -60,6 +60,8 @@ const translation = { bulkUpload: 'Téléchargement en masse de documents', agentMode: 'Mode Agent', workflow: 'Flux de travail', + llmLoadingBalancingTooltip: 'Ajoutez plusieurs clés API aux modèles, en contournant efficacement les limites de débit de l’API.', + llmLoadingBalancing: 'Équilibrage de charge LLM', }, comingSoon: 'Bientôt disponible', member: 'Membre', @@ -74,6 +76,7 @@ const translation = { }, ragAPIRequestTooltip: 'Fait référence au nombre d\'appels API invoquant uniquement les capacités de traitement de la base de connaissances de Dify.', receiptInfo: 'Seuls le propriétaire de l\'équipe et l\'administrateur de l\'équipe peuvent s\'abonner et consulter les informations de facturation', + annotationQuota: 'Quota d’annotation', }, plans: { sandbox: { diff --git a/web/i18n/fr-FR/common.ts b/web/i18n/fr-FR/common.ts index 2ae0731006..c4fed4405d 100644 --- a/web/i18n/fr-FR/common.ts +++ b/web/i18n/fr-FR/common.ts @@ -37,6 +37,7 @@ const translation = { params: 'Paramètres', duplicate: 'Dupliquer', rename: 'Renommer', + audioSourceUnavailable: 'AudioSource n’est pas disponible', }, placeholder: { input: 'Veuillez entrer', @@ -128,7 +129,8 @@ const translation = { workspace: 'Espace de travail', createWorkspace: 'Créer un Espace de Travail', helpCenter: 'Aide', - roadmapAndFeedback: 'Retour d\'information', + communityFeedback: 'Retour d\'information', + roadmap: 'Feuille de route', community: 'Communauté', about: 'À propos', logout: 'Se déconnecter', @@ -190,16 +192,21 @@ const translation = { invitationSent: 'Invitation envoyée', invitationSentTip: 'Invitation envoyée, et ils peuvent se connecter à Dify pour accéder aux données de votre équipe.', invitationLink: 'Lien d\'invitation', - failedinvitationEmails: 'Les utilisateurs ci-dessous n\'ont pas été invités avec succès', + failedInvitationEmails: 'Les utilisateurs ci-dessous n\'ont pas été invités avec succès', ok: 'D\'accord', removeFromTeam: 'Retirer de l\'équipe', removeFromTeamTip: 'Supprimera l\'accès de l\'équipe', setAdmin: 'Définir comme administrateur', setMember: 'Définir en tant que membre ordinaire', setEditor: 'Définir en tant qu\'éditeur', - disinvite: 'Annuler l\'invitation', + disInvite: 'Annuler l\'invitation', deleteMember: 'Supprimer Membre', you: '(Vous)', + builder: 'Constructeur', + datasetOperatorTip: 'Seul peut gérer la base de connaissances', + datasetOperator: 'Administrateur des connaissances', + setBuilder: 'Définir en tant que constructeur', + builderTip: 'Peut créer et modifier ses propres applications', }, integrations: { connected: 'Connecté', @@ -346,6 +353,22 @@ const translation = { quotaTip: 'Tokens gratuits restants disponibles', loadPresets: 'Charger les Présents', parameters: 'PARAMÈTRES', + modelHasBeenDeprecated: 'Ce modèle est obsolète', + providerManagedDescription: 'Utilisez l’ensemble unique d’informations d’identification fourni par le fournisseur de modèle.', + loadBalancingHeadline: 'Équilibrage', + loadBalancing: 'Équilibrage', + loadBalancingLeastKeyWarning: 'Pour activer l’équilibrage de charge, au moins 2 clés doivent être activées.', + apiKey: 'API-KEY', + apiKeyStatusNormal: 'L’état de l’APIKey est normal', + configLoadBalancing: 'Équilibrage de charge de configuration', + loadBalancingInfo: 'Par défaut, l’équilibrage de charge utilise la stratégie Round-robin. Si la limitation de vitesse est déclenchée, une période de recharge de 1 minute sera appliquée.', + editConfig: 'Modifier la configuration', + addConfig: 'Ajouter une configuration', + apiKeyRateLimit: 'La limite de débit a été atteinte, disponible après {{secondes}}s', + defaultConfig: 'Configuration par défaut', + loadBalancingDescription: 'Réduisez la pression grâce à plusieurs ensembles d’informations d’identification.', + providerManaged: 'Géré par le fournisseur', + upgradeForLoadBalancing: 'Mettez à niveau votre plan pour activer l’équilibrage de charge.', }, dataSource: { add: 'Ajouter une source de données', @@ -369,6 +392,15 @@ const translation = { preview: 'APERÇU', }, }, + website: { + configuredCrawlers: 'Robots d’exploration configurés', + with: 'Avec', + inactive: 'Inactif', + active: 'Actif', + title: 'Site internet', + description: 'Importez du contenu à partir de sites Web à l’aide du robot d’indexation.', + }, + configure: 'Configurer', }, plugin: { serpapi: { @@ -537,6 +569,10 @@ const translation = { created: 'Tag créé avec succès', failed: 'La création de la balise a échoué', }, + errorMsg: { + fieldRequired: '{{field}} est obligatoire', + urlError: 'L’URL doit commencer par http:// ou https://', + }, } export default translation diff --git a/web/i18n/fr-FR/dataset-creation.ts b/web/i18n/fr-FR/dataset-creation.ts index da3ac8d476..c08a3e5731 100644 --- a/web/i18n/fr-FR/dataset-creation.ts +++ b/web/i18n/fr-FR/dataset-creation.ts @@ -45,11 +45,35 @@ const translation = { input: 'Nom de la connaissance', placeholder: 'Veuillez entrer', nameNotEmpty: 'Le nom ne peut pas être vide', - nameLengthInvaild: 'Le nom doit comporter entre 1 et 40 caractères.', + nameLengthInvalid: 'Le nom doit comporter entre 1 et 40 caractères.', cancelButton: 'Annuler', confirmButton: 'Créer', failed: 'Création échouée', }, + website: { + limit: 'Limite', + fireCrawlNotConfiguredDescription: 'Configurez Firecrawl avec la clé API pour l’utiliser.', + selectAll: 'Tout sélectionner', + unknownError: 'Erreur inconnue', + firecrawlDoc: 'Docs Firecrawl', + totalPageScraped: 'Nombre total de pages extraites :', + preview: 'Aperçu', + crawlSubPage: 'Explorer les sous-pages', + configure: 'Configurer', + firecrawlDocLink: 'https://docs.dify.ai/guides/knowledge-base/sync-from-website', + maxDepth: 'Profondeur maximale', + fireCrawlNotConfigured: 'Firecrawl n’est pas configuré', + firecrawlTitle: 'Extraire du contenu web avec 🔥Firecrawl', + scrapTimeInfo: 'Pages récupérées au total dans un délai de {{time}}s', + options: 'Options', + exceptionErrorTitle: 'Une exception s’est produite lors de l’exécution de la tâche Firecrawl :', + includeOnlyPaths: 'Inclure uniquement les chemins d’accès', + resetAll: 'Tout réinitialiser', + run: 'Courir', + extractOnlyMainContent: 'Extraire uniquement le contenu principal (pas d’en-têtes, de navigations, de pieds de page, etc.)', + excludePaths: 'Exclure les chemins d’accès', + maxDepthTooltip: 'Profondeur maximale à explorer par rapport à l’URL saisie. La profondeur 0 gratte simplement la page de l’URL saisie, la profondeur 1 récupère l’URL et tout ce qui suit l’URL saisie + un /, et ainsi de suite.', + }, }, stepTwo: { segmentation: 'Paramètres de bloc', @@ -80,8 +104,8 @@ const translation = { QATitle: 'Segmentation en format Question & Réponse', QATip: 'Activer cette option consommera plus de jetons', QALanguage: 'Segmenter en utilisant', - emstimateCost: 'Estimation', - emstimateSegment: 'Morceaux estimés', + estimateCost: 'Estimation', + estimateSegment: 'Morceaux estimés', segmentCount: 'morceaux', calculating: 'En calcul...', fileSource: 'Prétraiter les documents', @@ -104,9 +128,11 @@ const translation = { previewSwitchTipStart: 'L\'aperçu actuel du morceau est en format texte, passer à un aperçu en format de questions-réponses va', previewSwitchTipEnd: 'consommer des tokens supplémentaires', characters: 'personnages', - indexSettedTip: 'Pour changer la méthode d\'index, veuillez aller à la', - retrivalSettedTip: 'Pour changer la méthode d\'index, veuillez aller à la', + indexSettingTip: 'Pour changer la méthode d\'index, veuillez aller à la', + retrievalSettingTip: 'Pour changer la méthode d\'index, veuillez aller à la', datasetSettingLink: 'Paramètres de connaissance.', + webpageUnit: 'Pages', + websiteSource: 'Site web de prétraitement', }, stepThree: { creationTitle: '🎉 Connaissance créée', @@ -125,6 +151,11 @@ const translation = { modelButtonConfirm: 'Confirmer', modelButtonCancel: 'Annuler', }, + firecrawl: { + apiKeyPlaceholder: 'Clé API de firecrawl.dev', + configFirecrawl: 'Configurer 🔥Firecrawl', + getApiKeyLinkText: 'Obtenez votre clé API auprès de firecrawl.dev', + }, } export default translation diff --git a/web/i18n/fr-FR/dataset-documents.ts b/web/i18n/fr-FR/dataset-documents.ts index c6b0fca1df..1aad7870a8 100644 --- a/web/i18n/fr-FR/dataset-documents.ts +++ b/web/i18n/fr-FR/dataset-documents.ts @@ -13,6 +13,8 @@ const translation = { status: 'STATUT', action: 'ACTION', }, + rename: 'Renommer', + name: 'Nom', }, action: { uploadFile: 'Télécharger un nouveau fichier', @@ -74,6 +76,7 @@ const translation = { error: 'Erreur d\'Importation', ok: 'D\'accord', }, + addUrl: 'Ajouter une URL', }, metadata: { title: 'Métadonnées', diff --git a/web/i18n/fr-FR/dataset-settings.ts b/web/i18n/fr-FR/dataset-settings.ts index 84d1692dff..9b1f44f54f 100644 --- a/web/i18n/fr-FR/dataset-settings.ts +++ b/web/i18n/fr-FR/dataset-settings.ts @@ -27,6 +27,8 @@ const translation = { longDescription: 'À propos de la méthode de récupération, vous pouvez la modifier à tout moment dans les paramètres de Connaissance.', }, save: 'Enregistrer', + me: '(Vous)', + permissionsInvitedMembers: 'Membres partiels de l’équipe', }, } diff --git a/web/i18n/fr-FR/dataset.ts b/web/i18n/fr-FR/dataset.ts index 014168e006..9c8df9f79d 100644 --- a/web/i18n/fr-FR/dataset.ts +++ b/web/i18n/fr-FR/dataset.ts @@ -71,6 +71,7 @@ const translation = { nTo1RetrievalLegacy: 'La récupération N-à-1 sera officiellement obsolète à partir de septembre. Il est recommandé d\'utiliser la dernière récupération multi-chemins pour obtenir de meilleurs résultats.', nTo1RetrievalLegacyLink: 'En savoir plus', nTo1RetrievalLegacyLinkText: 'La récupération N-à-1 sera officiellement obsolète en septembre.', + defaultRetrievalTip: 'La récupération à chemins multiples est utilisée par défaut. Les connaissances sont extraites de plusieurs bases de connaissances, puis reclassées.', } export default translation diff --git a/web/i18n/fr-FR/login.ts b/web/i18n/fr-FR/login.ts index c905320b22..cee09cf0e7 100644 --- a/web/i18n/fr-FR/login.ts +++ b/web/i18n/fr-FR/login.ts @@ -31,7 +31,7 @@ const translation = { pp: 'Politique de Confidentialité', tosDesc: 'En vous inscrivant, vous acceptez nos', goToInit: 'Si vous n\'avez pas initialisé le compte, veuillez vous rendre sur la page d\'initialisation', - donthave: 'Vous n\'avez pas ?', + dontHave: 'Vous n\'avez pas ?', invalidInvitationCode: 'Code d\'invitation invalide', accountAlreadyInited: 'Compte déjà initialisé', forgotPassword: 'Mot de passe oublié?', @@ -53,6 +53,7 @@ const translation = { nameEmpty: 'Le nom est requis', passwordEmpty: 'Un mot de passe est requis', passwordInvalid: 'Le mot de passe doit contenir des lettres et des chiffres, et la longueur doit être supérieure à 8.', + passwordLengthInValid: 'Le mot de passe doit comporter au moins 8 caractères.', }, license: { tip: 'Avant de commencer Dify Community Edition, lisez le GitHub', @@ -68,6 +69,7 @@ const translation = { activated: 'Connectez-vous maintenant', adminInitPassword: 'Mot de passe d\'initialisation de l\'administrateur', validate: 'Valider', + sso: 'Poursuivre avec l’authentification unique', } export default translation diff --git a/web/i18n/fr-FR/share-app.ts b/web/i18n/fr-FR/share-app.ts index 8f9e04e941..44d03b1e35 100644 --- a/web/i18n/fr-FR/share-app.ts +++ b/web/i18n/fr-FR/share-app.ts @@ -2,7 +2,7 @@ const translation = { common: { welcome: '', appUnavailable: 'L\'application n\'est pas disponible', - appUnkonwError: 'L\'application n\'est pas disponible', + appUnknownError: 'L\'application n\'est pas disponible', }, chat: { newChat: 'Nouveau chat', @@ -10,7 +10,7 @@ const translation = { unpinnedTitle: 'Discussions', newChatDefaultName: 'Nouvelle conversation', resetChat: 'Réinitialiser la conversation', - powerBy: 'Propulsé par', + poweredBy: 'Propulsé par', prompt: 'Prompt', privatePromptConfigTitle: 'Paramètres de conversation', publicPromptConfigTitle: 'Prompt Initial', diff --git a/web/i18n/fr-FR/tools.ts b/web/i18n/fr-FR/tools.ts index 5e2c770fea..34c71e7764 100644 --- a/web/i18n/fr-FR/tools.ts +++ b/web/i18n/fr-FR/tools.ts @@ -5,6 +5,7 @@ const translation = { all: 'Tout', builtIn: 'Intégré', custom: 'Personnalisé', + workflow: 'Flux de travail', }, contribute: { line1: 'Je suis intéressé par', @@ -75,6 +76,27 @@ const translation = { customDisclaimerPlaceholder: 'Entrez le texte de la clause de non-responsabilité personnalisée', deleteToolConfirmTitle: 'Supprimer cet outil ?', deleteToolConfirmContent: 'La suppression de l\'outil est irréversible. Les utilisateurs ne pourront plus accéder à votre outil.', + toolInput: { + required: 'Obligatoire', + name: 'Nom', + label: 'Étiquettes', + title: 'Entrée d’outil', + methodSetting: 'Réglage', + labelPlaceholder: 'Choisir des balises(facultatif)', + descriptionPlaceholder: 'Description de la signification du paramètre', + method: 'Méthode', + methodParameter: 'Paramètre', + methodSettingTip: 'L’utilisateur renseigne la configuration de l’outil', + methodParameterTip: 'Remplissages LLM pendant l’inférence', + description: 'Description', + }, + nameForToolCallTip: 'Ne prend en charge que les chiffres, les lettres et les traits de soulignement.', + confirmTitle: 'Confirmer pour enregistrer ?', + nameForToolCall: 'Nom de l’appel de l’outil', + confirmTip: 'Les applications utilisant cet outil seront affectées', + description: 'Description', + nameForToolCallPlaceHolder: 'Utilisé pour la reconnaissance automatique, tels que getCurrentWeather, list_pets', + descriptionPlaceholder: 'Brève description de l’objectif de l’outil, par exemple, obtenir la température d’un endroit spécifique.', }, test: { title: 'Test', @@ -114,6 +136,18 @@ const translation = { toolRemoved: 'Outil supprimé', notAuthorized: 'Outil non autorisé', howToGet: 'Comment obtenir', + addToolModal: { + type: 'type', + emptyTitle: 'Aucun outil de flux de travail disponible', + added: 'supplémentaire', + add: 'ajouter', + category: 'catégorie', + manageInTools: 'Gérer dans Outils', + emptyTip: 'Allez dans « Flux de travail -> Publier en tant qu’outil »', + }, + openInStudio: 'Ouvrir dans Studio', + customToolTip: 'En savoir plus sur les outils personnalisés Dify', + toolNameUsageTip: 'Nom de l’appel de l’outil pour le raisonnement et l’invite de l’agent', } export default translation diff --git a/web/i18n/fr-FR/workflow.ts b/web/i18n/fr-FR/workflow.ts index d3518d5742..8691f6f0d5 100644 --- a/web/i18n/fr-FR/workflow.ts +++ b/web/i18n/fr-FR/workflow.ts @@ -36,7 +36,7 @@ const translation = { searchVar: 'Rechercher une variable', variableNamePlaceholder: 'Nom de la variable', setVarValuePlaceholder: 'Définir la valeur de la variable', - needConnecttip: 'Cette étape n\'est connectée à rien', + needConnectTip: 'Cette étape n\'est connectée à rien', maxTreeDepth: 'Limite maximale de {{depth}} nœuds par branche', needEndNode: 'Le bloc de fin doit être ajouté', needAnswerNode: 'Le bloc de réponse doit être ajouté', @@ -186,6 +186,7 @@ const translation = { 'transform': 'Transformer', 'utilities': 'Utilitaires', 'noResult': 'Aucun résultat trouvé', + 'searchTool': 'Outil de recherche', }, blocks: { 'start': 'Début', @@ -411,10 +412,12 @@ const translation = { 'not empty': 'n\'est pas vide', 'null': 'est nul', 'not null': 'n\'est pas nul', + 'regex match': 'correspondance regex', }, enterValue: 'Entrez la valeur', addCondition: 'Ajouter une condition', conditionNotSetup: 'Condition NON configurée', + selectVariable: 'Sélectionner une variable...', }, variableAssigner: { title: 'Attribuer des variables', diff --git a/web/i18n/hi-IN/app-api.ts b/web/i18n/hi-IN/app-api.ts index 3c9ceadd29..b983fd0ccb 100644 --- a/web/i18n/hi-IN/app-api.ts +++ b/web/i18n/hi-IN/app-api.ts @@ -10,7 +10,7 @@ const translation = { pause: 'विराम', playing: 'चल रहा है', loading: 'लोड हो रहा है', - merMaind: { + merMaid: { rerender: 'पुनः रीरेंडर करें', }, never: 'कभी नहीं', diff --git a/web/i18n/hi-IN/app-debug.ts b/web/i18n/hi-IN/app-debug.ts index 29944c8d84..1b0633ef32 100644 --- a/web/i18n/hi-IN/app-debug.ts +++ b/web/i18n/hi-IN/app-debug.ts @@ -290,7 +290,7 @@ const translation = { historyNoBeEmpty: 'संवाद इतिहास प्रॉम्प्ट में सेट होना चाहिए', queryNoBeEmpty: 'प्रश्न प्रॉम्प्ट में सेट होना चाहिए', }, - variableConig: { + variableConfig: { 'addModalTitle': 'इनपुट फ़ील्ड जोड़ें', 'editModalTitle': 'इनपुट फ़ील्ड संपादित करें', 'description': 'वेरिएबल {{varName}} के लिए सेटिंग', diff --git a/web/i18n/hi-IN/app-log.ts b/web/i18n/hi-IN/app-log.ts index 7ed8718668..668ae12d65 100644 --- a/web/i18n/hi-IN/app-log.ts +++ b/web/i18n/hi-IN/app-log.ts @@ -93,6 +93,10 @@ const translation = { promptTemplate: 'प्रॉम्प्ट टेम्पलेट', promptInput: 'प्रॉम्प्ट इनपुट', response: 'प्रतिक्रिया', + iterations: 'पुनरूक्तियाँ', + toolUsed: 'प्रयुक्त उपकरण', + finalProcessing: 'अंतिम प्रसंस्करण', + iteration: 'चलना', }, } diff --git a/web/i18n/hi-IN/app-overview.ts b/web/i18n/hi-IN/app-overview.ts index b75206e032..b930fd413a 100644 --- a/web/i18n/hi-IN/app-overview.ts +++ b/web/i18n/hi-IN/app-overview.ts @@ -52,6 +52,8 @@ const translation = { title: 'वर्कफ़्लो स्टेप्स', show: 'दिखाएं', hide: 'छुपाएं', + subTitle: 'कार्यप्रवाह विवरण', + showDesc: 'WebApp में वर्कफ़्लो विवरण दिखाएँ या छुपाएँ', }, chatColorTheme: 'चैटबॉट का रंग थीम', chatColorThemeDesc: 'चैटबॉट का रंग थीम निर्धारित करें', @@ -70,6 +72,12 @@ const translation = { customDisclaimerTip: 'कस्टम अस्वीकरण टेक्स्ट क्लाइंट साइड पर प्रदर्शित होगा, जो एप्लिकेशन के बारे में अतिरिक्त जानकारी प्रदान करेगा', }, + sso: { + title: 'वेबएप एसएसओ', + label: 'SSO प्रमाणीकरण', + description: 'WebApp का उपयोग करने से पहले सभी उपयोगकर्ताओं को SSO के साथ लॉगिन करना आवश्यक है', + tooltip: 'WebApp SSO को सक्षम करने के लिए व्यवस्थापक से संपर्क करें', + }, }, embedded: { entry: 'एम्बेडेड', @@ -130,8 +138,11 @@ const translation = { tokenPS: 'टोकन/से.', totalMessages: { title: 'कुल संदेश', - explanation: - 'दैनिक एआई इंटरैक्शन की गिनती; प्रॉम्प्ट इंजीनियरिंग/डीबगिंग को शामिल नहीं किया गया।', + explanation: 'दैनिक AI इंटरैक्शन की गिनती।', + }, + totalConversations: { + title: 'कुल वार्तालाप', + explanation: 'दैनिक AI वार्तालाप की गिनती; प्रॉम्प्ट इंजीनियरिंग/डीबगिंग शामिल नहीं।', }, activeUsers: { title: 'सक्रिय उपयोगकर्ता', diff --git a/web/i18n/hi-IN/app.ts b/web/i18n/hi-IN/app.ts index 3f22b6701b..06c342cf61 100644 --- a/web/i18n/hi-IN/app.ts +++ b/web/i18n/hi-IN/app.ts @@ -122,7 +122,17 @@ const translation = { removeConfirmTitle: '{{key}} कॉन्फ़िगरेशन हटाएं?', removeConfirmContent: 'वर्तमान कॉन्फ़िगरेशन उपयोग में है, इसे हटाने से ट्रेसिंग सुविधा बंद हो जाएगी।', }, + view: 'देखना', }, + answerIcon: { + title: 'बदलने 🤖 के लिए WebApp चिह्न का उपयोग करें', + descriptionInExplore: 'एक्सप्लोर में बदलने 🤖 के लिए वेबऐप आइकन का उपयोग करना है या नहीं', + description: 'साझा अनुप्रयोग में प्रतिस्थापित 🤖 करने के लिए WebApp चिह्न का उपयोग करना है या नहीं', + }, + importFromDSLFile: 'डीएसएल फ़ाइल से', + importFromDSLUrl: 'यूआरएल से', + importFromDSL: 'DSL से आयात करें', + importFromDSLUrlPlaceholder: 'डीएसएल लिंक यहां पेस्ट करें', } export default translation diff --git a/web/i18n/hi-IN/common.ts b/web/i18n/hi-IN/common.ts index 0a210072e1..256cb9d426 100644 --- a/web/i18n/hi-IN/common.ts +++ b/web/i18n/hi-IN/common.ts @@ -37,6 +37,7 @@ const translation = { params: 'पैरामीटर', duplicate: 'डुप्लिकेट', rename: 'नाम बदलें', + audioSourceUnavailable: 'ऑडियो स्रोत अनुपलब्ध है', }, errorMsg: { fieldRequired: '{{field}} आवश्यक है', @@ -137,7 +138,8 @@ const translation = { workspace: 'वर्कस्पेस', createWorkspace: 'वर्कस्पेस बनाएं', helpCenter: 'सहायता', - roadmapAndFeedback: 'प्रतिक्रिया', + communityFeedback: 'प्रतिक्रिया', + roadmap: 'रोडमैप', community: 'समुदाय', about: 'के बारे में', logout: 'लॉग आउट', @@ -172,6 +174,9 @@ const translation = { langGeniusAccountTip: 'आपका Dify खाता और संबंधित उपयोगकर्ता डेटा।', editName: 'नाम संपादित करें', showAppLength: '{{length}} ऐप्स दिखाएं', + deleteConfirmTip: 'पुष्टि करने के लिए, कृपया अपने पंजीकृत ईमेल से निम्नलिखित भेजें', + delete: 'खाता हटाएं', + deleteTip: 'अपना खाता हटाने से आपका सारा डेटा स्थायी रूप से मिट जाएगा और इसे पुनर्प्राप्त नहीं किया जा सकता है।', }, members: { team: 'टीम', @@ -201,7 +206,7 @@ const translation = { invitationSentTip: 'आमंत्रण भेजा गया, और वे साइन इन करके आपकी टीम डेटा तक पहुंच सकते हैं।', invitationLink: 'आमंत्रण लिंक', - failedinvitationEmails: + failedInvitationEmails: 'नीचे दिए गए उपयोगकर्ताओं को सफलतापूर्वक आमंत्रित नहीं किया गया', ok: 'ठीक है', removeFromTeam: 'टीम से हटाएं', @@ -210,9 +215,11 @@ const translation = { setMember: 'सामान्य सदस्य के रूप में सेट करें', setBuilder: 'निर्माता के रूप में सेट करें', setEditor: 'संपादक के रूप में सेट करें', - disinvite: 'आमंत्रण रद्द करें', + disInvite: 'आमंत्रण रद्द करें', deleteMember: 'सदस्य को हटाएं', you: '(आप)', + datasetOperator: 'ज्ञान व्यवस्थापक', + datasetOperatorTip: 'केवल नॉलेज बेस प्रबंधित कर सकते हैं', }, integrations: { connected: 'कनेक्टेड', diff --git a/web/i18n/hi-IN/dataset-creation.ts b/web/i18n/hi-IN/dataset-creation.ts index 59913c71ea..0fa71acf4a 100644 --- a/web/i18n/hi-IN/dataset-creation.ts +++ b/web/i18n/hi-IN/dataset-creation.ts @@ -51,7 +51,7 @@ const translation = { input: 'ज्ञान का नाम', placeholder: 'कृपया दर्ज करें', nameNotEmpty: 'नाम खाली नहीं हो सकता', - nameLengthInvaild: 'नाम 1 से 40 वर्णों के बीच होना चाहिए', + nameLengthInvalid: 'नाम 1 से 40 वर्णों के बीच होना चाहिए', cancelButton: 'रद्द करें', confirmButton: 'बनाएं', failed: 'बनाना विफल रहा', @@ -121,8 +121,8 @@ const translation = { QATitle: 'प्रश्न और उत्तर प्रारूप में खंड करना', QATip: 'इस विकल्प को सक्षम करने से अधिक टोकन खर्च होंगे', QALanguage: 'का उपयोग करके खंड करना', - emstimateCost: 'अनुमानित लागत', - emstimateSegment: 'अनुमानित खंड', + estimateCost: 'अनुमानित लागत', + estimateSegment: 'अनुमानित खंड', segmentCount: 'खंड', calculating: 'गणना कर रहा है...', fileSource: 'दस्तावेज़ों को पूर्व-प्रसंस्करण करें', @@ -152,8 +152,8 @@ const translation = { 'वर्तमान खंड पूर्वावलोकन पाठ प्रारूप में है, प्रश्न-उत्तर प्रारूप में स्विच करने से', previewSwitchTipEnd: ' अतिरिक्त टोकन खर्च होंगे', characters: 'वर्ण', - indexSettedTip: 'इंडेक्स विधि बदलने के लिए, कृपया जाएं ', - retrivalSettedTip: 'इंडेक्स विधि बदलने के लिए, कृपया जाएं ', + indexSettingTip: 'इंडेक्स विधि बदलने के लिए, कृपया जाएं ', + retrievalSettingTip: 'इंडेक्स विधि बदलने के लिए, कृपया जाएं ', datasetSettingLink: 'ज्ञान सेटिंग्स।', }, stepThree: { diff --git a/web/i18n/hi-IN/dataset-settings.ts b/web/i18n/hi-IN/dataset-settings.ts index cd798e4fab..129643dd85 100644 --- a/web/i18n/hi-IN/dataset-settings.ts +++ b/web/i18n/hi-IN/dataset-settings.ts @@ -32,6 +32,8 @@ const translation = { 'प्राप्ति पद्धति के बारे में, आप इसे किसी भी समय ज्ञान सेटिंग्ज में बदल सकते हैं।', }, save: 'सेवना', + me: '(आप)', + permissionsInvitedMembers: 'आंशिक टीम के सदस्य', }, } diff --git a/web/i18n/hi-IN/dataset.ts b/web/i18n/hi-IN/dataset.ts index de33113d2b..afd8cd277c 100644 --- a/web/i18n/hi-IN/dataset.ts +++ b/web/i18n/hi-IN/dataset.ts @@ -78,6 +78,7 @@ const translation = { nTo1RetrievalLegacy: 'N-से-1 पुनर्प्राप्ति सितंबर से आधिकारिक तौर पर बंद कर दी जाएगी। बेहतर परिणाम प्राप्त करने के लिए नवीनतम बहु-मार्ग पुनर्प्राप्ति का उपयोग करने की सिफारिश की जाती है।', nTo1RetrievalLegacyLink: 'और जानें', nTo1RetrievalLegacyLinkText: 'N-से-1 पुनर्प्राप्ति सितंबर में आधिकारिक तौर पर बंद कर दी जाएगी।', + defaultRetrievalTip: 'मल्टी-पाथ रिट्रीवल का उपयोग डिफ़ॉल्ट रूप से किया जाता है। ज्ञान को कई ज्ञान आधारों से पुनर्प्राप्त किया जाता है और फिर फिर से रैंक किया जाता है।', } export default translation diff --git a/web/i18n/hi-IN/login.ts b/web/i18n/hi-IN/login.ts index 3ecba9a186..b3ca0b1a52 100644 --- a/web/i18n/hi-IN/login.ts +++ b/web/i18n/hi-IN/login.ts @@ -36,7 +36,7 @@ const translation = { tosDesc: 'साइन अप करके, आप हमारी सहमति देते हैं', goToInit: 'यदि आपने खाता प्रारंभ नहीं किया है, तो कृपया प्रारंभिक पृष्ठ पर जाएं', - donthave: 'नहीं है?', + dontHave: 'नहीं है?', invalidInvitationCode: 'अवैध निमंत्रण कोड', accountAlreadyInited: 'खाता पहले से प्रारंभ किया गया है', forgotPassword: 'क्या आपने अपना पासवर्ड भूल गए हैं?', diff --git a/web/i18n/hi-IN/share-app.ts b/web/i18n/hi-IN/share-app.ts index a3884be706..a5c7816fe2 100644 --- a/web/i18n/hi-IN/share-app.ts +++ b/web/i18n/hi-IN/share-app.ts @@ -3,6 +3,7 @@ const translation = { welcome: 'आपका स्वागत है', appUnavailable: 'ऐप उपलब्ध नहीं है', appUnknownError: 'अज्ञात त्रुटि, कृपया पुनः प्रयास करें', + appUnknownError: 'ऐप अनुपलब्ध है', }, chat: { newChat: 'नया चैट', @@ -10,7 +11,7 @@ const translation = { unpinnedTitle: 'चैट', newChatDefaultName: 'नया संवाद', resetChat: 'संवाद रीसेट करें', - powerBy: 'संचालित है', + poweredBy: 'संचालित है', prompt: 'प्रॉम्प्ट', privatePromptConfigTitle: 'संवाद सेटिंग्स', publicPromptConfigTitle: 'प्रारंभिक प्रॉम्प्ट', diff --git a/web/i18n/hi-IN/tools.ts b/web/i18n/hi-IN/tools.ts index ea8e915ea3..6b0cccebad 100644 --- a/web/i18n/hi-IN/tools.ts +++ b/web/i18n/hi-IN/tools.ts @@ -103,6 +103,7 @@ const translation = { label: 'टैग', labelPlaceholder: 'टैग चुनें(वैकल्पिक)', description: 'पैरामीटर के अर्थ का विवरण', + descriptionPlaceholder: 'पैरामीटर के अर्थ का विवरण', }, customDisclaimer: 'कस्टम अस्वीकरण', customDisclaimerPlaceholder: 'कस्टम अस्वीकरण दर्ज करें', diff --git a/web/i18n/hi-IN/workflow.ts b/web/i18n/hi-IN/workflow.ts index 8891fa8bc1..96c232d72f 100644 --- a/web/i18n/hi-IN/workflow.ts +++ b/web/i18n/hi-IN/workflow.ts @@ -36,7 +36,7 @@ const translation = { searchVar: 'वेरिएबल खोजें', variableNamePlaceholder: 'वेरिएबल नाम', setVarValuePlaceholder: 'वेरिएबल सेट करें', - needConnecttip: 'यह चरण किसी से जुड़ा नहीं है', + needConnectTip: 'यह चरण किसी से जुड़ा नहीं है', maxTreeDepth: 'प्रति शाखा अधिकतम {{depth}} नोड्स की सीमा', needEndNode: 'अंत ब्लॉक जोड़ा जाना चाहिए', needAnswerNode: 'उत्तर ब्लॉक जोड़ा जाना चाहिए', @@ -73,6 +73,13 @@ const translation = { 'कार्यप्रवाह अपडेट के बाद टूल पुनः कॉन्फ़िगरेशन आवश्यक है।', viewDetailInTracingPanel: 'विवरण देखें', syncingData: 'डेटा सिंक हो रहा है, बस कुछ सेकंड।', + overwriteAndImport: 'अधिलेखित और आयात', + importSuccess: 'सफलता आयात करें', + chooseDSL: 'डीएसएल (वाईएमएल) फ़ाइल चुनें', + importDSL: 'DSL आयात करें', + backupCurrentDraft: 'बैकअप वर्तमान ड्राफ्ट', + importFailure: 'आयात विफलता', + importDSLTip: 'वर्तमान ड्राफ्ट ओवरराइट हो जाएगा। आयात करने से पहले वर्कफ़्लो को बैकअप के रूप में निर्यात करें.', }, env: { envPanelTitle: 'पर्यावरण चर', @@ -182,6 +189,7 @@ const translation = { 'transform': 'परिवर्तन', 'utilities': 'उपयोगिताएं', 'noResult': 'कोई मिलान नहीं मिला', + 'searchTool': 'खोज उपकरण', }, blocks: { 'start': 'प्रारंभ', @@ -419,10 +427,12 @@ const translation = { 'not empty': 'खाली नहीं है', 'null': 'शून्य है', 'not null': 'शून्य नहीं है', + 'regex match': 'रेगेक्स मैच', }, enterValue: 'मान दर्ज करें', addCondition: 'शर्त जोड़ें', conditionNotSetup: 'शर्त सेटअप नहीं है', + selectVariable: 'चर का चयन करें...', }, variableAssigner: { title: 'वेरिएबल्स असाइन करें', diff --git a/web/i18n/it-IT/app-api.ts b/web/i18n/it-IT/app-api.ts index a31a771a57..48aceb5c48 100644 --- a/web/i18n/it-IT/app-api.ts +++ b/web/i18n/it-IT/app-api.ts @@ -10,7 +10,7 @@ const translation = { pause: 'Pausa', playing: 'In Riproduzione', loading: 'Caricamento', - merMaind: { + merMaid: { rerender: 'Rifare il rendering', }, never: 'Mai', diff --git a/web/i18n/it-IT/app-debug.ts b/web/i18n/it-IT/app-debug.ts index a4cf7bba2d..e4555b973a 100644 --- a/web/i18n/it-IT/app-debug.ts +++ b/web/i18n/it-IT/app-debug.ts @@ -293,7 +293,7 @@ const translation = { 'La cronologia delle conversazioni deve essere impostata nel prompt', queryNoBeEmpty: 'La query deve essere impostata nel prompt', }, - variableConig: { + variableConfig: { 'addModalTitle': 'Aggiungi Campo Input', 'editModalTitle': 'Modifica Campo Input', 'description': 'Impostazione per la variabile {{varName}}', diff --git a/web/i18n/it-IT/app-overview.ts b/web/i18n/it-IT/app-overview.ts index 380f7e46ad..cd545df6c6 100644 --- a/web/i18n/it-IT/app-overview.ts +++ b/web/i18n/it-IT/app-overview.ts @@ -52,6 +52,8 @@ const translation = { title: 'Fasi del Workflow', show: 'Mostra', hide: 'Nascondi', + subTitle: 'Dettagli del flusso di lavoro', + showDesc: 'Mostrare o nascondere i dettagli del flusso di lavoro in WebApp', }, chatColorTheme: 'Tema colore chat', chatColorThemeDesc: 'Imposta il tema colore del chatbot', @@ -72,6 +74,12 @@ const translation = { customDisclaimerTip: 'Il testo del disclaimer personalizzato verrà visualizzato sul lato client, fornendo informazioni aggiuntive sull\'applicazione', }, + sso: { + label: 'Autenticazione SSO', + title: 'WebApp SSO', + description: 'Tutti gli utenti devono effettuare l\'accesso con SSO prima di utilizzare WebApp', + tooltip: 'Contattare l\'amministratore per abilitare l\'SSO di WebApp', + }, }, embedded: { entry: 'Incorporato', @@ -132,8 +140,11 @@ const translation = { tokenPS: 'Token/s', totalMessages: { title: 'Totale Messaggi', - explanation: - 'Conteggio delle interazioni giornaliere con l\'AI; ingegneria dei prompt/debug esclusi.', + explanation: 'Conteggio delle interazioni giornaliere con l\'IA.', + }, + totalConversations: { + title: 'Conversazioni totali', + explanation: 'Conteggio delle conversazioni giornaliere con l\'IA; ingegneria/debug dei prompt esclusi.', }, activeUsers: { title: 'Utenti Attivi', diff --git a/web/i18n/it-IT/app.ts b/web/i18n/it-IT/app.ts index 265cb58ec4..f28b000b58 100644 --- a/web/i18n/it-IT/app.ts +++ b/web/i18n/it-IT/app.ts @@ -134,7 +134,17 @@ const translation = { removeConfirmContent: 'La configurazione attuale è in uso, rimuovendola disattiverà la funzione di Tracciamento.', }, + view: 'Vista', }, + answerIcon: { + description: 'Se utilizzare l\'icona WebApp per la sostituzione 🤖 nell\'applicazione condivisa', + title: 'Usa l\'icona WebApp per sostituire 🤖', + descriptionInExplore: 'Se utilizzare l\'icona WebApp per sostituirla 🤖 in Esplora', + }, + importFromDSLUrl: 'Dall\'URL', + importFromDSLFile: 'Da file DSL', + importFromDSL: 'Importazione da DSL', + importFromDSLUrlPlaceholder: 'Incolla qui il link DSL', } export default translation diff --git a/web/i18n/it-IT/common.ts b/web/i18n/it-IT/common.ts index 595a5075eb..aa675bb471 100644 --- a/web/i18n/it-IT/common.ts +++ b/web/i18n/it-IT/common.ts @@ -37,6 +37,7 @@ const translation = { params: 'Parametri', duplicate: 'Duplica', rename: 'Rinomina', + audioSourceUnavailable: 'AudioSource non è disponibile', }, errorMsg: { fieldRequired: '{{field}} è obbligatorio', @@ -137,7 +138,8 @@ const translation = { workspace: 'Workspace', createWorkspace: 'Crea Workspace', helpCenter: 'Aiuto', - roadmapAndFeedback: 'Feedback', + communityFeedback: 'Feedback', + roadmap: 'Tabella di marcia', community: 'Comunità', about: 'Informazioni', logout: 'Esci', @@ -208,7 +210,7 @@ const translation = { invitationSentTip: 'Invito inviato, e possono accedere a Dify per accedere ai dati del tuo team.', invitationLink: 'Link di Invito', - failedinvitationEmails: + failedInvitationEmails: 'Gli utenti seguenti non sono stati invitati con successo', ok: 'OK', removeFromTeam: 'Rimuovi dal team', @@ -217,7 +219,7 @@ const translation = { setMember: 'Imposta come membro ordinario', setBuilder: 'Imposta come builder', setEditor: 'Imposta come editor', - disinvite: 'Annulla l\'invito', + disInvite: 'Annulla l\'invito', deleteMember: 'Elimina Membro', you: '(Tu)', }, diff --git a/web/i18n/it-IT/dataset-creation.ts b/web/i18n/it-IT/dataset-creation.ts index 553c8218c4..1629776bf3 100644 --- a/web/i18n/it-IT/dataset-creation.ts +++ b/web/i18n/it-IT/dataset-creation.ts @@ -52,7 +52,7 @@ const translation = { input: 'Nome della Conoscenza', placeholder: 'Per favore inserisci', nameNotEmpty: 'Il nome non può essere vuoto', - nameLengthInvaild: 'Il nome deve essere tra 1 e 40 caratteri', + nameLengthInvalid: 'Il nome deve essere tra 1 e 40 caratteri', cancelButton: 'Annulla', confirmButton: 'Crea', failed: 'Creazione fallita', @@ -124,8 +124,8 @@ const translation = { QATitle: 'Segmentazione in formato Domanda & Risposta', QATip: 'Abilitare questa opzione consumerà più token', QALanguage: 'Segmenta usando', - emstimateCost: 'Stima', - emstimateSegment: 'Blocchi stimati', + estimateCost: 'Stima', + estimateSegment: 'Blocchi stimati', segmentCount: 'blocchi', calculating: 'Calcolo in corso...', fileSource: 'Preprocessa documenti', @@ -155,8 +155,8 @@ const translation = { 'L\'anteprima del blocco corrente è in formato testo, il passaggio a un\'anteprima in formato domanda e risposta', previewSwitchTipEnd: ' consumerà token aggiuntivi', characters: 'caratteri', - indexSettedTip: 'Per cambiare il metodo di indicizzazione, vai alle ', - retrivalSettedTip: 'Per cambiare il metodo di indicizzazione, vai alle ', + indexSettingTip: 'Per cambiare il metodo di indicizzazione, vai alle ', + retrievalSettingTip: 'Per cambiare il metodo di indicizzazione, vai alle ', datasetSettingLink: 'impostazioni della Conoscenza.', }, stepThree: { diff --git a/web/i18n/it-IT/dataset.ts b/web/i18n/it-IT/dataset.ts index 9223a3a96d..fc79c9b4c7 100644 --- a/web/i18n/it-IT/dataset.ts +++ b/web/i18n/it-IT/dataset.ts @@ -78,6 +78,7 @@ const translation = { nTo1RetrievalLegacy: 'Il recupero N-a-1 sarà ufficialmente deprecato da settembre. Si consiglia di utilizzare il più recente recupero multi-percorso per ottenere risultati migliori.', nTo1RetrievalLegacyLink: 'Scopri di più', nTo1RetrievalLegacyLinkText: 'Il recupero N-a-1 sarà ufficialmente deprecato a settembre.', + defaultRetrievalTip: 'Per impostazione predefinita, il recupero a percorsi multipli viene utilizzato. Le informazioni vengono recuperate da più knowledge base e quindi riclassificate.', } export default translation diff --git a/web/i18n/it-IT/login.ts b/web/i18n/it-IT/login.ts index 018f9dca46..b46960aa45 100644 --- a/web/i18n/it-IT/login.ts +++ b/web/i18n/it-IT/login.ts @@ -38,7 +38,7 @@ const translation = { tosDesc: 'Iscrivendoti, accetti i nostri', goToInit: 'Se non hai inizializzato l\'account, vai alla pagina di inizializzazione', - donthave: 'Non hai?', + dontHave: 'Non hai?', invalidInvitationCode: 'Codice di invito non valido', accountAlreadyInited: 'Account già inizializzato', forgotPassword: 'Hai dimenticato la password?', diff --git a/web/i18n/it-IT/share-app.ts b/web/i18n/it-IT/share-app.ts index b1f99d0ba1..772a6e902d 100644 --- a/web/i18n/it-IT/share-app.ts +++ b/web/i18n/it-IT/share-app.ts @@ -2,7 +2,7 @@ const translation = { common: { welcome: '', appUnavailable: 'L\'app non è disponibile', - appUnkonwError: 'L\'app non è disponibile', + appUnknownError: 'L\'app non è disponibile', }, chat: { newChat: 'Nuova chat', @@ -10,7 +10,7 @@ const translation = { unpinnedTitle: 'Chat', newChatDefaultName: 'Nuova conversazione', resetChat: 'Reimposta conversazione', - powerBy: 'Powered by', + poweredBy: 'Powered by', prompt: 'Prompt', privatePromptConfigTitle: 'Impostazioni conversazione', publicPromptConfigTitle: 'Prompt iniziale', diff --git a/web/i18n/it-IT/workflow.ts b/web/i18n/it-IT/workflow.ts index 5936679e13..62ce0c5677 100644 --- a/web/i18n/it-IT/workflow.ts +++ b/web/i18n/it-IT/workflow.ts @@ -36,7 +36,7 @@ const translation = { searchVar: 'Cerca variabile', variableNamePlaceholder: 'Nome variabile', setVarValuePlaceholder: 'Imposta variabile', - needConnecttip: 'Questo passaggio non è collegato a nulla', + needConnectTip: 'Questo passaggio non è collegato a nulla', maxTreeDepth: 'Limite massimo di {{depth}} nodi per ramo', needEndNode: 'Deve essere aggiunto il blocco di Fine', needAnswerNode: 'Deve essere aggiunto il blocco di Risposta', @@ -191,6 +191,7 @@ const translation = { 'transform': 'Trasforma', 'utilities': 'Utility', 'noResult': 'Nessuna corrispondenza trovata', + 'searchTool': 'Strumento di ricerca', }, blocks: { 'start': 'Inizio', @@ -430,6 +431,7 @@ const translation = { 'not empty': 'non è vuoto', 'null': 'è nullo', 'not null': 'non è nullo', + 'regex match': 'Corrispondenza regex', }, enterValue: 'Inserisci valore', addCondition: 'Aggiungi Condizione', diff --git a/web/i18n/ja-JP/app-api.ts b/web/i18n/ja-JP/app-api.ts index 63beaeb45c..721504f9f3 100644 --- a/web/i18n/ja-JP/app-api.ts +++ b/web/i18n/ja-JP/app-api.ts @@ -10,7 +10,7 @@ const translation = { pause: '一時停止', playing: '再生中', loading: '読み込み中', - merMaind: { + merMaid: { rerender: '再レンダリング', }, never: 'なし', diff --git a/web/i18n/ja-JP/app-debug.ts b/web/i18n/ja-JP/app-debug.ts index 6049be2406..e9ee765435 100644 --- a/web/i18n/ja-JP/app-debug.ts +++ b/web/i18n/ja-JP/app-debug.ts @@ -295,7 +295,7 @@ const translation = { historyNoBeEmpty: 'プロンプトには会話履歴を設定する必要があります', queryNoBeEmpty: 'プロンプトにクエリを設定する必要があります', }, - variableConig: { + variableConfig: { 'addModalTitle': '入力フィールドを追加', 'editModalTitle': '入力フィールドを編集', 'description': '{{varName}} の変数設定', diff --git a/web/i18n/ja-JP/app-overview.ts b/web/i18n/ja-JP/app-overview.ts index 1eb6fd1795..1fcd9d21c4 100644 --- a/web/i18n/ja-JP/app-overview.ts +++ b/web/i18n/ja-JP/app-overview.ts @@ -30,24 +30,26 @@ const translation = { overview: { title: '概要', appInfo: { - explanation: '使いやすいAI WebApp', + explanation: '使いやすいAI Webアプリ', accessibleAddress: '公開URL', preview: 'プレビュー', regenerate: '再生成', regenerateNotice: '公開URLを再生成しますか?', - preUseReminder: '続行する前にWebAppを有効にしてください。', + preUseReminder: '続行する前にWebアプリを有効にしてください。', settings: { entry: '設定', - title: 'WebApp設定', - webName: 'WebApp名', - webDesc: 'WebAppの説明', + title: 'Webアプリの設定', + webName: 'Webアプリの名前', + webDesc: 'Webアプリの説明', webDescTip: 'このテキストはクライアント側に表示され、アプリケーションの使用方法の基本的なガイダンスを提供します。', - webDescPlaceholder: 'WebAppの説明を入力してください', + webDescPlaceholder: 'Webアプリの説明を入力してください', language: '言語', workflow: { title: 'ワークフローステップ', show: '表示', hide: '非表示', + subTitle: 'ワークフローの詳細', + showDesc: 'Webアプリでワークフローの詳細を表示または非表示にする', }, chatColorTheme: 'チャットボットのカラーテーマ', chatColorThemeDesc: 'チャットボットのカラーテーマを設定します', @@ -64,6 +66,12 @@ const translation = { customDisclaimerPlaceholder: '免責事項を入力してください', customDisclaimerTip: 'アプリケーションの使用に関する免責事項を提供します。', }, + sso: { + title: 'WebアプリのSSO', + tooltip: '管理者に問い合わせて、WebアプリのSSOを有効にします', + label: 'SSO認証', + description: 'すべてのユーザーは、Webアプリを使用する前にSSOでログインする必要があります', + }, }, embedded: { entry: '埋め込み', @@ -83,8 +91,8 @@ const translation = { customize: { way: '方法', entry: 'カスタマイズ', - title: 'AI WebAppのカスタマイズ', - explanation: 'シナリオとスタイルのニーズに合わせてWeb Appのフロントエンドをカスタマイズできます。', + title: 'AI Webアプリのカスタマイズ', + explanation: 'シナリオとスタイルのニーズに合わせてWebアプリのフロントエンドをカスタマイズできます。', way1: { name: 'クライアントコードをフォークして修正し、Vercelにデプロイします(推奨)', step1: 'クライアントコードをフォークして修正します', @@ -119,7 +127,11 @@ const translation = { tokenPS: 'トークン/秒', totalMessages: { title: 'トータルメッセージ数', - explanation: '日次AIインタラクション数;工学的/デバッグ目的のプロンプトは除外されます。', + explanation: '日次AIインタラクション数。', + }, + totalConversations: { + title: '総会話数', + explanation: '日次AI会話数;プロンプトエンジニアリング/デバッグは除外。', }, activeUsers: { title: 'アクティブユーザー数', diff --git a/web/i18n/ja-JP/app.ts b/web/i18n/ja-JP/app.ts index 55f641f4c3..76c7d1c4f4 100644 --- a/web/i18n/ja-JP/app.ts +++ b/web/i18n/ja-JP/app.ts @@ -127,6 +127,12 @@ const translation = { removeConfirmTitle: '{{key}}の設定を削除しますか?', removeConfirmContent: '現在の設定は使用中です。これを削除すると、トレース機能が無効になります。', }, + view: '見る', + }, + answerIcon: { + title: 'Webアプリアイコンを使用して🤖を置き換える', + description: '共有アプリケーションの中で Webアプリアイコンを使用して🤖を置き換えるかどうか', + descriptionInExplore: 'ExploreでWebアプリアイコンを使用して🤖を置き換えるかどうか', }, } diff --git a/web/i18n/ja-JP/common.ts b/web/i18n/ja-JP/common.ts index fc61141bd3..e2517a619d 100644 --- a/web/i18n/ja-JP/common.ts +++ b/web/i18n/ja-JP/common.ts @@ -37,6 +37,7 @@ const translation = { params: 'パラメータ', duplicate: '重複', rename: '名前の変更', + audioSourceUnavailable: 'AudioSource が利用できません', }, errorMsg: { fieldRequired: '{{field}}は必要です', @@ -132,7 +133,8 @@ const translation = { workspace: 'ワークスペース', createWorkspace: 'ワークスペースを作成', helpCenter: 'ヘルプ', - roadmapAndFeedback: 'フィードバック', + communityFeedback: 'フィードバック', + roadmap: 'ロードマップ', community: 'コミュニティ', about: 'Difyについて', logout: 'ログアウト', @@ -198,7 +200,7 @@ const translation = { invitationSent: '招待が送信されました', invitationSentTip: '招待が送信され、彼らはDifyにサインインしてあなた様のチームデータにアクセスできます。', invitationLink: '招待リンク', - failedinvitationEmails: '以下のユーザーは正常に招待されませんでした', + failedInvitationEmails: '以下のユーザーは正常に招待されませんでした', ok: 'OK', removeFromTeam: 'チームから削除', removeFromTeamTip: 'チームへのアクセスが削除されます', @@ -206,7 +208,7 @@ const translation = { setMember: '通常のメンバーに設定', setBuilder: 'ビルダーに設定', setEditor: 'エディターに設定', - disinvite: '招待をキャンセル', + disInvite: '招待をキャンセル', deleteMember: 'メンバーを削除', you: '(あなた様)', }, diff --git a/web/i18n/ja-JP/dataset-creation.ts b/web/i18n/ja-JP/dataset-creation.ts index 448e208222..e6d204840a 100644 --- a/web/i18n/ja-JP/dataset-creation.ts +++ b/web/i18n/ja-JP/dataset-creation.ts @@ -50,7 +50,7 @@ const translation = { input: 'ナレッジ名', placeholder: '入力してください', nameNotEmpty: '名前は空にできません', - nameLengthInvaild: '名前は1〜40文字である必要があります', + nameLengthInvalid: '名前は1〜40文字である必要があります', cancelButton: 'キャンセル', confirmButton: '作成', failed: '作成に失敗しました', @@ -109,8 +109,8 @@ const translation = { QATitle: '質問と回答形式でセグメント化', QATip: 'このオプションを有効にすると、追加のトークンが消費されます', QALanguage: '使用言語', - emstimateCost: '見積もり', - emstimateSegment: '推定チャンク数', + estimateCost: '見積もり', + estimateSegment: '推定チャンク数', segmentCount: 'チャンク', calculating: '計算中...', fileSource: 'ドキュメントの前処理', @@ -135,8 +135,8 @@ const translation = { previewSwitchTipStart: '現在のチャンクプレビューはテキスト形式です。質問と回答形式のプレビューに切り替えると、', previewSwitchTipEnd: ' 追加のトークンが消費されます', characters: '文字', - indexSettedTip: 'インデックス方法を変更するには、', - retrivalSettedTip: 'インデックス方法を変更するには、', + indexSettingTip: 'インデックス方法を変更するには、', + retrievalSettingTip: '検索方法を変更するには、', datasetSettingLink: 'ナレッジ設定', }, stepThree: { diff --git a/web/i18n/ja-JP/dataset.ts b/web/i18n/ja-JP/dataset.ts index d2eaf05276..a765473b7e 100644 --- a/web/i18n/ja-JP/dataset.ts +++ b/web/i18n/ja-JP/dataset.ts @@ -37,7 +37,7 @@ const translation = { recommend: 'おすすめ', }, invertedIndex: { - title: '逆インデックス', + title: '転置インデックス', description: '効率的な検索に使用される構造です。各用語が含まれるドキュメントまたはWebページを指すように、用語ごとに整理されています。', }, change: '変更', @@ -53,6 +53,7 @@ const translation = { semantic_search: 'ベクトル検索', full_text_search: 'フルテキスト検索', hybrid_search: 'ハイブリッド検索', + invertedIndex: '逆さま', }, mixtureHighQualityAndEconomicTip: '高品質なナレッジベースと経済的なナレッジベースを混在させるには、Rerankモデルを構成する必要がある。', inconsistentEmbeddingModelTip: '選択されたナレッジベースが一貫性のない埋め込みモデルで構成されている場合、Rerankモデルの構成が必要です。', @@ -70,6 +71,7 @@ const translation = { nTo1RetrievalLegacy: '製品計画によると、N-to-1 Retrievalは9月に正式に廃止される予定です。それまでは通常通り使用できます。', nTo1RetrievalLegacyLink: '詳細を見る', nTo1RetrievalLegacyLinkText: ' N-to-1 retrievalは9月に正式に廃止されます。', + defaultRetrievalTip: 'デフォルトでは、マルチパス取得が使用されます。ナレッジは複数のナレッジ ベースから取得され、再ランク付けされます。', } export default translation diff --git a/web/i18n/ja-JP/login.ts b/web/i18n/ja-JP/login.ts index dd01e3b96a..72a26df3db 100644 --- a/web/i18n/ja-JP/login.ts +++ b/web/i18n/ja-JP/login.ts @@ -32,7 +32,7 @@ const translation = { pp: 'プライバシーポリシー', tosDesc: 'サインアップすることで、以下に同意するものとします', goToInit: 'アカウントを初期化していない場合は、初期化ページに移動してください', - donthave: 'お持ちでない場合', + dontHave: 'お持ちでない場合', invalidInvitationCode: '無効な招待コード', accountAlreadyInited: 'アカウントは既に初期化されています', forgotPassword: 'パスワードを忘れましたか?', diff --git a/web/i18n/ja-JP/share-app.ts b/web/i18n/ja-JP/share-app.ts index 503972dc48..6b7615c408 100644 --- a/web/i18n/ja-JP/share-app.ts +++ b/web/i18n/ja-JP/share-app.ts @@ -2,7 +2,7 @@ const translation = { common: { welcome: '', appUnavailable: 'アプリが利用できません', - appUnkonwError: 'アプリが利用できません', + appUnknownError: 'アプリが利用できません', }, chat: { newChat: '新しいチャット', @@ -10,7 +10,7 @@ const translation = { unpinnedTitle: 'チャット', newChatDefaultName: '新しい会話', resetChat: '会話をリセット', - powerBy: 'Powered by', + poweredBy: 'Powered by', prompt: 'プロンプト', privatePromptConfigTitle: '会話の設定', publicPromptConfigTitle: '初期プロンプト', diff --git a/web/i18n/ja-JP/workflow.ts b/web/i18n/ja-JP/workflow.ts index 8f506bcb46..d244e36bcd 100644 --- a/web/i18n/ja-JP/workflow.ts +++ b/web/i18n/ja-JP/workflow.ts @@ -36,7 +36,7 @@ const translation = { searchVar: '変数を検索', variableNamePlaceholder: '変数名', setVarValuePlaceholder: '変数を設定', - needConnecttip: 'このステップは何にも接続されていません', + needConnectTip: 'このステップは何にも接続されていません', maxTreeDepth: 'ブランチごとの最大制限は{{depth}}ノードです', needEndNode: '終了ブロックを追加する必要があります', needAnswerNode: '回答ブロックを追加する必要があります', @@ -412,10 +412,12 @@ const translation = { 'not empty': '空でない', 'null': 'null', 'not null': 'nullでない', + 'regex match': '正規表現マッチ', }, enterValue: '値を入力', addCondition: '条件を追加', conditionNotSetup: '条件が設定されていません', + selectVariable: '変数を選択...', }, variableAssigner: { title: '変数を代入する', diff --git a/web/i18n/ko-KR/app-api.ts b/web/i18n/ko-KR/app-api.ts index fc978cddf4..4708fac7dd 100644 --- a/web/i18n/ko-KR/app-api.ts +++ b/web/i18n/ko-KR/app-api.ts @@ -10,7 +10,7 @@ const translation = { pause: '일시 정지', playing: '실행 중', loading: '로드 중', - merMaind: { + merMaid: { rerender: '다시 렌더링', }, never: '없음', diff --git a/web/i18n/ko-KR/app-debug.ts b/web/i18n/ko-KR/app-debug.ts index 0a2488b64c..bafe0bf8d8 100644 --- a/web/i18n/ko-KR/app-debug.ts +++ b/web/i18n/ko-KR/app-debug.ts @@ -259,7 +259,7 @@ const translation = { historyNoBeEmpty: '프롬프트에 대화 기록을 설정해야 합니다', queryNoBeEmpty: '프롬프트에 쿼리를 설정해야 합니다', }, - variableConig: { + variableConfig: { 'addModalTitle': '입력 필드 추가', 'editModalTitle': '입력 필드 편집', 'description': '{{varName}} 변수 설정', diff --git a/web/i18n/ko-KR/app-overview.ts b/web/i18n/ko-KR/app-overview.ts index 47342984b3..b06e84587b 100644 --- a/web/i18n/ko-KR/app-overview.ts +++ b/web/i18n/ko-KR/app-overview.ts @@ -48,6 +48,8 @@ const translation = { title: '워크플로 단계', show: '표시', hide: '숨기기', + showDesc: 'WebApp에서 워크플로 세부 정보 표시 또는 숨기기', + subTitle: '워크플로우 세부 정보', }, chatColorTheme: '챗봇 색상 테마', chatColorThemeDesc: '챗봇의 색상 테마를 설정하세요', @@ -60,6 +62,15 @@ const translation = { privacyPolicy: '개인정보 처리방침', privacyPolicyPlaceholder: '개인정보 처리방침 링크를 입력하세요', privacyPolicyTip: '방문자가 애플리케이션이 수집하는 데이터를 이해하고, Dify의 개인정보 처리방침을 참조할 수 있도록 합니다.', + customDisclaimer: '사용자 지정 면책 조항', + customDisclaimerPlaceholder: '사용자 지정 면책 조항 텍스트를 입력합니다.', + customDisclaimerTip: '사용자 지정 고지 사항 텍스트는 클라이언트 쪽에 표시되어 응용 프로그램에 대한 추가 정보를 제공합니다', + }, + sso: { + label: 'SSO 인증', + title: '웹앱 SSO', + tooltip: '관리자에게 문의하여 WebApp SSO를 사용하도록 설정합니다.', + description: '모든 사용자는 WebApp을 사용하기 전에 SSO로 로그인해야 합니다.', }, }, embedded: { @@ -116,7 +127,11 @@ const translation = { tokenPS: '토큰/초', totalMessages: { title: '총 메시지 수', - explanation: '일일 AI 상호작용 수; 엔지니어링/디버깅 목적의 프롬프트는 제외됩니다.', + explanation: '일일 AI 상호작용 수.', + }, + totalConversations: { + title: '총 대화 수', + explanation: '일일 AI 대화 수; 프롬프트 엔지니어링/디버깅 제외.', }, activeUsers: { title: '활성 사용자 수', diff --git a/web/i18n/ko-KR/app.ts b/web/i18n/ko-KR/app.ts index a1fde30e4d..3f3abd3325 100644 --- a/web/i18n/ko-KR/app.ts +++ b/web/i18n/ko-KR/app.ts @@ -118,7 +118,17 @@ const translation = { removeConfirmTitle: '{{key}} 구성을 제거하시겠습니까?', removeConfirmContent: '현재 구성이 사용 중입니다. 제거하면 추적 기능이 꺼집니다.', }, + view: '보기', }, + answerIcon: { + description: 'WebApp 아이콘을 사용하여 공유 응용 프로그램에서 바꿀🤖지 여부', + title: 'WebApp 아이콘을 사용하여 🤖', + descriptionInExplore: 'Explore에서 WebApp 아이콘을 사용하여 바꿀🤖지 여부', + }, + importFromDSL: 'DSL에서 가져오기', + importFromDSLFile: 'DSL 파일에서', + importFromDSLUrl: 'URL에서', + importFromDSLUrlPlaceholder: '여기에 DSL 링크 붙여 넣기', } export default translation diff --git a/web/i18n/ko-KR/billing.ts b/web/i18n/ko-KR/billing.ts index ca6a361e06..94d557fd4b 100644 --- a/web/i18n/ko-KR/billing.ts +++ b/web/i18n/ko-KR/billing.ts @@ -58,6 +58,9 @@ const translation = { ragAPIRequest: 'RAG API 요청', agentMode: '에이전트 모드', workflow: '워크플로우', + llmLoadingBalancing: 'LLM 로드 밸런싱', + bulkUpload: '문서 대량 업로드', + llmLoadingBalancingTooltip: '모델에 여러 API 키를 추가하여 API 속도 제한을 효과적으로 우회할 수 있습니다.', }, comingSoon: '곧 출시 예정', member: '멤버', @@ -72,6 +75,8 @@ const translation = { }, ragAPIRequestTooltip: 'Dify의 지식베이스 처리 기능을 호출하는 API 호출 수를 나타냅니다.', receiptInfo: '팀 소유자 및 팀 관리자만 구독 및 청구 정보를 볼 수 있습니다', + annotationQuota: 'Annotation Quota(주석 할당량)', + documentsUploadQuota: '문서 업로드 할당량', }, plans: { sandbox: { diff --git a/web/i18n/ko-KR/common.ts b/web/i18n/ko-KR/common.ts index edd0295b89..8ef55da3f7 100644 --- a/web/i18n/ko-KR/common.ts +++ b/web/i18n/ko-KR/common.ts @@ -37,6 +37,7 @@ const translation = { params: '매개변수', duplicate: '중복', rename: '이름 바꾸기', + audioSourceUnavailable: '오디오 소스를 사용할 수 없습니다.', }, placeholder: { input: '입력해주세요', @@ -124,7 +125,8 @@ const translation = { workspace: '작업 공간', createWorkspace: '작업 공간 만들기', helpCenter: '도움말 센터', - roadmapAndFeedback: '로드맵 및 피드백', + communityFeedback: '로드맵 및 피드백', + roadmap: '로드맵', community: '커뮤니티', about: 'Dify 소개', logout: '로그아웃', @@ -186,16 +188,21 @@ const translation = { invitationSent: '초대가 전송되었습니다', invitationSentTip: '초대가 전송되었으며, 그들은 Dify에 로그인하여 당신의 팀 데이터에 액세스할 수 있습니다.', invitationLink: '초대 링크', - failedinvitationEmails: '다음 사용자들은 성공적으로 초대되지 않았습니다', + failedInvitationEmails: '다음 사용자들은 성공적으로 초대되지 않았습니다', ok: '확인', removeFromTeam: '팀에서 제거', removeFromTeamTip: '팀 액세스가 제거됩니다', setAdmin: '관리자 설정', setMember: '일반 멤버 설정', setEditor: '편집자 설정', - disinvite: '초대 취소', + disInvite: '초대 취소', deleteMember: '멤버 삭제', you: '(나)', + datasetOperator: '지식 관리자', + setBuilder: '빌더로 설정', + builder: '건설자', + builderTip: '자신의 앱을 구축 및 편집할 수 있습니다.', + datasetOperatorTip: '기술 자료만 관리할 수 있습니다.', }, integrations: { connected: '연결됨', @@ -342,6 +349,22 @@ const translation = { quotaTip: '남은 무료 토큰 사용 가능', loadPresets: '프리셋 로드', parameters: '매개변수', + apiKey: 'API 키', + defaultConfig: '기본 구성', + providerManaged: '제공자 관리', + loadBalancing: '부하 분산Load balancing', + addConfig: '구성 추가', + apiKeyStatusNormal: 'APIKey 상태는 정상입니다.', + configLoadBalancing: 'Config 로드 밸런싱', + editConfig: '구성 편집', + loadBalancingHeadline: '로드 밸런싱', + modelHasBeenDeprecated: '이 모델은 더 이상 사용되지 않습니다', + loadBalancingDescription: '여러 자격 증명 세트로 부담을 줄입니다.', + upgradeForLoadBalancing: '로드 밸런싱을 사용하도록 계획을 업그레이드합니다.', + apiKeyRateLimit: '속도 제한에 도달했으며, {{seconds}}s 후에 사용할 수 있습니다.', + loadBalancingInfo: '기본적으로 부하 분산은 라운드 로빈 전략을 사용합니다. 속도 제한이 트리거되면 1분의 휴지 기간이 적용됩니다.', + loadBalancingLeastKeyWarning: '로드 밸런싱을 사용하려면 최소 2개의 키를 사용하도록 설정해야 합니다.', + providerManagedDescription: '모델 공급자가 제공하는 단일 자격 증명 집합을 사용합니다.', }, dataSource: { add: '데이터 소스 추가하기', @@ -365,6 +388,15 @@ const translation = { preview: '미리보기', }, }, + website: { + inactive: '게으른', + title: '웹 사이트', + configuredCrawlers: '구성된 크롤러', + with: '와', + active: '활동적인', + description: '웹 크롤러를 사용하여 웹 사이트에서 콘텐츠를 가져옵니다.', + }, + configure: '구성', }, plugin: { serpapi: { @@ -533,6 +565,10 @@ const translation = { created: '태그가 성공적으로 생성되었습니다', failed: '태그 생성에 실패했습니다', }, + errorMsg: { + urlError: 'URL은 http:// 또는 https:// 로 시작해야 합니다.', + fieldRequired: '{{field}}는 필수입니다.', + }, } export default translation diff --git a/web/i18n/ko-KR/dataset-creation.ts b/web/i18n/ko-KR/dataset-creation.ts index 3039f69d6d..e8851acd2f 100644 --- a/web/i18n/ko-KR/dataset-creation.ts +++ b/web/i18n/ko-KR/dataset-creation.ts @@ -45,11 +45,35 @@ const translation = { input: '지식 이름', placeholder: '입력하세요', nameNotEmpty: '이름은 비워둘 수 없습니다', - nameLengthInvaild: '이름은 1~40자여야 합니다', + nameLengthInvalid: '이름은 1~40자여야 합니다', cancelButton: '취소', confirmButton: '생성', failed: '생성에 실패했습니다', }, + website: { + firecrawlDocLink: 'https://docs.dify.ai/guides/knowledge-base/sync-from-website', + limit: '한계', + options: '옵션', + firecrawlDoc: 'Firecrawl 문서', + selectAll: '모두 선택', + maxDepth: '최대 수심', + includeOnlyPaths: '경로만 포함', + excludePaths: '경로 제외', + preview: '미리 보기', + run: '달리다', + fireCrawlNotConfigured: 'Firecrawl이 구성되지 않았습니다.', + firecrawlTitle: 'Firecrawl로 🔥웹 콘텐츠 추출', + configure: '구성', + resetAll: '모두 재설정', + crawlSubPage: '하위 페이지 크롤링', + exceptionErrorTitle: 'Firecrawl 작업을 실행하는 동안 예외가 발생했습니다.', + scrapTimeInfo: '{{time}}s 내에 총 {{total}} 페이지를 스크랩했습니다.', + unknownError: '알 수 없는 오류', + totalPageScraped: '스크랩한 총 페이지 수:', + fireCrawlNotConfiguredDescription: 'API 키로 Firecrawl을 구성하여 사용합니다.', + extractOnlyMainContent: '기본 콘텐츠만 추출합니다(머리글, 탐색, 바닥글 등 없음).', + maxDepthTooltip: '입력한 URL을 기준으로 크롤링할 최대 수준입니다. 깊이 0은 입력 된 url의 페이지를 긁어 내고, 깊이 1은 url과 enteredURL + one / 이후의 모든 것을 긁어 모으는 식입니다.', + }, }, stepTwo: { segmentation: '청크 설정', @@ -80,8 +104,8 @@ const translation = { QATitle: '질문과 답변 형식으로 세그먼트화', QATip: '이 옵션을 활성화하면 추가 토큰이 소비됩니다', QALanguage: '사용 언어', - emstimateCost: '예상 비용', - emstimateSegment: '예상 청크 수', + estimateCost: '예상 비용', + estimateSegment: '예상 청크 수', segmentCount: '청크', calculating: '계산 중...', fileSource: '문서 전처리', @@ -104,9 +128,11 @@ const translation = { previewSwitchTipStart: '현재 청크 미리보기는 텍스트 형식입니다. 질문과 답변 형식 미리보기로 전환하면', previewSwitchTipEnd: ' 추가 토큰이 소비됩니다', characters: '문자', - indexSettedTip: '인덱스 방식을 변경하려면,', - retrivalSettedTip: '인덱스 방식을 변경하려면,', + indexSettingTip: '인덱스 방식을 변경하려면,', + retrievalSettingTip: '인덱스 방식을 변경하려면,', datasetSettingLink: '지식 설정', + webpageUnit: '페이지', + websiteSource: '웹 사이트 전처리', }, stepThree: { creationTitle: '🎉 지식이 생성되었습니다', @@ -126,6 +152,11 @@ const translation = { modelButtonConfirm: '확인', modelButtonCancel: '취소', }, + firecrawl: { + getApiKeyLinkText: 'firecrawl.dev 에서 API 키 가져오기', + apiKeyPlaceholder: 'firecrawl.dev 의 API 키', + configFirecrawl: 'Firecrawl 구성 🔥', + }, } export default translation diff --git a/web/i18n/ko-KR/dataset-documents.ts b/web/i18n/ko-KR/dataset-documents.ts index 8e7db58a6d..22c0330134 100644 --- a/web/i18n/ko-KR/dataset-documents.ts +++ b/web/i18n/ko-KR/dataset-documents.ts @@ -13,6 +13,8 @@ const translation = { status: '상태', action: '동작', }, + name: '이름', + rename: '이름 바꾸기', }, action: { uploadFile: '새 파일 업로드', @@ -74,6 +76,7 @@ const translation = { error: '가져오기 오류', ok: '확인', }, + addUrl: 'URL 추가', }, metadata: { title: '메타데이터', diff --git a/web/i18n/ko-KR/dataset-settings.ts b/web/i18n/ko-KR/dataset-settings.ts index 7dac64fce5..ef451ee866 100644 --- a/web/i18n/ko-KR/dataset-settings.ts +++ b/web/i18n/ko-KR/dataset-settings.ts @@ -27,6 +27,8 @@ const translation = { longDescription: ' 검색 방법에 대한 자세한 내용은 언제든지 지식 설정에서 변경할 수 있습니다.', }, save: '저장', + permissionsInvitedMembers: '부분 팀 구성원', + me: '(당신)', }, } diff --git a/web/i18n/ko-KR/dataset.ts b/web/i18n/ko-KR/dataset.ts index 907a1f21b6..9fd0dd16a7 100644 --- a/web/i18n/ko-KR/dataset.ts +++ b/web/i18n/ko-KR/dataset.ts @@ -70,6 +70,7 @@ const translation = { nTo1RetrievalLegacy: 'N-대-1 검색은 9월부터 공식적으로 더 이상 사용되지 않습니다. 더 나은 결과를 얻으려면 최신 다중 경로 검색을 사용하는 것이 좋습니다.', nTo1RetrievalLegacyLink: '자세히 알아보기', nTo1RetrievalLegacyLinkText: 'N-대-1 검색은 9월에 공식적으로 더 이상 사용되지 않습니다.', + defaultRetrievalTip: '다중 경로 검색이 기본적으로 사용됩니다. 지식은 여러 기술 자료에서 검색된 다음 순위가 다시 매겨집니다.', } export default translation diff --git a/web/i18n/ko-KR/login.ts b/web/i18n/ko-KR/login.ts index 01d1f538fe..ceddeb7b9b 100644 --- a/web/i18n/ko-KR/login.ts +++ b/web/i18n/ko-KR/login.ts @@ -31,7 +31,7 @@ const translation = { pp: '개인정보 처리 방침', tosDesc: '가입함으로써 다음 내용에 동의하게 됩니다.', goToInit: '계정이 초기화되지 않았다면 초기화 페이지로 이동하세요.', - donthave: '계정이 없으신가요?', + dontHave: '계정이 없으신가요?', invalidInvitationCode: '유효하지 않은 초대 코드입니다.', accountAlreadyInited: '계정은 이미 초기화되었습니다.', forgotPassword: '비밀번호를 잊으셨나요?', @@ -53,6 +53,7 @@ const translation = { nameEmpty: '사용자 이름을 입력하세요.', passwordEmpty: '비밀번호를 입력하세요.', passwordInvalid: '비밀번호는 문자와 숫자를 포함하고 8자 이상이어야 합니다.', + passwordLengthInValid: '비밀번호는 8자 이상이어야 합니다.', }, license: { tip: 'Dify Community Edition을 시작하기 전에 GitHub의', @@ -68,6 +69,7 @@ const translation = { activated: '지금 로그인하세요', adminInitPassword: '관리자 초기화 비밀번호', validate: '확인', + sso: 'SSO로 계속하기', } export default translation diff --git a/web/i18n/ko-KR/share-app.ts b/web/i18n/ko-KR/share-app.ts index 9c0738b3d7..be2e34a5fc 100644 --- a/web/i18n/ko-KR/share-app.ts +++ b/web/i18n/ko-KR/share-app.ts @@ -2,7 +2,7 @@ const translation = { common: { welcome: '', appUnavailable: '앱을 사용할 수 없습니다', - appUnkonwError: '앱을 사용할 수 없습니다', + appUnknownError: '앱을 사용할 수 없습니다', }, chat: { newChat: '새 채팅', @@ -10,7 +10,7 @@ const translation = { unpinnedTitle: '채팅', newChatDefaultName: '새 대화', resetChat: '대화 재설정', - powerBy: 'Powered by', + poweredBy: 'Powered by', prompt: '프롬프트', privatePromptConfigTitle: '채팅 설정', publicPromptConfigTitle: '초기 프롬프트', diff --git a/web/i18n/ko-KR/workflow.ts b/web/i18n/ko-KR/workflow.ts index d225d97141..7c85d02c3d 100644 --- a/web/i18n/ko-KR/workflow.ts +++ b/web/i18n/ko-KR/workflow.ts @@ -36,7 +36,7 @@ const translation = { searchVar: '변수 검색', variableNamePlaceholder: '변수 이름', setVarValuePlaceholder: '변수 값 설정', - needConnecttip: '이 단계는 아무것도 연결되어 있지 않습니다', + needConnectTip: '이 단계는 아무것도 연결되어 있지 않습니다', maxTreeDepth: '분기당 최대 {{depth}} 노드 제한', needEndNode: '종료 블록을 추가해야 합니다', needAnswerNode: '답변 블록을 추가해야 합니다', @@ -69,6 +69,14 @@ const translation = { manageInTools: '도구에서 관리', workflowAsToolTip: '워크플로우 업데이트 후 도구 재구성이 필요합니다.', viewDetailInTracingPanel: '세부 정보 보기', + importDSL: 'DSL 가져오기', + importFailure: '가져오기 실패', + chooseDSL: 'DSL(yml) 파일 선택', + backupCurrentDraft: '현재 초안 백업', + overwriteAndImport: '덮어쓰기 및 가져오기', + importSuccess: '가져오기 성공', + syncingData: '단 몇 초 만에 데이터를 동기화할 수 있습니다.', + importDSLTip: '현재 초안을 덮어씁니다. 가져오기 전에 워크플로를 백업으로 내보냅니다.', }, env: { envPanelTitle: '환경 변수', @@ -178,6 +186,7 @@ const translation = { 'transform': '변환', 'utilities': '유틸리티', 'noResult': '일치하는 결과 없음', + 'searchTool': '검색 도구', }, blocks: { 'start': '시작', @@ -403,10 +412,12 @@ const translation = { 'not empty': '비어 있지 않음', 'null': 'null임', 'not null': 'null이 아님', + 'regex match': '정규식 일치', }, enterValue: '값 입력', addCondition: '조건 추가', conditionNotSetup: '조건이 설정되지 않음', + selectVariable: '변수 선택...', }, variableAssigner: { title: '변수 할당', @@ -502,6 +513,25 @@ const translation = { iteration_other: '{{count}} 반복', currentIteration: '현재 반복', }, + note: { + editor: { + medium: '보통', + showAuthor: '작성자 표시', + link: '링크', + unlink: '해제', + small: '작다', + large: '큰', + placeholder: '메모 쓰기...', + bold: '대담한', + enterUrl: 'URL 입력...', + openLink: '열다', + italic: '이탤릭체', + invalidUrl: '잘못된 URL', + strikethrough: '취소선', + bulletList: '글머리 기호 목록', + }, + addNote: '메모 추가', + }, }, tracing: { stopBy: '{{user}}에 의해 중지됨', diff --git a/web/i18n/language.ts b/web/i18n/language.ts index e65d34d0ff..fde69328bd 100644 --- a/web/i18n/language.ts +++ b/web/i18n/language.ts @@ -49,6 +49,7 @@ export const NOTICE_I18N = { ko_KR: '중요 공지', pl_PL: 'Ważne ogłoszenie', uk_UA: 'Важливе повідомлення', + ru_RU: 'Важное Уведомление', vi_VN: 'Thông báo quan trọng', it_IT: 'Avviso Importante', fa_IR: 'هشدار مهم', @@ -74,6 +75,8 @@ export const NOTICE_I18N = { 'Nasz system będzie niedostępny od 19:00 do 24:00 UTC 28 sierpnia w celu aktualizacji. W przypadku pytań prosimy o kontakt z naszym zespołem wsparcia (support@dify.ai). Doceniamy Twoją cierpliwość.', uk_UA: 'Наша система буде недоступна з 19:00 до 24:00 UTC 28 серпня для оновлення. Якщо у вас виникнуть запитання, будь ласка, зв’яжіться з нашою службою підтримки (support@dify.ai). Дякуємо за терпіння.', + ru_RU: + 'Наша система будет недоступна с 19:00 до 24:00 UTC 28 августа для обновления. По вопросам, пожалуйста, обращайтесь в нашу службу поддержки (support@dify.ai). Спасибо за ваше терпение', vi_VN: 'Hệ thống của chúng tôi sẽ ngừng hoạt động từ 19:00 đến 24:00 UTC vào ngày 28 tháng 8 để nâng cấp. Nếu có thắc mắc, vui lòng liên hệ với nhóm hỗ trợ của chúng tôi (support@dify.ai). Chúng tôi đánh giá cao sự kiên nhẫn của bạn.', tr_TR: diff --git a/web/i18n/languages.json b/web/i18n/languages.json index d819e49089..a70963b067 100644 --- a/web/i18n/languages.json +++ b/web/i18n/languages.json @@ -68,7 +68,7 @@ "name": "Русский (Россия)", "prompt_name": "Russian", "example": " Привет, Dify!", - "supported": false + "supported": true }, { "value": "it-IT", diff --git a/web/i18n/pl-PL/app-api.ts b/web/i18n/pl-PL/app-api.ts index 46f9cbb454..05cad56fe2 100644 --- a/web/i18n/pl-PL/app-api.ts +++ b/web/i18n/pl-PL/app-api.ts @@ -10,7 +10,7 @@ const translation = { pause: 'Pauza', playing: 'Gra', loading: 'Ładowanie', - merMaind: { + merMaid: { rerender: 'Przerób Renderowanie', }, never: 'Nigdy', diff --git a/web/i18n/pl-PL/app-debug.ts b/web/i18n/pl-PL/app-debug.ts index afb412f264..7cf6c77cb4 100644 --- a/web/i18n/pl-PL/app-debug.ts +++ b/web/i18n/pl-PL/app-debug.ts @@ -289,7 +289,7 @@ const translation = { historyNoBeEmpty: 'Historia konwersacji musi być ustawiona w monicie', queryNoBeEmpty: 'Zapytanie musi być ustawione w monicie', }, - variableConig: { + variableConfig: { 'addModalTitle': 'Dodaj Pole Wejściowe', 'editModalTitle': 'Edytuj Pole Wejściowe', 'description': 'Ustawienia dla zmiennej {{varName}}', diff --git a/web/i18n/pl-PL/app-overview.ts b/web/i18n/pl-PL/app-overview.ts index 95e8aadb70..9f8bcd34dc 100644 --- a/web/i18n/pl-PL/app-overview.ts +++ b/web/i18n/pl-PL/app-overview.ts @@ -52,6 +52,8 @@ const translation = { title: 'Kroki przepływu pracy', show: 'Pokaż', hide: 'Ukryj', + subTitle: 'Szczegóły przepływu pracy', + showDesc: 'Pokazywanie lub ukrywanie szczegółów przepływu pracy w aplikacji internetowej', }, chatColorTheme: 'Motyw kolorystyczny czatu', chatColorThemeDesc: 'Ustaw motyw kolorystyczny czatu', @@ -69,6 +71,12 @@ const translation = { customDisclaimerPlaceholder: 'Wprowadź oświadczenie o ochronie danych', customDisclaimerTip: 'Niestandardowy tekst oświadczenia będzie wyświetlany po stronie klienta, dostarczając dodatkowych informacji o aplikacji.', }, + sso: { + tooltip: 'Skontaktuj się z administratorem, aby włączyć logowanie jednokrotne w aplikacji internetowej', + title: 'Logowanie jednokrotne w aplikacji internetowej', + label: 'Uwierzytelnianie logowania jednokrotnego', + description: 'Wszyscy użytkownicy muszą zalogować się za pomocą logowania jednokrotnego przed użyciem aplikacji internetowej', + }, }, embedded: { entry: 'Osadzone', @@ -130,8 +138,11 @@ const translation = { tokenPS: 'Tokeny/s', totalMessages: { title: 'Łączna liczba wiadomości', - explanation: - 'Dzienna liczba interakcji z AI; inżynieria i debugowanie monitów wykluczone.', + explanation: 'Liczba dziennych interakcji z AI.', + }, + totalConversations: { + title: 'Całkowita liczba rozmów', + explanation: 'Liczba dziennych rozmów z AI; inżynieria/debugowanie promptów wykluczone.', }, activeUsers: { title: 'Aktywni użytkownicy', diff --git a/web/i18n/pl-PL/app.ts b/web/i18n/pl-PL/app.ts index 6a47d43798..e672b7cd4f 100644 --- a/web/i18n/pl-PL/app.ts +++ b/web/i18n/pl-PL/app.ts @@ -129,7 +129,17 @@ const translation = { removeConfirmTitle: 'Usunąć konfigurację {{key}}?', removeConfirmContent: 'Obecna konfiguracja jest w użyciu, jej usunięcie wyłączy funkcję Śledzenia.', }, + view: 'Widok', }, + answerIcon: { + description: 'Czy w aplikacji udostępnionej ma być używana ikona aplikacji internetowej do zamiany 🤖.', + title: 'Użyj ikony WebApp, aby zastąpić 🤖', + descriptionInExplore: 'Czy używać ikony aplikacji internetowej do zastępowania 🤖 w Eksploruj', + }, + importFromDSL: 'Importowanie z DSL', + importFromDSLUrl: 'Z adresu URL', + importFromDSLFile: 'Z pliku DSL', + importFromDSLUrlPlaceholder: 'Wklej tutaj link DSL', } export default translation diff --git a/web/i18n/pl-PL/billing.ts b/web/i18n/pl-PL/billing.ts index 40ddc1f732..cff567e162 100644 --- a/web/i18n/pl-PL/billing.ts +++ b/web/i18n/pl-PL/billing.ts @@ -65,6 +65,8 @@ const translation = { bulkUpload: 'Masowe przesyłanie dokumentów', agentMode: 'Tryb agenta', workflow: 'Przepływ pracy', + llmLoadingBalancing: 'Równoważenie obciążenia LLM', + llmLoadingBalancingTooltip: 'Dodaj wiele kluczy API do modeli, skutecznie omijając limity szybkości interfejsu API.', }, comingSoon: 'Wkrótce dostępne', member: 'Członek', @@ -83,6 +85,7 @@ const translation = { 'Odnosi się do liczby wywołań API wykorzystujących tylko zdolności przetwarzania bazy wiedzy Dify.', receiptInfo: 'Tylko właściciel zespołu i administrator zespołu mogą subskrybować i przeglądać informacje o rozliczeniach', + annotationQuota: 'Przydział adnotacji', }, plans: { sandbox: { diff --git a/web/i18n/pl-PL/common.ts b/web/i18n/pl-PL/common.ts index 1f41abe154..91f5fb2899 100644 --- a/web/i18n/pl-PL/common.ts +++ b/web/i18n/pl-PL/common.ts @@ -37,6 +37,7 @@ const translation = { params: 'Parametry', duplicate: 'Duplikuj', rename: 'Zmień nazwę', + audioSourceUnavailable: 'AudioSource jest niedostępny', }, placeholder: { input: 'Proszę wprowadzić', @@ -133,7 +134,8 @@ const translation = { workspace: 'Przestrzeń robocza', createWorkspace: 'Utwórz przestrzeń roboczą', helpCenter: 'Pomoc', - roadmapAndFeedback: 'Opinie', + communityFeedback: 'Opinie', + roadmap: 'Plan działania', community: 'Społeczność', about: 'O', logout: 'Wyloguj się', @@ -198,16 +200,21 @@ const translation = { invitationSentTip: 'Zaproszenie zostało wysłane, a oni mogą zalogować się do Dify, aby uzyskać dostęp do danych Twojego zespołu.', invitationLink: 'Link zaproszenia', - failedinvitationEmails: 'Poniższe osoby nie zostały pomyślnie zaproszone', + failedInvitationEmails: 'Poniższe osoby nie zostały pomyślnie zaproszone', ok: 'OK', removeFromTeam: 'Usuń z zespołu', removeFromTeamTip: 'Usunie dostęp do zespołu', setAdmin: 'Ustaw jako administratora', setMember: 'Ustaw jako zwykłego członka', setEditor: 'Ustaw jako edytora', - disinvite: 'Anuluj zaproszenie', + disInvite: 'Anuluj zaproszenie', deleteMember: 'Usuń członka', you: '(Ty)', + datasetOperatorTip: 'Może zarządzać tylko bazą wiedzy', + setBuilder: 'Ustaw jako budowniczego', + builder: 'Budowniczy', + builderTip: 'Może tworzyć i edytować własne aplikacje', + datasetOperator: 'Wiedza Admin', }, integrations: { connected: 'Połączony', @@ -359,6 +366,22 @@ const translation = { quotaTip: 'Pozostałe dostępne darmowe tokeny', loadPresets: 'Załaduj ustawienia wstępne', parameters: 'PARAMETRY', + apiKey: 'KLUCZ-API', + loadBalancing: 'Równoważenie obciążenia', + defaultConfig: 'Domyślna konfiguracja', + providerManagedDescription: 'Użyj pojedynczego zestawu poświadczeń dostarczonych przez dostawcę modelu.', + loadBalancingHeadline: 'Równoważenie obciążenia', + modelHasBeenDeprecated: 'Ten model jest przestarzały', + loadBalancingDescription: 'Zmniejsz presję dzięki wielu zestawom poświadczeń.', + providerManaged: 'Zarządzany przez dostawcę', + upgradeForLoadBalancing: 'Uaktualnij swój plan, aby włączyć równoważenie obciążenia.', + apiKeyStatusNormal: 'Stan APIKey jest normalny', + loadBalancingLeastKeyWarning: 'Aby włączyć równoważenie obciążenia, muszą być włączone co najmniej 2 klucze.', + loadBalancingInfo: 'Domyślnie równoważenie obciążenia używa strategii działania okrężnego. Jeśli zostanie uruchomione ograniczenie szybkości, zostanie zastosowany 1-minutowy okres odnowienia.', + configLoadBalancing: 'Równoważenie obciążenia konfiguracji', + editConfig: 'Edytuj konfigurację', + addConfig: 'Dodaj konfigurację', + apiKeyRateLimit: 'Osiągnięto limit szybkości, dostępny po {{sekund}}s', }, dataSource: { add: 'Dodaj źródło danych', @@ -382,6 +405,15 @@ const translation = { preview: 'PODGLĄD', }, }, + website: { + active: 'Aktywny', + with: 'Z', + title: 'Strona internetowa', + description: 'Importuj zawartość ze stron internetowych za pomocą robota indeksującego.', + configuredCrawlers: 'Skonfigurowane roboty indeksujące', + inactive: 'Nieaktywny', + }, + configure: 'Konfigurować', }, plugin: { serpapi: { @@ -555,6 +587,10 @@ const translation = { created: 'Tag został pomyślnie utworzony', failed: 'Nie udało się utworzyć tagu', }, + errorMsg: { + fieldRequired: '{{field}} jest wymagane', + urlError: 'Adres URL powinien zaczynać się od http:// lub https://', + }, } export default translation diff --git a/web/i18n/pl-PL/dataset-creation.ts b/web/i18n/pl-PL/dataset-creation.ts index 1b12e51b05..64e50c6b33 100644 --- a/web/i18n/pl-PL/dataset-creation.ts +++ b/web/i18n/pl-PL/dataset-creation.ts @@ -46,11 +46,35 @@ const translation = { input: 'Nazwa Wiedzy', placeholder: 'Proszę wpisz', nameNotEmpty: 'Nazwa nie może być pusta', - nameLengthInvaild: 'Nazwa musi zawierać od 1 do 40 znaków', + nameLengthInvalid: 'Nazwa musi zawierać od 1 do 40 znaków', cancelButton: 'Anuluj', confirmButton: 'Utwórz', failed: 'Utworzenie nie powiodło się', }, + website: { + limit: 'Ograniczać', + firecrawlDocLink: 'https://docs.dify.ai/guides/knowledge-base/sync-from-website', + firecrawlDoc: 'Dokumentacja Firecrawl', + unknownError: 'Nieznany błąd', + fireCrawlNotConfiguredDescription: 'Skonfiguruj Firecrawl z kluczem API, aby z niego korzystać.', + run: 'Biegać', + configure: 'Konfigurować', + resetAll: 'Zresetuj wszystko', + preview: 'Prapremiera', + exceptionErrorTitle: 'Wystąpił wyjątek podczas uruchamiania zadania Firecrawl:', + maxDepth: 'Maksymalna głębokość', + crawlSubPage: 'Przeszukiwanie podstron', + options: 'Opcje', + scrapTimeInfo: 'Zeskrobano {{total}} stron w sumie w ciągu {{time}}s', + totalPageScraped: 'Łączna liczba zeskrobanych stron:', + extractOnlyMainContent: 'Wyodrębnij tylko główną zawartość (bez nagłówków, nawigacji, stopek itp.)', + excludePaths: 'Wykluczanie ścieżek', + includeOnlyPaths: 'Uwzględnij tylko ścieżki', + selectAll: 'Zaznacz wszystko', + firecrawlTitle: 'Wyodrębnij zawartość internetową za pomocą 🔥Firecrawl', + fireCrawlNotConfigured: 'Firecrawl nie jest skonfigurowany', + maxDepthTooltip: 'Maksymalna głębokość przeszukiwania względem wprowadzonego adresu URL. Głębokość 0 po prostu zeskrobuje stronę z wprowadzonego adresu URL, głębokość 1 zeskrobuje adres URL i wszystko po wprowadzeniuURL+ jeden / i tak dalej.', + }, }, stepTwo: { segmentation: 'Ustawienia bloków tekstu', @@ -88,8 +112,8 @@ const translation = { QATitle: 'Segmentacja w formacie pytania i odpowiedzi', QATip: 'Włączenie tej opcji spowoduje zużycie większej liczby tokenów', QALanguage: 'Segmentacja przy użyciu', - emstimateCost: 'Oszacowanie', - emstimateSegment: 'Oszacowane bloki', + estimateCost: 'Oszacowanie', + estimateSegment: 'Oszacowane bloki', segmentCount: 'bloki', calculating: 'Obliczanie...', fileSource: 'Przetwarzaj dokumenty', @@ -117,9 +141,11 @@ const translation = { 'Aktulany podgląd bloku jest w formacie tekstu, przełączenie na podgląd w formacie pytania i odpowiedzi spowoduje', previewSwitchTipEnd: ' dodatkowe zużycie tokenów', characters: 'znaki', - indexSettedTip: 'Aby zmienić metodę indeksowania, przejdź do ', - retrivalSettedTip: 'Aby zmienić metodę indeksowania, przejdź do ', + indexSettingTip: 'Aby zmienić metodę indeksowania, przejdź do ', + retrievalSettingTip: 'Aby zmienić metodę indeksowania, przejdź do ', datasetSettingLink: 'ustawień Wiedzy.', + webpageUnit: 'Stron', + websiteSource: 'Witryna internetowa przetwarzania wstępnego', }, stepThree: { creationTitle: '🎉 Utworzono Wiedzę', @@ -141,6 +167,11 @@ const translation = { modelButtonConfirm: 'Potwierdź', modelButtonCancel: 'Anuluj', }, + firecrawl: { + apiKeyPlaceholder: 'Klucz API od firecrawl.dev', + configFirecrawl: 'Konfiguracja 🔥Firecrawla', + getApiKeyLinkText: 'Pobierz klucz API z firecrawl.dev', + }, } export default translation diff --git a/web/i18n/pl-PL/dataset-documents.ts b/web/i18n/pl-PL/dataset-documents.ts index f8617a29cf..7152c3e9d6 100644 --- a/web/i18n/pl-PL/dataset-documents.ts +++ b/web/i18n/pl-PL/dataset-documents.ts @@ -13,6 +13,8 @@ const translation = { status: 'STATUS', action: 'AKCJA', }, + name: 'Nazwa', + rename: 'Przemianować', }, action: { uploadFile: 'Wgraj nowy plik', @@ -75,6 +77,7 @@ const translation = { error: 'Błąd importu', ok: 'OK', }, + addUrl: 'Dodaj adres URL', }, metadata: { title: 'Metadane', diff --git a/web/i18n/pl-PL/dataset-settings.ts b/web/i18n/pl-PL/dataset-settings.ts index b7d1738c54..3f069ab9b0 100644 --- a/web/i18n/pl-PL/dataset-settings.ts +++ b/web/i18n/pl-PL/dataset-settings.ts @@ -32,6 +32,8 @@ const translation = { ' dotyczące metody doboru, możesz to zmienić w dowolnym momencie w ustawieniach wiedzy.', }, save: 'Zapisz', + permissionsInvitedMembers: 'Częściowi członkowie zespołu', + me: '(Ty)', }, } diff --git a/web/i18n/pl-PL/dataset.ts b/web/i18n/pl-PL/dataset.ts index 14de4eaf40..efd8b75c95 100644 --- a/web/i18n/pl-PL/dataset.ts +++ b/web/i18n/pl-PL/dataset.ts @@ -77,6 +77,7 @@ const translation = { nTo1RetrievalLegacy: 'Wyszukiwanie N-do-1 zostanie oficjalnie wycofane od września. Zaleca się korzystanie z najnowszego wyszukiwania wielościeżkowego, aby uzyskać lepsze wyniki.', nTo1RetrievalLegacyLink: 'Dowiedz się więcej', nTo1RetrievalLegacyLinkText: 'Wyszukiwanie N-do-1 zostanie oficjalnie wycofane we wrześniu.', + defaultRetrievalTip: 'Pobieranie wielu ścieżek jest używane domyślnie. Wiedza jest pobierana z wielu baz wiedzy, a następnie ponownie klasyfikowana.', } export default translation diff --git a/web/i18n/pl-PL/login.ts b/web/i18n/pl-PL/login.ts index 075b79b913..be9e74f37d 100644 --- a/web/i18n/pl-PL/login.ts +++ b/web/i18n/pl-PL/login.ts @@ -36,7 +36,7 @@ const translation = { pp: 'Polityka prywatności', tosDesc: 'Założeniem konta zgadzasz się z naszymi', goToInit: 'Jeśli nie zainicjowałeś konta, przejdź do strony inicjalizacji', - donthave: 'Nie masz?', + dontHave: 'Nie masz?', invalidInvitationCode: 'Niewłaściwy kod zaproszenia', accountAlreadyInited: 'Konto już zainicjowane', forgotPassword: 'Zapomniałeś hasła?', @@ -59,6 +59,7 @@ const translation = { passwordEmpty: 'Hasło jest wymagane', passwordInvalid: 'Hasło musi zawierać litery i cyfry, a jego długość musi być większa niż 8', + passwordLengthInValid: 'Hasło musi składać się z co najmniej 8 znaków', }, license: { tip: 'Przed rozpoczęciem wersji społecznościowej Dify, przeczytaj GitHub', diff --git a/web/i18n/pl-PL/share-app.ts b/web/i18n/pl-PL/share-app.ts index eb5573c1a1..90b6ca1929 100644 --- a/web/i18n/pl-PL/share-app.ts +++ b/web/i18n/pl-PL/share-app.ts @@ -2,7 +2,7 @@ const translation = { common: { welcome: '', appUnavailable: 'Aplikacja jest niedostępna', - appUnkonwError: 'Aplikacja jest niedostępna', + appUnknownError: 'Aplikacja jest niedostępna', }, chat: { newChat: 'Nowy czat', @@ -10,7 +10,7 @@ const translation = { unpinnedTitle: 'Czaty', newChatDefaultName: 'Nowa rozmowa', resetChat: 'Resetuj rozmowę', - powerBy: 'Działany przez', + poweredBy: 'Działany przez', prompt: 'Podpowiedź', privatePromptConfigTitle: 'Ustawienia rozmowy', publicPromptConfigTitle: 'Początkowa podpowiedź', diff --git a/web/i18n/pl-PL/tools.ts b/web/i18n/pl-PL/tools.ts index f5d3226e8c..f34825b049 100644 --- a/web/i18n/pl-PL/tools.ts +++ b/web/i18n/pl-PL/tools.ts @@ -5,6 +5,7 @@ const translation = { all: 'Wszystkie', builtIn: 'Wbudowane', custom: 'Niestandardowe', + workflow: 'Przepływ pracy', }, contribute: { line1: 'Interesuje mnie ', @@ -77,6 +78,27 @@ const translation = { customDisclaimerPlaceholder: 'Proszę wprowadzić oświadczenie niestandardowe', deleteToolConfirmTitle: 'Skasuj ten przyrząd?', deleteToolConfirmContent: 'Usunięcie narzędzia jest nieodwracalne. Użytkownicy nie będą mieli już dostępu do Twojego narzędzia.', + toolInput: { + name: 'Nazwa', + required: 'Wymagane', + descriptionPlaceholder: 'Opis znaczenia parametru', + methodParameter: 'Parametr', + label: 'Tagi', + methodSetting: 'Ustawienie', + description: 'Opis', + method: 'Metoda', + methodParameterTip: 'LLM wypełnia się podczas wnioskowania', + labelPlaceholder: 'Wybierz tagi (opcjonalnie)', + methodSettingTip: 'Użytkownik wypełnia konfigurację narzędzia', + title: 'Wprowadzanie narzędzi', + }, + nameForToolCall: 'Nazwa wywołania narzędzia', + description: 'Opis', + descriptionPlaceholder: 'Krótki opis przeznaczenia narzędzia, np. zmierz temperaturę dla konkretnej lokalizacji.', + nameForToolCallTip: 'Obsługuje tylko cyfry, litery i podkreślenia.', + nameForToolCallPlaceHolder: 'Służy do rozpoznawania maszyn, takich jak getCurrentWeather, list_pets', + confirmTip: 'Będzie to miało wpływ na aplikacje korzystające z tego narzędzia', + confirmTitle: 'Potwierdź, aby zapisać ?', }, test: { title: 'Test', @@ -118,6 +140,18 @@ const translation = { toolRemoved: 'Narzędzie usunięte', notAuthorized: 'Narzędzie nieautoryzowane', howToGet: 'Jak uzyskać', + addToolModal: { + manageInTools: 'Zarządzanie w Narzędziach', + added: 'Dodane', + type: 'typ', + category: 'kategoria', + add: 'dodawać', + emptyTitle: 'Brak dostępnego narzędzia do przepływu pracy', + emptyTip: 'Przejdź do "Przepływ pracy -> Opublikuj jako narzędzie"', + }, + openInStudio: 'Otwieranie w Studio', + customToolTip: 'Dowiedz się więcej o niestandardowych narzędziach Dify', + toolNameUsageTip: 'Nazwa wywołania narzędzia do wnioskowania i podpowiadania agentowi', } export default translation diff --git a/web/i18n/pl-PL/workflow.ts b/web/i18n/pl-PL/workflow.ts index 62defed019..09b9cea1be 100644 --- a/web/i18n/pl-PL/workflow.ts +++ b/web/i18n/pl-PL/workflow.ts @@ -36,7 +36,7 @@ const translation = { searchVar: 'Szukaj zmiennej', variableNamePlaceholder: 'Nazwa zmiennej', setVarValuePlaceholder: 'Ustaw zmienną', - needConnecttip: 'Ten krok nie jest połączony z niczym', + needConnectTip: 'Ten krok nie jest połączony z niczym', maxTreeDepth: 'Maksymalny limit {{depth}} węzłów na gałąź', needEndNode: 'Należy dodać blok końcowy', needAnswerNode: 'Należy dodać blok odpowiedzi', @@ -69,6 +69,14 @@ const translation = { manageInTools: 'Zarządzaj w narzędziach', workflowAsToolTip: 'Wymagana rekonfiguracja narzędzia po aktualizacji przepływu pracy.', viewDetailInTracingPanel: 'Zobacz szczegóły', + importDSLTip: 'Bieżąca wersja robocza zostanie nadpisana. Eksportuj przepływ pracy jako kopię zapasową przed zaimportowaniem.', + syncingData: 'Synchronizacja danych w zaledwie kilka sekund.', + importSuccess: 'Import powodzenie', + importDSL: 'Importowanie DSL', + overwriteAndImport: 'Nadpisywanie i importowanie', + chooseDSL: 'Wybierz plik DSL(yml)', + backupCurrentDraft: 'Utwórz kopię zapasową bieżącej wersji roboczej', + importFailure: 'Niepowodzenie importu', }, env: { envPanelTitle: 'Zmienne Środowiskowe', @@ -178,6 +186,7 @@ const translation = { 'transform': 'Transformacja', 'utilities': 'Narzędzia pomocnicze', 'noResult': 'Nie znaleziono dopasowań', + 'searchTool': 'Wyszukiwarka', }, blocks: { 'start': 'Start', @@ -403,10 +412,12 @@ const translation = { 'not empty': 'nie jest pusty', 'null': 'jest null', 'not null': 'nie jest null', + 'regex match': 'Dopasowanie wyrażenia regularnego', }, enterValue: 'Wpisz wartość', addCondition: 'Dodaj warunek', conditionNotSetup: 'Warunek NIE został ustawiony', + selectVariable: 'Wybierz zmienną...', }, variableAssigner: { title: 'Przypisz zmienne', @@ -502,6 +513,25 @@ const translation = { iteration_other: '{{count}} Iteracje', currentIteration: 'Bieżąca iteracja', }, + note: { + editor: { + link: 'Łącze', + medium: 'Średni', + small: 'Mały', + italic: 'Kursywa', + enterUrl: 'Wpisz adres URL...', + showAuthor: 'Pokaż autora', + bold: 'Śmiały', + unlink: 'Odłączyć', + bulletList: 'Lista punktowana', + large: 'Duży', + openLink: 'Otwierać', + strikethrough: 'Przekreślenie', + invalidUrl: 'Nieprawidłowy adres URL', + placeholder: 'Napisz swoją notatkę...', + }, + addNote: 'Dodaj notatkę', + }, }, tracing: { stopBy: 'Zatrzymane przez {{user}}', diff --git a/web/i18n/pt-BR/app-api.ts b/web/i18n/pt-BR/app-api.ts index 95a9c84a3e..7bbd25695d 100644 --- a/web/i18n/pt-BR/app-api.ts +++ b/web/i18n/pt-BR/app-api.ts @@ -6,7 +6,7 @@ const translation = { ok: 'Em Serviço', copy: 'Copiar', copied: 'Copiado', - merMaind: { + merMaid: { rerender: 'Refazer Rerender', }, never: 'Nunca', @@ -74,6 +74,10 @@ const translation = { pathParams: 'Parâmetros de Caminho', query: 'Consulta', }, + play: 'Brincar', + loading: 'Carregamento', + pause: 'Pausa', + playing: 'Jogar', } export default translation diff --git a/web/i18n/pt-BR/app-debug.ts b/web/i18n/pt-BR/app-debug.ts index 9605bd5d95..df4312f887 100644 --- a/web/i18n/pt-BR/app-debug.ts +++ b/web/i18n/pt-BR/app-debug.ts @@ -265,7 +265,7 @@ const translation = { historyNoBeEmpty: 'O histórico da conversa deve ser definido na solicitação', queryNoBeEmpty: 'A consulta deve ser definida na solicitação', }, - variableConig: { + variableConfig: { 'addModalTitle': 'Adicionar Campo de Entrada', 'editModalTitle': 'Editar Campo de Entrada', 'description': 'Configuração para a variável {{varName}}', diff --git a/web/i18n/pt-BR/app-log.ts b/web/i18n/pt-BR/app-log.ts index a61d4204d4..96e604c49e 100644 --- a/web/i18n/pt-BR/app-log.ts +++ b/web/i18n/pt-BR/app-log.ts @@ -90,6 +90,13 @@ const translation = { iteração: 'Iteração', finalProcessing: 'Processamento Final', }, + agentLogDetail: { + iterations: 'Iterações', + agentMode: 'Modo Agente', + finalProcessing: 'Processamento final', + iteration: 'Iteração', + toolUsed: 'Ferramenta usada', + }, } export default translation diff --git a/web/i18n/pt-BR/app-overview.ts b/web/i18n/pt-BR/app-overview.ts index d288e331b3..a717ca259c 100644 --- a/web/i18n/pt-BR/app-overview.ts +++ b/web/i18n/pt-BR/app-overview.ts @@ -48,6 +48,8 @@ const translation = { title: 'Etapas do fluxo de trabalho', show: 'Mostrar', hide: 'Ocultar', + subTitle: 'Detalhes do fluxo de trabalho', + showDesc: 'Mostrar ou ocultar detalhes do fluxo de trabalho no WebApp', }, chatColorTheme: 'Tema de cor do chatbot', chatColorThemeDesc: 'Defina o tema de cor do chatbot', @@ -64,6 +66,12 @@ const translation = { customDisclaimerPlaceholder: 'Insira o texto do aviso legal', customDisclaimerTip: 'O texto do aviso legal personalizado será exibido no lado do cliente, fornecendo informações adicionais sobre o aplicativo', }, + sso: { + tooltip: 'Entre em contato com o administrador para habilitar o SSO do WebApp', + label: 'Autenticação SSO', + title: 'WebApp SSO', + description: 'Todos os usuários devem fazer login com SSO antes de usar o WebApp', + }, }, embedded: { entry: 'Embutido', @@ -119,7 +127,11 @@ const translation = { tokenPS: 'Token/s', totalMessages: { title: 'Total de Mensagens', - explanation: 'Contagem diária de interações AI; engenharia/de depuração excluída.', + explanation: 'Contagem diária de interações com IA.', + }, + totalConversations: { + title: 'Total de Conversas', + explanation: 'Contagem diária de conversas com IA; engenharia/depuração de prompts excluída.', }, activeUsers: { title: 'Usuários Ativos', diff --git a/web/i18n/pt-BR/app.ts b/web/i18n/pt-BR/app.ts index ef9122b86c..cf0c987eb2 100644 --- a/web/i18n/pt-BR/app.ts +++ b/web/i18n/pt-BR/app.ts @@ -122,7 +122,17 @@ const translation = { removeConfirmTitle: 'Remover configuração de {{key}}?', removeConfirmContent: 'A configuração atual está em uso, removê-la desligará o recurso de Rastreamento.', }, + view: 'Vista', }, + answerIcon: { + descriptionInExplore: 'Se o ícone do WebApp deve ser usado para substituir 🤖 no Explore', + description: 'Se o ícone WebApp deve ser usado para substituir 🤖 no aplicativo compartilhado', + title: 'Use o ícone do WebApp para substituir 🤖', + }, + importFromDSLUrlPlaceholder: 'Cole o link DSL aqui', + importFromDSLUrl: 'Do URL', + importFromDSLFile: 'Do arquivo DSL', + importFromDSL: 'Importar de DSL', } export default translation diff --git a/web/i18n/pt-BR/billing.ts b/web/i18n/pt-BR/billing.ts index 1ac082ec38..6eaeaa0fb2 100644 --- a/web/i18n/pt-BR/billing.ts +++ b/web/i18n/pt-BR/billing.ts @@ -1,108 +1,118 @@ const translation = { - currentPlan: 'Current Plan', + currentPlan: 'Plano Atual', upgradeBtn: { - plain: 'Upgrade Plan', - encourage: 'Upgrade Now', + plain: 'Fazer Upgrade do Plano', + encourage: 'Fazer Upgrade Agora', encourageShort: 'Upgrade', }, - viewBilling: 'View billing information', - buyPermissionDeniedTip: 'Please contact your enterprise administrator to subscribe', + viewBilling: 'Ver informações de cobrança', + buyPermissionDeniedTip: 'Por favor, entre em contato com o administrador da sua empresa para assinar', plansCommon: { - title: 'Choose a plan that’s right for you', - yearlyTip: 'Get 2 months for free by subscribing yearly!', - mostPopular: 'Most Popular', + title: 'Escolha o plano que melhor atende você', + yearlyTip: 'Receba 2 meses grátis assinando anualmente!', + mostPopular: 'Mais Popular', planRange: { - monthly: 'Monthly', - yearly: 'Yearly', + monthly: 'Mensalmente', + yearly: 'Anualmente', }, - month: 'month', - year: 'year', - save: 'Save ', - free: 'Free', - currentPlan: 'Current Plan', - contractOwner: 'Contact team manager', - startForFree: 'Start for free', - getStartedWith: 'Get started with ', - contactSales: 'Contact Sales', - talkToSales: 'Talk to Sales', - modelProviders: 'Model Providers', - teamMembers: 'Team Members', - buildApps: 'Build Apps', - vectorSpace: 'Vector Space', - vectorSpaceBillingTooltip: 'Each 1MB can store about 1.2million characters of vectorized data(estimated using OpenAI Embeddings, varies across models).', - vectorSpaceTooltip: 'Vector Space is the long-term memory system required for LLMs to comprehend your data.', - documentProcessingPriority: 'Document Processing Priority', - documentProcessingPriorityTip: 'For higher document processing priority, please upgrade your plan.', - documentProcessingPriorityUpgrade: 'Process more data with higher accuracy at faster speeds.', + month: 'mês', + year: 'ano', + save: 'Salvar', + free: 'Grátis', + currentPlan: 'Plano Atual', + contractOwner: 'Entre em contato com o gerente da equipe', + startForFree: 'Comece de graça', + getStartedWith: 'Comece com', + contactSales: 'Fale com a equipe de Vendas', + talkToSales: 'Fale com a equipe de Vendas', + modelProviders: 'Fornecedores de Modelos', + teamMembers: 'Membros da Equipe', + buildApps: 'Construir Aplicações', + vectorSpace: 'Espaço Vetorial', + vectorSpaceBillingTooltip: 'Cada 1MB pode armazenar cerca de 1,2 milhão de caracteres de dados vetorizados (estimado usando OpenAI Embeddings, varia entre os modelos).', + vectorSpaceTooltip: 'O Espaço Vetorial é o sistema de memória de longo prazo necessário para que LLMs compreendam seus dados.', + documentProcessingPriority: 'Prioridade no Processamento de Documentos', + documentProcessingPriorityTip: 'Para maior prioridade no processamento de documentos, faça o upgrade do seu plano.', + documentProcessingPriorityUpgrade: 'Processe mais dados com maior precisão e velocidade.', priority: { - 'standard': 'Standard', - 'priority': 'Priority', - 'top-priority': 'Top Priority', + 'standard': 'Padrão', + 'priority': 'Prioridade', + 'top-priority': 'Prioridade Máxima', }, - logsHistory: 'Logs history', - days: 'days', - unlimited: 'Unlimited', - support: 'Support', + logsHistory: 'Histórico de Logs', + days: 'dias', + unlimited: 'Ilimitado', + support: 'Suporte', supportItems: { - communityForums: 'Community forums', - emailSupport: 'Email support', - priorityEmail: 'Priority email & chat support', - logoChange: 'Logo change', - SSOAuthentication: 'SSO authentication', - personalizedSupport: 'Personalized support', - dedicatedAPISupport: 'Dedicated API support', - customIntegration: 'Custom integration and support', - ragAPIRequest: 'RAG API Requests', - agentModel: 'Agent Model', + communityForums: 'Fóruns da Comunidade', + emailSupport: 'Suporte por E-mail', + priorityEmail: 'Suporte prioritário por e-mail e chat', + logoChange: 'Mudança de logo', + SSOAuthentication: 'Autenticação SSO', + personalizedSupport: 'Suporte personalizado', + dedicatedAPISupport: 'Suporte dedicado à API', + customIntegration: 'Integração e suporte personalizados', + ragAPIRequest: 'Solicitações API RAG', + agentModel: 'Modelo de Agente', + workflow: 'Fluxo de trabalho', + llmLoadingBalancing: 'Balanceamento de carga LLM', + bulkUpload: 'Upload em massa de documentos', + llmLoadingBalancingTooltip: 'Adicione várias chaves de API aos modelos, efetivamente ignorando os limites de taxa da API.', + agentMode: 'Modo Agente', }, - comingSoon: 'Coming soon', - member: 'Member', - memberAfter: 'Member', + comingSoon: 'Em breve', + member: 'Membro', + memberAfter: 'Membro', messageRequest: { - title: 'Message Credits', - tooltip: 'Message invocation quotas for various plans using OpenAI models (except gpt4).Messages over the limit will use your OpenAI API Key.', + title: 'Créditos de Mensagem', + tooltip: 'Cotas de invocação de mensagens para vários planos usando modelos da OpenAI (exceto gpt4). Mensagens além do limite usarão sua Chave de API da OpenAI.', }, annotatedResponse: { - title: 'Annotation Quota Limits', - tooltip: 'Manual editing and annotation of responses provides customizable high-quality question-answering abilities for apps. (Applicable only in chat apps)', + title: 'Limites de Cota de Anotação', + tooltip: 'A edição manual e anotação de respostas oferece habilidades personalizadas de perguntas e respostas de alta qualidade para aplicativos. (Aplicável apenas em aplicativos de chat)', }, - ragAPIRequestTooltip: 'Refers to the number of API calls invoking only the knowledge base processing capabilities of Dify.', + ragAPIRequestTooltip: 'Refere-se ao número de chamadas de API que invocam apenas as capacidades de processamento da base de conhecimento do Dify.', receiptInfo: 'Somente proprietários e administradores de equipe podem se inscrever e visualizar informações de cobrança', + customTools: 'Ferramentas personalizadas', + documentsUploadQuota: 'Cota de upload de documentos', + annotationQuota: 'Cota de anotação', + contractSales: 'Entre em contato com a equipe de vendas', + unavailable: 'Indisponível', }, plans: { sandbox: { name: 'Sandbox', - description: '200 times GPT free trial', - includesTitle: 'Includes:', + description: '200 vezes GPT de teste gratuito', + includesTitle: 'Inclui:', }, professional: { - name: 'Professional', - description: 'For individuals and small teams to unlock more power affordably.', - includesTitle: 'Everything in free plan, plus:', + name: 'Profissional', + description: 'Para indivíduos e pequenas equipes desbloquearem mais poder de forma acessível.', + includesTitle: 'Tudo no plano gratuito, além de:', }, team: { - name: 'Team', - description: 'Collaborate without limits and enjoy top-tier performance.', - includesTitle: 'Everything in Professional plan, plus:', + name: 'Equipe', + description: 'Colabore sem limites e aproveite o desempenho de primeira linha.', + includesTitle: 'Tudo no plano Profissional, além de:', }, enterprise: { - name: 'Enterprise', - description: 'Get full capabilities and support for large-scale mission-critical systems.', - includesTitle: 'Everything in Team plan, plus:', + name: 'Empresa', + description: 'Obtenha capacidades completas e suporte para sistemas críticos em larga escala.', + includesTitle: 'Tudo no plano Equipe, além de:', }, }, vectorSpace: { - fullTip: 'Vector Space is full.', - fullSolution: 'Upgrade your plan to get more space.', + fullTip: 'O Espaço Vetorial está cheio.', + fullSolution: 'Faça o upgrade do seu plano para obter mais espaço.', }, apps: { - fullTipLine1: 'Upgrade your plan to', - fullTipLine2: 'build more apps.', + fullTipLine1: 'Faça o upgrade do seu plano para', + fullTipLine2: 'construir mais aplicativos.', }, annotatedResponse: { - fullTipLine1: 'Upgrade your plan to', - fullTipLine2: 'annotate more conversations.', - quotaTitle: 'Annotation Reply Quota', + fullTipLine1: 'Faça o upgrade do seu plano para', + fullTipLine2: 'anotar mais conversas.', + quotaTitle: 'Cota de Respostas Anotadas', }, } diff --git a/web/i18n/pt-BR/common.ts b/web/i18n/pt-BR/common.ts index f93979404b..f9e9eb7888 100644 --- a/web/i18n/pt-BR/common.ts +++ b/web/i18n/pt-BR/common.ts @@ -37,6 +37,7 @@ const translation = { params: 'Parâmetros', duplicate: 'Duplicada', rename: 'Renomear', + audioSourceUnavailable: 'AudioSource não está disponível', }, placeholder: { input: 'Por favor, insira', @@ -128,7 +129,8 @@ const translation = { workspace: 'Espaço de trabalho', createWorkspace: 'Criar Espaço de Trabalho', helpCenter: 'Ajuda', - roadmapAndFeedback: 'Feedback', + communityFeedback: 'Feedback', + roadmap: 'Roteiro', community: 'Comunidade', about: 'Sobre', logout: 'Sair', @@ -190,16 +192,21 @@ const translation = { invitationSent: 'Convite enviado', invitationSentTip: 'Convite enviado e eles podem fazer login no Dify para acessar os dados da sua equipe.', invitationLink: 'Link do Convite', - failedinvitationEmails: 'Os seguintes usuários não foram convidados com sucesso', + failedInvitationEmails: 'Os seguintes usuários não foram convidados com sucesso', ok: 'OK', removeFromTeam: 'Remover da equipe', removeFromTeamTip: 'Removerá o acesso da equipe', setAdmin: 'Definir como administrador', setMember: 'Definir como membro comum', setEditor: 'Definir como editor', - disinvite: 'Cancelar o convite', + disInvite: 'Cancelar o convite', deleteMember: 'Excluir Membro', you: '(Você)', + datasetOperatorTip: 'Só pode gerenciar a base de dados de conhecimento', + builder: 'Construtor', + setBuilder: 'Definir como construtor', + builderTip: 'Pode criar e editar seus próprios aplicativos', + datasetOperator: 'Administrador de conhecimento', }, integrations: { connected: 'Conectado', @@ -346,6 +353,22 @@ const translation = { quotaTip: 'Tokens gratuitos disponíveis restantes', loadPresets: 'Carregar Predefinições', parameters: 'PARÂMETROS', + loadBalancingDescription: 'Reduza a pressão com vários conjuntos de credenciais.', + configLoadBalancing: 'Balanceamento de carga de configuração', + upgradeForLoadBalancing: 'Atualize seu plano para habilitar o balanceamento de carga.', + providerManaged: 'Gerenciado pelo provedor', + apiKeyStatusNormal: 'O status do APIKey é normal', + loadBalancing: 'Balanceamento de carga', + addConfig: 'Adicionar configuração', + providerManagedDescription: 'Use o único conjunto de credenciais fornecido pelo provedor de modelo.', + apiKey: 'CHAVE DE API', + loadBalancingLeastKeyWarning: 'Para habilitar o balanceamento de carga, pelo menos 2 chaves devem estar habilitadas.', + editConfig: 'Editar configuração', + defaultConfig: 'Configuração padrão', + modelHasBeenDeprecated: 'Este modelo foi preterido', + loadBalancingInfo: 'Por padrão, o balanceamento de carga usa a estratégia Round-robin. Se a limitação de taxa for acionada, um período de espera de 1 minuto será aplicado.', + apiKeyRateLimit: 'O limite de taxa foi atingido, disponível após {{seconds}}s', + loadBalancingHeadline: 'Balanceamento de carga', }, dataSource: { add: 'Adicionar uma fonte de dados', @@ -369,6 +392,15 @@ const translation = { preview: 'PRÉ-VISUALIZAÇÃO', }, }, + website: { + inactive: 'Inativo', + active: 'Ativo', + title: 'Local na rede Internet', + with: 'Com', + configuredCrawlers: 'Rastreadores configurados', + description: 'Importe conteúdo de sites usando o rastreador da Web.', + }, + configure: 'Configurar', }, plugin: { serpapi: { @@ -537,6 +569,10 @@ const translation = { created: 'Tag criada com sucesso', failed: 'Falha na criação da tag', }, + errorMsg: { + fieldRequired: '{{field}} é obrigatório', + urlError: 'URL deve começar com http:// ou https://', + }, } export default translation diff --git a/web/i18n/pt-BR/dataset-creation.ts b/web/i18n/pt-BR/dataset-creation.ts index b721f2177b..4ab78a50c7 100644 --- a/web/i18n/pt-BR/dataset-creation.ts +++ b/web/i18n/pt-BR/dataset-creation.ts @@ -45,11 +45,35 @@ const translation = { input: 'Nome do Conhecimento', placeholder: 'Por favor, insira', nameNotEmpty: 'O nome não pode estar vazio', - nameLengthInvaild: 'O nome deve ter entre 1 e 40 caracteres', + nameLengthInvalid: 'O nome deve ter entre 1 e 40 caracteres', cancelButton: 'Cancelar', confirmButton: 'Criar', failed: 'Falha na criação', }, + website: { + fireCrawlNotConfiguredDescription: 'Configure o Firecrawl com a chave de API para usá-lo.', + run: 'Correr', + unknownError: 'Erro desconhecido', + crawlSubPage: 'Rastrear subpáginas', + selectAll: 'Selecionar tudo', + resetAll: 'Redefinir tudo', + firecrawlDocLink: 'https://docs.dify.ai/guides/knowledge-base/sync-from-website', + includeOnlyPaths: 'Incluir apenas caminhos', + configure: 'Configurar', + limit: 'Limite', + firecrawlDoc: 'Documentos do Firecrawl', + preview: 'Visualizar', + options: 'Opções', + scrapTimeInfo: 'Páginas {{total}} raspadas no total dentro de {{time}}s', + exceptionErrorTitle: 'Ocorreu uma exceção durante a execução do trabalho Firecrawl:', + fireCrawlNotConfigured: 'O Firecrawl não está configurado', + maxDepthTooltip: 'Profundidade máxima para rastrear em relação ao URL inserido. A profundidade 0 apenas raspa a página do url inserido, a profundidade 1 raspa o url e tudo depois de inseridoURL + um / e assim por diante.', + firecrawlTitle: 'Extraia conteúdo da web com 🔥Firecrawl', + maxDepth: 'Profundidade máxima', + totalPageScraped: 'Total de páginas raspadas:', + excludePaths: 'Excluir caminhos', + extractOnlyMainContent: 'Extraia apenas o conteúdo principal (sem cabeçalhos, navs, rodapés, etc.)', + }, }, stepTwo: { segmentation: 'Configurações de fragmentação', @@ -80,8 +104,8 @@ const translation = { QATitle: 'Fragmentação no formato de Perguntas e Respostas', QATip: 'Habilitar esta opção consumirá mais tokens', QALanguage: 'Fragmentar usando', - emstimateCost: 'Estimativa', - emstimateSegment: 'Fragmentos estimados', + estimateCost: 'Estimativa', + estimateSegment: 'Fragmentos estimados', segmentCount: 'fragmentos', calculating: 'Calculando...', fileSource: 'Pré-processar documentos', @@ -104,9 +128,11 @@ const translation = { previewSwitchTipStart: 'A visualização atual do fragmento está no formato de texto, alternar para uma visualização no formato de Perguntas e Respostas irá', previewSwitchTipEnd: ' consumir tokens adicionais', characters: 'caracteres', - indexSettedTip: 'Para alterar o método de índice, por favor vá para as ', - retrivalSettedTip: 'Para alterar o método de índice, por favor vá para as ', + indexSettingTip: 'Para alterar o método de índice, por favor vá para as ', + retrievalSettingTip: 'Para alterar o método de índice, por favor vá para as ', datasetSettingLink: 'configurações do Conhecimento.', + websiteSource: 'Site de pré-processamento', + webpageUnit: 'Páginas', }, stepThree: { creationTitle: '🎉 Conhecimento criado', @@ -125,6 +151,11 @@ const translation = { modelButtonConfirm: 'Confirmar', modelButtonCancel: 'Cancelar', }, + firecrawl: { + apiKeyPlaceholder: 'Chave de API do firecrawl.dev', + configFirecrawl: 'Configurar 🔥o Firecrawl', + getApiKeyLinkText: 'Obtenha sua chave de API do firecrawl.dev', + }, } export default translation diff --git a/web/i18n/pt-BR/dataset-documents.ts b/web/i18n/pt-BR/dataset-documents.ts index a7265a9cff..ded46c8a14 100644 --- a/web/i18n/pt-BR/dataset-documents.ts +++ b/web/i18n/pt-BR/dataset-documents.ts @@ -13,6 +13,8 @@ const translation = { status: 'STATUS', action: 'AÇÃO', }, + name: 'Nome', + rename: 'Renomear', }, action: { uploadFile: 'Enviar novo arquivo', @@ -74,6 +76,7 @@ const translation = { error: 'Erro na importação', ok: 'OK', }, + addUrl: 'Adicionar URL', }, metadata: { title: 'Metadados', diff --git a/web/i18n/pt-BR/dataset-settings.ts b/web/i18n/pt-BR/dataset-settings.ts index fff9d9c7d5..cfedbff337 100644 --- a/web/i18n/pt-BR/dataset-settings.ts +++ b/web/i18n/pt-BR/dataset-settings.ts @@ -27,6 +27,8 @@ const translation = { longDescription: ' sobre o método de recuperação, você pode alterar isso a qualquer momento nas configurações do conhecimento.', }, save: 'Salvar', + permissionsInvitedMembers: 'Membros parciais da equipe', + me: '(Você)', }, } diff --git a/web/i18n/pt-BR/dataset.ts b/web/i18n/pt-BR/dataset.ts index 8710879149..3feeb99a8b 100644 --- a/web/i18n/pt-BR/dataset.ts +++ b/web/i18n/pt-BR/dataset.ts @@ -70,6 +70,8 @@ const translation = { nTo1RetrievalLegacy: 'A recuperação N-para-1 será oficialmente descontinuada a partir de setembro. Recomenda-se usar a recuperação de múltiplos caminhos mais recente para obter melhores resultados.', nTo1RetrievalLegacyLink: 'Saiba mais', nTo1RetrievalLegacyLinkText: 'A recuperação N-para-1 será oficialmente descontinuada em setembro.', + intro6: 'como um plug-in de índice ChatGPT autônomo para publicar', + defaultRetrievalTip: 'A recuperação de vários caminhos é usada por padrão. O conhecimento é recuperado de várias bases de dados de conhecimento e, em seguida, reclassificado.', } export default translation diff --git a/web/i18n/pt-BR/login.ts b/web/i18n/pt-BR/login.ts index 88312778c3..a1f278dba8 100644 --- a/web/i18n/pt-BR/login.ts +++ b/web/i18n/pt-BR/login.ts @@ -31,7 +31,7 @@ const translation = { pp: 'Política de Privacidade', tosDesc: 'Ao se inscrever, você concorda com nossos', goToInit: 'Se você não inicializou a conta, vá para a página de inicialização', - donthave: 'Não tem?', + dontHave: 'Não tem?', invalidInvitationCode: 'Código de convite inválido', accountAlreadyInited: 'Conta já iniciada', forgotPassword: 'Esqueceu sua senha?', @@ -53,6 +53,7 @@ const translation = { nameEmpty: 'O nome é obrigatório', passwordEmpty: 'A senha é obrigatória', passwordInvalid: 'A senha deve conter letras e números e ter um comprimento maior que 8', + passwordLengthInValid: 'A senha deve ter pelo menos 8 caracteres', }, license: { tip: 'Antes de começar a usar a Edição Comunitária do Dify, leia a', @@ -66,6 +67,9 @@ const translation = { activatedTipStart: 'Você se juntou à equipe', activatedTipEnd: '', activated: 'Entrar agora', + adminInitPassword: 'Senha de inicialização do administrador', + validate: 'Validar', + sso: 'Continuar com SSO', } export default translation diff --git a/web/i18n/pt-BR/share-app.ts b/web/i18n/pt-BR/share-app.ts index 27baf35275..1e1861e01b 100644 --- a/web/i18n/pt-BR/share-app.ts +++ b/web/i18n/pt-BR/share-app.ts @@ -2,7 +2,7 @@ const translation = { common: { welcome: '', appUnavailable: 'O aplicativo não está disponível', - appUnkonwError: 'O aplicativo encontrou um erro desconhecido', + appUnknownError: 'O aplicativo encontrou um erro desconhecido', }, chat: { newChat: 'Nova conversa', @@ -10,7 +10,7 @@ const translation = { unpinnedTitle: 'Conversas', newChatDefaultName: 'Nova conversa', resetChat: 'Redefinir conversa', - powerBy: 'Desenvolvido por', + poweredBy: 'Desenvolvido por', prompt: 'Prompt', privatePromptConfigTitle: 'Configurações da conversa', publicPromptConfigTitle: 'Prompt inicial', diff --git a/web/i18n/pt-BR/tools.ts b/web/i18n/pt-BR/tools.ts index 28b6e82176..1b20715328 100644 --- a/web/i18n/pt-BR/tools.ts +++ b/web/i18n/pt-BR/tools.ts @@ -5,6 +5,7 @@ const translation = { all: 'Todas', builtIn: 'Integradas', custom: 'Personalizadas', + workflow: 'Fluxo de trabalho', }, contribute: { line1: 'Estou interessado em ', @@ -75,6 +76,27 @@ const translation = { customDisclaimerPlaceholder: 'Digite o aviso personalizado', deleteToolConfirmTitle: 'Excluir esta ferramenta?', deleteToolConfirmContent: 'Excluir a ferramenta é irreversível. Os usuários não poderão mais acessar sua ferramenta.', + toolInput: { + label: 'Tags', + methodSetting: 'Ambiente', + methodParameterTip: 'Preenchimentos de LLM durante a inferência', + methodSettingTip: 'O usuário preenche a configuração da ferramenta', + methodParameter: 'Parâmetro', + name: 'Nome', + description: 'Descrição', + method: 'Método', + required: 'Necessário', + title: 'Entrada de ferramenta', + labelPlaceholder: 'Escolha tags(opcional)', + descriptionPlaceholder: 'Descrição do significado do parâmetro', + }, + description: 'Descrição', + nameForToolCall: 'Nome da chamada da ferramenta', + confirmTip: 'Os aplicativos que usam essa ferramenta serão afetados', + confirmTitle: 'Confirme para salvar ?', + nameForToolCallTip: 'Suporta apenas números, letras e sublinhados.', + descriptionPlaceholder: 'Breve descrição da finalidade da ferramenta, por exemplo, obter a temperatura para um local específico.', + nameForToolCallPlaceHolder: 'Usado para reconhecimento de máquina, como getCurrentWeather, list_pets', }, test: { title: 'Testar', @@ -114,6 +136,18 @@ const translation = { toolRemoved: 'Ferramenta removida', notAuthorized: 'Ferramenta não autorizada', howToGet: 'Como obter', + addToolModal: { + category: 'categoria', + type: 'tipo', + emptyTip: 'Vá para "Fluxo de trabalho - > Publicar como ferramenta"', + add: 'adicionar', + emptyTitle: 'Nenhuma ferramenta de fluxo de trabalho disponível', + added: 'Adicionado', + manageInTools: 'Gerenciar em Ferramentas', + }, + openInStudio: 'Abrir no Studio', + customToolTip: 'Saiba mais sobre as ferramentas personalizadas da Dify', + toolNameUsageTip: 'Nome da chamada da ferramenta para raciocínio e solicitação do agente', } export default translation diff --git a/web/i18n/pt-BR/workflow.ts b/web/i18n/pt-BR/workflow.ts index 071f6e99f8..da41268302 100644 --- a/web/i18n/pt-BR/workflow.ts +++ b/web/i18n/pt-BR/workflow.ts @@ -36,7 +36,7 @@ const translation = { searchVar: 'Buscar variável', variableNamePlaceholder: 'Nome da variável', setVarValuePlaceholder: 'Definir valor da variável', - needConnecttip: 'Este passo não está conectado a nada', + needConnectTip: 'Este passo não está conectado a nada', maxTreeDepth: 'Limite máximo de {{depth}} nós por ramo', needEndNode: 'O bloco de fim deve ser adicionado', needAnswerNode: 'O bloco de resposta deve ser adicionado', @@ -69,6 +69,14 @@ const translation = { manageInTools: 'Gerenciar nas ferramentas', workflowAsToolTip: 'É necessária a reconfiguração da ferramenta após a atualização do fluxo de trabalho.', viewDetailInTracingPanel: 'Ver detalhes', + importSuccess: 'Sucesso da importação', + chooseDSL: 'Escolha o arquivo DSL(yml)', + importFailure: 'Falha na importação', + syncingData: 'Sincronizando dados, apenas alguns segundos.', + overwriteAndImport: 'Substituir e importar', + importDSLTip: 'O rascunho atual será substituído. Exporte o fluxo de trabalho como backup antes de importar.', + backupCurrentDraft: 'Fazer backup do rascunho atual', + importDSL: 'Importar DSL', }, env: { envPanelTitle: 'Variáveis de Ambiente', @@ -178,6 +186,7 @@ const translation = { 'transform': 'Transformar', 'utilities': 'Utilitários', 'noResult': 'Nenhum resultado encontrado', + 'searchTool': 'Ferramenta de pesquisa', }, blocks: { 'start': 'Iniciar', @@ -403,10 +412,12 @@ const translation = { 'not empty': 'não está vazio', 'null': 'é nulo', 'not null': 'não é nulo', + 'regex match': 'partida regex', }, enterValue: 'Digite o valor', addCondition: 'Adicionar condição', conditionNotSetup: 'Condição NÃO configurada', + selectVariable: 'Selecione a variável...', }, variableAssigner: { title: 'Atribuir variáveis', @@ -502,6 +513,25 @@ const translation = { iteration_other: '{{count}} Iterações', currentIteration: 'Iteração atual', }, + note: { + editor: { + small: 'Pequeno', + bold: 'Ousado', + openLink: 'Abrir', + strikethrough: 'Tachado', + italic: 'Itálico', + invalidUrl: 'URL inválido', + placeholder: 'Escreva sua nota...', + bulletList: 'Lista de marcadores', + link: 'Link', + enterUrl: 'Digite o URL...', + medium: 'Média', + large: 'Grande', + unlink: 'Desvincular', + showAuthor: 'Autor do programa', + }, + addNote: 'Adicionar nota', + }, }, tracing: { stopBy: 'Parado por {{user}}', diff --git a/web/i18n/ro-RO/app-api.ts b/web/i18n/ro-RO/app-api.ts index 0b86ec6976..e6a52ade42 100644 --- a/web/i18n/ro-RO/app-api.ts +++ b/web/i18n/ro-RO/app-api.ts @@ -10,7 +10,7 @@ const translation = { pause: 'Pauză', playing: 'În redare', loading: 'Se încarcă', - merMaind: { + merMaid: { rerender: 'Reprocesare', }, never: 'Niciodată', diff --git a/web/i18n/ro-RO/app-debug.ts b/web/i18n/ro-RO/app-debug.ts index 7363f2954f..bafeee8bb0 100644 --- a/web/i18n/ro-RO/app-debug.ts +++ b/web/i18n/ro-RO/app-debug.ts @@ -265,7 +265,7 @@ const translation = { historyNoBeEmpty: 'Istoricul conversației trebuie setat în prompt', queryNoBeEmpty: 'Interogația trebuie setată în prompt', }, - variableConig: { + variableConfig: { 'addModalTitle': 'Adăugați câmp de intrare', 'editModalTitle': 'Editați câmpul de intrare', 'description': 'Setare pentru variabila {{varName}}', diff --git a/web/i18n/ro-RO/app-overview.ts b/web/i18n/ro-RO/app-overview.ts index 007a76a10e..9a9c9be35b 100644 --- a/web/i18n/ro-RO/app-overview.ts +++ b/web/i18n/ro-RO/app-overview.ts @@ -48,6 +48,8 @@ const translation = { title: 'Pași flux de lucru', show: 'Afișați', hide: 'Ascundeți', + subTitle: 'Detalii despre fluxul de lucru', + showDesc: 'Afișarea sau ascunderea detaliilor fluxului de lucru în WebApp', }, chatColorTheme: 'Tema de culoare a chatului', chatColorThemeDesc: 'Setați tema de culoare a chatbotului', @@ -60,6 +62,15 @@ const translation = { privacyPolicy: 'Politica de confidențialitate', privacyPolicyPlaceholder: 'Introduceți link-ul politicii de confidențialitate', privacyPolicyTip: 'Ajută vizitatorii să înțeleagă datele pe care le colectează aplicația, consultați Politica de confidențialitate a Dify.', + customDisclaimerPlaceholder: 'Introduceți textul personalizat de declinare a responsabilității', + customDisclaimerTip: 'Textul personalizat de declinare a responsabilității va fi afișat pe partea clientului, oferind informații suplimentare despre aplicație', + customDisclaimer: 'Declinarea responsabilității personalizate', + }, + sso: { + label: 'Autentificare SSO', + title: 'WebApp SSO', + description: 'Toți utilizatorii trebuie să se conecteze cu SSO înainte de a utiliza WebApp', + tooltip: 'Contactați administratorul pentru a activa WebApp SSO', }, }, embedded: { @@ -116,7 +127,11 @@ const translation = { tokenPS: 'Token/s', totalMessages: { title: 'Mesaje totale', - explanation: 'Număr de interacțiuni AI zilnice; exclud proiectarea și depanarea promptelor.', + explanation: 'Numărul de interacțiuni zilnice cu IA.', + }, + totalConversations: { + title: 'Total Conversații', + explanation: 'Numărul de conversații zilnice cu IA; ingineria/depanarea prompturilor exclusă.', }, activeUsers: { title: 'Utilizatori activi', diff --git a/web/i18n/ro-RO/app.ts b/web/i18n/ro-RO/app.ts index 2d13dd4e66..9baaabdd07 100644 --- a/web/i18n/ro-RO/app.ts +++ b/web/i18n/ro-RO/app.ts @@ -122,7 +122,17 @@ const translation = { removeConfirmTitle: 'Eliminați configurația {{key}}?', removeConfirmContent: 'Configurația curentă este în uz, eliminarea acesteia va dezactiva funcția de Urmărire.', }, + view: 'Vedere', }, + answerIcon: { + descriptionInExplore: 'Dacă să utilizați pictograma WebApp pentru a înlocui 🤖 în Explore', + description: 'Dacă se utilizează pictograma WebApp pentru a înlocui 🤖 în aplicația partajată', + title: 'Utilizați pictograma WebApp pentru a înlocui 🤖', + }, + importFromDSL: 'Import din DSL', + importFromDSLUrl: 'De la URL', + importFromDSLUrlPlaceholder: 'Lipiți linkul DSL aici', + importFromDSLFile: 'Din fișierul DSL', } export default translation diff --git a/web/i18n/ro-RO/billing.ts b/web/i18n/ro-RO/billing.ts index 57b9986889..707d892047 100644 --- a/web/i18n/ro-RO/billing.ts +++ b/web/i18n/ro-RO/billing.ts @@ -60,6 +60,8 @@ const translation = { bulkUpload: 'Încărcare în bloc a documentelor', agentMode: 'Mod agent', workflow: 'Flux de lucru', + llmLoadingBalancing: 'Echilibrarea sarcinii LLM', + llmLoadingBalancingTooltip: 'Adăugați mai multe chei API la modele, ocolind efectiv limitele de rată API.', }, comingSoon: 'Vine în curând', member: 'Membru', @@ -74,6 +76,7 @@ const translation = { }, ragAPIRequestTooltip: 'Se referă la numărul de apeluri API care invocă doar capacitățile de procesare a bazei de cunoștințe a Dify.', receiptInfo: 'Doar proprietarul echipei și administratorul echipei pot să se aboneze și să vizualizeze informațiile de facturare', + annotationQuota: 'Cota de adnotare', }, plans: { sandbox: { diff --git a/web/i18n/ro-RO/common.ts b/web/i18n/ro-RO/common.ts index 34ca1c4671..1fd8778106 100644 --- a/web/i18n/ro-RO/common.ts +++ b/web/i18n/ro-RO/common.ts @@ -37,6 +37,7 @@ const translation = { params: 'Parametri', duplicate: 'Duplică', rename: 'Redenumește', + audioSourceUnavailable: 'Sursa audio nu este disponibilă', }, placeholder: { input: 'Vă rugăm să introduceți', @@ -63,6 +64,7 @@ const translation = { hiIN: 'Hindi', trTR: 'Turcă', faIR: 'Persană', + plPL: 'Poloneză', }, }, unit: { @@ -127,7 +129,8 @@ const translation = { workspace: 'Spațiu de lucru', createWorkspace: 'Creează Spațiu de lucru', helpCenter: 'Ajutor', - roadmapAndFeedback: 'Feedback', + communityFeedback: 'Feedback', + roadmap: 'Plan de acțiune', community: 'Comunitate', about: 'Despre', logout: 'Deconectare', @@ -189,16 +192,21 @@ const translation = { invitationSent: 'Invitație trimisă', invitationSentTip: 'Invitația a fost trimisă și pot să se autentifice în Dify pentru a accesa datele echipei dvs.', invitationLink: 'Link de invitație', - failedinvitationEmails: 'Următorii utilizatori nu au fost invitați cu succes', + failedInvitationEmails: 'Următorii utilizatori nu au fost invitați cu succes', ok: 'OK', removeFromTeam: 'Elimină din echipă', removeFromTeamTip: 'Va elimina accesul la echipă', setAdmin: 'Setează ca administrator', setMember: 'Setează ca membru obișnuit', setEditor: 'Setează ca editor', - disinvite: 'Anulează invitația', + disInvite: 'Anulează invitația', deleteMember: 'Șterge membru', you: '(Dvs.)', + datasetOperatorTip: 'Numai poate gestiona baza de cunoștințe', + builder: 'Constructor', + datasetOperator: 'Administrator de cunoștințe', + setBuilder: 'Setare ca constructor', + builderTip: 'Poate construi și edita propriile aplicații', }, integrations: { connected: 'Conectat', @@ -345,6 +353,22 @@ const translation = { quotaTip: 'Jetoane gratuite disponibile rămase', loadPresets: 'Încarcă presetări', parameters: 'PARAMETRI', + loadBalancingHeadline: 'Echilibrare', + loadBalancingInfo: 'În mod implicit, echilibrarea încărcării utilizează strategia Round-robin. Dacă se declanșează limitarea ratei, se va aplica o perioadă de reactivare de 1 minut.', + loadBalancing: 'Echilibrare', + apiKeyRateLimit: 'Limita de viteză a fost atinsă, disponibilă după {{secunde}}s', + providerManaged: 'Gestionat de furnizor', + providerManagedDescription: 'Utilizați setul unic de acreditări furnizat de furnizorul de modele.', + defaultConfig: 'Configurație implicită', + addConfig: 'Adăugați configurație', + apiKey: 'CHEIE API', + modelHasBeenDeprecated: 'Acest model a fost depreciat', + loadBalancingDescription: 'Reduceți presiunea cu mai multe seturi de acreditări.', + apiKeyStatusNormal: 'Starea APIKey este normală', + loadBalancingLeastKeyWarning: 'Pentru a activa echilibrarea încărcării trebuie activate cel puțin 2 chei.', + editConfig: 'Editați configurația', + configLoadBalancing: 'Echilibrarea încărcării de configurare', + upgradeForLoadBalancing: 'Actualizați-vă planul pentru a activa Load Balancing.', }, dataSource: { add: 'Adăugați o sursă de date', @@ -368,6 +392,15 @@ const translation = { preview: 'PREVIZUALIZARE', }, }, + website: { + inactive: 'Inactiv', + description: 'Importați conținut de pe site-uri web folosind crawlerul web.', + active: 'Activ', + with: 'Cu', + title: 'Site-ul web', + configuredCrawlers: 'Crawlere configurate', + }, + configure: 'Configura', }, plugin: { serpapi: { @@ -536,6 +569,10 @@ const translation = { created: 'Etichetă creată cu succes', failed: 'Crearea etichetei a eșuat', }, + errorMsg: { + fieldRequired: '{{câmp}} este obligatoriu', + urlError: 'URL-ul ar trebui să înceapă cu http:// sau https://', + }, } export default translation diff --git a/web/i18n/ro-RO/dataset-creation.ts b/web/i18n/ro-RO/dataset-creation.ts index 89e614e00c..efe3bb246c 100644 --- a/web/i18n/ro-RO/dataset-creation.ts +++ b/web/i18n/ro-RO/dataset-creation.ts @@ -45,11 +45,35 @@ const translation = { input: 'Numele Cunoștinței', placeholder: 'Vă rugăm să introduceți', nameNotEmpty: 'Numele nu poate fi gol', - nameLengthInvaild: 'Numele trebuie să fie între 1 și 40 de caractere', + nameLengthInvalid: 'Numele trebuie să fie între 1 și 40 de caractere', cancelButton: 'Anulează', confirmButton: 'Creează', failed: 'Crearea a eșuat', }, + website: { + crawlSubPage: 'Accesarea cu crawlere a subpaginilor', + limit: 'Limită', + selectAll: 'Selectează tot', + configure: 'Configura', + preview: 'Previzualizare', + run: 'Alerga', + maxDepth: 'Adâncime maximă', + firecrawlDoc: 'Documente Firecrawl', + options: 'Opțiuni', + exceptionErrorTitle: 'A apărut o excepție în timpul rulării lucrării Firecrawl:', + firecrawlTitle: 'Extrageți conținut web cu 🔥Firecrawl', + unknownError: 'Eroare necunoscută', + scrapTimeInfo: 'Pagini răzuite {{total}} în total în {{timp}}s', + firecrawlDocLink: 'https://docs.dify.ai/guides/knowledge-base/sync-from-website', + excludePaths: 'Excluderea căilor', + resetAll: 'Resetați toate', + extractOnlyMainContent: 'Extrageți doar conținutul principal (fără anteturi, navigări, subsoluri etc.)', + fireCrawlNotConfiguredDescription: 'Configurați Firecrawl cu cheia API pentru a-l utiliza.', + fireCrawlNotConfigured: 'Firecrawl nu este configurat', + includeOnlyPaths: 'Includeți numai căi', + totalPageScraped: 'Total pagini răzuite:', + maxDepthTooltip: 'Adâncimea maximă de accesat cu crawlere în raport cu adresa URL introdusă. Adâncimea 0 doar răzuiește pagina URL-ului introdus, adâncimea 1 răzuiește url-ul și tot ceea ce după ce a introdusURL + un / și așa mai departe.', + }, }, stepTwo: { segmentation: 'Setări de segmentare', @@ -80,8 +104,8 @@ const translation = { QATitle: 'Segmentarea în format Întrebare și Răspuns', QATip: 'Activarea acestei opțiuni va consuma mai multe jetoane', QALanguage: 'Segmentează folosind', - emstimateCost: 'Estimare', - emstimateSegment: 'Segmente estimate', + estimateCost: 'Estimare', + estimateSegment: 'Segmente estimate', segmentCount: 'segmente', calculating: 'Se calculează...', fileSource: 'Prelucrează documente', @@ -104,9 +128,11 @@ const translation = { previewSwitchTipStart: 'Previzualizarea curentă a segmentului este în format text, comutarea la o previzualizare în format întrebare și răspuns va', previewSwitchTipEnd: ' consuma jetoane suplimentare', characters: 'caractere', - indexSettedTip: 'Pentru a modifica metoda de indexare, vă rugăm să mergeți la ', - retrivalSettedTip: 'Pentru a modifica metoda de indexare, vă rugăm să mergeți la ', + indexSettingTip: 'Pentru a modifica metoda de indexare, vă rugăm să mergeți la ', + retrievalSettingTip: 'Pentru a modifica metoda de indexare, vă rugăm să mergeți la ', datasetSettingLink: 'setările Cunoștinței.', + webpageUnit: 'Pagini', + websiteSource: 'Site-ul web de preprocesare', }, stepThree: { creationTitle: '🎉 Cunoștință creată', @@ -125,6 +151,11 @@ const translation = { modelButtonConfirm: 'Confirmă', modelButtonCancel: 'Anulează', }, + firecrawl: { + configFirecrawl: 'Configurați 🔥Firecrawl', + getApiKeyLinkText: 'Obțineți cheia API de la firecrawl.dev', + apiKeyPlaceholder: 'Cheie API de la firecrawl.dev', + }, } export default translation diff --git a/web/i18n/ro-RO/dataset-documents.ts b/web/i18n/ro-RO/dataset-documents.ts index a7c0bf5d51..ed8720e35a 100644 --- a/web/i18n/ro-RO/dataset-documents.ts +++ b/web/i18n/ro-RO/dataset-documents.ts @@ -13,6 +13,8 @@ const translation = { status: 'STARE', action: 'ACȚIUNE', }, + name: 'Nume', + rename: 'Redenumire', }, action: { uploadFile: 'Încarcă un fișier nou', @@ -74,6 +76,7 @@ const translation = { error: 'Eroare la import', ok: 'OK', }, + addUrl: 'Adăugați adresa URL', }, metadata: { title: 'Metadate', diff --git a/web/i18n/ro-RO/dataset-settings.ts b/web/i18n/ro-RO/dataset-settings.ts index c0f9e76aeb..54780f9c16 100644 --- a/web/i18n/ro-RO/dataset-settings.ts +++ b/web/i18n/ro-RO/dataset-settings.ts @@ -27,6 +27,8 @@ const translation = { longDescription: ' despre metoda de recuperare, o puteți schimba în orice moment în setările cunoștințelor.', }, save: 'Salvare', + permissionsInvitedMembers: 'Membri parțiali ai echipei', + me: '(Tu)', }, } diff --git a/web/i18n/ro-RO/dataset.ts b/web/i18n/ro-RO/dataset.ts index 3e605baf92..baf54f68e6 100644 --- a/web/i18n/ro-RO/dataset.ts +++ b/web/i18n/ro-RO/dataset.ts @@ -71,6 +71,7 @@ const translation = { nTo1RetrievalLegacy: 'Recuperarea N-la-1 va fi oficial depreciată din septembrie. Se recomandă utilizarea celei mai recente recuperări cu căi multiple pentru a obține rezultate mai bune.', nTo1RetrievalLegacyLink: 'Află mai multe', nTo1RetrievalLegacyLinkText: 'Recuperarea N-la-1 va fi oficial depreciată în septembrie.', + defaultRetrievalTip: 'Recuperarea pe mai multe căi este utilizată în mod implicit. Cunoștințele sunt preluate din mai multe baze de cunoștințe și apoi reclasificate.', } export default translation diff --git a/web/i18n/ro-RO/login.ts b/web/i18n/ro-RO/login.ts index c8a0fad91c..6a8d899b33 100644 --- a/web/i18n/ro-RO/login.ts +++ b/web/i18n/ro-RO/login.ts @@ -32,7 +32,7 @@ const translation = { pp: 'Politica de confidențialitate', tosDesc: 'Prin înregistrarea, ești de acord cu', goToInit: 'Dacă nu ai inițializat încă contul, te rugăm să mergi la pagina de inițializare', - donthave: 'Nu ai?', + dontHave: 'Nu ai?', invalidInvitationCode: 'Cod de invitație invalid', accountAlreadyInited: 'Contul este deja inițializat', forgotPassword: 'Ați uitat parola?', @@ -54,6 +54,7 @@ const translation = { nameEmpty: 'Numele este obligatoriu', passwordEmpty: 'Parola este obligatorie', passwordInvalid: 'Parola trebuie să conțină litere și cifre, iar lungimea trebuie să fie mai mare de 8 caractere', + passwordLengthInValid: 'Parola trebuie să aibă cel puțin 8 caractere', }, license: { tip: 'Înainte de a începe Dify Community Edition, citește', diff --git a/web/i18n/ro-RO/share-app.ts b/web/i18n/ro-RO/share-app.ts index 06cf083a04..c9ec36ab03 100644 --- a/web/i18n/ro-RO/share-app.ts +++ b/web/i18n/ro-RO/share-app.ts @@ -2,7 +2,7 @@ const translation = { common: { welcome: '', appUnavailable: 'Aplicația nu este disponibilă', - appUnkonwError: 'Aplicația nu este disponibilă', + appUnknownError: 'Aplicația nu este disponibilă', }, chat: { newChat: 'Chat nou', @@ -10,7 +10,7 @@ const translation = { unpinnedTitle: 'Conversații', newChatDefaultName: 'Conversație nouă', resetChat: 'Resetează conversația', - powerBy: 'Furnizat de', + poweredBy: 'Furnizat de', prompt: 'Sugestie', privatePromptConfigTitle: 'Setări conversație', publicPromptConfigTitle: 'Sugestie inițială', diff --git a/web/i18n/ro-RO/tools.ts b/web/i18n/ro-RO/tools.ts index e878162426..165bdb26ed 100644 --- a/web/i18n/ro-RO/tools.ts +++ b/web/i18n/ro-RO/tools.ts @@ -5,6 +5,7 @@ const translation = { all: 'Toate', builtIn: 'Incorporat', custom: 'Personalizat', + workflow: 'Flux de lucru', }, contribute: { line1: 'Sunt interesat să ', @@ -73,6 +74,29 @@ const translation = { privacyPolicyPlaceholder: 'Vă rugăm să introduceți politica de confidențialitate', deleteToolConfirmTitle: 'Ștergeți această unealtă?', deleteToolConfirmContent: ' Ștergerea uneltă este irreversibilă. Utilizatorii nu vor mai putea accesa uneltă dvs.', + toolInput: { + methodParameter: 'Parametru', + description: 'Descriere', + methodSetting: 'Setare', + methodSettingTip: 'Utilizatorul completează configurația instrumentului', + methodParameterTip: 'Completări LLM în timpul inferenței', + name: 'Nume', + descriptionPlaceholder: 'Descrierea semnificației parametrului', + label: 'Tags', + required: 'Necesar', + method: 'Metodă', + title: 'Intrare instrument', + labelPlaceholder: 'Alegeți etichetele (opțional)', + }, + descriptionPlaceholder: 'Scurtă descriere a scopului instrumentului, de exemplu, obțineți temperatura pentru o anumită locație.', + nameForToolCall: 'Numele apelului instrumentului', + description: 'Descriere', + confirmTip: 'Aplicațiile care folosesc acest instrument vor fi afectate', + nameForToolCallPlaceHolder: 'Utilizat pentru recunoașterea mașinii, cum ar fi getCurrentWeather, list_pets', + customDisclaimer: 'Declinarea responsabilității personalizate', + confirmTitle: 'Confirmați pentru a salva?', + customDisclaimerPlaceholder: 'Vă rugăm să introduceți declinarea responsabilității personalizate', + nameForToolCallTip: 'Acceptă doar numere, litere și caractere de subliniere.', }, test: { title: 'Testează', @@ -112,6 +136,18 @@ const translation = { toolRemoved: 'Instrument eliminat', notAuthorized: 'Instrument neautorizat', howToGet: 'Cum să obții', + addToolModal: { + added: 'adăugat', + category: 'categorie', + manageInTools: 'Gestionați în Instrumente', + add: 'adăuga', + type: 'tip', + emptyTitle: 'Nu este disponibil niciun instrument de flux de lucru', + emptyTip: 'Accesați "Flux de lucru -> Publicați ca instrument"', + }, + openInStudio: 'Deschide în Studio', + customToolTip: 'Aflați mai multe despre instrumentele personalizate Dify', + toolNameUsageTip: 'Numele de apel al instrumentului pentru raționamentul și solicitarea agentului', } export default translation diff --git a/web/i18n/ro-RO/workflow.ts b/web/i18n/ro-RO/workflow.ts index 9cbd2c0d7e..f8177aeb06 100644 --- a/web/i18n/ro-RO/workflow.ts +++ b/web/i18n/ro-RO/workflow.ts @@ -36,7 +36,7 @@ const translation = { searchVar: 'Caută variabilă', variableNamePlaceholder: 'Nume variabilă', setVarValuePlaceholder: 'Setează valoarea variabilei', - needConnecttip: 'Acest pas nu este conectat la nimic', + needConnectTip: 'Acest pas nu este conectat la nimic', maxTreeDepth: 'Limită maximă de {{depth}} noduri pe ramură', needEndNode: 'Trebuie adăugat blocul de sfârșit', needAnswerNode: 'Trebuie adăugat blocul de răspuns', @@ -69,6 +69,14 @@ const translation = { manageInTools: 'Gestionează în instrumente', workflowAsToolTip: 'Reconfigurarea instrumentului este necesară după actualizarea fluxului de lucru.', viewDetailInTracingPanel: 'Vezi detalii', + overwriteAndImport: 'Suprascriere și import', + chooseDSL: 'Alegeți fișierul DSL(yml)', + syncingData: 'Sincronizarea datelor, doar câteva secunde.', + importDSL: 'Importați DSL', + importFailure: 'Eșecul importului', + importSuccess: 'Succesul importului', + backupCurrentDraft: 'Backup curent draft', + importDSLTip: 'Proiectul curent va fi suprascris. Exportați fluxul de lucru ca backup înainte de import.', }, env: { envPanelTitle: 'Variabile de Mediu', @@ -178,6 +186,7 @@ const translation = { 'transform': 'Transformare', 'utilities': 'Utilități', 'noResult': 'Niciun rezultat găsit', + 'searchTool': 'Instrument de căutare', }, blocks: { 'start': 'Începe', @@ -403,10 +412,12 @@ const translation = { 'not empty': 'nu este gol', 'null': 'este null', 'not null': 'nu este null', + 'regex match': 'potrivire regex', }, enterValue: 'Introduceți valoarea', addCondition: 'Adăugați condiție', conditionNotSetup: 'Condiția NU este setată', + selectVariable: 'Selectați variabila...', }, variableAssigner: { title: 'Atribuie variabile', @@ -502,6 +513,25 @@ const translation = { iteration_other: '{{count}} Iterații', currentIteration: 'Iterație curentă', }, + note: { + editor: { + small: 'Mic', + bold: 'Îndrăzneț', + unlink: 'Deconecta', + strikethrough: 'Tăiere', + invalidUrl: 'URL nevalidă', + medium: 'Medie', + openLink: 'Deschide', + large: 'Mare', + enterUrl: 'Introduceți adresa URL...', + italic: 'Cursiv', + placeholder: 'Scrie-ți notița...', + link: 'Legătură', + bulletList: 'Lista de marcatori', + showAuthor: 'Afișați autorul', + }, + addNote: 'Adăugați o notă', + }, }, tracing: { stopBy: 'Oprit de {{user}}', diff --git a/web/i18n/ru-RU/app-annotation.ts b/web/i18n/ru-RU/app-annotation.ts new file mode 100644 index 0000000000..18f2ae4a11 --- /dev/null +++ b/web/i18n/ru-RU/app-annotation.ts @@ -0,0 +1,87 @@ +const translation = { + title: 'Аннотации', + name: 'Ответить на аннотацию', + editBy: 'Ответ отредактирован {{author}}', + noData: { + title: 'Нет аннотаций', + description: 'Вы можете редактировать аннотации во время отладки приложения или импортировать их массово здесь для получения качественного ответа.', + }, + table: { + header: { + question: 'вопрос', + answer: 'ответ', + createdAt: 'создано', + hits: 'попаданий', + actions: 'действия', + addAnnotation: 'Добавить аннотацию', + bulkImport: 'Массовый импорт', + bulkExport: 'Массовый экспорт', + clearAll: 'Очистить все аннотации', + }, + }, + editModal: { + title: 'Редактировать ответ аннотации', + queryName: 'Запрос пользователя', + answerName: 'Storyteller Bot', + yourAnswer: 'Ваш ответ', + answerPlaceholder: 'Введите ваш ответ здесь', + yourQuery: 'Ваш запрос', + queryPlaceholder: 'Введите ваш запрос здесь', + removeThisCache: 'Удалить эту аннотацию', + createdAt: 'Создано', + }, + addModal: { + title: 'Добавить ответ аннотации', + queryName: 'Вопрос', + answerName: 'Ответ', + answerPlaceholder: 'Введите ответ здесь', + queryPlaceholder: 'Введите вопрос здесь', + createNext: 'Добавить еще один аннотированный ответ', + }, + batchModal: { + title: 'Массовый импорт', + csvUploadTitle: 'Перетащите сюда ваш CSV-файл или ', + browse: 'выберите файл', + tip: 'CSV-файл должен соответствовать следующей структуре:', + question: 'вопрос', + answer: 'ответ', + contentTitle: 'содержимое фрагмента', + content: 'содержимое', + template: 'Скачать шаблон здесь', + cancel: 'Отмена', + run: 'Запустить пакет', + runError: 'Ошибка запуска пакета', + processing: 'В процессе пакетной обработки', + completed: 'Импорт завершен', + error: 'Ошибка импорта', + ok: 'ОК', + }, + errorMessage: { + answerRequired: 'Ответ обязателен', + queryRequired: 'Вопрос обязателен', + }, + viewModal: { + annotatedResponse: 'Ответ аннотации', + hitHistory: 'История попаданий', + hit: 'Попадание', + hits: 'Попадания', + noHitHistory: 'Нет истории попаданий', + }, + hitHistoryTable: { + query: 'Запрос', + match: 'Совпадение', + response: 'Ответ', + source: 'Источник', + score: 'Оценка', + time: 'Время', + }, + initSetup: { + title: 'Начальная настройка ответа аннотации', + configTitle: 'Настройка ответа аннотации', + confirmBtn: 'Сохранить и включить', + configConfirmBtn: 'Сохранить', + }, + embeddingModelSwitchTip: 'Модель векторизации текста аннотаций, переключение между моделями будет осуществлено повторно, что приведет к дополнительным затратам.', +} + +export default translation diff --git a/web/i18n/ru-RU/app-api.ts b/web/i18n/ru-RU/app-api.ts new file mode 100644 index 0000000000..0c56d7a501 --- /dev/null +++ b/web/i18n/ru-RU/app-api.ts @@ -0,0 +1,83 @@ +const translation = { + apiServer: 'API Сервер', + apiKey: 'API Ключ', + status: 'Статус', + disabled: 'Отключено', + ok: 'В работе', + copy: 'Копировать', + copied: 'Скопировано', + play: 'Запустить', + pause: 'Приостановить', + playing: 'Запущено', + loading: 'Загрузка', + merMaid: { + rerender: 'Перезапустить рендеринг', + }, + never: 'Никогда', + apiKeyModal: { + apiSecretKey: 'Секретный ключ API', + apiSecretKeyTips: 'Чтобы предотвратить злоупотребление API, защитите свой API ключ. Избегайте использования его в виде plain-текста во фронтенд-коде. :)', + createNewSecretKey: 'Создать новый секретный ключ', + secretKey: 'Секретный ключ', + created: 'СОЗДАН', + lastUsed: 'ПОСЛЕДНЕЕ ИСПОЛЬЗОВАНИЕ', + generateTips: 'Храните этот ключ в безопасном и доступном месте.', + }, + actionMsg: { + deleteConfirmTitle: 'Удалить этот секретный ключ?', + deleteConfirmTips: 'Это действие необратимо.', + ok: 'ОК', + }, + completionMode: { + title: 'API приложения', + info: 'Для высококачественной генерации текста, такой как статьи, резюме и переводы, используйте API completion-messages с пользовательским вводом. Генерация текста основана на параметрах модели и шаблонах подсказок, установленных в Dify Prompt Engineering.', + createCompletionApi: 'Создать completion-message', + createCompletionApiTip: 'Создайте completion-message для поддержки режима вопросов и ответов.', + inputsTips: '(Необязательно) Укажите поля пользовательского ввода в виде пар ключ-значение, соответствующих переменным в Prompt Eng. Ключ - это имя переменной, Значение - это значение параметра. Если тип поля - Выбор, отправленное Значение должно быть одним из предустановленных вариантов.', + queryTips: 'Текстовое содержимое пользовательского ввода.', + blocking: 'Блокирующий тип, ожидает завершения выполнения и возвращает результаты. (Запросы могут быть прерваны, если процесс длительный)', + streaming: ' Ответ в рамках потока. Реализация потоковой передачи ответов на основе SSE (Server-Sent Events).', + messageFeedbackApi: 'Обратная связь по сообщению (лайк)', + messageFeedbackApiTip: 'Оцените полученные сообщения от имени конечных пользователей с помощью лайков или дизлайков. Эти данные видны на странице Журналы и аннотации и используются для будущей тонкой настройки модели.', + messageIDTip: 'Идентификатор сообщения', + ratingTip: 'лайк или дизлайк, null - отмена', + parametersApi: 'Получить информацию о параметрах приложения', + parametersApiTip: 'Получить настроенные входные параметры, включая имена переменных, имена полей, типы и значения по умолчанию. Обычно используется для отображения этих полей в форме или заполнения значений по умолчанию после загрузки клиента.', + }, + chatMode: { + title: 'API приложения чата', + info: 'Для универсальных диалоговых приложений, использующих формат вопросов и ответов, вызовите API chat-messages, чтобы начать диалог. Поддерживайте текущие разговоры, передавая возвращенный conversation_id. Параметры ответа и шаблоны зависят от настроек Dify Prompt Eng.', + createChatApi: 'Создать сообщение чата', + createChatApiTip: 'Создайте новое сообщение разговора или продолжите существующий диалог.', + inputsTips: '(Необязательно) Укажите поля пользовательского ввода в виде пар ключ-значение, соответствующих переменным в Prompt Eng. Ключ - это имя переменной, Значение - это значение параметра. Если тип поля - Выбор, отправленное Значение должно быть одним из предустановленных вариантов.', + queryTips: 'Содержимое пользовательского ввода/вопроса', + blocking: 'Блокирующий тип, ожидает завершения выполнения и возвращает результаты. (Запросы могут быть прерваны, если процесс длительный)', + streaming: 'потоковая передача возвращает. Реализация потоковой передачи возврата на основе SSE (Server-Sent Events).', + conversationIdTip: '(Необязательно) Идентификатор разговора: оставьте пустым для первого разговора; передайте conversation_id из контекста, чтобы продолжить диалог.', + messageFeedbackApi: 'Обратная связь конечного пользователя по сообщению, лайк', + messageFeedbackApiTip: 'Оцените полученные сообщения от имени конечных пользователей с помощью лайков или дизлайков. Эти данные видны на странице Журналы и аннотации и используются для будущей тонкой настройки модели.', + messageIDTip: 'Идентификатор сообщения', + ratingTip: 'лайк или дизлайк, null - отмена', + chatMsgHistoryApi: 'Получить историю сообщений чата', + chatMsgHistoryApiTip: 'Первая страница возвращает последние `limit` строк, которые находятся в обратном порядке.', + chatMsgHistoryConversationIdTip: 'Идентификатор разговора', + chatMsgHistoryFirstId: 'Идентификатор первой записи чата на текущей странице. По умолчанию - нет.', + chatMsgHistoryLimit: 'Сколько чатов возвращается за один запрос', + conversationsListApi: 'Получить список разговоров', + conversationsListApiTip: 'Получает список сеансов текущего пользователя. По умолчанию возвращаются последние 20 сеансов.', + conversationsListFirstIdTip: 'Идентификатор последней записи на текущей странице, по умолчанию - нет.', + conversationsListLimitTip: 'Сколько чатов возвращается за один запрос', + conversationRenamingApi: 'Переименование разговора', + conversationRenamingApiTip: 'Переименовать разговоры; имя отображается в многосессионных клиентских интерфейсах.', + conversationRenamingNameTip: 'Новое имя', + parametersApi: 'Получить информацию о параметрах приложения', + parametersApiTip: 'Получить настроенные входные параметры, включая имена переменных, имена полей, типы и значения по умолчанию. Обычно используется для отображения этих полей в форме или заполнения значений по умолчанию после загрузки клиента.', + }, + develop: { + requestBody: 'Тело запроса', + pathParams: 'Параметры пути', + query: 'Запрос', + }, +} + +export default translation diff --git a/web/i18n/ru-RU/app-debug.ts b/web/i18n/ru-RU/app-debug.ts new file mode 100644 index 0000000000..038165301e --- /dev/null +++ b/web/i18n/ru-RU/app-debug.ts @@ -0,0 +1,463 @@ +const translation = { + pageTitle: { + line1: 'PROMPT', + line2: 'Engineering', + }, + orchestrate: 'Оркестрация', + promptMode: { + simple: 'Переключиться в экспертный режим для редактирования всего ПРОМПТА', + advanced: 'Экспертный режим', + switchBack: 'Переключиться обратно', + advancedWarning: { + title: 'Вы переключились в экспертный режим, и после изменения ПРОМПТА вы НЕ СМОЖЕТЕ вернуться в базовый режим.', + description: 'В экспертном режиме вы можете редактировать весь ПРОМПТ.', + learnMore: 'Узнать больше', + ok: 'ОК', + }, + operation: { + addMessage: 'Добавить сообщение', + }, + contextMissing: 'Отсутствует компонент контекста, эффективность промпта может быть невысокой.', + }, + operation: { + applyConfig: 'Опубликовать', + resetConfig: 'Сбросить', + debugConfig: 'Отладка', + addFeature: 'Добавить функцию', + automatic: 'Сгенерировать', + stopResponding: 'Остановить ответ', + agree: 'лайк', + disagree: 'дизлайк', + cancelAgree: 'Отменить лайк', + cancelDisagree: 'Отменить дизлайк', + userAction: 'Пользователь ', + }, + notSetAPIKey: { + title: 'Ключ поставщика LLM не установлен', + trailFinished: 'Пробный период закончен', + description: 'Ключ поставщика LLM не установлен, его необходимо установить перед отладкой.', + settingBtn: 'Перейти к настройкам', + }, + trailUseGPT4Info: { + title: 'В настоящее время не поддерживается gpt-4', + description: 'Чтобы использовать gpt-4, пожалуйста, установите API ключ.', + }, + feature: { + groupChat: { + title: 'Улучшение чата', + description: 'Добавление настроек предварительного разговора для приложений может улучшить пользовательский опыт.', + }, + groupExperience: { + title: 'Улучшение опыта', + }, + conversationOpener: { + title: 'Начальное сообщение', + description: 'В чат-приложении первое предложение, которое ИИ активно говорит пользователю, обычно используется в качестве приветствия.', + }, + suggestedQuestionsAfterAnswer: { + title: 'Последующие вопросы', + description: 'Настройка предложения следующих вопросов может улучшить чат для пользователей.', + resDes: '3 предложения для следующего вопроса пользователя.', + tryToAsk: 'Попробуйте спросить', + }, + moreLikeThis: { + title: 'Больше похожего', + description: 'Сгенерируйте несколько текстов одновременно, а затем отредактируйте и продолжайте генерировать', + generateNumTip: 'Количество генерируемых каждый раз', + tip: 'Использование этой функции приведет к дополнительным расходам токенов', + }, + speechToText: { + title: 'Преобразование речи в текст', + description: 'После включения вы можете использовать голосовой ввод.', + resDes: 'Голосовой ввод включен', + }, + textToSpeech: { + title: 'Преобразование текста в речь', + description: 'После включения текст можно преобразовать в речь.', + resDes: 'Преобразование текста в аудио включено', + }, + citation: { + title: 'Цитаты и ссылки', + description: 'После включения отображается исходный документ и атрибутированная часть сгенерированного контента.', + resDes: 'Цитаты и ссылки включены', + }, + annotation: { + title: 'Ответ аннотации', + description: 'Вы можете вручную добавить высококачественный ответ в кэш для приоритетного сопоставления с похожими вопросами пользователей.', + resDes: 'Ответ аннотации включен', + scoreThreshold: { + title: 'Порог оценки', + description: 'Используется для установки порога сходства для ответа аннотации.', + easyMatch: 'Простое совпадение', + accurateMatch: 'Точное совпадение', + }, + matchVariable: { + title: 'Переменная соответствия', + choosePlaceholder: 'Выберите переменную соответствия', + }, + cacheManagement: 'Аннотации', + cached: 'Аннотировано', + remove: 'Удалить', + removeConfirm: 'Удалить эту аннотацию?', + add: 'Добавить аннотацию', + edit: 'Редактировать аннотацию', + }, + dataSet: { + title: 'Контекст', + noData: 'Вы можете импортировать знания в качестве контекста', + words: 'Слова', + textBlocks: 'Текстовые блоки', + selectTitle: 'Выберите справочные знания', + selected: 'Знания выбраны', + noDataSet: 'Знания не найдены', + toCreate: 'Перейти к созданию', + notSupportSelectMulti: 'В настоящее время поддерживаются только одни знания', + queryVariable: { + title: 'Переменная запроса', + tip: 'Эта переменная будет использоваться в качестве входных данных запроса для поиска контекста, получая информацию о контексте, связанную с вводом этой переменной.', + choosePlaceholder: 'Выберите переменную запроса', + noVar: 'Нет переменных', + noVarTip: 'пожалуйста, создайте переменную в разделе Переменные', + unableToQueryDataSet: 'Невозможно запросить знания', + unableToQueryDataSetTip: 'Не удалось успешно запросить знания, пожалуйста, выберите переменную запроса контекста в разделе контекста.', + ok: 'ОК', + contextVarNotEmpty: 'переменная запроса контекста не может быть пустой', + deleteContextVarTitle: 'Удалить переменную "{{varName}}"?', + deleteContextVarTip: 'Эта переменная была установлена в качестве переменной запроса контекста, и ее удаление повлияет на нормальное использование знаний. Если вам все еще нужно удалить ее, пожалуйста, выберите ее заново в разделе контекста.', + }, + }, + tools: { + title: 'Инструменты', + tips: 'Инструменты предоставляют стандартный метод вызова API, принимая пользовательский ввод или переменные в качестве параметров запроса для запроса внешних данных в качестве контекста.', + toolsInUse: '{{count}} инструментов используется', + modal: { + title: 'Инструмент', + toolType: { + title: 'Тип инструмента', + placeholder: 'Пожалуйста, выберите тип инструмента', + }, + name: { + title: 'Имя', + placeholder: 'Пожалуйста, введите имя', + }, + variableName: { + title: 'Имя переменной', + placeholder: 'Пожалуйста, введите имя переменной', + }, + }, + }, + conversationHistory: { + title: 'История разговоров', + description: 'Установить префиксы имен для ролей разговора', + tip: 'История разговоров не включена, пожалуйста, добавьте в промпт выше.', + learnMore: 'Узнать больше', + editModal: { + title: 'Редактировать имена ролей разговора', + userPrefix: 'Префикс пользователя', + assistantPrefix: 'Префикс помощника', + }, + }, + toolbox: { + title: 'НАБОР ИНСТРУМЕНТОВ', + }, + moderation: { + title: 'Модерация контента', + description: 'Обеспечьте безопасность выходных данных модели, используя API модерации или поддерживая список чувствительных слов.', + allEnabled: 'ВХОДНОЙ/ВЫХОДНОЙ контент включен', + inputEnabled: 'ВХОДНОЙ контент включен', + outputEnabled: 'ВЫХОДНОЙ контент включен', + modal: { + title: 'Настройки модерации контента', + provider: { + title: 'Поставщик', + openai: 'Модерация OpenAI', + openaiTip: { + prefix: 'Для модерации OpenAI требуется ключ API OpenAI, настроенный в ', + suffix: '.', + }, + keywords: 'Ключевые слова', + }, + keywords: { + tip: 'По одному на строку, разделенные разрывами строк. До 100 символов на строку.', + placeholder: 'По одному на строку, разделенные разрывами строк', + line: 'Строка', + }, + content: { + input: 'Модерировать ВХОДНОЙ контент', + output: 'Модерировать ВЫХОДНОЙ контент', + preset: 'Предустановленные ответы', + placeholder: 'Здесь содержимое предустановленных ответов', + condition: 'Модерация ВХОДНОГО и ВЫХОДНОГО контента включена хотя бы одна', + fromApi: 'Предустановленные ответы возвращаются API', + errorMessage: 'Предустановленные ответы не могут быть пустыми', + supportMarkdown: 'Markdown поддерживается', + }, + openaiNotConfig: { + before: 'Для модерации OpenAI требуется ключ API OpenAI, настроенный в', + after: '', + }, + }, + }, + }, + generate: { + title: 'Генератор промпта', + description: 'Генератор промпта использует настроенную модель для оптимизации промпта для повышения качества и улучшения структуры. Пожалуйста, напишите четкие и подробные инструкции.', + tryIt: 'Попробуйте', + instruction: 'Инструкции', + instructionPlaceHolder: 'Напишите четкие и конкретные инструкции.', + generate: 'Сгенерировать', + resTitle: 'Сгенерированный промпт', + noDataLine1: 'Опишите свой случай использования слева,', + noDataLine2: 'предварительный просмотр оркестрации будет показан здесь.', + apply: 'Применить', + loading: 'Оркестрация приложения для вас...', + overwriteTitle: 'Перезаписать существующую конфигурацию?', + overwriteMessage: 'Применение этого промпта перезапишет существующую конфигурацию.', + template: { + pythonDebugger: { + name: 'Отладчик Python', + instruction: 'Бот, который может генерировать и отлаживать ваш код на основе ваших инструкций', + }, + translation: { + name: 'Переводчик', + instruction: 'Переводчик, который может переводить на несколько языков', + }, + professionalAnalyst: { + name: 'Профессиональный аналитик', + instruction: 'Извлекайте информацию, выявляйте риски и извлекайте ключевую информацию из длинных отчетов в одну записку', + }, + excelFormulaExpert: { + name: 'Эксперт по формулам Excel', + instruction: 'Чат-бот, который может помочь начинающим пользователям понять, использовать и создавать формулы Excel на основе инструкций пользователя', + }, + travelPlanning: { + name: 'Планировщик путешествий', + instruction: 'Помощник по планированию путешествий - это интеллектуальный инструмент, разработанный, чтобы помочь пользователям без труда планировать свои поездки', + }, + SQLSorcerer: { + name: 'SQL-ассистент', + instruction: 'Преобразуйте повседневный язык в SQL-запросы', + }, + GitGud: { + name: 'Git gud', + instruction: 'Генерируйте соответствующие команды Git на основе описанных пользователем действий по управлению версиями', + }, + meetingTakeaways: { + name: 'Итоги совещания', + instruction: 'Извлекайте из совещаний краткие резюме, включая темы обсуждения, ключевые выводы и элементы действий', + }, + writingsPolisher: { + name: 'Редактор', + instruction: 'Используйте LLM, чтобы улучшить свои письменные работы', + }, + }, + }, + resetConfig: { + title: 'Подтвердить сброс?', + message: + 'Сброс отменяет изменения, восстанавливая последнюю опубликованную конфигурацию.', + }, + errorMessage: { + nameOfKeyRequired: 'имя ключа: {{key}} обязательно', + valueOfVarRequired: 'значение {{key}} не может быть пустым', + queryRequired: 'Требуется текст запроса.', + waitForResponse: + 'Пожалуйста, дождитесь завершения ответа на предыдущее сообщение.', + waitForBatchResponse: + 'Пожалуйста, дождитесь завершения ответа на пакетное задание.', + notSelectModel: 'Пожалуйста, выберите модель', + waitForImgUpload: 'Пожалуйста, дождитесь загрузки изображения', + }, + chatSubTitle: 'Инструкции', + completionSubTitle: 'Префикс Промпта', + promptTip: + 'Промпт направляют ответы ИИ с помощью инструкций и ограничений. Вставьте переменные, такие как {{input}}. Этот Промпт не будет видна пользователям.', + formattingChangedTitle: 'Форматирование изменено', + formattingChangedText: + 'Изменение форматирования приведет к сбросу области отладки, вы уверены?', + variableTitle: 'Переменные', + variableTip: + 'Пользователи заполняют переменные в форме, автоматически заменяя переменные в промпте.', + notSetVar: 'Переменные позволяют пользователям вводить промпты или вступительные замечания при заполнении форм. Вы можете попробовать ввести "{{input}}" в промптах.', + autoAddVar: 'В предварительной промпте упоминаются неопределенные переменные, хотите ли вы добавить их в форму пользовательского ввода?', + variableTable: { + key: 'Ключ переменной', + name: 'Имя поля пользовательского ввода', + optional: 'Необязательно', + type: 'Тип ввода', + action: 'Действия', + typeString: 'Строка', + typeSelect: 'Выбор', + }, + varKeyError: { + canNoBeEmpty: '{{key}} обязательно', + tooLong: '{{key}} слишком длинное. Не может быть длиннее 30 символов', + notValid: '{{key}} недействительно. Может содержать только буквы, цифры и подчеркивания', + notStartWithNumber: '{{key}} не может начинаться с цифры', + keyAlreadyExists: '{{key}} уже существует', + }, + otherError: { + promptNoBeEmpty: 'Промпт не может быть пустой', + historyNoBeEmpty: 'История разговоров должна быть установлена в промпте', + queryNoBeEmpty: 'Запрос должен быть установлен в промпте', + }, + variableConfig: { + 'addModalTitle': 'Добавить поле ввода', + 'editModalTitle': 'Редактировать поле ввода', + 'description': 'Настройка для переменной {{varName}}', + 'fieldType': 'Тип поля', + 'string': 'Короткий текст', + 'text-input': 'Короткий текст', + 'paragraph': 'Абзац', + 'select': 'Выбор', + 'number': 'Число', + 'notSet': 'Не задано, попробуйте ввести {{input}} в префикс промпта', + 'stringTitle': 'Параметры текстового поля формы', + 'maxLength': 'Максимальная длина', + 'options': 'Варианты', + 'addOption': 'Добавить вариант', + 'apiBasedVar': 'Переменная на основе API', + 'varName': 'Имя переменной', + 'labelName': 'Имя метки', + 'inputPlaceholder': 'Пожалуйста, введите', + 'content': 'Содержимое', + 'required': 'Обязательно', + 'errorMsg': { + labelNameRequired: 'Имя метки обязательно', + varNameCanBeRepeat: 'Имя переменной не может повторяться', + atLeastOneOption: 'Требуется хотя бы один вариант', + optionRepeat: 'Есть повторяющиеся варианты', + }, + }, + vision: { + name: 'Зрение', + description: 'Включение зрения позволит модели принимать изображения и отвечать на вопросы о них.', + settings: 'Настройки', + visionSettings: { + title: 'Настройки зрения', + resolution: 'Разрешение', + resolutionTooltip: `Низкое разрешение позволит модели получать версию изображения с низким разрешением 512 x 512 и представлять изображение с бюджетом 65 токенов. Это позволяет API возвращать ответы быстрее и потреблять меньше входных токенов для случаев использования, не требующих высокой детализации. + \n + Высокое разрешение сначала позволит модели увидеть изображение с низким разрешением, а затем создаст детальные фрагменты входных изображений в виде квадратов 512 пикселей на основе размера входного изображения. Каждый из детальных фрагментов использует вдвое больший бюджет токенов, в общей сложности 129 токенов.`, + high: 'Высокое', + low: 'Низкое', + uploadMethod: 'Метод загрузки', + both: 'Оба', + localUpload: 'Локальная загрузка', + url: 'URL', + uploadLimit: 'Лимит загрузки', + }, + }, + voice: { + name: 'Голос', + defaultDisplay: 'Голос по умолчанию', + description: 'Настройки преобразования текста в речь', + settings: 'Настройки', + voiceSettings: { + title: 'Настройки голоса', + language: 'Язык', + resolutionTooltip: 'Язык, поддерживаемый преобразованием текста в речь.', + voice: 'Голос', + autoPlay: 'Автовоспроизведение', + autoPlayEnabled: 'Включить', + autoPlayDisabled: 'Выключить', + }, + }, + openingStatement: { + title: 'Начальное сообщение', + add: 'Добавить', + writeOpener: 'Написать начальное сообщение', + placeholder: 'Напишите здесь свое начальное сообщение, вы можете использовать переменные, попробуйте ввести {{variable}}.', + openingQuestion: 'Начальные вопросы', + noDataPlaceHolder: + 'Начало разговора с пользователем может помочь ИИ установить более тесную связь с ним в диалоговых приложениях.', + varTip: 'Вы можете использовать переменные, попробуйте ввести {{variable}}', + tooShort: 'Для генерации вступительного замечания к разговору требуется не менее 20 слов начального промпта.', + notIncludeKey: 'Начальный промпт не включает переменную: {{key}}. Пожалуйста, добавьте её в начальную промпт.', + }, + modelConfig: { + model: 'Модель', + setTone: 'Установить тон ответов', + title: 'Модель и параметры', + modeType: { + chat: 'Чат', + completion: 'Завершение', + }, + }, + inputs: { + title: 'Отладка и предварительный просмотр', + noPrompt: 'Попробуйте написать промпт во входных данных предварительного промпта', + userInputField: 'Поле пользовательского ввода', + noVar: 'Заполните значение переменной, которое будет автоматически заменяться в промпте каждый раз при запуске нового сеанса.', + chatVarTip: + 'Заполните значение переменной, которое будет автоматически заменяться в промпте каждый раз при запуске нового сеанса', + completionVarTip: + 'Заполните значение переменной, которое будет автоматически заменяться в промпте каждый раз при отправке вопроса.', + previewTitle: 'Предварительный просмотр промпта', + queryTitle: 'Содержимое запроса', + queryPlaceholder: 'Пожалуйста, введите текст запроса.', + run: 'ЗАПУСТИТЬ', + }, + result: 'Выходной текст', + datasetConfig: { + settingTitle: 'Настройки поиска', + knowledgeTip: 'Нажмите кнопку "+", чтобы добавить знания', + retrieveOneWay: { + title: 'Поиск N-к-1', + description: 'На основе намерения пользователя и описаний знаний агент автономно выбирает наилучшие знания для запроса. Лучше всего подходит для приложений с различными, ограниченными знаниями.', + }, + retrieveMultiWay: { + title: 'Многопутный поиск', + description: 'На основе намерения пользователя выполняет запросы по всем знаниям, извлекает соответствующий текст из нескольких источников и выбирает наилучшие результаты, соответствующие запросу пользователя, после повторного ранжирования.', + }, + rerankModelRequired: 'Требуется rerank-модель ', + params: 'Параметры', + top_k: 'Top K', + top_kTip: 'Используется для фильтрации фрагментов, наиболее похожих на вопросы пользователей. Система также будет динамически корректировать значение Top K в зависимости от max_tokens выбранной модели.', + score_threshold: 'Порог оценки', + score_thresholdTip: 'Используется для установки порога сходства для фильтрации фрагментов.', + retrieveChangeTip: 'Изменение режима индексации и режима поиска может повлиять на приложения, связанные с этими знаниями.', + }, + debugAsSingleModel: 'Отладка как одной модели', + debugAsMultipleModel: 'Отладка как нескольких моделей', + duplicateModel: 'Дублировать', + publishAs: 'Опубликовать как', + assistantType: { + name: 'Тип помощника', + chatAssistant: { + name: 'Базовый помощник', + description: 'Создайте помощника на основе чата, используя большую языковую модель', + }, + agentAssistant: { + name: 'Агент-помощник', + description: 'Создайте интеллектуального агента, который может автономно выбирать инструменты для выполнения задач', + }, + }, + agent: { + agentMode: 'Режим агента', + agentModeDes: 'Установите тип режима вывода для агента', + agentModeType: { + ReACT: 'ReAct', + functionCall: 'Вызов функции', + }, + setting: { + name: 'Настройки агента', + description: 'Настройки агента-помощника позволяют установить режим агента и расширенные функции, такие как встроенные промпты, доступные только в типе агента.', + maximumIterations: { + name: 'Максимальное количество итераций', + description: 'Ограничьте количество итераций, которые может выполнить агент-помощник', + }, + }, + buildInPrompt: 'Встроенный промпт', + firstPrompt: 'Первый промпт', + nextIteration: 'Следующая итерация', + promptPlaceholder: 'Напишите здесь свой первый промпт', + tools: { + name: 'Инструменты', + description: 'Использование инструментов может расширить возможности LLM, такие как поиск в Интернете или выполнение научных расчетов', + enabled: 'Включено', + }, + }, +} + +export default translation diff --git a/web/i18n/ru-RU/app-log.ts b/web/i18n/ru-RU/app-log.ts new file mode 100644 index 0000000000..c6c54ef178 --- /dev/null +++ b/web/i18n/ru-RU/app-log.ts @@ -0,0 +1,95 @@ +const translation = { + title: 'Логирование', + description: 'В логах записывается состояние работы приложения, включая пользовательский ввод и ответы ИИ.', + dateTimeFormat: 'DD.MM.YYYY HH:mm', + table: { + header: { + updatedTime: 'Время обновления', + time: 'Время создания', + endUser: 'Конечный пользователь или аккаунт', + input: 'Ввод', + output: 'Вывод', + summary: 'Заголовок', + messageCount: 'Количество сообщений', + userRate: 'Оценка пользователя', + adminRate: 'Оценка оп.', + startTime: 'ВРЕМЯ НАЧАЛА', + status: 'СТАТУС', + runtime: 'ВРЕМЯ ВЫПОЛНЕНИЯ', + tokens: 'ТОКЕНЫ', + user: 'Конечный пользователь или аккаунт', + version: 'ВЕРСИЯ', + }, + pagination: { + previous: 'Предыдущий', + next: 'Следующий', + }, + empty: { + noChat: 'Еще нет чатов', + noOutput: 'Нет вывода', + element: { + title: 'Есть кто-нибудь?', + content: 'Наблюдайте и аннотируйте взаимодействия между конечными пользователями и приложениями ИИ здесь, чтобы постоянно повышать точность ИИ. Вы можете попробовать поделиться или протестировать веб-приложение самостоятельно, а затем вернуться на эту страницу.', + }, + }, + }, + detail: { + time: 'Время', + conversationId: 'Идентификатор разговора', + promptTemplate: 'Шаблон подсказки', + promptTemplateBeforeChat: 'Шаблон подсказки перед чатом · Как системное сообщение', + annotationTip: 'Улучшения, отмеченные {{user}}', + timeConsuming: '', + second: 'с', + tokenCost: 'Потрачено токенов', + loading: 'загрузка', + operation: { + like: 'лайк', + dislike: 'дизлайк', + addAnnotation: 'Добавить улучшение', + editAnnotation: 'Редактировать улучшение', + annotationPlaceholder: 'Введите ожидаемый ответ, который вы хотите получить от ИИ, который может быть использован для тонкой настройки модели и постоянного улучшения качества генерации текста в будущем.', + }, + variables: 'Переменные', + uploadImages: 'Загруженные изображения', + }, + filter: { + period: { + today: 'Сегодня', + last7days: 'Последние 7 дней', + last4weeks: 'Последние 4 недели', + last3months: 'Последние 3 месяца', + last12months: 'Последние 12 месяцев', + monthToDate: 'С начала месяца', + quarterToDate: 'С начала квартала', + yearToDate: 'С начала года', + allTime: 'Все время', + }, + annotation: { + all: 'Все', + annotated: 'Аннотированные улучшения ({{count}} элементов)', + not_annotated: 'Не аннотировано', + }, + sortBy: 'Сортировать по:', + descending: 'по убыванию', + ascending: 'по возрастанию', + }, + workflowTitle: 'Журналы рабочих процессов', + workflowSubtitle: 'Журнал записал работу Automate.', + runDetail: { + title: 'Журнал разговоров', + workflowTitle: 'Подробная информация о журнале', + }, + promptLog: 'Журнал подсказок', + agentLog: 'Журнал агента', + viewLog: 'Просмотреть журнал', + agentLogDetail: { + agentMode: 'Режим агента', + toolUsed: 'Использованный инструмент', + iterations: 'Итерации', + iteration: 'Итерация', + finalProcessing: 'Окончательная обработка', + }, +} + +export default translation diff --git a/web/i18n/ru-RU/app-overview.ts b/web/i18n/ru-RU/app-overview.ts new file mode 100644 index 0000000000..2969ddd6e7 --- /dev/null +++ b/web/i18n/ru-RU/app-overview.ts @@ -0,0 +1,168 @@ +const translation = { + welcome: { + firstStepTip: 'Чтобы начать,', + enterKeyTip: 'введите свой ключ API OpenAI ниже', + getKeyTip: 'Получите свой ключ API на панели инструментов OpenAI', + placeholder: 'Ваш ключ API OpenAI (например, sk-xxxx)', + }, + apiKeyInfo: { + cloud: { + trial: { + title: 'Вы используете пробную квоту {{providerName}}.', + description: 'Пробная квота предоставляется для тестирования. Прежде чем пробная квота будет исчерпана, пожалуйста, настройте своего собственного поставщика модели или приобретите дополнительную квоту.', + }, + exhausted: { + title: 'Ваша пробная квота была исчерпана, пожалуйста, настройте свой APIKey.', + description: 'Вы исчерпали свою пробную квоту. Пожалуйста, настройте своего собственного поставщика модели или приобретите дополнительную квоту.', + }, + }, + selfHost: { + title: { + row1: 'Чтобы начать,', + row2: 'сначала настройте своего поставщика модели.', + }, + }, + callTimes: 'Количество вызовов', + usedToken: 'Использованные токены', + setAPIBtn: 'Перейти к настройке поставщика модели', + tryCloud: 'Или попробуйте облачную версию Dify с бесплатной квотой', + }, + overview: { + title: 'Обзор', + appInfo: { + explanation: 'Готовое к использованию веб-приложение ИИ', + accessibleAddress: 'Публичный URL', + preview: 'Предварительный просмотр', + regenerate: 'Перегенерировать', + regenerateNotice: 'Вы хотите перегенерировать публичный URL?', + preUseReminder: 'Пожалуйста, включите веб-приложение перед продолжением.', + settings: { + entry: 'Настройки', + title: 'Настройки веб-приложения', + webName: 'Название веб-приложения', + webDesc: 'Описание веб-приложения', + webDescTip: 'Этот текст будет отображаться на стороне клиента, предоставляя базовые инструкции по использованию приложения', + webDescPlaceholder: 'Введите описание веб-приложения', + language: 'Язык', + workflow: { + title: 'Рабочий процесс', + subTitle: 'Подробности рабочего процесса', + show: 'Показать', + hide: 'Скрыть', + showDesc: 'Показать или скрыть подробности рабочего процесса в веб-приложении', + }, + chatColorTheme: 'Цветовая тема чата', + chatColorThemeDesc: 'Установите цветовую тему чат-бота', + chatColorThemeInverted: 'Инвертированные цвета', + invalidHexMessage: 'Неверное HEX-значение', + sso: { + label: 'SSO аутентификация', + title: 'WebApp SSO', + description: 'Все пользователи должны войти в систему с помощью SSO перед использованием WebApp', + tooltip: 'Обратитесь к администратору, чтобы включить WebApp SSO', + }, + more: { + entry: 'Показать больше настроек', + copyright: 'Авторские права', + copyRightPlaceholder: 'Введите имя автора или организации', + privacyPolicy: 'Политика конфиденциальности', + privacyPolicyPlaceholder: 'Введите ссылку на политику конфиденциальности', + privacyPolicyTip: 'Помогает посетителям понять, какие данные собирает приложение, см. Политику конфиденциальности Dify.', + customDisclaimer: 'Пользовательский отказ от ответственности', + customDisclaimerPlaceholder: 'Введите текст пользовательского отказа от ответственности', + customDisclaimerTip: 'Текст пользовательского отказа от ответственности будет отображаться на стороне клиента, предоставляя дополнительную информацию о приложении', + }, + }, + embedded: { + entry: 'Встраивание', + title: 'Встроить на веб-сайт', + explanation: 'Выберите способ встраивания чат-приложения на свой веб-сайт', + iframe: 'Чтобы добавить чат-приложение в любое место на вашем веб-сайте, добавьте этот iframe в свой HTML-код.', + scripts: 'Чтобы добавить чат-приложение в правый нижний угол вашего веб-сайта, добавьте этот код в свой HTML.', + chromePlugin: 'Установите расширение Dify Chatbot для Chrome', + copied: 'Скопировано', + copy: 'Копировать', + }, + qrcode: { + title: 'QR-код ссылки', + scan: 'Сканировать, чтобы поделиться', + download: 'Скачать QR-код', + }, + customize: { + way: 'способ', + entry: 'Настроить', + title: 'Настроить веб-приложение ИИ', + explanation: 'Вы можете настроить внешний интерфейс веб-приложения в соответствии со своими потребностями.', + way1: { + name: 'Создайте форк клиентского кода, измените его и разверните на Vercel (рекомендуется)', + step1: 'Создайте форк клиентского кода и измените его', + step1Tip: 'Нажмите здесь, чтобы создать форк исходного кода в своей учетной записи GitHub и изменить код', + step1Operation: 'Dify-WebClient', + step2: 'Развернуть на Vercel', + step2Tip: 'Нажмите здесь, чтобы импортировать репозиторий в Vercel и развернуть', + step2Operation: 'Импортировать репозиторий', + step3: 'Настроить переменные среды', + step3Tip: 'Добавьте следующие переменные среды в Vercel', + }, + way2: { + name: 'Напишите клиентский код для вызова API и разверните его на сервере', + operation: 'Документация', + }, + }, + }, + apiInfo: { + title: 'API серверной части', + explanation: 'Легко интегрируется в ваше приложение', + accessibleAddress: 'Конечная точка API сервиса', + doc: 'Справочник по API', + }, + status: { + running: 'В работе', + disable: 'Отключено', + }, + }, + analysis: { + title: 'Анализ', + ms: 'мс', + tokenPS: 'Токен/с', + totalMessages: { + title: 'Всего сообщений', + explanation: 'Ежедневное количество взаимодействий с ИИ.', + }, + totalConversations: { + title: 'Всего чатов', + explanation: 'Ежедневное количество чатов с LLM; проектирование/отладка не учитываются.', + }, + activeUsers: { + title: 'Активные пользователи', + explanation: 'Уникальные пользователи, участвующие в вопросах и ответах с LLM; проектирование/отладка не учитываются.', + }, + tokenUsage: { + title: 'Использование токенов', + explanation: 'Отражает ежедневное использование токенов языковой модели для приложения, полезно для целей контроля затрат.', + consumed: 'Потрачено', + }, + avgSessionInteractions: { + title: 'Среднее количество взаимодействий за сеанс', + explanation: 'Количество непрерывных взаимодействий пользователя с LLM; для приложений на основе чатов.', + }, + avgUserInteractions: { + title: 'Среднее количество взаимодействий пользователя', + explanation: 'Отражает ежедневную частоту использования пользователями. Эта метрика отражает активность пользователей.', + }, + userSatisfactionRate: { + title: 'Уровень удовлетворенности пользователей', + explanation: 'Количество лайков на 1000 сообщений. Это указывает на долю ответов, которыми пользователи довольны.', + }, + avgResponseTime: { + title: 'Среднее время ответа', + explanation: 'Время (мс) для обработки/ответа LLM; для текстовых приложений.', + }, + tps: { + title: 'Скорость вывода токенов', + explanation: 'Измерьте производительность LLM. Подсчитайте скорость вывода токенов LLM от начала запроса до завершения вывода.', + }, + }, +} + +export default translation diff --git a/web/i18n/ru-RU/app.ts b/web/i18n/ru-RU/app.ts new file mode 100644 index 0000000000..f5f45e65f1 --- /dev/null +++ b/web/i18n/ru-RU/app.ts @@ -0,0 +1,138 @@ +const translation = { + createApp: 'СОЗДАТЬ ПРИЛОЖЕНИЕ', + types: { + all: 'Все', + chatbot: 'Чат-бот', + agent: 'Агент', + workflow: 'Рабочий процесс', + completion: 'Завершение', + }, + duplicate: 'Дублировать', + duplicateTitle: 'Дублировать приложение', + export: 'Экспортировать DSL', + exportFailed: 'Ошибка экспорта DSL.', + importDSL: 'Импортировать файл DSL', + createFromConfigFile: 'Создать из файла DSL', + importFromDSL: 'Импортировать из DSL', + importFromDSLFile: 'Из файла DSL', + importFromDSLUrl: 'Из URL', + importFromDSLUrlPlaceholder: 'Вставьте ссылку DSL сюда', + deleteAppConfirmTitle: 'Удалить это приложение?', + deleteAppConfirmContent: + 'Удаление приложения необратимо. Пользователи больше не смогут получить доступ к вашему приложению, и все настройки подсказок и журналы будут безвозвратно удалены.', + appDeleted: 'Приложение удалено', + appDeleteFailed: 'Не удалось удалить приложение', + join: 'Присоединяйтесь к сообществу', + communityIntro: + 'Общайтесь с членами команды, участниками и разработчиками на разных каналах.', + roadmap: 'Посмотреть наш roadmap', + newApp: { + startFromBlank: 'Создать с нуля', + startFromTemplate: 'Создать из шаблона', + captionAppType: 'Какой тип приложения вы хотите создать?', + chatbotDescription: 'Создайте приложение на основе чата. Это приложение использует формат вопросов и ответов, позволяя общаться непрерывно.', + completionDescription: 'Создайте приложение, которое генерирует высококачественный текст на основе подсказок, например, генерирует статьи, резюме, переводы и многое другое.', + completionWarning: 'Этот тип приложения больше не будет поддерживаться.', + agentDescription: 'Создайте интеллектуального агента, который может автономно выбирать инструменты для выполнения задач', + workflowDescription: 'Создайте приложение, которое генерирует высококачественный текст на основе рабочего процесса, организованного с высокой степенью настройки. Подходит для опытных пользователей.', + workflowWarning: 'В настоящее время находится в бета-версии', + chatbotType: 'Метод организации чат-бота', + basic: 'Базовый', + basicTip: 'Для начинающих, можно переключиться на Chatflow позже', + basicFor: 'ДЛЯ НАЧИНАЮЩИХ', + basicDescription: 'Базовый конструктор позволяет создать приложение чат-бота с помощью простых настроек, без возможности изменять встроенные подсказки. Подходит для начинающих.', + advanced: 'Chatflow', + advancedFor: 'Для продвинутых пользователей', + advancedDescription: 'Организация рабочего процесса организует чат-ботов в виде рабочих процессов, предлагая высокую степень настройки, включая возможность редактирования встроенных подсказок. Подходит для опытных пользователей.', + captionName: 'Значок и название приложения', + appNamePlaceholder: 'Дайте вашему приложению имя', + captionDescription: 'Описание', + appDescriptionPlaceholder: 'Введите описание приложения', + useTemplate: 'Использовать этот шаблон', + previewDemo: 'Предварительный просмотр', + chatApp: 'Ассистент', + chatAppIntro: + 'Я хочу создать приложение на основе чата. Это приложение использует формат вопросов и ответов, позволяя общаться непрерывно.', + agentAssistant: 'Новый Ассистент Агента', + completeApp: 'Генератор текста', + completeAppIntro: + 'Я хочу создать приложение, которое генерирует высококачественный текст на основе подсказок, например, генерирует статьи, резюме, переводы и многое другое.', + showTemplates: 'Я хочу выбрать из шаблона', + hideTemplates: 'Вернуться к выбору режима', + Create: 'Создать', + Cancel: 'Отмена', + nameNotEmpty: 'Имя не может быть пустым', + appTemplateNotSelected: 'Пожалуйста, выберите шаблон', + appTypeRequired: 'Пожалуйста, выберите тип приложения', + appCreated: 'Приложение создано', + appCreateFailed: 'Не удалось создать приложение', + }, + editApp: 'Редактировать информацию', + editAppTitle: 'Редактировать информацию о приложении', + editDone: 'Информация о приложении обновлена', + editFailed: 'Не удалось обновить информацию о приложении', + iconPicker: { + ok: 'ОК', + cancel: 'Отмена', + emoji: 'Эмодзи', + image: 'Изображение', + }, + switch: 'Переключиться на Workflow', + switchTipStart: 'Для вас будет создана новая копия Workflow. Новая копия ', + switchTip: 'не позволит', + switchTipEnd: ' переключиться обратно на базовую организацию.', + switchLabel: 'Копия приложения, которая будет создана', + removeOriginal: 'Удалить исходное приложение', + switchStart: 'Переключиться', + typeSelector: { + all: 'ВСЕ типы', + chatbot: 'Чат-бот', + agent: 'Агент', + workflow: 'Рабочий процесс', + completion: 'Завершение', + }, + tracing: { + title: 'Отслеживание производительности приложения', + description: 'Настройка стороннего поставщика LLMOps и отслеживание производительности приложения.', + config: 'Настройка', + view: 'Просмотр', + collapse: 'Свернуть', + expand: 'Развернуть', + tracing: 'Отслеживание', + disabled: 'Отключено', + disabledTip: 'Пожалуйста, сначала настройте провайдера LLM', + enabled: 'В работе', + tracingDescription: 'Запись полного контекста выполнения приложения, включая вызовы LLM, контекст, подсказки, HTTP-запросы и многое другое, на стороннюю платформу трассировки.', + configProviderTitle: { + configured: 'Настроено', + notConfigured: 'Настройте провайдера, чтобы включить трассировку', + moreProvider: 'Больше провайдеров', + }, + langsmith: { + title: 'LangSmith', + description: 'Универсальная платформа для разработчиков для каждого этапа жизненного цикла приложения на базе LLM.', + }, + langfuse: { + title: 'Langfuse', + description: 'Трассировка, оценка, управление подсказками и метрики для отладки и улучшения вашего приложения LLM.', + }, + inUse: 'Используется', + configProvider: { + title: 'Настройка ', + placeholder: 'Введите ваш {{key}}', + project: 'Проект', + publicKey: 'Публичный ключ', + secretKey: 'Секретный ключ', + viewDocsLink: 'Посмотреть документацию {{key}}', + removeConfirmTitle: 'Удалить конфигурацию {{key}}?', + removeConfirmContent: 'Текущая конфигурация используется, ее удаление отключит функцию трассировки.', + }, + }, + answerIcon: { + title: 'Использование значка WebApp для замены 🤖', + description: 'Следует ли использовать значок WebApp для замены 🤖 в общем приложении', + descriptionInExplore: 'Следует ли использовать значок WebApp для замены 🤖 в разделе "Обзор"', + }, +} + +export default translation diff --git a/web/i18n/ru-RU/billing.ts b/web/i18n/ru-RU/billing.ts new file mode 100644 index 0000000000..e7760d9ac6 --- /dev/null +++ b/web/i18n/ru-RU/billing.ts @@ -0,0 +1,118 @@ +const translation = { + currentPlan: 'Текущий тарифный план', + upgradeBtn: { + plain: 'Обновить тарифный план', + encourage: 'Обновить сейчас', + encourageShort: 'Обновить', + }, + viewBilling: 'Управление счетами и подписками', + buyPermissionDeniedTip: 'Пожалуйста, свяжитесь с администратором вашей организации, чтобы подписаться', + plansCommon: { + title: 'Выберите тарифный план, который подходит именно вам', + yearlyTip: 'Получите 2 месяца бесплатно, подписавшись на год!', + mostPopular: 'Самый популярный', + planRange: { + monthly: 'Ежемесячно', + yearly: 'Ежегодно', + }, + month: 'месяц', + year: 'год', + save: 'Сэкономить ', + free: 'Бесплатно', + currentPlan: 'Текущий тарифный план', + contractSales: 'Связаться с отделом продаж', + contractOwner: 'Связаться с руководителем команды', + startForFree: 'Начать бесплатно', + getStartedWith: 'Начать с ', + contactSales: 'Связаться с отделом продаж', + talkToSales: 'Поговорить с отделом продаж', + modelProviders: 'Поставщики моделей', + teamMembers: 'Участники команды', + annotationQuota: 'Квота аннотаций', + buildApps: 'Создать приложения', + vectorSpace: 'Векторное пространство', + vectorSpaceBillingTooltip: 'Каждый 1 МБ может хранить около 1,2 миллиона символов векторизованных данных (оценка с использованием Embeddings OpenAI, варьируется в зависимости от модели).', + vectorSpaceTooltip: 'Векторное пространство - это система долговременной памяти, необходимая LLM для понимания ваших данных.', + documentsUploadQuota: 'Квота загрузки документов', + documentProcessingPriority: 'Приоритет обработки документов', + documentProcessingPriorityTip: 'Для более высокого приоритета обработки документов, пожалуйста, обновите свой тарифный план.', + documentProcessingPriorityUpgrade: 'Обрабатывайте больше данных с большей точностью и на более высоких скоростях.', + priority: { + 'standard': 'Стандартный', + 'priority': 'Приоритетный', + 'top-priority': 'Высокий приоритет', + }, + logsHistory: 'История журналов', + customTools: 'Пользовательские инструменты', + unavailable: 'Недоступно', + days: 'дней', + unlimited: 'Неограниченно', + support: 'Поддержка', + supportItems: { + communityForums: 'Форумы сообщества', + emailSupport: 'Поддержка по электронной почте', + priorityEmail: 'Приоритетная поддержка по электронной почте и в чате', + logoChange: 'Изменение логотипа', + SSOAuthentication: 'SSO аутентификация', + personalizedSupport: 'Персональная поддержка', + dedicatedAPISupport: 'Выделенная поддержка API', + customIntegration: 'Пользовательская интеграция и поддержка', + ragAPIRequest: 'Запросы RAG API', + bulkUpload: 'Массовая загрузка документов', + agentMode: 'Режим агента', + workflow: 'Рабочий процесс', + llmLoadingBalancing: 'Балансировка нагрузки LLM', + llmLoadingBalancingTooltip: 'Добавьте несколько ключей API к моделям, эффективно обходя ограничения скорости API.', + }, + comingSoon: 'Скоро', + member: 'Участник', + memberAfter: 'Участник', + messageRequest: { + title: 'Кредиты на сообщения', + tooltip: 'Квоты вызова сообщений для различных тарифных планов, использующих модели OpenAI (кроме gpt4). Сообщения, превышающие лимит, будут использовать ваш ключ API OpenAI.', + }, + annotatedResponse: { + title: 'Ограничения квоты аннотаций', + tooltip: 'Ручное редактирование и аннотирование ответов обеспечивает настраиваемые высококачественные возможности ответов на вопросы для приложений. (Применимо только в чат-приложениях)', + }, + ragAPIRequestTooltip: 'Относится к количеству вызовов API, вызывающих только возможности обработки базы знаний Dify.', + receiptInfo: 'Только владелец команды и администратор команды могут подписываться и просматривать информацию о выставлении счетов', + }, + plans: { + sandbox: { + name: 'Песочница', + description: '200 бесплатных пробных использований GPT', + includesTitle: 'Включает:', + }, + professional: { + name: 'Профессиональный', + description: 'Для частных лиц и небольших команд, чтобы разблокировать больше возможностей по доступной цене.', + includesTitle: 'Все в бесплатном плане, плюс:', + }, + team: { + name: 'Команда', + description: 'Сотрудничайте без ограничений и наслаждайтесь высочайшей производительностью.', + includesTitle: 'Все в профессиональном плане, плюс:', + }, + enterprise: { + name: 'Корпоративный', + description: 'Получите полный набор возможностей и поддержку для крупномасштабных критически важных систем.', + includesTitle: 'Все в командном плане, плюс:', + }, + }, + vectorSpace: { + fullTip: 'Векторное пространство заполнено.', + fullSolution: 'Обновите свой тарифный план, чтобы получить больше места.', + }, + apps: { + fullTipLine1: 'Обновите свой тарифный план, чтобы', + fullTipLine2: 'создавать больше приложений.', + }, + annotatedResponse: { + fullTipLine1: 'Обновите свой тарифный план, чтобы', + fullTipLine2: 'аннотировать больше разговоров.', + quotaTitle: 'Квота ответов аннотаций', + }, +} + +export default translation diff --git a/web/i18n/ru-RU/common.ts b/web/i18n/ru-RU/common.ts new file mode 100644 index 0000000000..82e3471e60 --- /dev/null +++ b/web/i18n/ru-RU/common.ts @@ -0,0 +1,578 @@ +const translation = { + api: { + success: 'Успешно', + actionSuccess: 'Действие выполнено успешно', + saved: 'Сохранено', + create: 'Создано', + remove: 'Удалено', + }, + operation: { + create: 'Создать', + confirm: 'Подтвердить', + cancel: 'Отмена', + clear: 'Очистить', + save: 'Сохранить', + saveAndEnable: 'Сохранить и включить', + edit: 'Редактировать', + add: 'Добавить', + added: 'Добавлено', + refresh: 'Перезапустить', + reset: 'Сбросить', + search: 'Поиск', + change: 'Изменить', + remove: 'Удалить', + send: 'Отправить', + copy: 'Копировать', + lineBreak: 'Разрыв строки', + sure: 'Я уверен', + download: 'Скачать', + delete: 'Удалить', + settings: 'Настройки', + setup: 'Настроить', + getForFree: 'Получить бесплатно', + reload: 'Перезагрузить', + ok: 'ОК', + log: 'Журнал', + learnMore: 'Узнать больше', + params: 'Параметры', + duplicate: 'Дублировать', + rename: 'Переименовать', + audioSourceUnavailable: 'AudioSource недоступен', + }, + errorMsg: { + fieldRequired: '{{field}} обязательно', + urlError: 'URL должен начинаться с http:// или https://', + }, + placeholder: { + input: 'Пожалуйста, введите', + select: 'Пожалуйста, выберите', + }, + voice: { + language: { + zhHans: 'Китайский', + zhHant: 'Традиционный китайский', + enUS: 'Английский', + deDE: 'Немецкий', + frFR: 'Французский', + esES: 'Испанский', + itIT: 'Итальянский', + thTH: 'Тайский', + idID: 'Индонезийский', + jaJP: 'Японский', + koKR: 'Корейский', + ptBR: 'Португальский', + ruRU: 'Русский', + ukUA: 'Украинский', + viVN: 'Вьетнамский', + plPL: 'Польский', + roRO: 'Румынский', + hiIN: 'Хинди', + trTR: 'Турецкий', + faIR: 'Персидский', + }, + }, + unit: { + char: 'символов', + }, + actionMsg: { + noModification: 'На данный момент нет изменений.', + modifiedSuccessfully: 'Изменено успешно', + modifiedUnsuccessfully: 'Изменено неудачно', + copySuccessfully: 'Скопировано успешно', + paySucceeded: 'Оплата прошла успешно', + payCancelled: 'Оплата отменена', + generatedSuccessfully: 'Сгенерировано успешно', + generatedUnsuccessfully: 'Сгенерировано неудачно', + }, + model: { + params: { + temperature: 'Temperature', + temperatureTip: + 'Контролирует случайность: более низкое значение приводит к менее случайным завершениям. По мере приближения температуры к нулю модель станет детерминированной и повторяющейся.', + top_p: 'Top P', + top_pTip: + 'Контролирует разнообразие с помощью ядерной выборки: 0,5 означает, что рассматривается половина всех вариантов, взвешенных по вероятности.', + presence_penalty: 'Presence penalty', + presence_penaltyTip: + 'Насколько штрафовать новые токены в зависимости от того, появляются ли они в тексте до сих пор.\nУвеличивает вероятность того, что модель будет говорить о новых темах.', + frequency_penalty: 'Frequency penalty', + frequency_penaltyTip: + 'Насколько штрафовать новые токены в зависимости от их существующей частоты в тексте до сих пор.\nУменьшает вероятность того, что модель будет повторять одну и ту же строку дословно.', + max_tokens: 'Максимальное количество токенов', + max_tokensTip: + 'Используется для ограничения максимальной длины ответа в токенах. \nБольшие значения могут ограничивать пространство, оставленное для подсказок, журналов чата и знаний. \nРекомендуется установить его ниже двух третей\ngpt-4-1106-preview, gpt-4-vision-preview max token (input 128k output 4k)', + maxTokenSettingTip: 'Ваша настройка максимального количества токенов высока, что потенциально ограничивает пространство для подсказок, запросов и данных. Подумайте о том, чтобы установить его ниже 2/3.', + setToCurrentModelMaxTokenTip: 'Максимальное количество токенов обновлено до 80% максимального количества токенов текущей модели {{maxToken}}.', + stop_sequences: 'Стоп-последовательности', + stop_sequencesTip: 'До четырех последовательностей, где API прекратит генерировать дальнейшие токены. Возвращаемый текст не будет содержать стоп-последовательность.', + stop_sequencesPlaceholder: 'Введите последовательность и нажмите Tab', + }, + tone: { + Creative: 'Творческий', + Balanced: 'Сбалансированный', + Precise: 'Точный', + Custom: 'Пользовательский', + }, + addMoreModel: 'Перейдите в настройки, чтобы добавить больше моделей', + }, + menus: { + status: 'бета', + explore: 'Исследовать', + apps: 'Студия', + plugins: 'Плагины', + pluginsTips: 'Интегрируйте сторонние плагины или создавайте совместимые с ChatGPT AI-плагины.', + datasets: 'Знания', + datasetsTips: 'СКОРО: Импортируйте свои собственные текстовые данные или записывайте данные в режиме реального времени через Webhook для улучшения контекста LLM.', + newApp: 'Новое приложение', + newDataset: 'Создать знания', + tools: 'Инструменты', + }, + userProfile: { + settings: 'Настройки', + emailSupport: 'Поддержка по электронной почте', + workspace: 'Рабочее пространство', + createWorkspace: 'Создать рабочее пространство', + helpCenter: 'Помощь', + communityFeedback: 'Обратная связь', + roadmap: 'План развития', + community: 'Сообщество', + about: 'О нас', + logout: 'Выйти', + }, + settings: { + accountGroup: 'АККАУНТ', + workplaceGroup: 'РАБОЧЕЕ ПРОСТРАНСТВО', + account: 'Моя учетная запись', + members: 'Участники', + billing: 'Оплата', + integrations: 'Интеграции', + language: 'Язык', + provider: 'Поставщик модели', + dataSource: 'Источник данных', + plugin: 'Плагины', + apiBasedExtension: 'API расширение', + }, + account: { + avatar: 'Аватар', + name: 'Имя', + email: 'Электронная почта', + password: 'Пароль', + passwordTip: 'Вы можете установить постоянный пароль, если не хотите использовать временные коды входа', + setPassword: 'Установить пароль', + resetPassword: 'Сбросить пароль', + currentPassword: 'Текущий пароль', + newPassword: 'Новый пароль', + confirmPassword: 'Подтвердите пароль', + notEqual: 'Два пароля различаются.', + langGeniusAccount: 'Учетная запись Dify', + langGeniusAccountTip: 'Ваша учетная запись Dify и связанные с ней пользовательские данные.', + editName: 'Редактировать имя', + showAppLength: 'Показать {{length}} приложений', + delete: 'Удалить учетную запись', + deleteTip: 'Удаление вашей учетной записи приведет к безвозвратному удалению всех ваших данных, и их невозможно будет восстановить.', + deleteConfirmTip: 'Для подтверждения, пожалуйста, отправьте следующее с вашего зарегистрированного адреса электронной почты на ', + }, + members: { + team: 'Команда', + invite: 'Добавить', + name: 'ИМЯ', + lastActive: 'ПОСЛЕДНЯЯ АКТИВНОСТЬ', + role: 'РОЛИ', + pending: 'Ожидание...', + owner: 'Владелец', + admin: 'Администратор', + adminTip: 'Может создавать приложения и управлять настройками команды', + normal: 'Обычный', + normalTip: 'Может только использовать приложения, не может создавать приложения', + builder: 'Разработчик', + builderTip: 'Может создавать и редактировать собственные приложения', + editor: 'Редактор', + editorTip: 'Может создавать и редактировать приложения', + datasetOperator: 'Администратор знаний', + datasetOperatorTip: 'Может управлять только базой знаний', + inviteTeamMember: 'Добавить участника команды', + inviteTeamMemberTip: 'Они могут получить доступ к данным вашей команды сразу после входа в систему.', + email: 'Электронная почта', + emailInvalid: 'Неверный формат электронной почты', + emailPlaceholder: 'Пожалуйста, введите адреса электронной почты', + sendInvite: 'Отправить приглашение', + invitedAsRole: 'Приглашен как пользователь с ролью {{role}}', + invitationSent: 'Приглашение отправлено', + invitationSentTip: 'Приглашение отправлено, и они могут войти в Dify, чтобы получить доступ к данным вашей команды.', + invitationLink: 'Ссылка для приглашения', + failedInvitationEmails: 'Следующие пользователи не были успешно приглашены', + ok: 'ОК', + removeFromTeam: 'Удалить из команды', + removeFromTeamTip: 'Удалить доступ к команде', + setAdmin: 'Назначить администратором', + setMember: 'Назначить обычным участником', + setBuilder: 'Назначить разработчиком', + setEditor: 'Назначить редактором', + disInvite: 'Отменить приглашение', + deleteMember: 'Удалить участника', + you: '(Вы)', + }, + integrations: { + connected: 'Подключено', + google: 'Google', + googleAccount: 'Войти с помощью учетной записи Google', + github: 'GitHub', + githubAccount: 'Войти с помощью учетной записи GitHub', + connect: 'Подключить', + }, + language: { + displayLanguage: 'Язык отображения', + timezone: 'Часовой пояс', + }, + provider: { + apiKey: 'Ключ API', + enterYourKey: 'Введите свой ключ API здесь', + invalidKey: 'Неверный ключ API OpenAI', + validatedError: 'Ошибка валидации: ', + validating: 'Проверка ключа...', + saveFailed: 'Ошибка сохранения ключа API', + apiKeyExceedBill: 'Этот API-ключ не имеет доступной квоты, пожалуйста, прочитайте', + addKey: 'Добавить ключ', + comingSoon: 'Скоро', + editKey: 'Редактировать', + invalidApiKey: 'Неверный ключ API', + azure: { + apiBase: 'Базовый API', + apiBasePlaceholder: 'Базовый URL-адрес API вашей конечной точки Azure OpenAI.', + apiKey: 'Ключ API', + apiKeyPlaceholder: 'Введите свой ключ API здесь', + helpTip: 'Узнать о службе Azure OpenAI', + }, + openaiHosted: { + openaiHosted: 'Размещенный OpenAI', + onTrial: 'ПРОБНАЯ ВЕРСИЯ', + exhausted: 'КВОТА ИСЧЕРПАНА', + desc: 'Хостинговая служба OpenAI, предоставляемая Dify, позволяет вам использовать такие модели, как GPT-3.5. Прежде чем ваша пробная квота будет исчерпана, вам необходимо настроить других поставщиков моделей.', + callTimes: 'Количество вызовов', + usedUp: 'Пробная квота исчерпана. Добавьте собственного поставщика модели.', + useYourModel: 'В настоящее время используется собственный поставщик модели.', + close: 'Закрыть', + }, + anthropicHosted: { + anthropicHosted: 'Anthropic Claude', + onTrial: 'ПРОБНАЯ ВЕРСИЯ', + exhausted: 'КВОТА ИСЧЕРПАНА', + desc: 'Мощная модель, которая отлично справляется с широким спектром задач, от сложных диалогов и создания творческого контента до подробных инструкций.', + callTimes: 'Количество вызовов', + usedUp: 'Пробная квота исчерпана. Добавьте собственного поставщика модели.', + useYourModel: 'В настоящее время используется собственный поставщик модели.', + close: 'Закрыть', + }, + anthropic: { + using: 'Возможность встраивания использует', + enableTip: 'Чтобы включить модель Anthropic, вам необходимо сначала привязаться к OpenAI или Azure OpenAI Service.', + notEnabled: 'Не включено', + keyFrom: 'Получите свой ключ API от Anthropic', + }, + encrypted: { + front: 'Ваш API-ключ будет зашифрован и сохранен с использованием', + back: ' технологии.', + }, + }, + modelProvider: { + notConfigured: 'Системная модель еще не полностью настроена, и некоторые функции могут быть недоступны.', + systemModelSettings: 'Настройки системной модели', + systemModelSettingsLink: 'Зачем нужно настраивать системную модель?', + selectModel: 'Выберите свою модель', + setupModelFirst: 'Пожалуйста, сначала настройте свою модель', + systemReasoningModel: { + key: 'Модель системного мышления', + tip: 'Установите модель вывода по умолчанию, которая будет использоваться для создания приложений, а также такие функции, как генерация имени диалога и предложение следующего вопроса, также будут использовать модель вывода по умолчанию.', + }, + embeddingModel: { + key: 'Модель встраивания', + tip: 'Установите модель по умолчанию для обработки встраивания документов знаний, как поиск, так и импорт знаний используют эту модель встраивания для обработки векторизации. Переключение приведет к несоответствию векторного измерения между импортированными знаниями и вопросом, что приведет к сбою поиска. Чтобы избежать сбоя поиска, пожалуйста, не переключайте эту модель по своему усмотрению.', + required: 'Модель встраивания обязательна', + }, + speechToTextModel: { + key: 'Модель преобразования речи в текст', + tip: 'Установите модель по умолчанию для ввода речи в текст в разговоре.', + }, + ttsModel: { + key: 'Модель преобразования текста в речь', + tip: 'Установите модель по умолчанию для ввода текста в речь в разговоре.', + }, + rerankModel: { + key: 'Модель повторного ранжирования', + tip: 'Модель повторного ранжирования изменит порядок списка документов-кандидатов на основе семантического соответствия запросу пользователя, улучшая результаты семантического ранжирования', + }, + apiKey: 'API-КЛЮЧ', + quota: 'Квота', + searchModel: 'Поиск модели', + noModelFound: 'Модель не найдена для {{model}}', + models: 'Модели', + showMoreModelProvider: 'Показать больше поставщиков моделей', + selector: { + tip: 'Эта модель была удалена. Пожалуйста, добавьте модель или выберите другую модель.', + emptyTip: 'Нет доступных моделей', + emptySetting: 'Пожалуйста, перейдите в настройки для настройки', + rerankTip: 'Пожалуйста, настройте модель повторного ранжирования', + }, + card: { + quota: 'КВОТА', + onTrial: 'Пробная версия', + paid: 'Платный', + quotaExhausted: 'Квота исчерпана', + callTimes: 'Количество вызовов', + tokens: 'Токены', + buyQuota: 'Купить квоту', + priorityUse: 'Приоритетное использование', + removeKey: 'Удалить API-ключ', + tip: 'Приоритет будет отдаваться платной квоте. Пробная квота будет использоваться после исчерпания платной квоты.', + }, + item: { + deleteDesc: '{{modelName}} используются в качестве моделей системного мышления. Некоторые функции будут недоступны после удаления. Пожалуйста, подтвердите.', + freeQuota: 'БЕСПЛАТНАЯ КВОТА', + }, + addApiKey: 'Добавьте свой API-ключ', + invalidApiKey: 'Неверный API-ключ', + encrypted: { + front: 'Ваш API-ключ будет зашифрован и сохранен с использованием', + back: ' технологии.', + }, + freeQuota: { + howToEarn: 'Как заработать', + }, + addMoreModelProvider: 'ДОБАВИТЬ БОЛЬШЕ ПОСТАВЩИКОВ МОДЕЛЕЙ', + addModel: 'Добавить модель', + modelsNum: '{{num}} Моделей', + showModels: 'Показать модели', + showModelsNum: 'Показать {{num}} моделей', + collapse: 'Свернуть', + config: 'Настройка', + modelAndParameters: 'Модель и параметры', + model: 'Модель', + featureSupported: '{{feature}} поддерживается', + callTimes: 'Количество вызовов', + credits: 'Кредиты на сообщения', + buyQuota: 'Купить квоту', + getFreeTokens: 'Получить бесплатные токены', + priorityUsing: 'Приоритетное использование', + deprecated: 'Устаревший', + confirmDelete: 'Подтвердить удаление?', + quotaTip: 'Оставшиеся доступные бесплатные токены', + loadPresets: 'Загрузить предустановки', + parameters: 'ПАРАМЕТРЫ', + loadBalancing: 'Балансировка нагрузки', + loadBalancingDescription: 'Снизьте нагрузку с помощью нескольких наборов учетных данных.', + loadBalancingHeadline: 'Балансировка нагрузки', + configLoadBalancing: 'Настроить балансировку нагрузки', + modelHasBeenDeprecated: 'Эта модель устарела', + providerManaged: 'Управляется поставщиком', + providerManagedDescription: 'Используйте один набор учетных данных, предоставленный поставщиком модели.', + defaultConfig: 'Настройка по умолчанию', + apiKeyStatusNormal: 'Статус APIKey в норме', + apiKeyRateLimit: 'Достигнут предел скорости, доступен через {{seconds}}s', + addConfig: 'Добавить конфигурацию', + editConfig: 'Редактировать конфигурацию', + loadBalancingLeastKeyWarning: 'Для включения балансировки нагрузки необходимо включить не менее 2 ключей.', + loadBalancingInfo: 'По умолчанию балансировка нагрузки использует стратегию Round-robin. Если срабатывает ограничение скорости, будет применен 1-минутный период охлаждения.', + upgradeForLoadBalancing: 'Обновите свой тарифный план, чтобы включить балансировку нагрузки.', + }, + dataSource: { + add: 'Добавить источник данных', + connect: 'Подключить', + configure: 'Настроить', + notion: { + title: 'Notion', + description: 'Использование Notion в качестве источника данных для знаний.', + connectedWorkspace: 'Подключенное рабочее пространство', + addWorkspace: 'Добавить рабочее пространство', + connected: 'Подключено', + disconnected: 'Отключено', + changeAuthorizedPages: 'Изменить авторизованные страницы', + pagesAuthorized: 'Авторизованные страницы', + sync: 'Синхронизировать', + remove: 'Удалить', + selector: { + pageSelected: 'Выбранные страницы', + searchPages: 'Поиск страниц...', + noSearchResult: 'Нет результатов поиска', + addPages: 'Добавить страницы', + preview: 'ПРЕДПРОСМОТР', + }, + }, + website: { + title: 'Веб-сайт', + description: 'Импортировать контент с веб-сайтов с помощью веб-краулера.', + with: 'С', + configuredCrawlers: 'Настроенные краулеры', + active: 'Активный', + inactive: 'Неактивный', + }, + }, + plugin: { + serpapi: { + apiKey: 'Ключ API', + apiKeyPlaceholder: 'Введите свой ключ API', + keyFrom: 'Получите свой ключ SerpAPI на странице учетной записи SerpAPI', + }, + }, + apiBasedExtension: { + title: 'API-расширения обеспечивают централизованное управление API, упрощая настройку для удобного использования в приложениях Dify.', + link: 'Узнайте, как разработать собственное API-расширение.', + linkUrl: 'https://docs.dify.ai/features/extension/api_based_extension', + add: 'Добавить API Extension', + selector: { + title: 'API Extension', + placeholder: 'Пожалуйста, выберите API-расширение', + manage: 'Управление API-расширением', + }, + modal: { + title: 'Добавить API-расширение', + editTitle: 'Редактировать API-расширение', + name: { + title: 'Имя', + placeholder: 'Пожалуйста, введите имя', + }, + apiEndpoint: { + title: 'API Endpoint', + placeholder: 'Пожалуйста, введите конечную точку API', + }, + apiKey: { + title: 'API-ключ', + placeholder: 'Пожалуйста, введите API-ключ', + lengthError: 'Длина API-ключа не может быть меньше 5 символов', + }, + }, + type: 'Тип', + }, + about: { + changeLog: 'Журнал изменений', + updateNow: 'Обновить сейчас', + nowAvailable: 'Dify {{version}} теперь доступен.', + latestAvailable: 'Dify {{version}} - последняя доступная версия.', + }, + appMenus: { + overview: 'Мониторинг', + promptEng: 'Оркестрация', + apiAccess: 'Доступ к API', + logAndAnn: 'Журналы и аннотации', + logs: 'Журналы', + }, + environment: { + testing: 'ТЕСТИРОВАНИЕ', + development: 'РАЗРАБОТКА', + }, + appModes: { + completionApp: 'Генератор текста', + chatApp: 'Чат-приложение', + }, + datasetMenus: { + documents: 'Документы', + hitTesting: 'Тестирование поиска', + settings: 'Настройки', + emptyTip: 'Знания не были связаны, пожалуйста, перейдите в приложение или плагин, чтобы завершить связывание.', + viewDoc: 'Просмотреть документацию', + relatedApp: 'связанные приложения', + }, + voiceInput: { + speaking: 'Говорите сейчас...', + converting: 'Преобразование в текст...', + notAllow: 'микрофон не авторизован', + }, + modelName: { + 'gpt-3.5-turbo': 'GPT-3.5-Turbo', + 'gpt-3.5-turbo-16k': 'GPT-3.5-Turbo-16K', + 'gpt-4': 'GPT-4', + 'gpt-4-32k': 'GPT-4-32K', + 'text-davinci-003': 'Text-Davinci-003', + 'text-embedding-ada-002': 'Text-Embedding-Ada-002', + 'whisper-1': 'Whisper-1', + 'claude-instant-1': 'Claude-Instant', + 'claude-2': 'Claude-2', + }, + chat: { + renameConversation: 'Переименовать разговор', + conversationName: 'Название разговора', + conversationNamePlaceholder: 'Пожалуйста, введите название разговора', + conversationNameCanNotEmpty: 'Название разговора обязательно', + citation: { + title: 'ЦИТАТЫ', + linkToDataset: 'Ссылка на знания', + characters: 'Символы:', + hitCount: 'Количество совпадений:', + vectorHash: 'Векторный хэш:', + hitScore: 'Оценка совпадения:', + }, + }, + promptEditor: { + placeholder: 'Напишите здесь свое ключевое слово подсказки, введите \'{\', чтобы вставить переменную, введите \'/\', чтобы вставить блок содержимого подсказки', + context: { + item: { + title: 'Контекст', + desc: 'Вставить шаблон контекста', + }, + modal: { + title: '{{num}} знаний в контексте', + add: 'Добавить контекст ', + footer: 'Вы можете управлять контекстами в разделе «Контекст» ниже.', + }, + }, + history: { + item: { + title: 'История разговоров', + desc: 'Вставить шаблон исторического сообщения', + }, + modal: { + title: 'ПРИМЕР', + user: 'Привет', + assistant: 'Привет! Как я могу вам помочь сегодня?', + edit: 'Редактировать имена ролей разговора', + }, + }, + variable: { + item: { + title: 'Переменные и внешние инструменты', + desc: 'Вставить переменные и внешние инструменты', + }, + outputToolDisabledItem: { + title: 'Переменные', + desc: 'Вставить переменные', + }, + modal: { + add: 'Новая переменная', + addTool: 'Новый инструмент', + }, + }, + query: { + item: { + title: 'Запрос', + desc: 'Вставить шаблон запроса пользователя', + }, + }, + existed: 'Уже существует в подсказке', + }, + imageUploader: { + uploadFromComputer: 'Загрузить с компьютера', + uploadFromComputerReadError: 'Ошибка чтения изображения, повторите попытку.', + uploadFromComputerUploadError: 'Ошибка загрузки изображения, загрузите еще раз.', + uploadFromComputerLimit: 'Загружаемые изображения не могут превышать {{size}} МБ', + pasteImageLink: 'Вставить ссылку на изображение', + pasteImageLinkInputPlaceholder: 'Вставьте ссылку на изображение здесь', + pasteImageLinkInvalid: 'Неверная ссылка на изображение', + imageUpload: 'Загрузка изображения', + }, + tag: { + placeholder: 'Все теги', + addNew: 'Добавить новый тег', + noTag: 'Нет тегов', + noTagYet: 'Еще нет тегов', + addTag: 'Добавить теги', + editTag: 'Редактировать теги', + manageTags: 'Управление тегами', + selectorPlaceholder: 'Введите для поиска или создания', + create: 'Создать', + delete: 'Удалить тег', + deleteTip: 'Тег используется, удалить его?', + created: 'Тег успешно создан', + failed: 'Ошибка создания тега', + }, +} + +export default translation diff --git a/web/i18n/ru-RU/custom.ts b/web/i18n/ru-RU/custom.ts new file mode 100644 index 0000000000..8725c83577 --- /dev/null +++ b/web/i18n/ru-RU/custom.ts @@ -0,0 +1,30 @@ +const translation = { + custom: 'Настройка', + upgradeTip: { + prefix: 'Обновите свой тарифный план, чтобы', + suffix: 'настроить свой бренд.', + }, + webapp: { + title: 'Настроить бренд веб-приложения', + removeBrand: 'Удалить Powered by Dify', + changeLogo: 'Изменить изображение бренда Powered by', + changeLogoTip: 'Формат SVG или PNG с минимальным размером 40x40px', + }, + app: { + title: 'Настроить бренд заголовка приложения', + changeLogoTip: 'Формат SVG или PNG с минимальным размером 80x80px', + }, + upload: 'Загрузить', + uploading: 'Загрузка', + uploadedFail: 'Ошибка загрузки изображения, пожалуйста изображение, загрузите еще раз.', + change: 'Изменить', + apply: 'Применить', + restore: 'Восстановить значения по умолчанию', + customize: { + contactUs: ' свяжитесь с нами ', + prefix: 'Чтобы настроить логотип бренда в приложении, пожалуйста,', + suffix: 'чтобы перейти на корпоративную версию.', + }, +} + +export default translation diff --git a/web/i18n/ru-RU/dataset-creation.ts b/web/i18n/ru-RU/dataset-creation.ts new file mode 100644 index 0000000000..c4dce774d8 --- /dev/null +++ b/web/i18n/ru-RU/dataset-creation.ts @@ -0,0 +1,161 @@ +const translation = { + steps: { + header: { + creation: 'Создать базу знаний', + update: 'Добавить данные', + }, + one: 'Выберите источник данных', + two: 'Предварительная обработка и очистка текста', + three: 'Выполнить и завершить', + }, + error: { + unavailable: 'Эта база знаний недоступна', + }, + firecrawl: { + configFirecrawl: 'Настроить 🔥Firecrawl', + apiKeyPlaceholder: 'Ключ API с firecrawl.dev', + getApiKeyLinkText: 'Получите свой ключ API с firecrawl.dev', + }, + stepOne: { + filePreview: 'Предварительный просмотр файла', + pagePreview: 'Предварительный просмотр страницы', + dataSourceType: { + file: 'Импортировать из файла', + notion: 'Синхронизировать из Notion', + web: 'Синхронизировать с веб-сайта', + }, + uploader: { + title: 'Загрузить файл', + button: 'Перетащите файл или', + browse: 'Обзор', + tip: 'Поддерживаются {{supportTypes}}. Максимум {{size}} МБ каждый.', + validation: { + typeError: 'Тип файла не поддерживается', + size: 'Файл слишком большой. Максимум {{size}} МБ', + count: 'Несколько файлов не поддерживаются', + filesNumber: 'Вы достигли лимита пакетной загрузки {{filesNumber}} файлов.', + }, + cancel: 'Отмена', + change: 'Изменить', + failed: 'Ошибка загрузки', + }, + notionSyncTitle: 'Notion не подключен', + notionSyncTip: 'Чтобы синхронизировать данные из Notion, сначала необходимо установить соединение с Notion.', + connect: 'Перейти к подключению', + button: 'Далее', + emptyDatasetCreation: 'Я хочу создать пустую базу знаний', + modal: { + title: 'Создать пустую базу знаний', + tip: 'Пустая база знаний не будет содержать документов, и вы можете загружать документы в любое время.', + input: 'Название базы знаний', + placeholder: 'Пожалуйста, введите', + nameNotEmpty: 'Название не может быть пустым', + nameLengthInvalid: 'Название должно быть от 1 до 40 символов', + cancelButton: 'Отмена', + confirmButton: 'Создать', + failed: 'Ошибка создания', + }, + website: { + fireCrawlNotConfigured: 'Firecrawl не настроен', + fireCrawlNotConfiguredDescription: 'Настройте Firecrawl с API-ключом.', + configure: 'Настроить', + run: 'Запустить', + firecrawlTitle: 'Извлечь веб-контент с помощью 🔥Firecrawl', + firecrawlDoc: 'Документация Firecrawl', + firecrawlDocLink: 'https://docs.dify.ai/guides/knowledge-base/sync-from-website', + options: 'Опции', + crawlSubPage: 'Сканировать подстраницы', + limit: 'Лимит', + maxDepth: 'Максимальная глубина', + excludePaths: 'Исключить пути', + includeOnlyPaths: 'Включить только пути', + extractOnlyMainContent: 'Извлекать только основной контент (без заголовков, навигации, футеров и т. д.)', + exceptionErrorTitle: 'Произошло исключение при запуске задания Firecrawl:', + unknownError: 'Неизвестная ошибка', + totalPageScraped: 'Всего просканировано страниц:', + selectAll: 'Выбрать все', + resetAll: 'Сбросить все', + scrapTimeInfo: 'Всего просканировано {{total}} страниц за {{time}} секунд', + preview: 'Предварительный просмотр', + maxDepthTooltip: 'Максимальная глубина сканирования относительно введенного URL. Глубина 0 сканирует только страницу введенного URL, глубина 1 сканирует URL и все, что находится после введенного URL + один /, и так далее.', + }, + }, + stepTwo: { + segmentation: 'Настройки фрагментации', + auto: 'Автоматически', + autoDescription: 'Автоматически устанавливать правила фрагментации и предварительной обработки. Пользователям, не знакомым с системой, рекомендуется выбрать этот вариант.', + custom: 'Пользовательский', + customDescription: 'Настроить правила фрагментации, длину фрагментов, правила предварительной обработки и т. д.', + separator: 'Идентификатор сегмента', + separatorPlaceholder: 'Например, новая строка (\\\\n) или специальный разделитель (например, "***")', + maxLength: 'Максимальная длина фрагмента', + overlap: 'Перекрытие фрагментов', + overlapTip: 'Установка перекрытия фрагментов может сохранить семантическую связь между ними, улучшая эффект поиска. Рекомендуется установить 10%-25% от максимального размера фрагмента.', + overlapCheck: 'перекрытие фрагментов не должно превышать максимальную длину фрагмента', + rules: 'Правила предварительной обработки текста', + removeExtraSpaces: 'Заменить последовательные пробелы, новые строки и табуляции', + removeUrlEmails: 'Удалить все URL-адреса и адреса электронной почты', + removeStopwords: 'Удалить стоп-слова, такие как "a", "an", "the"', + preview: 'Подтвердить и просмотреть', + reset: 'Сбросить', + indexMode: 'Режим индексации', + qualified: 'Высокое качество', + recommend: 'Рекомендуется', + qualifiedTip: 'Вызов интерфейса встраивания системы по умолчанию для обработки, чтобы обеспечить более высокую точность при запросах пользователей.', + warning: 'Пожалуйста, сначала настройте ключ API поставщика модели.', + click: 'Перейти к настройкам', + economical: 'Экономичный', + economicalTip: 'Используйте автономные векторные движки, индексы ключевых слов и т. д., чтобы снизить точность, не тратя токены', + QATitle: 'Сегментация в формате вопрос-ответ', + QATip: 'Включение этой опции приведет к потреблению большего количества токенов', + QALanguage: 'Сегментировать с помощью', + estimateCost: 'Оценка', + estimateSegment: 'Оценочное количество фрагментов', + segmentCount: 'фрагментов', + calculating: 'Вычисление...', + fileSource: 'Предварительная обработка документов', + notionSource: 'Предварительная обработка страниц', + websiteSource: 'Предварительная обработка веб-сайта', + other: 'и другие ', + fileUnit: ' файлов', + notionUnit: ' страниц', + webpageUnit: ' страниц', + previousStep: 'Предыдущий шаг', + nextStep: 'Сохранить и обработать', + save: 'Сохранить и обработать', + cancel: 'Отмена', + sideTipTitle: 'Зачем нужна фрагментация и предварительная обработка?', + sideTipP1: 'При обработке текстовых данных фрагментация и очистка являются двумя важными этапами предварительной обработки.', + sideTipP2: 'Сегментация разбивает длинный текст на абзацы, чтобы модели могли лучше его понимать. Это улучшает качество и релевантность результатов модели.', + sideTipP3: 'Очистка удаляет ненужные символы и форматы, делая знания более чистыми и легкими для анализа.', + sideTipP4: 'Правильная фрагментация и очистка улучшают производительность модели, обеспечивая более точные и ценные результаты.', + previewTitle: 'Предварительный просмотр', + previewTitleButton: 'Предварительный просмотр', + previewButton: 'Переключение в формат вопрос-ответ', + previewSwitchTipStart: 'Текущий предварительный просмотр фрагмента находится в текстовом формате, переключение на предварительный просмотр в формате вопрос-ответ', + previewSwitchTipEnd: ' потребляет дополнительные токены', + characters: 'символов', + indexSettingTip: 'Чтобы изменить метод индексации, пожалуйста, перейдите в ', + retrievalSettingTip: 'Чтобы изменить метод индексации, пожалуйста, перейдите в ', + datasetSettingLink: 'настройки базы знаний.', + }, + stepThree: { + creationTitle: '🎉 База знаний создана', + creationContent: 'Мы автоматически назвали базу знаний, вы можете изменить ее в любое время', + label: 'Название базы знаний', + additionTitle: '🎉 Документ загружен', + additionP1: 'Документ был загружен в базу знаний', + additionP2: ', вы можете найти его в списке документов базы знаний.', + stop: 'Остановить обработку', + resume: 'Возобновить обработку', + navTo: 'Перейти к документу', + sideTipTitle: 'Что дальше', + sideTipContent: 'После завершения индексации документа база знаний может быть интегрирована в приложение в качестве контекста, вы можете найти настройку контекста на странице prompt orchestration. Вы также можете создать-workflow приложение как отдельный как независимый плагин.', + modelTitle: 'Вы уверены, что хотите остановить встраивание?', + modelContent: 'Если вам нужно будет возобновить обработку позже, вы продолжите с того места, где остановились.', + modelButtonConfirm: 'Подтвердить', + modelButtonCancel: 'Отмена', + }, +} + +export default translation diff --git a/web/i18n/ru-RU/dataset-documents.ts b/web/i18n/ru-RU/dataset-documents.ts new file mode 100644 index 0000000000..b1870fb680 --- /dev/null +++ b/web/i18n/ru-RU/dataset-documents.ts @@ -0,0 +1,352 @@ +const translation = { + list: { + title: 'Документы', + desc: 'Здесь отображаются все файлы базы знаний, и вся база знаний может быть связана с цитатами Dify или проиндексирована с помощью чата.', + addFile: 'Добавить файл', + addPages: 'Добавить страницы', + addUrl: 'Добавить URL', + table: { + header: { + fileName: 'НАЗВАНИЕ ФАЙЛА', + words: 'СЛОВА', + hitCount: 'КОЛИЧЕСТВО ОБРАЩЕНИЙ', + uploadTime: 'ВРЕМЯ ЗАГРУЗКИ', + status: 'СТАТУС', + action: 'ДЕЙСТВИЕ', + }, + rename: 'Переименовать', + name: 'Название', + }, + action: { + uploadFile: 'Загрузить новый файл', + settings: 'Настройки сегментации', + addButton: 'Добавить фрагмент', + add: 'Добавить фрагмент', + batchAdd: 'Пакетное добавление', + archive: 'Архивировать', + unarchive: 'Разархивировать', + delete: 'Удалить', + enableWarning: 'Архивный файл не может быть включен', + sync: 'Синхронизировать', + }, + index: { + enable: 'Включить', + disable: 'Отключить', + all: 'Все', + enableTip: 'Файл может быть проиндексирован', + disableTip: 'Файл не может быть проиндексирован', + }, + status: { + queuing: 'В очереди', + indexing: 'Индексация', + paused: 'Приостановлено', + error: 'Ошибка', + available: 'Доступно', + enabled: 'Включено', + disabled: 'Отключено', + archived: 'Архивировано', + }, + empty: { + title: 'Пока нет документов', + upload: { + tip: 'Вы можете загружать файлы, синхронизировать с веб-сайта или из веб-приложений, таких как Notion, GitHub и т. д.', + }, + sync: { + tip: 'Dify будет периодически загружать файлы из вашего Notion и завершать обработку.', + }, + }, + delete: { + title: 'Вы уверены, что хотите удалить?', + content: 'Если вам нужно будет возобновить обработку позже, вы продолжите с того места, где остановились', + }, + batchModal: { + title: 'Пакетное добавление фрагментов', + csvUploadTitle: 'Перетащите сюда свой CSV-файл или ', + browse: 'обзор', + tip: 'CSV-файл должен соответствовать следующей структуре:', + question: 'вопрос', + answer: 'ответ', + contentTitle: 'содержимое фрагмента', + content: 'содержимое', + template: 'Скачать шаблон здесь', + cancel: 'Отмена', + run: 'Запустить пакет', + runError: 'Ошибка запуска пакета', + processing: 'В процессе пакетной обработки', + completed: 'Импорт завершен', + error: 'Ошибка импорта', + ok: 'ОК', + }, + }, + metadata: { + title: 'Метаданные', + desc: 'Маркировка метаданных для документов позволяет ИИ своевременно получать к ним доступ и раскрывать источник ссылок для пользователей.', + dateTimeFormat: 'D MMMM YYYY, HH:mm', + docTypeSelectTitle: 'Пожалуйста, выберите тип документа', + docTypeChangeTitle: 'Изменить тип документа', + docTypeSelectWarning: + 'Если тип документа будет изменен, заполненные сейчас метаданные больше не будут сохранены', + firstMetaAction: 'Поехали', + placeholder: { + add: 'Добавить ', + select: 'Выбрать ', + }, + source: { + upload_file: 'Загрузить файл', + notion: 'Синхронизировать из Notion', + github: 'Синхронизировать из Github', + }, + type: { + book: 'Книга', + webPage: 'Веб-страница', + paper: 'Статья', + socialMediaPost: 'Пост в социальных сетях', + personalDocument: 'Личный документ', + businessDocument: 'Деловой документ', + IMChat: 'Чат в мессенджере', + wikipediaEntry: 'Статья в Википедии', + notion: 'Синхронизировать из Notion', + github: 'Синхронизировать из Github', + technicalParameters: 'Технические параметры', + }, + field: { + processRule: { + processDoc: 'Обработка документа', + segmentRule: 'Правило фрагментации', + segmentLength: 'Длина фрагментов', + processClean: 'Очистка текста', + }, + book: { + title: 'Название', + language: 'Язык', + author: 'Автор', + publisher: 'Издатель', + publicationDate: 'Дата публикации', + ISBN: 'ISBN', + category: 'Категория', + }, + webPage: { + title: 'Название', + url: 'URL', + language: 'Язык', + authorPublisher: 'Автор/Издатель', + publishDate: 'Дата публикации', + topicsKeywords: 'Темы/Ключевые слова', + description: 'Описание', + }, + paper: { + title: 'Название', + language: 'Язык', + author: 'Автор', + publishDate: 'Дата публикации', + journalConferenceName: 'Название журнала/конференции', + volumeIssuePage: 'Том/Выпуск/Страница', + DOI: 'DOI', + topicsKeywords: 'Темы/Ключевые слова', + abstract: 'Аннотация', + }, + socialMediaPost: { + platform: 'Платформа', + authorUsername: 'Автор/Имя пользователя', + publishDate: 'Дата публикации', + postURL: 'URL поста', + topicsTags: 'Темы/Теги', + }, + personalDocument: { + title: 'Название', + author: 'Автор', + creationDate: 'Дата создания', + lastModifiedDate: 'Дата последнего изменения', + documentType: 'Тип документа', + tagsCategory: 'Теги/Категория', + }, + businessDocument: { + title: 'Название', + author: 'Автор', + creationDate: 'Дата создания', + lastModifiedDate: 'Дата последнего изменения', + documentType: 'Тип документа', + departmentTeam: 'Отдел/Команда', + }, + IMChat: { + chatPlatform: 'Платформа чата', + chatPartiesGroupName: 'Участники чата/Название группы', + participants: 'Участники', + startDate: 'Дата начала', + endDate: 'Дата окончания', + topicsKeywords: 'Темы/Ключевые слова', + fileType: 'Тип файла', + }, + wikipediaEntry: { + title: 'Название', + language: 'Язык', + webpageURL: 'URL веб-страницы', + editorContributor: 'Редактор/Автор', + lastEditDate: 'Дата последнего редактирования', + summaryIntroduction: 'Краткое содержание/Введение', + }, + notion: { + title: 'Название', + language: 'Язык', + author: 'Автор', + createdTime: 'Время создания', + lastModifiedTime: 'Время последнего изменения', + url: 'URL', + tag: 'Тег', + description: 'Описание', + }, + github: { + repoName: 'Название репозитория', + repoDesc: 'Описание репозитория', + repoOwner: 'Владелец репозитория', + fileName: 'Название файла', + filePath: 'Путь к файлу', + programmingLang: 'Язык программирования', + url: 'URL', + license: 'Лицензия', + lastCommitTime: 'Время последнего коммита', + lastCommitAuthor: 'Автор последнего коммита', + }, + originInfo: { + originalFilename: 'Исходное имя файла', + originalFileSize: 'Исходный размер файла', + uploadDate: 'Дата загрузки', + lastUpdateDate: 'Дата последнего обновления', + source: 'Источник', + }, + technicalParameters: { + segmentSpecification: 'Спецификация фрагментов', + segmentLength: 'Длина фрагментов', + avgParagraphLength: 'Средняя длина абзаца', + paragraphs: 'Абзацы', + hitCount: 'Количество обращений', + embeddingTime: 'Время встраивания', + embeddedSpend: 'Потрачено на встраивание', + }, + }, + languageMap: { + zh: 'Китайский', + en: 'Английский', + es: 'Испанский', + fr: 'Французский', + de: 'Немецкий', + ja: 'Японский', + ko: 'Корейский', + ru: 'Русский', + ar: 'Арабский', + pt: 'Португальский', + it: 'Итальянский', + nl: 'Голландский', + pl: 'Польский', + sv: 'Шведский', + tr: 'Турецкий', + he: 'Иврит', + hi: 'Хинди', + da: 'Датский', + fi: 'Финский', + no: 'Норвежский', + hu: 'Венгерский', + el: 'Греческий', + cs: 'Чешский', + th: 'Тайский', + id: 'Индонезийский', + }, + categoryMap: { + book: { + fiction: 'Художественная литература', + biography: 'Биография', + history: 'История', + science: 'Наука', + technology: 'Технологии', + education: 'Образование', + philosophy: 'Философия', + religion: 'Религия', + socialSciences: 'Социальные науки', + art: 'Искусство', + travel: 'Путешествия', + health: 'Здоровье', + selfHelp: 'Самопомощь', + businessEconomics: 'Бизнес/Экономика', + cooking: 'Кулинария', + childrenYoungAdults: 'Детская/Подростковая литература', + comicsGraphicNovels: 'Комиксы/Графические романы', + poetry: 'Поэзия', + drama: 'Драматургия', + other: 'Другое', + }, + personalDoc: { + notes: 'Заметки', + blogDraft: 'Черновик блога', + diary: 'Дневник', + researchReport: 'Научный отчет', + bookExcerpt: 'Отрывок из книги', + schedule: 'Расписание', + list: 'Список', + projectOverview: 'Обзор проекта', + photoCollection: 'Коллекция фотографий', + creativeWriting: 'Творческое письмо', + codeSnippet: 'Фрагмент кода', + designDraft: 'Черновик дизайна', + personalResume: 'Личное резюме', + other: 'Другое', + }, + businessDoc: { + meetingMinutes: 'Протокол собрания', + researchReport: 'Научный отчет', + proposal: 'Предложение', + employeeHandbook: 'Справочник сотрудника', + trainingMaterials: 'Учебные материалы', + requirementsDocument: 'Документ с требованиями', + designDocument: 'Проектный документ', + productSpecification: 'Спецификация продукта', + financialReport: 'Финансовый отчет', + marketAnalysis: 'Анализ рынка', + projectPlan: 'План проекта', + teamStructure: 'Структура команды', + policiesProcedures: 'Политики и процедуры', + contractsAgreements: 'Договоры и соглашения', + emailCorrespondence: 'Переписка по электронной почте', + other: 'Другое', + }, + }, + }, + embedding: { + processing: 'Расчет эмбеддингов...', + paused: 'Расчет эмбеддингов приостановлен', + completed: 'Встраивание завершено', + error: 'Ошибка расчета эмбеддингов', + docName: 'Предварительная обработка документа', + mode: 'Правило сегментации', + segmentLength: 'Длина фрагментов', + textCleaning: 'Предварительная очистка текста', + segments: 'Абзацы', + highQuality: 'Режим высокого качества', + economy: 'Экономичный режим', + estimate: 'Оценочное потребление', + stop: 'Остановить обработку', + resume: 'Возобновить обработку', + automatic: 'Автоматически', + custom: 'Пользовательский', + previewTip: 'Предварительный просмотр абзацев будет доступен после завершения расчета эмбеддингов', + }, + segment: { + paragraphs: 'Абзацы', + keywords: 'Ключевые слова', + addKeyWord: 'Добавить ключевое слово', + keywordError: 'Максимальная длина ключевого слова - 20', + characters: 'символов', + hitCount: 'Количество обращений', + vectorHash: 'Векторный хэш: ', + questionPlaceholder: 'добавьте вопрос здесь', + questionEmpty: 'Вопрос не может быть пустым', + answerPlaceholder: 'добавьте ответ здесь', + answerEmpty: 'Ответ не может быть пустым', + contentPlaceholder: 'добавьте содержимое здесь', + contentEmpty: 'Содержимое не может быть пустым', + newTextSegment: 'Новый текстовый сегмент', + newQaSegment: 'Новый сегмент вопрос-ответ', + delete: 'Удалить этот фрагмент?', + }, +} + +export default translation diff --git a/web/i18n/ru-RU/dataset-hit-testing.ts b/web/i18n/ru-RU/dataset-hit-testing.ts new file mode 100644 index 0000000000..0d3a14a676 --- /dev/null +++ b/web/i18n/ru-RU/dataset-hit-testing.ts @@ -0,0 +1,28 @@ +const translation = { + title: 'Тестирование поиска', + desc: 'Проверьте эффективность поиска в базе знаний на основе заданного текста запроса.', + dateTimeFormat: 'DD.MM.YYYY HH:mm', + recents: 'Недавние', + table: { + header: { + source: 'Источник', + text: 'Текст', + time: 'Время', + }, + }, + input: { + title: 'Исходный текст', + placeholder: 'Пожалуйста, введите текст, рекомендуется использовать короткое повествовательное предложение.', + countWarning: 'До 200 символов.', + indexWarning: 'Только база знаний высокого качества.', + testing: 'Тестирование', + }, + hit: { + title: 'НАЙДЕННЫЕ АБЗАЦЫ', + emptyTip: 'Результаты тестирования поиска будут отображаться здесь', + }, + noRecentTip: 'Здесь нет результатов недавних запросов', + viewChart: 'Посмотреть ВЕКТОРНУЮ ДИАГРАММУ', +} + +export default translation diff --git a/web/i18n/ru-RU/dataset-settings.ts b/web/i18n/ru-RU/dataset-settings.ts new file mode 100644 index 0000000000..f732562d23 --- /dev/null +++ b/web/i18n/ru-RU/dataset-settings.ts @@ -0,0 +1,35 @@ +const translation = { + title: 'Настройки базы знаний', + desc: 'Здесь вы можете изменить свойства и методы работы базы знаний.', + form: { + name: 'Название базы знаний', + namePlaceholder: 'Пожалуйста, введите название базы знаний', + nameError: 'Название не может быть пустым', + desc: 'Описание базы знаний', + descInfo: 'Пожалуйста, напишите четкое текстовое описание, чтобы обрисовать содержание базы знаний. Это описание будет использоваться в качестве основы для сопоставления при выборе из нескольких баз знаний для вывода.', + descPlaceholder: 'Опишите, что находится в этой базе знаний. Подробное описание позволяет ИИ своевременно получать доступ к содержимому базы знаний. Если оставить пустым, Dify будет использовать стратегию поиска по умолчанию.', + descWrite: 'Узнайте, как написать хорошее описание базы знаний.', + permissions: 'Разрешения', + permissionsOnlyMe: 'Только я', + permissionsAllMember: 'Все участники команды', + permissionsInvitedMembers: 'Отдельные участники команды', + me: '(Вы)', + indexMethod: 'Метод индексации', + indexMethodHighQuality: 'Высокое качество', + indexMethodHighQualityTip: 'Вызов модели встраивания для обработки, чтобы обеспечить более высокую точность при запросах пользователей.', + indexMethodEconomy: 'Экономичный', + indexMethodEconomyTip: 'Используйте автономные векторные движки, индексы ключевых слов и т. д., чтобы снизить точность, не тратя токены', + embeddingModel: 'Модель встраивания', + embeddingModelTip: 'Изменить встроенную модель, пожалуйста, перейдите в ', + embeddingModelTipLink: 'Настройки', + retrievalSetting: { + title: 'Настройки поиска', + learnMore: 'Узнать больше', + description: ' о методе поиска.', + longDescription: ' о методе поиска, вы можете изменить это в любое время в настройках базы знаний.', + }, + save: 'Сохранить', + }, +} + +export default translation diff --git a/web/i18n/ru-RU/dataset.ts b/web/i18n/ru-RU/dataset.ts new file mode 100644 index 0000000000..4a7590ad60 --- /dev/null +++ b/web/i18n/ru-RU/dataset.ts @@ -0,0 +1,77 @@ +const translation = { + knowledge: 'База знаний', + documentCount: ' документов', + wordCount: ' тыс. слов', + appCount: ' связанных приложений', + createDataset: 'Создать базу знаний', + createDatasetIntro: 'Импортируйте свои собственные текстовые данные или записывайте данные в режиме реального времени через Webhook для улучшения контекста LLM.', + deleteDatasetConfirmTitle: 'Удалить эту базу знаний?', + deleteDatasetConfirmContent: + 'Удаление базы знаний необратимо. Пользователи больше не смогут получить доступ к вашей базе знаний, и все настройки подсказок и журналы будут безвозвратно удалены.', + datasetUsedByApp: 'База знаний используется некоторыми приложениями. Приложения больше не смогут использовать эту базу знаний, и все настройки подсказок и журналы будут безвозвратно удалены.', + datasetDeleted: 'База знаний удалена', + datasetDeleteFailed: 'Не удалось удалить базу знаний', + didYouKnow: 'Знаете ли вы?', + intro1: 'Базу знаний можно интегрировать в приложение Dify ', + intro2: 'в качестве контекста', + intro3: ',', + intro4: 'или ее ', + intro5: 'можно создать', + intro6: ' как отдельный плагин индекса ChatGPT для публикации', + unavailable: 'Недоступно', + unavailableTip: 'Модель встраивания недоступна, необходимо настроить модель встраивания по умолчанию', + datasets: 'БАЗЫ ЗНАНИЙ', + datasetsApi: 'ДОСТУП К API', + retrieval: { + semantic_search: { + title: 'Векторный поиск', + description: 'Создайте встраивания запросов и найдите фрагмент текста, наиболее похожий на его векторное представление.', + }, + full_text_search: { + title: 'Полнотекстовый поиск', + description: 'Индексируйте все термины в документе, позволяя пользователям искать любой термин и извлекать соответствующий фрагмент текста, содержащий эти термины.', + }, + hybrid_search: { + title: 'Гибридный поиск', + description: 'Выполняйте полнотекстовый поиск и векторный поиск одновременно, переранжируйте, чтобы выбрать наилучшее соответствие запросу пользователя. Пользователи могут выбрать установку весов или настройку модели переранжирования.', + recommend: 'Рекомендуется', + }, + invertedIndex: { + title: 'Инвертированный индекс', + description: 'Инвертированный индекс - это структура, используемая для эффективного поиска. Организованный по терминам, каждый термин указывает на документы или веб-страницы, содержащие его.', + }, + change: 'Изменить', + changeRetrievalMethod: 'Изменить метод поиска', + }, + docsFailedNotice: 'документов не удалось проиндексировать', + retry: 'Повторить попытку', + indexingTechnique: { + high_quality: 'HQ', + economy: 'ECO', + }, + indexingMethod: { + semantic_search: 'ВЕКТОР', + full_text_search: 'ПОЛНЫЙ ТЕКСТ', + hybrid_search: 'ГИБРИД', + invertedIndex: 'ИНВЕРТИРОВАННЫЙ', + }, + mixtureHighQualityAndEconomicTip: 'Для смешивания высококачественных и экономичных баз знаний требуется модель переранжирования.', + inconsistentEmbeddingModelTip: 'Модель переранжирования требуется, если модели встраивания выбранных баз знаний несовместимы.', + retrievalSettings: 'Настройки поиска', + rerankSettings: 'Настройки переранжирования', + weightedScore: { + title: 'Взвешенная оценка', + description: 'Регулируя назначенные веса, эта стратегия переранжирования определяет, следует ли отдавать приоритет семантическому или ключевому соответствию.', + semanticFirst: 'Семантика в первую очередь', + keywordFirst: 'Ключевые слова в первую очередь', + customized: 'Настраиваемый', + semantic: 'Семантика', + keyword: 'Ключевые слова', + }, + nTo1RetrievalLegacy: 'Поиск N-к-1 будет официально прекращен с сентября. Рекомендуется использовать новейший многопутный поиск для получения лучших результатов.', + nTo1RetrievalLegacyLink: 'Узнать больше', + nTo1RetrievalLegacyLinkText: ' Поиск N-к-1 будет официально прекращен в сентябре.', + defaultRetrievalTip: 'По умолчанию используется многоканальная проверка. Знания извлекаются из нескольких баз знаний, а затем повторно ранжируются.', +} + +export default translation diff --git a/web/i18n/ru-RU/explore.ts b/web/i18n/ru-RU/explore.ts new file mode 100644 index 0000000000..6c0b41f7d4 --- /dev/null +++ b/web/i18n/ru-RU/explore.ts @@ -0,0 +1,41 @@ +const translation = { + title: 'Обзор', + sidebar: { + discovery: 'Открытия', + chat: 'Чат', + workspace: 'Рабочее пространство', + action: { + pin: 'Закрепить', + unpin: 'Открепить', + rename: 'Переименовать', + delete: 'Удалить', + }, + delete: { + title: 'Удалить приложение', + content: 'Вы уверены, что хотите удалить это приложение?', + }, + }, + apps: { + title: 'Обзор приложений от Dify', + description: 'Используйте эти шаблонные приложения мгновенно или настройте свои собственные приложения на основе шаблонов.', + allCategories: 'Рекомендуемые', + }, + appCard: { + addToWorkspace: 'Добавить в рабочее пространство', + customize: 'Настроить', + }, + appCustomize: { + title: 'Создать приложение из {{name}}', + subTitle: 'Значок и название приложения', + nameRequired: 'Название приложения обязательно', + }, + category: { + Assistant: 'Ассистент', + Writing: 'Написание', + Translate: 'Перевод', + Programming: 'Программирование', + HR: 'HR', + }, +} + +export default translation diff --git a/web/i18n/ru-RU/layout.ts b/web/i18n/ru-RU/layout.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/ru-RU/layout.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/ru-RU/login.ts b/web/i18n/ru-RU/login.ts new file mode 100644 index 0000000000..81918745dd --- /dev/null +++ b/web/i18n/ru-RU/login.ts @@ -0,0 +1,75 @@ +const translation = { + pageTitle: 'Привет, давайте начнем!👋', + welcome: 'Добро пожаловать в Dify, пожалуйста, войдите, чтобы продолжить.', + email: 'Адрес электронной почты', + emailPlaceholder: 'Ваш адрес электронной почты', + password: 'Пароль', + passwordPlaceholder: 'Ваш пароль', + name: 'Имя пользователя', + namePlaceholder: 'Ваше имя пользователя', + forget: 'Забыли пароль?', + signBtn: 'Войти', + sso: 'Продолжить с SSO', + installBtn: 'Настроить', + setAdminAccount: 'Настройка учетной записи администратора', + setAdminAccountDesc: 'Максимальные привилегии для учетной записи администратора, которые можно использовать для создания приложений, управления поставщиками LLM и т. д.', + createAndSignIn: 'Создать и войти', + oneMoreStep: 'Еще один шаг', + createSample: 'На основе этой информации мы создадим для вас пример приложения', + invitationCode: 'Пригласительный код', + invitationCodePlaceholder: 'Ваш пригласительный код', + interfaceLanguage: 'Язык интерфейса', + timezone: 'Часовой пояс', + go: 'Перейти к Dify', + sendUsMail: 'Отправьте нам по электронной почте свое представление, и мы обработаем запрос на приглашение.', + acceptPP: 'Я прочитал и принимаю политику конфиденциальности', + reset: 'Пожалуйста, выполните следующую команду, чтобы сбросить пароль', + withGitHub: 'Продолжить с GitHub', + withGoogle: 'Продолжить с Google', + rightTitle: 'Раскройте весь потенциал LLM', + rightDesc: 'Без труда создавайте визуально привлекательные, работоспособные и улучшаемые приложения ИИ.', + tos: 'Условия обслуживания', + pp: 'Политика конфиденциальности', + tosDesc: 'Регистрируясь, вы соглашаетесь с нашими', + goToInit: 'Если вы не инициализировали учетную запись, перейдите на страницу инициализации', + dontHave: 'Нет?', + invalidInvitationCode: 'Неверный пригласительный код', + accountAlreadyInited: 'Учетная запись уже инициализирована', + forgotPassword: 'Забыли пароль?', + resetLinkSent: 'Ссылка для сброса отправлена', + sendResetLink: 'Отправить ссылку для сброса', + backToSignIn: 'Вернуться к входу', + forgotPasswordDesc: 'Пожалуйста, введите свой адрес электронной почты, чтобы сбросить пароль. Мы отправим вам электронное письмо с инструкциями о том, как сбросить пароль.', + checkEmailForResetLink: 'Пожалуйста, проверьте свою электронную почту на наличие ссылки для сброса пароля. Если она не появится в течение нескольких минут, обязательно проверьте папку со спамом.', + passwordChanged: 'Войдите сейчас', + changePassword: 'Изменить пароль', + changePasswordTip: 'Пожалуйста, введите новый пароль для своей учетной записи', + invalidToken: 'Неверный или просроченный токен', + confirmPassword: 'Подтвердите пароль', + confirmPasswordPlaceholder: 'Подтвердите свой новый пароль', + passwordChangedTip: 'Ваш пароль был успешно изменен', + error: { + emailEmpty: 'Адрес электронной почты обязателен', + emailInValid: 'Пожалуйста, введите действительный адрес электронной почты', + nameEmpty: 'Имя обязательно', + passwordEmpty: 'Пароль обязателен', + passwordLengthInValid: 'Пароль должен содержать не менее 8 символов', + passwordInvalid: 'Пароль должен содержать буквы и цифры, а длина должна быть больше 8', + }, + license: { + tip: 'Перед запуском Dify Community Edition ознакомьтесь с лицензией GitHub', + link: 'Лицензия с открытым исходным кодом', + }, + join: 'Присоединиться', + joinTipStart: 'Приглашаем вас присоединиться к', + joinTipEnd: 'команде на Dify', + invalid: 'Ссылка истекла', + explore: 'Изучить Dify', + activatedTipStart: 'Вы присоединились к команде', + activatedTipEnd: '', + activated: 'Войдите сейчас', + adminInitPassword: 'Пароль инициализации администратора', + validate: 'Проверить', +} + +export default translation diff --git a/web/i18n/ru-RU/register.ts b/web/i18n/ru-RU/register.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/ru-RU/register.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/ru-RU/run-log.ts b/web/i18n/ru-RU/run-log.ts new file mode 100644 index 0000000000..2099d6794f --- /dev/null +++ b/web/i18n/ru-RU/run-log.ts @@ -0,0 +1,29 @@ +const translation = { + input: 'ВВОД', + result: 'РЕЗУЛЬТАТ', + detail: 'ДЕТАЛИ', + tracing: 'ТРАССИРОВКА', + resultPanel: { + status: 'СТАТУС', + time: 'ПРОШЕДШЕЕ ВРЕМЯ', + tokens: 'ВСЕГО ТОКЕНОВ', + }, + meta: { + title: 'МЕТАДАННЫЕ', + status: 'Статус', + version: 'Версия', + executor: 'Исполнитель', + startTime: 'Время начала', + time: 'Прошедшее время', + tokens: 'Всего токенов', + steps: 'Шаги выполнения', + }, + resultEmpty: { + title: 'Этот запуск выводит только формат JSON,', + tipLeft: 'пожалуйста, перейдите на ', + link: 'панель деталей', + tipRight: ' чтобы просмотреть его.', + }, +} + +export default translation diff --git a/web/i18n/ru-RU/share-app.ts b/web/i18n/ru-RU/share-app.ts new file mode 100644 index 0000000000..f0166b26f1 --- /dev/null +++ b/web/i18n/ru-RU/share-app.ts @@ -0,0 +1,74 @@ +const translation = { + common: { + welcome: '', + appUnavailable: 'Приложение недоступно', + appUnknownError: 'Приложение недоступно', + }, + chat: { + newChat: 'Новый чат', + pinnedTitle: 'Закрепленные', + unpinnedTitle: 'Чаты', + newChatDefaultName: 'Новый разговор', + resetChat: 'Сбросить разговор', + poweredBy: 'Работает на', + prompt: 'Подсказка', + privatePromptConfigTitle: 'Настройки разговора', + publicPromptConfigTitle: 'Начальная подсказка', + configStatusDes: 'Перед началом вы можете изменить настройки разговора', + configDisabled: + 'Для этого сеанса использовались настройки предыдущего сеанса.', + startChat: 'Начать чат', + privacyPolicyLeft: + 'Пожалуйста, ознакомьтесь с ', + privacyPolicyMiddle: + 'политикой конфиденциальности', + privacyPolicyRight: + ', предоставленной разработчиком приложения.', + deleteConversation: { + title: 'Удалить разговор', + content: 'Вы уверены, что хотите удалить этот разговор?', + }, + tryToSolve: 'Попробуйте решить', + temporarySystemIssue: 'Извините, временная проблема с системой.', + }, + generation: { + tabs: { + create: 'Запустить один раз', + batch: 'Запустить пакетно', + saved: 'Сохраненные', + }, + savedNoData: { + title: 'Вы еще не сохранили ни одного результата!', + description: 'Начните генерировать контент, и вы найдете свои сохраненные результаты здесь.', + startCreateContent: 'Начать создавать контент', + }, + title: 'Завершение ИИ', + queryTitle: 'Содержимое запроса', + completionResult: 'Результат завершения', + queryPlaceholder: 'Напишите содержимое вашего запроса...', + run: 'Выполнить', + copy: 'Копировать', + resultTitle: 'Завершение ИИ', + noData: 'ИИ даст вам то, что вы хотите, здесь.', + csvUploadTitle: 'Перетащите сюда свой CSV-файл или ', + browse: 'обзор', + csvStructureTitle: 'CSV-файл должен соответствовать следующей структуре:', + downloadTemplate: 'Скачать шаблон здесь', + field: 'Поле', + batchFailed: { + info: '{{num}} неудачных выполнений', + retry: 'Повторить попытку', + outputPlaceholder: 'Нет выходного содержимого', + }, + errorMsg: { + empty: 'Пожалуйста, введите содержимое в загруженный файл.', + fileStructNotMatch: 'Загруженный CSV-файл не соответствует структуре.', + emptyLine: 'Строка {{rowIndex}} пуста', + invalidLine: 'Строка {{rowIndex}}: значение {{varName}} не может быть пустым', + moreThanMaxLengthLine: 'Строка {{rowIndex}}: значение {{varName}} не может превышать {{maxLength}} символов', + atLeastOne: 'Пожалуйста, введите хотя бы одну строку в загруженный файл.', + }, + }, +} + +export default translation diff --git a/web/i18n/ru-RU/tools.ts b/web/i18n/ru-RU/tools.ts new file mode 100644 index 0000000000..e0dfd571b2 --- /dev/null +++ b/web/i18n/ru-RU/tools.ts @@ -0,0 +1,153 @@ +const translation = { + title: 'Инструменты', + createCustomTool: 'Создать пользовательский инструмент', + customToolTip: 'Узнать больше о пользовательских инструментах Dify', + type: { + all: 'Все', + builtIn: 'Встроенные', + custom: 'Пользовательские', + workflow: 'Рабочий процесс', + }, + contribute: { + line1: 'Я заинтересован в', + line2: 'внесении инструментов в Dify.', + viewGuide: 'Посмотреть руководство', + }, + author: 'Автор', + auth: { + unauthorized: 'Авторизовать', + authorized: 'Авторизовано', + setup: 'Настроить авторизацию для использования', + setupModalTitle: 'Настроить авторизацию', + setupModalTitleDescription: 'После настройки учетных данных все участники рабочего пространства смогут использовать этот инструмент при оркестровке приложений.', + }, + includeToolNum: 'Включено {{num}} инструментов', + addTool: 'Добавить инструмент', + addToolModal: { + type: 'тип', + category: 'категория', + add: 'добавить', + added: 'добавлено', + manageInTools: 'Управлять в инструментах', + emptyTitle: 'Нет доступных инструментов рабочего процесса', + emptyTip: 'Перейдите в "Рабочий процесс -> Опубликовать как инструмент"', + }, + createTool: { + title: 'Создать пользовательский инструмент', + editAction: 'Настроить', + editTitle: 'Редактировать пользовательский инструмент', + name: 'Название', + toolNamePlaceHolder: 'Введите название инструмента', + nameForToolCall: 'Название вызова инструмента', + nameForToolCallPlaceHolder: 'Используется для машинного распознавания, например getCurrentWeather, list_pets', + nameForToolCallTip: 'Поддерживаются только цифры, буквы и подчеркивания.', + description: 'Описание', + descriptionPlaceholder: 'Краткое описание назначения инструмента, например, получить температуру для определенного местоположения.', + schema: 'Схема', + schemaPlaceHolder: 'Введите свою схему OpenAPI здесь', + viewSchemaSpec: 'Посмотреть спецификацию OpenAPI-Swagger', + importFromUrl: 'Импортировать из URL', + importFromUrlPlaceHolder: 'https://...', + urlError: 'Пожалуйста, введите действительный URL', + examples: 'Примеры', + exampleOptions: { + json: 'Погода (JSON)', + yaml: 'Зоомагазин (YAML)', + blankTemplate: 'Пустой шаблон', + }, + availableTools: { + title: 'Доступные инструменты', + name: 'Название', + description: 'Описание', + method: 'Метод', + path: 'Путь', + action: 'Действия', + test: 'Тест', + }, + authMethod: { + title: 'Метод авторизации', + type: 'Тип авторизации', + keyTooltip: 'Ключ заголовка HTTP, вы можете оставить его как "Authorization", если не знаете, что это такое, или установить его на пользовательское значение', + types: { + none: 'Нет', + api_key: 'Ключ API', + apiKeyPlaceholder: 'Название заголовка HTTP для ключа API', + apiValuePlaceholder: 'Введите ключ API', + }, + key: 'Ключ', + value: 'Значение', + }, + authHeaderPrefix: { + title: 'Тип авторизации', + types: { + basic: 'Базовый', + bearer: 'Bearer', + custom: 'Пользовательский', + }, + }, + privacyPolicy: 'Политика конфиденциальности', + privacyPolicyPlaceholder: 'Пожалуйста, введите политику конфиденциальности', + toolInput: { + title: 'Входные данные инструмента', + name: 'Название', + required: 'Обязательно', + method: 'Метод', + methodSetting: 'Настройка', + methodSettingTip: 'Пользователь заполняет конфигурацию инструмента', + methodParameter: 'Параметр', + methodParameterTip: 'LLM заполняет во время вывода', + label: 'Теги', + labelPlaceholder: 'Выберите теги (необязательно)', + description: 'Описание', + descriptionPlaceholder: 'Описание значения параметра', + }, + customDisclaimer: 'Пользовательский отказ от ответственности', + customDisclaimerPlaceholder: 'Пожалуйста, введите пользовательский отказ от ответственности', + confirmTitle: 'Подтвердить сохранение?', + confirmTip: 'Приложения, использующие этот инструмент, будут затронуты', + deleteToolConfirmTitle: 'Удалить этот инструмент?', + deleteToolConfirmContent: 'Удаление инструмента необратимо. Пользователи больше не смогут получить доступ к вашему инструменту.', + }, + test: { + title: 'Тест', + parametersValue: 'Параметры и значение', + parameters: 'Параметры', + value: 'Значение', + testResult: 'Результаты теста', + testResultPlaceholder: 'Результат теста будет отображаться здесь', + }, + thought: { + using: 'Использование', + used: 'Использовано', + requestTitle: 'Запрос к', + responseTitle: 'Ответ от', + }, + setBuiltInTools: { + info: 'Информация', + setting: 'Настройка', + toolDescription: 'Описание инструмента', + parameters: 'параметры', + string: 'строка', + number: 'число', + required: 'Обязательно', + infoAndSetting: 'Информация и настройки', + }, + noCustomTool: { + title: 'Нет пользовательских инструментов!', + content: 'Добавьте и управляйте своими пользовательскими инструментами здесь для создания приложений ИИ.', + createTool: 'Создать инструмент', + }, + noSearchRes: { + title: 'Извините, результаты не найдены!', + content: 'Мы не смогли найти никаких инструментов, соответствующих вашему поиску.', + reset: 'Сбросить поиск', + }, + builtInPromptTitle: 'Подсказка', + toolRemoved: 'Инструмент удален', + notAuthorized: 'Инструмент не авторизован', + howToGet: 'Как получить', + openInStudio: 'Открыть в Studio', + toolNameUsageTip: 'Название вызова инструмента для рассуждений агента и подсказок', +} + +export default translation diff --git a/web/i18n/ru-RU/workflow.ts b/web/i18n/ru-RU/workflow.ts new file mode 100644 index 0000000000..b31b798bd3 --- /dev/null +++ b/web/i18n/ru-RU/workflow.ts @@ -0,0 +1,541 @@ +const translation = { + common: { + undo: 'Отменить', + redo: 'Повторить', + editing: 'Редактирование', + autoSaved: 'Автосохранено', + unpublished: 'Не опубликовано', + published: 'Опубликовано', + publish: 'Опубликовать', + update: 'Обновить', + run: 'Запустить', + running: 'Выполняется', + inRunMode: 'В режиме выполнения', + inPreview: 'В режиме предпросмотра', + inPreviewMode: 'В режиме предпросмотра', + preview: 'Предпросмотр', + viewRunHistory: 'Посмотреть историю запусков', + runHistory: 'История запусков', + goBackToEdit: 'Вернуться к редактору', + conversationLog: 'Журнал разговоров', + features: 'Функции', + debugAndPreview: 'Предпросмотр', + restart: 'Перезапустить', + currentDraft: 'Текущий черновик', + currentDraftUnpublished: 'Текущий черновик не опубликован', + latestPublished: 'Последняя опубликованная версия', + publishedAt: 'Опубликовано', + restore: 'Восстановить', + runApp: 'Запустить приложение', + batchRunApp: 'Пакетный запуск приложения', + accessAPIReference: 'Доступ к справочнику API', + embedIntoSite: 'Встроить на сайт', + addTitle: 'Добавить заголовок...', + addDescription: 'Добавить описание...', + noVar: 'Нет переменной', + searchVar: 'Поиск переменной', + variableNamePlaceholder: 'Имя переменной', + setVarValuePlaceholder: 'Установить значение переменной', + needConnectTip: 'Этот шаг ни к чему не подключен', + maxTreeDepth: 'Максимальный предел {{depth}} узлов на ветку', + needEndNode: 'Необходимо добавить блок "Конец"', + needAnswerNode: 'Необходимо добавить блок "Ответ"', + workflowProcess: 'Процесс рабочего процесса', + notRunning: 'Еще не запущено', + previewPlaceholder: 'Введите текст в поле ниже, чтобы начать отладку чат-бота', + effectVarConfirm: { + title: 'Удалить переменную', + content: 'Переменная используется в других узлах. Вы все еще хотите удалить ее?', + }, + insertVarTip: 'Нажмите клавишу "/" чтобы быстро вставить', + processData: 'Обработка данных', + input: 'Вход', + output: 'Выход', + jinjaEditorPlaceholder: 'Введите "/" или "{" для вставки переменной', + viewOnly: 'Только просмотр', + showRunHistory: 'Показать историю запусков', + enableJinja: 'Включить поддержку шаблонов Jinja', + learnMore: 'Узнать больше', + copy: 'Копировать', + duplicate: 'Дублировать', + addBlock: 'Добавить блок', + pasteHere: 'Вставить сюда', + pointerMode: 'Режим указателя', + handMode: 'Режим руки', + model: 'Модель', + workflowAsTool: 'Рабочий процесс как инструмент', + configureRequired: 'Требуется настройка', + configure: 'Настроить', + manageInTools: 'Управление в инструментах', + workflowAsToolTip: 'После обновления рабочего процесса требуется перенастройка инструмента.', + viewDetailInTracingPanel: 'Посмотреть подробности', + syncingData: 'Синхронизация данных, всего несколько секунд.', + importDSL: 'Импортировать DSL', + importDSLTip: 'Текущий черновик будет перезаписан. Экспортируйте рабочий процесс в качестве резервной копии перед импортом.', + backupCurrentDraft: 'Резервное копирование текущего черновика', + chooseDSL: 'Выберите файл DSL(yml)', + overwriteAndImport: 'Перезаписать и импортировать', + importFailure: 'Ошибка импорта', + importSuccess: 'Импорт успешно завершен', + }, + env: { + envPanelTitle: 'Переменные среды', + envDescription: 'Переменные среды могут использоваться для хранения конфиденциальной информации и учетных данных. Они доступны только для чтения и могут быть отделены от файла DSL во время экспорта.', + envPanelButton: 'Добавить переменную', + modal: { + title: 'Добавить переменную среды', + editTitle: 'Редактировать переменную среды', + type: 'Тип', + name: 'Имя', + namePlaceholder: 'Имя переменной среды', + value: 'Значение', + valuePlaceholder: 'Значение переменной среды', + secretTip: 'Используется для определения конфиденциальной информации или данных, с настройками DSL, настроенными для предотвращения утечки.', + }, + export: { + title: 'Экспортировать секретные переменные среды?', + checkbox: 'Экспортировать секретные значения', + ignore: 'Экспортировать DSL', + export: 'Экспортировать DSL с секретными значениями ', + }, + }, + chatVariable: { + panelTitle: 'Переменные разговора', + panelDescription: 'Переменные разговора используются для хранения интерактивной информации, которую LLM необходимо запомнить, включая историю разговоров, загруженные файлы, пользовательские настройки. Они доступны для чтения и записи. ', + docLink: 'Посетите нашу документацию, чтобы узнать больше.', + button: 'Добавить переменную', + modal: { + title: 'Добавить переменную разговора', + editTitle: 'Редактировать переменную разговора', + name: 'Имя', + namePlaceholder: 'Имя переменной', + type: 'Тип', + value: 'Значение по умолчанию', + valuePlaceholder: 'Значение по умолчанию, оставьте пустым, чтобы не устанавливать', + description: 'Описание', + descriptionPlaceholder: 'Опишите переменную', + editInJSON: 'Редактировать в JSON', + oneByOne: 'Добавлять по одному', + editInForm: 'Редактировать в форме', + arrayValue: 'Значение', + addArrayValue: 'Добавить значение', + objectKey: 'Ключ', + objectType: 'Тип', + objectValue: 'Значение по умолчанию', + }, + storedContent: 'Сохраненный контент', + updatedAt: 'Обновлено в ', + }, + changeHistory: { + title: 'История изменений', + placeholder: 'Вы еще ничего не изменили', + clearHistory: 'Очистить историю', + hint: 'Подсказка', + hintText: 'Ваши действия по редактированию отслеживаются в истории изменений, которая хранится на вашем устройстве в течение этого сеанса. Эта история будет очищена, когда вы покинете редактор.', + stepBackward_one: '{{count}} шаг назад', + stepBackward_other: '{{count}} шагов назад', + stepForward_one: '{{count}} шаг вперед', + stepForward_other: '{{count}} шагов вперед', + sessionStart: 'Начало сеанса', + currentState: 'Текущее состояние', + nodeTitleChange: 'Изменено название блока', + nodeDescriptionChange: 'Изменено описание блока', + nodeDragStop: 'Блок перемещен', + nodeChange: 'Блок изменен', + nodeConnect: 'Блок подключен', + nodePaste: 'Блок вставлен', + nodeDelete: 'Блок удален', + nodeAdd: 'Блок добавлен', + nodeResize: 'Размер блока изменен', + noteAdd: 'Заметка добавлена', + noteChange: 'Заметка изменена', + noteDelete: 'Заметка удалена', + edgeDelete: 'Блок отключен', + }, + errorMsg: { + fieldRequired: '{{field}} обязательно для заполнения', + authRequired: 'Требуется авторизация', + invalidJson: '{{field}} неверный JSON', + fields: { + variable: 'Имя переменной', + variableValue: 'Значение переменной', + code: 'Код', + model: 'Модель', + rerankModel: 'Модель переранжирования', + }, + invalidVariable: 'Неверная переменная', + }, + singleRun: { + testRun: 'Тестовый запуск ', + startRun: 'Начать запуск', + running: 'Выполняется', + testRunIteration: 'Итерация тестового запуска', + back: 'Назад', + iteration: 'Итерация', + }, + tabs: { + 'searchBlock': 'Поиск блока', + 'blocks': 'Блоки', + 'searchTool': 'Поиск инструмента', + 'tools': 'Инструменты', + 'allTool': 'Все', + 'builtInTool': 'Встроенные', + 'customTool': 'Пользовательские', + 'workflowTool': 'Рабочий процесс', + 'question-understand': 'Понимание вопроса', + 'logic': 'Логика', + 'transform': 'Преобразование', + 'utilities': 'Утилиты', + 'noResult': 'Ничего не найдено', + }, + blocks: { + 'start': 'Начало', + 'end': 'Конец', + 'answer': 'Ответ', + 'llm': 'LLM', + 'knowledge-retrieval': 'Поиск знаний', + 'question-classifier': 'Классификатор вопросов', + 'if-else': 'ЕСЛИ/ИНАЧЕ', + 'code': 'Код', + 'template-transform': 'Шаблон', + 'http-request': 'HTTP-запрос', + 'variable-assigner': 'Агрегатор переменных', + 'variable-aggregator': 'Агрегатор переменных', + 'assigner': 'Назначение переменной', + 'iteration-start': 'Начало итерации', + 'iteration': 'Итерация', + 'parameter-extractor': 'Извлечение параметров', + }, + blocksAbout: { + 'start': 'Определите начальные параметры для запуска рабочего процесса', + 'end': 'Определите конец и тип результата рабочего процесса', + 'answer': 'Определите содержимое ответа в чате', + 'llm': 'Вызов больших языковых моделей для ответа на вопросы или обработки естественного языка', + 'knowledge-retrieval': 'Позволяет запрашивать текстовый контент, связанный с вопросами пользователей, из базы знаний', + 'question-classifier': 'Определите условия классификации вопросов пользователей, LLM может определить, как будет развиваться разговор на основе описания классификации', + 'if-else': 'Позволяет разделить рабочий процесс на две ветки на основе условий if/else', + 'code': 'Выполните фрагмент кода Python или NodeJS для реализации пользовательской логики', + 'template-transform': 'Преобразование данных в строку с использованием синтаксиса шаблонов Jinja', + 'http-request': 'Разрешить отправку запросов на сервер по протоколу HTTP', + 'variable-assigner': 'Объединение переменных из нескольких ветвей в одну переменную для унифицированной настройки подчиненных узлов.', + 'assigner': 'Узел назначения переменной используется для назначения значений записываемым переменным (например, переменным разговора).', + 'variable-aggregator': 'Объединение переменных из нескольких ветвей в одну переменную для унифицированной настройки подчиненных узлов.', + 'iteration': 'Выполнение нескольких шагов над объектом списка до тех пор, пока не будут выведены все результаты.', + 'parameter-extractor': 'Используйте LLM для извлечения структурированных параметров из естественного языка для вызова инструментов или HTTP-запросов.', + }, + operator: { + zoomIn: 'Увеличить', + zoomOut: 'Уменьшить', + zoomTo50: 'Масштаб 50%', + zoomTo100: 'Масштаб 100%', + zoomToFit: 'По размеру', + }, + panel: { + userInputField: 'Поле ввода пользователя', + changeBlock: 'Изменить блок', + helpLink: 'Ссылка на справку', + about: 'О программе', + createdBy: 'Создано ', + nextStep: 'Следующий шаг', + addNextStep: 'Добавить следующий блок в этот рабочий процесс', + selectNextStep: 'Выбрать следующий блок', + runThisStep: 'Выполнить этот шаг', + checklist: 'Контрольный список', + checklistTip: 'Убедитесь, что все проблемы решены перед публикацией', + checklistResolved: 'Все проблемы решены', + organizeBlocks: 'Организовать блоки', + change: 'Изменить', + optional: '(необязательно)', + }, + nodes: { + common: { + outputVars: 'Выходные переменные', + insertVarTip: 'Вставить переменную', + memory: { + memory: 'Память', + memoryTip: 'Настройки памяти чата', + windowSize: 'Размер окна', + conversationRoleName: 'Имя роли разговора', + user: 'Префикс пользователя', + assistant: 'Префикс помощника', + }, + memories: { + title: 'Воспоминания', + tip: 'Память чата', + builtIn: 'Встроенные', + }, + }, + start: { + required: 'обязательно', + inputField: 'Поле ввода', + builtInVar: 'Встроенные переменные', + outputVars: { + query: 'Ввод пользователя', + memories: { + des: 'История разговоров', + type: 'тип сообщения', + content: 'содержимое сообщения', + }, + files: 'Список файлов', + }, + noVarTip: 'Установите входные данные, которые можно использовать в рабочем процессе', + }, + end: { + outputs: 'Выходы', + output: { + type: 'тип вывода', + variable: 'выходная переменная', + }, + type: { + 'none': 'Нет', + 'plain-text': 'Простой текст', + 'structured': 'Структурированный', + }, + }, + answer: { + answer: 'Ответ', + outputVars: 'Выходные переменные', + }, + llm: { + model: 'модель', + variables: 'переменные', + context: 'контекст', + contextTooltip: 'Вы можете импортировать знания как контекст', + notSetContextInPromptTip: 'Чтобы включить функцию контекста, пожалуйста, заполните переменную контекста в PROMPT.', + prompt: 'подсказка', + roleDescription: { + system: 'Дайте высокоуровневые инструкции для разговора', + user: 'Предоставьте инструкции, запросы или любой текстовый ввод для модели', + assistant: 'Ответы модели на основе сообщений пользователя', + }, + addMessage: 'Добавить сообщение', + vision: 'зрение', + files: 'Файлы', + resolution: { + name: 'Разрешение', + high: 'Высокое', + low: 'Низкое', + }, + outputVars: { + output: 'Создать контент', + usage: 'Информация об использовании модели', + }, + singleRun: { + variable: 'Переменная', + }, + sysQueryInUser: 'sys.query в сообщении пользователя обязателен', + }, + knowledgeRetrieval: { + queryVariable: 'Переменная запроса', + knowledge: 'Знания', + outputVars: { + output: 'Извлеченные сегментированные данные', + content: 'Сегментированный контент', + title: 'Сегментированный заголовок', + icon: 'Сегментированный значок', + url: 'Сегментированный URL', + metadata: 'Другие метаданные', + }, + }, + http: { + inputVars: 'Входные переменные', + api: 'API', + apiPlaceholder: 'Введите URL, введите "/" для вставки переменной', + notStartWithHttp: 'API должен начинаться с http:// или https://', + key: 'Ключ', + value: 'Значение', + bulkEdit: 'Массовое редактирование', + keyValueEdit: 'Редактирование ключа-значения', + headers: 'Заголовки', + params: 'Параметры', + body: 'Тело', + outputVars: { + body: 'Содержимое ответа', + statusCode: 'Код состояния ответа', + headers: 'Список заголовков ответа JSON', + files: 'Список файлов', + }, + authorization: { + 'authorization': 'Авторизация', + 'authorizationType': 'Тип авторизации', + 'no-auth': 'Нет', + 'api-key': 'API-ключ', + 'auth-type': 'Тип аутентификации', + 'basic': 'Базовая', + 'bearer': 'Bearer', + 'custom': 'Пользовательская', + 'api-key-title': 'API-ключ', + 'header': 'Заголовок', + }, + insertVarPlaceholder: 'введите "/" для вставки переменной', + timeout: { + title: 'Тайм-аут', + connectLabel: 'Тайм-аут подключения', + connectPlaceholder: 'Введите тайм-аут подключения в секундах', + readLabel: 'Тайм-аут чтения', + readPlaceholder: 'Введите тайм-аут чтения в секундах', + writeLabel: 'Тайм-аут записи', + writePlaceholder: 'Введите тайм-аут записи в секундах', + }, + }, + code: { + inputVars: 'Входные переменные', + outputVars: 'Выходные переменные', + advancedDependencies: 'Расширенные зависимости', + advancedDependenciesTip: 'Добавьте сюда некоторые предварительно загруженные зависимости, которые занимают больше времени для потребления или не являются встроенными по умолчанию', + searchDependencies: 'Поиск зависимостей', + }, + templateTransform: { + inputVars: 'Входные переменные', + code: 'Код', + codeSupportTip: 'Поддерживает только Jinja2', + outputVars: { + output: 'Преобразованный контент', + }, + }, + ifElse: { + if: 'Если', + else: 'Иначе', + elseDescription: 'Используется для определения логики, которая должна быть выполнена, когда условие if не выполняется.', + and: 'и', + or: 'или', + operator: 'Оператор', + notSetVariable: 'Пожалуйста, сначала установите переменную', + comparisonOperator: { + 'contains': 'содержит', + 'not contains': 'не содержит', + 'start with': 'начинается с', + 'end with': 'заканчивается на', + 'is': 'равно', + 'is not': 'не равно', + 'empty': 'пусто', + 'not empty': 'не пусто', + 'null': 'null', + 'not null': 'не null', + 'regex match': 'Совпадение с регулярным выражением', + }, + enterValue: 'Введите значение', + addCondition: 'Добавить условие', + conditionNotSetup: 'Условие НЕ настроено', + selectVariable: 'Выберите переменную...', + }, + variableAssigner: { + title: 'Назначить переменные', + outputType: 'Тип вывода', + varNotSet: 'Переменная не установлена', + noVarTip: 'Добавьте переменные, которые нужно назначить', + type: { + string: 'Строка', + number: 'Число', + object: 'Объект', + array: 'Массив', + }, + aggregationGroup: 'Группа агрегации', + aggregationGroupTip: 'Включение этой функции позволяет агрегатору переменных агрегировать несколько наборов переменных.', + addGroup: 'Добавить группу', + outputVars: { + varDescribe: 'Вывод {{groupName}}', + }, + setAssignVariable: 'Установить переменную назначения', + }, + assigner: { + 'assignedVariable': 'Назначенная переменная', + 'writeMode': 'Режим записи', + 'writeModeTip': 'Режим добавления: доступен только для переменных массива.', + 'over-write': 'Перезаписать', + 'append': 'Добавить', + 'plus': 'Плюс', + 'clear': 'Очистить', + 'setVariable': 'Установить переменную', + 'variable': 'Переменная', + }, + tool: { + toAuthorize: 'Авторизовать', + inputVars: 'Входные переменные', + outputVars: { + text: 'контент, сгенерированный инструментом', + files: { + title: 'файлы, сгенерированные инструментом', + type: 'Поддерживаемый тип. Сейчас поддерживаются только изображения', + transfer_method: 'Метод передачи. Значение - remote_url или local_file', + url: 'URL изображения', + upload_file_id: 'Идентификатор загруженного файла', + }, + json: 'json, сгенерированный инструментом', + }, + }, + questionClassifiers: { + model: 'модель', + inputVars: 'Входные переменные', + outputVars: { + className: 'Имя класса', + }, + class: 'Класс', + classNamePlaceholder: 'Введите имя вашего класса', + advancedSetting: 'Расширенные настройки', + topicName: 'Название темы', + topicPlaceholder: 'Введите название вашей темы', + addClass: 'Добавить класс', + instruction: 'Инструкция', + instructionTip: 'Введите дополнительные инструкции, чтобы помочь классификатору вопросов лучше понять, как классифицировать вопросы.', + instructionPlaceholder: 'Введите вашу инструкцию', + }, + parameterExtractor: { + inputVar: 'Входная переменная', + extractParameters: 'Извлечь параметры', + importFromTool: 'Импортировать из инструментов', + addExtractParameter: 'Добавить параметр для извлечения', + addExtractParameterContent: { + name: 'Имя', + namePlaceholder: 'Имя извлекаемого параметра', + type: 'Тип', + typePlaceholder: 'Тип извлекаемого параметра', + description: 'Описание', + descriptionPlaceholder: 'Описание извлекаемого параметра', + required: 'Обязательный', + requiredContent: 'Обязательный используется только в качестве ссылки для вывода модели, а не для обязательной проверки вывода параметра.', + }, + extractParametersNotSet: 'Параметры для извлечения не настроены', + instruction: 'Инструкция', + instructionTip: 'Введите дополнительные инструкции, чтобы помочь извлекателю параметров понять, как извлекать параметры.', + advancedSetting: 'Расширенные настройки', + reasoningMode: 'Режим рассуждения', + reasoningModeTip: 'Вы можете выбрать соответствующий режим рассуждения, основываясь на способности модели реагировать на инструкции для вызова функций или подсказки.', + isSuccess: 'Успешно. В случае успеха значение равно 1, в случае сбоя - 0.', + errorReason: 'Причина ошибки', + }, + iteration: { + deleteTitle: 'Удалить узел итерации?', + deleteDesc: 'Удаление узла итерации приведет к удалению всех дочерних узлов', + input: 'Вход', + output: 'Выходные переменные', + iteration_one: '{{count}} Итерация', + iteration_other: '{{count}} Итераций', + currentIteration: 'Текущая итерация', + }, + note: { + addNote: 'Добавить заметку', + editor: { + placeholder: 'Напишите свою заметку...', + small: 'Маленький', + medium: 'Средний', + large: 'Большой', + bold: 'Жирный', + italic: 'Курсив', + strikethrough: 'Зачеркнутый', + link: 'Ссылка', + openLink: 'Открыть', + unlink: 'Удалить ссылку', + enterUrl: 'Введите URL...', + invalidUrl: 'Неверный URL', + bulletList: 'Маркированный список', + showAuthor: 'Показать автора', + }, + }, + }, + tracing: { + stopBy: 'Остановлено {{user}}', + }, +} + +export default translation diff --git a/web/i18n/tr-TR/app-api.ts b/web/i18n/tr-TR/app-api.ts index be6466f001..9a64de546b 100644 --- a/web/i18n/tr-TR/app-api.ts +++ b/web/i18n/tr-TR/app-api.ts @@ -10,7 +10,7 @@ const translation = { pause: 'Duraklat', playing: 'Oynatılıyor', loading: 'Yükleniyor', - merMaind: { + merMaid: { rerender: 'Yeniden İşleme', }, never: 'Asla', diff --git a/web/i18n/tr-TR/app-debug.ts b/web/i18n/tr-TR/app-debug.ts index fbf51535fe..f08d221d45 100644 --- a/web/i18n/tr-TR/app-debug.ts +++ b/web/i18n/tr-TR/app-debug.ts @@ -301,7 +301,7 @@ const translation = { historyNoBeEmpty: 'Konuşma geçmişi prompt\'ta ayarlanmalıdır', queryNoBeEmpty: 'Sorgu prompt\'ta ayarlanmalıdır', }, - variableConig: { + variableConfig: { addModalTitle: 'Giriş Alanı Ekle', editModalTitle: 'Giriş Alanı Düzenle', description: 'Değişken ayarı {{varName}}', diff --git a/web/i18n/tr-TR/app-overview.ts b/web/i18n/tr-TR/app-overview.ts index 77a54dc4b3..721bac0000 100644 --- a/web/i18n/tr-TR/app-overview.ts +++ b/web/i18n/tr-TR/app-overview.ts @@ -48,6 +48,8 @@ const translation = { title: 'Workflow Adımları', show: 'Göster', hide: 'Gizle', + showDesc: 'WebApp\'te iş akışı ayrıntılarını gösterme veya gizleme', + subTitle: 'İş Akışı Detayları', }, chatColorTheme: 'Sohbet renk teması', chatColorThemeDesc: 'Sohbet botunun renk temasını ayarlayın', @@ -64,6 +66,12 @@ const translation = { customDisclaimerPlaceholder: 'Özel ifşa metnini girin', customDisclaimerTip: 'Özel ifşa metni istemci tarafında görüntülenecek ve uygulama hakkında ek bilgiler sağlayacak', }, + sso: { + title: 'WebApp SSO\'su', + tooltip: 'WebApp SSO\'yu etkinleştirmek için yöneticiyle iletişime geçin', + label: 'SSO Kimlik Doğrulaması', + description: 'Tüm kullanıcıların WebApp\'i kullanmadan önce SSO ile oturum açmaları gerekir', + }, }, embedded: { entry: 'Gömülü', @@ -119,7 +127,11 @@ const translation = { tokenPS: 'Token/s', totalMessages: { title: 'Toplam Mesajlar', - explanation: 'Günlük AI etkileşim sayısı; prompt mühendisliği/hata ayıklama hariç.', + explanation: 'Günlük AI etkileşimi sayısı.', + }, + totalConversations: { + title: 'Toplam Konuşmalar', + explanation: 'Günlük AI konuşmaları sayısı; prompt mühendisliği/hata ayıklama hariç.', }, activeUsers: { title: 'Aktif Kullanıcılar', diff --git a/web/i18n/tr-TR/app.ts b/web/i18n/tr-TR/app.ts index fb1ac36762..09cb680f50 100644 --- a/web/i18n/tr-TR/app.ts +++ b/web/i18n/tr-TR/app.ts @@ -122,6 +122,12 @@ const translation = { removeConfirmTitle: '{{key}} yapılandırmasını kaldır?', removeConfirmContent: 'Mevcut yapılandırma kullanımda, kaldırılması İzleme özelliğini kapatacaktır.', }, + view: 'Görünüm', + }, + answerIcon: { + descriptionInExplore: 'Keşfet\'te değiştirilecek 🤖 WebApp simgesinin kullanılıp kullanılmayacağı', + title: 'Değiştirmek 🤖 için WebApp simgesini kullanın', + description: 'Paylaşılan uygulamada değiştirmek 🤖 için WebApp simgesinin kullanılıp kullanılmayacağı', }, } diff --git a/web/i18n/tr-TR/common.ts b/web/i18n/tr-TR/common.ts index a194ffd769..a41925cd20 100644 --- a/web/i18n/tr-TR/common.ts +++ b/web/i18n/tr-TR/common.ts @@ -37,6 +37,7 @@ const translation = { params: 'Parametreler', duplicate: 'Çoğalt', rename: 'Yeniden Adlandır', + audioSourceUnavailable: 'AudioSource kullanılamıyor', }, errorMsg: { fieldRequired: '{{field}} gereklidir', @@ -132,7 +133,8 @@ const translation = { workspace: 'Çalışma Alanı', createWorkspace: 'Çalışma Alanı Oluştur', helpCenter: 'Yardım', - roadmapAndFeedback: 'Geri Bildirim', + communityFeedback: 'Geri Bildirim', + roadmap: 'Yol haritası', community: 'Topluluk', about: 'Hakkında', logout: 'Çıkış Yap', @@ -198,7 +200,7 @@ const translation = { invitationSent: 'Davet gönderildi', invitationSentTip: 'Davet gönderildi, Dify\'ye giriş yaparak takım verilerinize erişebilirler.', invitationLink: 'Davet Linki', - failedinvitationEmails: 'Aşağıdaki kullanıcılar başarıyla davet edilmedi', + failedInvitationEmails: 'Aşağıdaki kullanıcılar başarıyla davet edilmedi', ok: 'Tamam', removeFromTeam: 'Takımdan Kaldır', removeFromTeamTip: 'Takım erişimi kaldırılacak', @@ -206,7 +208,7 @@ const translation = { setMember: 'Normal üye olarak ayarla', setBuilder: 'Oluşturucu olarak ayarla', setEditor: 'Editör olarak ayarla', - disinvite: 'Davetiyeyi iptal et', + disInvite: 'Davetiyeyi iptal et', deleteMember: 'Üyeyi Sil', you: '(Siz)', }, diff --git a/web/i18n/tr-TR/dataset-creation.ts b/web/i18n/tr-TR/dataset-creation.ts index b35cbc26b2..b26608c39f 100644 --- a/web/i18n/tr-TR/dataset-creation.ts +++ b/web/i18n/tr-TR/dataset-creation.ts @@ -50,7 +50,7 @@ const translation = { input: 'Bilgi adı', placeholder: 'Lütfen girin', nameNotEmpty: 'Ad boş olamaz', - nameLengthInvaild: 'Ad 1 ile 40 karakter arasında olmalıdır', + nameLengthInvalid: 'Ad 1 ile 40 karakter arasında olmalıdır', cancelButton: 'İptal', confirmButton: 'Oluştur', failed: 'Oluşturma başarısız', @@ -109,8 +109,8 @@ const translation = { QATitle: 'Soru ve Yanıt formatında parçalama', QATip: 'Bu seçeneği etkinleştirmek daha fazla token tüketecektir', QALanguage: 'Kullanarak parçalara ayır', - emstimateCost: 'Tahmin', - emstimateSegment: 'Tahmini parçalar', + estimateCost: 'Tahmin', + estimateSegment: 'Tahmini parçalar', segmentCount: 'parçalar', calculating: 'Hesaplanıyor...', fileSource: 'Belgeleri ön işleme', @@ -135,8 +135,8 @@ const translation = { previewSwitchTipStart: 'Geçerli parça önizlemesi metin formatındadır, soru ve yanıt formatına geçiş ek tüketir', previewSwitchTipEnd: 'token', characters: 'karakterler', - indexSettedTip: 'Dizin yöntemini değiştirmek için, lütfen', - retrivalSettedTip: 'Dizin yöntemini değiştirmek için, lütfen', + indexSettingTip: 'Dizin yöntemini değiştirmek için, lütfen', + retrievalSettingTip: 'Dizin yöntemini değiştirmek için, lütfen', datasetSettingLink: 'Bilgi ayarlarına gidin.', }, stepThree: { diff --git a/web/i18n/tr-TR/dataset.ts b/web/i18n/tr-TR/dataset.ts index 31d483f504..5e55e071c5 100644 --- a/web/i18n/tr-TR/dataset.ts +++ b/web/i18n/tr-TR/dataset.ts @@ -53,6 +53,7 @@ const translation = { semantic_search: 'VEKTÖR', full_text_search: 'TAM METİN', hybrid_search: 'HİBRİT', + invertedIndex: 'TERS', }, mixtureHighQualityAndEconomicTip: 'Yüksek kaliteli ve ekonomik bilgi tabanlarının karışımı için Yeniden Sıralama modeli gereklidir.', inconsistentEmbeddingModelTip: 'Seçilen bilgi tabanlarının Yerleştirme modelleri tutarsızsa Yeniden Sıralama modeli gereklidir.', @@ -70,6 +71,7 @@ const translation = { nTo1RetrievalLegacy: 'Geri alım stratejisinin optimizasyonu ve yükseltilmesi nedeniyle, N-to-1 geri alımı Eylül ayında resmi olarak kullanım dışı kalacaktır. O zamana kadar normal şekilde kullanabilirsiniz.', nTo1RetrievalLegacyLink: 'Daha fazla bilgi edin', nTo1RetrievalLegacyLinkText: 'N-1 geri alma Eylül ayında resmi olarak kullanımdan kaldırılacaktır.', + defaultRetrievalTip: 'Varsayılan olarak çok alma kullanılır. Bilgi, birden fazla bilgi tabanından alınır ve ardından yeniden sıralanır.', } export default translation diff --git a/web/i18n/tr-TR/login.ts b/web/i18n/tr-TR/login.ts index 617b58be36..8f0a9eff89 100644 --- a/web/i18n/tr-TR/login.ts +++ b/web/i18n/tr-TR/login.ts @@ -32,7 +32,7 @@ const translation = { pp: 'Gizlilik Politikası', tosDesc: 'Kaydolarak, Hizmet Şartlarımızı kabul etmiş olursunuz', goToInit: 'Hesabı başlatmadıysanız, lütfen başlatma sayfasına gidin', - donthave: 'Sahip değil misiniz?', + dontHave: 'Sahip değil misiniz?', invalidInvitationCode: 'Geçersiz davet kodu', accountAlreadyInited: 'Hesap zaten başlatılmış', forgotPassword: 'Şifrenizi mi unuttunuz?', diff --git a/web/i18n/tr-TR/share-app.ts b/web/i18n/tr-TR/share-app.ts index 4fe58a8b2b..26c6f56fb4 100644 --- a/web/i18n/tr-TR/share-app.ts +++ b/web/i18n/tr-TR/share-app.ts @@ -2,7 +2,7 @@ const translation = { common: { welcome: '', appUnavailable: 'Uygulama kullanılamıyor', - appUnkonwError: 'Uygulama kullanılamıyor', + appUnknownError: 'Uygulama kullanılamıyor', }, chat: { newChat: 'Yeni sohbet', @@ -10,7 +10,7 @@ const translation = { unpinnedTitle: 'Sohbetler', newChatDefaultName: 'Yeni konuşma', resetChat: 'Konuşmayı sıfırla', - powerBy: 'Tarafından desteklenmektedir', + poweredBy: 'Tarafından desteklenmektedir', prompt: 'Prompt', privatePromptConfigTitle: 'Konuşma ayarları', publicPromptConfigTitle: 'Başlangıç Promptu', diff --git a/web/i18n/tr-TR/workflow.ts b/web/i18n/tr-TR/workflow.ts index dd5fe17c37..856c5d518f 100644 --- a/web/i18n/tr-TR/workflow.ts +++ b/web/i18n/tr-TR/workflow.ts @@ -36,7 +36,7 @@ const translation = { searchVar: 'Değişkeni ara', variableNamePlaceholder: 'Değişken adı', setVarValuePlaceholder: 'Değişkeni ayarla', - needConnecttip: 'Bu adım hiçbir şeye bağlı değil', + needConnectTip: 'Bu adım hiçbir şeye bağlı değil', maxTreeDepth: 'Her dal için maksimum {{depth}} düğüm limiti', needEndNode: 'Son blok eklenmelidir', needAnswerNode: 'Yanıt bloğu eklenmelidir', @@ -186,6 +186,7 @@ const translation = { 'transform': 'Dönüştür', 'utilities': 'Yardımcı Araçlar', 'noResult': 'Eşleşen bulunamadı', + 'searchTool': 'Arama aracı', }, blocks: { 'start': 'Başlat', @@ -365,6 +366,7 @@ const translation = { 'custom': 'Özel', 'api-key-title': 'API Anahtarı', 'header': 'Başlık', + 'auth-type': 'Kimlik Doğrulama Türü', }, insertVarPlaceholder: 'değişkeni eklemek için \'/\' yazın', timeout: { @@ -411,13 +413,13 @@ const translation = { 'not empty': 'boş değil', 'null': 'null', 'not null': 'null değil', + 'regex match': 'normal ifade maçı', }, enterValue: 'Değer girin', addCondition: 'Koşul Ekle', conditionNotSetup: 'Koşul AYARLANMADI', selectVariable: 'Değişken seçin...', }, - variableAssigner: { title: 'Değişken ata', outputType: 'Çıktı Türü', diff --git a/web/i18n/uk-UA/app-api.ts b/web/i18n/uk-UA/app-api.ts index 62385e43e7..6f46e9a9b4 100644 --- a/web/i18n/uk-UA/app-api.ts +++ b/web/i18n/uk-UA/app-api.ts @@ -9,7 +9,7 @@ const translation = { play: 'Відтворити', pause: 'Пауза', playing: 'Відтворення', - merMaind: { + merMaid: { rerender: 'Повторити рендер', }, never: 'Ніколи', @@ -61,6 +61,23 @@ const translation = { pathParams: 'Параметри шляху', query: 'Запит', }, + completionMode: { + messageIDTip: 'Ідентифікатор повідомлення', + streaming: 'Потокове передавання повертається. Реалізація повернення потокового мовлення на основі SSE (Server-Sent Events).', + blocking: 'Тип блокування, очікування завершення виконання та повернення результатів. (Запити можуть бути перервані, якщо процес тривалий)', + title: 'API програми для завершення', + ratingTip: 'Подобається чи не подобається, null – це скасувати', + createCompletionApiTip: 'Створіть повідомлення про завершення, щоб підтримувати режим запитань і відповідей.', + parametersApi: 'Отримання інформації про параметри програми', + queryTips: 'Текстовий контент, що вводиться користувачем.', + createCompletionApi: 'Створити повідомлення про завершення', + messageFeedbackApi: 'Відгук у повідомленні (подобається)', + messageFeedbackApiTip: 'Оцінюйте отримані повідомлення від імені кінцевих користувачів з лайками або дизлайками. Ці дані відображаються на сторінці «Журнали та анотації» та використовуються для доопрацювання майбутньої моделі.', + info: 'Для створення високоякісного тексту, такого як статті, резюме та переклади, використовуйте API повідомлень про завершення з введенням користувачем. Генерація тексту залежить від параметрів моделі та шаблонів підказок, встановлених у Dify Prompt Engineering.', + inputsTips: '(Необов\'язково.) Надайте поля введення користувача у вигляді пар ключ-значення, що відповідають змінним у Prompt Eng. Key — це ім\'я змінної, Value — значення параметра. Якщо вибрано тип поля Вибір, надіслане значення має бути одним із попередньо встановлених варіантів.', + parametersApiTip: 'Отримання налаштованих вхідних параметрів, включаючи імена змінних, імена полів, типи та значення за замовчуванням. Зазвичай використовується для відображення цих полів у формі або заповнення значень за замовчуванням після завантаження клієнта.', + }, + loading: 'Завантаження', } export default translation diff --git a/web/i18n/uk-UA/app-debug.ts b/web/i18n/uk-UA/app-debug.ts index 7c0ba45b3c..1fc6981122 100644 --- a/web/i18n/uk-UA/app-debug.ts +++ b/web/i18n/uk-UA/app-debug.ts @@ -259,7 +259,7 @@ const translation = { historyNoBeEmpty: 'Історію розмови необхідно встановити у підказці', // Conversation history must be set in the prompt queryNoBeEmpty: 'Запит має бути встановлений у підказці', // Query must be set in the prompt }, - variableConig: { + variableConfig: { 'addModalTitle': 'Додати Поле Введення', 'editModalTitle': 'Редагувати Поле Введення', 'description': 'Налаштування для змінної {{varName}}', diff --git a/web/i18n/uk-UA/app-overview.ts b/web/i18n/uk-UA/app-overview.ts index 8bd1f0fb39..11c88c5699 100644 --- a/web/i18n/uk-UA/app-overview.ts +++ b/web/i18n/uk-UA/app-overview.ts @@ -48,6 +48,8 @@ const translation = { title: 'Кроки робочого процесу', show: 'Показати', hide: 'Приховати', + subTitle: 'Деталі робочого процесу', + showDesc: 'Відображення або приховування відомостей про робочий процес у веб-програмі', }, chatColorTheme: 'Тема кольору чату', chatColorThemeDesc: 'Встановіть тему кольору чат-бота', @@ -64,6 +66,12 @@ const translation = { customDisclaimerPlaceholder: 'Введіть відмову від відповідальності', customDisclaimerTip: 'Відображається на клієнтському боці, щоб визначити відповідальність за використання додатка', }, + sso: { + title: 'Єдиний вхід для WebApp', + description: 'Усі користувачі повинні увійти в систему за допомогою єдиного входу перед використанням WebApp', + tooltip: 'Зверніться до адміністратора, щоб увімкнути єдиний вхід WebApp', + label: 'Автентифікація за допомогою єдиного входу', + }, }, embedded: { entry: 'Вбудоване', @@ -119,7 +127,11 @@ const translation = { tokenPS: 'Токени/с', totalMessages: { title: 'Загальна кількість повідомлень', - explanation: 'Щоденна кількість взаємодій з штучним інтелектом; інженерія/налагодження запитів виключено.', + explanation: 'Кількість щоденних взаємодій з ШІ.', + }, + totalConversations: { + title: 'Загальна кількість розмов', + explanation: 'Кількість щоденних розмов з ШІ; інженерія/налагодження промптів виключено.', }, activeUsers: { title: 'Активні користувачі', diff --git a/web/i18n/uk-UA/app.ts b/web/i18n/uk-UA/app.ts index fbe9eea81e..c8fb4ca7d4 100644 --- a/web/i18n/uk-UA/app.ts +++ b/web/i18n/uk-UA/app.ts @@ -122,7 +122,17 @@ const translation = { removeConfirmTitle: 'Видалити налаштування {{key}}?', removeConfirmContent: 'Поточне налаштування використовується, його видалення вимкне функцію Відстеження.', }, + view: 'Вид', }, + answerIcon: { + title: 'Використовуйте піктограму WebApp для заміни 🤖', + description: 'Чи слід використовувати піктограму WebApp для заміни 🤖 у спільній програмі', + descriptionInExplore: 'Чи використовувати піктограму веб-програми для заміни 🤖 в Огляді', + }, + importFromDSLUrl: 'З URL', + importFromDSL: 'Імпорт з DSL', + importFromDSLUrlPlaceholder: 'Вставте посилання на DSL тут', + importFromDSLFile: 'З DSL-файлу', } export default translation diff --git a/web/i18n/uk-UA/billing.ts b/web/i18n/uk-UA/billing.ts index afc434e652..cebdb11521 100644 --- a/web/i18n/uk-UA/billing.ts +++ b/web/i18n/uk-UA/billing.ts @@ -58,6 +58,9 @@ const translation = { ragAPIRequest: 'RAG API запити', agentMode: 'Режим агента', workflow: 'Робочий процес', + bulkUpload: 'Масове завантаження документів', + llmLoadingBalancing: 'Балансування навантаження LLM', + llmLoadingBalancingTooltip: 'Додавайте кілька ключів API до моделей, ефективно обходячи обмеження швидкості API.', }, comingSoon: 'Скоро', member: 'Учасник', @@ -72,6 +75,8 @@ const translation = { }, ragAPIRequestTooltip: 'Відноситься до кількості викликів API, що викликають лише можливості обробки бази знань Dify.', receiptInfo: 'Лише власник команди та адміністратор команди можуть підписуватися та переглядати інформацію про виставлення рахунків', + annotationQuota: 'Квота анотацій', + documentsUploadQuota: 'Квота завантаження документів', }, plans: { sandbox: { diff --git a/web/i18n/uk-UA/common.ts b/web/i18n/uk-UA/common.ts index 33324ce0f2..cc70772be3 100644 --- a/web/i18n/uk-UA/common.ts +++ b/web/i18n/uk-UA/common.ts @@ -37,6 +37,7 @@ const translation = { params: 'Параметри', duplicate: 'дублікат', rename: 'Перейменувати', + audioSourceUnavailable: 'AudioSource недоступний', }, placeholder: { input: 'Будь ласка, введіть текст', @@ -128,7 +129,8 @@ const translation = { workspace: 'Робочий простір', createWorkspace: 'Створити робочий простір', helpCenter: 'Довідковий центр', - roadmapAndFeedback: 'відгуки', + communityFeedback: 'відгуки', + roadmap: 'Дорожня карта', community: 'Спільнота', about: 'Про нас', logout: 'Вийти', @@ -190,16 +192,21 @@ const translation = { invitationSent: 'Запрошення надіслано', invitationSentTip: 'Запрошення надіслано, і вони можуть увійти в Dify, щоб отримати доступ до даних вашої команди.', invitationLink: 'Посилання на запрошення', - failedinvitationEmails: 'Наступних користувачів не було успішно запрошено', + failedInvitationEmails: 'Наступних користувачів не було успішно запрошено', ok: 'ОК', removeFromTeam: 'Видалити з команди', removeFromTeamTip: 'Буде видалено доступ до команди', setAdmin: 'Призначити адміністратором', setMember: 'Встановити як звичайного члена', setEditor: 'Встановити як Редактор', - disinvite: 'Скасувати запрошення', + disInvite: 'Скасувати запрошення', deleteMember: 'Видалити учасника', you: '(Ви)', + builder: 'Будівник', + datasetOperatorTip: 'Тільки може управляти базою знань', + datasetOperator: 'Адміністратор знань', + setBuilder: 'Встановити як будівельник', + builderTip: 'Може створювати та редагувати власні програми', }, integrations: { connected: 'Підключено', @@ -344,8 +351,25 @@ const translation = { deprecated: 'Застарілий', confirmDelete: 'підтвердити видалення?', quotaTip: 'Залишилося доступних безкоштовних токенів', - loadPresets: 'Завантажити', // If need adjustment, provide more context on 'Load Presets' function + // If need adjustment, provide more context on 'Load Presets' function + loadPresets: 'Завантажити', parameters: 'ПАРАМЕТРИ', + apiKeyStatusNormal: 'Статус APIKey нормальний', + loadBalancing: 'Балансування навантаження', + editConfig: 'Редагувати конфігурацію', + loadBalancingHeadline: 'Балансування навантаження', + apiKey: 'API-КЛЮЧ', + defaultConfig: 'Конфігурація за замовчуванням', + providerManaged: 'Під управлінням провайдера', + loadBalancingDescription: 'Зменшіть тиск за допомогою кількох наборів облікових даних.', + modelHasBeenDeprecated: 'Ця модель вважається застарілою', + addConfig: 'Додати конфігурацію', + configLoadBalancing: 'Балансування навантаження конфігурації', + upgradeForLoadBalancing: 'Оновіть свій план, щоб увімкнути балансування навантаження.', + apiKeyRateLimit: 'Було досягнуто ліміту швидкості, доступного після {{seconds}}', + providerManagedDescription: 'Використовуйте єдиний набір облікових даних, наданий постачальником моделі.', + loadBalancingLeastKeyWarning: 'Щоб увімкнути балансування навантаження, має бути ввімкнено щонайменше 2 клавіші.', + loadBalancingInfo: 'За замовчуванням для балансування навантаження використовується стратегія кругової системи. Якщо спрацьовує обмеження швидкості, буде застосовано період перезарядки тривалістю 1 хвилина.', }, dataSource: { add: 'Додати джерело даних', @@ -369,6 +393,15 @@ const translation = { preview: 'ПЕРЕДПЕРЕГЛЯД', }, }, + website: { + with: 'З', + active: 'Активний', + inactive: 'Неактивні', + configuredCrawlers: 'Налаштовані обхідні роботи', + title: 'Веб-сторінка', + description: 'Імпортуйте вміст із веб-сайтів за допомогою веб-сканера.', + }, + configure: 'Настроїти', }, plugin: { serpapi: { @@ -537,6 +570,10 @@ const translation = { created: 'Тег створено успішно', failed: 'Не вдалося створити тег', }, + errorMsg: { + fieldRequired: '{{field}} є обов\'язковим', + urlError: 'URL-адреса повинна починатися з http:// або https://', + }, } export default translation diff --git a/web/i18n/uk-UA/dataset-creation.ts b/web/i18n/uk-UA/dataset-creation.ts index 6c0099a771..e4a38f41f4 100644 --- a/web/i18n/uk-UA/dataset-creation.ts +++ b/web/i18n/uk-UA/dataset-creation.ts @@ -45,11 +45,35 @@ const translation = { input: 'Назва Знань', placeholder: 'Введіть, будь ласка', nameNotEmpty: 'Ім’я не може бути порожнім', - nameLengthInvaild: 'Ім’я має бути від 1 до 40 символів', + nameLengthInvalid: 'Ім’я має бути від 1 до 40 символів', cancelButton: 'Скасувати', confirmButton: 'Створити', failed: 'Створення не вдалося', }, + website: { + totalPageScraped: 'Всього вискоблених сторінок:', + run: 'Бігти', + configure: 'Настроїти', + limit: 'Межа', + selectAll: 'Вибрати все', + unknownError: 'Невідома помилка', + maxDepth: 'Максимальна глибина', + crawlSubPage: 'Сканування підсторінок', + firecrawlDocLink: 'https://docs.dify.ai/guides/knowledge-base/sync-from-website', + preview: 'Попередній перегляд', + fireCrawlNotConfigured: 'Firecrawl не налаштовано', + includeOnlyPaths: 'Включати лише контури', + options: 'Параметри', + resetAll: 'Скинути все', + excludePaths: 'Виключення контурів', + firecrawlDoc: 'Документація Firecrawl', + exceptionErrorTitle: 'Виняток стався під час виконання завдання Firecrawl:', + firecrawlTitle: 'Видобування веб-вмісту за допомогою 🔥Firecrawl', + scrapTimeInfo: 'Викрадено {{total}} сторінок загалом протягом {{time}}s', + fireCrawlNotConfiguredDescription: 'Налаштуйте Firecrawl за допомогою ключа API, щоб використовувати його.', + extractOnlyMainContent: 'Витягуйте лише основний контент (без заголовків, навігаторів, нижніх колонтитулів тощо)', + maxDepthTooltip: 'Максимальна глибина для сканування щодо введеної URL-адреси. Глибина 0 просто зішкрібає сторінку введеного url, глибина 1 шкребе url і все після введеногоURL + один /, і так далі.', + }, }, stepTwo: { segmentation: 'Налаштування фрагментації', @@ -80,8 +104,8 @@ const translation = { QATitle: 'Сегментація у форматі "питання та відповідь"', QATip: 'Увімкнення цієї опції споживатиме більше токенів', QALanguage: 'Сегментація з використанням', - emstimateCost: 'Оцінка', - emstimateSegment: 'Орієнтовні фрагменти', + estimateCost: 'Оцінка', + estimateSegment: 'Орієнтовні фрагменти', segmentCount: 'фрагментів', calculating: 'Розраховується...', fileSource: 'Попередня обробка документа', @@ -104,9 +128,11 @@ const translation = { previewSwitchTipStart: 'Поточний попередній перегляд має текстовий формат, зміна способу подання на формат запитань та відповідей ', previewSwitchTipEnd: ' потребує додаткових токенів', characters: 'символів', - indexSettedTip: 'Щоб змінити метод індексування, будь ласка, перейдіть до ', - retrivalSettedTip: 'Щоб змінити метод індексування, будь ласка, перейдіть до ', + indexSettingTip: 'Щоб змінити метод індексування, будь ласка, перейдіть до ', + retrievalSettingTip: 'Щоб змінити метод індексування, будь ласка, перейдіть до ', datasetSettingLink: 'Налаштування знань.', + webpageUnit: 'Сторінок', + websiteSource: 'Веб-сайт попередньої обробки', }, stepThree: { creationTitle: '🎉 Знання створено', @@ -125,6 +151,11 @@ const translation = { modelButtonConfirm: 'Підтвердити', modelButtonCancel: 'Скасувати', }, + firecrawl: { + getApiKeyLinkText: 'Отримайте свій API-ключ від firecrawl.dev', + configFirecrawl: 'Налаштування 🔥Firecrawl', + apiKeyPlaceholder: 'Ключ API від firecrawl.dev', + }, } export default translation diff --git a/web/i18n/uk-UA/dataset-documents.ts b/web/i18n/uk-UA/dataset-documents.ts index 90b686ba08..0b20d534e7 100644 --- a/web/i18n/uk-UA/dataset-documents.ts +++ b/web/i18n/uk-UA/dataset-documents.ts @@ -13,6 +13,8 @@ const translation = { status: 'СТАТУС', action: 'ДІЯ', }, + name: 'Ім\'я', + rename: 'Перейменувати', }, action: { uploadFile: 'Завантажити новий файл', @@ -74,6 +76,7 @@ const translation = { error: 'Помилка імпорту', ok: 'ОК', }, + addUrl: 'Додати URL-адресу', }, metadata: { title: 'Метадані', diff --git a/web/i18n/uk-UA/dataset-settings.ts b/web/i18n/uk-UA/dataset-settings.ts index 4ea1e24f26..85e80902a7 100644 --- a/web/i18n/uk-UA/dataset-settings.ts +++ b/web/i18n/uk-UA/dataset-settings.ts @@ -27,6 +27,8 @@ const translation = { longDescription: ' про метод вибірки, ви можете змінити це будь-коли в налаштуваннях бази знань.', }, save: 'Зберегти', + me: '(Ви)', + permissionsInvitedMembers: 'Часткові члени команди', }, } diff --git a/web/i18n/uk-UA/dataset.ts b/web/i18n/uk-UA/dataset.ts index 3bf59ed33b..1bf6786976 100644 --- a/web/i18n/uk-UA/dataset.ts +++ b/web/i18n/uk-UA/dataset.ts @@ -1,6 +1,7 @@ const translation = { knowledge: 'Знання', - documentCount: ' док.', // Скорочення від 'документів' + // Скорочення від 'документів' + documentCount: ' док.', wordCount: ' тис. слів', appCount: ' пов\'язаних додатків', createDataset: 'Створити Знання', @@ -71,6 +72,7 @@ const translation = { nTo1RetrievalLegacy: 'N-до-1 пошук буде офіційно застарілим з вересня. Рекомендується використовувати найновіший багатошляховий пошук для отримання кращих результатів.', nTo1RetrievalLegacyLink: 'Дізнатися більше', nTo1RetrievalLegacyLinkText: 'N-до-1 пошук буде офіційно застарілим у вересні.', + defaultRetrievalTip: 'За замовчуванням використовується отримання кількома шляхами. Знання витягуються з кількох баз знань, а потім заново ранжуються.', } export default translation diff --git a/web/i18n/uk-UA/login.ts b/web/i18n/uk-UA/login.ts index 46de22bec2..7acc1920fc 100644 --- a/web/i18n/uk-UA/login.ts +++ b/web/i18n/uk-UA/login.ts @@ -31,7 +31,7 @@ const translation = { pp: 'Політика конфіденційності', tosDesc: 'Реєструючись, ви приймаєте наші', goToInit: 'Якщо ви ще не ініціалізували обліковий запис, перейдіть на сторінку ініціалізації', - donthave: 'Не маєте?', + dontHave: 'Не маєте?', invalidInvitationCode: 'Недійсний код запрошення', accountAlreadyInited: 'Обліковий запис уже ініціалізовано', forgotPassword: 'Забули пароль?', @@ -53,6 +53,7 @@ const translation = { nameEmpty: 'Ім\'я обов\'язкове', passwordEmpty: 'Пароль є обов’язковим', passwordInvalid: 'Пароль повинен містити літери та цифри, а довжина повинна бути більшою за 8', + passwordLengthInValid: 'Пароль повинен бути не менше 8 символів', }, license: { tip: 'Перед запуском Dify Community Edition ознайомтеся з ліцензією з відкритим кодом на GitHub', @@ -68,6 +69,7 @@ const translation = { activated: 'Увійти зараз', adminInitPassword: 'Пароль ініціалізації адміністратора', validate: 'Перевірити', + sso: 'Продовжуйте працювати з SSW', } export default translation diff --git a/web/i18n/uk-UA/share-app.ts b/web/i18n/uk-UA/share-app.ts index 9a121aaadc..3465a6e5b9 100644 --- a/web/i18n/uk-UA/share-app.ts +++ b/web/i18n/uk-UA/share-app.ts @@ -2,7 +2,7 @@ const translation = { common: { welcome: '', appUnavailable: 'Додаток недоступний', - appUnkonwError: 'Додаток недоступний', + appUnknownError: 'Додаток недоступний', }, chat: { newChat: 'Новий чат', @@ -10,7 +10,7 @@ const translation = { unpinnedTitle: 'Чати', newChatDefaultName: 'Нова розмова', resetChat: 'Очистити розмову', - powerBy: 'Забезпечується', + poweredBy: 'Забезпечується', prompt: 'Підказка', privatePromptConfigTitle: 'Налаштування розмови', publicPromptConfigTitle: 'Початкова підказка', @@ -27,7 +27,6 @@ const translation = { tryToSolve: 'Спробувати вирішити', temporarySystemIssue: 'Вибачте, тимчасова системна проблема.', }, - generation: { tabs: { create: 'Запустити один раз', @@ -65,7 +64,6 @@ const translation = { moreThanMaxLengthLine: 'Рядок {{rowIndex}}: значення {{varName}} не може містити більше {{maxLength}} символів', atLeastOne: 'Будь ласка, введіть принаймні один рядок у завантажений файл.', }, - }, } diff --git a/web/i18n/uk-UA/tools.ts b/web/i18n/uk-UA/tools.ts index 313332e3a4..309a450afc 100644 --- a/web/i18n/uk-UA/tools.ts +++ b/web/i18n/uk-UA/tools.ts @@ -5,6 +5,7 @@ const translation = { all: 'Усі', builtIn: 'Вбудовані', custom: 'Користувацькі', + workflow: 'Робочий процес', }, contribute: { line1: 'Мені цікаво зробити свій внесок', @@ -67,6 +68,7 @@ const translation = { bearer: 'Bearer', custom: 'Custom', }, + title: 'Тип аутентифікації', }, privacyPolicy: 'Політика конфіденційності', privacyPolicyPlaceholder: 'Введіть політику конфіденційності', @@ -74,8 +76,28 @@ const translation = { customDisclaimerPlaceholder: 'Введіть власні відомості', deleteToolConfirmTitle: 'Видалити цей інструмент?', deleteToolConfirmContent: 'Видалення інструменту є незворотнім. Користувачі більше не зможуть отримати доступ до вашого інструменту.', + toolInput: { + label: 'Мітки', + name: 'Ім\'я', + required: 'Необхідний', + method: 'Метод', + title: 'Введення інструменту', + methodSetting: 'Параметр', + description: 'Опис', + methodParameter: 'Параметр', + labelPlaceholder: 'Виберіть теги (необов\'язково)', + descriptionPlaceholder: 'Опис значення параметра', + methodSettingTip: 'Користувач заповнює конфігурацію інструменту', + methodParameterTip: 'LLM заповнюється під час логічного висновку', + }, + description: 'Опис', + nameForToolCall: 'Ім\'я виклику інструменту', + confirmTitle: 'Підтвердьте, щоб зберегти?', + nameForToolCallTip: 'Підтримує лише цифри, літери та підкреслення.', + confirmTip: 'Це вплине на програми, які використовують цей інструмент', + nameForToolCallPlaceHolder: 'Використовується для розпізнавання машин, таких як getCurrentWeather, list_pets', + descriptionPlaceholder: 'Короткий опис призначення інструменту, наприклад, отримання температури для конкретного місця.', }, - test: { title: 'Тест', parametersValue: 'Параметри та значення', @@ -114,6 +136,18 @@ const translation = { toolRemoved: 'Інструмент видалено', notAuthorized: 'Інструмент не авторизовано', howToGet: 'Як отримати', + addToolModal: { + category: 'категорія', + add: 'Додати', + added: 'Додано', + type: 'тип', + manageInTools: 'Керування в інструментах', + emptyTip: 'Перейдіть до розділу "Робочий процес -> Опублікувати як інструмент"', + emptyTitle: 'Немає доступного інструменту для роботи з робочими процесами', + }, + openInStudio: 'Відкрити в Студії', + customToolTip: 'Дізнайтеся більше про користувацькі інструменти Dify', + toolNameUsageTip: 'Ім\'я виклику інструменту для міркувань і підказок агента', } export default translation diff --git a/web/i18n/uk-UA/workflow.ts b/web/i18n/uk-UA/workflow.ts index 066a245770..c6b98d1b5b 100644 --- a/web/i18n/uk-UA/workflow.ts +++ b/web/i18n/uk-UA/workflow.ts @@ -36,7 +36,7 @@ const translation = { searchVar: 'Пошук змінної', variableNamePlaceholder: 'Назва змінної', setVarValuePlaceholder: 'Встановити значення змінної', - needConnecttip: 'Цей крок ні до чого не підключений', + needConnectTip: 'Цей крок ні до чого не підключений', maxTreeDepth: 'Максимальний ліміт {{depth}} вузлів на гілку', needEndNode: 'Потрібно додати кінцевий блок', needAnswerNode: 'Потрібно додати блок відповіді', @@ -69,6 +69,14 @@ const translation = { manageInTools: 'Керування в інструментах', workflowAsToolTip: 'Після оновлення робочого потоку необхідна переконфігурація інструменту.', viewDetailInTracingPanel: 'Переглянути деталі', + importSuccess: 'Успіх імпорту', + overwriteAndImport: 'Перезапис та імпорт', + importFailure: 'Помилка імпорту', + importDSL: 'Імпорт DSL', + syncingData: 'Синхронізація даних, всього за кілька секунд.', + chooseDSL: 'Виберіть файл DSL(yml)', + backupCurrentDraft: 'Резервна поточна чернетка', + importDSLTip: 'Поточна чернетка буде перезаписана. Експортуйте робочий процес як резервну копію перед імпортом.', }, env: { envPanelTitle: 'Змінні середовища', @@ -178,6 +186,7 @@ const translation = { 'transform': 'Трансформація', 'utilities': 'Утиліти', 'noResult': 'Нічого не знайдено', + 'searchTool': 'Інструмент пошуку', }, blocks: { 'start': 'Початок', @@ -403,10 +412,12 @@ const translation = { 'not empty': 'не порожній', 'null': 'є null', 'not null': 'не є null', + 'regex match': 'Регулярний вираз збігу', }, enterValue: 'Введіть значення', addCondition: 'Додати умову', conditionNotSetup: 'Умова НЕ налаштована', + selectVariable: 'Виберіть змінну...', }, variableAssigner: { title: 'Присвоєння змінних', @@ -502,6 +513,25 @@ const translation = { iteration_other: '{{count}} Ітерацій', currentIteration: 'Поточна ітерація', }, + note: { + editor: { + large: 'Великий', + bold: 'Жирний', + openLink: 'Відкривати', + small: 'Малий', + link: 'Посилання', + italic: 'Курсив', + placeholder: 'Напишіть свою замітку...', + strikethrough: 'Закреслені', + medium: 'Середнє', + showAuthor: 'Показати автора', + bulletList: 'Маркований список', + enterUrl: 'Введіть URL-адресу...', + unlink: 'Від\'єднати', + invalidUrl: 'Невірна URL-адреса', + }, + addNote: 'Додати примітку', + }, }, tracing: { stopBy: 'Зупинено користувачем {{user}}', diff --git a/web/i18n/vi-VN/app-api.ts b/web/i18n/vi-VN/app-api.ts index cb89b98008..2d4ee90e3c 100644 --- a/web/i18n/vi-VN/app-api.ts +++ b/web/i18n/vi-VN/app-api.ts @@ -9,7 +9,7 @@ const translation = { play: 'Chạy', pause: 'Tạm dừng', playing: 'Đang chạy', - merMaind: { + merMaid: { rerender: 'Vẽ lại', }, never: 'Không bao giờ', @@ -77,6 +77,7 @@ const translation = { pathParams: 'Tham số đường dẫn', query: 'Truy vấn', }, + loading: 'Tải', } export default translation diff --git a/web/i18n/vi-VN/app-debug.ts b/web/i18n/vi-VN/app-debug.ts index 906b39d10a..4e8a1962fe 100644 --- a/web/i18n/vi-VN/app-debug.ts +++ b/web/i18n/vi-VN/app-debug.ts @@ -259,7 +259,7 @@ const translation = { historyNoBeEmpty: 'Lịch sử cuộc trò chuyện phải được thiết lập trong lời nhắc', queryNoBeEmpty: 'Truy vấn phải được thiết lập trong lời nhắc', }, - variableConig: { + variableConfig: { 'addModalTitle': 'Thêm trường nhập', 'editModalTitle': 'Chỉnh sửa trường nhập', 'description': 'Cài đặt cho biến {{varName}}', diff --git a/web/i18n/vi-VN/app-log.ts b/web/i18n/vi-VN/app-log.ts index c4df7b512f..30a3988c12 100644 --- a/web/i18n/vi-VN/app-log.ts +++ b/web/i18n/vi-VN/app-log.ts @@ -89,7 +89,9 @@ const translation = { iterations: 'Số lần lặp', iteration: 'Lần lặp', finalProcessing: 'Xử lý cuối cùng', + agentMode: 'Chế độ đại lý', }, + agentLog: 'Nhật ký đại lý', } export default translation diff --git a/web/i18n/vi-VN/app-overview.ts b/web/i18n/vi-VN/app-overview.ts index 55a53d73a2..7cc7428906 100644 --- a/web/i18n/vi-VN/app-overview.ts +++ b/web/i18n/vi-VN/app-overview.ts @@ -48,6 +48,8 @@ const translation = { title: 'Các bước quy trình', show: 'Hiển thị', hide: 'Ẩn', + showDesc: 'Hiển thị hoặc ẩn chi tiết dòng công việc trong WebApp', + subTitle: 'Chi tiết quy trình làm việc', }, chatColorTheme: 'Giao diện màu trò chuyện', chatColorThemeDesc: 'Thiết lập giao diện màu của chatbot', @@ -64,6 +66,12 @@ const translation = { customDisclaimerPlaceholder: 'Nhập liên kết tuyên bố từ chối trách nhiệm', customDisclaimerTip: 'Liên kết này sẽ hiển thị ở phía người dùng, cung cấp thông tin về trách nhiệm của ứng dụng', }, + sso: { + title: 'SSO ứng dụng web', + description: 'Tất cả người dùng được yêu cầu đăng nhập bằng SSO trước khi sử dụng WebApp', + tooltip: 'Liên hệ với quản trị viên để bật SSO WebApp', + label: 'Xác thực SSO', + }, }, embedded: { entry: 'Nhúng', @@ -119,7 +127,11 @@ const translation = { tokenPS: 'Token/giây', totalMessages: { title: 'Tổng số tin nhắn', - explanation: 'Số lần tương tác AI hàng ngày; không tính việc tạo lại/lặp lại câu hỏi.', + explanation: 'Số lượng tương tác AI hàng ngày.', + }, + totalConversations: { + title: 'Tổng số cuộc hội thoại', + explanation: 'Số lượng cuộc hội thoại AI hàng ngày; không bao gồm kỹ thuật/gỡ lỗi prompt.', }, activeUsers: { title: 'Người dùng hoạt động', diff --git a/web/i18n/vi-VN/app.ts b/web/i18n/vi-VN/app.ts index 4052506f83..9e84341f63 100644 --- a/web/i18n/vi-VN/app.ts +++ b/web/i18n/vi-VN/app.ts @@ -122,7 +122,17 @@ const translation = { removeConfirmTitle: 'Xóa cấu hình {{key}}?', removeConfirmContent: 'Cấu hình hiện tại đang được sử dụng, việc xóa nó sẽ tắt tính năng Theo dõi.', }, + view: 'Cảnh', }, + answerIcon: { + description: 'Có nên sử dụng biểu tượng WebApp để thay thế 🤖 trong ứng dụng được chia sẻ hay không', + descriptionInExplore: 'Có nên sử dụng biểu tượng WebApp để thay thế 🤖 trong Khám phá hay không', + title: 'Sử dụng biểu tượng WebApp để thay thế 🤖', + }, + importFromDSLFile: 'Từ tệp DSL', + importFromDSL: 'Nhập từ DSL', + importFromDSLUrlPlaceholder: 'Dán liên kết DSL vào đây', + importFromDSLUrl: 'Từ URL', } export default translation diff --git a/web/i18n/vi-VN/billing.ts b/web/i18n/vi-VN/billing.ts index 71abd8a884..595481e3a4 100644 --- a/web/i18n/vi-VN/billing.ts +++ b/web/i18n/vi-VN/billing.ts @@ -60,6 +60,8 @@ const translation = { bulkUpload: 'Tải lên tài liệu hàng loạt', agentMode: 'Chế độ Đại lý', workflow: 'Quy trình làm việc', + llmLoadingBalancing: 'Cân bằng tải LLM', + llmLoadingBalancingTooltip: 'Thêm nhiều khóa API vào mô hình, vượt qua giới hạn tốc độ API một cách hiệu quả.', }, comingSoon: 'Sắp ra mắt', member: 'Thành viên', @@ -74,6 +76,7 @@ const translation = { }, ragAPIRequestTooltip: 'Đề cập đến số lượng cuộc gọi API triệu hồi chỉ khả năng xử lý cơ sở kiến thức của Dify.', receiptInfo: 'Chỉ chủ nhóm và quản trị viên nhóm có thể đăng ký và xem thông tin thanh toán', + annotationQuota: 'Hạn ngạch chú thích', }, plans: { sandbox: { diff --git a/web/i18n/vi-VN/common.ts b/web/i18n/vi-VN/common.ts index 19855d31f0..252fa7e1df 100644 --- a/web/i18n/vi-VN/common.ts +++ b/web/i18n/vi-VN/common.ts @@ -37,6 +37,7 @@ const translation = { params: 'Tham số', duplicate: 'Nhân bản', rename: 'Đổi tên', + audioSourceUnavailable: 'AudioSource không khả dụng', }, placeholder: { input: 'Vui lòng nhập', @@ -128,7 +129,8 @@ const translation = { workspace: 'Không gian làm việc', createWorkspace: 'Tạo Không gian làm việc', helpCenter: 'Trung tâm trợ giúp', - roadmapAndFeedback: 'Phản hồi', + communityFeedback: 'Phản hồi', + roadmap: 'Lộ trình', community: 'Cộng đồng', about: 'Về chúng tôi', logout: 'Đăng xuất', @@ -190,16 +192,21 @@ const translation = { invitationSent: 'Lời mời đã được gửi', invitationSentTip: 'Lời mời đã được gửi, và họ có thể đăng nhập vào Dify để truy cập vào dữ liệu nhóm của bạn.', invitationLink: 'Liên kết Lời mời', - failedinvitationEmails: 'Dưới đây là danh sách email không gửi được lời mời', + failedInvitationEmails: 'Dưới đây là danh sách email không gửi được lời mời', ok: 'OK', removeFromTeam: 'Xóa khỏi nhóm', removeFromTeamTip: 'Sẽ xóa quyền truy cập nhóm', setAdmin: 'Đặt làm quản trị viên', setMember: 'Đặt thành viên bình thường', setEditor: 'Đặt làm biên tập viên', - disinvite: 'Hủy lời mời', + disInvite: 'Hủy lời mời', deleteMember: 'Xóa thành viên', you: '(Bạn)', + datasetOperatorTip: 'Chỉ có thể quản lý cơ sở kiến thức', + builderTip: 'Có thể xây dựng và chỉnh sửa ứng dụng của riêng mình', + builder: 'Chủ thầu', + datasetOperator: 'Quản trị viên kiến thức', + setBuilder: 'Đặt làm trình tạo', }, integrations: { connected: 'Đã kết nối', @@ -346,6 +353,22 @@ const translation = { quotaTip: 'Số lượng mã thông báo miễn phí còn lại', loadPresets: 'Tải Cài đặt trước', parameters: 'THAM SỐ', + loadBalancingHeadline: 'Cân bằng tải', + loadBalancing: 'Cân bằng tải', + configLoadBalancing: 'Cấu hình cân bằng tải', + defaultConfig: 'Cấu hình mặc định', + modelHasBeenDeprecated: 'Mô hình này đã bị phản đối', + providerManagedDescription: 'Sử dụng bộ thông tin đăng nhập duy nhất do nhà cung cấp mô hình cung cấp.', + apiKeyStatusNormal: 'Trạng thái APIKey bình thường', + editConfig: 'Chỉnh sửa cấu hình', + loadBalancingInfo: 'Theo mặc định, cân bằng tải sử dụng chiến lược Vòng tròn. Nếu giới hạn tốc độ được kích hoạt, thời gian hồi chiêu 1 phút sẽ được áp dụng.', + addConfig: 'Thêm cấu hình', + loadBalancingDescription: 'Giảm áp lực với nhiều bộ thông tin xác thực.', + apiKey: 'KHÓA API', + providerManaged: 'Nhà cung cấp được quản lý', + apiKeyRateLimit: 'Đã đạt đến giới hạn tốc độ, có sẵn sau {{giây}} giây', + upgradeForLoadBalancing: 'Nâng cấp gói của bạn để bật Cân bằng tải.', + loadBalancingLeastKeyWarning: 'Để bật cân bằng tải, ít nhất 2 phím phải được bật.', }, dataSource: { add: 'Thêm nguồn dữ liệu', @@ -369,6 +392,15 @@ const translation = { preview: 'Xem trước', }, }, + website: { + title: 'Trang mạng', + inactive: 'Không hoạt động', + with: 'Với', + active: 'Hoạt động', + configuredCrawlers: 'Trình thu thập thông tin đã định cấu hình', + description: 'Nhập nội dung từ các trang web bằng trình thu thập dữ liệu web.', + }, + configure: 'Cấu hình', }, plugin: { serpapi: { @@ -537,6 +569,10 @@ const translation = { created: 'Thẻ được tạo thành công', failed: 'Tạo thẻ không thành công', }, + errorMsg: { + fieldRequired: '{{trường}} là bắt buộc', + urlError: 'URL phải bắt đầu bằng http:// hoặc https://', + }, } export default translation diff --git a/web/i18n/vi-VN/dataset-creation.ts b/web/i18n/vi-VN/dataset-creation.ts index 23b210d177..da69020287 100644 --- a/web/i18n/vi-VN/dataset-creation.ts +++ b/web/i18n/vi-VN/dataset-creation.ts @@ -45,11 +45,35 @@ const translation = { input: 'Tên Kiến thức', placeholder: 'Vui lòng nhập', nameNotEmpty: 'Tên không thể để trống', - nameLengthInvaild: 'Tên phải từ 1 đến 40 ký tự', + nameLengthInvalid: 'Tên phải từ 1 đến 40 ký tự', cancelButton: 'Hủy', confirmButton: 'Tạo', failed: 'Tạo thất bại', }, + website: { + fireCrawlNotConfigured: 'Firecrawl không được cấu hình', + limit: 'Giới hạn', + run: 'Chạy', + firecrawlDoc: 'Tài liệu Firecrawl', + fireCrawlNotConfiguredDescription: 'Định cấu hình Firecrawl bằng khóa API để sử dụng.', + configure: 'Cấu hình', + scrapTimeInfo: 'Tổng cộng {{tổng}} trang được thu thập trong vòng {{thời gian}}', + options: 'Tùy chọn', + unknownError: 'Lỗi không xác định', + extractOnlyMainContent: 'Chỉ trích xuất nội dung chính (không có đầu trang, điều hướng, chân trang, v.v.)', + exceptionErrorTitle: 'Một ngoại lệ xảy ra trong khi chạy tác vụ Firecrawl:', + firecrawlDocLink: 'https://docs.dify.ai/guides/knowledge-base/sync-from-website', + selectAll: 'Chọn tất cả', + firecrawlTitle: 'Trích xuất nội dung web bằng 🔥Firecrawl', + totalPageScraped: 'Tổng số trang được cạo:', + excludePaths: 'Loại trừ đường dẫn', + includeOnlyPaths: 'Chỉ bao gồm đường dẫn', + maxDepth: 'Độ sâu tối đa', + preview: 'Download', + resetAll: 'Đặt lại tất cả', + crawlSubPage: 'Thu thập dữ liệu các trang phụ', + maxDepthTooltip: 'Độ sâu tối đa cần thu thập dữ liệu so với URL đã nhập. Độ sâu 0 chỉ cần cạo trang của url đã nhập, độ sâu 1 cạo url và mọi thứ sau khi nhậpURL + một /, v.v.', + }, }, stepTwo: { segmentation: 'Cài đặt phân đoạn', @@ -80,8 +104,8 @@ const translation = { QATitle: 'Phân đoạn theo định dạng Câu hỏi & Trả lời', QATip: 'Bật tùy chọn này sẽ tiêu tốn thêm token', QALanguage: 'Phân đoạn bằng', - emstimateCost: 'Ước tính', - emstimateSegment: 'Số đoạn ước tính', + estimateCost: 'Ước tính', + estimateSegment: 'Số đoạn ước tính', segmentCount: 'đoạn', calculating: 'Đang tính toán...', fileSource: 'Tiền xử lý tài liệu', @@ -104,9 +128,11 @@ const translation = { previewSwitchTipStart: 'Xem trước đoạn hiện tại đang ở định dạng văn bản, chuyển sang xem trước dạng câu hỏi và trả lời sẽ', previewSwitchTipEnd: ' tiêu tốn thêm token', characters: 'ký tự', - indexSettedTip: 'Để thay đổi phương pháp chỉ mục, vui lòng đi tới ', - retrivalSettedTip: 'Để thay đổi phương pháp truy xuất, vui lòng đi tới ', + indexSettingTip: 'Để thay đổi phương pháp chỉ mục, vui lòng đi tới ', + retrievalSettingTip: 'Để thay đổi phương pháp truy xuất, vui lòng đi tới ', datasetSettingLink: 'cài đặt Kiến thức.', + websiteSource: 'Trang web tiền xử lý', + webpageUnit: 'Trang', }, stepThree: { creationTitle: '🎉 Kiến thức đã được tạo', @@ -125,6 +151,11 @@ const translation = { modelButtonConfirm: 'Xác nhận', modelButtonCancel: 'Hủy', }, + firecrawl: { + getApiKeyLinkText: 'Lấy khóa API của bạn từ firecrawl.dev', + configFirecrawl: 'Định cấu hình 🔥Firecrawl', + apiKeyPlaceholder: 'Khóa API từ firecrawl.dev', + }, } export default translation diff --git a/web/i18n/vi-VN/dataset-documents.ts b/web/i18n/vi-VN/dataset-documents.ts index 5df6e40718..16570dff6e 100644 --- a/web/i18n/vi-VN/dataset-documents.ts +++ b/web/i18n/vi-VN/dataset-documents.ts @@ -13,6 +13,8 @@ const translation = { status: 'TRẠNG THÁI', action: 'THAO TÁC', }, + rename: 'Rename', + name: 'Tên', }, action: { uploadFile: 'Tải lên tệp mới', @@ -74,6 +76,7 @@ const translation = { error: 'Lỗi nhập', ok: 'OK', }, + addUrl: 'Thêm URL', }, metadata: { title: 'Siêu dữ liệu', diff --git a/web/i18n/vi-VN/dataset-settings.ts b/web/i18n/vi-VN/dataset-settings.ts index e6feb78278..cc68bea7ae 100644 --- a/web/i18n/vi-VN/dataset-settings.ts +++ b/web/i18n/vi-VN/dataset-settings.ts @@ -27,6 +27,8 @@ const translation = { longDescription: ' về phương pháp truy xuất. Bạn có thể thay đổi điều này bất kỳ lúc nào trong cài đặt Kiến thức.', }, save: 'Lưu', + permissionsInvitedMembers: 'Thành viên một phần trong nhóm', + me: '(Bạn)', }, } diff --git a/web/i18n/vi-VN/dataset.ts b/web/i18n/vi-VN/dataset.ts index 81b4597800..a2b9f8d087 100644 --- a/web/i18n/vi-VN/dataset.ts +++ b/web/i18n/vi-VN/dataset.ts @@ -71,6 +71,7 @@ const translation = { nTo1RetrievalLegacy: 'Truy xuất N-đến-1 sẽ chính thức bị loại bỏ từ tháng 9. Khuyến nghị sử dụng truy xuất đa đường dẫn mới nhất để có kết quả tốt hơn.', nTo1RetrievalLegacyLink: 'Tìm hiểu thêm', nTo1RetrievalLegacyLinkText: 'Truy xuất N-đến-1 sẽ chính thức bị loại bỏ vào tháng 9.', + defaultRetrievalTip: 'Truy xuất nhiều đường dẫn được sử dụng theo mặc định. Kiến thức được lấy từ nhiều cơ sở kiến thức và sau đó được xếp hạng lại.', } export default translation diff --git a/web/i18n/vi-VN/login.ts b/web/i18n/vi-VN/login.ts index 8d291c7f33..0ee39ffe2c 100644 --- a/web/i18n/vi-VN/login.ts +++ b/web/i18n/vi-VN/login.ts @@ -31,7 +31,7 @@ const translation = { pp: 'Chính sách bảo mật', tosDesc: 'Bằng cách đăng ký, bạn đồng ý với', goToInit: 'Nếu bạn chưa khởi tạo tài khoản, vui lòng chuyển đến trang khởi tạo', - donthave: 'Chưa có tài khoản?', + dontHave: 'Chưa có tài khoản?', invalidInvitationCode: 'Mã mời không hợp lệ', accountAlreadyInited: 'Tài khoản đã được khởi tạo', forgotPassword: 'Quên mật khẩu?', @@ -53,6 +53,7 @@ const translation = { nameEmpty: 'Vui lòng nhập tên', passwordEmpty: 'Vui lòng nhập mật khẩu', passwordInvalid: 'Mật khẩu phải chứa cả chữ và số, và có độ dài ít nhất 8 ký tự', + passwordLengthInValid: 'Mật khẩu phải có ít nhất 8 ký tự', }, license: { tip: 'Trước khi bắt đầu sử dụng Phiên bản Cộng đồng của Dify, vui lòng đọc', @@ -68,6 +69,7 @@ const translation = { activated: 'Đăng nhập ngay', adminInitPassword: 'Mật khẩu khởi tạo quản trị viên', validate: 'Xác thực', + sso: 'Tiếp tục với SSO', } export default translation diff --git a/web/i18n/vi-VN/share-app.ts b/web/i18n/vi-VN/share-app.ts index d440ad55dc..7078ecc299 100644 --- a/web/i18n/vi-VN/share-app.ts +++ b/web/i18n/vi-VN/share-app.ts @@ -2,7 +2,7 @@ const translation = { common: { welcome: '', appUnavailable: 'Ứng dụng không khả dụng', - appUnkonwError: 'Ứng dụng gặp lỗi không xác định', + appUnknownError: 'Ứng dụng gặp lỗi không xác định', }, chat: { newChat: 'Cuộc trò chuyện mới', @@ -10,7 +10,7 @@ const translation = { unpinnedTitle: 'Trò chuyện', newChatDefaultName: 'Cuộc trò chuyện mới', resetChat: 'Đặt lại cuộc trò chuyện', - powerBy: 'Được cung cấp bởi', + poweredBy: 'Được cung cấp bởi', prompt: 'Lời nhắc', privatePromptConfigTitle: 'Cài đặt cuộc trò chuyện', publicPromptConfigTitle: 'Lời nhắc ban đầu', diff --git a/web/i18n/vi-VN/tools.ts b/web/i18n/vi-VN/tools.ts index 40e16a5fa9..b03a6ccc98 100644 --- a/web/i18n/vi-VN/tools.ts +++ b/web/i18n/vi-VN/tools.ts @@ -5,6 +5,7 @@ const translation = { all: 'Tất cả', builtIn: 'Tích hợp sẵn', custom: 'Tùy chỉnh', + workflow: 'Quy trình làm việc', }, contribute: { line1: 'Tôi quan tâm đến việc ', @@ -75,6 +76,27 @@ const translation = { customDisclaimerPlaceholder: 'Vui lòng nhập tuyên bố từ chối trách nhiệm tùy chỉnh', deleteToolConfirmTitle: 'Xóa công cụ này?', deleteToolConfirmContent: 'Xóa công cụ là không thể hoàn tác. Người dùng sẽ không thể truy cập lại công cụ của bạn.', + toolInput: { + label: 'Tags', + methodParameter: 'Thông số', + name: 'Tên', + descriptionPlaceholder: 'Mô tả ý nghĩa của tham số', + methodSetting: 'Khung cảnh', + title: 'Công cụ nhập liệu', + methodSettingTip: 'Người dùng điền vào cấu hình công cụ', + required: 'Bắt buộc', + method: 'Phương pháp', + methodParameterTip: 'LLM lấp đầy trong quá trình suy luận', + description: 'Sự miêu tả', + labelPlaceholder: 'Chọn thẻ (tùy chọn)', + }, + nameForToolCallTip: 'Chỉ hỗ trợ số, chữ cái và dấu gạch dưới.', + nameForToolCall: 'Công cụ gọi tên', + nameForToolCallPlaceHolder: 'Được sử dụng để nhận dạng máy, chẳng hạn như getCurrentWeather, list_pets', + descriptionPlaceholder: 'Mô tả ngắn gọn về mục đích của công cụ, ví dụ: lấy nhiệt độ cho một vị trí cụ thể.', + description: 'Sự miêu tả', + confirmTitle: 'Xác nhận để lưu ?', + confirmTip: 'Các ứng dụng sử dụng công cụ này sẽ bị ảnh hưởng', }, test: { title: 'Kiểm tra', @@ -114,6 +136,18 @@ const translation = { toolRemoved: 'Công cụ đã bị xóa', notAuthorized: 'Công cụ chưa được xác thực', howToGet: 'Cách nhận', + addToolModal: { + category: 'loại', + manageInTools: 'Quản lý trong Công cụ', + type: 'kiểu', + add: 'thêm', + added: 'Thêm', + emptyTip: 'Đi tới "Quy trình làm việc -> Xuất bản dưới dạng công cụ"', + emptyTitle: 'Không có sẵn công cụ quy trình làm việc', + }, + toolNameUsageTip: 'Tên cuộc gọi công cụ để lý luận và nhắc nhở tổng đài viên', + customToolTip: 'Tìm hiểu thêm về các công cụ tùy chỉnh Dify', + openInStudio: 'Mở trong Studio', } export default translation diff --git a/web/i18n/vi-VN/workflow.ts b/web/i18n/vi-VN/workflow.ts index 3cb12f23ac..d850d1a732 100644 --- a/web/i18n/vi-VN/workflow.ts +++ b/web/i18n/vi-VN/workflow.ts @@ -36,7 +36,7 @@ const translation = { searchVar: 'Tìm kiếm biến', variableNamePlaceholder: 'Tên biến', setVarValuePlaceholder: 'Đặt giá trị biến', - needConnecttip: 'Bước này không được kết nối với bất kỳ điều gì', + needConnectTip: 'Bước này không được kết nối với bất kỳ điều gì', maxTreeDepth: 'Giới hạn tối đa {{depth}} nút trên mỗi nhánh', needEndNode: 'Phải thêm khối Kết thúc', needAnswerNode: 'Phải thêm khối Trả lời', @@ -69,6 +69,14 @@ const translation = { manageInTools: 'Quản lý trong công cụ', workflowAsToolTip: 'Cần cấu hình lại công cụ sau khi cập nhật quy trình làm việc.', viewDetailInTracingPanel: 'Xem chi tiết', + importSuccess: 'Nhập thành công', + backupCurrentDraft: 'Sao lưu dự thảo hiện tại', + chooseDSL: 'Chọn tệp DSL(yml)', + importDSLTip: 'Dự thảo hiện tại sẽ bị ghi đè. Xuất quy trình làm việc dưới dạng bản sao lưu trước khi nhập.', + importFailure: 'Nhập không thành công', + overwriteAndImport: 'Ghi đè và nhập', + importDSL: 'Nhập DSL', + syncingData: 'Đồng bộ hóa dữ liệu, chỉ vài giây.', }, env: { envPanelTitle: 'Biến Môi Trường', @@ -177,7 +185,8 @@ const translation = { 'logic': 'Logic', 'transform': 'Chuyển đổi', 'utilities': 'Tiện ích', - 'noResult': 'Không tìm thấy kết quả phù hợp', + 'noResult': 'Không tìm thấy kế;t quả phù hợp', + 'searchTool': 'Công cụ tìm kiếm', }, blocks: { 'start': 'Bắt đầu', @@ -403,10 +412,12 @@ const translation = { 'not empty': 'không trống', 'null': 'là null', 'not null': 'không là null', + 'regex match': 'Trận đấu Regex', }, enterValue: 'Nhập giá trị', addCondition: 'Thêm điều kiện', conditionNotSetup: 'Điều kiện chưa được thiết lập', + selectVariable: 'Chọn biến...', }, variableAssigner: { title: 'Gán biến', @@ -502,6 +513,25 @@ const translation = { iteration_other: '{{count}} Lặp', currentIteration: 'Lặp hiện tại', }, + note: { + editor: { + openLink: 'Mở', + italic: 'Nghiêng', + link: 'Liên kết', + medium: 'Đau vừa', + small: 'Nhỏ', + placeholder: 'Viết ghi chú của bạn...', + large: 'Lớn', + showAuthor: 'Hiển thị tác giả', + bulletList: 'Danh sách dấu đầu dòng', + bold: 'Dũng cảm', + unlink: 'Hủy liên kết', + invalidUrl: 'URL không hợp lệ', + strikethrough: 'Gạch ngang', + enterUrl: 'Nhập URL...', + }, + addNote: 'Thêm ghi chú', + }, }, tracing: { stopBy: 'Dừng bởi {{user}}', diff --git a/web/i18n/zh-Hans/app-api.ts b/web/i18n/zh-Hans/app-api.ts index f8f6ab7083..6b9048b66e 100644 --- a/web/i18n/zh-Hans/app-api.ts +++ b/web/i18n/zh-Hans/app-api.ts @@ -10,7 +10,7 @@ const translation = { pause: '暂停', playing: '播放中', loading: '加载中', - merMaind: { + merMaid: { rerender: '重新渲染', }, never: '从未', diff --git a/web/i18n/zh-Hans/app-debug.ts b/web/i18n/zh-Hans/app-debug.ts index febf80d786..62ef300f4d 100644 --- a/web/i18n/zh-Hans/app-debug.ts +++ b/web/i18n/zh-Hans/app-debug.ts @@ -298,7 +298,7 @@ const translation = { historyNoBeEmpty: '提示词中必须设置对话历史', queryNoBeEmpty: '提示词中必须设置查询内容', }, - variableConig: { + variableConfig: { 'addModalTitle': '添加变量', 'editModalTitle': '编辑变量', 'description': '设置变量 {{varName}}', diff --git a/web/i18n/zh-Hans/app.ts b/web/i18n/zh-Hans/app.ts index e12ed1b35d..ee316200fa 100644 --- a/web/i18n/zh-Hans/app.ts +++ b/web/i18n/zh-Hans/app.ts @@ -76,6 +76,11 @@ const translation = { emoji: '表情符号', image: '图片', }, + answerIcon: { + title: '使用 WebApp 图标替换 🤖', + description: '是否使用 WebApp 图标替换分享的应用界面中的 🤖', + descriptionInExplore: '是否使用 WebApp 图标替换 Explore 界面中的 🤖', + }, switch: '迁移为工作流编排', switchTipStart: '将为您创建一个使用工作流编排的新应用。新应用将', switchTip: '不能够', diff --git a/web/i18n/zh-Hans/common.ts b/web/i18n/zh-Hans/common.ts index 5333d18763..52ab7d6f02 100644 --- a/web/i18n/zh-Hans/common.ts +++ b/web/i18n/zh-Hans/common.ts @@ -37,6 +37,7 @@ const translation = { params: '参数设置', duplicate: '复制', rename: '重命名', + audioSourceUnavailable: '音源不可用', }, errorMsg: { fieldRequired: '{{field}} 为必填项', @@ -132,7 +133,8 @@ const translation = { workspace: '工作空间', createWorkspace: '创建工作空间', helpCenter: '帮助文档', - roadmapAndFeedback: '用户反馈', + communityFeedback: '用户反馈', + roadmap: '路线图', community: '社区', about: '关于', logout: '登出', @@ -196,16 +198,19 @@ const translation = { invitationSent: '邀请已发送', invitationSentTip: '邀请已发送,对方登录 Dify 后即可访问你的团队数据。', invitationLink: '邀请链接', - failedinvitationEmails: '邀请以下邮箱失败', + failedInvitationEmails: '邀请以下邮箱失败', ok: '好的', removeFromTeam: '移除团队', removeFromTeamTip: '将取消团队访问', setAdmin: '设为管理员', setMember: '设为普通成员', setEditor: '设为编辑', - disinvite: '取消邀请', + disInvite: '取消邀请', deleteMember: '删除成员', you: '(你)', + builderTip: '可以构建和编辑自己的应用程序', + setBuilder: 'Set as builder (设置为构建器)', + builder: '构建器', }, integrations: { connected: '登录方式', @@ -367,6 +372,7 @@ const translation = { loadBalancingLeastKeyWarning: '至少启用 2 个 Key 以使用负载均衡', loadBalancingInfo: '默认情况下,负载平衡使用 Round-robin 策略。如果触发速率限制,将应用 1 分钟的冷却时间', upgradeForLoadBalancing: '升级以解锁负载均衡功能', + apiKey: 'API 密钥', }, dataSource: { add: '添加数据源', diff --git a/web/i18n/zh-Hans/dataset-creation.ts b/web/i18n/zh-Hans/dataset-creation.ts index 257f409abd..47a15921f7 100644 --- a/web/i18n/zh-Hans/dataset-creation.ts +++ b/web/i18n/zh-Hans/dataset-creation.ts @@ -50,7 +50,7 @@ const translation = { input: '知识库名称', placeholder: '请输入知识库名称', nameNotEmpty: '名称不能为空', - nameLengthInvaild: '名称长度不能超过 40 个字符', + nameLengthInvalid: '名称长度不能超过 40 个字符', cancelButton: '取消', confirmButton: '创建', failed: '创建失败', @@ -109,8 +109,8 @@ const translation = { QATitle: '采用 Q&A 分段模式', QATip: '开启后将会消耗额外的 token', QALanguage: '分段使用', - emstimateCost: '执行嵌入预估消耗', - emstimateSegment: '预估分段数', + estimateCost: '执行嵌入预估消耗', + estimateSegment: '预估分段数', segmentCount: '段', calculating: '计算中...', fileSource: '预处理文档', @@ -135,8 +135,8 @@ const translation = { previewSwitchTipStart: '当前分段预览是文本模式,切换到 Q&A 模式将会', previewSwitchTipEnd: '消耗额外的 token', characters: '字符', - indexSettedTip: '要更改索引方法,请转到', - retrivalSettedTip: '要更改检索方法,请转到', + indexSettingTip: '要更改索引方法和 embedding 模型,请转到', + retrievalSettingTip: '要更改检索方法,请转到', datasetSettingLink: '知识库设置。', }, stepThree: { diff --git a/web/i18n/zh-Hans/dataset.ts b/web/i18n/zh-Hans/dataset.ts index f76be97818..013830af6f 100644 --- a/web/i18n/zh-Hans/dataset.ts +++ b/web/i18n/zh-Hans/dataset.ts @@ -55,6 +55,7 @@ const translation = { hybrid_search: '混合检索', invertedIndex: '倒排索引', }, + defaultRetrievalTip: '默认情况下使用多路召回。从多个知识库中检索知识,然后重新排序。', mixtureHighQualityAndEconomicTip: '混合使用高质量和经济型知识库需要配置 Rerank 模型。', inconsistentEmbeddingModelTip: '当所选知识库配置的 Embedding 模型不一致时,需要配置 Rerank 模型。', retrievalSettings: '召回设置', diff --git a/web/i18n/zh-Hans/login.ts b/web/i18n/zh-Hans/login.ts index 5ac9b9fcb4..f0a6ab76a3 100644 --- a/web/i18n/zh-Hans/login.ts +++ b/web/i18n/zh-Hans/login.ts @@ -31,7 +31,7 @@ const translation = { pp: '隐私政策', tosDesc: '使用即代表你并同意我们的', goToInit: '如果您还没有初始化账户,请前往初始化页面', - donthave: '还没有邀请码?', + dontHave: '还没有邀请码?', invalidInvitationCode: '无效的邀请码', accountAlreadyInited: '账户已经初始化', forgotPassword: '忘记密码?', @@ -53,6 +53,7 @@ const translation = { nameEmpty: '用户名不能为空', passwordEmpty: '密码不能为空', passwordInvalid: '密码必须包含字母和数字,且长度不小于8位', + passwordLengthInValid: '密码必须至少为 8 个字符', }, license: { tip: '启动 Dify 社区版之前, 请阅读 GitHub 上的', @@ -68,6 +69,7 @@ const translation = { activated: '现在登录', adminInitPassword: '管理员初始化密码', validate: '验证', + sso: '使用 SSO 继续', } export default translation diff --git a/web/i18n/zh-Hans/share-app.ts b/web/i18n/zh-Hans/share-app.ts index bb8e1574fd..968381bb37 100644 --- a/web/i18n/zh-Hans/share-app.ts +++ b/web/i18n/zh-Hans/share-app.ts @@ -2,7 +2,7 @@ const translation = { common: { welcome: '', appUnavailable: '应用不可用', - appUnkonwError: '应用不可用', + appUnknownError: '应用不可用', }, chat: { newChat: '新对话', @@ -10,7 +10,7 @@ const translation = { unpinnedTitle: '对话列表', newChatDefaultName: '新的对话', resetChat: '重置对话', - powerBy: 'Powered by', + poweredBy: 'Powered by', prompt: '提示词', privatePromptConfigTitle: '对话设置', publicPromptConfigTitle: '对话前提示词', @@ -32,7 +32,6 @@ const translation = { create: '运行一次', batch: '批量运行', saved: '已保存', - }, savedNoData: { title: '您还没有保存结果!', diff --git a/web/i18n/zh-Hans/workflow.ts b/web/i18n/zh-Hans/workflow.ts index 56d1de6ceb..0f00b117c1 100644 --- a/web/i18n/zh-Hans/workflow.ts +++ b/web/i18n/zh-Hans/workflow.ts @@ -36,7 +36,7 @@ const translation = { variableNamePlaceholder: '变量名', searchVar: '搜索变量', setVarValuePlaceholder: '设置变量值', - needConnecttip: '此节点尚未连接到其他节点', + needConnectTip: '此节点尚未连接到其他节点', maxTreeDepth: '每个分支最大限制 {{depth}} 个节点', needEndNode: '必须添加结束节点', needAnswerNode: '必须添加直接回复节点', @@ -412,6 +412,7 @@ const translation = { 'not empty': '不为空', 'null': '空', 'not null': '不为空', + 'regex match': '正则匹配', }, enterValue: '输入值', addCondition: '添加条件', diff --git a/web/i18n/zh-Hant/app-api.ts b/web/i18n/zh-Hant/app-api.ts index 18ae6dcfff..63a9778378 100644 --- a/web/i18n/zh-Hant/app-api.ts +++ b/web/i18n/zh-Hant/app-api.ts @@ -10,7 +10,7 @@ const translation = { pause: '暫停', playing: '播放中', loading: '載入中', - merMaind: { + merMaid: { rerender: '重新渲染', }, never: '從未', diff --git a/web/i18n/zh-Hant/app-debug.ts b/web/i18n/zh-Hant/app-debug.ts index ca4dfbb0cf..ad29195cb5 100644 --- a/web/i18n/zh-Hant/app-debug.ts +++ b/web/i18n/zh-Hant/app-debug.ts @@ -244,7 +244,7 @@ const translation = { historyNoBeEmpty: '提示詞中必須設定對話歷史', queryNoBeEmpty: '提示詞中必須設定查詢內容', }, - variableConig: { + variableConfig: { 'addModalTitle': '新增變數', 'editModalTitle': '編輯變數', 'description': '設定變數 {{varName}}', diff --git a/web/i18n/zh-Hant/app-overview.ts b/web/i18n/zh-Hant/app-overview.ts index ecf2b5c3b1..7ad7fc86d9 100644 --- a/web/i18n/zh-Hant/app-overview.ts +++ b/web/i18n/zh-Hant/app-overview.ts @@ -48,6 +48,8 @@ const translation = { title: '工作流程步驟', show: '展示', hide: '隱藏', + subTitle: '工作流詳細資訊', + showDesc: '在 WebApp 中顯示或隱藏工作流詳細資訊', }, chatColorTheme: '聊天顏色主題', chatColorThemeDesc: '設定聊天機器人的顏色主題', @@ -64,6 +66,12 @@ const translation = { customDisclaimerPlaceholder: '請輸入免責聲明', customDisclaimerTip: '客製化的免責聲明文字將在客戶端顯示,提供有關應用程式的額外資訊。', }, + sso: { + description: '所有使用者在使用 WebApp 之前都需要使用 SSO 登錄', + title: 'WebApp SSO', + tooltip: '聯繫管理員以啟用 WebApp SSO', + label: 'SSO 身份驗證', + }, }, embedded: { entry: '嵌入', @@ -123,7 +131,11 @@ const translation = { }, activeUsers: { title: '活躍使用者數', - explanation: '與 AI 有效互動,即有一問一答以上的唯一使用者數。提示詞編排和除錯的會話不計入。', + explanation: '每日AI互動次數。', + }, + totalConversations: { + title: '總對話數', + explanation: '每日AI對話次數;不包括提示工程/調試。', }, tokenUsage: { title: '費用消耗', diff --git a/web/i18n/zh-Hant/app.ts b/web/i18n/zh-Hant/app.ts index ff162c5b61..5d52bb102b 100644 --- a/web/i18n/zh-Hant/app.ts +++ b/web/i18n/zh-Hant/app.ts @@ -123,6 +123,15 @@ const translation = { removeConfirmContent: '當前配置正在使用中,移除它將關閉追蹤功能。', }, }, + answerIcon: { + descriptionInExplore: '是否使用 WebApp 圖示在 Explore 中取代 🤖', + title: '使用 WebApp 圖示取代 🤖', + description: '是否在共享應用程式中使用 WebApp 圖示進行取代 🤖', + }, + importFromDSLUrl: '寄件者 URL', + importFromDSL: '從 DSL 導入', + importFromDSLFile: '從 DSL 檔', + importFromDSLUrlPlaceholder: '在此處粘貼 DSL 連結', } export default translation diff --git a/web/i18n/zh-Hant/billing.ts b/web/i18n/zh-Hant/billing.ts index dd6b69e334..f318b6fa66 100644 --- a/web/i18n/zh-Hant/billing.ts +++ b/web/i18n/zh-Hant/billing.ts @@ -60,6 +60,8 @@ const translation = { bulkUpload: '批次上傳文件', agentMode: '代理模式', workflow: '工作流', + llmLoadingBalancing: 'LLM 負載均衡', + llmLoadingBalancingTooltip: '向模型添加多個 API 金鑰,從而有效地繞過 API 速率限制。', }, comingSoon: '即將推出', member: '成員', @@ -74,6 +76,7 @@ const translation = { }, ragAPIRequestTooltip: '指單獨呼叫 Dify 知識庫資料處理能力的 API。', receiptInfo: '只有團隊所有者和團隊管理員才能訂閱和檢視賬單資訊', + annotationQuota: '註釋配額', }, plans: { sandbox: { diff --git a/web/i18n/zh-Hant/common.ts b/web/i18n/zh-Hant/common.ts index 02296907d9..c1f3ed2b2b 100644 --- a/web/i18n/zh-Hant/common.ts +++ b/web/i18n/zh-Hant/common.ts @@ -37,6 +37,7 @@ const translation = { params: '引數設定', duplicate: '複製', rename: '重新命名', + audioSourceUnavailable: '音訊來源不可用', }, placeholder: { input: '請輸入', @@ -128,7 +129,8 @@ const translation = { workspace: '工作空間', createWorkspace: '建立工作空間', helpCenter: '幫助文件', - roadmapAndFeedback: '使用者反饋', + communityFeedback: '使用者反饋', + roadmap: '路線圖', community: '社群', about: '關於', logout: '登出', @@ -190,16 +192,21 @@ const translation = { invitationSent: '邀請已傳送', invitationSentTip: '邀請已傳送,對方登入 Dify 後即可訪問你的團隊資料。', invitationLink: '邀請連結', - failedinvitationEmails: '邀請以下郵箱失敗', + failedInvitationEmails: '邀請以下郵箱失敗', ok: '好的', removeFromTeam: '移除團隊', removeFromTeamTip: '將取消團隊訪問', setAdmin: '設為管理員', setMember: '設為普通成員', setEditor: '設為編輯', - disinvite: '取消邀請', + disInvite: '取消邀請', deleteMember: '刪除成員', you: '(你)', + setBuilder: 'Set as builder (設置為建構器)', + datasetOperator: '知識管理員', + builder: '建築工人', + builderTip: '可以構建和編輯自己的應用程式', + datasetOperatorTip: '只能管理知識庫', }, integrations: { connected: '登入方式', @@ -346,6 +353,22 @@ const translation = { quotaTip: '剩餘免費額度', loadPresets: '載入預設', parameters: '引數', + loadBalancingHeadline: '負載均衡', + apiKeyStatusNormal: 'APIKey 狀態正常', + defaultConfig: '默認配置', + configLoadBalancing: '配置負載均衡', + loadBalancingDescription: '使用多組憑證減輕壓力。', + addConfig: '添加配置', + upgradeForLoadBalancing: '升級您的計劃以啟用Load Balancing。', + apiKey: 'API 金鑰', + loadBalancing: '負載均衡', + providerManagedDescription: '使用模型提供程式提供的單組憑證。', + modelHasBeenDeprecated: '此模型已棄用', + apiKeyRateLimit: '已達到速率限制,在 {{seconds}} 秒後可用', + providerManaged: '提供者管理', + editConfig: '編輯配置', + loadBalancingInfo: '默認情況下,負載均衡使用 Round-robin 策略。如果觸發了速率限制,將應用 1 分鐘的冷卻時間。', + loadBalancingLeastKeyWarning: '要啟用負載均衡,必須至少啟用 2 個金鑰。', }, dataSource: { add: '新增資料來源', @@ -369,6 +392,15 @@ const translation = { preview: '預覽', }, }, + website: { + active: '積極', + title: '網站', + with: '跟', + inactive: '無效', + configuredCrawlers: '配置的爬網程式', + description: '使用 Web 爬蟲從網站導入內容。', + }, + configure: '配置', }, plugin: { serpapi: { @@ -537,6 +569,10 @@ const translation = { created: '標籤建立成功', failed: '標籤建立失敗', }, + errorMsg: { + fieldRequired: '{{field}} 為必填項', + urlError: 'URL應以 http:// 或 https:// 開頭', + }, } export default translation diff --git a/web/i18n/zh-Hant/dataset-creation.ts b/web/i18n/zh-Hant/dataset-creation.ts index 849e1578da..fd810d41c1 100644 --- a/web/i18n/zh-Hant/dataset-creation.ts +++ b/web/i18n/zh-Hant/dataset-creation.ts @@ -45,11 +45,35 @@ const translation = { input: '知識庫名稱', placeholder: '請輸入知識庫名稱', nameNotEmpty: '名稱不能為空', - nameLengthInvaild: '名稱長度不能超過 40 個字元', + nameLengthInvalid: '名稱長度不能超過 40 個字元', cancelButton: '取消', confirmButton: '建立', failed: '建立失敗', }, + website: { + maxDepth: '最大深度', + selectAll: '全選', + exceptionErrorTitle: '運行 Firecrawl 作業時發生異常:', + run: '跑', + extractOnlyMainContent: '僅提取主要內容(無頁眉、導航、頁腳等)', + fireCrawlNotConfiguredDescription: '使用 API 金鑰配置 Firecrawl 以使用它。', + limit: '限制', + crawlSubPage: '抓取子頁面', + firecrawlDocLink: 'https://docs.dify.ai/guides/knowledge-base/sync-from-website', + preview: '預覽', + configure: '配置', + excludePaths: '排除路徑', + options: '選項', + firecrawlDoc: 'Firecrawl 文件', + totalPageScraped: '抓取的總頁數:', + firecrawlTitle: '使用 🔥Firecrawl 提取 Web 內容', + includeOnlyPaths: '僅包含路徑', + resetAll: '全部重置', + scrapTimeInfo: '在 {{time}} 秒內總共抓取了 {{total}} 個頁面', + unknownError: '未知錯誤', + fireCrawlNotConfigured: '未配置 Firecrawl', + maxDepthTooltip: '相對於輸入的 URL 的最大爬網深度。深度 0 只是抓取輸入的 url 的頁面,深度 1 抓取 url 以及 enteredURL + 1 / 之後的所有內容,依此類推。', + }, }, stepTwo: { segmentation: '分段設定', @@ -80,8 +104,8 @@ const translation = { QATitle: '採用 Q&A 分段模式', QATip: '開啟後將會消耗額外的 token', QALanguage: '分段使用', - emstimateCost: '執行嵌入預估消耗', - emstimateSegment: '預估分段數', + estimateCost: '執行嵌入預估消耗', + estimateSegment: '預估分段數', segmentCount: '段', calculating: '計算中...', fileSource: '預處理文件', @@ -104,9 +128,11 @@ const translation = { previewSwitchTipStart: '當前分段預覽是文字模式,切換到 Q&A 模式將會', previewSwitchTipEnd: '消耗額外的 token', characters: '字元', - indexSettedTip: '要更改索引方法,請轉到', - retrivalSettedTip: '要更改檢索方法,請轉到', + indexSettingTip: '要更改索引方法,請轉到', + retrievalSettingTip: '要更改檢索方法,請轉到', datasetSettingLink: '知識庫設定。', + websiteSource: '預處理網站', + webpageUnit: '頁面', }, stepThree: { creationTitle: '🎉 知識庫已建立', @@ -125,6 +151,11 @@ const translation = { modelButtonConfirm: '確認停止', modelButtonCancel: '取消', }, + firecrawl: { + configFirecrawl: '配置 🔥Firecrawl', + apiKeyPlaceholder: '來自 firecrawl.dev 的 API 金鑰', + getApiKeyLinkText: '從 firecrawl.dev 獲取 API 金鑰', + }, } export default translation diff --git a/web/i18n/zh-Hant/dataset-documents.ts b/web/i18n/zh-Hant/dataset-documents.ts index ccc0fcf764..b4e6b44181 100644 --- a/web/i18n/zh-Hant/dataset-documents.ts +++ b/web/i18n/zh-Hant/dataset-documents.ts @@ -13,6 +13,8 @@ const translation = { status: '狀態', action: '操作', }, + name: '名字', + rename: '重新命名', }, action: { uploadFile: '上傳新檔案', @@ -74,6 +76,7 @@ const translation = { error: '匯入出錯', ok: '確定', }, + addUrl: '添加 URL', }, metadata: { title: '元資料', diff --git a/web/i18n/zh-Hant/dataset-settings.ts b/web/i18n/zh-Hant/dataset-settings.ts index d18c3fdd9b..f34d1d4acc 100644 --- a/web/i18n/zh-Hant/dataset-settings.ts +++ b/web/i18n/zh-Hant/dataset-settings.ts @@ -27,6 +27,8 @@ const translation = { longDescription: '關於檢索方法,您可以隨時在知識庫設定中更改此設定。', }, save: '儲存', + permissionsInvitedMembers: '部分團隊成員', + me: '(您)', }, } diff --git a/web/i18n/zh-Hant/dataset.ts b/web/i18n/zh-Hant/dataset.ts index 1e011bc987..1888a28631 100644 --- a/web/i18n/zh-Hant/dataset.ts +++ b/web/i18n/zh-Hant/dataset.ts @@ -71,6 +71,7 @@ const translation = { nTo1RetrievalLegacy: 'N對1檢索將從9月起正式棄用。建議使用最新的多路徑檢索以獲得更好的結果。', nTo1RetrievalLegacyLink: '了解更多', nTo1RetrievalLegacyLinkText: 'N對1檢索將於9月正式棄用。', + defaultRetrievalTip: '默認情況下,使用多路徑檢索。從多個知識庫中檢索知識,然後重新排名。', } export default translation diff --git a/web/i18n/zh-Hant/login.ts b/web/i18n/zh-Hant/login.ts index cce869f38a..649f618158 100644 --- a/web/i18n/zh-Hant/login.ts +++ b/web/i18n/zh-Hant/login.ts @@ -31,7 +31,7 @@ const translation = { pp: '隱私政策', tosDesc: '使用即代表你並同意我們的', goToInit: '如果您還沒有初始化賬戶,請前往初始化頁面', - donthave: '還沒有邀請碼?', + dontHave: '還沒有邀請碼?', invalidInvitationCode: '無效的邀請碼', accountAlreadyInited: '賬戶已經初始化', forgotPassword: '忘記密碼?', @@ -53,6 +53,7 @@ const translation = { nameEmpty: '使用者名稱不能為空', passwordEmpty: '密碼不能為空', passwordInvalid: '密碼必須包含字母和數字,且長度不小於8位', + passwordLengthInValid: '密碼必須至少為8個字元', }, license: { tip: '啟動 Dify 社群版之前, 請閱讀 GitHub 上的', @@ -68,6 +69,7 @@ const translation = { activated: '現在登入', adminInitPassword: '管理員初始化密碼', validate: '驗證', + sso: '繼續使用 SSO', } export default translation diff --git a/web/i18n/zh-Hant/share-app.ts b/web/i18n/zh-Hant/share-app.ts index e91cbaf121..ea5f206985 100644 --- a/web/i18n/zh-Hant/share-app.ts +++ b/web/i18n/zh-Hant/share-app.ts @@ -2,7 +2,7 @@ const translation = { common: { welcome: '', appUnavailable: '應用不可用', - appUnkonwError: '應用不可用', + appUnknownError: '應用不可用', }, chat: { newChat: '新對話', @@ -10,7 +10,7 @@ const translation = { unpinnedTitle: '對話列表', newChatDefaultName: '新的對話', resetChat: '重置對話', - powerBy: 'Powered by', + poweredBy: 'Powered by', prompt: '提示詞', privatePromptConfigTitle: '對話設定', publicPromptConfigTitle: '對話前提示詞', @@ -32,7 +32,6 @@ const translation = { create: '執行一次', batch: '批次執行', saved: '已儲存', - }, savedNoData: { title: '您還沒有儲存結果!', diff --git a/web/i18n/zh-Hant/tools.ts b/web/i18n/zh-Hant/tools.ts index 58ba9f5c81..d45980c017 100644 --- a/web/i18n/zh-Hant/tools.ts +++ b/web/i18n/zh-Hant/tools.ts @@ -5,6 +5,7 @@ const translation = { all: '全部', builtIn: '內建', custom: '自定義', + workflow: '工作流', }, contribute: { line1: '我有興趣為 ', @@ -75,6 +76,27 @@ const translation = { customDisclaimerPlaceholder: '請輸入自定義免責聲明', deleteToolConfirmTitle: '刪除這個工具?', deleteToolConfirmContent: '刪除工具是不可逆的。用戶將無法再訪問您的工具。', + toolInput: { + labelPlaceholder: '選擇標籤(選擇標籤)', + label: '標籤', + required: '必填', + methodSettingTip: '用戶填寫工具配置', + name: '名字', + description: '描述', + methodParameterTip: '推理期間 LLM 填充', + method: '方法', + title: '工具輸入', + methodSetting: '設置', + methodParameter: '參數', + descriptionPlaceholder: '參數含義的描述', + }, + description: '描述', + nameForToolCall: '工具調用名稱', + confirmTitle: '確認儲存 ?', + descriptionPlaceholder: '工具用途的簡要描述,例如,獲取特定位置的溫度。', + nameForToolCallTip: '僅支援數位、字母和下劃線。', + confirmTip: '使用此工具的應用程式將受到影響', + nameForToolCallPlaceHolder: '用於機器識別,例如 getCurrentWeather、list_pets', }, test: { title: '測試', @@ -114,6 +136,18 @@ const translation = { toolRemoved: '工具已被移除', notAuthorized: '工具未授權', howToGet: '如何獲取', + addToolModal: { + add: '加', + type: '類型', + added: '添加', + manageInTools: '在工具中管理', + category: '類別', + emptyTitle: '沒有可用的工作流程工具', + emptyTip: '轉到“工作流 - >發佈為工具”', + }, + customToolTip: '瞭解有關 Dify 自訂工具的更多資訊', + toolNameUsageTip: '用於代理推理和提示的工具調用名稱', + openInStudio: '在 Studio 中打開', } export default translation diff --git a/web/i18n/zh-Hant/workflow.ts b/web/i18n/zh-Hant/workflow.ts index 3a456858fe..618fa8ce2e 100644 --- a/web/i18n/zh-Hant/workflow.ts +++ b/web/i18n/zh-Hant/workflow.ts @@ -36,7 +36,7 @@ const translation = { variableNamePlaceholder: '變量名', searchVar: '搜索變量', setVarValuePlaceholder: '設置變量值', - needConnecttip: '此節點尚未連接到其他節點', + needConnectTip: '此節點尚未連接到其他節點', maxTreeDepth: '每個分支最大限制 {{depth}} 個節點', needEndNode: '必須添加結束節點', needAnswerNode: '必須添加直接回覆節點', @@ -69,6 +69,14 @@ const translation = { manageInTools: '訪問工具頁', workflowAsToolTip: '工作流更新後需要重新配置工具參數', viewDetailInTracingPanel: '查看詳細信息', + importDSL: '導入 DSL', + backupCurrentDraft: 'Backup Current Draft', + overwriteAndImport: '覆蓋和導入', + importSuccess: '導入成功', + chooseDSL: '選擇 DSL(yml) 檔', + syncingData: '同步數據,只需幾秒鐘。', + importDSLTip: '當前草稿將被覆蓋。在導入之前將工作流匯出為備份。', + importFailure: '匯入失敗', }, env: { envPanelTitle: '環境變數', @@ -142,6 +150,7 @@ const translation = { noteAdd: '註釋已添加', noteChange: '註釋已更改', edgeDelete: '區塊已斷開連接', + noteDelete: '註釋已刪除', }, errorMsg: { fieldRequired: '{{field}} 不能為空', @@ -177,6 +186,7 @@ const translation = { 'transform': '轉換', 'utilities': '工具', 'noResult': '未找到匹配項', + 'searchTool': '搜索工具', }, blocks: { 'start': '開始', @@ -402,10 +412,12 @@ const translation = { 'not empty': '不為空', 'null': '空', 'not null': '不為空', + 'regex match': '正則表達式匹配', }, enterValue: '輸入值', addCondition: '添加條件', conditionNotSetup: '條件未設置', + selectVariable: '選擇變數...', }, variableAssigner: { title: '變量賦值', @@ -501,6 +513,25 @@ const translation = { iteration_other: '{{count}}個迭代', currentIteration: '當前迭代', }, + note: { + editor: { + link: '連結', + openLink: '打開', + medium: '中等', + small: '小', + invalidUrl: 'URL 無效', + italic: '斜體的', + bulletList: '項目符號清單', + large: '大', + unlink: '取消連結', + enterUrl: '輸入網址...', + bold: '大膽', + showAuthor: '顯示作者', + strikethrough: '刪除線', + placeholder: '寫下您的筆記...', + }, + addNote: '添加註釋', + }, }, tracing: { stopBy: '由{{user}}終止', diff --git a/web/models/app.ts b/web/models/app.ts index 82efcd5fa0..e550b82ab6 100644 --- a/web/models/app.ts +++ b/web/models/app.ts @@ -4,7 +4,7 @@ import type { App, AppSSO, AppTemplate, SiteConfig } from '@/types/app' /* export type App = { id: string name: string - decription: string + description: string mode: AppMode enable_site: boolean enable_api: boolean @@ -103,15 +103,15 @@ export type AppTokenCostsResponse = { export type UpdateAppModelConfigResponse = { result: string } -export type ApikeyItemResponse = { +export type ApiKeyItemResponse = { id: string token: string last_used_at: string created_at: string } -export type ApikeysListResponse = { - data: ApikeyItemResponse[] +export type ApiKeysListResponse = { + data: ApiKeyItemResponse[] } export type CreateApiKeyResponse = { diff --git a/web/models/datasets.ts b/web/models/datasets.ts index 0ae7831245..23d1fe6136 100644 --- a/web/models/datasets.ts +++ b/web/models/datasets.ts @@ -227,6 +227,8 @@ export type DocumentReq = { export type CreateDocumentReq = DocumentReq & { data_source: DataSource retrieval_model: RetrievalConfig + embedding_model: string + embedding_model_provider: string } export type IndexingEstimateParams = DocumentReq & Partial & { @@ -437,7 +439,7 @@ export type RelatedAppResponse = { total: number } -export type SegmentUpdator = { +export type SegmentUpdater = { content: string answer?: string keywords?: string[] diff --git a/web/models/debug.ts b/web/models/debug.ts index 2b2af80065..565798e598 100644 --- a/web/models/debug.ts +++ b/web/models/debug.ts @@ -215,7 +215,7 @@ export type LogSessionListResponse = { query: string // user's query question message: string // prompt send to LLM answer: string - creat_at: string + created_at: string }[] total: number page: number @@ -224,7 +224,7 @@ export type LogSessionListResponse = { // log session detail and debug export type LogSessionDetailResponse = { id: string - cnversation_id: string + conversation_id: string model_provider: string query: string inputs: Record[] diff --git a/web/models/explore.ts b/web/models/explore.ts index 78dd2e8675..ad60d99c6f 100644 --- a/web/models/explore.ts +++ b/web/models/explore.ts @@ -8,6 +8,7 @@ export type AppBasicInfo = { icon_url: string name: string description: string + use_icon_as_answer_icon: boolean } export type AppCategory = 'Writing' | 'Translate' | 'HR' | 'Programming' | 'Assistant' diff --git a/web/models/log.ts b/web/models/log.ts index 6f8ebb1a78..8da1c4cf4e 100644 --- a/web/models/log.ts +++ b/web/models/log.ts @@ -6,7 +6,7 @@ import type { } from '@/app/components/workflow/types' import type { Metadata } from '@/app/components/base/chat/chat/type' -// Log type contains key:string conversation_id:string created_at:string quesiton:string answer:string +// Log type contains key:string conversation_id:string created_at:string question:string answer:string export type Conversation = { id: string key: string diff --git a/web/models/share.ts b/web/models/share.ts index 127f3d0a51..3521365e82 100644 --- a/web/models/share.ts +++ b/web/models/share.ts @@ -25,6 +25,7 @@ export type SiteInfo = { privacy_policy?: string custom_disclaimer?: string show_workflow_steps?: boolean + use_icon_as_answer_icon?: boolean } export type AppMeta = { diff --git a/web/package.json b/web/package.json index e896f58886..b6275f20ae 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "dify-web", - "version": "0.7.2", + "version": "0.7.3", "private": true, "engines": { "node": ">=18.17.0" @@ -15,7 +15,8 @@ "prepare": "cd ../ && node -e \"if (process.env.NODE_ENV !== 'production'){process.exit(1)} \" || husky install ./web/.husky", "gen-icons": "node ./app/components/base/icons/script.js", "uglify-embed": "node ./bin/uglify-embed", - "check-i18n": "node ./i18n/script.js", + "check-i18n": "node ./i18n/check-i18n.js", + "auto-gen-i18n": "node ./i18n/auto-gen-i18n.js", "test": "jest", "test:watch": "jest --watch" }, @@ -86,6 +87,7 @@ "reactflow": "^11.11.3", "recordrtc": "^5.6.2", "rehype-katex": "^6.0.2", + "rehype-raw": "^7.0.0", "remark-breaks": "^3.0.2", "remark-gfm": "^3.0.1", "remark-math": "^5.1.1", @@ -126,6 +128,7 @@ "@types/sortablejs": "^1.15.1", "@types/uuid": "^9.0.8", "autoprefixer": "^10.4.14", + "bing-translate-api": "^4.0.2", "code-inspector-plugin": "^0.13.0", "cross-env": "^7.0.3", "eslint": "^8.36.0", @@ -134,6 +137,7 @@ "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "lint-staged": "^13.2.2", + "magicast": "^0.3.4", "postcss": "^8.4.31", "sass": "^1.61.0", "tailwindcss": "^3.4.4", diff --git a/web/public/embed.js b/web/public/embed.js index 14420f0c8c..8ed7a67dc8 100644 --- a/web/public/embed.js +++ b/web/public/embed.js @@ -73,7 +73,7 @@ box-shadow: rgba(150, 150, 150, 0.2) 0px 10px 30px 0px, rgba(150, 150, 150, 0.2) 0px 0px 0px 1px; bottom: 5rem; right: 1rem; width: 24rem; max-width: calc(100vw - 2rem); height: 40rem; max-height: calc(100vh - 6rem); border-radius: 0.75rem; display: flex; z-index: 2147483647; - overflow: hidden; left: unset; background-color: #F3F4F6; + overflow: hidden; left: unset; background-color: #F3F4F6;user-select: none; `; document.body.appendChild(iframe); @@ -255,6 +255,9 @@ if (!document.getElementById(buttonId)) { createButton(); } + + createIframe(); + document.getElementById(iframeId).style.display = 'none'; } // Add esc Exit keyboard event triggered diff --git a/web/public/embed.min.js b/web/public/embed.min.js index ec721a204d..0e023cb5d1 100644 --- a/web/public/embed.min.js +++ b/web/public/embed.min.js @@ -1 +1,31 @@ -!function(){const e="difyChatbotConfig",t="dify-chatbot-bubble-button",n="dify-chatbot-bubble-window",o=window[e],i={open:'\n \n ',close:'\n \n '};async function d(){if(!o||!o.token)return void console.error(`${e} is empty or token is not provided`);const d=new URLSearchParams(await async function(){const e=o?.inputs||{},t={};return await Promise.all(Object.entries(e).map((async([e,n])=>{t[e]=await async function(e){const t=(new TextEncoder).encode(e),n=new Response(new Blob([t]).stream().pipeThrough(new CompressionStream("gzip"))).arrayBuffer(),o=new Uint8Array(await n);return btoa(String.fromCharCode(...o))}(n)}))),t}()),s=`${o.baseUrl||`https://${o.isDev?"dev.":""}udify.app`}/chatbot/${o.token}?${d}`;function c(){const e=document.getElementById(n),o=document.getElementById(t);if(e&&o){const t=o.getBoundingClientRect(),n=window.innerHeight-t.bottom,i=window.innerWidth-t.right,d=t.left;e.style.bottom=`${n+t.height+5+e.clientHeight>window.innerHeight?n-e.clientHeight-5:n+t.height+5}px`,e.style.right=`${i+e.clientWidth>window.innerWidth?window.innerWidth-d-e.clientWidth:i}px`}}s.length>2048&&console.error("The URL is too long, please reduce the number of inputs to prevent the bot from failing to load"),document.getElementById(t)||function(){const e=document.createElement("div");Object.entries(o.containerProps||{}).forEach((([t,n])=>{"className"===t?e.classList.add(...n.split(" ")):"style"===t?"object"==typeof n?Object.assign(e.style,n):e.style.cssText=n:"function"==typeof n?e.addEventListener(t.replace(/^on/,"").toLowerCase(),n):e[t]=n})),e.id=t;const d=document.createElement("style");document.head.appendChild(d),d.sheet.insertRule(`\n #${e.id} {\n position: fixed;\n bottom: var(--${e.id}-bottom, 1rem);\n right: var(--${e.id}-right, 1rem);\n left: var(--${e.id}-left, unset);\n top: var(--${e.id}-top, unset);\n width: var(--${e.id}-width, 50px);\n height: var(--${e.id}-height, 50px);\n border-radius: var(--${e.id}-border-radius, 25px);\n background-color: var(--${e.id}-bg-color, #155EEF);\n box-shadow: var(--${e.id}-box-shadow, rgba(0, 0, 0, 0.2) 0px 4px 8px 0px);\n cursor: pointer;\n z-index: 2147483647;\n transition: all 0.2s ease-in-out 0s;\n }\n `),d.sheet.insertRule(`\n #${e.id}:hover {\n transform: var(--${e.id}-hover-transform, scale(1.1));\n }\n `);const l=document.createElement("div");l.style.cssText="display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; z-index: 2147483647;",l.innerHTML=i.open,e.appendChild(l),document.body.appendChild(e),e.addEventListener("click",(function(){const e=document.getElementById(n);if(!e)return function(){const e=document.createElement("iframe");e.allow="fullscreen;microphone",e.title="dify chatbot bubble window",e.id=n,e.src=s,e.style.cssText="\n border: none; position: fixed; flex-direction: column; justify-content: space-between;\n box-shadow: rgba(150, 150, 150, 0.2) 0px 10px 30px 0px, rgba(150, 150, 150, 0.2) 0px 0px 0px 1px;\n bottom: 5rem; right: 1rem; width: 24rem; max-width: calc(100vw - 2rem); height: 40rem;\n max-height: calc(100vh - 6rem); border-radius: 0.75rem; display: flex; z-index: 2147483647;\n overflow: hidden; left: unset; background-color: #F3F4F6;\n ",document.body.appendChild(e)}(),c(),this.title="Exit (ESC)",l.innerHTML=i.close,void document.addEventListener("keydown",r);e.style.display="none"===e.style.display?"block":"none",l.innerHTML="none"===e.style.display?i.open:i.close,"none"===e.style.display?document.removeEventListener("keydown",r):document.addEventListener("keydown",r),c()})),o.draggable&&function(e,o){let d,r,s=!1;function c(t){s=!0,d=t.clientX-e.offsetLeft,r=t.clientY-e.offsetTop}function l(c){if(!s)return;e.style.transition="none",e.style.cursor="grabbing";const l=document.getElementById(n);l&&(l.style.display="none",e.querySelector("div").innerHTML=i.open);const a=c.clientX-d,h=window.innerHeight-c.clientY-r,p=e.getBoundingClientRect(),u=window.innerWidth-p.width,m=window.innerHeight-p.height;"x"!==o&&"both"!==o||e.style.setProperty(`--${t}-left`,`${Math.max(0,Math.min(a,u))}px`),"y"!==o&&"both"!==o||e.style.setProperty(`--${t}-bottom`,`${Math.max(0,Math.min(h,m))}px`)}function a(){s=!1,e.style.transition="",e.style.cursor="pointer"}e.addEventListener("mousedown",c),document.addEventListener("mousemove",l),document.addEventListener("mouseup",a)}(e,o.dragAxis||"both")}()}function r(e){if("Escape"===e.key){const e=document.getElementById(n),o=document.getElementById(t);e&&"none"!==e.style.display&&(e.style.display="none",o.querySelector("div").innerHTML=i.open)}}document.addEventListener("keydown",r),o?.dynamicScript?d():document.body.onload=d}(); +(()=>{let t="difyChatbotConfig",a="dify-chatbot-bubble-button",c="dify-chatbot-bubble-window",h=window[t],p={open:` + + `,close:` + + `};async function e(){if(h&&h.token){var e=new URLSearchParams(await(async()=>{var e=h?.inputs||{};let n={};return await Promise.all(Object.entries(e).map(async([e,t])=>{n[e]=(e=t,e=(new TextEncoder).encode(e),e=new Response(new Blob([e]).stream().pipeThrough(new CompressionStream("gzip"))).arrayBuffer(),e=new Uint8Array(await e),await btoa(String.fromCharCode(...e)))})),n})());let t=`${h.baseUrl||`https://${h.isDev?"dev.":""}udify.app`}/chatbot/${h.token}?`+e;function o(){var e=document.createElement("iframe");e.allow="fullscreen;microphone",e.title="dify chatbot bubble window",e.id=c,e.src=t,e.style.cssText=` + border: none; position: fixed; flex-direction: column; justify-content: space-between; + box-shadow: rgba(150, 150, 150, 0.2) 0px 10px 30px 0px, rgba(150, 150, 150, 0.2) 0px 0px 0px 1px; + bottom: 5rem; right: 1rem; width: 24rem; max-width: calc(100vw - 2rem); height: 40rem; + max-height: calc(100vh - 6rem); border-radius: 0.75rem; display: flex; z-index: 2147483647; + overflow: hidden; left: unset; background-color: #F3F4F6;user-select: none; + `,document.body.appendChild(e)}function i(){var e,t,n,o=document.getElementById(c),i=document.getElementById(a);o&&i&&(i=i.getBoundingClientRect(),e=window.innerHeight-i.bottom,t=window.innerWidth-i.right,n=i.left,o.style.bottom=`${e+i.height+5+o.clientHeight>window.innerHeight?e-o.clientHeight-5:e+i.height+5}px`,o.style.right=`${t+o.clientWidth>window.innerWidth?window.innerWidth-n-o.clientWidth:t}px`)}function n(){let n=document.createElement("div");Object.entries(h.containerProps||{}).forEach(([e,t])=>{"className"===e?n.classList.add(...t.split(" ")):"style"===e?"object"==typeof t?Object.assign(n.style,t):n.style.cssText=t:"function"==typeof t?n.addEventListener(e.replace(/^on/,"").toLowerCase(),t):n[e]=t}),n.id=a;var e=document.createElement("style");document.head.appendChild(e),e.sheet.insertRule(` + #${n.id} { + position: fixed; + bottom: var(--${n.id}-bottom, 1rem); + right: var(--${n.id}-right, 1rem); + left: var(--${n.id}-left, unset); + top: var(--${n.id}-top, unset); + width: var(--${n.id}-width, 50px); + height: var(--${n.id}-height, 50px); + border-radius: var(--${n.id}-border-radius, 25px); + background-color: var(--${n.id}-bg-color, #155EEF); + box-shadow: var(--${n.id}-box-shadow, rgba(0, 0, 0, 0.2) 0px 4px 8px 0px); + cursor: pointer; + z-index: 2147483647; + transition: all 0.2s ease-in-out 0s; + } + `),e.sheet.insertRule(` + #${n.id}:hover { + transform: var(--${n.id}-hover-transform, scale(1.1)); + } + `);let t=document.createElement("div");if(t.style.cssText="display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; z-index: 2147483647;",t.innerHTML=p.open,n.appendChild(t),document.body.appendChild(n),n.addEventListener("click",function(){var e=document.getElementById(c);e?(e.style.display="none"===e.style.display?"block":"none",t.innerHTML="none"===e.style.display?p.open:p.close,"none"===e.style.display?document.removeEventListener("keydown",d):document.addEventListener("keydown",d),i()):(o(),i(),this.title="Exit (ESC)",t.innerHTML=p.close,document.addEventListener("keydown",d))}),h.draggable){var s=n;var l=h.dragAxis||"both";let i=!1,d,r;s.addEventListener("mousedown",function(e){i=!0,d=e.clientX-s.offsetLeft,r=e.clientY-s.offsetTop}),document.addEventListener("mousemove",function(e){var t,n,o;i&&(s.style.transition="none",s.style.cursor="grabbing",(t=document.getElementById(c))&&(t.style.display="none",s.querySelector("div").innerHTML=p.open),t=e.clientX-d,e=window.innerHeight-e.clientY-r,o=s.getBoundingClientRect(),n=window.innerWidth-o.width,o=window.innerHeight-o.height,"x"!==l&&"both"!==l||s.style.setProperty(`--${a}-left`,Math.max(0,Math.min(t,n))+"px"),"y"!==l&&"both"!==l||s.style.setProperty(`--${a}-bottom`,Math.max(0,Math.min(e,o))+"px"))}),document.addEventListener("mouseup",function(){i=!1,s.style.transition="",s.style.cursor="pointer"})}}2048('apps', { body: { name, icon_type, icon, icon_background, mode, description, model_config: config } }) } -export const updateAppInfo: Fetcher = ({ appID, name, icon_type, icon, icon_background, description }) => { - return put(`apps/${appID}`, { body: { name, icon_type, icon, icon_background, description } }) +export const updateAppInfo: Fetcher = ({ appID, name, icon_type, icon, icon_background, description, use_icon_as_answer_icon }) => { + return put(`apps/${appID}`, { body: { name, icon_type, icon, icon_background, description, use_icon_as_answer_icon } }) } export const copyApp: Fetcher = ({ appID, name, icon_type, icon, icon_background, mode, description }) => { @@ -110,8 +110,8 @@ export const fetchAppListNoMock: Fetcher(url, params) } -export const fetchApiKeysList: Fetcher }> = ({ url, params }) => { - return get(url, params) +export const fetchApiKeysList: Fetcher }> = ({ url, params }) => { + return get(url, params) } export const delApikey: Fetcher }> = ({ url, params }) => { diff --git a/web/service/base.ts b/web/service/base.ts index bda83f1c8e..8f1b22bc1b 100644 --- a/web/service/base.ts +++ b/web/service/base.ts @@ -4,7 +4,7 @@ import type { AnnotationReply, MessageEnd, MessageReplace, ThoughtItem } from '@ import type { VisionFile } from '@/types/app' import type { IterationFinishedResponse, - IterationNextedResponse, + IterationNextResponse, IterationStartedResponse, NodeFinishedResponse, NodeStartedResponse, @@ -57,7 +57,7 @@ export type IOnWorkflowFinished = (workflowFinished: WorkflowFinishedResponse) = export type IOnNodeStarted = (nodeStarted: NodeStartedResponse) => void export type IOnNodeFinished = (nodeFinished: NodeFinishedResponse) => void export type IOnIterationStarted = (workflowStarted: IterationStartedResponse) => void -export type IOnIterationNexted = (workflowStarted: IterationNextedResponse) => void +export type IOnIterationNext = (workflowStarted: IterationNextResponse) => void export type IOnIterationFinished = (workflowFinished: IterationFinishedResponse) => void export type IOnTextChunk = (textChunk: TextChunkResponse) => void export type IOnTTSChunk = (messageId: string, audioStr: string, audioType?: string) => void @@ -84,7 +84,7 @@ export type IOtherOptions = { onNodeStarted?: IOnNodeStarted onNodeFinished?: IOnNodeFinished onIterationStart?: IOnIterationStarted - onIterationNext?: IOnIterationNexted + onIterationNext?: IOnIterationNext onIterationFinish?: IOnIterationFinished onTextChunk?: IOnTextChunk onTTSChunk?: IOnTTSChunk @@ -137,7 +137,7 @@ const handleStream = ( onNodeStarted?: IOnNodeStarted, onNodeFinished?: IOnNodeFinished, onIterationStart?: IOnIterationStarted, - onIterationNext?: IOnIterationNexted, + onIterationNext?: IOnIterationNext, onIterationFinish?: IOnIterationFinished, onTextChunk?: IOnTextChunk, onTTSChunk?: IOnTTSChunk, @@ -187,7 +187,7 @@ const handleStream = ( return } if (bufferObj.event === 'message' || bufferObj.event === 'agent_message') { - // can not use format here. Because message is splited. + // can not use format here. Because message is splitted. onData(unicodeToChar(bufferObj.answer), isFirstMessage, { conversationId: bufferObj.conversation_id, taskId: bufferObj.task_id, @@ -223,7 +223,7 @@ const handleStream = ( onIterationStart?.(bufferObj as IterationStartedResponse) } else if (bufferObj.event === 'iteration_next') { - onIterationNext?.(bufferObj as IterationNextedResponse) + onIterationNext?.(bufferObj as IterationNextResponse) } else if (bufferObj.event === 'iteration_completed') { onIterationFinish?.(bufferObj as IterationFinishedResponse) diff --git a/web/service/datasets.ts b/web/service/datasets.ts index c861a73c37..4ca269a7d6 100644 --- a/web/service/datasets.ts +++ b/web/service/datasets.ts @@ -18,14 +18,14 @@ import type { ProcessRuleResponse, RelatedAppResponse, SegmentDetailModel, - SegmentUpdator, + SegmentUpdater, SegmentsQuery, SegmentsResponse, createDocumentResponse, } from '@/models/datasets' import type { CommonResponse, DataSourceNotionWorkspace } from '@/models/common' import type { - ApikeysListResponse, + ApiKeysListResponse, CreateApiKeyResponse, } from '@/models/app' import type { RetrievalConfig } from '@/types/app' @@ -184,11 +184,11 @@ export const disableSegment: Fetcher(`/datasets/${datasetId}/segments/${segmentId}/disable`) } -export const updateSegment: Fetcher<{ data: SegmentDetailModel; doc_form: string }, { datasetId: string; documentId: string; segmentId: string; body: SegmentUpdator }> = ({ datasetId, documentId, segmentId, body }) => { +export const updateSegment: Fetcher<{ data: SegmentDetailModel; doc_form: string }, { datasetId: string; documentId: string; segmentId: string; body: SegmentUpdater }> = ({ datasetId, documentId, segmentId, body }) => { return patch<{ data: SegmentDetailModel; doc_form: string }>(`/datasets/${datasetId}/documents/${documentId}/segments/${segmentId}`, { body }) } -export const addSegment: Fetcher<{ data: SegmentDetailModel; doc_form: string }, { datasetId: string; documentId: string; body: SegmentUpdator }> = ({ datasetId, documentId, body }) => { +export const addSegment: Fetcher<{ data: SegmentDetailModel; doc_form: string }, { datasetId: string; documentId: string; body: SegmentUpdater }> = ({ datasetId, documentId, body }) => { return post<{ data: SegmentDetailModel; doc_form: string }>(`/datasets/${datasetId}/documents/${documentId}/segment`, { body }) } @@ -221,8 +221,8 @@ export const fetchNotionPagePreview: Fetcher<{ content: string }, { workspaceID: return get<{ content: string }>(`notion/workspaces/${workspaceID}/pages/${pageID}/${pageType}/preview`) } -export const fetchApiKeysList: Fetcher }> = ({ url, params }) => { - return get(url, params) +export const fetchApiKeysList: Fetcher }> = ({ url, params }) => { + return get(url, params) } export const delApikey: Fetcher }> = ({ url, params }) => { diff --git a/web/service/debug.ts b/web/service/debug.ts index 8e90fe565f..38068cad6e 100644 --- a/web/service/debug.ts +++ b/web/service/debug.ts @@ -96,7 +96,7 @@ export const fetchPromptTemplate = ({ }) } -export const fetchTextGenerationMessge = ({ +export const fetchTextGenerationMessage = ({ appId, messageId, }: { appId: string; messageId: string }) => { diff --git a/web/service/share.ts b/web/service/share.ts index f5a695f6c3..0e46e30d01 100644 --- a/web/service/share.ts +++ b/web/service/share.ts @@ -1,9 +1,9 @@ -import type { IOnCompleted, IOnData, IOnError, IOnFile, IOnIterationFinished, IOnIterationNexted, IOnIterationStarted, IOnMessageEnd, IOnMessageReplace, IOnNodeFinished, IOnNodeStarted, IOnTTSChunk, IOnTTSEnd, IOnTextChunk, IOnTextReplace, IOnThought, IOnWorkflowFinished, IOnWorkflowStarted } from './base' +import type { IOnCompleted, IOnData, IOnError, IOnFile, IOnIterationFinished, IOnIterationNext, IOnIterationStarted, IOnMessageEnd, IOnMessageReplace, IOnNodeFinished, IOnNodeStarted, IOnTTSChunk, IOnTTSEnd, IOnTextChunk, IOnTextReplace, IOnThought, IOnWorkflowFinished, IOnWorkflowStarted } from './base' import { del as consoleDel, get as consoleGet, patch as consolePatch, post as consolePost, delPublic as del, getPublic as get, patchPublic as patch, postPublic as post, ssePost, } from './base' -import type { Feedbacktype } from '@/app/components/base/chat/chat/type' +import type { FeedbackType } from '@/app/components/base/chat/chat/type' import type { AppConversationData, AppData, @@ -86,7 +86,7 @@ export const sendWorkflowMessage = async ( onNodeFinished: IOnNodeFinished onWorkflowFinished: IOnWorkflowFinished onIterationStart: IOnIterationStarted - onIterationNext: IOnIterationNexted + onIterationNext: IOnIterationNext onIterationFinish: IOnIterationFinished onTextChunk: IOnTextChunk onTextReplace: IOnTextReplace @@ -180,7 +180,7 @@ export const fetchAppMeta = async (isInstalledApp: boolean, installedAppId = '') return (getAction('get', isInstalledApp))(getUrl('meta', isInstalledApp, installedAppId)) as Promise } -export const updateFeedback = async ({ url, body }: { url: string; body: Feedbacktype }, isInstalledApp: boolean, installedAppId = '') => { +export const updateFeedback = async ({ url, body }: { url: string; body: FeedbackType }, isInstalledApp: boolean, installedAppId = '') => { return (getAction('post', isInstalledApp))(getUrl(url, isInstalledApp, installedAppId), { body }) } diff --git a/web/service/workflow.ts b/web/service/workflow.ts index 93ab0006d4..431beef96c 100644 --- a/web/service/workflow.ts +++ b/web/service/workflow.ts @@ -26,7 +26,7 @@ export const fetchWorkflowRunHistory: Fetcher(url) } -export const fetcChatRunHistory: Fetcher = (url) => { +export const fetchChatRunHistory: Fetcher = (url) => { return get(url) } diff --git a/web/themes/dark.css b/web/themes/dark.css index b94124aad2..8aab0f5fbb 100644 --- a/web/themes/dark.css +++ b/web/themes/dark.css @@ -147,13 +147,13 @@ html[data-theme="dark"] { --color-components-main-nav-nav-user-border: #FFFFFF0D; - --color-components-silder-knob: #F4F4F5; - --color-components-silder-knob-hover: #FEFEFE; - --color-components-silder-knob-disabled: #FFFFFF33; - --color-components-silder-range: #296DFF; - --color-components-silder-track: #FFFFFF33; - --color-components-silder-knob-border-hover: #1018284D; - --color-components-silder-knob-border: #10182833; + --color-components-slider-knob: #F4F4F5; + --color-components-slider-knob-hover: #FEFEFE; + --color-components-slider-knob-disabled: #FFFFFF33; + --color-components-slider-range: #296DFF; + --color-components-slider-track: #FFFFFF33; + --color-components-slider-knob-border-hover: #1018284D; + --color-components-slider-knob-border: #10182833; --color-components-segmented-control-item-active-bg: #FFFFFF14; --color-components-segmented-control-item-active-border: #C8CEDA14; @@ -268,7 +268,7 @@ html[data-theme="dark"] { --color-background-body: #1D1D20; --color-background-default-subtle: #222225; - --color-background-neurtral-subtle: #1D1D20; + --color-background-neutral-subtle: #1D1D20; --color-background-sidenav-bg: #27272AEB; --color-background-default: #222225; --color-background-soft: #18181B40; @@ -324,8 +324,8 @@ html[data-theme="dark"] { --color-workflow-link-line-normal: #676F83; --color-workflow-link-line-handle: #296DFF; - --color-workflow-minmap-bg: #27272B; - --color-workflow-minmap-block: #C8CEDA14; + --color-workflow-minimap-bg: #27272B; + --color-workflow-minimap-block: #C8CEDA14; --color-workflow-display-success-bg: #17B26A33; --color-workflow-display-success-border-1: #17B26AE5; @@ -371,8 +371,8 @@ html[data-theme="dark"] { --color-divider-deep: #C8CEDA33; --color-divider-burn: #18181BF2; --color-divider-intense: #C8CEDA66; - --color-divider-soild: #3A3A40; - --color-divider-soild-alt: #747481; + --color-divider-solid: #3A3A40; + --color-divider-solid-alt: #747481; --color-state-base-hover: #C8CEDA14; --color-state-base-active: #C8CEDA33; @@ -383,24 +383,24 @@ html[data-theme="dark"] { --color-state-accent-hover: #155AEF24; --color-state-accent-active: #155AEF24; --color-state-accent-hover-alt: #155AEF40; - --color-state-accent-soild: #5289FF; + --color-state-accent-solid: #5289FF; --color-state-accent-active-alt: #155AEF33; --color-state-destructive-hover: #F0443824; --color-state-destructive-hover-alt: #F0443840; --color-state-destructive-active: #F044384D; - --color-state-destructive-soild: #F97066; + --color-state-destructive-solid: #F97066; --color-state-destructive-border: #F97066; --color-state-success-hover: #17B26A24; --color-state-success-hover-alt: #17B26A40; --color-state-success-active: #17B26A4D; - --color-state-success-soild: #47CD89; + --color-state-success-solid: #47CD89; --color-state-warning-hover: #F7900924; --color-state-warning-hover-alt: #F7900940; --color-state-warning-active: #F790094D; - --color-state-warning-soild: #F79009; + --color-state-warning-solid: #F79009; --color-effects-highlight: #C8CEDA14; --color-effects-highlight-lightmode-off: #C8CEDA14; diff --git a/web/themes/light.css b/web/themes/light.css index 80a0fa36f5..5a5ef63769 100644 --- a/web/themes/light.css +++ b/web/themes/light.css @@ -147,13 +147,13 @@ html[data-theme="light"] { --color-components-main-nav-nav-user-border: #FFFFFF; - --color-components-silder-knob: #FFFFFF; - --color-components-silder-knob-hover: #FFFFFF; - --color-components-silder-knob-disabled: #FFFFFFF2; - --color-components-silder-range: #296DFF; - --color-components-silder-track: #E9EBF0; - --color-components-silder-knob-border-hover: #10182833; - --color-components-silder-knob-border: #10182824; + --color-components-slider-knob: #FFFFFF; + --color-components-slider-knob-hover: #FFFFFF; + --color-components-slider-knob-disabled: #FFFFFFF2; + --color-components-slider-range: #296DFF; + --color-components-slider-track: #E9EBF0; + --color-components-slider-knob-border-hover: #10182833; + --color-components-slider-knob-border: #10182824; --color-components-segmented-control-item-active-bg: #FFFFFF; --color-components-segmented-control-item-active-border: #FFFFFF; @@ -268,7 +268,7 @@ html[data-theme="light"] { --color-background-body: #F2F4F7; --color-background-default-subtle: #FCFCFD; - --color-background-neurtral-subtle: #F9FAFB; + --color-background-neutral-subtle: #F9FAFB; --color-background-sidenav-bg: #FFFFFFCC; --color-background-default: #FFFFFF; --color-background-soft: #F9FAFB; @@ -324,8 +324,8 @@ html[data-theme="light"] { --color-workflow-link-line-normal: #D0D5DC; --color-workflow-link-line-handle: #296DFF; - --color-workflow-minmap-bg: #E9EBF0; - --color-workflow-minmap-block: #C8CEDA4D; + --color-workflow-minimap-bg: #E9EBF0; + --color-workflow-minimap-block: #C8CEDA4D; --color-workflow-display-success-bg: #ECFDF3; --color-workflow-display-success-border-1: #17B26ACC; @@ -371,8 +371,8 @@ html[data-theme="light"] { --color-divider-deep: #10182824; --color-divider-burn: #1018280A; --color-divider-intense: #1018284D; - --color-divider-soild: #D0D5DC; - --color-divider-soild-alt: #98A2B2; + --color-divider-solid: #D0D5DC; + --color-divider-solid-alt: #98A2B2; --color-state-base-hover: #C8CEDA33; --color-state-base-active: #C8CEDA66; @@ -383,24 +383,24 @@ html[data-theme="light"] { --color-state-accent-hover: #EFF4FF; --color-state-accent-active: #155AEF14; --color-state-accent-hover-alt: #D1E0FF; - --color-state-accent-soild: #296DFF; + --color-state-accent-solid: #296DFF; --color-state-accent-active-alt: #155AEF24; --color-state-destructive-hover: #FEF3F2; --color-state-destructive-hover-alt: #FEE4E2; --color-state-destructive-active: #FECDCA; - --color-state-destructive-soild: #F04438; + --color-state-destructive-solid: #F04438; --color-state-destructive-border: #FDA29B; --color-state-success-hover: #ECFDF3; --color-state-success-hover-alt: #DCFAE6; --color-state-success-active: #ABEFC6; - --color-state-success-soild: #17B26A; + --color-state-success-solid: #17B26A; --color-state-warning-hover: #FFFAEB; --color-state-warning-hover-alt: #FEF0C7; --color-state-warning-active: #FEDF89; - --color-state-warning-soild: #F79009; + --color-state-warning-solid: #F79009; --color-effects-highlight: #FFFFFF; --color-effects-highlight-lightmode-off: #FFFFFF00; diff --git a/web/themes/tailwind-theme-var-define.ts b/web/themes/tailwind-theme-var-define.ts index caeb01b5fa..9178d23f24 100644 --- a/web/themes/tailwind-theme-var-define.ts +++ b/web/themes/tailwind-theme-var-define.ts @@ -147,13 +147,13 @@ const vars = { 'components-main-nav-nav-user-border': 'var(--color-components-main-nav-nav-user-border)', - 'components-silder-knob': 'var(--color-components-silder-knob)', - 'components-silder-knob-hover': 'var(--color-components-silder-knob-hover)', - 'components-silder-knob-disabled': 'var(--color-components-silder-knob-disabled)', - 'components-silder-range': 'var(--color-components-silder-range)', - 'components-silder-track': 'var(--color-components-silder-track)', - 'components-silder-knob-border-hover': 'var(--color-components-silder-knob-border-hover)', - 'components-silder-knob-border': 'var(--color-components-silder-knob-border)', + 'components-slider-knob': 'var(--color-components-slider-knob)', + 'components-slider-knob-hover': 'var(--color-components-slider-knob-hover)', + 'components-slider-knob-disabled': 'var(--color-components-slider-knob-disabled)', + 'components-slider-range': 'var(--color-components-slider-range)', + 'components-slider-track': 'var(--color-components-slider-track)', + 'components-slider-knob-border-hover': 'var(--color-components-slider-knob-border-hover)', + 'components-slider-knob-border': 'var(--color-components-slider-knob-border)', 'components-segmented-control-item-active-bg': 'var(--color-components-segmented-control-item-active-bg)', 'components-segmented-control-item-active-border': 'var(--color-components-segmented-control-item-active-border)', @@ -268,7 +268,7 @@ const vars = { 'background-body': 'var(--color-background-body)', 'background-default-subtle': 'var(--color-background-default-subtle)', - 'background-neurtral-subtle': 'var(--color-background-neurtral-subtle)', + 'background-neutral-subtle': 'var(--color-background-neutral-subtle)', 'background-sidenav-bg': 'var(--color-background-sidenav-bg)', 'background-default': 'var(--color-background-default)', 'background-soft': 'var(--color-background-soft)', @@ -324,8 +324,8 @@ const vars = { 'workflow-link-line-normal': 'var(--color-workflow-link-line-normal)', 'workflow-link-line-handle': 'var(--color-workflow-link-line-handle)', - 'workflow-minmap-bg': 'var(--color-workflow-minmap-bg)', - 'workflow-minmap-block': 'var(--color-workflow-minmap-block)', + 'workflow-minimap-bg': 'var(--color-workflow-minimap-bg)', + 'workflow-minimap-block': 'var(--color-workflow-minimap-block)', 'workflow-display-success-bg': 'var(--color-workflow-display-success-bg)', 'workflow-display-success-border-1': 'var(--color-workflow-display-success-border-1)', @@ -371,8 +371,8 @@ const vars = { 'divider-deep': 'var(--color-divider-deep)', 'divider-burn': 'var(--color-divider-burn)', 'divider-intense': 'var(--color-divider-intense)', - 'divider-soild': 'var(--color-divider-soild)', - 'divider-soild-alt': 'var(--color-divider-soild-alt)', + 'divider-solid': 'var(--color-divider-solid)', + 'divider-solid-alt': 'var(--color-divider-solid-alt)', 'state-base-hover': 'var(--color-state-base-hover)', 'state-base-active': 'var(--color-state-base-active)', @@ -383,24 +383,24 @@ const vars = { 'state-accent-hover': 'var(--color-state-accent-hover)', 'state-accent-active': 'var(--color-state-accent-active)', 'state-accent-hover-alt': 'var(--color-state-accent-hover-alt)', - 'state-accent-soild': 'var(--color-state-accent-soild)', + 'state-accent-solid': 'var(--color-state-accent-solid)', 'state-accent-active-alt': 'var(--color-state-accent-active-alt)', 'state-destructive-hover': 'var(--color-state-destructive-hover)', 'state-destructive-hover-alt': 'var(--color-state-destructive-hover-alt)', 'state-destructive-active': 'var(--color-state-destructive-active)', - 'state-destructive-soild': 'var(--color-state-destructive-soild)', + 'state-destructive-solid': 'var(--color-state-destructive-solid)', 'state-destructive-border': 'var(--color-state-destructive-border)', 'state-success-hover': 'var(--color-state-success-hover)', 'state-success-hover-alt': 'var(--color-state-success-hover-alt)', 'state-success-active': 'var(--color-state-success-active)', - 'state-success-soild': 'var(--color-state-success-soild)', + 'state-success-solid': 'var(--color-state-success-solid)', 'state-warning-hover': 'var(--color-state-warning-hover)', 'state-warning-hover-alt': 'var(--color-state-warning-hover-alt)', 'state-warning-active': 'var(--color-state-warning-active)', - 'state-warning-soild': 'var(--color-state-warning-soild)', + 'state-warning-solid': 'var(--color-state-warning-solid)', 'effects-highlight': 'var(--color-effects-highlight)', 'effects-highlight-lightmode-off': 'var(--color-effects-highlight-lightmode-off)', diff --git a/web/types/app.ts b/web/types/app.ts index fb8a407dd2..cb05bc3878 100644 --- a/web/types/app.ts +++ b/web/types/app.ts @@ -297,6 +297,7 @@ export type SiteConfig = { icon_url: string | null show_workflow_steps: boolean + use_icon_as_answer_icon: boolean } export type AppIconType = 'image' | 'emoji' @@ -323,6 +324,8 @@ export type App = { icon_background: string | null /** Icon URL, only available when icon_type is 'image' */ icon_url: string | null + /** Whether to use app icon as answer icon */ + use_icon_as_answer_icon: boolean /** Mode */ mode: AppMode diff --git a/web/types/workflow.ts b/web/types/workflow.ts index f7991bc4e0..e6b001bd79 100644 --- a/web/types/workflow.ts +++ b/web/types/workflow.ts @@ -158,7 +158,7 @@ export type IterationStartedResponse = { } } -export type IterationNextedResponse = { +export type IterationNextResponse = { task_id: string workflow_run_id: string event: string diff --git a/web/utils/var.ts b/web/utils/var.ts index 436ebfc70b..236c9debac 100644 --- a/web/utils/var.ts +++ b/web/utils/var.ts @@ -1,4 +1,4 @@ -import { MAX_VAR_KEY_LENGHT, VAR_ITEM_TEMPLATE, VAR_ITEM_TEMPLATE_IN_WORKFLOW, getMaxVarNameLength } from '@/config' +import { MAX_VAR_KEY_LENGTH, VAR_ITEM_TEMPLATE, VAR_ITEM_TEMPLATE_IN_WORKFLOW, getMaxVarNameLength } from '@/config' import { CONTEXT_PLACEHOLDER_TEXT, HISTORY_PLACEHOLDER_TEXT, PRE_PROMPT_PLACEHOLDER_TEXT, QUERY_PLACEHOLDER_TEXT } from '@/app/components/base/prompt-editor/constants' import { InputVarType } from '@/app/components/workflow/types' @@ -47,7 +47,7 @@ export const checkKey = (key: string, canBeEmpty?: boolean) => { if (canBeEmpty && key === '') return true - if (key.length > MAX_VAR_KEY_LENGHT) + if (key.length > MAX_VAR_KEY_LENGTH) return 'tooLong' if (otherAllowedRegex.test(key)) { @@ -86,7 +86,7 @@ export const getVars = (value: string) => { return ![CONTEXT_PLACEHOLDER_TEXT, HISTORY_PLACEHOLDER_TEXT, QUERY_PLACEHOLDER_TEXT, PRE_PROMPT_PLACEHOLDER_TEXT].includes(item) }).map((item) => { return item.replace('{{', '').replace('}}', '') - }).filter(key => key.length <= MAX_VAR_KEY_LENGHT) || [] + }).filter(key => key.length <= MAX_VAR_KEY_LENGTH) || [] const keyObj: Record = {} // remove duplicate keys const res: string[] = [] diff --git a/web/yarn.lock b/web/yarn.lock index d50aa33f3e..3c020c9664 100644 --- a/web/yarn.lock +++ b/web/yarn.lock @@ -260,6 +260,13 @@ resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz" integrity sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg== +"@babel/parser@^7.25.4": + version "7.25.6" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.6.tgz#85660c5ef388cbbf6e3d2a694ee97a38f18afe2f" + integrity sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q== + dependencies: + "@babel/types" "^7.25.6" + "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" @@ -406,6 +413,15 @@ "@babel/helper-validator-identifier" "^7.24.7" to-fast-properties "^2.0.0" +"@babel/types@^7.25.4", "@babel/types@^7.25.6": + version "7.25.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.6.tgz#893942ddb858f32ae7a004ec9d3a76b3463ef8e6" + integrity sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw== + dependencies: + "@babel/helper-string-parser" "^7.24.8" + "@babel/helper-validator-identifier" "^7.24.7" + to-fast-properties "^2.0.0" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -1454,6 +1470,11 @@ resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== +"@sindresorhus/is@^4.0.0": + version "4.6.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" + integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== + "@sinonjs/commons@^3.0.0": version "3.0.1" resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd" @@ -1481,6 +1502,13 @@ "@swc/counter" "^0.1.3" tslib "^2.4.0" +"@szmarczak/http-timer@^4.0.5": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" + integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== + dependencies: + defer-to-connect "^2.0.0" + "@tailwindcss/line-clamp@^0.4.4": version "0.4.4" resolved "https://registry.npmjs.org/@tailwindcss/line-clamp/-/line-clamp-0.4.4.tgz" @@ -1601,6 +1629,16 @@ dependencies: "@babel/types" "^7.20.7" +"@types/cacheable-request@^6.0.1": + version "6.0.3" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183" + integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw== + dependencies: + "@types/http-cache-semantics" "*" + "@types/keyv" "^3.1.4" + "@types/node" "*" + "@types/responselike" "^1.0.0" + "@types/crypto-js@^4.1.1": version "4.1.1" resolved "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.1.1.tgz" @@ -1859,6 +1897,18 @@ dependencies: "@types/unist" "*" +"@types/hast@^3.0.0": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-3.0.4.tgz#1d6b39993b82cea6ad783945b0508c25903e15aa" + integrity sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ== + dependencies: + "@types/unist" "*" + +"@types/http-cache-semantics@*": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4" + integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA== + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.6" resolved "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" @@ -1925,6 +1975,13 @@ resolved "https://registry.npmjs.org/@types/katex/-/katex-0.16.0.tgz" integrity sha512-hz+S3nV6Mym5xPbT9fnO8dDhBFQguMYpY0Ipxv06JMi1ORgnEM4M1ymWDUhUNer3ElLmT583opRo4RzxKmh9jw== +"@types/keyv@^3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" + integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== + dependencies: + "@types/node" "*" + "@types/lodash-es@^4.17.7": version "4.17.7" resolved "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.7.tgz" @@ -1944,6 +2001,13 @@ dependencies: "@types/unist" "*" +"@types/mdast@^4.0.0": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-4.0.4.tgz#7ccf72edd2f1aa7dd3437e180c64373585804dd6" + integrity sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA== + dependencies: + "@types/unist" "*" + "@types/mdx@^2.0.0": version "2.0.5" resolved "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.5.tgz" @@ -2035,6 +2099,13 @@ resolved "https://registry.npmjs.org/@types/recordrtc/-/recordrtc-5.6.11.tgz" integrity sha512-X4XD5nltz0cjmyzsPNegQReOPF+C5ARTfSPAPhqnKV7SsfRta/M4FBJ5AtSInCaEveL71FLLSVQE9mg8Uuo++w== +"@types/responselike@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.3.tgz#cc29706f0a397cfe6df89debfe4bf5cea159db50" + integrity sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw== + dependencies: + "@types/node" "*" + "@types/semver@^7.3.12": version "7.5.0" resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz" @@ -2060,6 +2131,11 @@ resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz" integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== +"@types/unist@^3.0.0": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.2.tgz#6dd61e43ef60b34086287f83683a5c1b2dc53d20" + integrity sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ== + "@types/uuid@^9.0.8": version "9.0.8" resolved "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz" @@ -2161,6 +2237,11 @@ "@typescript-eslint/types" "5.59.9" eslint-visitor-keys "^3.3.0" +"@ungap/structured-clone@^1.0.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + "@vue/compiler-core@3.4.25": version "3.4.25" resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.25.tgz" @@ -2578,6 +2659,13 @@ binary-extensions@^2.0.0: resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== +bing-translate-api@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/bing-translate-api/-/bing-translate-api-4.0.2.tgz#52807a128e883bf074b4174c5e674ffca60685e7" + integrity sha512-JJ8XUehnxzOhHU91oy86xEtp8OOMjVEjCZJX042fKxoO19NNvxJ5omeCcxQNFoPbDqVpBJwqiGVquL0oPdQm1Q== + dependencies: + got "^11.8.6" + boolbase@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" @@ -2670,6 +2758,24 @@ busboy@1.6.0: dependencies: streamsearch "^1.1.0" +cacheable-lookup@^5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" + integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== + +cacheable-request@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.4.tgz#7a33ebf08613178b403635be7b899d3e69bbe817" + integrity sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^4.0.0" + lowercase-keys "^2.0.0" + normalize-url "^6.0.1" + responselike "^2.0.0" + call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz" @@ -2893,6 +2999,13 @@ cliui@^8.0.1: strip-ansi "^6.0.1" wrap-ansi "^7.0.0" +clone-response@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" + integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== + dependencies: + mimic-response "^1.0.0" + clsx@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz" @@ -3464,6 +3577,13 @@ decode-named-character-reference@^1.0.0: dependencies: character-entities "^2.0.0" +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + dedent@^1.0.0: version "1.5.3" resolved "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz#99aee19eb9bae55a67327717b6e848d0bf777e5a" @@ -3521,6 +3641,11 @@ default-browser@^4.0.0: execa "^7.1.1" titleize "^3.0.0" +defer-to-connect@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== + define-data-property@^1.0.1, define-data-property@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz" @@ -3571,6 +3696,13 @@ detect-newline@^3.0.0: resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== +devlop@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/devlop/-/devlop-1.1.0.tgz#4db7c2ca4dc6e0e834c30be70c94bbc976dc7018" + integrity sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA== + dependencies: + dequal "^2.0.0" + didyoumean@^1.2.2: version "1.2.2" resolved "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz" @@ -3720,6 +3852,13 @@ emoji-regex@^9.2.2: resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + enhanced-resolve@^5.12.0: version "5.16.1" resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz" @@ -4557,6 +4696,13 @@ get-package-type@^0.1.0: resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + get-stream@^6.0.0, get-stream@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" @@ -4675,6 +4821,23 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" +got@^11.8.6: + version "11.8.6" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" + integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== + dependencies: + "@sindresorhus/is" "^4.0.0" + "@szmarczak/http-timer" "^4.0.5" + "@types/cacheable-request" "^6.0.1" + "@types/responselike" "^1.0.0" + cacheable-lookup "^5.0.3" + cacheable-request "^7.0.2" + decompress-response "^6.0.0" + http2-wrapper "^1.0.0-beta.5.2" + lowercase-keys "^2.0.0" + p-cancelable "^2.0.0" + responselike "^2.0.0" + graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" @@ -4780,6 +4943,20 @@ hast-util-from-parse5@^7.0.0: vfile-location "^4.0.0" web-namespaces "^2.0.0" +hast-util-from-parse5@^8.0.0: + version "8.0.1" + resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz#654a5676a41211e14ee80d1b1758c399a0327651" + integrity sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ== + dependencies: + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + devlop "^1.0.0" + hastscript "^8.0.0" + property-information "^6.0.0" + vfile "^6.0.0" + vfile-location "^5.0.0" + web-namespaces "^2.0.0" + hast-util-is-element@^2.0.0: version "2.1.3" resolved "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-2.1.3.tgz" @@ -4800,6 +4977,32 @@ hast-util-parse-selector@^3.0.0: dependencies: "@types/hast" "^2.0.0" +hast-util-parse-selector@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz#352879fa86e25616036037dd8931fb5f34cb4a27" + integrity sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A== + dependencies: + "@types/hast" "^3.0.0" + +hast-util-raw@^9.0.0: + version "9.0.4" + resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-9.0.4.tgz#2da03e37c46eb1a6f1391f02f9b84ae65818f7ed" + integrity sha512-LHE65TD2YiNsHD3YuXcKPHXPLuYh/gjp12mOfU8jxSrm1f/yJpsb0F/KKljS6U9LJoP0Ux+tCe8iJ2AsPzTdgA== + dependencies: + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + "@ungap/structured-clone" "^1.0.0" + hast-util-from-parse5 "^8.0.0" + hast-util-to-parse5 "^8.0.0" + html-void-elements "^3.0.0" + mdast-util-to-hast "^13.0.0" + parse5 "^7.0.0" + unist-util-position "^5.0.0" + unist-util-visit "^5.0.0" + vfile "^6.0.0" + web-namespaces "^2.0.0" + zwitch "^2.0.0" + hast-util-to-estree@^2.0.0: version "2.3.3" resolved "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-2.3.3.tgz" @@ -4821,6 +5024,19 @@ hast-util-to-estree@^2.0.0: unist-util-position "^4.0.0" zwitch "^2.0.0" +hast-util-to-parse5@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz#477cd42d278d4f036bc2ea58586130f6f39ee6ed" + integrity sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw== + dependencies: + "@types/hast" "^3.0.0" + comma-separated-tokens "^2.0.0" + devlop "^1.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + web-namespaces "^2.0.0" + zwitch "^2.0.0" + hast-util-to-text@^3.1.0: version "3.1.2" resolved "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-3.1.2.tgz" @@ -4858,6 +5074,17 @@ hastscript@^7.0.0: property-information "^6.0.0" space-separated-tokens "^2.0.0" +hastscript@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-8.0.0.tgz#4ef795ec8dee867101b9f23cc830d4baf4fd781a" + integrity sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw== + dependencies: + "@types/hast" "^3.0.0" + comma-separated-tokens "^2.0.0" + hast-util-parse-selector "^4.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + heap@^0.2.6: version "0.2.7" resolved "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz" @@ -4899,6 +5126,11 @@ html-parse-stringify@^3.0.1: dependencies: void-elements "3.1.0" +html-void-elements@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-3.0.0.tgz#fc9dbd84af9e747249034d4d62602def6517f1d7" + integrity sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg== + htmlparser2@^8.0.1: version "8.0.2" resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz" @@ -4909,6 +5141,11 @@ htmlparser2@^8.0.1: domutils "^3.0.1" entities "^4.4.0" +http-cache-semantics@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -4918,6 +5155,14 @@ http-proxy-agent@^5.0.0: agent-base "6" debug "4" +http2-wrapper@^1.0.0-beta.5.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" + integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.0.0" + https-proxy-agent@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -5905,6 +6150,11 @@ jsesc@~0.5.0: resolved "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz" integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + json-parse-even-better-errors@^2.3.0: version "2.3.1" resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" @@ -5957,6 +6207,13 @@ katex@^0.16.0, katex@^0.16.10: dependencies: commander "^8.3.0" +keyv@^4.0.0: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + khroma@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/khroma/-/khroma-2.0.0.tgz" @@ -6128,6 +6385,11 @@ loose-envify@^1.1.0, loose-envify@^1.4.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + lowlight@^1.17.0: version "1.20.0" resolved "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz" @@ -6160,6 +6422,15 @@ lz-string@^1.5.0: resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== +magicast@^0.3.4: + version "0.3.5" + resolved "https://registry.yarnpkg.com/magicast/-/magicast-0.3.5.tgz#8301c3c7d66704a0771eb1bad74274f0ec036739" + integrity sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ== + dependencies: + "@babel/parser" "^7.25.4" + "@babel/types" "^7.25.4" + source-map-js "^1.2.0" + make-dir@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" @@ -6385,6 +6656,21 @@ mdast-util-to-hast@^12.1.0: unist-util-position "^4.0.0" unist-util-visit "^4.0.0" +mdast-util-to-hast@^13.0.0: + version "13.2.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz#5ca58e5b921cc0a3ded1bc02eed79a4fe4fe41f4" + integrity sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA== + dependencies: + "@types/hast" "^3.0.0" + "@types/mdast" "^4.0.0" + "@ungap/structured-clone" "^1.0.0" + devlop "^1.0.0" + micromark-util-sanitize-uri "^2.0.0" + trim-lines "^3.0.0" + unist-util-position "^5.0.0" + unist-util-visit "^5.0.0" + vfile "^6.0.0" + mdast-util-to-markdown@^1.0.0, mdast-util-to-markdown@^1.3.0: version "1.5.0" resolved "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz" @@ -6701,6 +6987,14 @@ micromark-util-character@^1.0.0: micromark-util-symbol "^1.0.0" micromark-util-types "^1.0.0" +micromark-util-character@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-2.1.0.tgz#31320ace16b4644316f6bf057531689c71e2aee1" + integrity sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ== + dependencies: + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + micromark-util-chunked@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz" @@ -6747,6 +7041,11 @@ micromark-util-encode@^1.0.0: resolved "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz" integrity sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw== +micromark-util-encode@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz#0921ac7953dc3f1fd281e3d1932decfdb9382ab1" + integrity sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA== + micromark-util-events-to-acorn@^1.0.0: version "1.2.3" resolved "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-1.2.3.tgz" @@ -6789,6 +7088,15 @@ micromark-util-sanitize-uri@^1.0.0, micromark-util-sanitize-uri@^1.1.0: micromark-util-encode "^1.0.0" micromark-util-symbol "^1.0.0" +micromark-util-sanitize-uri@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz#ec8fbf0258e9e6d8f13d9e4770f9be64342673de" + integrity sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw== + dependencies: + micromark-util-character "^2.0.0" + micromark-util-encode "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-subtokenize@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz" @@ -6804,11 +7112,21 @@ micromark-util-symbol@^1.0.0: resolved "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz" integrity sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag== +micromark-util-symbol@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz#12225c8f95edf8b17254e47080ce0862d5db8044" + integrity sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw== + micromark-util-types@^1.0.0, micromark-util-types@^1.0.1: version "1.1.0" resolved "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz" integrity sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg== +micromark-util-types@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-2.0.0.tgz#63b4b7ffeb35d3ecf50d1ca20e68fc7caa36d95e" + integrity sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w== + micromark@^3.0.0: version "3.2.0" resolved "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz" @@ -6870,6 +7188,16 @@ mimic-fn@^4.0.0: resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz" integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + min-indent@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz" @@ -7010,6 +7338,11 @@ normalize-range@^0.1.2: resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz" integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== + normalize-wheel@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/normalize-wheel/-/normalize-wheel-1.0.1.tgz#aec886affdb045070d856447df62ecf86146ec45" @@ -7129,9 +7462,9 @@ object.values@^1.1.6, object.values@^1.1.7: define-properties "^1.2.0" es-abstract "^1.22.1" -once@^1.3.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" @@ -7172,6 +7505,11 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" +p-cancelable@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" + integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== + p-limit@^2.2.0: version "2.3.0" resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" @@ -7498,6 +7836,14 @@ psl@^1.1.33: resolved "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + punycode@^2.1.0: version "2.3.0" resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" @@ -7535,6 +7881,11 @@ queue-microtask@^1.2.2: resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + rc-input@~1.3.5: version "1.3.6" resolved "https://registry.npmjs.org/rc-input/-/rc-input-1.3.6.tgz" @@ -7867,6 +8218,15 @@ rehype-katex@^6.0.2: katex "^0.16.0" unist-util-visit "^4.0.0" +rehype-raw@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/rehype-raw/-/rehype-raw-7.0.0.tgz#59d7348fd5dbef3807bbaa1d443efd2dd85ecee4" + integrity sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww== + dependencies: + "@types/hast" "^3.0.0" + hast-util-raw "^9.0.0" + vfile "^6.0.0" + remark-breaks@^3.0.2: version "3.0.3" resolved "https://registry.npmjs.org/remark-breaks/-/remark-breaks-3.0.3.tgz" @@ -7938,6 +8298,11 @@ resize-observer-polyfill@^1.5.1: resolved "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz" integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== +resolve-alpn@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== + resolve-cwd@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" @@ -7983,6 +8348,13 @@ resolve@^2.0.0-next.4: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +responselike@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc" + integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw== + dependencies: + lowercase-keys "^2.0.0" + restore-cursor@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" @@ -8382,7 +8754,7 @@ string-length@^4.0.1: string-width@4.2.3, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3, string-width@^5.0.0, string-width@^5.0.1, string-width@^5.1.2: version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" @@ -8439,14 +8811,7 @@ stringify-entities@^4.0.0: character-entities-html4 "^2.0.0" character-entities-legacy "^3.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -8760,9 +9125,9 @@ tslib@^1.8.1, tslib@^1.9.3: integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.0.1: - version "2.6.3" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0" - integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ== + version "2.7.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" + integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== tslib@^2.1.0, tslib@^2.4.0, tslib@^2.4.1, tslib@^2.5.0: version "2.5.3" @@ -8900,6 +9265,13 @@ unist-util-is@^5.0.0: dependencies: "@types/unist" "^2.0.0" +unist-util-is@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-6.0.0.tgz#b775956486aff107a9ded971d996c173374be424" + integrity sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw== + dependencies: + "@types/unist" "^3.0.0" + unist-util-position-from-estree@^1.0.0, unist-util-position-from-estree@^1.1.0: version "1.1.2" resolved "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-1.1.2.tgz" @@ -8914,6 +9286,13 @@ unist-util-position@^4.0.0: dependencies: "@types/unist" "^2.0.0" +unist-util-position@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-5.0.0.tgz#678f20ab5ca1207a97d7ea8a388373c9cf896be4" + integrity sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA== + dependencies: + "@types/unist" "^3.0.0" + unist-util-remove-position@^4.0.0: version "4.0.2" resolved "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-4.0.2.tgz" @@ -8936,6 +9315,13 @@ unist-util-stringify-position@^3.0.0: dependencies: "@types/unist" "^2.0.0" +unist-util-stringify-position@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz#449c6e21a880e0855bf5aabadeb3a740314abac2" + integrity sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ== + dependencies: + "@types/unist" "^3.0.0" + unist-util-visit-parents@^5.0.0, unist-util-visit-parents@^5.1.1: version "5.1.3" resolved "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz" @@ -8944,6 +9330,14 @@ unist-util-visit-parents@^5.0.0, unist-util-visit-parents@^5.1.1: "@types/unist" "^2.0.0" unist-util-is "^5.0.0" +unist-util-visit-parents@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz#4d5f85755c3b8f0dc69e21eca5d6d82d22162815" + integrity sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw== + dependencies: + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" + unist-util-visit@^4.0.0: version "4.1.2" resolved "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz" @@ -8953,6 +9347,15 @@ unist-util-visit@^4.0.0: unist-util-is "^5.0.0" unist-util-visit-parents "^5.1.1" +unist-util-visit@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-5.0.0.tgz#a7de1f31f72ffd3519ea71814cccf5fd6a9217d6" + integrity sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg== + dependencies: + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" + unist-util-visit-parents "^6.0.0" + universalify@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" @@ -9059,6 +9462,14 @@ vfile-location@^4.0.0: "@types/unist" "^2.0.0" vfile "^5.0.0" +vfile-location@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-5.0.3.tgz#cb9eacd20f2b6426d19451e0eafa3d0a846225c3" + integrity sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg== + dependencies: + "@types/unist" "^3.0.0" + vfile "^6.0.0" + vfile-message@^3.0.0: version "3.1.4" resolved "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz" @@ -9067,6 +9478,14 @@ vfile-message@^3.0.0: "@types/unist" "^2.0.0" unist-util-stringify-position "^3.0.0" +vfile-message@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-4.0.2.tgz#c883c9f677c72c166362fd635f21fc165a7d1181" + integrity sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw== + dependencies: + "@types/unist" "^3.0.0" + unist-util-stringify-position "^4.0.0" + vfile@^5.0.0: version "5.3.7" resolved "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz" @@ -9077,6 +9496,15 @@ vfile@^5.0.0: unist-util-stringify-position "^3.0.0" vfile-message "^3.0.0" +vfile@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-6.0.2.tgz#ef49548ea3d270097a67011921411130ceae7deb" + integrity sha512-zND7NlS8rJYb/sPqkb13ZvbbUoExdbi4w3SfRrMq6R3FvnLQmmfpajJNITuuYm6AZ5uao9vy4BAos3EXBPf2rg== + dependencies: + "@types/unist" "^3.0.0" + unist-util-stringify-position "^4.0.0" + vfile-message "^4.0.0" + vite-code-inspector-plugin@0.13.0: version "0.13.0" resolved "https://registry.npmjs.org/vite-code-inspector-plugin/-/vite-code-inspector-plugin-0.13.0.tgz" @@ -9220,7 +9648,8 @@ word-wrap@^1.2.3: resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz" integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: + name wrap-ansi-cjs version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -9238,15 +9667,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" @@ -9373,4 +9793,4 @@ zustand@^4.4.1, zustand@^4.5.2: zwitch@^2.0.0: version "2.0.4" resolved "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz" - integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A== \ No newline at end of file + integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==