slack-smart-bot 1.14.1 → 1.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (176) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +237 -48
  3. data/img/chat_gpt.png +0 -0
  4. data/img/chat_gpt_session.png +0 -0
  5. data/img/chat_gpt_share.png +0 -0
  6. data/img/command_add_sc.png +0 -0
  7. data/img/command_bot_help_echo.png +0 -0
  8. data/img/command_loop.png +0 -0
  9. data/img/command_my_timeoff.png +0 -0
  10. data/img/command_recap.png +0 -0
  11. data/img/command_repl1.png +0 -0
  12. data/img/command_repl2.png +0 -0
  13. data/img/command_ruby.png +0 -0
  14. data/img/command_run_repl.png +0 -0
  15. data/img/command_see_announcements.png +0 -0
  16. data/img/command_see_statuses.png +0 -0
  17. data/img/command_see_team.png +0 -0
  18. data/img/command_summarize.png +0 -0
  19. data/img/commands_inline.png +0 -0
  20. data/img/commands_on_demand.png +0 -0
  21. data/img/commands_on_external_call.png +0 -0
  22. data/img/image_editing.png +0 -0
  23. data/img/image_generation.png +0 -0
  24. data/img/image_variations.png +0 -0
  25. data/img/openai-300.png +0 -0
  26. data/img/openai.png +0 -0
  27. data/img/slack-300.png +0 -0
  28. data/img/slack.png +0 -0
  29. data/img/smart-bot-150.png +0 -0
  30. data/img/smart-bot-profile-pic-2.png +0 -0
  31. data/img/smart-bot-profile-pic.png +0 -0
  32. data/img/smart-bot.png +0 -0
  33. data/img/whisper.png +0 -0
  34. data/lib/slack/smart-bot/ai/open_ai/connect.rb +165 -43
  35. data/lib/slack/smart-bot/ai/open_ai/models.rb +61 -9
  36. data/lib/slack/smart-bot/ai/open_ai/send_gpt_chat.rb +67 -11
  37. data/lib/slack/smart-bot/ai/open_ai/send_image_edit.rb +4 -3
  38. data/lib/slack/smart-bot/ai/open_ai/send_image_generation.rb +4 -4
  39. data/lib/slack/smart-bot/ai/open_ai/send_image_variation.rb +4 -3
  40. data/lib/slack/smart-bot/ai/open_ai/whisper_transcribe.rb +4 -3
  41. data/lib/slack/smart-bot/comm/ask.rb +20 -8
  42. data/lib/slack/smart-bot/comm/dont_understand.rb +2 -2
  43. data/lib/slack/smart-bot/comm/event_hello.rb +30 -1
  44. data/lib/slack/smart-bot/comm/get_channel_members.rb +2 -1
  45. data/lib/slack/smart-bot/comm/get_presence.rb +1 -0
  46. data/lib/slack/smart-bot/comm/get_smartbot_team_info.rb +10 -0
  47. data/lib/slack/smart-bot/comm/get_user_info.rb +45 -6
  48. data/lib/slack/smart-bot/comm/get_users.rb +8 -1
  49. data/lib/slack/smart-bot/comm/respond.rb +225 -196
  50. data/lib/slack/smart-bot/comm/send_msg_channel.rb +2 -2
  51. data/lib/slack/smart-bot/comm/send_msg_user.rb +10 -9
  52. data/lib/slack/smart-bot/comm/unreact.rb +2 -2
  53. data/lib/slack/smart-bot/comm.rb +1 -0
  54. data/lib/slack/smart-bot/commands/general/add_admin.rb +16 -6
  55. data/lib/slack/smart-bot/commands/general/add_announcement.rb +3 -3
  56. data/lib/slack/smart-bot/commands/general/add_vacation.rb +28 -12
  57. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat.rb +272 -23
  58. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_add_collaborator.rb +42 -0
  59. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_copy_session.rb +89 -0
  60. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_delete_session.rb +45 -0
  61. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_get_prompts.rb +41 -0
  62. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_list_sessions.rb +81 -0
  63. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_share_session.rb +52 -0
  64. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_use_model.rb +52 -0
  65. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_edit_image.rb +14 -11
  66. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_generate_image.rb +15 -11
  67. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_models.rb +29 -17
  68. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_variations_image.rb +16 -13
  69. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_whisper.rb +13 -7
  70. data/lib/slack/smart-bot/commands/general/allow_access.rb +8 -4
  71. data/lib/slack/smart-bot/commands/general/bot_help.rb +24 -9
  72. data/lib/slack/smart-bot/commands/general/bye_bot.rb +9 -5
  73. data/lib/slack/smart-bot/commands/general/delete_announcement.rb +2 -1
  74. data/lib/slack/smart-bot/commands/general/delete_share.rb +2 -1
  75. data/lib/slack/smart-bot/commands/general/deny_access.rb +1 -1
  76. data/lib/slack/smart-bot/commands/general/get_smartbot_readme.rb +15 -0
  77. data/lib/slack/smart-bot/commands/general/hi_bot.rb +10 -4
  78. data/lib/slack/smart-bot/commands/general/personal_settings.rb +26 -8
  79. data/lib/slack/smart-bot/commands/general/poster.rb +26 -2
  80. data/lib/slack/smart-bot/commands/general/public_holidays.rb +14 -24
  81. data/lib/slack/smart-bot/commands/general/recap.rb +399 -0
  82. data/lib/slack/smart-bot/commands/general/remove_admin.rb +19 -9
  83. data/lib/slack/smart-bot/commands/general/remove_vacation.rb +23 -6
  84. data/lib/slack/smart-bot/commands/general/see_access.rb +2 -1
  85. data/lib/slack/smart-bot/commands/general/see_admins.rb +8 -4
  86. data/lib/slack/smart-bot/commands/general/see_announcements.rb +5 -5
  87. data/lib/slack/smart-bot/commands/general/see_favorite_commands.rb +4 -4
  88. data/lib/slack/smart-bot/commands/general/see_shares.rb +1 -1
  89. data/lib/slack/smart-bot/commands/general/see_vacations.rb +34 -17
  90. data/lib/slack/smart-bot/commands/general/set_public_holidays.rb +4 -2
  91. data/lib/slack/smart-bot/commands/general/share_messages.rb +3 -3
  92. data/lib/slack/smart-bot/commands/general/summarize.rb +191 -0
  93. data/lib/slack/smart-bot/commands/general/teams/add_team.rb +4 -8
  94. data/lib/slack/smart-bot/commands/general/teams/delete_team.rb +3 -3
  95. data/lib/slack/smart-bot/commands/general/teams/memos/add_memo_team.rb +34 -29
  96. data/lib/slack/smart-bot/commands/general/teams/memos/add_memo_team_comment.rb +1 -1
  97. data/lib/slack/smart-bot/commands/general/teams/memos/delete_memo_team.rb +6 -4
  98. data/lib/slack/smart-bot/commands/general/teams/memos/see_memo_team.rb +26 -15
  99. data/lib/slack/smart-bot/commands/general/teams/memos/see_memos_team.rb +33 -24
  100. data/lib/slack/smart-bot/commands/general/teams/memos/set_memo_status.rb +4 -4
  101. data/lib/slack/smart-bot/commands/general/teams/ping_team.rb +10 -8
  102. data/lib/slack/smart-bot/commands/general/teams/see_teams.rb +73 -61
  103. data/lib/slack/smart-bot/commands/general/teams/see_vacations_team.rb +28 -13
  104. data/lib/slack/smart-bot/commands/general/teams/update_team.rb +9 -9
  105. data/lib/slack/smart-bot/commands/general_bot_commands.rb +1153 -835
  106. data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +19 -17
  107. data/lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb +12 -9
  108. data/lib/slack/smart-bot/commands/on_bot/admin/remove_routine.rb +2 -0
  109. data/lib/slack/smart-bot/commands/on_bot/admin/run_routine.rb +1 -0
  110. data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +5 -3
  111. data/lib/slack/smart-bot/commands/on_bot/admin_master/delete_message.rb +2 -3
  112. data/lib/slack/smart-bot/commands/on_bot/admin_master/get_bot_logs.rb +2 -3
  113. data/lib/slack/smart-bot/commands/on_bot/admin_master/react_to.rb +2 -3
  114. data/lib/slack/smart-bot/commands/on_bot/admin_master/send_message.rb +7 -6
  115. data/lib/slack/smart-bot/commands/on_bot/admin_master/update_message.rb +2 -3
  116. data/lib/slack/smart-bot/commands/on_bot/delete_repl.rb +1 -1
  117. data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +21 -20
  118. data/lib/slack/smart-bot/commands/on_bot/general/bot_stats.rb +40 -7
  119. data/lib/slack/smart-bot/commands/on_bot/general/bot_status.rb +6 -2
  120. data/lib/slack/smart-bot/commands/on_bot/general/stop_using_rules.rb +7 -6
  121. data/lib/slack/smart-bot/commands/on_bot/general/suggest_command.rb +5 -4
  122. data/lib/slack/smart-bot/commands/on_bot/general/use_rules.rb +4 -3
  123. data/lib/slack/smart-bot/commands/on_bot/get_repl.rb +4 -4
  124. data/lib/slack/smart-bot/commands/on_bot/kill_repl.rb +1 -1
  125. data/lib/slack/smart-bot/commands/on_bot/repl.rb +110 -53
  126. data/lib/slack/smart-bot/commands/on_bot/repl_client.rb +35 -29
  127. data/lib/slack/smart-bot/commands/on_bot/run_repl.rb +5 -5
  128. data/lib/slack/smart-bot/commands/on_bot/see_repls.rb +1 -2
  129. data/lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb +5 -4
  130. data/lib/slack/smart-bot/commands/on_extended/bot_rules.rb +22 -11
  131. data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +12 -7
  132. data/lib/slack/smart-bot/commands/on_master/admin_master/notify_message.rb +2 -2
  133. data/lib/slack/smart-bot/commands/on_master/admin_master/publish_announcements.rb +1 -1
  134. data/lib/slack/smart-bot/commands/on_master/admin_master/set_general_message.rb +5 -5
  135. data/lib/slack/smart-bot/commands/on_master/admin_master/set_maintenance.rb +5 -5
  136. data/lib/slack/smart-bot/commands/on_master/create_bot.rb +3 -3
  137. data/lib/slack/smart-bot/commands.rb +10 -0
  138. data/lib/slack/smart-bot/config.rb +126 -0
  139. data/lib/slack/smart-bot/listen.rb +12 -11
  140. data/lib/slack/smart-bot/process.rb +62 -55
  141. data/lib/slack/smart-bot/process_first.rb +106 -65
  142. data/lib/slack/smart-bot/treat_message.rb +79 -47
  143. data/lib/slack/smart-bot/utils/answer.rb +11 -3
  144. data/lib/slack/smart-bot/utils/answer_delete.rb +11 -3
  145. data/lib/slack/smart-bot/utils/check_vacations.rb +21 -3
  146. data/lib/slack/smart-bot/utils/create_routine_thread.rb +13 -13
  147. data/lib/slack/smart-bot/utils/display_calendar.rb +42 -8
  148. data/lib/slack/smart-bot/utils/encryption/decrypt.rb +16 -9
  149. data/lib/slack/smart-bot/utils/encryption/encrypt.rb +14 -11
  150. data/lib/slack/smart-bot/utils/find_user.rb +71 -0
  151. data/lib/slack/smart-bot/utils/get_access_channels.rb +22 -3
  152. data/lib/slack/smart-bot/utils/get_channels_name_and_id.rb +3 -4
  153. data/lib/slack/smart-bot/utils/get_command_ids.rb +5 -5
  154. data/lib/slack/smart-bot/utils/get_countries_candelarific.rb +18 -0
  155. data/lib/slack/smart-bot/utils/get_help.rb +21 -19
  156. data/lib/slack/smart-bot/utils/get_openai_sessions.rb +47 -0
  157. data/lib/slack/smart-bot/utils/get_personal_settings.rb +29 -3
  158. data/lib/slack/smart-bot/utils/get_rules_imported.rb +27 -6
  159. data/lib/slack/smart-bot/utils/get_shares.rb +1 -1
  160. data/lib/slack/smart-bot/utils/get_team_members.rb +4 -4
  161. data/lib/slack/smart-bot/utils/get_vacations.rb +15 -7
  162. data/lib/slack/smart-bot/utils/has_access.rb +10 -4
  163. data/lib/slack/smart-bot/utils/is_admin.rb +25 -17
  164. data/lib/slack/smart-bot/utils/local_time.rb +29 -0
  165. data/lib/slack/smart-bot/utils/save_stats.rb +5 -3
  166. data/lib/slack/smart-bot/utils/update_access_channels.rb +19 -3
  167. data/lib/slack/smart-bot/utils/update_openai_sessions.rb +42 -0
  168. data/lib/slack/smart-bot/utils/update_personal_settings.rb +11 -3
  169. data/lib/slack/smart-bot/utils/update_rules_imported.rb +18 -3
  170. data/lib/slack/smart-bot/utils/update_vacations.rb +5 -2
  171. data/lib/slack/smart-bot/utils/upgrade_to_use_team_ids.rb +276 -0
  172. data/lib/slack/smart-bot/utils.rb +6 -1
  173. data/lib/slack-smart-bot.rb +182 -76
  174. data/lib/slack-smart-bot_general_commands.rb +10 -9
  175. data/whats_new.txt +30 -13
  176. metadata +152 -18
