Source code for camel.schemas.openai_converter

# ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========

import os
from typing import Any, Callable, Dict, Optional, Type, Union

from pydantic import BaseModel

from camel.models import ModelFactory
from camel.types import ModelType
from camel.types.enums import ModelPlatformType
from camel.utils import (
    api_keys_required,
    get_pydantic_model,
)

from .base import BaseConverter

DEFAULT_CONVERTER_PROMPTS = """
    Extract key entities and attributes from the user 
    provided text, and convert them into a structured JSON format.
"""


[docs] class OpenAISchemaConverter(BaseConverter): r"""OpenAISchemaConverter is a class that converts a string or a function into a BaseModel schema. Args: model_type (ModelType, optional): The model type to be used. (default: ModelType.GPT_4O_MINI) model_config_dict (Optional[Dict[str, Any]], optional): A dictionary that will be fed into:obj:`openai.ChatCompletion.create()`. If :obj:`None`, :obj:`ChatGPTConfig().as_dict()` will be used. (default: :obj:`None`) api_key (Optional[str], optional): The API key for authenticating with the OpenAI service. (default: :obj:`None`) output_schema (Optional[Type[BaseModel]], optional): The expected format of the response. (default: :obj:`None`) prompt (Optional[str], optional): The prompt to be used. (default: :obj:`None`) """ @api_keys_required( [ ("api_key", "OPENAI_API_KEY"), ] ) def __init__( self, model_type: ModelType = ModelType.GPT_4O_MINI, model_config_dict: Optional[Dict[str, Any]] = None, api_key: Optional[str] = None, ): self.model_type = model_type self.model_config_dict = model_config_dict or {} api_key = api_key or os.environ.get("OPENAI_API_KEY") self._client = ModelFactory.create( # type: ignore[attr-defined] ModelPlatformType.OPENAI, model_type, api_key=api_key, )._client super().__init__()
[docs] def convert( # type: ignore[override] self, content: str, output_schema: Union[Type[BaseModel], str, Callable], prompt: Optional[str] = DEFAULT_CONVERTER_PROMPTS, ) -> BaseModel: r"""Formats the input content into the expected BaseModel Args: content (str): The content to be formatted. output_schema (Union[Type[BaseModel], str, Callable]): The expected format of the response. Returns: BaseModel: The formatted response. """ prompt = prompt or DEFAULT_CONVERTER_PROMPTS if output_schema is None: raise ValueError("Expected an output schema, got None.") if not isinstance(output_schema, type): output_schema = get_pydantic_model(output_schema) elif not issubclass(output_schema, BaseModel): raise ValueError( f"Expected a BaseModel, got {type(output_schema)}" ) self.model_config_dict["response_format"] = output_schema response = self._client.beta.chat.completions.parse( messages=[ {'role': 'system', 'content': prompt}, {'role': 'user', 'content': content}, ], model=self.model_type, **self.model_config_dict, ) message = response.choices[0].message if not isinstance(message.parsed, output_schema): raise ValueError( f"Expected a {output_schema}, got {type(message.parsed)}." ) return message.parsed