From 45ae51103698573129ca8cdcdde862762aa37238 Mon Sep 17 00:00:00 2001 From: Tianyi Jing Date: Thu, 9 Oct 2025 21:23:15 +0800 Subject: [PATCH 1/4] fix: add missing toType to `toolCredentialToFormSchemas` (#26681) Signed-off-by: jingfelix --- .../account-setting/model-provider-page/model-modal/Form.tsx | 2 +- web/app/components/tools/utils/to-form-schema.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx b/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx index 7c259f1a78..bdaeacb5c0 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx @@ -276,7 +276,7 @@ function Form<
- {label[language] || label.en_US} + {label[language] || label.en_US} {required && ( * )} diff --git a/web/app/components/tools/utils/to-form-schema.ts b/web/app/components/tools/utils/to-form-schema.ts index c1d17b48ef..8e85a5f9b0 100644 --- a/web/app/components/tools/utils/to-form-schema.ts +++ b/web/app/components/tools/utils/to-form-schema.ts @@ -45,6 +45,7 @@ export const toolCredentialToFormSchemas = (parameters: ToolCredential[]) => { return { ...parameter, variable: parameter.name, + type: toType(parameter.type), label: parameter.label, tooltip: parameter.help, show_on: [], From 33b08143234b393de246476fba5e8f92371cdb6a Mon Sep 17 00:00:00 2001 From: GuanMu Date: Thu, 9 Oct 2025 21:36:42 +0800 Subject: [PATCH 2/4] refactor(types): remove `any` usages and strengthen typings across web and base (#26677) --- .../share/text-generation/result/index.tsx | 8 ++-- .../workflow/hooks/use-workflow-history.ts | 12 +++--- .../variable/var-reference-picker.tsx | 2 +- .../json-schema-config.tsx | 2 +- .../visual-editor/edit-card/index.tsx | 10 +++-- web/service/base.ts | 39 +++++++++++++------ 6 files changed, 45 insertions(+), 28 deletions(-) diff --git a/web/app/components/share/text-generation/result/index.tsx b/web/app/components/share/text-generation/result/index.tsx index ddc0d772c3..7a4e606636 100644 --- a/web/app/components/share/text-generation/result/index.tsx +++ b/web/app/components/share/text-generation/result/index.tsx @@ -78,15 +78,15 @@ const Result: FC = ({ setRespondingFalse() }, [controlStopResponding]) - const [completionRes, doSetCompletionRes] = useState('') - const completionResRef = useRef() - const setCompletionRes = (res: any) => { + const [completionRes, doSetCompletionRes] = useState('') + const completionResRef = useRef('') + const setCompletionRes = (res: string) => { completionResRef.current = res doSetCompletionRes(res) } const getCompletionRes = () => completionResRef.current const [workflowProcessData, doSetWorkflowProcessData] = useState() - const workflowProcessDataRef = useRef() + const workflowProcessDataRef = useRef(undefined) const setWorkflowProcessData = (data: WorkflowProcess) => { workflowProcessDataRef.current = data doSetWorkflowProcessData(data) diff --git a/web/app/components/workflow/hooks/use-workflow-history.ts b/web/app/components/workflow/hooks/use-workflow-history.ts index a9b2f0f699..58bbe415a8 100644 --- a/web/app/components/workflow/hooks/use-workflow-history.ts +++ b/web/app/components/workflow/hooks/use-workflow-history.ts @@ -41,16 +41,16 @@ export const useWorkflowHistory = () => { const { store: workflowHistoryStore } = useWorkflowHistoryStore() const { t } = useTranslation() - const [undoCallbacks, setUndoCallbacks] = useState([]) - const [redoCallbacks, setRedoCallbacks] = useState([]) + const [undoCallbacks, setUndoCallbacks] = useState<(() => void)[]>([]) + const [redoCallbacks, setRedoCallbacks] = useState<(() => void)[]>([]) - const onUndo = useCallback((callback: unknown) => { - setUndoCallbacks((prev: any) => [...prev, callback]) + const onUndo = useCallback((callback: () => void) => { + setUndoCallbacks(prev => [...prev, callback]) return () => setUndoCallbacks(prev => prev.filter(cb => cb !== callback)) }, []) - const onRedo = useCallback((callback: unknown) => { - setRedoCallbacks((prev: any) => [...prev, callback]) + const onRedo = useCallback((callback: () => void) => { + setRedoCallbacks(prev => [...prev, callback]) return () => setRedoCallbacks(prev => prev.filter(cb => cb !== callback)) }, []) diff --git a/web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx b/web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx index ba27d023e7..4d74e09fde 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx +++ b/web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx @@ -127,7 +127,7 @@ const VarReferencePicker: FC = ({ const reactflow = useReactFlow() - const startNode = availableNodes.find((node: any) => { + const startNode = availableNodes.find((node: Node) => { return node.data.type === BlockEnum.Start }) diff --git a/web/app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-config.tsx b/web/app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-config.tsx index 4adb924190..be80a8aac7 100644 --- a/web/app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-config.tsx +++ b/web/app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-config.tsx @@ -120,7 +120,7 @@ const JsonSchemaConfig: FC = ({ setJson(JSON.stringify(schema, null, 2)) }, [currentTab]) - const handleSubmit = useCallback((schema: any) => { + const handleSubmit = useCallback((schema: Record) => { const jsonSchema = jsonToSchema(schema) as SchemaRoot if (currentTab === SchemaView.VisualEditor) setJsonSchema(jsonSchema) diff --git a/web/app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/edit-card/index.tsx b/web/app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/edit-card/index.tsx index 1db31cd470..4aa0f99d3f 100644 --- a/web/app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/edit-card/index.tsx +++ b/web/app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/edit-card/index.tsx @@ -152,14 +152,16 @@ const EditCard: FC = ({ }, [isAdvancedEditing, emitPropertyOptionsChange, currentFields]) const handleAdvancedOptionsChange = useCallback((options: AdvancedOptionsType) => { - let enumValue: any = options.enum - if (enumValue === '') { + let enumValue: SchemaEnumType | undefined + if (options.enum === '') { enumValue = undefined } else { - enumValue = options.enum.replace(/\s/g, '').split(',') + const stringArray = options.enum.replace(/\s/g, '').split(',') if (currentFields.type === Type.number) - enumValue = (enumValue as SchemaEnumType).map(value => Number(value)).filter(num => !Number.isNaN(num)) + enumValue = stringArray.map(value => Number(value)).filter(num => !Number.isNaN(num)) + else + enumValue = stringArray } setCurrentFields(prev => ({ ...prev, enum: enumValue })) if (isAdvancedEditing) return diff --git a/web/service/base.ts b/web/service/base.ts index 6e189f1481..358f54183b 100644 --- a/web/service/base.ts +++ b/web/service/base.ts @@ -180,7 +180,7 @@ const handleStream = ( let isFirstMessage = true function read() { let hasError = false - reader?.read().then((result: any) => { + reader?.read().then((result: ReadableStreamReadResult) => { if (result.done) { onCompleted?.() return @@ -322,7 +322,21 @@ const handleStream = ( const baseFetch = base -export const upload = async (options: any, isPublicAPI?: boolean, url?: string, searchParams?: string): Promise => { +type UploadOptions = { + xhr: XMLHttpRequest + method: string + url?: string + headers?: Record + data: FormData + onprogress?: (this: XMLHttpRequest, ev: ProgressEvent) => void +} + +type UploadResponse = { + id: string + [key: string]: unknown +} + +export const upload = async (options: UploadOptions, isPublicAPI?: boolean, url?: string, searchParams?: string): Promise => { const urlPrefix = isPublicAPI ? PUBLIC_API_PREFIX : API_PREFIX const token = await getAccessToken(isPublicAPI) const defaultOptions = { @@ -331,18 +345,18 @@ export const upload = async (options: any, isPublicAPI?: boolean, url?: string, headers: { Authorization: `Bearer ${token}`, }, - data: {}, } - options = { + const mergedOptions = { ...defaultOptions, ...options, - headers: { ...defaultOptions.headers, ...options.headers }, + url: options.url || defaultOptions.url, + headers: { ...defaultOptions.headers, ...options.headers } as Record, } return new Promise((resolve, reject) => { - const xhr = options.xhr - xhr.open(options.method, options.url) - for (const key in options.headers) - xhr.setRequestHeader(key, options.headers[key]) + const xhr = mergedOptions.xhr + xhr.open(mergedOptions.method, mergedOptions.url) + for (const key in mergedOptions.headers) + xhr.setRequestHeader(key, mergedOptions.headers[key]) xhr.withCredentials = true xhr.responseType = 'json' @@ -354,8 +368,9 @@ export const upload = async (options: any, isPublicAPI?: boolean, url?: string, reject(xhr) } } - xhr.upload.onprogress = options.onprogress - xhr.send(options.data) + if (mergedOptions.onprogress) + xhr.upload.onprogress = mergedOptions.onprogress + xhr.send(mergedOptions.data) }) } @@ -432,7 +447,7 @@ export const ssePost = async ( if (!/^[23]\d{2}$/.test(String(res.status))) { if (res.status === 401) { if (isPublicAPI) { - res.json().then((data: any) => { + res.json().then((data: { code?: string; message?: string }) => { if (isPublicAPI) { if (data.code === 'web_app_access_denied') requiredWebSSOLogin(data.message, 403) From 3c4aa24198dd980130f6d30074de949d5a0d75f0 Mon Sep 17 00:00:00 2001 From: Asuka Minato Date: Thu, 9 Oct 2025 23:11:14 +0900 Subject: [PATCH 3/4] Refactor: Remove unnecessary casts and tighten type checking (#26625) Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- api/core/plugin/utils/chunk_merger.py | 5 +++-- .../workflow/nodes/knowledge_index/knowledge_index_node.py | 4 ++-- api/pyrightconfig.json | 1 - api/services/tools/mcp_tools_manage_service.py | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/api/core/plugin/utils/chunk_merger.py b/api/core/plugin/utils/chunk_merger.py index e30076f9d3..28cb70f96a 100644 --- a/api/core/plugin/utils/chunk_merger.py +++ b/api/core/plugin/utils/chunk_merger.py @@ -1,6 +1,6 @@ from collections.abc import Generator from dataclasses import dataclass, field -from typing import TypeVar, Union, cast +from typing import TypeVar, Union from core.agent.entities import AgentInvokeMessage from core.tools.entities.tool_entities import ToolInvokeMessage @@ -87,7 +87,8 @@ def merge_blob_chunks( ), meta=resp.meta, ) - yield cast(MessageType, merged_message) + assert isinstance(merged_message, (ToolInvokeMessage, AgentInvokeMessage)) + yield merged_message # type: ignore # Clean up the buffer del files[chunk_id] else: diff --git a/api/core/workflow/nodes/knowledge_index/knowledge_index_node.py b/api/core/workflow/nodes/knowledge_index/knowledge_index_node.py index 8d685fa82e..05e0c7707a 100644 --- a/api/core/workflow/nodes/knowledge_index/knowledge_index_node.py +++ b/api/core/workflow/nodes/knowledge_index/knowledge_index_node.py @@ -2,7 +2,7 @@ import datetime import logging import time from collections.abc import Mapping -from typing import Any, cast +from typing import Any from sqlalchemy import func, select @@ -62,7 +62,7 @@ class KnowledgeIndexNode(Node): return self._node_data def _run(self) -> NodeRunResult: # type: ignore - node_data = cast(KnowledgeIndexNodeData, self._node_data) + node_data = self._node_data variable_pool = self.graph_runtime_state.variable_pool dataset_id = variable_pool.get(["sys", SystemVariableKey.DATASET_ID]) if not dataset_id: diff --git a/api/pyrightconfig.json b/api/pyrightconfig.json index 9bc7498cb2..67571316a9 100644 --- a/api/pyrightconfig.json +++ b/api/pyrightconfig.json @@ -25,7 +25,6 @@ "reportMissingParameterType": "hint", "reportMissingTypeArgument": "hint", "reportUnnecessaryComparison": "hint", - "reportUnnecessaryCast": "hint", "reportUnnecessaryIsInstance": "hint", "reportUntypedFunctionDecorator": "hint", diff --git a/api/services/tools/mcp_tools_manage_service.py b/api/services/tools/mcp_tools_manage_service.py index dd626dd615..605ad8379b 100644 --- a/api/services/tools/mcp_tools_manage_service.py +++ b/api/services/tools/mcp_tools_manage_service.py @@ -1,7 +1,7 @@ import hashlib import json from datetime import datetime -from typing import Any, cast +from typing import Any from sqlalchemy import or_ from sqlalchemy.exc import IntegrityError @@ -55,7 +55,7 @@ class MCPToolManageService: cache=NoOpProviderCredentialCache(), ) - return cast(dict[str, str], encrypter_instance.encrypt(headers)) + return encrypter_instance.encrypt(headers) @staticmethod def get_mcp_provider_by_provider_id(provider_id: str, tenant_id: str) -> MCPToolProvider: From 885dff82e3f28d4c1eaae5e39b2b32a9cfb4494e Mon Sep 17 00:00:00 2001 From: Nan LI Date: Fri, 10 Oct 2025 09:00:06 +0800 Subject: [PATCH 4/4] feat: update HTTP timeout configurations and enhance timeout input handling in UI (#26685) --- api/configs/feature/__init__.py | 6 ++-- .../unit_tests/configs/test_dify_config.py | 32 +++++++++++++++---- docker/.env.example | 10 ++++++ docker/docker-compose.yaml | 3 ++ .../nodes/http/components/timeout/index.tsx | 13 ++++++-- 5 files changed, 51 insertions(+), 13 deletions(-) diff --git a/api/configs/feature/__init__.py b/api/configs/feature/__init__.py index 42c88dda8b..5b871f69f9 100644 --- a/api/configs/feature/__init__.py +++ b/api/configs/feature/__init__.py @@ -362,11 +362,11 @@ class HttpConfig(BaseSettings): ) HTTP_REQUEST_MAX_READ_TIMEOUT: int = Field( - ge=1, description="Maximum read timeout in seconds for HTTP requests", default=60 + ge=1, description="Maximum read timeout in seconds for HTTP requests", default=600 ) HTTP_REQUEST_MAX_WRITE_TIMEOUT: int = Field( - ge=1, description="Maximum write timeout in seconds for HTTP requests", default=20 + ge=1, description="Maximum write timeout in seconds for HTTP requests", default=600 ) HTTP_REQUEST_NODE_MAX_BINARY_SIZE: PositiveInt = Field( @@ -771,7 +771,7 @@ class MailConfig(BaseSettings): MAIL_TEMPLATING_TIMEOUT: int = Field( description=""" - Timeout for email templating in seconds. Used to prevent infinite loops in malicious templates. + Timeout for email templating in seconds. Used to prevent infinite loops in malicious templates. Only available in sandbox mode.""", default=3, ) diff --git a/api/tests/unit_tests/configs/test_dify_config.py b/api/tests/unit_tests/configs/test_dify_config.py index 2968de4b91..209b6bf59b 100644 --- a/api/tests/unit_tests/configs/test_dify_config.py +++ b/api/tests/unit_tests/configs/test_dify_config.py @@ -15,13 +15,13 @@ def test_dify_config(monkeypatch: pytest.MonkeyPatch): # Set environment variables using monkeypatch monkeypatch.setenv("CONSOLE_API_URL", "https://example.com") monkeypatch.setenv("CONSOLE_WEB_URL", "https://example.com") - monkeypatch.setenv("HTTP_REQUEST_MAX_WRITE_TIMEOUT", "30") + monkeypatch.setenv("HTTP_REQUEST_MAX_WRITE_TIMEOUT", "30") # Custom value for testing monkeypatch.setenv("DB_USERNAME", "postgres") monkeypatch.setenv("DB_PASSWORD", "postgres") monkeypatch.setenv("DB_HOST", "localhost") monkeypatch.setenv("DB_PORT", "5432") monkeypatch.setenv("DB_DATABASE", "dify") - monkeypatch.setenv("HTTP_REQUEST_MAX_READ_TIMEOUT", "600") + monkeypatch.setenv("HTTP_REQUEST_MAX_READ_TIMEOUT", "300") # Custom value for testing # load dotenv file with pydantic-settings config = DifyConfig() @@ -35,16 +35,36 @@ def test_dify_config(monkeypatch: pytest.MonkeyPatch): assert config.SENTRY_TRACES_SAMPLE_RATE == 1.0 assert config.TEMPLATE_TRANSFORM_MAX_LENGTH == 400_000 - # annotated field with default value - assert config.HTTP_REQUEST_MAX_READ_TIMEOUT == 600 + # annotated field with custom configured value + assert config.HTTP_REQUEST_MAX_READ_TIMEOUT == 300 - # annotated field with configured value + # annotated field with custom configured value assert config.HTTP_REQUEST_MAX_WRITE_TIMEOUT == 30 # values from pyproject.toml assert Version(config.project.version) >= Version("1.0.0") +def test_http_timeout_defaults(monkeypatch: pytest.MonkeyPatch): + """Test that HTTP timeout defaults are correctly set""" + # clear system environment variables + os.environ.clear() + + # Set minimal required env vars + monkeypatch.setenv("DB_USERNAME", "postgres") + monkeypatch.setenv("DB_PASSWORD", "postgres") + monkeypatch.setenv("DB_HOST", "localhost") + monkeypatch.setenv("DB_PORT", "5432") + monkeypatch.setenv("DB_DATABASE", "dify") + + config = DifyConfig() + + # Verify default timeout values + assert config.HTTP_REQUEST_MAX_CONNECT_TIMEOUT == 10 + assert config.HTTP_REQUEST_MAX_READ_TIMEOUT == 600 + assert config.HTTP_REQUEST_MAX_WRITE_TIMEOUT == 600 + + # 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`. def test_flask_configs(monkeypatch: pytest.MonkeyPatch): @@ -55,7 +75,6 @@ def test_flask_configs(monkeypatch: pytest.MonkeyPatch): # Set environment variables using monkeypatch monkeypatch.setenv("CONSOLE_API_URL", "https://example.com") monkeypatch.setenv("CONSOLE_WEB_URL", "https://example.com") - monkeypatch.setenv("HTTP_REQUEST_MAX_WRITE_TIMEOUT", "30") monkeypatch.setenv("DB_USERNAME", "postgres") monkeypatch.setenv("DB_PASSWORD", "postgres") monkeypatch.setenv("DB_HOST", "localhost") @@ -105,7 +124,6 @@ def test_inner_api_config_exist(monkeypatch: pytest.MonkeyPatch): # Set environment variables using monkeypatch monkeypatch.setenv("CONSOLE_API_URL", "https://example.com") monkeypatch.setenv("CONSOLE_WEB_URL", "https://example.com") - monkeypatch.setenv("HTTP_REQUEST_MAX_WRITE_TIMEOUT", "30") monkeypatch.setenv("DB_USERNAME", "postgres") monkeypatch.setenv("DB_PASSWORD", "postgres") monkeypatch.setenv("DB_HOST", "localhost") diff --git a/docker/.env.example b/docker/.env.example index e04ef9e5bc..6d07cf7fa5 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -930,6 +930,16 @@ WORKFLOW_LOG_CLEANUP_BATCH_SIZE=100 HTTP_REQUEST_NODE_MAX_BINARY_SIZE=10485760 HTTP_REQUEST_NODE_MAX_TEXT_SIZE=1048576 HTTP_REQUEST_NODE_SSL_VERIFY=True + +# HTTP request node timeout configuration +# Maximum timeout values (in seconds) that users can set in HTTP request nodes +# - Connect timeout: Time to wait for establishing connection (default: 10s) +# - Read timeout: Time to wait for receiving response data (default: 600s, 10 minutes) +# - Write timeout: Time to wait for sending request data (default: 600s, 10 minutes) +HTTP_REQUEST_MAX_CONNECT_TIMEOUT=10 +HTTP_REQUEST_MAX_READ_TIMEOUT=600 +HTTP_REQUEST_MAX_WRITE_TIMEOUT=600 + # Base64 encoded CA certificate data for custom certificate verification (PEM format, optional) # HTTP_REQUEST_NODE_SSL_CERT_DATA=LS0tLS1CRUdJTi... # Base64 encoded client certificate data for mutual TLS authentication (PEM format, optional) diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index abac6d3b1e..5d47471093 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -418,6 +418,9 @@ x-shared-env: &shared-api-worker-env HTTP_REQUEST_NODE_MAX_BINARY_SIZE: ${HTTP_REQUEST_NODE_MAX_BINARY_SIZE:-10485760} HTTP_REQUEST_NODE_MAX_TEXT_SIZE: ${HTTP_REQUEST_NODE_MAX_TEXT_SIZE:-1048576} HTTP_REQUEST_NODE_SSL_VERIFY: ${HTTP_REQUEST_NODE_SSL_VERIFY:-True} + HTTP_REQUEST_MAX_CONNECT_TIMEOUT: ${HTTP_REQUEST_MAX_CONNECT_TIMEOUT:-10} + HTTP_REQUEST_MAX_READ_TIMEOUT: ${HTTP_REQUEST_MAX_READ_TIMEOUT:-600} + HTTP_REQUEST_MAX_WRITE_TIMEOUT: ${HTTP_REQUEST_MAX_WRITE_TIMEOUT:-600} RESPECT_XFORWARD_HEADERS_ENABLED: ${RESPECT_XFORWARD_HEADERS_ENABLED:-false} SSRF_PROXY_HTTP_URL: ${SSRF_PROXY_HTTP_URL:-http://ssrf_proxy:3128} SSRF_PROXY_HTTPS_URL: ${SSRF_PROXY_HTTPS_URL:-http://ssrf_proxy:3128} diff --git a/web/app/components/workflow/nodes/http/components/timeout/index.tsx b/web/app/components/workflow/nodes/http/components/timeout/index.tsx index 40ebab0e2a..bb84091d67 100644 --- a/web/app/components/workflow/nodes/http/components/timeout/index.tsx +++ b/web/app/components/workflow/nodes/http/components/timeout/index.tsx @@ -5,6 +5,8 @@ import { useTranslation } from 'react-i18next' import type { Timeout as TimeoutPayloadType } from '../../types' import Input from '@/app/components/base/input' import { FieldCollapse } from '@/app/components/workflow/nodes/_base/components/collapse' +import { useStore } from '@/app/components/workflow/store' +import { BlockEnum } from '@/app/components/workflow/types' type Props = { readonly: boolean @@ -61,6 +63,11 @@ const Timeout: FC = ({ readonly, payload, onChange }) => { const { t } = useTranslation() const { connect, read, write, max_connect_timeout, max_read_timeout, max_write_timeout } = payload ?? {} + // Get default config from store for max timeout values + const nodesDefaultConfigs = useStore(s => s.nodesDefaultConfigs) + const defaultConfig = nodesDefaultConfigs?.[BlockEnum.HttpRequest] + const defaultTimeout = defaultConfig?.timeout || {} + return (
@@ -73,7 +80,7 @@ const Timeout: FC = ({ readonly, payload, onChange }) => { value={connect} onChange={v => onChange?.({ ...payload, connect: v })} min={1} - max={max_connect_timeout || 300} + max={max_connect_timeout || defaultTimeout.max_connect_timeout || 10} /> = ({ readonly, payload, onChange }) => { value={read} onChange={v => onChange?.({ ...payload, read: v })} min={1} - max={max_read_timeout || 600} + max={max_read_timeout || defaultTimeout.max_read_timeout || 600} /> = ({ readonly, payload, onChange }) => { value={write} onChange={v => onChange?.({ ...payload, write: v })} min={1} - max={max_write_timeout || 600} + max={max_write_timeout || defaultTimeout.max_write_timeout || 600} />