H-AdminSim_Arena / utils /client.py
ljm565's picture
feat: Updated rating criteria
3703b6a
import os
from openai import OpenAI
from dotenv import load_dotenv
from typing import List, Optional
from utils import log
class GPTClient:
def __init__(self, model: str, api_key: Optional[str] = None):
# Initialize
self.model = model
self._init_environment(api_key)
self.histories = list()
self.token_usages = dict()
self.__first_turn = True
def _init_environment(self, api_key: Optional[str] = None) -> None:
"""
Initialize OpenAI client.
Args:
api_key (Optional[str]): API key for OpenAI. If not provided, it will
be loaded from environment variables.
"""
if not api_key:
load_dotenv(override=True)
api_key = os.environ.get("OPENAI_API_KEY", None)
self.client = OpenAI(api_key=api_key)
def reset_history(self, verbose: bool = True) -> None:
"""
Reset the conversation history.
Args:
verbose (bool): Whether to print verbose output. Defaults to True.
"""
self.__first_turn = True
self.histories = list()
self.token_usages = dict()
if verbose:
log('Conversation history has been reset.', color=True)
def __make_payload(self, user_prompt: str) -> List[dict]:
"""
Create a payload for API calls to the GPT model.
Args:
user_prompt (str): User prompt.
Returns:
List[dict]: Payload including prompts and image data.
"""
payloads = list()
user_contents = {"role": "user", "content": []}
# User prompts
user_contents["content"].append(
{"type": "text", "text": user_prompt}
)
payloads.append(user_contents)
return payloads
def __call__(self,
user_prompt: str,
system_prompt: Optional[str] = None,
using_multi_turn: bool = True,
greeting: Optional[str] = None,
verbose: bool = True,
**kwargs) -> str:
"""
Sends a chat completion request to the model with optional image input and system prompt.
Args:
user_prompt (str): The main user prompt or query to send to the model.
system_prompt (Optional[str], optional): An optional system-level prompt to set context or behavior. Defaults to None.
using_multi_turn (bool): Whether to structure it as multi-turn. Defaults to True.
greeting (Optional[str]): An optional greeting message to include in the conversation. Defaults to None.
verbose (bool): Whether to print verbose output. Defaults to True.
Raises:
e: Any exception raised during the API call is re-raised.
Returns:
str: The model's response message.
"""
try:
# To ensure empty history
if not using_multi_turn:
self.reset_history(verbose)
if self.__first_turn:
# System prompt
if system_prompt:
self.histories.append({"role": "system", "content": [{"type": "text", "text": system_prompt}]})
# Greeting
if greeting and self.__first_turn:
self.histories.append({"role": "assistant", "content": [{"type": "text", "text": greeting}]})
self.__first_turn = False
# User prompt
self.histories += self.__make_payload(user_prompt)
# Model response
response = self.client.chat.completions.create(
model=self.model,
messages=self.histories,
**kwargs
)
assistant_msg = response.choices[0].message
self.histories.append({"role": assistant_msg.role, "content": [{"type": "text", "text": assistant_msg.content}]})
# Logging token usage
if response.usage:
self.token_usages.setdefault("prompt_tokens", []).append(response.usage.prompt_tokens)
self.token_usages.setdefault("completion_tokens", []).append(response.usage.completion_tokens)
self.token_usages.setdefault("total_tokens", []).append(response.usage.total_tokens)
self.token_usages.setdefault("reasoning_tokens", []).append(response.usage.completion_tokens_details.reasoning_tokens)
return assistant_msg.content
except Exception as e:
raise e