Module: QuickQuestion

Defined in:
lib/quickquestion.rb

Constant Summary collapse

VERSION =
"0.2.0"
DB_PATH =
File.join(XDG::Config.new.home, "qq/log.sqlite3")

Class Method Summary collapse

Class Method Details

.calculate_cost(usage) ⇒ Object



42
43
44
45
46
# File 'lib/quickquestion.rb', line 42

def self.calculate_cost(usage)
  input_tokens = BigDecimal(usage["input_tokens"])
  output_tokens = BigDecimal(usage["output_tokens"])
  (input_tokens * 3 + output_tokens * 15) / BigDecimal("1_000_000")
end

.dbObject



21
22
23
# File 'lib/quickquestion.rb', line 21

def self.db
  @db ||= setup_db
end

.log_query(query, response, input_tokens, output_tokens, cost) ⇒ Object



48
49
50
51
52
53
54
55
56
57
# File 'lib/quickquestion.rb', line 48

def self.log_query(query, response, input_tokens, output_tokens, cost)
  db[:queries].insert(
    at: Time.now.utc,
    query: query,
    response: response,
    input_tokens: input_tokens,
    output_tokens: output_tokens,
    cost: cost
  )
end

.query(input) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/quickquestion.rb', line 25

def self.query(input)
  api_key = ENV["ANTHROPIC_API_KEY"]
  raise "ANTHROPIC_API_KEY environment variable is not set" if api_key.nil? || api_key.empty?

  claude = Claude::Client.new(api_key)
  prompt = "Give concise expert answers. Answer calmly and directly. If unsure, answer about the most common case. Never repeat questions or introduce your answer. If giving code samples, do not explain unless explicitly asked."
  messages = claude.user_message(prompt + "\n" + input)
  response = claude.messages(messages, model: Claude::Model::CLAUDE_SONNET_LATEST)
  text = claude.parse_response(response)
  usage = response["usage"]
  input_tokens = usage["input_tokens"]
  output_tokens = usage["output_tokens"]
  cost = calculate_cost(usage)
  log_query(input, text, input_tokens, output_tokens, cost)
  "#{text} (Cost: $#{cost.truncate(4).to_s("F")})"
end

.setup_dbObject



11
12
13
14
15
16
17
18
19
# File 'lib/quickquestion.rb', line 11

def self.setup_db
  FileUtils.mkdir_p(File.dirname(DB_PATH))
  @db ||= Sequel.connect("sqlite://#{DB_PATH}")

  Sequel.extension :migration
  Sequel::TimestampMigrator.run(@db, File.join(File.dirname(__FILE__), "migration"))

  @db
end