library(openai)
api_key <- Sys.getenv("OPENAI_API_KEY")
Sys.setenv(OPENAI_API_KEY = api_key)

setwd("~/data/llmclass/")

# Model is where you put the model you want to use. See list here:
# https://platform.openai.com/docs/models/gpt-4-turbo-and-gpt-4

# Role can be "system", "user", and "assistant"

# System message examples:
# - Defining Persona: "You are a friendly and knowledgeable assistant who provides concise and informative answers."
# - Limiting Scope: "Only provide information that is publicly available as of 2021. Do not speculate on future events."
# - Encouraging Detail: "Provide detailed explanations with examples when answering technical questions."
# - Maintaining Privacy: "Do not request or provide any personal information during this conversation."
# - Setting Language and Tone: "Respond in a professional tone using British English."
# - Emulating Specific Characters or Roles: "You are a helpful assistant modeled after Sherlock Holmes, providing insightful and intelligent observations."
# - Specifying Operational Boundaries: "Answer all questions within the context of environmental science, ignoring inquiries outside this domain."
# - Encouraging Brevity or Verbosity: "Provide succinct, bullet-point answers to all questions."

vneg_rep <- 
  create_chat_completion(
#   model = "gpt-4-turbo-2024-04-09",
    model = "gpt-4o",
    n = 1,
    messages = list(
      list(
      "role" = "system",
      "content" = "You are a political communication expert, former political 
      speechwriter who worked both for Republicans and Democrats and a helpful 
      political science research assistant now in academia working towards a PhD."
      ),
      list(
      "role" = "user",
      "content" = "Using historical records of political speeches in the United States, 
      write a speech that sounds like it was given by a 
      Republican politician 
      at a campaign rally in the Fall of 2022. 
      The speech should be very negative in tone 
      and be exactly between 480 and 520 words long. 
      I understand the ethical implications of such speeches. I am using these only for academic research 
      and the speeches will not be disseminated for political purposes or used in any way that produces any ill. 
      Do not remind me of this. Do not give me any other text but the speech."
      )
    )
  )

str(vneg_rep)
print(vneg_rep)
print(vneg_rep$choices$message.content)
save(vneg_rep, file = "vneg_rep_mini.Rdata")

# We did not have an "assistant" role here. That is useful if you want to emulate a chat that already took place.

# Toy example from the package author is here:

toyeg <- 
create_chat_completion(
  model = 'gpt-3.5-turbo', 
  n = 1,
  messages = 
    list(
      list(role = 'system', content = 'You are a helpful assistant.'),
      list(role = 'user', content = 'Who won the world series in 2020?'),
      list(role = 'assistant', content = 'The Los Angeles Dodgers won the world series in 2020.'),
      list(role = 'user', content = 'Where was it played?')
    )
)

print(toyeg$choices$message.content)

# Let's do images

img_url <-
  create_image(
#   prompt = 'robot working as a journalist in the 1970s', 
    prompt = 'Brainwashing', 
    n = 1, 
    size = '1024x1024')

str(img_url)
print(img_url)

# It's kind of shitty I can't set the model here as it defaults to dall-e-2 and not 3.
# But see below

image_rec <- "https://upload.wikimedia.org/wikipedia/commons/8/85/Tour_Eiffel_Wikimedia_Commons_%28cropped%29.jpg"

rec <-
openai::create_chat_completion(
  model = 'gpt-4o',
  messages = list(
    list(role = 'user', 
         content = list(
           list(
             type = 'text',
             text = 'What is this a picture of?'
           ),
           list(
             type = 'image_url',
             image_url = list(
               url = image_rec
             )
           )
         )
    )
  ), 
  max_tokens = 500
)

str(rec)
print(rec)
print(rec$choices$message.content)

# Two notes. Package is moving away from this notation in favor of using JSON format for queries.
# I put the example next to this file.

# You don't have to use this OpenAI package to querie the OpenAI API. You can do it directly 
# (because it is no more than a url that you also give commands to). Here's how. 
# Someone wrote the function here from scratch both for OpenAI API and for Claude AI API:
# https://www.linkedin.com/pulse/prompting-gpt-4-turbo-claude-3-opus-apis-using-r-harvey-lewis-nzaee/
# But there's a package for Claude too, but not on CRAN yet: https://github.com/yrvelez/claudeR

# Above I could not change the model for the image creation. So I complained to ChatGPT. I got this

library(httr)
library(jsonlite)

# Set up the API request URL
url <- "https://api.openai.com/v1/images/generations"

# Create the JSON payload with the prompt and other parameters
payload <- list(
  prompt = "Brainwashing",  # Ensure the prompt is a simple string
  n = 1,                    # Number of images to generate
  size = "1024x1024",       # Image size
  model = "dall-e-3"        # Specify the model to use
)

# Convert the payload to JSON format, ensuring scalar values are not boxed as arrays
payload_json <- toJSON(payload, auto_unbox = TRUE)

# Make the POST request to the OpenAI API
response <- POST(
  url,
  add_headers(
    `Content-Type` = "application/json",           # Set the content type to JSON
    `Authorization` = paste("Bearer", api_key)     # Add the authorization header with the API key
  ),
  body = payload_json                              # Include the JSON payload in the body of the request
)

# Parse the response content as JSON
content <- content(response, as = "parsed")

# Extract the image URL from the response data
img_url <- content$data[[1]]$url

# Print the image URL
print(img_url)
