Skip to content

Commit

Permalink
Merge branch 'master' into ENG-3283
Browse files Browse the repository at this point in the history
  • Loading branch information
tushar-composio authored Jan 10, 2025
2 parents 78fc5b1 + 77f7dd1 commit 62e767b
Show file tree
Hide file tree
Showing 154 changed files with 624 additions and 551 deletions.
1 change: 1 addition & 0 deletions docs/mint.json
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@
"faq/api_key/cli",
"faq/integrations_and_connections/list_of_tools",
"faq/supported_llms/supported_llm",
"monitoring-docs",
"changelog"
]
},
Expand Down
17 changes: 17 additions & 0 deletions docs/monitoring-logs.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
title: "Monitoring Logs"
sidebarTitle: "Monitoring Logs"
description: "How to monitor logs & troubleshoot errors"
---

#### Monitoring Action Execution & Triggers Logs
<Steps>
<Step title="Head over to Dashboard">
You can monitor the action execution & triggers logs by clicking on [Action Logs](https://app.composio.dev/logs) and [Triggers Logs](https://app.composio.dev/trigger_logs) under **Logs** on the dashboard.
<img height="200" src="enterprise/media/manage-projects/logs-1.jpg" />
</Step>
<Step title="Click on any log to view details">
Click on any log to view detais like log id, provider name, action name, request & response body. Similarly in triggers logs, you can view the trigger name, trigger ID & payload
<img height="200" src="enterprise/media/manage-projects/logs-2.jpg" />
</Step>
</Steps>
33 changes: 29 additions & 4 deletions docs/patterns/tools/build-tools/custom-action-with-auth.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,24 @@ def list_repositories(
# Custom Action Logic
]
```
```javascript JavaScript
coming soon!
```javascript JavaScript {9,10}
const action = await openAIToolset.createAction({
actionName: "star_repo",
toolName: "github",
description: "Stars a repository on GitHub",
inputParams: z.object({
owner: z.string().describe("The owner of the repository"),
repo: z.string().describe("The name of the repository"),
}),
callback: async (inputParams, authCredentials, executeRequest) => {
console.log(authCredentials);
},
})
```
</CodeGroup>
Below is an example of the connection parameters for a GitHub account:
```bash Output
<CodeGroup>
```bash Python
scope='********'
base_url='https://api.github.com'
client_id='********'
Expand All @@ -207,7 +219,20 @@ headers={
}
queryParams={}
```

```javascript JavaScript
{
headers: {
Authorization: 'Bearer aDVVU0k0*************',
'x-request-id': '9dcc107d-0d5b-4c17-a915-b2519d477dc1'
},
queryParams: { },
baseUrl: 'https://api.x.com'
}
[
'{"data":{},"error":"Failed to execute action","successfull":false,"successful":false}'
]
```
</CodeGroup>

### Why Use Custom Actions?

Expand Down
2 changes: 1 addition & 1 deletion js/src/sdk/client/core/OpenAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export type OpenAPIConfig = {
};
};

export const COMPOSIO_BASE_URL = "https://backend.composio.dev/";
export const COMPOSIO_BASE_URL = "https://backend.composio.dev";

export const OpenAPI: OpenAPIConfig = {
BASE: COMPOSIO_BASE_URL,
Expand Down
5 changes: 3 additions & 2 deletions js/src/sdk/models/backendClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { client as axiosClient } from "../client/services.gen";
import { setAxiosClientConfig } from "../utils/config";
import { CEG } from "../utils/error";
import { COMPOSIO_SDK_ERROR_CODES } from "../utils/errors/src/constants";
import { removeTrailingSlashIfExists } from "../utils/string";

/**
* Class representing the details required to initialize and configure the API client.
Expand Down Expand Up @@ -35,7 +36,7 @@ export class BackendClient {
constructor(apiKey: string, baseUrl: string, runtime?: string) {
this.runtime = runtime || "";
this.apiKey = apiKey;
this.baseUrl = baseUrl;
this.baseUrl = removeTrailingSlashIfExists(baseUrl);
this.instance = axiosClient.instance;

if (!apiKey) {
Expand Down Expand Up @@ -84,7 +85,7 @@ export class BackendClient {
*/
private initializeApiClient() {
axiosClient.setConfig({
baseURL: this.baseUrl,
baseURL: removeTrailingSlashIfExists(this.baseUrl),
headers: {
"X-API-KEY": `${this.apiKey}`,
"X-SOURCE": "js_sdk",
Expand Down
2 changes: 2 additions & 0 deletions js/src/sdk/utils/string.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const removeTrailingSlashIfExists = (str: string) =>
str.replace(/\/+$/, "");
2 changes: 1 addition & 1 deletion python/composio/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.6.12"
__version__ = "0.6.13"
2 changes: 1 addition & 1 deletion python/dockerfiles/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ RUN /bin/python3 -m venv .composio/venv
RUN export PATH=$PATH:$(pwd)/.composio/venv/bin

# Install composio
RUN python -m pip install composio-core[all]==0.6.12 fastapi playwright uvicorn
RUN python -m pip install composio-core[all]==0.6.13 fastapi playwright uvicorn

# Install playwright deps
RUN playwright install-deps
Expand Down
24 changes: 12 additions & 12 deletions python/examples/advanced_agents/AI_PM_agent/crewai/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
RESPOND_ONLY_IF_TAGGED = (
True # Set to True to have the bot respond only when tagged in a message
)
import agentops
agentops.init(os.environ["AGENTOPS_API_KEY"])
# import agentops
# agentops.init(os.environ["AGENTOPS_API_KEY"])

#from langchain_cerebras import ChatCerebras

Expand All @@ -46,7 +46,7 @@ def proc(mail_message, sender_mail):
"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()
slack_listener.wait_forever()



Expand All @@ -55,20 +55,20 @@ def proc(mail_message, sender_mail):
goal="You are an agent that creates issues in Linear based on customer feedback emails",
backstory="You are an expert in using Linear and creating issues on it.",
llm=llm,
tools=composio_tools,
tools=composio_tools, # type: ignore
)


# 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:
def callback_slack_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"
return "Bot ignored" # type: ignore

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

Expand All @@ -77,7 +77,7 @@ def callback_new_message(event: TriggerEventData) -> None:
print(f"Bot not tagged, ignoring message - {message} - {BOT_USER_ID}")
return (
f"Bot not tagged, ignoring message - {json.dumps(payload)} - {BOT_USER_ID}"
)
) # type: ignore

# Extract channel and timestamp information from the event payload
channel_id = payload.get("channel", "")
Expand All @@ -98,14 +98,14 @@ def callback_new_message(event: TriggerEventData) -> None:
),
expected_output="issue was created",
agent=issue_creator_agent,
tools=composio_tools
tools=composio_tools # type: ignore
)

crew = Crew(
agents=[issue_creator_agent],
tasks=[issue_task],
process=Process.sequential,
tools = composio_tools
tools = composio_tools # type: ignore
)

result = crew.kickoff()
Expand All @@ -120,7 +120,7 @@ def callback_new_message(event: TriggerEventData) -> None:


@gmail_listener.callback(filters={"trigger_name": "gmail_new_gmail_message"})
def callback_new_message(event: TriggerEventData) -> None:
def callback_gmail_new_message(event: TriggerEventData) -> None:
print("MESSAGE RECEIVED")
print("here in the function")
payload = event.payload
Expand All @@ -140,12 +140,12 @@ def callback_new_message(event: TriggerEventData) -> None:
"pre": {
Action.LINEAR_CREATE_LINEAR_ISSUE: proc(mail_message, sender_mail)
},
}
} # type: ignore
)


print("GMAIL LISTENING")

gmail_listener.listen()
gmail_listener.wait_forever()


10 changes: 5 additions & 5 deletions python/examples/advanced_agents/AI_PM_agent/crewai/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ pip install -r requirements.txt
echo "Login to your Composio acount"
composio login

# Add trello tool

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

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

# Copy env backup to .env file
Expand Down
34 changes: 14 additions & 20 deletions python/examples/advanced_agents/AI_PM_agent/llamaindex/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
RESPOND_ONLY_IF_TAGGED = (
True # Set to True to have the bot respond only when tagged in a message
)
import agentops
agentops.init(os.environ["AGENTOPS_API_KEY"])
# import agentops
# agentops.init(os.environ["AGENTOPS_API_KEY"])

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

Expand All @@ -44,7 +44,7 @@ def proc():
"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()
slack_listener.wait_forever()



Expand All @@ -60,7 +60,7 @@ def proc():
]

agent = FunctionCallingAgentWorker(
tools=composio_tools,
tools=composio_tools, # type: ignore
llm=llm,
prefix_messages=prefix_messages,
max_function_calls=10,
Expand All @@ -71,23 +71,23 @@ def proc():

# 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:
def callback_slack_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"
return "Bot ignored" # type: ignore

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}"
)
f"Bot not tagged, ignoring message - {json.dumps(payload)} - {BOT_USER_ID}" # type: ignore
) # type: ignore

# Extract channel and timestamp information from the event payload
channel_id = payload.get("channel", "")
Expand All @@ -105,16 +105,16 @@ def callback_new_message(event: TriggerEventData) -> None:
),
)
]
tools = composio_toolset.get_tools(apps=[App.LINEAR])
tools = composio_toolset.get_tools(apps=[App.LINEAR]) # type: ignore
# Process the message and post the response in the same channel or thread
check_agent = FunctionCallingAgentWorker(
tools=tools,
tools=tools, # type: ignore
llm=llm,
prefix_messages=YES_OR_NO_prefix_messages,
max_function_calls=10,
allow_parallel_tool_calls=False,
verbose=True,
).as_agent()
).as_agent() # type: ignore
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.
Expand All @@ -125,7 +125,7 @@ def callback_new_message(event: TriggerEventData) -> None:
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)
print(result) # type: ignore
composio_toolset.execute_action(
action=Action.SLACKBOT_CHAT_POST_MESSAGE,
params={
Expand All @@ -152,16 +152,10 @@ def callback_new_message(event: TriggerEventData) -> None:
return
print(sender_mail)
print("WAITING FOR SLACK CONFIRMATION")
composio_toolset_1 = ComposioToolSet(
processors={
"pre": {
Action.LINEAR_CREATE_LINEAR_ISSUE: proc()
},
}
)
proc()


print("GMAIL LISTENING")

gmail_listener.listen()
gmail_listener.wait_forever()

Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,14 @@ pip install -r requirements.txt
echo "Login to your Composio acount"
composio login

# Add trello tool

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

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

# Copy env backup to .env file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pip install -r requirements.txt
echo "Login to your Composio acount"
composio login

# Add trello tool

echo "Add tool. Finish the flow"
composio add serpapi

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pip install -r requirements.txt
echo "Login to your Composio acount"
composio login

# Add trello tool

echo "Add tool. Finish the flow"
composio add serpapi

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def create_prefix_message():

# Initialize the agent
agent = FunctionCallingAgentWorker(
tools=tools,
tools=tools, # type: ignore
llm=llm,
prefix_messages=prefix_messages,
max_function_calls=10,
Expand Down
Loading

0 comments on commit 62e767b

Please sign in to comment.