chatgpt_assistant 0.1.3 → 0.1.5

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.
@@ -25,5 +25,14 @@ module ChatgptAssistant
25
25
  def discord_voice_bot_connected?
26
26
  user && evnt.user.voice_channel && evnt.voice && !chat.nil?
27
27
  end
28
+
29
+ def discord_next_action?
30
+ return true if evnt.channel.type != 1
31
+
32
+ %w[login register start help new_chat sl_chat ask list hist connect disconnect speak].each do |action|
33
+ return true if evnt.message.content.include?("#{discord_prefix}#{action}")
34
+ end
35
+ false
36
+ end
28
37
  end
29
38
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "helpers/telegram_helper"
4
+ require_relative "helpers/telegram_voice_helper"
4
5
 
5
6
  module ChatgptAssistant
6
7
  # This class is responsible for the telegram bot features
@@ -24,6 +25,7 @@ module ChatgptAssistant
24
25
  private
25
26
 
26
27
  include TelegramHelper
28
+ include TelegramVoiceHelper
27
29
 
28
30
  attr_accessor :msg, :visitor, :chat, :chat_id
29
31
 
@@ -47,14 +49,10 @@ module ChatgptAssistant
47
49
  end
48
50
 
49
51
  def start_event
50
- register_visitor_action("start", visitor.id) unless visitor.tel_user
51
- register_user_action("start", visitor.tel_user.id) if visitor.tel_user
52
52
  telegram_send_start_message
53
53
  end
54
54
 
55
55
  def help_event
56
- register_visitor_action("help", visitor.id) unless visitor.tel_user
57
- register_user_action("help", visitor.tel_user.id) if visitor.tel_user
58
56
  help_messages.each { |m| send_message m, msg.chat.id }
59
57
  end
60
58
 
@@ -63,7 +61,6 @@ module ChatgptAssistant
63
61
  return no_chat_selected_message unless user.current_chat
64
62
  return no_messages_founded_message if user.current_chat.messages.count.zero?
65
63
 
66
- register_user_action("hist", user.id)
67
64
  telegram_user_history.each do |m|
68
65
  send_message m, msg.chat.id
69
66
  end
@@ -72,7 +69,6 @@ module ChatgptAssistant
72
69
  def list_event
73
70
  return unless valid_for_list_action?
74
71
 
75
- register_user_action("list", user.id)
76
72
  send_message commom_messages[:chat_list], msg.chat.id
77
73
  chats_str = ""
78
74
  user.chats.each_with_index { |c, i| chats_str += "Chat #{i + 1} - #{c.title}\n" }
@@ -90,7 +86,6 @@ module ChatgptAssistant
90
86
  end
91
87
 
92
88
  def login_event
93
- register_visitor_action("login", visitor.id) unless visitor.tel_user
94
89
  user_info = msg.text.split("/").last
95
90
  email, password = user_info.split(":")
96
91
  case telegram_user_auth(email, password, msg.chat.id)
@@ -104,7 +99,6 @@ module ChatgptAssistant
104
99
  end
105
100
 
106
101
  def register_event
107
- register_visitor_action("register", visitor.id)
108
102
  user_info = msg.text.split("/").last
109
103
  email, password = user_info.split(":")
110
104
  registered_email = telegram_user_create visitor.id, email, password
@@ -114,14 +108,12 @@ module ChatgptAssistant
114
108
  def new_chat_event
115
109
  return not_logged_in_message unless user
116
110
 
117
- register_user_action("new_chat", user.id)
118
111
  telegram_create_chat
119
112
  end
120
113
 
121
114
  def select_chat_event
122
115
  return not_logged_in_message unless user
123
116
 
124
- register_user_action("select_chat", user.id)
125
117
  title = msg.text.split("/").last
126
118
  chat = user.chat_by_title(title)
127
119
  return chat_not_found_message unless chat
@@ -131,15 +123,11 @@ module ChatgptAssistant
131
123
  end
132
124
 
133
125
  def stop_event
134
- register_event_action("stop", visitor.id) unless visitor.tel_user
135
- register_user_action("stop", visitor.tel_user.id) if visitor.tel_user
136
126
  send_message commom_messages[:stop], msg.chat.id
137
127
  bot.api.leave_chat(chat_id: msg.chat.id)
138
128
  end
139
129
 
140
130
  def nil_event