@@ -1,60 +1,182 @@
1
1
  class SlackSmartBot
2
2
  module AI
3
3
  module OpenAI
4
- def self.connect(ai_open_ai, general_config, personal_settings, reconnect: false)
4
+ def self.connect(ai_open_ai, general_config, personal_settings, reconnect: false, service: :chat_gpt)
5
5
  require "openai"
6
+ require "nice_http"
6
7
  user = Thread.current[:user]
8
+ team_id_user = Thread.current[:team_id_user]
9
+
7
10
  ai_open_ai = {} if ai_open_ai.nil?
11
+ ai_open_ai_user = {}
8
12
 
9
13
  # ._ai to avoid to call .ai method from amazing_print
10
- ai_open_ai[user.name] ||= { client: nil, gpt_model: general_config._ai.open_ai.gpt_model, whisper_model: general_config._ai.open_ai.whisper_model, image_size: general_config._ai.open_ai.image_size }
11
- if personal_settings.key?(user.name) and personal_settings[user.name].key?("ai.open_ai.gpt_model") and
12
- personal_settings[user.name]["ai.open_ai.gpt_model"] != ""
13
- ai_open_ai[user.name][:gpt_model] = personal_settings[user.name]["ai.open_ai.gpt_model"]
14
- elsif general_config.key?(:ai) and general_config[:ai].key?(:open_ai) and general_config[:ai][:open_ai].key?(:gpt_model) and
15
- general_config[:ai][:open_ai][:gpt_model] != ""
16
- ai_open_ai[user.name][:gpt_model] = general_config[:ai][:open_ai][:gpt_model]
17
- end
18
- if personal_settings.key?(user.name) and personal_settings[user.name].key?("ai.open_ai.whisper_model") and
19
- personal_settings[user.name]["ai.open_ai.whisper_model"] != ""
20
- ai_open_ai[user.name][:whisper_model] = personal_settings[user.name]["ai.open_ai.whisper_model"]
21
- elsif general_config.key?(:ai) and general_config[:ai].key?(:open_ai) and general_config[:ai][:open_ai].key?(:whisper_model) and
22
- general_config[:ai][:open_ai][:whisper_model] != ""
23
- ai_open_ai[user.name][:whisper_model] = general_config[:ai][:open_ai][:whisper_model]
24
- end
25
- if personal_settings.key?(user.name) and personal_settings[user.name].key?("ai.open_ai.image_size") and
26
- personal_settings[user.name]["ai.open_ai.image_size"] != ""
27
- ai_open_ai[user.name][:image_size] = personal_settings[user.name]["ai.open_ai.image_size"]
28
- elsif general_config.key?(:ai) and general_config[:ai].key?(:open_ai) and general_config[:ai][:open_ai].key?(:image_size) and
29
- general_config[:ai][:open_ai][:image_size] != ""
30
- ai_open_ai[user.name][:image_size] = general_config[:ai][:open_ai][:image_size]
31
- end
32
- if ai_open_ai.key?(user.name) and ai_open_ai[user.name] != nil and ai_open_ai[user.name].key?(:client) and
33
- ai_open_ai[user.name][:client] != nil and !reconnect
34
- # do nothing
35
- elsif personal_settings.key?(user.name) and personal_settings[user.name].key?("ai.open_ai.access_token") and
36
- personal_settings[user.name]["ai.open_ai.access_token"].to_s != ""
37
- ai_open_ai[user.name].client = ::OpenAI::Client.new(access_token: personal_settings[user.name]["ai.open_ai.access_token"].to_s)
38
- elsif general_config.key?(:ai) and general_config[:ai].key?(:open_ai) and general_config[:ai][:open_ai].key?(:access_token) and
39
- general_config[:ai][:open_ai][:access_token] != ""
40
- ai_open_ai[user.name].client = ::OpenAI::Client.new(access_token: general_config[:ai][:open_ai][:access_token])
14
+ ai_open_ai_user = {
15
+ host: general_config._ai.open_ai.host,
16
+ access_token: general_config._ai.open_ai.access_token,
17
+ models: {
18
+ client: nil,
19
+ host: general_config._ai.open_ai.models.host,
20
+ access_token: general_config._ai.open_ai.models.access_token,
21
+ url: general_config._ai.open_ai.models.url,
22
+ api_type: general_config._ai.open_ai.models.api_type,
23
+ api_version: general_config._ai.open_ai.models.api_version,
24
+ },
25
+ chat_gpt: {
26
+ client: nil,
27
+ host: general_config._ai.open_ai.chat_gpt.host,
28
+ access_token: general_config._ai.open_ai.chat_gpt.access_token,
29
+ model: general_config._ai.open_ai.chat_gpt.model,
30
+ smartbot_model: general_config._ai.open_ai.chat_gpt.smartbot_model,
31
+ api_type: general_config._ai.open_ai.chat_gpt.api_type,
32
+ api_version: general_config._ai.open_ai.chat_gpt.api_version,
33
+ fixed_user: general_config._ai.open_ai.chat_gpt.fixed_user, #for testing purposes
34
+ },
35
+ dall_e: {
36
+ client: nil,
37
+ host: general_config._ai.open_ai.dall_e.host,
38
+ access_token: general_config._ai.open_ai.dall_e.access_token,
39
+ image_size: general_config._ai.open_ai.dall_e.image_size,
40
+ model: general_config._ai.open_ai.dall_e.model,
41
+ },
42
+ whisper: {
43
+ client: nil,
44
+ host: general_config._ai.open_ai.whisper.host,
45
+ access_token: general_config._ai.open_ai.whisper.access_token,
46
+ model: general_config._ai.open_ai.whisper.model,
47
+ },
48
+ }
49
+ if personal_settings.key?(team_id_user) and personal_settings[team_id_user].key?("ai.open_ai.host") and
50
+ personal_settings[team_id_user]["ai.open_ai.host"] != ""
51
+ ai_open_ai_user[:host] = personal_settings[team_id_user]["ai.open_ai.host"]
52
+ ai_open_ai_user[:chat_gpt][:host] = ai_open_ai_user[:host]
53
+ ai_open_ai_user[:dall_e][:host] = ai_open_ai_user[:host]
54
+ ai_open_ai_user[:whisper][:host] = ai_open_ai_user[:host]
55
+ ai_open_ai_user[:models][:host] = ai_open_ai_user[:host]
56
+ end
57
+
58
+ if personal_settings.key?(team_id_user) and personal_settings[team_id_user].key?("ai.open_ai.access_token") and
59
+ personal_settings[team_id_user]["ai.open_ai.access_token"] != ""
60
+ ai_open_ai_user[:access_token] = personal_settings[team_id_user]["ai.open_ai.access_token"]
61
+ ai_open_ai_user[:chat_gpt][:access_token] = ai_open_ai_user[:access_token]
62
+ ai_open_ai_user[:dall_e][:access_token] = ai_open_ai_user[:access_token]
63
+ ai_open_ai_user[:whisper][:access_token] = ai_open_ai_user[:access_token]
64
+ ai_open_ai_user[:models][:access_token] = ai_open_ai_user[:access_token]
65
+ end
66
+
67
+ if personal_settings.key?(team_id_user) and personal_settings[team_id_user].key?("ai.open_ai.chat_gpt.model") and
68
+ personal_settings[team_id_user]["ai.open_ai.chat_gpt.model"] != ""
69
+ ai_open_ai_user[:chat_gpt][:model] = personal_settings[team_id_user]["ai.open_ai.chat_gpt.model"]
70
+ end
71
+ if personal_settings.key?(team_id_user) and personal_settings[team_id_user].key?("ai.open_ai.chat_gpt.smartbot_model") and
72
+ personal_settings[team_id_user]["ai.open_ai.chat_gpt.smartbot_model"] != ""
73
+ ai_open_ai_user[:chat_gpt][:smartbot_model] = personal_settings[team_id_user]["ai.open_ai.chat_gpt.smartbot_model"]
74
+ end
75
+
76
+ if personal_settings.key?(team_id_user) and personal_settings[team_id_user].key?("ai.open_ai.whisper.model") and
77
+ personal_settings[team_id_user]["ai.open_ai.whisper.model"] != ""
78
+ ai_open_ai_user[:whisper][:model] = personal_settings[team_id_user]["ai.open_ai.whisper.model"]
79
+ end
80
+ if personal_settings.key?(team_id_user) and personal_settings[team_id_user].key?("ai.open_ai.dall_e.image_size") and
81
+ personal_settings[team_id_user]["ai.open_ai.dall_e.image_size"] != ""
82
+ ai_open_ai_user[:dall_e][:image_size] = personal_settings[team_id_user]["ai.open_ai.dall_e.image_size"]
83
+ end
84
+
85
+ if personal_settings.key?(team_id_user) and personal_settings[team_id_user].key?("ai.open_ai.chat_gpt.host") and
86
+ personal_settings[team_id_user]["ai.open_ai.chat_gpt.host"] != ""
87
+ ai_open_ai_user[:chat_gpt][:host] = personal_settings[team_id_user]["ai.open_ai.chat_gpt.host"]
88
+ end
89
+ if personal_settings.key?(team_id_user) and personal_settings[team_id_user].key?("ai.open_ai.dall_e.host") and
90
+ personal_settings[team_id_user]["ai.open_ai.dall_e.host"] != ""
91
+ ai_open_ai_user[:dall_e][:host] = personal_settings[team_id_user]["ai.open_ai.dall_e.host"]
92
+ end
93
+ if personal_settings.key?(team_id_user) and personal_settings[team_id_user].key?("ai.open_ai.whisper.host") and
94
+ personal_settings[team_id_user]["ai.open_ai.whisper.host"] != ""
95
+ ai_open_ai_user[:whisper][:host] = personal_settings[team_id_user]["ai.open_ai.whisper.host"]
96
+ end
97
+
98
+ if personal_settings.key?(team_id_user) and personal_settings[team_id_user].key?("ai.open_ai.chat_gpt.access_token") and
99
+ personal_settings[team_id_user]["ai.open_ai.chat_gpt.access_token"] != ""
100
+ ai_open_ai_user[:chat_gpt][:access_token] = personal_settings[team_id_user]["ai.open_ai.chat_gpt.access_token"]
101
+ end
102
+ if personal_settings.key?(team_id_user) and personal_settings[team_id_user].key?("ai.open_ai.dall_e.access_token") and
103
+ personal_settings[team_id_user]["ai.open_ai.dall_e.access_token"] != ""
104
+ ai_open_ai_user[:dall_e][:access_token] = personal_settings[team_id_user]["ai.open_ai.dall_e.access_token"]
105
+ end
106
+ if personal_settings.key?(team_id_user) and personal_settings[team_id_user].key?("ai.open_ai.whisper.access_token") and
107
+ personal_settings[team_id_user]["ai.open_ai.whisper.access_token"] != ""
108
+ ai_open_ai_user[:whisper][:access_token] = personal_settings[team_id_user]["ai.open_ai.whisper.access_token"]
109
+ end
110
+
111
+ if personal_settings.key?(team_id_user) and personal_settings[team_id_user].key?("ai.open_ai.chat_gpt.api_type") and
112
+ personal_settings[team_id_user]["ai.open_ai.chat_gpt.api_type"] != ""
113
+ ai_open_ai_user[:chat_gpt][:api_type] = personal_settings[team_id_user]["ai.open_ai.chat_gpt.api_type"]
114
+ end
115
+ if personal_settings.key?(team_id_user) and personal_settings[team_id_user].key?("ai.open_ai.chat_gpt.api_version") and
116
+ personal_settings[team_id_user]["ai.open_ai.chat_gpt.api_version"] != ""
117
+ ai_open_ai_user[:chat_gpt][:api_version] = personal_settings[team_id_user]["ai.open_ai.chat_gpt.api_version"]
118
+ end
119
+ if personal_settings.key?(team_id_user) and personal_settings[team_id_user].key?("ai.open_ai.models.host") and
120
+ personal_settings[team_id_user]["ai.open_ai.models.host"] != ""
121
+ ai_open_ai_user[:models][:host] = personal_settings[team_id_user]["ai.open_ai.models.host"]
122
+ end
123
+ if personal_settings.key?(team_id_user) and personal_settings[team_id_user].key?("ai.open_ai.models.access_token") and
124
+ personal_settings[team_id_user]["ai.open_ai.models.access_token"] != ""
125
+ ai_open_ai_user[:models][:access_token] = personal_settings[team_id_user]["ai.open_ai.models.access_token"]
126
+ end
127
+ if personal_settings.key?(team_id_user) and personal_settings[team_id_user].key?("ai.open_ai.models.url") and
128
+ personal_settings[team_id_user]["ai.open_ai.models.url"] != ""
129
+ ai_open_ai_user[:models][:url] = personal_settings[team_id_user]["ai.open_ai.models.url"]
130
+ end
131
+
132
+ host = ai_open_ai_user[service].host
133
+ access_token = ai_open_ai_user[service].access_token
134
+
135
+ ai_open_ai[team_id_user] ||= ai_open_ai_user.deep_copy
136
+
137
+ if ai_open_ai.key?(team_id_user) and ai_open_ai[team_id_user] != nil and ai_open_ai[team_id_user][service].key?(:client) and
138
+ ai_open_ai[team_id_user][service][:client] != nil and !reconnect
139
+ # do nothing, we already have a client and we don't want to reconnect
140
+ elsif access_token.to_s != ""
141
+ ai_open_ai[team_id_user][service] = ai_open_ai_user[service].deep_copy
142
+ if host == ""
143
+ ai_open_ai[team_id_user][service][:client] = ::OpenAI::Client.new(uri_base: "https://api.openai.com/", access_token: access_token, request_timeout: 300)
144
+ else
145
+ if ai_open_ai_user[service].key?(:url) and ai_open_ai_user[service][:url] != ""
146
+ ai_open_ai[team_id_user][service][:client] = NiceHttp.new(host: host, headers: { 'Authorization': "Bearer #{ai_open_ai_user[service][:access_token]}" }, ssl: true, timeout: (30))
147
+ elsif ai_open_ai_user[service].key?(:api_type) and ai_open_ai_user[service][:api_type] == :openai_azure
148
+ if general_config._ai.open_ai.key?(:testing) and general_config._ai.open_ai.testing #and !general_config.simulate #todo: check
149
+ log = "#{general_config.path}/logs/chat_gpt_azure_#{team_id_user}.log"
150
+ else
151
+ log = :no
152
+ end
153
+ ai_open_ai[team_id_user][service][:client] = NiceHttp.new(host: host, headers: { 'api-key': access_token }, ssl: true, timeout: (30), log: log)
154
+ else
155
+ ai_open_ai[team_id_user][service][:client] = ::OpenAI::Client.new(uri_base: host, access_token: access_token, request_timeout: 300)
156
+ end
157
+ end
41
158
  else
