Custom API Tool Doesn't Handle allOf #4970

Closed
opened 2026-02-21 18:08:49 -05:00 by yindo · 6 comments
Owner

Originally created by @mbbyn on GitHub (Aug 9, 2024).

Self Checks

  • This is only for bug report, if you would like to ask a question, please head to Discussions.
  • I have searched for existing issues search for existing issues, including closed ones.
  • I confirm that I am using English to submit this report (我已阅读并同意 Language Policy).
  • [FOR CHINESE USERS] 请务必使用英文提交 Issue,否则会被关闭。谢谢!:)
  • Please do not modify this template :) and fill in all the required fields.

Dify version

0.6.16

Cloud or Self Hosted

Self Hosted (Docker)

Steps to reproduce

  • prepare an OpenAPI JSON with a schema containing allOf
  • Add it as a custom tool
  • Click "Configure", then "test" an API with allOf parameter.

✔️ Expected Behavior

The "Test" call would call the API with all the entered parameters.

Actual Behavior

The API is call doesn't pass allOf parameters.

Evidence

Running the custom tool in a workflow

image

Testing the custom tool from the tool creation screen

image

Server logs

image

Originally created by @mbbyn on GitHub (Aug 9, 2024). ### Self Checks - [X] This is only for bug report, if you would like to ask a question, please head to [Discussions](https://github.com/langgenius/dify/discussions/categories/general). - [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 submit this report (我已阅读并同意 [Language Policy](https://github.com/langgenius/dify/issues/1542)). - [X] [FOR CHINESE USERS] 请务必使用英文提交 Issue,否则会被关闭。谢谢!:) - [X] Please do not modify this template :) and fill in all the required fields. ### Dify version 0.6.16 ### Cloud or Self Hosted Self Hosted (Docker) ### Steps to reproduce - prepare an OpenAPI JSON with a schema containing `allOf` - Add it as a custom tool - Click "Configure", then "test" an API with `allOf` parameter. ### ✔️ Expected Behavior The "Test" call would call the API with all the entered parameters. ### ❌ Actual Behavior The API is call doesn't pass `allOf` parameters. ## Evidence Running the custom tool in a workflow ![image](https://github.com/user-attachments/assets/94b61580-c9a1-4f96-aaef-5681aba3f3a2) Testing the custom tool from the tool creation screen ![image](https://github.com/user-attachments/assets/9528230c-2444-40a2-916c-0e3726b2a70f) Server logs ![image](https://github.com/user-attachments/assets/82079d4f-2f95-40b1-98f0-e6a332a8b91b)
yindo added the 🐞 bug label 2026-02-21 18:08:49 -05:00
yindo closed this issue 2026-02-21 18:08:49 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Aug 9, 2024):

The issue you're encountering with multiple parameters not being passed correctly in a custom tool has been addressed in a recent pull request. The changes made in the pull request fix: tool params not work as expected when develop a tool include the addition of a method to transform tool parameters into the correct type before they are used. This ensures that all parameters are correctly typed and prevents them from being converted to empty values during validation.

Here are the key changes:

  1. Addition of _transform_tool_parameters_type Method:

    def _transform_tool_parameters_type(self, tool_parameters: dict[str, Any]) -> dict[str, Any]:
        """
        Transform tool parameters type
        """
        result = deepcopy(tool_parameters)
        for parameter in self.parameters or []:
            if parameter.name in tool_parameters:
                result[parameter.name] = ToolParameterConverter.cast_parameter_by_type(tool_parameters[parameter.name], parameter.type)
    
        return result
    
  2. Modification in invoke Method:

    def invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> list[ToolInvokeMessage]:
        if self.runtime.runtime_parameters:
            tool_parameters.update(self.runtime.runtime_parameters)
    
        tool_parameters = self._transform_tool_parameters_type(tool_parameters)
    
        result = self._invoke(
            user_id=user_id,
            tool_parameters=tool_parameters,
        )
    
        if not isinstance(result, list):
            result = [result]
    
        return result
    

These changes ensure that the tool parameters are transformed into the correct type before being used, which should resolve the issue of multiple parameters not being passed correctly [1].

Additionally, there have been recent updates in the do_http_request method to handle different types of parameters (path, query, cookie, header) and process request bodies based on the Content-Type. This ensures that parameters are correctly assigned and converted based on their specified types [2].

For further details, you can refer to the pull request and the recent changes in the codebase.

To continue talking to Dosu, mention @dosu.

