Class: Boxcars::Perplexityai

Inherits:
Engine
  • Object
show all
Defined in:
lib/boxcars/engine/perplexityai.rb

Overview

A engine that uses OpenAI’s API.

Constant Summary collapse

DEFAULT_PER_PARAMS =

The default parameters to use when asking the engine.

{
  model: "'llama-3-sonar-large-32k-online'",
  temperature: 0.1
}.freeze
DEFAULT_PER_NAME =

the default name of the engine

"PerplexityAI engine"
DEFAULT_PER_DESCRIPTION =

the default description of the engine

"useful for when you need to use AI to answer questions. " \
"You should ask targeted questions"

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Engine

#generate, #generation_info, #get_num_tokens

Constructor Details

#initialize(name: DEFAULT_PER_NAME, description: DEFAULT_PER_DESCRIPTION, prompts: [], batch_size: 20, **kwargs) ⇒ Perplexityai

A engine is a container for a single tool to run.

Parameters:

  • name (String) (defaults to: DEFAULT_PER_NAME)

    The name of the engine. Defaults to “PerplexityAI engine”.

  • description (String) (defaults to: DEFAULT_PER_DESCRIPTION)

    A description of the engine. Defaults to: useful for when you need to use AI to answer questions. You should ask targeted questions“.

  • prompts (Array<String>) (defaults to: [])

    The prompts to use when asking the engine. Defaults to [].

  • batch_size (Integer) (defaults to: 20)

    The number of prompts to send to the engine at once. Defaults to 20.



27
28
29
30
31
32
# File 'lib/boxcars/engine/perplexityai.rb', line 27

def initialize(name: DEFAULT_PER_NAME, description: DEFAULT_PER_DESCRIPTION, prompts: [], batch_size: 20, **kwargs)
  @perplexity_params = DEFAULT_PER_PARAMS.merge(kwargs)
  @prompts = prompts
  @batch_size = batch_size
  super(description: description, name: name)
end

Instance Attribute Details

#batch_sizeObject (readonly)

Returns the value of attribute batch_size.



7
8
9
# File 'lib/boxcars/engine/perplexityai.rb', line 7

def batch_size
  @batch_size
end

#model_kwargsObject (readonly)

Returns the value of attribute model_kwargs.



7
8
9
# File 'lib/boxcars/engine/perplexityai.rb', line 7

def model_kwargs
  @model_kwargs
end

#perplexity_paramsObject (readonly)

Returns the value of attribute perplexity_params.



7
8
9
# File 'lib/boxcars/engine/perplexityai.rb', line 7

def perplexity_params
  @perplexity_params
end

#promptsObject (readonly)

Returns the value of attribute prompts.



7
8
9
# File 'lib/boxcars/engine/perplexityai.rb', line 7

def prompts
  @prompts
end

Instance Method Details

#chat(parameters:) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/boxcars/engine/perplexityai.rb', line 38

def chat(parameters:)
  conn = Faraday.new(url: "https://api.perplexity.ai/chat/completions") do |faraday|
    faraday.request :json
    faraday.response :json
    faraday.response :raise_error
    # faraday.options.timeout = 180 # 3 minutes
  end

  response = conn.post do |req|
    req.headers['Authorization'] = "Bearer #{ENV.fetch('PERPLEXITY_API_KEY')}"
    req.body = {
      model: parameters[:model],
      messages: parameters[:messages]
    }
  end

  response.body
end

#check_response(response, must_haves: %w[choices])) ⇒ Object

make sure we got a valid response

Parameters:

  • response (Hash)

    The response to check.

  • must_haves (Array<String>) (defaults to: %w[choices]))

    The keys that must be in the response. Defaults to %w.

Raises:

  • (KeyError)

    if there is an issue with the access token.

  • (ValueError)

    if the response is not valid.



95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/boxcars/engine/perplexityai.rb', line 95

def check_response(response, must_haves: %w[choices])
  if response['error']
    code = response.dig('error', 'code')
    msg = response.dig('error', 'message') || 'unknown error'
    raise KeyError, "PERPLEXITY_API_KEY not valid" if code == 'invalid_api_key'

    raise ValueError, "PerplexityAI error: #{msg}"
  end

  must_haves.each do |key|
    raise ValueError, "Expecting key #{key} in response" unless response.key?(key)
  end
end

#client(prompt:, inputs: {}, **kwargs) ⇒ Object

Get an answer from the engine.

Parameters:

  • prompt (String)

    The prompt to use when asking the engine.

  • openai_access_token (String)

    The access token to use when asking the engine. Defaults to Boxcars.configuration.openai_access_token.

  • kwargs (Hash)

    Additional parameters to pass to the engine if wanted.



62
63
64
65
66
67
68
69
# File 'lib/boxcars/engine/perplexityai.rb', line 62

def client(prompt:, inputs: {}, **kwargs)
  prompt = prompt.first if prompt.is_a?(Array)
  params = prompt.as_messages(inputs).merge(default_params).merge(kwargs)
  if Boxcars.configuration.log_prompts
    Boxcars.debug(params[:messages].last(2).map { |p| ">>>>>> Role: #{p[:role]} <<<<<<\n#{p[:content]}" }.join("\n"), :cyan)
  end
  chat(parameters: params)
end

#conversation_model?(_model) ⇒ Boolean

Returns:

  • (Boolean)


34
35
36
# File 'lib/boxcars/engine/perplexityai.rb', line 34

def conversation_model?(_model)
  true
end

#default_paramsObject

Get the default parameters for the engine.



86
87
88
# File 'lib/boxcars/engine/perplexityai.rb', line 86

def default_params
  perplexity_params
end

#run(question, **kwargs) ⇒ Object

get an answer from the engine for a question.

Parameters:

  • question (String)

    The question to ask the engine.

  • kwargs (Hash)

    Additional parameters to pass to the engine if wanted.

Raises:



74
75
76
77
78
79
80
81
82
83
# File 'lib/boxcars/engine/perplexityai.rb', line 74

def run(question, **kwargs)
  prompt = Prompt.new(template: question)
  response = client(prompt: prompt, **kwargs)
  raise Error, "PerplexityAI: No response from API" unless response
  raise Error, "PerplexityAI: #{response['error']}" if response["error"]

  answer = response["choices"].map { |c| c.dig("message", "content") || c["text"] }.join("\n").strip
  puts answer
  answer
end