Using custom tool if response is more than 10 seconds the response is time out. #1032

Closed
opened 2026-02-21 17:29:35 -05:00 by yindo · 4 comments
Owner

Originally created by @myrulezzz on GitHub (Feb 4, 2024).

Originally assigned to: @crazywoola, @VincePotato on GitHub.

Self Checks

1. Is this request related to a challenge you're experiencing?

Created a custom tool that calls a fastapi to fetch results for an oracle database.
For some dbs the response is generated after 10-15 seconds with curl command however from dify i get time out error.

2. Describe the feature you'd like to see

Be able to tune the response wait time for custom tools

3. How will this feature improve your workflow or experience?

Will give control when creating custom tool to add max wait time for response

4. Additional context or comments

If you have a fastapi which the response gets 10-15 seconds to return and you add it as a custom tool in dify you will get most probably time out error in the response of the api

5. Can you help us with this feature?

  • I am interested in contributing to this feature.
Originally created by @myrulezzz on GitHub (Feb 4, 2024). Originally assigned to: @crazywoola, @VincePotato on GitHub. ### Self Checks - [X] I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones. - [X] I confirm that I am using English to file this report (我已阅读并同意 [Language Policy](https://github.com/langgenius/dify/issues/1542)). ### 1. Is this request related to a challenge you're experiencing? Created a custom tool that calls a fastapi to fetch results for an oracle database. For some dbs the response is generated after 10-15 seconds with curl command however from dify i get time out error. ### 2. Describe the feature you'd like to see Be able to tune the response wait time for custom tools ### 3. How will this feature improve your workflow or experience? Will give control when creating custom tool to add max wait time for response ### 4. Additional context or comments If you have a fastapi which the response gets 10-15 seconds to return and you add it as a custom tool in dify you will get most probably time out error in the response of the api ### 5. Can you help us with this feature? - [ ] I am interested in contributing to this feature.
yindo added the 💪 enhancement label 2026-02-21 17:29:35 -05:00
yindo closed this issue 2026-02-21 17:29:35 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Feb 4, 2024):

🤖

Hey there, @myrulezzz! Great to see you back and diving into another intriguing challenge with Dify. Your knack for pushing the boundaries never ceases to amaze! 🚀

Thank you for your feature request. Currently, the timeout setting for the dify API when it interacts with custom tools is hardcoded to 10 seconds in the get_api_tool_provider_remote_schema method. This method sends an HTTP GET request to the specified URL and waits for a response. If the response is not received within 10 seconds, a timeout error is thrown.

Here is the relevant code snippet:

def get_api_tool_provider_remote_schema(
    user_id: str, tenant_id: str, url: str
):
    """
        get api tool provider remote schema
    """
    headers = {
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0",
        "Accept": "*/*",
    }

    try:
        response = get(url, headers=headers, timeout=10)
        if response.status_code != 200:
            raise ValueError(f'Got status code {response.status_code}')
        schema = response.text
        # try to parse schema, avoid SSRF attack
        ToolManageService.parser_api_schema(schema)
    except Exception as e:
        raise ValueError(f'invalid schema, please check the url you provided')
    
    return {
        'schema': schema
    }

Source: api/services/tools_manage_service.py

Your suggestion to make this timeout configurable is a good one, as it would allow users to adjust the timeout based on the performance of their custom tools. However, as of now, there is no configuration file or environment variable that controls this timeout setting.

This feature would require changes to the codebase to allow the timeout value to be set via a configuration file or an environment variable. This would involve modifying the get_api_tool_provider_remote_schema method to read the timeout value from the configuration or environment, and use that value for the timeout parameter in the get function call.

Please note that increasing the timeout value could lead to longer wait times for the user if the custom tool is slow to respond. It's important to find a balance between allowing enough time for the custom tool to respond and keeping the user wait time to a minimum.

I hope this answers your question. If you have any further questions or need more clarification, please let me know.

Sources


This response is meant to be useful and save you time. It is not meant to be a precise solution, but rather a starting point for your own research.

Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.

If you want to continue the conversation, start your reply with @dosu-bot.

