open_ai_bot 0.3.2 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e31ed7bc34cf94ba2d339a1efa6b57a0d9fd972aec39961a98253cb5b9dcc4df
4
- data.tar.gz: 2f92b54b9788efacd9bf50b66004c777a8eeb3bd934ffc65a2ea93a4a12c39e6
3
+ metadata.gz: 70a3fabb10c860e1d7c45e83c74b38f7b393d4a1d31c86a73ccc4f827af6dcd8
4
+ data.tar.gz: 91436b52ead57fb638b4de1d74f573041fd541bae1352315632ae4414853fb28
5
5
  SHA512:
6
- metadata.gz: 38ff4646a9493b2771d62cce25d8a2ff0ab589bc2d300041fec4536e6e75065e33c79fe452994dd5d9a628be6646e4ed97bb97a7c28503811b3a3db1b8fefa9f
7
- data.tar.gz: 872adfdeb95db9ccbdd8073ee736136a40d4517b1b4eddee9ddf5885638dfe286c705554dd708c654dd1e9b83c62682626fd63cf3d2e878fea536a4d79c08d67
6
+ metadata.gz: '0908d995df133104dd4a591e7a9cff2c561f39753fc0570ac15eb3d9808ab644f7c04afef5682580c020bfca9d2e05e70573a4258427e9737bb18c2ef120ba60'
7
+ data.tar.gz: 6b54406776b00460dea2f1451313558b60bdb8fddb5dd843ec6ed64e6052a42affeae69bfe166be25ad7d641dd9d71980b25adaf0bb620462ce4b0e73d63d806
data/Gemfile CHANGED
@@ -4,4 +4,4 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "down", "~> 5.4"
6
6
  gem "rubydium", ">= 0.2.5"
7
- gem "ruby-openai", "~> 5.1"
7
+ gem "ruby-openai", "~> 8.1"
data/Gemfile.lock CHANGED
@@ -35,26 +35,29 @@ GEM
35
35
  dry-inflector (~> 1.0)
36
36
  dry-logic (~> 1.4)
37
37
  zeitwerk (~> 2.6)
38
- event_stream_parser (0.3.0)
39
- faraday (2.9.1)
40
- faraday-net_http (>= 2.0, < 3.2)
41
- faraday-multipart (1.0.4)
42
- multipart-post (~> 2)
43
- faraday-net_http (3.1.0)
44
- net-http
38
+ event_stream_parser (1.0.0)
39
+ faraday (2.13.1)
40
+ faraday-net_http (>= 2.0, < 3.5)
41
+ json
42
+ logger
43
+ faraday-multipart (1.1.0)
44
+ multipart-post (~> 2.0)
45
+ faraday-net_http (3.4.1)
46
+ net-http (>= 0.5.0)
45
47
  fiber-annotation (0.2.0)
46
48
  fiber-local (1.1.0)
47
49
  fiber-storage
48
50
  fiber-storage (0.1.1)
49
51
  ice_nine (0.11.2)
50
52
  io-event (1.6.0)
51
- json (2.7.2)
53
+ json (2.12.2)
54
+ logger (1.7.0)
52
55
  multipart-post (2.4.1)
53
- net-http (0.4.1)
56
+ net-http (0.6.0)
54
57
  uri
55
58
  public_suffix (5.0.5)
56
- ruby-openai (5.2.0)
57
- event_stream_parser (>= 0.3.0, < 1.0.0)
59
+ ruby-openai (8.1.0)
60
+ event_stream_parser (>= 0.3.0, < 2.0.0)
58
61
  faraday (>= 1)
59
62
  faraday-multipart (>= 1)
60
63
  rubydium (0.4.1)
@@ -65,7 +68,7 @@ GEM
65
68
  faraday (~> 2.0)
66
69
  faraday-multipart (~> 1.0)
67
70
  zeitwerk (~> 2.6)
68
- uri (0.13.0)
71
+ uri (1.0.3)
69
72
  zeitwerk (2.6.15)
70
73
 
71
74
  PLATFORMS
@@ -74,7 +77,7 @@ PLATFORMS
74
77
 
75
78
  DEPENDENCIES
76
79
  down (~> 5.4)
77
- ruby-openai (~> 5.1)
80
+ ruby-openai (~> 8.1)
78
81
  rubydium (>= 0.2.5)
