Skip to content

Commit

Permalink
feat/human_in_loop added
Browse files Browse the repository at this point in the history
  • Loading branch information
Prat011 committed Aug 21, 2024
1 parent 36cd36d commit a5939f1
Show file tree
Hide file tree
Showing 5 changed files with 247 additions and 0 deletions.
1 change: 1 addition & 0 deletions python/examples/human_in_the_loop/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
OPENAI_API_KEY=KEY
161 changes: 161 additions & 0 deletions python/examples/human_in_the_loop/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# Import necessary libraries
import os
from tkinter import END # For accessing environment variables
import dotenv # For loading environment variables from a .env file
# Import modules from Composio and LlamaIndex
import re
from datetime import datetime
from composio_llamaindex import App, ComposioToolSet, Action
from llama_index.core.agent import FunctionCallingAgentWorker
from llama_index.core.llms import ChatMessage
from llama_index.llms.openai import OpenAI
from composio.client.collections import TriggerEventData
from composio_llamaindex import Action, App, ComposioToolSet

# Load environment variables from a .env file
dotenv.load_dotenv()

BOT_USER_ID = os.environ[
"BOT_USER_ID"
] # Bot ID for Composio. Replace with your own bot member ID, once bot joins the channel.
RESPOND_ONLY_IF_TAGGED = (
True # Set to True to have the bot respond only when tagged in a message
)

llm = OpenAI(model="gpt-4o")

composio_toolset = ComposioToolSet()
slack_listener = composio_toolset.create_trigger_listener()
gmail_listener = composio_toolset.create_trigger_listener()

def proc():
print("listener")
composio_toolset.execute_action(
action=Action.SLACKBOT_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL,
params={
"channel": "general",
"text": f"Are you sure you want to post message:{mail_message} from sender email:{sender_mail}. If yes, tag test_app and tell it the project id and team id.",
},
)
slack_listener.listen()

composio_tools = composio_toolset.get_tools(
apps=[App.LINEAR, App.GMAIL]
)



prefix_messages = [
ChatMessage(
role="system",
content=(
"You are an agent that creates issues in Linear based on customer feedback emails"
),
)
]

agent = FunctionCallingAgentWorker(
tools=composio_tools,
llm=llm,
prefix_messages=prefix_messages,
max_function_calls=10,
allow_parallel_tool_calls=False,
verbose=True,
).as_agent()


# Callback function for handling new messages in a Slack channel
@slack_listener.callback(filters={"trigger_name": "slackbot_receive_message"})
def callback_new_message(event: TriggerEventData) -> None:
print("Recieved new messsage")
payload = event.payload
user_id = payload.get("user", "")

# Ignore messages from the bot itself to prevent self-responses
if user_id == BOT_USER_ID:
return "Bot ignored"

message = payload.get("text", "")

# Respond only if the bot is tagged in the message, if configured to do so
if RESPOND_ONLY_IF_TAGGED and f"<@{BOT_USER_ID}>" not in message:
print(f"Bot not tagged, ignoring message - {message} - {BOT_USER_ID}")
return (
f"Bot not tagged, ignoring message - {json.dumps(payload)} - {BOT_USER_ID}"
)

# Extract channel and timestamp information from the event payload
channel_id = payload.get("channel", "")
ts = payload.get("ts", "")
thread_ts = payload.get("thread_ts", ts)



YES_OR_NO_prefix_messages = [
ChatMessage(
role="system",
content=(
"Take input from the user on team id and project id and create an issue on Linear "
),
)
]
tools = composio_toolset.get_actions(apps=[App.LINEAR])
# Process the message and post the response in the same channel or thread
check_agent = FunctionCallingAgentWorker(
tools=tools,
llm=llm,
prefix_messages=YES_OR_NO_prefix_messages,
max_function_calls=10,
allow_parallel_tool_calls=False,
verbose=True,
).as_agent()
query_task = f"""
2. If you decide to create an issue, Create it on Linear.
3. If you decide to create an issue it should be a summary of the email content.
4. The email content is {mail_message} and sender email is {sender_mail}
4. The format should be <id>:<content>
5. If you decide NO, then dont call any agent and end operation.
message:{message}
6. If the user does not give project id or team id find them out by using Linear Tool's actions.
"""
result = check_agent.chat(query_task)
print(result)
composio_toolset.execute_action(
action=Action.SLACKBOT_CHAT_POST_MESSAGE,
params={
"channel": channel_id,
"text": result.response,
"thread_ts": thread_ts,
},
)