42
- ai_open_ai[user.name] = nil
159
+ ai_open_ai[team_id_user] = nil
43
160
  message = ["You need to set the OpenAI access token in the config file or in the personal settings."]
44
161
  message << "You can get it from https://platform.openai.com/account/api-keys"
45
- message << "Then in case you are a master admin, you can set it in the SmartBot config file:"
46
- message << " `ai: { open_ai: { access_token: 'ACCESS_TOKEN'} }`"
47
162
  message << "If you want to use your personal access token, you can set it on a DM with SmartBot in the personal settings:"
48
- message << " `set personal settings ai.open_ai.access_token ACCESS_TOKEN`"
49
- message << "By default we will be using the gpt_model #{general_config._ai.open_ai.gpt_model}. You can change it in the config file or in personal settings:"
50
- message << " `set personal settings ai.open_ai.gpt_model gpt-4`"
51
- message << "By default we will be using the whisper_model #{general_config._ai.open_ai.whisper_model}. You can change it in the config file or in personal settings:"
52
- message << " `set personal settings ai.open_ai.whisper_model whisper-1`"
53
- message << "You can also change the image size in the config file or in personal settings:"
54
- message << " `set personal settings ai.open_ai.image_size 512x512`"
163
+ message << " `set personal settings ai.open_ai.#{service}.access_token ACCESS_TOKEN`"
164
+ if service == :chat_gpt
165
+ message << "By default we will be using the chatgpt model #{general_config._ai.open_ai.chat_gpt.model}. You can change it in the config file or in personal settings:"
166
+ message << " `set personal settings ai.open_ai.chat_gpt.model gpt-4-0314`"
167
+ message << "For specifying the model for ChatGPT on REPLs: `set personal settings ai.open_ai.chat_gpt.smartbot_model gpt-4-0314`"
168
+ elsif service == :whisper
169
+ message << "By default we will be using the whisper model #{general_config._ai.open_ai.whisper.model}. You can change it in the config file or in personal settings:"
170
+ message << " `set personal settings ai.open_ai.whisper.model whisper-1`"
171
+ elsif service == :dall_e
172
+ message << "You can also change the image size in the config file or in personal settings:"
173
+ message << " `set personal settings ai.open_ai.dall_e.image_size 512x512`"
174
+ end
175
+ message << "In case you are a master admin, you can set it in the SmartBot config file:"
176
+ message << " `ai: { open_ai: { #{service}: { access_token: 'ACCESS_TOKEN'} } }`"
55
177
  return ai_open_ai, message.join("\n")
