chatgpt_assistant 0.1.3 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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"