chatgpt_assistant 0.1.4 → 0.1.6
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 +4 -4
- data/.env_sample +1 -1
- data/.rubocop.yml +3 -3
- data/Gemfile +19 -5
- data/Gemfile.lock +64 -50
- data/README.md +14 -13
- data/Rakefile +2 -0
- data/docker-compose.prod.yml +1 -1
- data/docker-compose.yml +18 -0
- data/exe/chatgpt_bot +3 -0
- data/lib/bots/application_bot.rb +15 -5
- data/lib/bots/discord_bot.rb +42 -15
- data/lib/bots/helpers/authentication_helper.rb +7 -6
- data/lib/bots/helpers/discord_helper.rb +29 -7
- data/lib/bots/helpers/discord_voice_helper.rb +1 -1
- data/lib/bots/helpers/messenger_helper.rb +35 -36
- data/lib/bots/helpers/search_helper.rb +3 -3
- data/lib/bots/helpers/telegram_helper.rb +19 -35
- data/lib/bots/helpers/telegram_voice_helper.rb +33 -0
- data/lib/bots/helpers/validation_helper.rb +9 -0
- data/lib/bots/helpers/visit_helper.rb +4 -0
- data/lib/bots/jobs/new_chat_job.rb +17 -0
- data/lib/bots/jobs/register_job.rb +16 -0
- data/lib/bots/jobs/voice_connect_job.rb +14 -0
- data/lib/bots/services/new_chat_service.rb +34 -0
- data/lib/bots/services/register_service.rb +36 -0
- data/lib/bots/services/voice_connect_service.rb +29 -0
- data/lib/bots/telegram_bot.rb +72 -54
- data/lib/chatgpt_assistant/chatter.rb +17 -6
- data/lib/chatgpt_assistant/config.rb +23 -3
- data/lib/chatgpt_assistant/default_messages.rb +72 -30
- data/lib/chatgpt_assistant/error.rb +219 -0
- data/lib/chatgpt_assistant/migrations.rb +3 -30
- data/lib/chatgpt_assistant/models.rb +24 -29
- data/lib/chatgpt_assistant/sidekiq.rb +7 -0
- data/lib/chatgpt_assistant/sidekiq.yml +10 -0
- data/lib/chatgpt_assistant/version.rb +1 -1
- data/lib/chatgpt_assistant.rb +4 -12
- data/prompts-data/awesome-en-prompts.csv +164 -0
- data/prompts-data/awesome-pt-prompts.csv +164 -0
- metadata +15 -4
- data/lib/bots/helpers/logger_action_helper.rb +0 -14
@@ -0,0 +1,219 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ChatgptAssistant
|
4
|
+
# Load Error
|
5
|
+
module LoadError
|
6
|
+
def load_error_context
|
7
|
+
language = ENV.fetch("LANGUAGE", "en")
|
8
|
+
discord_prefix = ENV.fetch("DISCORD_PREFIX", "!")
|
9
|
+
DefaultMessages.new(language, discord_prefix).error_messages
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# No User Error
|
14
|
+
class NoRegisterInfoError < StandardError
|
15
|
+
def initialize(message = load_error_context[:no_register_info])
|
16
|
+
super(message)
|
17
|
+
end
|
18
|
+
|
19
|
+
include LoadError
|
20
|
+
end
|
21
|
+
|
22
|
+
# Nil Command Error
|
23
|
+
class NilError < StandardError
|
24
|
+
def initialize(message = load_error_context[:nil])
|
25
|
+
super(message)
|
26
|
+
end
|
27
|
+
|
28
|
+
include LoadError
|
29
|
+
end
|
30
|
+
|
31
|
+
# Wrong Email Error
|
32
|
+
class WrongEmailError < StandardError
|
33
|
+
def initialize(message = load_error_context[:wrong_email])
|
34
|
+
super(message)
|
35
|
+
end
|
36
|
+
|
37
|
+
include LoadError
|
38
|
+
end
|
39
|
+
|
40
|
+
# Wrong Password Error
|
41
|
+
class WrongPasswordError < StandardError
|
42
|
+
def initialize(message = load_error_context[:wrong_password])
|
43
|
+
super(message)
|
44
|
+
end
|
45
|
+
|
46
|
+
include LoadError
|
47
|
+
end
|
48
|
+
|
49
|
+
# User Already Exists Error
|
50
|
+
class UserAlreadyExistsError < StandardError
|
51
|
+
def initialize(message = load_error_context[:user_already_exists])
|
52
|
+
super(message)
|
53
|
+
end
|
54
|
+
|
55
|
+
include LoadError
|
56
|
+
end
|
57
|
+
|
58
|
+
# Chat Already Exists Error
|
59
|
+
class ChatAlreadyExistsError < StandardError
|
60
|
+
def initialize(message = load_error_context[:chat_already_exists])
|
61
|
+
super(message)
|
62
|
+
end
|
63
|
+
|
64
|
+
include LoadError
|
65
|
+
end
|
66
|
+
|
67
|
+
# Sign Up Error
|
68
|
+
class SignUpError < StandardError
|
69
|
+
def initialize(message = load_error_context[:sign_up_error])
|
70
|
+
super(message)
|
71
|
+
end
|
72
|
+
|
73
|
+
include LoadError
|
74
|
+
end
|
75
|
+
|
76
|
+
# Chat Not Created Error
|
77
|
+
class ChatNotCreatedError < StandardError
|
78
|
+
def initialize(message = load_error_context[:chat_not_created_error])
|
79
|
+
super(message)
|
80
|
+
end
|
81
|
+
|
82
|
+
include LoadError
|
83
|
+
end
|
84
|
+
|
85
|
+
# Message Not Created Error
|
86
|
+
class MessageNotCreatedError < StandardError
|
87
|
+
def initialize(message = load_error_context[:message_not_created_error])
|
88
|
+
super(message)
|
89
|
+
end
|
90
|
+
|
91
|
+
include LoadError
|
92
|
+
end
|
93
|
+
|
94
|
+
# No Chat Selected Error
|
95
|
+
class NoChatSelectedError < StandardError
|
96
|
+
def initialize(message = load_error_context[:no_chat_selected])
|
97
|
+
super(message)
|
98
|
+
end
|
99
|
+
|
100
|
+
include LoadError
|
101
|
+
end
|
102
|
+
|
103
|
+
# No Messages Founded Error
|
104
|
+
class NoMessagesFoundedError < StandardError
|
105
|
+
def initialize(message = load_error_context[:no_messages_founded])
|
106
|
+
super(message)
|
107
|
+
end
|
108
|
+
|
109
|
+
include LoadError
|
110
|
+
end
|
111
|
+
|
112
|
+
# No Chats Founded Error
|
113
|
+
class NoChatsFoundedError < StandardError
|
114
|
+
def initialize(message = load_error_context[:no_chats_founded])
|
115
|
+
super(message)
|
116
|
+
end
|
117
|
+
|
118
|
+
include LoadError
|
119
|
+
end
|
120
|
+
|
121
|
+
# Chat Not Found Error
|
122
|
+
class ChatNotFoundError < StandardError
|
123
|
+
def initialize(message = load_error_context[:chat_not_found])
|
124
|
+
super(message)
|
125
|
+
end
|
126
|
+
|
127
|
+
include LoadError
|
128
|
+
end
|
129
|
+
|
130
|
+
# User Not Found Error
|
131
|
+
class UserNotFoundError < StandardError
|
132
|
+
def initialize(message = load_error_context[:user_not_found])
|
133
|
+
super(message)
|
134
|
+
end
|
135
|
+
|
136
|
+
include LoadError
|
137
|
+
end
|
138
|
+
|
139
|
+
# User Not Registered Error
|
140
|
+
class UserNotRegisteredError < StandardError
|
141
|
+
def initialize(message = load_error_context[:user_not_registered])
|
142
|
+
super(message)
|
143
|
+
end
|
144
|
+
|
145
|
+
include LoadError
|
146
|
+
end
|
147
|
+
|
148
|
+
# User Logged In Error
|
149
|
+
class UserLoggedInError < StandardError
|
150
|
+
def initialize(message = load_error_context[:user_logged_in])
|
151
|
+
super(message)
|
152
|
+
end
|
153
|
+
|
154
|
+
include LoadError
|
155
|
+
end
|
156
|
+
|
157
|
+
# User Not Logged In Error
|
158
|
+
class UserNotLoggedInError < StandardError
|
159
|
+
def initialize(message = load_error_context[:user_not_logged_in])
|
160
|
+
super(message)
|
161
|
+
end
|
162
|
+
|
163
|
+
include LoadError
|
164
|
+
end
|
165
|
+
|
166
|
+
# User Not In Voice Channel Error
|
167
|
+
class UserNotInVoiceChannelError < StandardError
|
168
|
+
def initialize(message = load_error_context[:user_not_in_voice_channel])
|
169
|
+
super(message)
|
170
|
+
end
|
171
|
+
|
172
|
+
include LoadError
|
173
|
+
end
|
174
|
+
|
175
|
+
# Bot Not In Voice Channel Error
|
176
|
+
class BotNotInVoiceChannelError < StandardError
|
177
|
+
def initialize(message = load_error_context[:bot_not_in_voice_channel])
|
178
|
+
super(message)
|
179
|
+
end
|
180
|
+
|
181
|
+
include LoadError
|
182
|
+
end
|
183
|
+
|
184
|
+
# Message Not Found Error
|
185
|
+
class MessageHistoryTooLongError < StandardError
|
186
|
+
def initialize(message = load_error_context[:message_history_too_long])
|
187
|
+
super(message)
|
188
|
+
end
|
189
|
+
|
190
|
+
include LoadError
|
191
|
+
end
|
192
|
+
|
193
|
+
# Text Length Too Long Error
|
194
|
+
class TextLengthTooLongError < StandardError
|
195
|
+
def initialize(message = load_error_context[:text_length_too_long])
|
196
|
+
super(message)
|
197
|
+
end
|
198
|
+
|
199
|
+
include LoadError
|
200
|
+
end
|
201
|
+
|
202
|
+
# Invalid Command Error
|
203
|
+
class InvalidCommandError < StandardError
|
204
|
+
def initialize(message = load_error_context[:invalid_command])
|
205
|
+
super(message)
|
206
|
+
end
|
207
|
+
|
208
|
+
include LoadError
|
209
|
+
end
|
210
|
+
|
211
|
+
# Something Went Wrong Error
|
212
|
+
class SomethingWentWrongError < StandardError
|
213
|
+
def initialize(message = load_error_context[:something_went_wrong])
|
214
|
+
super(message)
|
215
|
+
end
|
216
|
+
|
217
|
+
include LoadError
|
218
|
+
end
|
219
|
+
end
|
@@ -19,21 +19,6 @@ class VisitorMigration < ActiveRecord::Migration[5.2]
|
|
19
19
|
end
|
20
20
|
end
|
21
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
|
32
|
-
t.timestamps
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
22
|
# User model
|
38
23
|
class UserMigration < ActiveRecord::Migration[5.2]
|
39
24
|
def change
|
@@ -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
|
@@ -5,8 +5,6 @@ require "active_record"
|
|
5
5
|
# Visitor model
|
6
6
|
class Visitor < ActiveRecord::Base
|
7
7
|
has_many :visitor_actions
|
8
|
-
# has_one :tel_user, foreign_key: "telegram_id", class_name: "User"
|
9
|
-
# has_one :dis_user, foreign_key: "discord_id", class_name: "User"
|
10
8
|
validates :name, presence: true
|
11
9
|
validates :platform, presence: true
|
12
10
|
enum platform: { telegram: 0, discord: 1 }
|
@@ -20,34 +18,29 @@ class Visitor < ActiveRecord::Base
|
|
20
18
|
end
|
21
19
|
end
|
22
20
|
|
23
|
-
# VisitorActions model
|
24
|
-
class VisitorAction < ActiveRecord::Base
|
25
|
-
belongs_to :visitor
|
26
|
-
validates :action, presence: true
|
27
|
-
validates :description, presence: true
|
28
|
-
validates :role, presence: true
|
29
|
-
enum role: { user: 0, assistant: 1, warning: 2 }
|
30
|
-
end
|
31
|
-
|
32
21
|
# User model
|
33
22
|
class User < ActiveRecord::Base
|
34
23
|
attr_accessor :password
|
35
24
|
|
36
25
|
belongs_to :tel_visitor, optional: true, foreign_key: "telegram_id", class_name: "Visitor"
|
37
26
|
belongs_to :dis_visitor, optional: true, foreign_key: "discord_id", class_name: "Visitor"
|
38
|
-
|
39
|
-
validates :email, presence: true, uniqueness: true
|
40
|
-
validates :role, presence: true
|
41
|
-
validates :open_chats, presence: true
|
42
|
-
validates :closed_chats, presence: true
|
43
|
-
validates :total_chats, presence: true
|
44
|
-
validates :total_messages, presence: true
|
27
|
+
|
28
|
+
validates :email, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }, length: { maximum: 100 }, on: :create
|
29
|
+
validates :role, presence: true, on: :create
|
30
|
+
validates :open_chats, presence: true, on: :create
|
31
|
+
validates :closed_chats, presence: true, on: :create
|
32
|
+
validates :total_chats, presence: true, on: :create
|
33
|
+
validates :total_messages, presence: true, on: :create
|
34
|
+
validates :password, presence: true, on: :create
|
35
|
+
|
36
|
+
before_save :encrypt_password, if: :password
|
37
|
+
|
45
38
|
has_many :chats
|
46
39
|
|
47
40
|
def encrypt_password
|
48
41
|
return if password.nil?
|
49
42
|
|
50
|
-
self.password_salt = BCrypt::Engine.generate_salt
|
43
|
+
self.password_salt = BCrypt::Engine.generate_salt
|
51
44
|
self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
|
52
45
|
end
|
53
46
|
|
@@ -62,16 +55,10 @@ class User < ActiveRecord::Base
|
|
62
55
|
def chat_by_title(title)
|
63
56
|
chats.find_by(title: title)
|
64
57
|
end
|
65
|
-
end
|
66
58
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
validates :user_id, presence: true
|
71
|
-
validates :action, presence: true
|
72
|
-
validates :description, presence: true
|
73
|
-
validates :role, presence: true
|
74
|
-
enum role: { user: 0, assistant: 1, warning: 2 }
|
59
|
+
def chat_history
|
60
|
+
current_chat.messages.last(10).map { |m| "#{m.role}: #{m.content}\nat: #{m.created_at}" }
|
61
|
+
end
|
75
62
|
end
|
76
63
|
|
77
64
|
# Chat model
|
@@ -82,12 +69,20 @@ class Chat < ActiveRecord::Base
|
|
82
69
|
|
83
70
|
belongs_to :user
|
84
71
|
has_many :messages
|
72
|
+
|
73
|
+
after_create :init_chat_if_actor_provided
|
74
|
+
|
75
|
+
def init_chat_if_actor_provided
|
76
|
+
return if actor.nil?
|
77
|
+
|
78
|
+
messages.create(content: prompt, role: "system")
|
79
|
+
end
|
85
80
|
end
|
86
81
|
|
87
82
|
# Message model
|
88
83
|
class Message < ActiveRecord::Base
|
89
84
|
validates :content, presence: true
|
90
|
-
enum role: { user: 0, assistant: 1 }
|
85
|
+
enum role: { user: 0, assistant: 1, system: 2 }
|
91
86
|
|
92
87
|
belongs_to :chat
|
93
88
|
end
|
data/lib/chatgpt_assistant.rb
CHANGED
@@ -7,14 +7,18 @@ require_relative "chatgpt_assistant/chatter"
|
|
7
7
|
require_relative "chatgpt_assistant/version"
|
8
8
|
require_relative "chatgpt_assistant/config"
|
9
9
|
require_relative "chatgpt_assistant/models"
|
10
|
+
require_relative "chatgpt_assistant/error"
|
10
11
|
require_relative "bots/application_bot"
|
11
12
|
require_relative "bots/telegram_bot"
|
12
13
|
require_relative "bots/discord_bot"
|
14
|
+
require "awesome_chatgpt_actors"
|
13
15
|
require "streamio-ffmpeg"
|
14
16
|
require "aws-sdk-polly"
|
15
17
|
require "telegram/bot"
|
16
18
|
require "ibm_watson"
|
17
19
|
require "discordrb"
|
20
|
+
require "sidekiq"
|
21
|
+
require "sidekiq-scheduler"
|
18
22
|
require "faraday"
|
19
23
|
require "bcrypt"
|
20
24
|
|
@@ -31,24 +35,12 @@ module ChatgptAssistant
|
|
31
35
|
return discord_bot if discord_mode?
|
32
36
|
|
33
37
|
raise "Invalid mode"
|
34
|
-
rescue StandardError => e
|
35
|
-
save_error(e)
|
36
|
-
retry
|
37
38
|
end
|
38
39
|
|
39
40
|
private
|
40
41
|
|
41
42
|
attr_reader :mode, :config
|
42
43
|
|
43
|
-
def save_error(err)
|
44
|
-
puts "Error: #{err.message}"
|
45
|
-
err.backtrace.each { |line| puts line }
|
46
|
-
Error.create(message: err.message, backtrace: err.backtrace) unless err.message == Error.last&.message
|
47
|
-
rescue StandardError
|
48
|
-
puts "Error: #{err.message}"
|
49
|
-
puts "Backtrace: #{err.backtrace}"
|
50
|
-
end
|
51
|
-
|
52
44
|
def telegram_mode?
|
53
45
|
mode == "telegram"
|
54
46
|
end
|