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.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -1
- data/Dockerfile +1 -1
- data/Gemfile +3 -1
- data/Gemfile.lock +17 -6
- data/Rakefile +2 -0
- data/SECURITY.md +15 -0
- data/exe/chatgpt_bot +1 -1
- data/lib/bots/discord_bot.rb +43 -13
- data/lib/bots/helpers/authentication_helper.rb +6 -6
- data/lib/bots/helpers/discord_helper.rb +26 -4
- data/lib/bots/helpers/discord_voice_helper.rb +1 -1
- data/lib/bots/helpers/logger_action_helper.rb +0 -7
- data/lib/bots/helpers/messenger_helper.rb +28 -26
- data/lib/bots/helpers/telegram_helper.rb +16 -28
- data/lib/bots/helpers/telegram_voice_helper.rb +33 -0
- data/lib/bots/helpers/validation_helper.rb +9 -0
- data/lib/bots/telegram_bot.rb +2 -15
- data/lib/chatgpt_assistant/audio_recognition.rb +4 -6
- data/lib/chatgpt_assistant/audio_synthesis.rb +2 -6
- data/lib/chatgpt_assistant/chatter.rb +17 -6
- data/lib/chatgpt_assistant/config.rb +17 -19
- data/lib/chatgpt_assistant/migrations.rb +4 -31
- data/lib/chatgpt_assistant/models.rb +9 -21
- data/lib/chatgpt_assistant/version.rb +1 -1
- data/lib/chatgpt_assistant.rb +1 -0
- data/prompts-data/awesome-chatgpt-prompts.csv +164 -0
- metadata +6 -2
@@ -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
|
data/lib/bots/telegram_bot.rb
CHANGED
@@ -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.
|
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
|
-
|
40
|
+
Authorization: "Bearer #{openai_api_key}"
|
43
41
|
}
|
44
42
|
end
|
45
43
|
|
46
44
|
def payload
|
47
45
|
{
|
48
|
-
|
49
|
-
|
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.
|
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.
|
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
|
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
|
33
|
-
"
|
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
|
13
|
-
@language = ENV
|
14
|
-
@mode = ENV
|
15
|
-
@database_host = ENV
|
16
|
-
@database_name = ENV
|
17
|
-
@database_username = ENV
|
18
|
-
@database_password = ENV
|
19
|
-
@openai_api_key = ENV
|
20
|
-
@telegram_token = ENV
|
21
|
-
@discord_token = ENV
|
22
|
-
@discord_client_id = ENV
|
23
|
-
@ibm_api_key = ENV
|
24
|
-
@ibm_url = ENV
|
25
|
-
@aws_access_key_id = ENV
|
26
|
-
@aws_secret_access_key = ENV
|
27
|
-
@aws_region = ENV
|
28
|
-
@discord_prefix = ENV
|
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,
|
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
|
data/lib/chatgpt_assistant.rb
CHANGED
@@ -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"
|