@gmail_listener.callback(filters={"trigger_name": "gmail_new_gmail_message"})
def callback_new_message(event: TriggerEventData) -> None:
print("MESSAGE RECEIVED")
print("here in the function")
payload = event.payload
global mail_message
global sender_mail
thread_id = payload.get("threadId")
mail_message = payload.get("messageText")
print(payload)
sender_mail = payload.get("sender")
if sender_mail is None:
print("No sender email found")
return
print(sender_mail)
print("WAITING FOR SLACK CONFIRMATION")
composio_toolset_1 = ComposioToolSet(
processors={
"pre": {
Action.LINEAR_CREATE_LINEAR_ISSUE: proc()
},
}
)


print("GMAIL LISTENING")

gmail_listener.listen()

40 changes: 40 additions & 0 deletions python/examples/human_in_the_loop/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Human in the Loop Guide

This guide provides detailed steps to create a Human in the Loop Agent that leverages Composio, agentic frameworks such as LlamaIndex and ChatGPT to review PRs every time they're created. Ensure you have Python 3.8 or higher installed.

## Adding a Slackbot
![alt text](https://github.com/composiohq/composio/blob/feat/slack-assistant/python/examples/slack_bot_agent/adding_slack_bot.gif?raw=true)

## Steps to perform before running

Ensure that triggers are enabled in the Composio Dashboard. These are the triggers to enable:
1. [Slack Bot Receive Message (trigger_id = SLACKBOT_RECEIVE_MESSAGE)](https://app.composio.dev/app/slackbot)
2. [Slack Bot Receive Thread Reply (trigger_id = SLACKBOT_RECEIVE_THREAD_REPLY)](https://app.composio.dev/app/slackbot)
3. [Gmail Receive Email (trigger_id = NEW_GMAIL_MESSAGE)](https://app.composio.dev/app/gmail)
Add the slackbot to any channel in your workspace to use it.

## Steps to Run

**Navigate to the Project Directory:**
Change to the directory where the `setup.sh`, `main.py`, `requirements.txt`, and `README.md` files are located. For example:
```sh
cd path/to/project/directory
```

### 1. Run the Setup File
Make the setup.sh Script Executable (if necessary):
On Linux or macOS, you might need to make the setup.sh script executable:
```shell
chmod +x setup.sh
```
Execute the setup.sh script to set up the environment and install dependencies:
```shell
./setup.sh
```
Now, fill in the `.env` file with your secrets.

### 2. Run the Python Script
```shell
python cookbook/examples/human_in_the_loop/main.py
```

3 changes: 3 additions & 0 deletions python/examples/human_in_the_loop/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
composio-llamaindex
llama-index
python-dotenv
42 changes: 42 additions & 0 deletions python/examples/human_in_the_loop/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash

# Create a virtual environment
echo "Creating virtual environment..."
python3 -m venv ~/.venvs/human_in_the_loop

# Activate the virtual environment
echo "Activating virtual environment..."
source ~/.venvs/human_in_the_loop/bin/activate

# Install libraries from requirements.txt
echo "Installing libraries from requirements.txt..."
pip install -r requirements.txt

# Login to your account
echo "Login to your Composio acount"
composio login

# Add trello tool

echo "Add slackbot tool. Finish the flow"
composio add slackbot
composio add gmail

echo "Enable Slackbot triggers"
composio triggers enable slackbot_receive_message
composio triggers enable slackbot_receive_thread_reply
composio triggers enable new_gmail_message

# Copy env backup to .env file
if [ -f ".env.example" ]; then
echo "Copying .env.example to .env..."
cp .env.example .env
else
echo "No .env.example file found. Creating a new .env file..."
touch .env
fi

# Prompt user to fill the .env file
echo "Please fill in the .env file with the necessary environment variables."

echo "Setup completed successfully!"

0 comments on commit a5939f1

Please sign in to comment.