Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
dify
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ai-tech
dify
Commits
a769edbc
Unverified
Commit
a769edbc
authored
Feb 29, 2024
by
Yeuoly
Committed by
GitHub
Feb 29, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix/custom tool any of (#2625)
parent
57ffecd0
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
64 additions
and
22 deletions
+64
-22
api_tool.py
api/core/tools/tool/api_tool.py
+63
-21
test-api.tsx
...omponents/tools/edit-custom-collection-modal/test-api.tsx
+1
-1
No files found.
api/core/tools/tool/api_tool.py
View file @
a769edbc
...
@@ -67,9 +67,9 @@ class ApiTool(Tool):
...
@@ -67,9 +67,9 @@ class ApiTool(Tool):
if
'api_key_header_prefix'
in
credentials
:
if
'api_key_header_prefix'
in
credentials
:
api_key_header_prefix
=
credentials
[
'api_key_header_prefix'
]
api_key_header_prefix
=
credentials
[
'api_key_header_prefix'
]
if
api_key_header_prefix
==
'basic'
:
if
api_key_header_prefix
==
'basic'
and
credentials
[
'api_key_value'
]
:
credentials
[
'api_key_value'
]
=
f
'Basic {credentials["api_key_value"]}'
credentials
[
'api_key_value'
]
=
f
'Basic {credentials["api_key_value"]}'
elif
api_key_header_prefix
==
'bearer'
:
elif
api_key_header_prefix
==
'bearer'
and
credentials
[
'api_key_value'
]
:
credentials
[
'api_key_value'
]
=
f
'Bearer {credentials["api_key_value"]}'
credentials
[
'api_key_value'
]
=
f
'Bearer {credentials["api_key_value"]}'
elif
api_key_header_prefix
==
'custom'
:
elif
api_key_header_prefix
==
'custom'
:
pass
pass
...
@@ -184,21 +184,7 @@ class ApiTool(Tool):
...
@@ -184,21 +184,7 @@ class ApiTool(Tool):
for
name
,
property
in
properties
.
items
():
for
name
,
property
in
properties
.
items
():
if
name
in
parameters
:
if
name
in
parameters
:
# convert type
# convert type
try
:
body
[
name
]
=
self
.
_convert_body_property_type
(
property
,
parameters
[
name
])
value
=
parameters
[
name
]
if
property
[
'type'
]
==
'integer'
:
value
=
int
(
value
)
elif
property
[
'type'
]
==
'number'
:
# check if it is a float
if
'.'
in
value
:
value
=
float
(
value
)
else
:
value
=
int
(
value
)
elif
property
[
'type'
]
==
'boolean'
:
value
=
bool
(
value
)
body
[
name
]
=
value
except
ValueError
as
e
:
body
[
name
]
=
parameters
[
name
]
elif
name
in
required
:
elif
name
in
required
:
raise
ToolProviderCredentialValidationError
(
raise
ToolProviderCredentialValidationError
(
f
"Missing required parameter {name} in operation {self.api_bundle.operation_id}"
f
"Missing required parameter {name} in operation {self.api_bundle.operation_id}"
...
@@ -228,10 +214,6 @@ class ApiTool(Tool):
...
@@ -228,10 +214,6 @@ class ApiTool(Tool):
elif
method
==
'put'
:
elif
method
==
'put'
:
response
=
ssrf_proxy
.
put
(
url
,
params
=
params
,
headers
=
headers
,
cookies
=
cookies
,
data
=
body
,
timeout
=
10
,
follow_redirects
=
True
)
response
=
ssrf_proxy
.
put
(
url
,
params
=
params
,
headers
=
headers
,
cookies
=
cookies
,
data
=
body
,
timeout
=
10
,
follow_redirects
=
True
)
elif
method
==
'delete'
:
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
)
response
=
ssrf_proxy
.
delete
(
url
,
params
=
params
,
headers
=
headers
,
cookies
=
cookies
,
data
=
body
,
timeout
=
10
,
allow_redirects
=
True
)
elif
method
==
'patch'
:
elif
method
==
'patch'
:
response
=
ssrf_proxy
.
patch
(
url
,
params
=
params
,
headers
=
headers
,
cookies
=
cookies
,
data
=
body
,
timeout
=
10
,
follow_redirects
=
True
)
response
=
ssrf_proxy
.
patch
(
url
,
params
=
params
,
headers
=
headers
,
cookies
=
cookies
,
data
=
body
,
timeout
=
10
,
follow_redirects
=
True
)
...
@@ -243,6 +225,66 @@ class ApiTool(Tool):
...
@@ -243,6 +225,66 @@ class ApiTool(Tool):
raise
ValueError
(
f
'Invalid http method {method}'
)
raise
ValueError
(
f
'Invalid http method {method}'
)
return
response
return
response
def
_convert_body_property_any_of
(
self
,
property
:
dict
[
str
,
Any
],
value
:
Any
,
any_of
:
list
[
dict
[
str
,
Any
]],
max_recursive
=
10
)
->
Any
:
if
max_recursive
<=
0
:
raise
Exception
(
"Max recursion depth reached"
)
for
option
in
any_of
or
[]:
try
:
if
'type'
in
option
:
# Attempt to convert the value based on the type.
if
option
[
'type'
]
==
'integer'
or
option
[
'type'
]
==
'int'
:
return
int
(
value
)
elif
option
[
'type'
]
==
'number'
:
if
'.'
in
str
(
value
):
return
float
(
value
)
else
:
return
int
(
value
)
elif
option
[
'type'
]
==
'string'
:
return
str
(
value
)
elif
option
[
'type'
]
==
'boolean'
:
if
str
(
value
)
.
lower
()
in
[
'true'
,
'1'
]:
return
True
elif
str
(
value
)
.
lower
()
in
[
'false'
,
'0'
]:
return
False
else
:
continue
# Not a boolean, try next option
elif
option
[
'type'
]
==
'null'
and
not
value
:
return
None
else
:
continue
# Unsupported type, try next option
elif
'anyOf'
in
option
and
isinstance
(
option
[
'anyOf'
],
list
):
# Recursive call to handle nested anyOf
return
self
.
_convert_body_property_any_of
(
property
,
value
,
option
[
'anyOf'
],
max_recursive
-
1
)
except
ValueError
:
continue
# Conversion failed, try next option
# If no option succeeded, you might want to return the value as is or raise an error
return
value
# or raise ValueError(f"Cannot convert value '{value}' to any specified type in anyOf")
def
_convert_body_property_type
(
self
,
property
:
dict
[
str
,
Any
],
value
:
Any
)
->
Any
:
try
:
if
'type'
in
property
:
if
property
[
'type'
]
==
'integer'
or
property
[
'type'
]
==
'int'
:
return
int
(
value
)
elif
property
[
'type'
]
==
'number'
:
# check if it is a float
if
'.'
in
value
:
return
float
(
value
)
else
:
return
int
(
value
)
elif
property
[
'type'
]
==
'string'
:
return
str
(
value
)
elif
property
[
'type'
]
==
'boolean'
:
return
bool
(
value
)
elif
property
[
'type'
]
==
'null'
:
if
value
is
None
:
return
None
else
:
raise
ValueError
(
f
"Invalid type {property['type']} for property {property}"
)
elif
'anyOf'
in
property
and
isinstance
(
property
[
'anyOf'
],
list
):
return
self
.
_convert_body_property_any_of
(
property
,
value
,
property
[
'anyOf'
])
except
ValueError
as
e
:
return
value
def
_invoke
(
self
,
user_id
:
str
,
tool_parameters
:
dict
[
str
,
Any
])
->
ToolInvokeMessage
|
list
[
ToolInvokeMessage
]:
def
_invoke
(
self
,
user_id
:
str
,
tool_parameters
:
dict
[
str
,
Any
])
->
ToolInvokeMessage
|
list
[
ToolInvokeMessage
]:
"""
"""
...
...
web/app/components/tools/edit-custom-collection-modal/test-api.tsx
View file @
a769edbc
...
@@ -43,7 +43,7 @@ const TestApi: FC<Props> = ({
...
@@ -43,7 +43,7 @@ const TestApi: FC<Props> = ({
}
}
const
data
=
{
const
data
=
{
tool_name
:
toolName
,
tool_name
:
toolName
,
credentials
:
tempCredential
,
credentials
,
schema_type
:
customCollection
.
schema_type
,
schema_type
:
customCollection
.
schema_type
,
schema
:
customCollection
.
schema
,
schema
:
customCollection
.
schema
,
parameters
:
parametersValue
,
parameters
:
parametersValue
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment