aidial_assistant/open_api/operation_selector.py (31 lines of code) (raw):

import json from typing import Union from urllib.parse import urljoin from langchain.tools import APIOperation, OpenAPISpec from pydantic import BaseModel class OpenAPICommand(BaseModel): command: str args: dict class OpenAPIClarification(BaseModel): user_question: str OpenAPIResponse = Union[OpenAPICommand, OpenAPIClarification] class OpenAPIResponseWrapper(BaseModel): """Just a wrapper class for the union to ease parsing""" resp: OpenAPIResponse @staticmethod def parse_str(s) -> OpenAPIResponse: return OpenAPIResponseWrapper.parse_obj({"resp": json.loads(s)}).resp OpenAPIOperations = dict[str, APIOperation] def collect_operations(spec: OpenAPISpec, spec_url: str) -> OpenAPIOperations: operations: dict[str, APIOperation] = {} def add_operation(spec, path, method): operation = APIOperation.from_openapi_spec(spec, path, method) # type: ignore operation.base_url = urljoin(spec_url, operation.base_url) operations[operation.operation_id] = operation if spec.paths is None: # type: ignore return operations for path, path_item in spec.paths.items(): # type: ignore if path_item.get is not None: add_operation(spec, path, "get") if path_item.post is not None: add_operation(spec, path, "post") return operations