This commit is contained in:
@@ -105,6 +105,29 @@ class ApiBasedToolSchemaParser:
|
|||||||
# overwrite the content
|
# overwrite the content
|
||||||
interface["operation"]["requestBody"]["content"][content_type]["schema"] = root
|
interface["operation"]["requestBody"]["content"][content_type]["schema"] = root
|
||||||
|
|
||||||
|
# handle allOf reference in schema properties
|
||||||
|
for prop_dict in root.get("properties", {}).values():
|
||||||
|
for item in prop_dict.get("allOf", []):
|
||||||
|
if "$ref" in item:
|
||||||
|
ref_schema = openapi
|
||||||
|
reference = item["$ref"].split("/")[1:]
|
||||||
|
for ref in reference:
|
||||||
|
ref_schema = ref_schema[ref]
|
||||||
|
else:
|
||||||
|
ref_schema = item
|
||||||
|
for key, value in ref_schema.items():
|
||||||
|
if isinstance(value, list):
|
||||||
|
if key not in prop_dict:
|
||||||
|
prop_dict[key] = []
|
||||||
|
# extends list field
|
||||||
|
if isinstance(prop_dict[key], list):
|
||||||
|
prop_dict[key].extend(value)
|
||||||
|
elif key not in prop_dict:
|
||||||
|
# add new field
|
||||||
|
prop_dict[key] = value
|
||||||
|
if "allOf" in prop_dict:
|
||||||
|
del prop_dict["allOf"]
|
||||||
|
|
||||||
# parse body parameters
|
# parse body parameters
|
||||||
if "schema" in interface["operation"]["requestBody"]["content"][content_type]:
|
if "schema" in interface["operation"]["requestBody"]["content"][content_type]:
|
||||||
body_schema = interface["operation"]["requestBody"]["content"][content_type]["schema"]
|
body_schema = interface["operation"]["requestBody"]["content"][content_type]["schema"]
|
||||||
|
@@ -54,3 +54,58 @@ def test_parse_openapi_to_tool_bundle_operation_id(app):
|
|||||||
assert tool_bundles[0].operation_id == "<root>_get"
|
assert tool_bundles[0].operation_id == "<root>_get"
|
||||||
assert tool_bundles[1].operation_id == "apiresources_get"
|
assert tool_bundles[1].operation_id == "apiresources_get"
|
||||||
assert tool_bundles[2].operation_id == "createResource"
|
assert tool_bundles[2].operation_id == "createResource"
|
||||||
|
|
||||||
|
|
||||||
|
def test_parse_openapi_to_tool_bundle_properties_all_of(app):
|
||||||
|
openapi = {
|
||||||
|
"openapi": "3.0.0",
|
||||||
|
"info": {"title": "Simple API", "version": "1.0.0"},
|
||||||
|
"servers": [{"url": "http://localhost:3000"}],
|
||||||
|
"paths": {
|
||||||
|
"/api/resource": {
|
||||||
|
"get": {
|
||||||
|
"requestBody": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Request",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"required": True,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"Request": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"prop1": {
|
||||||
|
"enum": ["option1"],
|
||||||
|
"description": "desc prop1",
|
||||||
|
"allOf": [
|
||||||
|
{"$ref": "#/components/schemas/AllOfItem"},
|
||||||
|
{
|
||||||
|
"enum": ["option2"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"AllOfItem": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["option3"],
|
||||||
|
"description": "desc allOf item",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
with app.test_request_context():
|
||||||
|
tool_bundles = ApiBasedToolSchemaParser.parse_openapi_to_tool_bundle(openapi)
|
||||||
|
|
||||||
|
assert tool_bundles[0].parameters[0].type == "string"
|
||||||
|
assert tool_bundles[0].parameters[0].llm_description == "desc prop1"
|
||||||
|
# TODO: support enum in OpenAPI
|
||||||
|
# assert set(tool_bundles[0].parameters[0].options) == {"option1", "option2", "option3"}
|
||||||
|
Reference in New Issue
Block a user