Skip to content

Commit dfc393f

Browse files
authored
Merge pull request #58 from alan-turing-institute/emoji-before-processing
Emoji react before processing the response
2 parents 21fc710 + 1e58c52 commit dfc393f

File tree

5 files changed

+63
-44
lines changed

5 files changed

+63
-44
lines changed

slack_bot/slack_bot/bot/bot.py

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Standard library imports
22
import logging
3+
from typing import Optional
34

45
# Third-party imports
56
from slack_sdk.socket_mode import SocketModeClient
@@ -21,57 +22,57 @@ def __call__(self, client: SocketModeClient, req: SocketModeRequest) -> None:
2122
return None
2223

2324
# Acknowledge the request
25+
logging.info(f"Received an events_api request")
2426
response = SocketModeResponse(envelope_id=req.envelope_id)
2527
client.send_socket_mode_response(response)
2628

2729
try:
28-
# Extract user and message information
30+
# Extract event from payload
2931
event = req.payload["event"]
32+
sender_is_bot = "bot_id" in event
33+
34+
# Ignore messages from bots
35+
if sender_is_bot:
36+
logging.info(f"Ignoring an event triggered by a bot.")
37+
return None
38+
39+
# Extract user and message information
3040
message = event["text"]
3141
user_id = event["user"]
3242
event_type = event["type"]
3343
event_subtype = event.get("subtype", None)
34-
sender_is_bot = "bot_id" in event
3544

3645
# Ignore changes to messages.
3746
if event_type == "message" and event_subtype == "message_changed":
38-
logging.info(f"Ignoring changes to messages.")
47+
logging.info(f"Ignoring a change to a message.")
3948
return None
4049

41-
logging.info(f"Received message '{message}' from user '{user_id}'")
42-
43-
# Ignore messages from bots
44-
if sender_is_bot:
45-
logging.info(f"Ignoring messages from bots.")
46-
return None
50+
# Start processing the message
51+
logging.info(f"Processing message '{message}' from user '{user_id}'.")
4752

4853
# If this is a direct message to REGinald...
4954
if event_type == "message" and event_subtype is None:
55+
self.react(client, event["channel"], event["ts"])
5056
model_response = self.model.direct_message(message, user_id)
5157

5258
# If @REGinald is mentioned in a channel
5359
elif event_type == "app_mention":
60+
self.react(client, event["channel"], event["ts"])
5461
model_response = self.model.channel_mention(message, user_id)
5562

5663
# Otherwise
5764
else:
58-
logging.info(f"Received unexpected event of type '{event['type']}'")
65+
logging.info(f"Received unexpected event of type '{event['type']}'.")
5966
return None
6067

6168
# Add an emoji and a reply as required
62-
if model_response:
63-
if model_response.emoji:
64-
logging.info(f"Applying emoji {model_response.emoji}")
65-
client.web_client.reactions_add(
66-
name=model_response.emoji,
67-
channel=event["channel"],
68-
timestamp=event["ts"],
69-
)
70-
if model_response.message:
71-
logging.info(f"Posting reply {model_response.message}")
72-
client.web_client.chat_postMessage(
73-
channel=event["channel"], text=model_response.message
74-
)
69+
if model_response and model_response.message:
70+
logging.info(f"Posting reply {model_response.message}.")
71+
client.web_client.chat_postMessage(
72+
channel=event["channel"], text=model_response.message
73+
)
74+
else:
75+
logging.info(f"No reply was generated.")
7576

7677
except KeyError as exc:
7778
logging.warning(f"Attempted to access key that does not exist.\n{str(exc)}")
@@ -81,3 +82,15 @@ def __call__(self, client: SocketModeClient, req: SocketModeRequest) -> None:
8182
f"Something went wrong in processing a Slack request.\nPayload: {req.payload}.\n{str(exc)}"
8283
)
8384
raise
85+
86+
def react(self, client: SocketModeClient, channel: str, timestamp: str) -> None:
87+
"""Emoji react to the input message"""
88+
if self.model.emoji:
89+
logging.info(f"Reacting with emoji {self.model.emoji}.")
90+
client.web_client.reactions_add(
91+
name=self.model.emoji,
92+
channel=channel,
93+
timestamp=timestamp,
94+
)
95+
else:
96+
logging.info(f"No emoji defined for this model.")

slack_bot/slack_bot/models/base.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@
44

55

66
class MessageResponse:
7-
def __init__(self, message: Optional[str], emoji: Optional[str]) -> None:
7+
def __init__(self, message: Optional[str]) -> None:
88
self.message = message
9-
self.emoji = emoji
109

1110

1211
class ResponseModel(ABC):
13-
def __init__(self, *args: Any, **kwargs: Any):
14-
pass
12+
def __init__(self, emoji: Optional[str], *args: Any, **kwargs: Any):
13+
self.emoji = emoji
1514

