# frozen_string_literal: true require 'json' require 'rest-client' module Cryptum # This plugin is used for interacting w/ OpenAI's REST API # This is based on the following OpenAI API Specification: # https://api.openai.com/v1 module OpenAI # Supported Method Parameters:: # open_ai_rest_call( # env: 'required - env object containing OpenAI Bearer token', # option_choice = 'required - option_choice object in case proxy is configured', # http_method: 'optional HTTP method (defaults to GET) # rest_call: 'required rest call to make per the schema', # params: 'optional params passed in the URI or HTTP Headers', # http_body: 'optional HTTP body sent in HTTP methods that support it e.g. POST' # ) private_class_method def self.open_ai_rest_call(opts = {}) env = opts[:env] option_choice = opts[:option_choice] http_method = if opts[:http_method].nil? :GET else opts[:http_method].to_s.upcase.scrub.strip.chomp.to_sym end rest_call = opts[:rest_call].to_s.scrub params = opts[:params] http_body = opts[:http_body].to_s.scrub base_open_ai_api_uri = 'https://api.openai.com/v1' bearer_token = env[:open_ai_bearer_token] if option_choice.proxy rest_client = RestClient rest_client.proxy = option_choice.proxy rest_client_request = rest_client::Request else rest_client_request = RestClient::Request end case http_method when :GET response = rest_client_request.execute( method: :GET, url: "#{base_open_ai_api_uri}/#{rest_call}", headers: { content_type: 'application/json; charset=UTF-8', authorization: "Bearer #{bearer_token}", params: params }, verify_ssl: false ) when :POST response = rest_client_request.execute( method: :POST, url: "#{base_open_ai_api_uri}/#{rest_call}", headers: { content_type: 'application/json; charset=UTF-8', authorization: "Bearer #{bearer_token}" }, payload: http_body, verify_ssl: false ) else raise @@logger.error("Unsupported HTTP Method #{http_method} for #{self} Plugin") end response rescue RestClient::ExceptionWithResponse => e File.open('/tmp/cryptum-errors.txt', 'a') do |f| f.puts Time.now.strftime('%Y-%m-%d %H:%M:%S.%N %z') f.puts "Module: #{self}" f.puts "URL: #{api_endpoint}#{api_call}" f.puts "PARAMS: #{params.inspect}" f.puts "HTTP POST BODY: #{http_body.inspect}" if http_body != '' f.puts "#{e}\n#{e.response}\n\n\n" end rescue StandardError => e raise e end # Supported Method Parameters:: # models = PWN::Plugins::OpenAI.get_models( # env: 'required - env object containing OpenAI Bearer token', # option_choice = 'required - option_choice object in case proxy is configured', # ) public_class_method def self.get_models(opts = {}) env = opts[:env] option_choice = opts[:option_choice] response = open_ai_rest_call( env: env, option_choice: option_choice, http_method: :post, rest_call: 'models' ) JSON.parse(response, symbolize_names: true) rescue StandardError => e raise e end # Supported Method Parameters:: # response = PWN::Plugins::OpenAI.chat_gpt( # env: 'required - env object containing OpenAI Bearer token', # option_choice = 'required - option_choice object in case proxy is configured', # request: 'required - message to ChatGPT' # ) public_class_method def self.chat_gpt(opts = {}) env = opts[:env] option_choice = opts[:option_choice] request = opts[:request] http_body = { model: 'text-davinci-003', prompt: request, temperature: 0, max_tokens: 1024 } response = open_ai_rest_call( env: env, option_choice: option_choice, http_method: :post, rest_call: 'completions', http_body: http_body.to_json ) JSON.parse(response, symbolize_names: true) rescue StandardError => e raise e end # Display Usage for this Module public_class_method def self.help puts "USAGE: models = PWN::Plugins::OpenAI.get_models( env: 'required - env object containing OpenAI Bearer token', option_choice = 'required - option_choice object in case proxy is configured', ) response = #{self}.chat_gpt( env: 'required - env object containing OpenAI Bearer token', option_choice = 'required - option_choice object in case proxy is configured', request: 'required - message to ChatGPT' ) " end end end