@dosubot[bot] commented on GitHub (Feb 4, 2024): _🤖_ <!-- Greeting --> Hey there, @myrulezzz! Great to see you back and diving into another intriguing challenge with Dify. Your knack for pushing the boundaries never ceases to amaze! 🚀 <!-- Answer --> Thank you for your feature request. Currently, the timeout setting for the dify API when it interacts with custom tools is hardcoded to 10 seconds in the `get_api_tool_provider_remote_schema` method. This method sends an HTTP GET request to the specified URL and waits for a response. If the response is not received within 10 seconds, a timeout error is thrown. Here is the relevant code snippet: ```py def get_api_tool_provider_remote_schema( user_id: str, tenant_id: str, url: str ): """ get api tool provider remote schema """ headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0", "Accept": "*/*", } try: response = get(url, headers=headers, timeout=10) if response.status_code != 200: raise ValueError(f'Got status code {response.status_code}') schema = response.text # try to parse schema, avoid SSRF attack ToolManageService.parser_api_schema(schema) except Exception as e: raise ValueError(f'invalid schema, please check the url you provided') return { 'schema': schema } ``` Source: [api/services/tools_manage_service.py](https://github.com/langgenius/dify/blob/main/api/services/tools_manage_service.py) Your suggestion to make this timeout configurable is a good one, as it would allow users to adjust the timeout based on the performance of their custom tools. However, as of now, there is no configuration file or environment variable that controls this timeout setting. This feature would require changes to the codebase to allow the timeout value to be set via a configuration file or an environment variable. This would involve modifying the `get_api_tool_provider_remote_schema` method to read the timeout value from the configuration or environment, and use that value for the timeout parameter in the `get` function call. Please note that increasing the timeout value could lead to longer wait times for the user if the custom tool is slow to respond. It's important to find a balance between allowing enough time for the custom tool to respond and keeping the user wait time to a minimum. I hope this answers your question. If you have any further questions or need more clarification, please let me know. ## Sources - [api/services/tools_manage_service.py](https://github.com/langgenius/dify/blob/main/api/services/tools_manage_service.py) --- This response is meant to be useful and save you time. It is **not meant to be a precise solution**, but rather a starting point for your own research. Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant. If you want to continue the conversation, start your reply with @dosu-bot.
Author
Owner

@myrulezzz commented on GitHub (Feb 9, 2024):

Thanks it will be a good addition

@myrulezzz commented on GitHub (Feb 9, 2024): Thanks it will be a good addition
Author
Owner

@lanelam commented on GitHub (Feb 19, 2024):

For those who are bothered by the same problem, I tried bot's suggestion to modify local file api/services/tools_manage_service.py but it did not work.

The right place is at api/core/tools/tool/api_tool.py, and the relevant code snippet is:

    def do_http_request(self, url: str, method: str, headers: dict[str, Any], parameters: dict[str, Any]) -> httpx.Response:
        """
            do http request depending on api bundle
        """

        # ...

        # do http request
        if method == 'get':
            response = ssrf_proxy.get(
                url, params=params, headers=headers, cookies=cookies, timeout=10, follow_redirects=True)
        elif method == 'post':
            response = ssrf_proxy.post(url, params=params, headers=headers,
                                       cookies=cookies, data=body, timeout=10, follow_redirects=True)
        elif method == 'put':
            response = ssrf_proxy.put(url, params=params, headers=headers,
                                      cookies=cookies, data=body, timeout=10, follow_redirects=True)
        elif method == 'delete':
            """
            request body data is unsupported for DELETE method in standard http protocol
            however, OpenAPI 3.0 supports request body data for DELETE method, so we support it here by using requests
            """
            response = ssrf_proxy.delete(url, params=params, headers=headers,
                                         cookies=cookies, data=body, timeout=10, allow_redirects=True)
        elif method == 'patch':
            response = ssrf_proxy.patch(url, params=params, headers=headers,
                                        cookies=cookies, data=body, timeout=10, follow_redirects=True)
        elif method == 'head':
            response = ssrf_proxy.head(
                url, params=params, headers=headers, cookies=cookies, timeout=10, follow_redirects=True)
        elif method == 'options':
            response = ssrf_proxy.options(
                url, params=params, headers=headers, cookies=cookies, timeout=10, follow_redirects=True)
        else:
            raise ValueError(f'Invalid http method {method}')

        return response

Change timeout=10 to a timeout you seem fits.

@lanelam commented on GitHub (Feb 19, 2024): For those who are bothered by the same problem, I tried bot's suggestion to modify local file [api/services/tools_manage_service.py](api/services/tools_manage_service.py) but it did not work. The right place is at [api/core/tools/tool/api_tool.py](api/core/tools/tool/api_tool.py), and the relevant code snippet is: ```python def do_http_request(self, url: str, method: str, headers: dict[str, Any], parameters: dict[str, Any]) -> httpx.Response: """ do http request depending on api bundle """ # ... # do http request if method == 'get': response = ssrf_proxy.get( url, params=params, headers=headers, cookies=cookies, timeout=10, follow_redirects=True) elif method == 'post': response = ssrf_proxy.post(url, params=params, headers=headers, cookies=cookies, data=body, timeout=10, follow_redirects=True) elif method == 'put': response = ssrf_proxy.put(url, params=params, headers=headers, cookies=cookies, data=body, timeout=10, follow_redirects=True) elif method == 'delete': """ request body data is unsupported for DELETE method in standard http protocol however, OpenAPI 3.0 supports request body data for DELETE method, so we support it here by using requests """ response = ssrf_proxy.delete(url, params=params, headers=headers, cookies=cookies, data=body, timeout=10, allow_redirects=True) elif method == 'patch': response = ssrf_proxy.patch(url, params=params, headers=headers, cookies=cookies, data=body, timeout=10, follow_redirects=True) elif method == 'head': response = ssrf_proxy.head( url, params=params, headers=headers, cookies=cookies, timeout=10, follow_redirects=True) elif method == 'options': response = ssrf_proxy.options( url, params=params, headers=headers, cookies=cookies, timeout=10, follow_redirects=True) else: raise ValueError(f'Invalid http method {method}') return response ``` Change `timeout=10` to a timeout you seem fits.
Author
Owner

@github-actions[bot] commented on GitHub (Mar 5, 2024):

Close due to it's no longer active, if you have any questions, you can reopen it.

@github-actions[bot] commented on GitHub (Mar 5, 2024): Close due to it's no longer active, if you have any questions, you can reopen it.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify#1032