slack-smart-bot 1.14.1 → 1.15.0

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.
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