56
178
  end
57
- return ai_open_ai, ''
179
+ return ai_open_ai, ""
58
180
  end
59
181
  end
60
182
  end
@@ -1,20 +1,72 @@
1
1
  class SlackSmartBot
2
2
  module AI
3
3
  module OpenAI
4
- def self.models(open_ai_client, model='')
4
+ def self.models(open_ai_client, models_config, model='', return_response: false)
5
5
  require "openai"
6
+ require 'amazing_print'
6
7
  user = Thread.current[:user]
7
- if model.empty?
8
- response = open_ai_client.models.list
9
- result = response.body.json().data.id.sort.join("\n")
8
+ if model.empty? or model == 'chatgpt'
9
+ if open_ai_client.is_a?(NiceHttp) and models_config.url != ""
10
+ resp = open_ai_client.get(models_config.url)
11
+ models = resp.body.json(:model_name)
12
+ models.select!{|i| i.include?('gpt-')} if model == 'chatgpt'
13
+ elsif open_ai_client.is_a?(NiceHttp) #azure
14
+ resp = open_ai_client.get("/openai/deployments?api-version=#{models_config.api_version}")
15
+ models = resp.body.json(:id)
16
+ models.select!{|i| i.include?('gpt-')} if model == 'chatgpt'
17
+ else
18
+ response = open_ai_client.models.list
19
+ models = []
20
+ response.data.each do |model|
21
+ models << model["id"]
22
+ end
23
+ models.select!{|i| i.include?('gpt-')} if model == 'chatgpt'
24
+ end
25
+ if return_response
26
+ return models.uniq.sort
27
+ else
28
+ return models.uniq.sort.join("\n")
29
+ end
10
30
  else
11
- response = open_ai_client.models.retrieve(id: model)
12
- result = response.body
31
+ response_obj = {}
32
+ if open_ai_client.is_a?(NiceHttp) and models_config.url != ""
33
+ resp = open_ai_client.get(models_config.url)
34
+ result = {}
35
+ resp.data.json.data.each do |m|
36
+ if m[:model_name].to_s == model
37
+ result = m
38
+ break
39
+ end
40
+ end
41
+ if result.empty?
42
+ response = {message: "Model not found"}
43
+ response_obj = response
44
+ else
45
+ response = {message: ''}
46
+ result[:model_info].each do |k,v|
47
+ response.message += "#{k}: #{v}\n"
48
+ end
49
+ response_obj = result[:model_info]
50
+ end
51
+ elsif open_ai_client.is_a?(NiceHttp) #azure
52
+ resp = open_ai_client.get("/openai/deployments/#{model}?api-version=#{models_config.api_version}")
53
+ response = resp.body.json()
54
+ response_obj = response
55
+ else
56
+ response = open_ai_client.models.retrieve(id: model)
57
+ response_obj = response
58
+ end
59
+ result = response.ai
13
60
  end
14
- if !response.body.json(:message).empty? and response.body.json(:content).empty?
15
- result = response.body.json(:message)
61
+ response = response.to_json
62
+ if !response.json(:message).empty? and response.json(:content).empty?
63
+ result = response.json(:message)
64
+ end
65
+ if return_response
66
+ return response_obj
67
+ else
68
+ return result
16
69
  end