79
82
 
80
83
  BUNDLED WITH
@@ -145,9 +145,11 @@ module OpenAI
145
145
  def get_tokens_info!(response)
146
146
  completion_tokens = response.dig("usage", "completion_tokens")
147
147
  prompt_tokens = response.dig("usage", "prompt_tokens")
148
- vision_tokens = current_thread.claim_vision_tokens!
148
+ cached_prompt_tokens = response.dig("usage", "prompt_tokens_details", "cached_tokens")
149
149
 
150
- result = current_thread.model.request_cost(completion_tokens:, prompt_tokens:, vision_tokens:, current_thread:)
150
+ current_thread.model.request_cost(
151
+ completion_tokens:, prompt_tokens:, cached_prompt_tokens:, current_thread:
152
+ )
151
153
  end
152
154
 
153
155
  def send_chat_gpt_response(text, tokens_info)
@@ -5,6 +5,7 @@ module OpenAI
5
5
  def initialize(defaults = [], model)
6
6
  @history ||= defaults
7
7
  @model = model.is_a?(Model) ? model : Model.new(model)
8
+ puts "Using #{@model}"
8
9
  puts @history
9
10
  end
10
11
 
@@ -24,10 +25,6 @@ module OpenAI
24
25
  @history.map(&:cost).compact.sum
25
26
  end
26
27
 
27
- def claim_vision_tokens!
28
- @history.reject(&:vision_tokens_claimed?).map(&:claim_vision_tokens!).compact.sum
29
- end
30
-
31
28
  def add(message)
32
29
  return false unless message&.valid?
33
30
  return false if @history.any? { message.id == _1.id}
@@ -10,17 +10,6 @@ module OpenAI
10
10
  kwargs.each_pair { public_send("#{_1}=", _2) }
11
11
  @role = :user
12
12
  @timestamp = Time.now.to_i
13
- @vision_tokens_claimed = !image
14
- end
15
-
16
- def vision_tokens_claimed?
17
- @vision_tokens_claimed
18
- end
19
-
20
- def claim_vision_tokens!
21
- # binding.pry
22
- @vision_tokens_claimed = true
23
- image&.tokens
24
13
  end
25
14
 
26
15
  def valid?
data/lib/open_ai/model.rb CHANGED
@@ -1,24 +1,59 @@
1
1
  module OpenAI
2
2
  class Model