141
- register_event_action("nil", visitor.id) unless visitor.tel_user
142
- register_user_action("nil", visitor.tel_user.id) if visitor.tel_user
143
131
  send_message error_messages[:nil], msg.chat.id
144
132
  end
145
133
 
@@ -147,7 +135,6 @@ module ChatgptAssistant
147
135
  return not_logged_in_message unless user
148
136
  return no_chat_selected_message if user.current_chat_id.nil?
149
137
 
150
- register_user_action("audio", user.id)
151
138
  user_audio = transcribe_file(telegram_audio_url)
152
139
  message = Message.new(content: user_audio[:text], chat_id: user.current_chat_id, role: "user")
153
140
  if message.save
@@ -29,9 +29,7 @@ module ChatgptAssistant
29
29
 
30
30
  def download_audio(audio_url)
31
31
  audio_conn = Faraday.new(url: audio_url)
32
- File.open(dl_file_name, "wb") do |file|
33
- file.write(audio_conn.get.body)
34
- end
32
+ File.binwrite(dl_file_name, audio_conn.get.body)
35
33
  FFMPEG::Movie.new(dl_file_name).transcode(file_name)
36
34
  File.delete(dl_file_name)
37
35
  end
@@ -39,14 +37,14 @@ module ChatgptAssistant
39
37
  def header
40
38
  {
41
39
  "Content-Type": "multipart/form-data",
42
- "Authorization": "Bearer #{openai_api_key}"
40
+ Authorization: "Bearer #{openai_api_key}"
43
41
  }
44
42
  end
45
43
 
46
44
  def payload
47
45
  {
48
- "file": Faraday::UploadIO.new(file_name, "audio/mp3"),
49
- "model": "whisper-1"
46
+ file: Faraday::UploadIO.new(file_name, "audio/mp3"),
47
+ model: "whisper-1"
50
48
  }
51
49
  end
52
50
 
@@ -61,9 +61,7 @@ module ChatgptAssistant
61
61
  engine: "neural"
62
62
  )
63
63
 
64
- File.open("voice/aws-#{time}.mp3", "wb") do |file|
65
- file.write(response.audio_stream.read)
66
- end
64
+ File.binwrite("voice/aws-#{time}.mp3", response.audio_stream.read)
67
65
  "voice/aws-#{time}.mp3"
68
66
  end
69
67
 
@@ -86,9 +84,7 @@ module ChatgptAssistant
86
84
  voice: voice
87
85
  ).result
88
86
 
89
- File.open("voice/ibm-#{time}.mp3", "wb") do |audio_file|
90
- audio_file.write(audio)
91
- end
87
+ File.binwrite("voice/ibm-#{time}.mp3", audio)
92
88
  "voice/ibm-#{time}.mp3"
93
89
  end
94
90
 
@@ -10,27 +10,36 @@ module ChatgptAssistant
10
10
  @openai_api_key = openai_api_key
11
11
  end
12
12
 
13
- def chat(message, chat_id)
13
+ def chat(message, chat_id, error_message)
14
+ @error_message = error_message
14
15
  @chat_id = chat_id
15
16
  @message = message
16
17
  @response = request(message)
17
18
  @json = JSON.parse(response.body)
18
19
 
19
- return error_log if response.status != 200
20
+ return no_response_error if json["choices"].empty?
21
+ return bot_offline_error if response.status != 200
20
22
 
21
23
  text = json["choices"][0]["message"]["content"]
22
24
 
23
25
  Message.create(content: text, role: "assistant", chat_id: chat_id)
24
26
  text
27
+ rescue StandardError => e
28
+ Error.create(message: e.message, backtrace: e.backtrace)
29
+ error_message
25
30
  end
26
31
 
27
32
  private
28
33
 
29
34
  attr_reader :openai_api_key, :response, :message
30
- attr_accessor :chat_id, :json
35
+ attr_accessor :chat_id, :json, :error_message
31
36
 
32
- def error_log
33
- "Algo deu errado, tente novamente mais tarde." # TODO: use a DefaultMessage object
37
+ def no_response_error
38
+ "I'm sorry, I didn't understand you. Please, try again."
39
+ end
40
+
41
+ def bot_offline_error
42
+ "I'm sorry, I'm offline. Please, try again later."
34
43
  end
35
44
 
36
45
  def header
@@ -59,7 +68,9 @@ module ChatgptAssistant
59
68
  end