17
- return result
18
70
  end
19
71
  end
20
72
  end
@@ -1,21 +1,77 @@
1
1
  class SlackSmartBot
2
2
  module AI
3
3
  module OpenAI
4
- def self.send_gpt_chat(open_ai_client, model, message)
4
+ def self.send_gpt_chat(open_ai_client, model, message, chat_gpt_config)
5
5
  require "openai"
6
+ require 'nice_http'
6
7
  user = Thread.current[:user]
7
- response = open_ai_client.chat(
8
- parameters: {
9
- model: model, # Required.
10
- messages: [{ role: "user", content: message }], # Required.
11
- temperature: 0.7,
12
- },
13
- )
14
- if !response.body.json(:message).empty? and response.body.json(:content).empty?
15
- result = response.body.json(:message)
8
+ if user.key?(:sso_user_name)
9
+ user_name = user.sso_user_name
10
+ else
11
+ user_name = user.name
12
+ end
13
+ parameters = {
14
+ model: model, # Required.
15
+ messages: [{ role: "user", content: message }], # Required.
16
+ temperature: 0.7,
17
+ user: user_name
18
+ }
19
+ parameters.user = chat_gpt_config.fixed_user if chat_gpt_config.fixed_user.to_s != ""
20
+ if open_ai_client.is_a?(NiceHttp)
21
+ begin
22
+ response = {}
23
+ tries = 0
24
+ while (!response.key?(:data) or response.data.nil? or response.data.empty? ) and tries < 10
25
+ begin
26
+ request = {
27
+ path: "/openai/deployments/#{model}/chat/completions?api-version=#{chat_gpt_config.api_version}",
28
+ data: parameters
29
+ }
30
+ response = open_ai_client.post(request)
31
+ rescue Exception => exception
32
+ response = {message: exception.message}.to_json
33
+ end
34
+ tries += 1
35
+ sleep 1 if !response.key?(:data) or response.data.nil? or response.data.empty? #wait a second before trying again
36
+ end
37
+ response.data = { message: ""}.to_json if !response.key?(:data) or response.data.nil? or response.data.empty?
38
+ response = response.data
39
+ rescue Exception => exception
40
+ response = {message: exception.message}.to_json
41
+ end
42
+ else
43
+ begin
44
+ response = open_ai_client.chat(parameters: parameters)
45
+ response = response.to_json
46
+ rescue Exception => e
47
+ response = e.response
48
+ if !response.nil? and response.status == 403 and response.body.error.message.to_s.include?("You must pass a valid 'user'")
49
+ response.body.error.message += "\nThe user on Slack is: #{user.name}\nYou have to go to your Profile Slack Account on a browser. Then go to Settings.\nNow go to Username and click on expand, change the name to your SSO name and click on Save"
50
+ end
51
+ if response.nil?
52
+ response = {message: e.message}
53
+ else
54
+ response = response.to_json
55
+ end
56
+ end
57
+ end
58
+ if response.nil?
59
+ result = "No response from the AI. Please contact the SmartBot administrator."
60
+ return false, result
61
+ elsif response.is_a?(Hash) and response.key?(:message) and !response.key?(:content)
62
+ result = response[:message]
63
+ return false, result
64
+ elsif !response.json(:message).empty? and response.json(:content).empty?
65
+ result = response.json(:message)
66
+ return false, result
67
+ elsif !response.json(:error).empty? and !response.json(:code).empty?
68
+ result = response.json(:code)
69
+ return false, result
70
+ elsif !response.json(:error).empty?
71
+ result = response.json(:error).to_s
16
72
  return false, result
