dify
dify copied to clipboard
Using custom tool if response is more than 10 seconds the response is time out.
Self Checks
- [X] I have searched for existing issues search for existing issues, including closed ones.
- [X] I confirm that I am using English to file this report (我已阅读并同意 Language Policy).
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.
🤖
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.
Thanks it will be a good addition
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.
Close due to it's no longer active, if you have any questions, you can reopen it.