Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Require api_url for setting up slack bot #125

Merged
merged 5 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ The Reginald project consists of:

```
├── azure
│   └── Setup REGinald infrastructure on Azure
│   └── scripts to setup Reginald infrastructure on Azure
├── data
│   └── Directory to store llama-index data indexes and other public Turing data
│   └── directory to store llama-index data indexes and other public Turing data
├── docker
│   └── Scripts for building a Docker images for both Reginald app and Slack-bot only app
│   └── scripts for building a Docker images for both Reginald app and Slack-bot only app
├── notebooks
│   └── data processing notebooks
│   └── development notebooks for llama-index REGinald models
│   └── development notebooks for llama-index Reginald models
└── reginald
└── models: scripts for setting up query and chat engines
└── slack_bot: scripts for setting up Slack bot
Expand Down
217 changes: 82 additions & 135 deletions poetry.lock

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ authors = ["Evelina Gabasova <[email protected]>",
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.11"
python = ">=3.11,<3.12"
accelerate = "^0.23.0"
bitsandbytes = { version="^0.41.1", optional=true }
datasets = { version="^2.12.0", optional=true }
Expand All @@ -26,10 +26,10 @@ gitpython = "^3.1.36"
gradio = { version="^3.34.0", optional=true }
httpx = { version="^0.25.0", optional=true }
ipykernel = { version="^6.23.2", optional=true }
langchain = "^0.0.294"
llama-cpp-python = "^0.2.7"
llama-index = "^0.8.29.post1"
llama-hub = "^0.0.31"
langchain = "^0.0.327"
llama-cpp-python = "^0.2.11"
llama-index = "^0.8.57"
llama-hub = "^0.0.42"
nbconvert = {version = "^7.8.0", optional = true}
nest_asyncio = "^1.5.8"
openai = "^0.27.8"
Expand Down
4 changes: 2 additions & 2 deletions reginald/models/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ def main():
- /direct_message: for obtaining responses from direct messages
- /channel_mention: for obtaining responses from channel mentions
"""
# Parse command line arguments
# parse command line arguments
parser = Parser()

# pass args to setup_llm
llm_kwargs = vars(parser.parse_args())

# Initialise logging
# initialise logging
logging.basicConfig(
datefmt=r"%Y-%m-%d %H:%M:%S",
format="%(asctime)s [%(levelname)8s] %(message)s",
Expand Down
6 changes: 2 additions & 4 deletions reginald/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,15 @@
from reginald.slack_bot.setup_bot import setup_slack_bot, setup_slack_client
from reginald.utils import Parser

API_URL = "http://127.0.0.1:8000"


async def main():
# Parse command line arguments
# parse command line arguments
parser = Parser()

# pass args to setup_llm
llm_kwargs = vars(parser.parse_args())

# Initialise logging
# initialise logging
logging.basicConfig(
datefmt=r"%Y-%m-%d %H:%M:%S",
format="%(asctime)s [%(levelname)8s] %(message)s",
Expand Down
48 changes: 24 additions & 24 deletions reginald/slack_bot/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@ async def __call__(self, client: SocketModeClient, req: SocketModeRequest) -> No
Slack request
"""
if req.type == "events_api":
# Acknowledge the request
# acknowledge the request
logging.info("Received an events_api request")
response = SocketModeResponse(envelope_id=req.envelope_id)
await client.send_socket_mode_response(response)

try:
# Extract event from payload
# extract event from payload
event = req.payload["event"]

# Ignore messages from bots
# ignore messages from bots
if event.get("bot_id") is not None:
logging.info("Ignoring an event triggered by a bot.")
return
Expand Down Expand Up @@ -80,13 +80,13 @@ async def __call__(self, client: SocketModeClient, req: SocketModeRequest) -> No
raise

elif req.type == "slash_commands":
# Acknowledge the request
# acknowledge the request
logging.info("Received an slash_commands request")
response = SocketModeResponse(envelope_id=req.envelope_id)
await client.send_socket_mode_response(response)

try:
# Extract command, user, etc from payload
# extract command, user, etc from payload
command = req.payload["command"]
user_id = req.payload["user_id"]

Expand Down Expand Up @@ -137,7 +137,7 @@ async def worker(self, queue: asyncio.Queue) -> None:
while True:
(client, event) = await queue.get()
await self._process_request(client, event)
# Notify the queue that the "work item" has been processed.
# notify the queue that the "work item" has been processed.
queue.task_done()

async def _process_request(
Expand All @@ -155,13 +155,13 @@ async def _process_request(
req : SocketModeRequest
Slack request
"""
# Extract user and message information
# extract user and message information
message = event["text"]
user_id = event["user"]
event_type = event["type"]
event_subtype = event.get("subtype", None)

# Start processing the message
# start processing the message
logging.info(f"Processing message '{message}' from user '{user_id}'.")

await client.web_client.reactions_remove(
Expand All @@ -170,26 +170,26 @@ async def _process_request(
timestamp=event["ts"],
)

# If this is a direct message to REGinald...
# if this is a direct message to Reginald...
if event_type == "message" and event_subtype is None:
await self.react(client, event["channel"], event["ts"])
model_response = await asyncio.get_running_loop().run_in_executor(
None, self.model.direct_message, message, user_id
)

# If @REGinald is mentioned in a channel
# if @Reginald is mentioned in a channel
elif event_type == "app_mention":
await self.react(client, event["channel"], event["ts"])
model_response = await asyncio.get_running_loop().run_in_executor(
None, self.model.channel_mention, message, user_id
)

# Otherwise
# otherwise
else:
logging.info(f"Received unexpected event of type '{event['type']}'.")
return

# Add a reply as required
# add a reply as required
if model_response and model_response.message:
logging.info(f"Posting reply {model_response.message}.")
await client.web_client.chat_postMessage(
Expand Down Expand Up @@ -256,16 +256,16 @@ async def __call__(self, client: SocketModeClient, req: SocketModeRequest) -> No
Slack request
"""
if req.type == "events_api":
# Acknowledge the request
# acknowledge the request
logging.info("Received an events_api request")
response = SocketModeResponse(envelope_id=req.envelope_id)
await client.send_socket_mode_response(response)

try:
# Extract event from payload
# extract event from payload
event = req.payload["event"]

# Ignore messages from bots
# ignore messages from bots
if event.get("bot_id") is not None:
logging.info("Ignoring an event triggered by a bot.")
return
Expand Down Expand Up @@ -298,13 +298,13 @@ async def __call__(self, client: SocketModeClient, req: SocketModeRequest) -> No
raise

elif req.type == "slash_commands":
# Acknowledge the request
# acknowledge the request
logging.info("Received an slash_commands request")
response = SocketModeResponse(envelope_id=req.envelope_id)
await client.send_socket_mode_response(response)

try:
# Extract command, user, etc from payload
# extract command, user, etc from payload
command = req.payload["command"]
user_id = req.payload["user_id"]

Expand Down Expand Up @@ -355,7 +355,7 @@ async def worker(self, queue: asyncio.Queue) -> None:
while True:
(client, event) = await queue.get()
await self._process_request(client, event)
# Notify the queue that the "work item" has been processed.
# notify the queue that the "work item" has been processed.
queue.task_done()

async def _process_request(
Expand All @@ -373,13 +373,13 @@ async def _process_request(
req : SocketModeRequest
Slack request
"""
# Extract user and message information
# extract user and message information
message = event["text"]
user_id = event["user"]
event_type = event["type"]
event_subtype = event.get("subtype", None)

# Start processing the message
# start processing the message
logging.info(f"Processing message '{message}' from user '{user_id}'.")

await client.web_client.reactions_remove(
Expand All @@ -388,7 +388,7 @@ async def _process_request(
timestamp=event["ts"],
)

# If this is a direct message to REGinald...
# if this is a direct message to Reginald...
if event_type == "message" and event_subtype is None:
await self.react(client, event["channel"], event["ts"])
model_response = await asyncio.get_running_loop().run_in_executor(
Expand All @@ -399,7 +399,7 @@ async def _process_request(
),
)

# If @REGinald is mentioned in a channel
# if @Reginald is mentioned in a channel
elif event_type == "app_mention":
await self.react(client, event["channel"], event["ts"])
model_response = await asyncio.get_running_loop().run_in_executor(
Expand All @@ -410,7 +410,7 @@ async def _process_request(
),
)

# Otherwise
# otherwise
else:
logging.info(f"Received unexpected event of type '{event['type']}'.")
return
Expand All @@ -419,7 +419,7 @@ async def _process_request(
raise ValueError("Unable to get response.")
model_response = model_response.json()

# Add a reply as required
# add a reply as required
if model_response and model_response["message"]:
logging.info(f"Posting reply {model_response['message']}.")
await client.web_client.chat_postMessage(
Expand Down
38 changes: 24 additions & 14 deletions reginald/slack_bot/setup_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@
from reginald.models.models.base import ResponseModel
from reginald.slack_bot.bot import ApiBot, Bot

# mb set this as env variable
API_URL = "http://0.0.0.0:8000"


def setup_slack_bot(model: ResponseModel) -> Bot:
"""
Expand All @@ -30,7 +27,7 @@ def setup_slack_bot(model: ResponseModel) -> Bot:
"""
logging.info(f"Initalising bot with model: {model}")

slack_bot = Bot(model)
slack_bot = Bot(model=model)

logging.info("Connecting to Slack...")
if os.environ.get("SLACK_APP_TOKEN") is None:
Expand All @@ -40,7 +37,7 @@ def setup_slack_bot(model: ResponseModel) -> Bot:
return slack_bot


def setup_api_slack_bot(emoji: str) -> ApiBot:
def setup_api_slack_bot(api_url: str, emoji: str) -> ApiBot:
"""
Initialise `ApiBot` with response model.

Expand All @@ -54,11 +51,11 @@ def setup_api_slack_bot(emoji: str) -> ApiBot:
ApiBot
Bot which uses an API for responding to messages
"""
logging.info(f"Initalising bot at {API_URL}")
logging.info(f"Initalising bot at {api_url}")
logging.info(f"Initalising bot with {emoji} emoji")

# set up bot with the API_URL and emoji
slack_bot = ApiBot(API_URL, emoji)
# set up bot with the api_url and emoji
slack_bot = ApiBot(api_url=api_url, emoji=emoji)

logging.info("Connecting to Slack...")
if os.environ.get("SLACK_APP_TOKEN") is None:
Expand Down Expand Up @@ -116,8 +113,14 @@ async def main():
then establishes a WebSocket connection to the
Socket Mode servers and listens for events.
"""
# Parse command line arguments
# parse command line arguments
parser = argparse.ArgumentParser()
parser.add_argument(
"--api-url",
"-a",
help="Select the API URL for the model",
default=os.environ.get("REGINALD_API_URL"),
)
parser.add_argument(
"--emoji",
"-e",
Expand All @@ -126,23 +129,30 @@ async def main():
)
args = parser.parse_args()

# Initialise logging
if args.api_url is None:
logging.error(
"API URL is not set. Please set the REGINALD_API_URL "
"environment variable or pass in the --api-url argument"
)
sys.exit(1)

# initialise logging
logging.basicConfig(
datefmt=r"%Y-%m-%d %H:%M:%S",
format="%(asctime)s [%(levelname)8s] %(message)s",
level=logging.INFO,
)

# set up slack bot
bot = setup_api_slack_bot(args.emoji)
bot = setup_api_slack_bot(api_url=args.api_url, emoji=args.emoji)

# set up slack client
client = setup_slack_client(bot)
client = setup_slack_client(slack_bot=bot)

# Establish a WebSocket connection to the Socket Mode servers
# establish a WebSocket connection to the Socket Mode servers
await client.connect()

# Listen for events
# listen for events
logging.info("Listening for requests...")
await asyncio.sleep(float("inf"))

Expand Down