17
73
  else
18
- result = response.body.json(:content)
74
+ result = response.json(:content)
19
75
  return true, result
20
76
  end
21
77
  end
@@ -11,10 +11,11 @@ class SlackSmartBot
11
11
  else
12
12
  response = open_api_client.images.edit(parameters: { image: image, prompt: message, size: size })
13
13
  end
14
- if !response.body.json(:message).empty?
15
- return false, "*OpenAI*: #{response.body.json(:message)}"
14
+ response = response.to_json
15
+ if !response.json(:message).empty?
16
+ return false, "*OpenAI*: #{response.json(:message)}"
16
17
  else
17
- urls = [response.body.json(:url)].flatten
18
+ urls = [response.json(:url)].flatten
18
19
  return true, urls
19
20
  end
20
21
  end
@@ -4,12 +4,12 @@ class SlackSmartBot
4
4
  def self.send_image_generation(open_ai_client, message, image_size)
5
5
  require "openai"
6
6
  user = Thread.current[:user]
7
- #todo: personal settings size #Jal
8
7
  response = open_ai_client.images.generate(parameters: { prompt: message, size: image_size })
9
- if !response.body.json(:message).empty?
10
- return false, "*OpenAI*: #{response.body.json(:message)}"
8
+ response = response.to_json
9
+ if !response.json(:message).empty?
10
+ return false, "*OpenAI*: #{response.json(:message)}"
11
11
  else
12
- urls = [response.body.json(:url)].flatten
12
+ urls = response.json(:url)
13
13
  return true, urls
14
14
  end
15
15
  end
@@ -10,10 +10,11 @@ class SlackSmartBot
10
10
  else
11
11
  response = open_ai_client.images.variations(parameters: { image: image, n: variations, size: size })
12
12
  end
13
- if !response.body.json(:message).empty?
14
- return false, "*OpenAI*: #{response.body.json(:message)}"
13
+ response = response.to_json
14
+ if !response.json(:message).empty?
15
+ return false, "*OpenAI*: #{response.json(:message)}"
15
16
  else
16
- urls = [response.body.json(:url)].flatten
17
+ urls = [response.json(:url)].flatten
17
18
  return true, urls
18
19
  end
19
20
  end
@@ -10,10 +10,11 @@ class SlackSmartBot
10
10
  file: File.open(file, "rb"),
11
11
  },
12
12
  )
13
- if !response.body.json(:message).empty?
14
- return false, response.body.json(:message)
13
+ response = response.to_json
14
+ if !response.json(:message).empty?
15
+ return false, response.json(:message)
15
16
  else
16
- return true, response.body.json(:text)
17
+ return true, response.json(:text)
17
18
  end
18
19
  end
19
20
  end
@@ -8,18 +8,30 @@ class SlackSmartBot
8
8
  dest = Thread.current[:dest]
9
9
  end
10
10
  if to.nil?
11
- to = Thread.current[:user].name
11
+ to = Thread.current[:team_id_user]
12
12
  end
13
13
  if context.nil?
14
14
  context = Thread.current[:command]
15
15
  end
16
- message = "#{to}: #{question}"
16
+ #remove the team_id from the user to
17
+ if to.is_a?(String)
18
+ if to.match?(/^[A-Z0-9]{7,11}_/)
19
+ to_name = to.split('_')[1..-1].join('_')
20
+ else
21
+ to_name = to
22
+ to = "#{config.team_id}_#{to}"
23
+ end
24
+ else
25
+ to_name = to.name
26
+ to = "#{to.team_id}_#{to.name}"
27
+ end
28
+ message = "#{to_name}: #{question}"
17
29
  if dest.nil?
18
30
  if config[:simulate]