1615
def direct_message(self, message: str, user_id: str) -> MessageResponse:
1716
"""When the strategy receives a message it should return a MessageResponse where both are optional"""

slack_bot/slack_bot/models/chat_completion.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@
99
from .base import MessageResponse, ResponseModel
1010

1111

12-
class ChatCompletionAzure(ResponseModel):
13-
def __init__(self, **kwargs: Any) -> None:
12+
class ChatCompletionBase(ResponseModel):
13+
def __init__(self, *args, **kwargs) -> None:
14+
super().__init__(emoji="books")
15+
16+
17+
class ChatCompletionAzure(ChatCompletionBase):
18+
def __init__(self, *args: Any, **kwargs: Any) -> None:
19+
super().__init__(*args, **kwargs)
1420
self.api_base = os.getenv("OPENAI_AZURE_API_BASE")
1521
self.api_key = os.getenv("OPENAI_AZURE_API_KEY")
1622
self.api_type = "azure"
@@ -39,8 +45,7 @@ def direct_message(self, message: str, user_id: str) -> MessageResponse:
3945
temperature=self.temperature,
4046
top_p=self.top_p,
4147
)
42-
text = response["choices"][0]["text"]
43-
return MessageResponse(text, "open_hands")
48+
return MessageResponse(response["choices"][0]["text"])
4449

4550
def channel_mention(self, message: str, user_id: str) -> MessageResponse:
4651
openai.api_base = self.api_base
@@ -58,26 +63,24 @@ def channel_mention(self, message: str, user_id: str) -> MessageResponse:
5863
temperature=self.temperature,
5964
top_p=self.top_p,
6065
)
61-
text = response["choices"][0]["text"]
62-
return MessageResponse(text, "open_hands")
66+
return MessageResponse(response["choices"][0]["text"])
6367

6468

65-
class ChatCompletionOpenAI(ResponseModel):
66-
def __init__(self, **kwargs) -> None:
69+
class ChatCompletionOpenAI(ChatCompletionBase):
70+
def __init__(self, *args: Any, **kwargs: Any) -> None:
71+
super().__init__(*args, **kwargs)
6772
self.api_key = os.getenv("OPENAI_API_KEY")
6873

6974
def direct_message(self, message: str, user_id: str) -> MessageResponse:
7075
openai.api_key = self.api_key
7176
response = openai.ChatCompletion.create(
7277
model="gpt-3.5-turbo", messages=[{"role": "user", "content": message}]
7378
)
74-
text = response["choices"][0]["message"]["content"]
75-
return MessageResponse(text, "open_hands")
79+
return MessageResponse(response["choices"][0]["message"]["content"])
7680

7781
def channel_mention(self, message: str, user_id: str) -> MessageResponse:
7882
openai.api_key = self.api_key
7983
response = openai.ChatCompletion.create(
8084
model="gpt-3.5-turbo", messages=[{"role": "user", "content": message}]
8185
)
82-
text = response["choices"][0]["message"]["content"]
83-
return MessageResponse(text, "open_hands")
86+
return MessageResponse(response["choices"][0]["message"]["content"])

slack_bot/slack_bot/models/hello.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22

33

44
class Hello(ResponseModel):
5+
def __init__(self):
6+
super().__init__(emoji="wave")
7+
58
def direct_message(self, message: str, user_id: str) -> MessageResponse:
6-
return MessageResponse(None, "tada")
9+
return MessageResponse("Let's discuss this in a channel!")
710

811
def channel_mention(self, message: str, user_id: str) -> MessageResponse:
9-
return MessageResponse(f"Hello <@{user_id}>", "+1")
12+
return MessageResponse(f"Hello <@{user_id}>")

slack_bot/slack_bot/models/llama.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,12 @@ def __init__(
6060
max_input_size: int,
6161
data_dir: pathlib.Path,
6262
which_index: str,
63-
num_output: int = 256,
6463
chunk_size_limit: Optional[int] = None,
6564
chunk_overlap_ratio: float = 0.1,
6665
force_new_index: bool = False,
66+
num_output: int = 256,
6767
) -> None:
68+
super().__init__(emoji="llama")
6869
logging.info("Setting up Huggingface backend.")
6970
self.max_input_size = max_input_size
7071
self.model_name = model_name
@@ -214,11 +215,11 @@ def _prep_llm_predictor(self) -> LLMPredictor:
214215

215216
def direct_message(self, message: str, user_id: str) -> MessageResponse:
216217
backend_response = self._get_response(message, user_id)
217-
return MessageResponse(backend_response, "llama")
218+
return MessageResponse(backend_response)
218219

219220
def channel_mention(self, message: str, user_id: str) -> MessageResponse:
220221
backend_response = self._get_response(message, user_id)
221-
return MessageResponse(backend_response, "llama")
222+
return MessageResponse(backend_response)
222223

223224

224225
class LlamaDistilGPT2(Llama):

0 commit comments

Comments
 (0)