60
69
  {
61
70
  model: "gpt-3.5-turbo",
62
- messages: messages
71
+ messages: messages,
72
+ max_tokens: 1000,
73
+ temperature: 0.1
63
74
  }.to_json
64
75
  end
65
76
 
@@ -9,23 +9,23 @@ module ChatgptAssistant
9
9
  # This class is responsible for the configuration of the Chatgpt Assistant
10
10
  class Config
11
11
  def initialize
12
- @env_type = ENV["ENV_TYPE"]
13
- @language = ENV["LANGUAGE"]
14
- @mode = ENV["MODE"]
15
- @database_host = ENV["POSTGRES_HOST"]
16
- @database_name = ENV["POSTGRES_DB"]
17
- @database_username = ENV["POSTGRES_USER"]
18
- @database_password = ENV["POSTGRES_PASSWORD"]
19
- @openai_api_key = ENV["OPENAI_API_KEY"]
20
- @telegram_token = ENV["TELEGRAM_TOKEN"]
21
- @discord_token = ENV["DISCORD_TOKEN"]
22
- @discord_client_id = ENV["DISCORD_CLIENT_ID"]
23
- @ibm_api_key = ENV["IBM_API_KEY"]
24
- @ibm_url = ENV["IBM_URL"]
25
- @aws_access_key_id = ENV["AWS_ACCESS_KEY_ID"]
26
- @aws_secret_access_key = ENV["AWS_SECRET_ACCESS_KEY"]
27
- @aws_region = ENV["AWS_REGION"]
28
- @discord_prefix = ENV["DISCORD_PREFIX"]
12
+ @env_type = ENV.fetch("ENV_TYPE", nil)
13
+ @language = ENV.fetch("LANGUAGE", nil)
14
+ @mode = ENV.fetch("MODE", nil)
15
+ @database_host = ENV.fetch("POSTGRES_HOST", nil)
16
+ @database_name = ENV.fetch("POSTGRES_DB", nil)
17
+ @database_username = ENV.fetch("POSTGRES_USER", nil)
18
+ @database_password = ENV.fetch("POSTGRES_PASSWORD", nil)
19
+ @openai_api_key = ENV.fetch("OPENAI_API_KEY", nil)
20
+ @telegram_token = ENV.fetch("TELEGRAM_TOKEN", nil)
21
+ @discord_token = ENV.fetch("DISCORD_TOKEN", nil)
22
+ @discord_client_id = ENV.fetch("DISCORD_CLIENT_ID", nil)
23
+ @ibm_api_key = ENV.fetch("IBM_API_KEY", nil)
24
+ @ibm_url = ENV.fetch("IBM_URL", nil)
25
+ @aws_access_key_id = ENV.fetch("AWS_ACCESS_KEY_ID", nil)
26
+ @aws_secret_access_key = ENV.fetch("AWS_SECRET_ACCESS_KEY", nil)
27
+ @aws_region = ENV.fetch("AWS_REGION", nil)
28
+ @discord_prefix = ENV.fetch("DISCORD_PREFIX", nil)
29
29
  end
30
30
 
31
31
  attr_reader :openai_api_key, :telegram_token, :discord_token, :ibm_api_key, :ibm_url,
@@ -48,9 +48,7 @@ module ChatgptAssistant
48
48
  db_connection
49
49
  ActiveRecord::Base.logger = Logger.new($stdout)
50
50
  VisitorMigration.new.migrate(:up)
51
- VisitorActionsMigration.new.migrate(:up)
52
51
  UserMigration.new.migrate(:up)
53
- UserActionsMigration.new.migrate(:up)
54
52
  ChatMigration.new.migrate(:up)
55
53
  MessageMigration.new.migrate(:up)
56
54
  ErrorMigration.new.migrate(:up)
@@ -13,22 +13,7 @@ class VisitorMigration < ActiveRecord::Migration[5.2]
13
13
  t.string :discord_id, limit: 100
14
14
  t.integer :platform, null: false, default: 0
15
15
  t.string :name, null: false
16
- t.integer :current_user_id, null: false, default: 0
17
- t.timestamps
18
- end
19
- end
20
- end
21
-
22
- # VisitorActions model
23
- class VisitorActionsMigration < ActiveRecord::Migration[5.2]
24
- def change
25
- return if ActiveRecord::Base.connection.table_exists? :visitor_actions
26
-
27
- create_table :visitor_actions do |t|
28
- t.references :visitor, null: false, foreign_key: true
29
- t.text :action, null: false
30
- t.text :description, null: false
31
- t.integer :role, null: false, default: 0
16
+ t.integer :current_user_id, default: 0
32
17
  t.timestamps