19
31
  open("#{config.path}/buffer_complete.log", "a") { |f|
20
- f.puts "|#{@channel_id}|#{config[:nick_id]}|#{config[:nick]}|#{message}~~~"
32
+ f.puts "|#{@channel_id}|#{Thread.current[:thread_ts]}|#{config[:nick_id]}|#{config[:nick]}|#{message}~~~"
21
33
  }
22
- else
34
+ else
23
35
  if Thread.current[:on_thread]
24
36
  client.message(channel: @channel_id, text: message, as_user: true, thread_ts: Thread.current[:thread_ts])
25
37
  else
@@ -29,15 +41,15 @@ class SlackSmartBot
29
41
  if config[:testing] and config.on_master_bot and !@buffered
30
42
  @buffered = true
31
43
  open("#{config.path}/buffer.log", "a") { |f|
32
- f.puts "|#{@channel_id}|#{config[:nick_id]}|#{config[:nick]}|#{message}"
44
+ f.puts "|#{@channel_id}|#{Thread.current[:thread_ts]}|#{config[:nick_id]}|#{config[:nick]}|#{message}"
33
45
  }
34
46
  end
35
47
  elsif dest[0] == "C" or dest[0] == "G" # channel
36
48
  if config[:simulate]
37
49
  open("#{config.path}/buffer_complete.log", "a") { |f|
38
- f.puts "|#{dest}|#{config[:nick_id]}|#{config[:nick]}|#{message}~~~"
50
+ f.puts "|#{dest}|#{Thread.current[:thread_ts]}|#{config[:nick_id]}|#{config[:nick]}|#{message}~~~"
39
51
  }
40
- else
52
+ else
41
53
  if Thread.current[:on_thread]
42
54
  client.message(channel: dest, text: message, as_user: true, thread_ts: Thread.current[:thread_ts])
43
55
  else
@@ -47,7 +59,7 @@ class SlackSmartBot
47
59
  if config[:testing] and config.on_master_bot and !@buffered
48
60
  @buffered = true
49
61
  open("#{config.path}/buffer.log", "a") { |f|
50
- f.puts "|#{dest}|#{config[:nick_id]}|#{config[:nick]}|#{message}"
62
+ f.puts "|#{dest}|#{Thread.current[:thread_ts]}|#{config[:nick_id]}|#{config[:nick]}|#{message}"
51
63
  }
52
64
  end
53
65
  elsif dest[0] == "D" #private message
@@ -10,8 +10,8 @@ class SlackSmartBot
10
10
  if typem==:on_extended
11
11
  get_bots_created()
12
12
  end
13
- text = get_help(rules_file, dest, user.name, typem==:on_extended, true)
14
-
13
+ text = get_help(rules_file, dest, user, typem==:on_extended, true)
14
+
15
15
  ff = text.scan(/^\s*`\s*([^`]+)\s*`\s*$/i).flatten
16
16
  ff.delete("!THE_COMMAND")
17
17
  ff.delete("@NAME_OF_BOT THE_COMMAND")
@@ -1,5 +1,10 @@
1
1
  class SlackSmartBot
2
2
  def event_hello()
3
+
4
+ if config.on_master_bot
5
+ File.open("#{config.path}/status/version.txt", 'w') {|f| f.write(VERSION) }
6
+ end
7
+
3
8
  @first_time_bot_started ||= true
4
9
  unless config.simulate
5
10
  m = "Successfully connected, welcome '#{client.self.name}' to the '#{client.team.name}' team at https://#{client.team.domain}.slack.com."
@@ -9,6 +14,30 @@ class SlackSmartBot
9
14
  @logger.info m
10
15
  config.nick = client.self.name
11
16
  config.nick_id = client.self.id
17
+ if config.granular_token.empty?
18
+ config.nick_granular = ""
19
+ config.nick_id_granular = ""
20
+ else
21
+ conn_granular = NiceHttp.new(host: "https://slack.com", log: :no)
22
+ conn_granular.headers = { authorization: "Bearer #{config.granular_token}" }
23
+ resp = conn_granular.get("/api/auth.test")
24
+ if resp.code.to_s == '200' and resp.body.json(:ok) == true
25
+ config.nick_granular = resp.body.json(:user)
26
+ config.nick_id_granular = resp.body.json(:user_id)
27
+ else
28
+ config.nick_granular = ""
29
+ config.nick_id_granular = ""
30
+ end
31
+ conn_granular.close
32
+ end
33
+ if client.team.key?(:enterprise_id)
34
+ config.team_id = client.team.enterprise_id
35
+ config.team_name = client.team.enterprise_name
36
+ else
37
+ config.team_id = client.team.id
38
+ config.team_name = client.team.name
39
+ end
40
+ config.team_domain = client.team.domain
12
41
  end
13
42
  @salutations = [config[:nick], "<@#{config[:nick_id]}>", "@#{config[:nick]}", "bot", "smart", "smartbot", "smart-bot", "smart bot"]
14
43
 
@@ -33,4 +62,4 @@ class SlackSmartBot
33
62
  end
34
63
  @first_time_bot_started = false
35
64
  end
36
- end
65
+ end
@@ -13,7 +13,8 @@ class SlackSmartBot
13
13
  end
14
14
  rescue Exception => stack
15
15
  @logger.warn stack
16
+ return []
16
17
  end
17
18
 
18
19
  end
19
- end
20
+ end
@@ -15,6 +15,7 @@ class SlackSmartBot
15
15
  end
16
16
  rescue Exception => stack
17
17
  @logger.warn stack
18
+ return {presence: "unknown"}
18
19
  end
19
20
  end
20
21
  end
@@ -0,0 +1,10 @@
1
+ class SlackSmartBot
2
+ def get_smartbot_team_info(token=nil)
3
+ token = config.token if token.nil?
4
+ client_web = Slack::Web::Client.new(token: token)
5
+ client_web.auth_test
6
+ resp = client_web.team_info
7
+ client_web = nil
8
+ return resp
9
+ end
10
+ end