@dosubot[bot] commented on GitHub (Aug 9, 2024): <!-- Answer --> The issue you're encountering with multiple parameters not being passed correctly in a custom tool has been addressed in a recent pull request. The changes made in the pull request [fix: tool params not work as expected when develop a tool](https://github.com/langgenius/dify/pull/6550) include the addition of a method to transform tool parameters into the correct type before they are used. This ensures that all parameters are correctly typed and prevents them from being converted to empty values during validation. Here are the key changes: 1. **Addition of `_transform_tool_parameters_type` Method:** ```python def _transform_tool_parameters_type(self, tool_parameters: dict[str, Any]) -> dict[str, Any]: """ Transform tool parameters type """ result = deepcopy(tool_parameters) for parameter in self.parameters or []: if parameter.name in tool_parameters: result[parameter.name] = ToolParameterConverter.cast_parameter_by_type(tool_parameters[parameter.name], parameter.type) return result ``` 2. **Modification in `invoke` Method:** ```python def invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> list[ToolInvokeMessage]: if self.runtime.runtime_parameters: tool_parameters.update(self.runtime.runtime_parameters) tool_parameters = self._transform_tool_parameters_type(tool_parameters) result = self._invoke( user_id=user_id, tool_parameters=tool_parameters, ) if not isinstance(result, list): result = [result] return result ``` These changes ensure that the tool parameters are transformed into the correct type before being used, which should resolve the issue of multiple parameters not being passed correctly <sup>[[1]](https://github.com/langgenius/dify/blob/main/api/core/tools/tool/tool.py)</sup>. Additionally, there have been recent updates in the `do_http_request` method to handle different types of parameters (`path`, `query`, `cookie`, `header`) and process request bodies based on the `Content-Type`. This ensures that parameters are correctly assigned and converted based on their specified types <sup>[[2]](https://github.com/langgenius/dify/blob/main/api/core/tools/tool/api_tool.py)</sup>. For further details, you can refer to the pull request and the recent changes in the codebase. <!-- Dosu Comment Footer --> *To continue talking to [Dosu](https://dosu.dev), mention @dosu.*
Author
Owner

@crazywoola commented on GitHub (Aug 9, 2024):

It seems you didn't handle the request from our server properly. https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400 The validation error raised in your server not ours.

@crazywoola commented on GitHub (Aug 9, 2024): It seems you didn't handle the request from our server properly. https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400 The validation error raised in your server not ours.
Author
Owner

@mbbyn commented on GitHub (Aug 9, 2024):

@crazywoola 4xx errors usually refer to a client issue not a server issue. As you can see from the logs, the server is not receiving all the required parameters, which means the client is not sending them in the first place.

I believe this is a Dify HTTP client bug and this issue should be opened.

In reference to the Mozilla link, it also states the same:

image

@mbbyn commented on GitHub (Aug 9, 2024): @crazywoola 4xx errors usually refer to a client issue not a server issue. As you can see from the logs, the server is not receiving all the required parameters, which means the client is not sending them in the first place. I believe this is a Dify HTTP client bug and this issue should be opened. In reference to the Mozilla link, it also states the same: ![image](https://github.com/user-attachments/assets/e6f7d02c-2f26-4af8-8e37-47e5ea0afa69)
Author
Owner

@mbbyn commented on GitHub (Aug 9, 2024):

I took a look at the dify code responsible for translating API Tool to an HTTP request, and it seem to be parsing the Open API schema manually, missing allOf parsing in the process. The respective code is here:

https://github.com/langgenius/dify/blob/c6b0dc6a29ff6096b0febb2204b6d20d83f68ace/api/core/tools/tool/api_tool.py#L198-L232

Reference schema

image

@mbbyn commented on GitHub (Aug 9, 2024): I took a look at the dify code responsible for translating API Tool to an HTTP request, and it seem to be parsing the Open API schema manually, missing `allOf` parsing in the process. The respective code is here: https://github.com/langgenius/dify/blob/c6b0dc6a29ff6096b0febb2204b6d20d83f68ace/api/core/tools/tool/api_tool.py#L198-L232 Reference schema ![image](https://github.com/user-attachments/assets/06a3be7d-9dc6-45e9-86f7-13c261393e58)
Author
Owner

@mbbyn commented on GitHub (Aug 9, 2024):

I built a small PoC that uses openapi_python_client library to parse the OpenAPI schema into typed pydantic models. I believe this will both solve this bug, expand support to even more options, and reduce the code maintained in Dify as this is a solved problem (IMHO) and no need for Dify to write a separate parser for OpenAPI spec.

Here is PoC. Please let me know if this is something you would be interested in accepting as a PR?

image

@mbbyn commented on GitHub (Aug 9, 2024): I built a small PoC that uses `openapi_python_client` library to parse the OpenAPI schema into typed pydantic models. I believe this will both solve this bug, expand support to even more options, and reduce the code maintained in Dify as this is a solved problem (IMHO) and no need for Dify to write a separate parser for OpenAPI spec. Here is PoC. Please let me know if this is something you would be interested in accepting as a PR? ![image](https://github.com/user-attachments/assets/4503f416-d565-4c21-94da-21f560224385)
Author
Owner

@mbbyn commented on GitHub (Aug 11, 2024):

Hope you would consider reopening @crazywoola @takatost. If it is not supported, we will use a work around that doesn't rely on allOf.

@mbbyn commented on GitHub (Aug 11, 2024): Hope you would consider reopening @crazywoola @takatost. If it is not supported, we will use a work around that doesn't rely on `allOf`.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify#4970