|
|
|
@@ -1,4 +1,6 @@ |
|
|
|
|
|
|
|
import re |
|
|
|
import uuid |
|
|
|
from json import loads as json_loads |
|
|
|
|
|
|
|
from requests import get |
|
|
|
@@ -46,7 +48,7 @@ class ApiBasedToolSchemaParser: |
|
|
|
parameters = [] |
|
|
|
if 'parameters' in interface['operation']: |
|
|
|
for parameter in interface['operation']['parameters']: |
|
|
|
parameters.append(ToolParameter( |
|
|
|
tool_parameter = ToolParameter( |
|
|
|
name=parameter['name'], |
|
|
|
label=I18nObject( |
|
|
|
en_US=parameter['name'], |
|
|
|
@@ -61,7 +63,14 @@ class ApiBasedToolSchemaParser: |
|
|
|
form=ToolParameter.ToolParameterForm.LLM, |
|
|
|
llm_description=parameter.get('description'), |
|
|
|
default=parameter['schema']['default'] if 'schema' in parameter and 'default' in parameter['schema'] else None, |
|
|
|
)) |
|
|
|
) |
|
|
|
|
|
|
|
# check if there is a type |
|
|
|
typ = ApiBasedToolSchemaParser._get_tool_parameter_type(parameter) |
|
|
|
if typ: |
|
|
|
tool_parameter.type = typ |
|
|
|
|
|
|
|
parameters.append(tool_parameter) |
|
|
|
# create tool bundle |
|
|
|
# check if there is a request body |
|
|
|
if 'requestBody' in interface['operation']: |
|
|
|
@@ -80,13 +89,14 @@ class ApiBasedToolSchemaParser: |
|
|
|
root = root[ref] |
|
|
|
# overwrite the content |
|
|
|
interface['operation']['requestBody']['content'][content_type]['schema'] = root |
|
|
|
|
|
|
|
# parse body parameters |
|
|
|
if 'schema' in interface['operation']['requestBody']['content'][content_type]: |
|
|
|
body_schema = interface['operation']['requestBody']['content'][content_type]['schema'] |
|
|
|
required = body_schema['required'] if 'required' in body_schema else [] |
|
|
|
properties = body_schema['properties'] if 'properties' in body_schema else {} |
|
|
|
for name, property in properties.items(): |
|
|
|
parameters.append(ToolParameter( |
|
|
|
tool = ToolParameter( |
|
|
|
name=name, |
|
|
|
label=I18nObject( |
|
|
|
en_US=name, |
|
|
|
@@ -101,7 +111,14 @@ class ApiBasedToolSchemaParser: |
|
|
|
form=ToolParameter.ToolParameterForm.LLM, |
|
|
|
llm_description=property['description'] if 'description' in property else '', |
|
|
|
default=property['default'] if 'default' in property else None, |
|
|
|
)) |
|
|
|
) |
|
|
|
|
|
|
|
# check if there is a type |
|
|
|
typ = ApiBasedToolSchemaParser._get_tool_parameter_type(property) |
|
|
|
if typ: |
|
|
|
tool.type = typ |
|
|
|
|
|
|
|
parameters.append(tool) |
|
|
|
|
|
|
|
# check if parameters is duplicated |
|
|
|
parameters_count = {} |
|
|
|
@@ -119,7 +136,11 @@ class ApiBasedToolSchemaParser: |
|
|
|
path = interface['path'] |
|
|
|
if interface['path'].startswith('/'): |
|
|
|
path = interface['path'][1:] |
|
|
|
path = path.replace('/', '_') |
|
|
|
# remove special characters like / to ensure the operation id is valid ^[a-zA-Z0-9_-]{1,64}$ |
|
|
|
path = re.sub(r'[^a-zA-Z0-9_-]', '', path) |
|
|
|
if not path: |
|
|
|
path = str(uuid.uuid4()) |
|
|
|
|
|
|
|
interface['operation']['operationId'] = f'{path}_{interface["method"]}' |
|
|
|
|
|
|
|
bundles.append(ApiBasedToolBundle( |
|
|
|
@@ -134,7 +155,23 @@ class ApiBasedToolSchemaParser: |
|
|
|
)) |
|
|
|
|
|
|
|
return bundles |
|
|
|
|
|
|
|
@staticmethod |
|
|
|
def _get_tool_parameter_type(parameter: dict) -> ToolParameter.ToolParameterType: |
|
|
|
parameter = parameter or {} |
|
|
|
typ = None |
|
|
|
if 'type' in parameter: |
|
|
|
typ = parameter['type'] |
|
|
|
elif 'schema' in parameter and 'type' in parameter['schema']: |
|
|
|
typ = parameter['schema']['type'] |
|
|
|
|
|
|
|
if typ == 'integer' or typ == 'number': |
|
|
|
return ToolParameter.ToolParameterType.NUMBER |
|
|
|
elif typ == 'boolean': |
|
|
|
return ToolParameter.ToolParameterType.BOOLEAN |
|
|
|
elif typ == 'string': |
|
|
|
return ToolParameter.ToolParameterType.STRING |
|
|
|
|
|
|
|
@staticmethod |
|
|
|
def parse_openapi_yaml_to_tool_bundle(yaml: str, extra_info: dict = None, warning: dict = None) -> list[ApiBasedToolBundle]: |
|
|
|
""" |