3
- # All prices are per 1K tokens
3
+ # All prices are in USD per 1M tokens
4
4
  MODEL_INFO = {
5
+ "gpt-4.1": {
6
+ max_context: 1_047_576,
7
+ input_price: 2.00,
8
+ cached_input_price: 0.50,
9
+ output_price: 8.00,
10
+ vision: true
11
+ },
12
+ "gpt-4.1-mini": {
13
+ max_context: 1_047_576,
14
+ input_price: 0.40,
15
+ cached_input_price: 0.10,
16
+ output_price: 1.60,
17
+ vision: true
18
+ },
19
+ "gpt-4.1-nano": {
20
+ max_context: 1_047_576,
21
+ input_price: 0.10,
22
+ cached_input_price: 0.025,
23
+ output_price: 0.40,
24
+ vision: true
25
+ },
5
26
  "gpt-4o": {
6
27
  max_context: 128_000,
7
- prompt_price: 0.005,
8
- completion_price: 0.015,
9
- vision_price: 0.005
28
+ input_price: 5.00,
29
+ cached_input_price: 2.50,
30
+ output_price: 20.00,
31
+ vision: true
10
32
  },
11
- "gpt-3.5-turbo": {
12
- max_context: 16385,
13
- prompt_price: 0.0005,
14
- completion_price: 0.0015,
15
- vision_price: 0
33
+ "gpt-4o-mini": {
34
+ max_context: 128_000,
35
+ input_price: 0.60,
36
+ cached_input_price: 0.30,
37
+ output_price: 2.40,
38
+ vision: true
39
+ },
40
+ "o3": {
41
+ max_context: 200_000,
42
+ input_price: 2.00,
43
+ cached_input_price: 0.50,
44
+ output_price: 8.00,
45
+ vision: true
46
+ },
47
+ "o4-mini": {
48
+ max_context: 200_000,
49
+ input_price: 1.10,
50
+ cached_input_price: 0.275,
51
+ output_price: 4.40,
52
+ vision: true
16
53
  }
17
54
  }
18
55
 
19
- attr_accessor :max_context, :prompt_price, :completion_price, :vision_price
20
-
21
- [:max_context, :prompt_price, :completion_price, :vision_price].each do |attr|
56
+ [:max_context, :input_price, :cached_input_price, :output_price].each do |attr|
22
57
  define_method(attr) do
23
58
  MODEL_INFO[@model][attr]
24
59
  end
@@ -37,21 +72,21 @@ module OpenAI
37
72
  end
38
73
 
39
74
  def has_vision?
40
- MODEL_INFO[@model][:vision_price].positive?
75
+ MODEL_INFO[@model][:vision]
41
76
  end
42
77
 
43
- def request_cost(prompt_tokens:, completion_tokens:, vision_tokens:, current_thread:)
44
- prompt_cost = prompt_tokens * prompt_price / 1000
45
- completion_cost = completion_tokens * completion_price / 1000
46
- vision_cost = vision_tokens * vision_price / 1000
78
+ def request_cost(prompt_tokens:, cached_prompt_tokens:, completion_tokens:, current_thread:)
79
+ prompt_cost = prompt_tokens * input_price / 1_000_000
80
+ cached_prompt_cost = cached_prompt_tokens * cached_input_price / 1_000_000
81
+ completion_cost = completion_tokens * output_price / 1_000_000
47
82
 
48
- total = prompt_cost + completion_cost + vision_cost
83
+ total = prompt_cost + cached_prompt_cost + completion_cost
49
84
  thread_total = current_thread.total_cost
50
85
 
51
86
  info = "\n\n" + {
52
- prompt: "#{prompt_tokens} tokens (#{prompt_cost.round(5)}$)",
87
+ cached_prompt: "#{cached_prompt_tokens} tokens (#{cached_prompt_cost.round(5)}$)",
88
+ uncached_prompt: "#{prompt_tokens} tokens (#{prompt_cost.round(5)}$)",
53
89
  completion: "#{completion_tokens} tokens (#{completion_cost.round(5)}$)",
54
- vision: "#{vision_tokens} tokens (#{vision_cost.round(5)}$)",
55
90
  total: "#{total.round(5)}$",
56
91
  total_for_this_conversation: "#{(thread_total + total).round(5)}$",
57
92
  max_context: max_context
@@ -62,4 +97,4 @@ module OpenAI
62
97
  { info:, total: }
63
98
  end
64
99
  end
65
- end
100
+ end
data/lib/open_ai_bot.rb CHANGED
@@ -27,6 +27,14 @@ class OpenAIBot < Rubydium::Bot
27
27
  on_command "/help", description: "Sends useful help info" do
28
28
  reply(self.class.help_message)
29
29
  end
30
+ on_command "/d" do
31
+ return unless @user.username == config.owner_username
32
+ return unless @target&.id.in? [config.bot_id, @user.id]
33
+
34
+ current_thread.delete(@replies_to.message_id)
35
+ safe_delete(@replies_to)
36
+ safe_delete(@msg)
37
+ end
30
38
 
31
39
  def allowed_chat?
32
40
  return true if @user.username == config.owner_username
data/main.rb CHANGED
@@ -24,7 +24,7 @@ bot = bots[bot_name]
24
24
  bot.config = YAML.load_file("#{__dir__}/config.yaml")
25
25
  bot.configure do |config|
26
26
  config.open_ai_client = OpenAI::Client.new(
27
- access_token: config.open_ai_token
27
+ access_token: config.open_ai['token']
28
28
  # organization_id: config.open_ai_organization_id
29
29
  )
30
30
  end
data/open_ai_bot.gemspec CHANGED
@@ -8,7 +8,7 @@ require_relative "lib/ext/in"
8
8
 
9
9
  Gem::Specification.new do |spec|
10
10
  spec.name = "open_ai_bot"
11
- spec.version = "0.3.2"
11
+ spec.version = "0.3.4"
12
12
  spec.authors = ["bulgakke"]
13
13
  spec.email = ["vvp835@yandex.ru"]
14
14
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: open_ai_bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - bulgakke
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-06-08 00:00:00.000000000 Z
11
+ date: 2025-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: down