33
18
  end
34
19
  end
@@ -56,21 +41,6 @@ class UserMigration < ActiveRecord::Migration[5.2]
56
41
  end
57
42
  end
58
43
 
59
- # UserActions model
60
- class UserActionsMigration < ActiveRecord::Migration[5.2]
61
- def change
62
- return if ActiveRecord::Base.connection.table_exists? :user_actions
63
-
64
- create_table :user_actions do |t|
65
- t.references :user, null: false, foreign_key: true
66
- t.text :action, null: false, default: ""
67
- t.text :description, null: false, default: ""
68
- t.integer :role, null: false, default: 0
69
- t.timestamps
70
- end
71
- end
72
- end
73
-
74
44
  # Chat model
75
45
  class ChatMigration < ActiveRecord::Migration[5.2]
76
46
  def change
@@ -80,6 +50,9 @@ class ChatMigration < ActiveRecord::Migration[5.2]
80
50
  t.references :user, null: false, foreign_key: true
81
51
  t.text :title, null: false, default: "", limit: 100
82
52
  t.integer :status, null: false, default: 0
53
+ t.integer :messages_count, null: false, default: 0
54
+ t.string :actor
55
+ t.text :prompt
83
56
  t.timestamps
84
57
  end
85
58
  end
@@ -7,8 +7,6 @@ class Visitor < ActiveRecord::Base
7
7
  has_many :visitor_actions
8
8
  # has_one :tel_user, foreign_key: "telegram_id", class_name: "User"
9
9
  # has_one :dis_user, foreign_key: "discord_id", class_name: "User"
10
- validates :telegram_id, uniqueness: true
11
- validates :discord_id, uniqueness: true
12
10
  validates :name, presence: true
13
11
  validates :platform, presence: true
14
12
  enum platform: { telegram: 0, discord: 1 }
@@ -22,15 +20,6 @@ class Visitor < ActiveRecord::Base
22
20
  end
23
21
  end
24
22
 
25
- # VisitorActions model
26
- class VisitorAction < ActiveRecord::Base
27
- belongs_to :visitor
28
- validates :action, presence: true
29
- validates :description, presence: true
30
- validates :role, presence: true
31
- enum role: { user: 0, assistant: 1, warning: 2 }
32
- end
33
-
34
23
  # User model
35
24
  class User < ActiveRecord::Base
36
25
  attr_accessor :password
@@ -66,16 +55,6 @@ class User < ActiveRecord::Base
66
55
  end
67
56
  end
68
57
 
69
- # UserActions model
70
- class UserAction < ActiveRecord::Base
71
- belongs_to :user
72
- validates :user_id, presence: true
73
- validates :action, presence: true
74
- validates :description, presence: true
75
- validates :role, presence: true
76
- enum role: { user: 0, assistant: 1, warning: 2 }
77
- end
78
-
79
58
  # Chat model
80
59
  class Chat < ActiveRecord::Base
81
60
  validates :user_id, presence: true
@@ -84,6 +63,15 @@ class Chat < ActiveRecord::Base
84
63
 
85
64
  belongs_to :user
86
65
  has_many :messages
66
+
67
+ after_create :init_chat_if_actor_provided
68
+
69
+ def init_chat_if_actor_provided
70
+ return if actor.nil?
71
+
72
+ messages.create(content: prompt, role: "user")
73
+ messages.create(content: "Hello, I'm #{actor}. I will follow #{prompt}", role: "assistant")
74
+ end
87
75
  end
88
76
 
89
77
  # Message model
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ChatgptAssistant
4
- VERSION = "0.1.3"
4
+ VERSION = "0.1.5"
5
5
  end
@@ -10,6 +10,7 @@ require_relative "chatgpt_assistant/models"
10
10
  require_relative "bots/application_bot"
11
11
  require_relative "bots/telegram_bot"
12
12
  require_relative "bots/discord_bot"
13
+ require "awesome_chatgpt_actors"
13
14
  require "streamio-ffmpeg"
14
15
  require "aws-sdk-polly"
15
16
  require "telegram/bot"