diff --git a/.github/workflows/common.yml b/.github/workflows/common.yml index 2412807723d..eab05728adf 100644 --- a/.github/workflows/common.yml +++ b/.github/workflows/common.yml @@ -3,11 +3,7 @@ on: push: branches: - master - paths: - - 'python/**' pull_request: - paths: - - 'python/**' jobs: lock_check: @@ -59,11 +55,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | - sudo apt-get update --fix-missing - sudo apt-get autoremove - sudo apt-get autoclean - pip install --user --upgrade setuptools - pip install tox==4.6.3 + pip install 'tox>=4.21,<5' tox-uv - name: Code style check run: | tox -e black-diff @@ -79,8 +71,6 @@ jobs: run: working-directory: ./python continue-on-error: False - needs: - - lock_check runs-on: ${{ matrix.os }} strategy: matrix: @@ -100,11 +90,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install Dependencies run: | - sudo apt-get update --fix-missing - sudo apt-get autoremove - sudo apt-get autoclean - pip install --user --upgrade setuptools - pip install tox==4.6.3 + pip install 'tox>=4.21,<5' tox-uv - name: Unittests run: | export COMPOSIO_API_KEY=${{ secrets.COMPOSIO_API_KEY_STAGING }} @@ -112,20 +98,57 @@ jobs: export FLY_API_TOKEN=${{ secrets.FLY_API_TOKEN }} export E2B_API_KEY=${{ secrets.E2B_API_KEY_STAGING }} - tox -e test -- -m 'not e2e' + tox -e test -- -m 'not e2e and not swe' - if: matrix.python-version == '3.10' name: Upload test results to Codecov uses: codecov/test-results-action@v1 with: token: ${{ secrets.CODECOV_TOKEN }} + swe: + defaults: + run: + working-directory: ./python + continue-on-error: False + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + python-version: ["3.10"] + timeout-minutes: 20 + concurrency: + group: 'test:swe:${{ matrix.python-version }}:${{ github.ref }}' + cancel-in-progress: true + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + fetch-depth: 0 + + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install Dependencies + run: | + pip install 'tox>=4.21,<5' tox-uv + - name: Unittests + run: | + export COMPOSIO_API_KEY=${{ secrets.COMPOSIO_API_KEY_STAGING }} + export COMPOSIO_BASE_URL=${{ secrets.COMPOSIO_BASE_URL_STAGING }} + export FLY_API_TOKEN=${{ secrets.FLY_API_TOKEN }} + export E2B_API_KEY=${{ secrets.E2B_API_KEY_STAGING }} + + tox -e test -- -m 'swe' + - name: Upload test results to Codecov + uses: codecov/test-results-action@v1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + e2e: defaults: run: working-directory: ./python continue-on-error: False - needs: - - lock_check runs-on: ${{ matrix.os }} strategy: matrix: @@ -154,11 +177,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install Dependencies run: | - sudo apt-get update --fix-missing - sudo apt-get autoremove - sudo apt-get autoclean - pip install --user --upgrade setuptools - pip install tox==4.6.3 + pip install 'tox>=4.21,<5' tox-uv - name: Build docker images run: | cd dockerfiles diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index c6c5d7aebf3..a3499ff7cf0 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -85,10 +85,6 @@ jobs: COMPOSIO_BASE_URL: ${{ inputs.base_url || secrets.COMPOSIO_BASE_URL || 'https://backend.composio.dev/api' }} # TODO(@kaavee): Add Anthropic API key run: | - sudo apt-get update --fix-missing - sudo apt-get autoremove - sudo apt-get autoclean - python -m pip install --upgrade pip pipenv pytest python -m pip install plugins/${{matrix.package}} python -m pip install '.[all]' diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 443ca8e3bfa..fe7670f02a5 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -31,10 +31,6 @@ jobs: COMPOSIO_BASE_URL: https://backend.composio.dev/api COMPOSIO_API_KEY: ${{secrets.COMPOSIO_API_KEY_RELEASE}} run: | - sudo apt-get update --fix-missing - sudo apt-get autoremove - sudo apt-get autoclean - # Setup release python -m pip install --upgrade pip python -m pip install . @@ -91,10 +87,6 @@ jobs: python-version: ${{ matrix.python-version }} - name: Build ${{ matrix.package }} run: | - sudo apt-get update --fix-missing - sudo apt-get autoremove - sudo apt-get autoclean - python -m pip install --upgrade pip pip install twine build # Build dist @@ -128,10 +120,6 @@ jobs: python-version: ${{ matrix.python-version }} - name: Build run: | - sudo apt-get update --fix-missing - sudo apt-get autoremove - sudo apt-get autoclean - python -m pip install --upgrade pip pip install twine build # Build dist diff --git a/docs/framework/langflow.mdx b/docs/framework/langflow.mdx new file mode 100644 index 00000000000..b858291fff1 --- /dev/null +++ b/docs/framework/langflow.mdx @@ -0,0 +1,57 @@ +--- +title: "Using Composio With LangFlow" +sidebarTitle: "LangFlow" +icon: "network-wired" +description: "Use Composio with LangFlow to create LLM agents that can interact with external apps" +--- + +## Star A Repository on Github +In this example, we will use LangFlow to star a repository on Github using Composio Tools + + + +Head over to the [LangFlow](https://astra.datastax.com/langflow) website, create a new project, look for Composio component in the component list and add it to your project + + + + +Go to your [Composio Dashboard](https://app.composio.dev/) and copy your API key, paste it in the API Key field in the Composio component and then search for Github in apps list and select it + + + + +Click on refresh button, a link to authenticate with Github will be generated (if you don't have connected Github account), click on it and authenticate + +Most recent connected Github account with entity Id `default` will be considered for executing the action + + + + + +After authenticating, click on the refresh button to verify connection status + + + +Select the action `GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER` and you're done configuring the Composio component + + + +Look for agent in Components list, add it to your project, connect Composio component as tools to the agent then configure the agent (model provider, model name, api key, etc.). + + +Lastly modify the agent input to **Star the repo composiohq/composio** + + + +Look for chat output in Components list, add it to your project, connect agent's response to the chat output component. We will use this component to monitor the agent's response + + + +Click on the run button on chat output to run the agent, and open playground to monitor the agent's response + + + +Hurray! You have successfully starred the repository composiohq/composio + + + diff --git a/docs/framework/media/langflow/1.jpg b/docs/framework/media/langflow/1.jpg new file mode 100644 index 00000000000..15c793d6beb Binary files /dev/null and b/docs/framework/media/langflow/1.jpg differ diff --git a/docs/framework/media/langflow/10.jpg b/docs/framework/media/langflow/10.jpg new file mode 100644 index 00000000000..a761146c53b Binary files /dev/null and b/docs/framework/media/langflow/10.jpg differ diff --git a/docs/framework/media/langflow/11.jpg b/docs/framework/media/langflow/11.jpg new file mode 100644 index 00000000000..39631c91111 Binary files /dev/null and b/docs/framework/media/langflow/11.jpg differ diff --git a/docs/framework/media/langflow/12.jpg b/docs/framework/media/langflow/12.jpg new file mode 100644 index 00000000000..87dd9165e64 Binary files /dev/null and b/docs/framework/media/langflow/12.jpg differ diff --git a/docs/framework/media/langflow/13.jpg b/docs/framework/media/langflow/13.jpg new file mode 100644 index 00000000000..30674473b20 Binary files /dev/null and b/docs/framework/media/langflow/13.jpg differ diff --git a/docs/framework/media/langflow/14.jpg b/docs/framework/media/langflow/14.jpg new file mode 100644 index 00000000000..e31a2da4f92 Binary files /dev/null and b/docs/framework/media/langflow/14.jpg differ diff --git a/docs/framework/media/langflow/2.jpg b/docs/framework/media/langflow/2.jpg new file mode 100644 index 00000000000..ebba5104abb Binary files /dev/null and b/docs/framework/media/langflow/2.jpg differ diff --git a/docs/framework/media/langflow/3.jpg b/docs/framework/media/langflow/3.jpg new file mode 100644 index 00000000000..2f74931d63b Binary files /dev/null and b/docs/framework/media/langflow/3.jpg differ diff --git a/docs/framework/media/langflow/4.jpg b/docs/framework/media/langflow/4.jpg new file mode 100644 index 00000000000..3d67ee8ac09 Binary files /dev/null and b/docs/framework/media/langflow/4.jpg differ diff --git a/docs/framework/media/langflow/5.jpg b/docs/framework/media/langflow/5.jpg new file mode 100644 index 00000000000..320baea667a Binary files /dev/null and b/docs/framework/media/langflow/5.jpg differ diff --git a/docs/framework/media/langflow/6.jpg b/docs/framework/media/langflow/6.jpg new file mode 100644 index 00000000000..7ffdccfcbf4 Binary files /dev/null and b/docs/framework/media/langflow/6.jpg differ diff --git a/docs/framework/media/langflow/7.jpg b/docs/framework/media/langflow/7.jpg new file mode 100644 index 00000000000..8aad781f06d Binary files /dev/null and b/docs/framework/media/langflow/7.jpg differ diff --git a/docs/framework/media/langflow/8.jpg b/docs/framework/media/langflow/8.jpg new file mode 100644 index 00000000000..5c7c5876213 Binary files /dev/null and b/docs/framework/media/langflow/8.jpg differ diff --git a/docs/framework/media/langflow/9.jpg b/docs/framework/media/langflow/9.jpg new file mode 100644 index 00000000000..49b41fd85b0 Binary files /dev/null and b/docs/framework/media/langflow/9.jpg differ diff --git a/docs/introduction/intro/quickstart_3.mdx b/docs/introduction/intro/quickstart_3.mdx index 5efec0306b3..0bf68bc6b67 100644 --- a/docs/introduction/intro/quickstart_3.mdx +++ b/docs/introduction/intro/quickstart_3.mdx @@ -6,260 +6,212 @@ description: "Quickstart: Learn how to use Triggers with Composio." --- ## Composio Quick Start - -Set up Triggers that automatically execute Actions. - -Follow these 5 steps to list your emails as soon as you receive them: - - -**What you'll achieve:** By the end of this guide, you'll have an AI agent capable of listing all the emails you receive as soon as you receive them. - +In this guide we'll configure and enable a trigger to listen to new emails in Gmail & configure an agent add important label to emails that contains details about bank transactions. - - -```shell Installing the library -pip install composio_core composio_openai + +```shell CLI +pip install composio-core composio_openai ``` - - -We'll use **`Jessica`** as our example user. Choose your method: + +We'll use **`Jessica`** as the user id [(entity id)](../../patterns/Auth/connected_account#entities). +You need to have an active Gmail Integration. Learn how to do this [here](https://youtu.be/LmyWy4LiedQ?si=u5uFArlNL0tew0Wf) - - -```shell Add Gmail Integration +```shell CLI composio login - -composio add gmail -e "Jessica" # Launches Gmail login +composio add gmail -e "Jessica" ``` - - - - -```python Add Gmail Integration -from composio import ComposioToolSet, App - +```python Python +from composio_openai import ComposioToolSet, App, Trigger toolset = ComposioToolSet(entity_id="Jessica") -entity = toolset.get_entity() -request = entity.initiate_connection(App.GMAIL) + +request = toolset.initiate_connection(app=App.GMAIL) print(f"Open this URL to authenticate: {request.redirectUrl}") ``` - - - - -Ensure you complete the authentication process by following the URL provided in your console. - - + +Don't forget to set your `COMPOSIO_API_KEY` and `OPENAI_API_KEY` in your environment variables. + - - ```shell CLI -# Enable the trigger composio triggers enable gmail_new_gmail_message - -# To disable a trigger -composio triggers disable ``` - - - - ```python Python -from composio import Composio, App - -client = Composio() -entity = client.get_entity(id="Jessica") - -# Enable trigger with optional config parameter -entity.enable_trigger(app=App.GMAIL, trigger_name="gmail_new_gmail_message", config={}) +entity = toolset.get_entity(id="Jessica") -# Disable trigger by ID (if needed) -# entity.disable_trigger("gmail_new_gmail_message") +entity.enable_trigger( + app=App.GMAIL, + trigger_name="gmail_new_gmail_message", + config={"userId": "me", "interval": 1, "labelIds": "INBOX"}, +) ``` - - - - + -```python Set up your development environment -from composio_openai import ComposioToolSet, Action -from openai import OpenAI - -openai_client = OpenAI() -composio_toolset = ComposioToolSet() +```python Python +def agent_function(thread_id: str, message: str, sender_mail: str): + tools = toolset.get_tools(apps=[App.GMAIL]) + + response = openai_client.chat.completions.create( + model="gpt-4o-mini", + tools=tools, + messages=[ + { + "role": "system", + "content": "You are a helpful assistant that can parse the email content, identify bank transactions and add the 'important' label to the email. Otherwise, don't do anything.", + }, + { + "role": "user", + "content": f"Thread ID: {thread_id}\nMessage: {message}\nSender: {sender_mail}", + }, + ], + ) + result = toolset.handle_tool_calls(response) + print(result) ``` - - -Don't forget to set your `COMPOSIO_API_KEY` and `OPENAI_API_KEY` in your environment variables. - - - -```python Creating a trigger listener for Gmail -from composio import Trigger - -listener = composio_toolset.create_trigger_listener() +```python Python +listener = toolset.create_trigger_listener() -# Triggers when a new event takes place @listener.callback(filters={"trigger_name": Trigger.GMAIL_NEW_GMAIL_MESSAGE}) def callback_function(event): - # Parse event data and perform actions payload = event.payload thread_id = payload.get("threadId") message = payload.get("messageText") sender_mail = payload.get("sender") - print(sender_mail + ":" + message) + agent_function(thread_id, message, sender_mail) + +print("Starting listener") listener.wait_forever() ``` - - - + - - + -```shell Install packages +```shell CLI npm install composio-core openai ``` - -We'll use **`Jessica`** as our example user. Choose your method: + +We'll use **`Jessica`** as the user id [(entity id)](../../patterns/Auth/connected_account#entities). +You need to have an active Gmail Integration. Learn how to do this [here](https://youtu.be/LmyWy4LiedQ?si=u5uFArlNL0tew0Wf) - - -```shell Adding tool via CLI +```shell CLI composio login - -composio add gmail -e "Jessica" # Launches Gmail login +composio add gmail -e "Jessica" ``` - - - - -```javascript Adding tool via JS -import { Composio } from "composio-core"; - -const client = new Composio(process.env.COMPOSIO_API_KEY); +```javascript JavaScript +import { OpenAIToolSet, Composio } from "composio-core"; +import { OpenAI } from "openai"; -const entity = await client.getEntity("Jessica"); -const connection = await entity.initiateConnection('gmail'); +const toolset = new OpenAIToolSet(); +const openai_client = new OpenAI(); -console.log(`Open this URL to authenticate: ${connection.redirectUrl}`); +const connectionRequest = await toolset.client.connectedAccounts.initiate({ + appName: "gmail", + entityId: "Jessica", + authMode: "OAUTH2", + authConfig: {}, +}); +console.log(connectionRequest.redirectUrl); ``` - - - - -Ensure you complete the authentication process by following the URL provided in your console. - - + +Don't forget to set your `COMPOSIO_API_KEY` and `OPENAI_API_KEY` in your environment variables. + - - -```shell Enabling trigger with CLI +```shell CLI composio triggers enable gmail_new_gmail_message - -# To disable a trigger -composio triggers disable ``` - - - - -```javascript Enabling triggers with JS -import { LangchainToolSet } from "composio-core"; - -const toolset = new LangchainToolSet({ apiKey: process.env.COMPOSIO_API_KEY }); -const composio_client = toolset.client; -const entityId = "Jessica"; -const connectedAccounts = await composio_client.connectedAccounts.list({ - user_uuid: entityId, - appNames: 'gmail', - status: 'ACTIVE' -}); - -const triggerSetupData = await composio_client.triggers.setup( - connectedAccounts.items[0].id, - "gmail_new_gmail_message", - {} -); +```javascript JavaScript +const entity = toolset.client.getEntity("Jessica"); + +const response = await entity.setupTrigger("gmail", "gmail_new_gmail_message", { + userId: "me", + interval: 1, + labelIds: "INBOX" +}) +console.log(response) ``` - - - - + -```javascript Set up your development environment -import { OpenAI } from "openai"; -import { OpenAIToolSet } from "composio-core"; - -const openai_client = new OpenAI({ - apiKey: process.env.OPENAI_API_KEY -}); - -const composio_toolset = new OpenAIToolSet({ - apiKey: process.env.COMPOSIO_API_KEY, -}); +```javascript JavaScript +const agentFunction = async (threadId, subject, senderMail) => { + const tools = await toolset.getTools({ apps: ["gmail"] }); + + const response = await openai_client.chat.completions.create({ + model: "gpt-4o-mini", + messages: [ + { + role: "system", + content: "You are a helpful assistant that can parse the email content, identify bank transactions and add the 'important' label to the email. Otherwise, don't do anything" + }, + { + role: "user", + content: `Thread ID: ${threadId}, Subject: ${subject}, Sender: ${senderMail}` + } + ], + tools: tools, + tool_choice: "auto", + }); + + const result = await toolset.handleToolCall(response); + console.log(result); +} ``` - - -Don't forget to set your `COMPOSIO_API_KEY` and `OPENAI_API_KEY` in your environment variables. - - - - -```javascript Creating a trigger listener for gmail -import { LangchainToolSet } from "composio-core"; - -const toolset = new LangchainToolSet({ apiKey: process.env.COMPOSIO_API_KEY }); -const composio_client = toolset.client; - -// Subscribe to triggers and perform actions -composio_client.triggers.subscribe((data) => { - console.log("trigger received", data); -}); +```javascript JavaScript +toolset.client.triggers.subscribe( + (data) => { + const { + payload: { + threadId, + subject, + sender + } + } = data; + agentFunction(threadId, subject, sender); + }, + { + triggerName: "gmail_new_gmail_message" + } +); ``` - @@ -270,16 +222,15 @@ composio_client.triggers.subscribe((data) => { Congratulations! You've just: -1. 🔐 Authenticated your Gmail account with Composio +1. 🔐 Connected your Gmail account with Composio 2. 🛠 Enabled Triggers -3. 🧠 Passed these triggers to an AI language model -4. ⭐ All the emails received were listed -5. ✅ Successfully executed the trigger and actions on Gmail +3. 🧠 Passed these triggers event payloads to an AI language model +4. ⭐ Added the important label to emails that contain details about bank transactions - + Integrate with popular agentic frameworks diff --git a/docs/mint.json b/docs/mint.json index be52c876c94..2be2033ab9d 100644 --- a/docs/mint.json +++ b/docs/mint.json @@ -100,7 +100,8 @@ "patterns/tools/use-tools/get-action-inputs", "patterns/tools/use-tools/processing-actions", "patterns/tools/use-tools/configure-tools", - "patterns/tools/use-tools/action-guide-without-agents" + "patterns/tools/use-tools/action-guide-without-agents", + "patterns/tools/use-tools/use-tools-with-your-auth" ] }, { @@ -140,6 +141,7 @@ "framework/autogen", "framework/crewai", "framework/langchain", + "framework/langflow", "framework/langgraph", "framework/letta", "framework/litellm", diff --git a/docs/patterns/tools/use-tools/processing-actions.mdx b/docs/patterns/tools/use-tools/processing-actions.mdx index 30db7ab3e17..2b44b745ba1 100644 --- a/docs/patterns/tools/use-tools/processing-actions.mdx +++ b/docs/patterns/tools/use-tools/processing-actions.mdx @@ -50,12 +50,13 @@ Coming Soon -This function will be used to modify the schema of the `LINEAR_CREATE_LINEAR_ISSUE` action, here we are modifying the description for the parameters `project_id` & `team_id` to not required, later in the program we will pass these values as inputs to the action. The technical term for this is **Action-level Schema Processing**. +This function will be used to modify the schema of the `LINEAR_CREATE_LINEAR_ISSUE` action, we get rid of the parameters `project_id` and `team_id`, later in the program we will pass these values as inputs to the action manually. The technical term for this is **Action-level Schema Processing**. ```python Python def linear_schema_processor(schema: dict) -> dict: - schema['project_id']['description'] = schema['project_id']['description'].replace('is required', 'not required') - schema['team_id']['description'] = schema['team_id']['description'].replace('is required', 'not required') + # This way the agent doesn't expect a project and team ID to run the action + del schema['project_id'] + del schema['team_id'] return schema ``` ```javascript JavaScript @@ -82,8 +83,8 @@ This function will be used to modify the output data for the `LINEAR_CREATE_LINE ```python Python def linear_post_processor(output_data: dict) -> dict: output_data = { - 'success': output_data['successful'], - 'issue_id': output_data['data']['id'] + 'success': output_data['successfull'], + 'issue_id': output_data['id'], } return output_data ``` diff --git a/docs/patterns/tools/use-tools/use-actions-with-custom-auth.mdx b/docs/patterns/tools/use-tools/use-actions-with-custom-auth.mdx new file mode 100644 index 00000000000..15b834f392d --- /dev/null +++ b/docs/patterns/tools/use-tools/use-actions-with-custom-auth.mdx @@ -0,0 +1,65 @@ +--- +title: "🛠️ How Can I Use Tools and Actions With Custom Authentication?" +sidebarTitle: "Use Custom Auth" +icon: "lock" +description: "Guide to use Custom Authentication With Tools And Actions" +--- + +### Using Tools and Actions with Custom Auth + +Composio allows you to [execute actions directly](action-guide-without-agents) using custom authentication, in this guide we'll see how to star a repo on GitHub using `GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER` action and passing the **Bearer token** in the headers. You can get the connection paramateters of a connected account like the access token using SDK, learn more [here](../..//Auth/using-connections#fetch-the-connection-parameters) + + + +Use the `add_auth` method to add the custom authentication to the toolset for the app you want to use. `in_` is where you want to add the auth, `name` is the name of the header you want to add and `value` is the value of the header. +```python {7-13} +from composio import ComposioToolSet, App + +toolset = ComposioToolSet() + +toolset.add_auth( + app=App.GITHUB, + parameters=[ + dict( + name="Authorization", + in_="header", + value="Bearer gho_XL9IXXXXXX", + ) + ], +) + +toolset.execute_action( + action="GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER", + params={"owner": "composiohq", "repo": "composio"}, +) +``` + + +Here you need to pass the authentication parameters inside the `authConfig`. `in_` is where you want to add the auth, `name` is the name of the header you want to add and `value` is the value of the header. +```javascript {10-14} +import { OpenAIToolSet } from "composio-core"; + +const toolset = new OpenAIToolSet(); + +const response = await toolset.client.actions.execute({ + actionName: "GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER", + requestBody: { + appName: "github", + authConfig: { + parameters: [{ + name: "Authorization", + in: "header", + value: `Bearer gho_XL9IXXXXXX` + }] + }, + input: { + "owner": "composiohq", + "repo": "composio" + } + } +}); + +console.log(response) +``` + + diff --git a/docs/patterns/tools/use-tools/use-tools-with-your-auth.mdx b/docs/patterns/tools/use-tools/use-tools-with-your-auth.mdx new file mode 100644 index 00000000000..35c6ff08603 --- /dev/null +++ b/docs/patterns/tools/use-tools/use-tools-with-your-auth.mdx @@ -0,0 +1,65 @@ +--- +title: "🛠️ How Can I Use Tools and Actions With Existing Authentication?" +sidebarTitle: "Use Tools With Your Auth" +icon: "lock" +description: "Guide to using existing authentication with tools and actions" +--- + +### Using Tools and Actions with Existing Authentication + +Composio allows you to [execute actions directly](action-guide-without-agents) using existing authentication, in this guide we'll see how to star a repo on GitHub using `GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER` action and passing the **Bearer token** in the headers. You can get the connection paramateters of a connected account like the access token using SDK, learn more [here](../..//Auth/using-connections#fetch-the-connection-parameters) + + + +Use the `add_auth` method to add the existing authentication to the toolset for the app you want to use. `in_` is where you want to add the auth, `name` is the name of the header you want to add and `value` is the value of the header. +```python {7-13} +from composio import ComposioToolSet, App + +toolset = ComposioToolSet() + +toolset.add_auth( + app=App.GITHUB, + parameters=[ + dict( + name="Authorization", + in_="header", + value="Bearer gho_XL9IXXXXXX", + ) + ], +) + +toolset.execute_action( + action="GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER", + params={"owner": "composiohq", "repo": "composio"}, +) +``` + + +Here you need to pass the authentication parameters inside the `authConfig`. `in_` is where you want to add the auth, `name` is the name of the header you want to add and `value` is the value of the header. +```javascript {10-14} +import { OpenAIToolSet } from "composio-core"; + +const toolset = new OpenAIToolSet(); + +const response = await toolset.client.actions.execute({ + actionName: "GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER", + requestBody: { + appName: "github", + authConfig: { + parameters: [{ + name: "Authorization", + in: "header", + value: `Bearer gho_XL9IXXXXXX` + }] + }, + input: { + "owner": "composiohq", + "repo": "composio" + } + } +}); + +console.log(response) +``` + + diff --git a/docs/patterns/triggers/triggers.mdx b/docs/patterns/triggers/triggers.mdx index 99c137f5e9e..7f7f4267999 100644 --- a/docs/patterns/triggers/triggers.mdx +++ b/docs/patterns/triggers/triggers.mdx @@ -10,8 +10,14 @@ You can enable a trigger by specifying the trigger enum, available on the [dashb + +View the required configuration parameters for enabling a trigger by using the show command. For example, this will display what parameters are needed for Github's new star event trigger: +```Bash +composio triggers show GITHUB_STAR_ADDED_EVENT +``` + -You need to pass the trigger enum to enable a trigger. +You need to pass the trigger enum to enable a trigger & you'll be prompted to enter the required parameters. ```Bash composio triggers enable GITHUB_STAR_ADDED_EVENT ``` @@ -39,6 +45,24 @@ toolset = ComposioToolSet() trigger_schema = toolset.get_trigger("GITHUB_STAR_ADDED_EVENT") print(trigger_schema.config) ``` + +Response: +```json +properties={ + 'owner': TriggerConfigPropertyModel(description='Owner of the repository', + title='Owner', + type='string'), + 'repo': TriggerConfigPropertyModel(description='Repository name', + title='Repo', + type='string') +} +title='WebhookConfigSchema' +type='object' +required=[ + 'owner', + 'repo' +] +``` You need to pass the trigger enum and the config parameters to enable a trigger, and **trigger id** will be returned. @@ -157,4 +181,16 @@ toolset.triggers.subscribe( ``` +Trigger event payload when the repository composio is starred: +```json +payload={ + 'action': 'created', + 'starred_at': '2024-12-11T15:31:26Z', + 'repository_id': 861033276, + 'repository_name': 'composio', + 'repository_url': 'https://github.com/composioHQ/composio/', + 'starred_by': 'abhishekpatil4', + 'triggerName': 'GITHUB_STAR_ADDED_EVENT' +} +``` To learn how to configure and use your own webhooks for listening to triggers, visit our [Webhooks Guide](/patterns/triggers/webhooks). \ No newline at end of file diff --git a/js/package.json b/js/package.json index 76e05589217..75c4c953b55 100644 --- a/js/package.json +++ b/js/package.json @@ -11,7 +11,7 @@ "openapispec:generate": "npx @hey-api/openapi-ts", "run:cli": "ts-node src/cli/index.ts", "run:sample": "ts-node sample.ts", - "eslint": "eslint 'src/**/*.{ts,js}' --max-warnings=281", + "eslint": "eslint 'src/**/*.{ts,js}' --max-warnings=261", "prettier": "prettier --write 'src/**/*.{ts,js,cjs}'", "prettier:check": "prettier --check 'src/**/*.{ts,js,mjs,cjs}'", "build": "rollup -c rollup.config.mjs && ./setup_cli.sh", diff --git a/js/src/cli/actions.ts b/js/src/cli/actions.ts new file mode 100644 index 00000000000..559d94f140a --- /dev/null +++ b/js/src/cli/actions.ts @@ -0,0 +1,74 @@ +import chalk from "chalk"; +import { Command } from "commander"; +import client from "../sdk/client/client"; +import { getOpenAPIClient } from "../sdk/utils/config"; +import { ListActionsV2Data } from "../sdk/client"; + +export default class ActionCommand { + private program: Command; + + constructor(program: Command) { + this.program = program; + this.program + .command("actions") + .description("Composio Actions") + .option( + "-a, --apps ", + "List all actions for the given apps", + (value, previous: string[]) => previous.concat([value]), + [] + ) + .option( + "--tags ", + "List all actions for the given tags", + (value, previous: string[]) => previous.concat([value]), + [] + ) + .option( + "--use-case ", + "Search for actions based on the given use case" + ) + .option("--limit ", "Limit the number of actions to display") + .option("--enabled", "Only show enabled actions") + .action(this.handleAction.bind(this)); + } + + private async handleAction(options: { + apps?: string[]; + tags?: string[]; + useCase?: string; + limit?: number; + enabled?: boolean; + }): Promise { + getOpenAPIClient(); + const { apps = [], tags = [], useCase, limit, enabled } = options; + if (apps.length === 0) { + console.log(chalk.red("Please provide at least one app name")); + return; + } + const data: ListActionsV2Data = { + query: { + apps: apps.join(","), + ...(tags.length && { tags: tags.join(",") }), + ...(limit && { limit }), + ...(enabled && { showEnabledOnly: enabled }), + ...(useCase && { useCase }), + }, + }; + try { + const response = await client.actionsV2.listActionsV2(data); + if (response.data?.items.length === 0) { + console.log(chalk.yellow("No actions found")); + return; + } + console.log(chalk.green("Here are the actions for the app:")); + console.log(""); + // render list + const actions = response.data?.items || []; + actions.forEach((action) => console.log(action.name)); + } catch (error) { + console.log(chalk.red((error as Error)?.message)); + return; + } + } +} diff --git a/js/src/cli/index.ts b/js/src/cli/index.ts index 8e6bb08388d..d2057055707 100644 --- a/js/src/cli/index.ts +++ b/js/src/cli/index.ts @@ -12,6 +12,7 @@ import login from "./login"; import logout from "./logout"; import triggers from "./triggers"; import whoami from "./whoami"; +import actions from "./actions"; // SDK Imports import { TELEMETRY_EVENTS } from "../sdk/utils/telemetry/events"; @@ -28,6 +29,7 @@ new connections(program); new integrations(program); new triggers(program); new add(program); +new actions(program); function formatLine(content: string): string { return `${content}`; diff --git a/python/composio/__version__.py b/python/composio/__version__.py index a5a945d8240..906d362f7de 100644 --- a/python/composio/__version__.py +++ b/python/composio/__version__.py @@ -1 +1 @@ -__version__ = "0.5.52-rc.2" +__version__ = "0.6.0" diff --git a/python/composio/client/__init__.py b/python/composio/client/__init__.py index f83335032bf..42994e95e9a 100644 --- a/python/composio/client/__init__.py +++ b/python/composio/client/__init__.py @@ -251,6 +251,19 @@ def execute( :param session_id: ID of the current workspace session :return: Dictionary containing execution result """ + return self._execute( + action, params, connected_account_id, session_id, text, auth + ) + + def _execute( + self, + action: Action, + params: t.Dict, + connected_account_id: t.Optional[str] = None, + session_id: t.Optional[str] = None, + text: t.Optional[str] = None, + auth: t.Optional[CustomAuthObject] = None, + ) -> t.Dict: if action.no_auth: return self.client.actions.execute( action=action, diff --git a/python/composio/client/enums/enum.py b/python/composio/client/enums/enum.py index a37076f9eb0..3e155ec13e9 100644 --- a/python/composio/client/enums/enum.py +++ b/python/composio/client/enums/enum.py @@ -77,6 +77,9 @@ def __hash__(self) -> int: def __repr__(self) -> str: return f"{self.__class__.__name__}.{self.slug}" + def __str__(self) -> str: + return self.slug + def __eq__(self, other: object) -> bool: if isinstance(other, Enum): return self.slug == other.slug diff --git a/python/composio/tools/base/abs.py b/python/composio/tools/base/abs.py index f1a14efd9de..bbcaf0c04ee 100644 --- a/python/composio/tools/base/abs.py +++ b/python/composio/tools/base/abs.py @@ -40,6 +40,7 @@ def remove_json_ref(data: t.Dict) -> t.Dict: jsonref.replace_refs( obj=data, lazy_load=False, + merge_props=True, ), indent=2, ) diff --git a/python/composio/tools/toolset.py b/python/composio/tools/toolset.py index 0bf2d153871..144ceaee8f4 100644 --- a/python/composio/tools/toolset.py +++ b/python/composio/tools/toolset.py @@ -489,7 +489,8 @@ def _execute_remote( if auth is None: self.check_connected_account(action=action) - output = self.client.get_entity(id=entity_id).execute( + entity = self.client.get_entity(id=entity_id) + output = entity._execute( # pylint: disable=protected-access action=action, params=params, connected_account_id=connected_account_id, diff --git a/python/composio/utils/warnings.py b/python/composio/utils/warnings.py index 223344b8dd8..5e90907ca45 100644 --- a/python/composio/utils/warnings.py +++ b/python/composio/utils/warnings.py @@ -24,17 +24,14 @@ def _fetch_latest_version(): def create_latest_version_warning_hook(version: str): + if os.environ.get("COMPOSIO_DISABLE_VERSION_CHECK", "false").lower() != "false": + return lambda: None + version_thread = threading.Thread(target=_fetch_latest_version, daemon=True) version_thread.start() def latest_version_warning() -> None: try: - if ( - os.environ.get("COMPOSIO_DISABLE_VERSION_CHECK", "false").lower() - == "true" - ): - return - version_thread.join(timeout=0.1) if _latest_version is None: return diff --git a/python/dockerfiles/Dockerfile b/python/dockerfiles/Dockerfile index 431d1a8d676..f95ce486606 100644 --- a/python/dockerfiles/Dockerfile +++ b/python/dockerfiles/Dockerfile @@ -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.5.48-rc.1 fastapi playwright uvicorn +RUN python -m pip install composio-core[all]==0.6.0 fastapi playwright uvicorn # Install playwright deps RUN playwright install-deps diff --git a/python/plugins/autogen/setup.py b/python/plugins/autogen/setup.py index ee94a9cc509..664cd6dda86 100644 --- a/python/plugins/autogen/setup.py +++ b/python/plugins/autogen/setup.py @@ -9,7 +9,7 @@ setup( name="composio_autogen", - version="0.5.52-rc.2", + version="0.6.0", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio to get an array of tools with your Autogen agent.", @@ -23,7 +23,7 @@ ], python_requires=">=3.9,<4", install_requires=[ - "composio_core>=0.5.50,<=0.5.52-rc.2", + "composio_core>=0.5.0,<=0.6.0", "pyautogen>=0.2.19", "flaml==2.2.0", ], diff --git a/python/plugins/camel/setup.py b/python/plugins/camel/setup.py index e63479ca427..4a8b4c7a3c0 100644 --- a/python/plugins/camel/setup.py +++ b/python/plugins/camel/setup.py @@ -9,7 +9,7 @@ setup( name="composio_camel", - version="0.5.52-rc.2", + version="0.6.0", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio to get an array of tools with your Claude LLMs.", @@ -23,7 +23,7 @@ ], python_requires=">=3.9,<4", install_requires=[ - "composio_core>=0.5.50,<=0.5.52-rc.2", + "composio_core>=0.5.0,<=0.6.0", "camel-ai>=0.1.5.7,<=0.2.2", "pillow", ], diff --git a/python/plugins/claude/setup.py b/python/plugins/claude/setup.py index e63c62ca613..5a844357cea 100644 --- a/python/plugins/claude/setup.py +++ b/python/plugins/claude/setup.py @@ -9,7 +9,7 @@ setup( name="composio_claude", - version="0.5.52-rc.2", + version="0.6.0", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio to get an array of tools with your Claude LLMs.", @@ -22,6 +22,6 @@ "Operating System :: OS Independent", ], python_requires=">=3.9,<4", - install_requires=["composio_openai>=0.5.50,<=0.5.52-rc.2", "anthropic>=0.25.7"], + install_requires=["composio_openai>=0.5.0,<=0.6.0", "anthropic>=0.25.7"], include_package_data=True, ) diff --git a/python/plugins/crew_ai/setup.py b/python/plugins/crew_ai/setup.py index 01b7649ffb8..dbb4c85990d 100644 --- a/python/plugins/crew_ai/setup.py +++ b/python/plugins/crew_ai/setup.py @@ -9,7 +9,7 @@ setup( name="composio_crewai", - version="0.5.52-rc.2", + version="0.6.0", author="Himanshu", author_email="himanshu@composio.dev", description="Use Composio to get an array of tools with your CrewAI agent.", @@ -23,7 +23,7 @@ ], python_requires=">=3.9,<4", install_requires=[ - "composio_langchain>=0.5.50,<=0.5.52-rc.2", + "composio_langchain>=0.5.0,<=0.6.0", "crewai>=0.51.0", ], include_package_data=True, diff --git a/python/plugins/google/setup.py b/python/plugins/google/setup.py index e69346df3f3..a8ec8be22f1 100644 --- a/python/plugins/google/setup.py +++ b/python/plugins/google/setup.py @@ -9,7 +9,7 @@ setup( name="composio_google", - version="0.5.52-rc.2", + version="0.6.0", author="Assistant", author_email="karan@composio.dev", description="Use Composio to get an array of tools with your Google AI Python Gemini model.", @@ -23,7 +23,7 @@ ], python_requires=">=3.9,<4", install_requires=[ - "composio_core>=0.5.50,<=0.5.52-rc.2", + "composio_core>=0.5.0,<=0.6.0", "google-cloud-aiplatform>=1.38.0", ], include_package_data=True, diff --git a/python/plugins/griptape/setup.py b/python/plugins/griptape/setup.py index 59b337a0709..04c1bd1aad1 100644 --- a/python/plugins/griptape/setup.py +++ b/python/plugins/griptape/setup.py @@ -9,7 +9,7 @@ setup( name="composio_griptape", - version="0.5.52-rc.2", + version="0.6.0", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio to get an array of tools with your Griptape wokflow.", @@ -22,6 +22,6 @@ "Operating System :: OS Independent", ], python_requires=">=3.9,<4", - install_requires=["composio_core>=0.5.50,<=0.5.52-rc.2", "griptape>=0.24.2"], + install_requires=["composio_core>=0.5.0,<=0.6.0", "griptape>=0.24.2"], include_package_data=True, ) diff --git a/python/plugins/julep/setup.py b/python/plugins/julep/setup.py index 11ae8128d9e..312c0873a7b 100644 --- a/python/plugins/julep/setup.py +++ b/python/plugins/julep/setup.py @@ -9,7 +9,7 @@ setup( name="composio_julep", - version="0.5.52-rc.2", + version="0.6.0", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio to get an array of tools with your Julep wokflow.", @@ -22,6 +22,6 @@ "Operating System :: OS Independent", ], python_requires=">=3.9,<4", - install_requires=["composio_openai>=0.5.50,<=0.5.52-rc.2", "julep>=0.3.2"], + install_requires=["composio_openai>=0.5.0,<=0.6.0", "julep>=0.3.2"], include_package_data=True, ) diff --git a/python/plugins/langchain/setup.py b/python/plugins/langchain/setup.py index 7afc4349436..21015e2be64 100644 --- a/python/plugins/langchain/setup.py +++ b/python/plugins/langchain/setup.py @@ -9,7 +9,7 @@ setup( name="composio_langchain", - version="0.5.52-rc.2", + version="0.6.0", author="Karan", author_email="karan@composio.dev", description="Use Composio to get an array of tools with your LangChain agent.", @@ -27,7 +27,7 @@ "langchain-openai>=0.0.2.post1", "pydantic>=2.6.4", "langchainhub>=0.1.15", - "composio_core>=0.5.50,<=0.5.52-rc.2", + "composio_core>=0.5.0,<=0.6.0", ], include_package_data=True, ) diff --git a/python/plugins/langgraph/setup.py b/python/plugins/langgraph/setup.py index 4c10dd49cb0..af333023527 100644 --- a/python/plugins/langgraph/setup.py +++ b/python/plugins/langgraph/setup.py @@ -9,7 +9,7 @@ setup( name="composio_langgraph", - version="0.5.52-rc.2", + version="0.6.0", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio to get array of tools with LnagGraph Agent Workflows", @@ -23,7 +23,7 @@ ], python_requires=">=3.9,<4", install_requires=[ - "composio_langchain>=0.5.50,<=0.5.52-rc.2", + "composio_langchain>=0.5.0,<=0.6.0", "langgraph", ], include_package_data=True, diff --git a/python/plugins/llamaindex/setup.py b/python/plugins/llamaindex/setup.py index ee3d0d2ed37..478a33f3734 100644 --- a/python/plugins/llamaindex/setup.py +++ b/python/plugins/llamaindex/setup.py @@ -9,7 +9,7 @@ setup( name="composio_llamaindex", - version="0.5.52-rc.2", + version="0.6.0", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio to get an array of tools with your LlamaIndex agent.", @@ -24,7 +24,7 @@ python_requires=">=3.9,<4", install_requires=[ "llama_index>=0.10.43", - "composio_core>=0.5.50,<=0.5.52-rc.2", + "composio_core>=0.5.0,<=0.6.0", ], include_package_data=True, ) diff --git a/python/plugins/lyzr/setup.py b/python/plugins/lyzr/setup.py index 58180021e2a..5ab06406832 100644 --- a/python/plugins/lyzr/setup.py +++ b/python/plugins/lyzr/setup.py @@ -9,7 +9,7 @@ setup( name="composio_lyzr", - version="0.5.52-rc.2", + version="0.6.0", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio to get an array of tools with your Lyzr workflow.", @@ -25,7 +25,7 @@ install_requires=[ "lyzr-automata>=0.1.3", "pydantic>=2.6.4", - "composio_core>=0.5.50,<=0.5.52-rc.2", + "composio_core>=0.5.0,<=0.6.0", "langchain>=0.1.0", ], include_package_data=True, diff --git a/python/plugins/openai/setup.py b/python/plugins/openai/setup.py index 95b389aa341..9c2b2e6ca94 100644 --- a/python/plugins/openai/setup.py +++ b/python/plugins/openai/setup.py @@ -9,7 +9,7 @@ setup( name="composio_openai", - version="0.5.52-rc.2", + version="0.6.0", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio to get an array of tools with your OpenAI Function Call.", @@ -22,6 +22,6 @@ "Operating System :: OS Independent", ], python_requires=">=3.9,<4", - install_requires=["composio_core>=0.5.50,<=0.5.52-rc.2", "openai"], + install_requires=["composio_core>=0.5.0,<=0.6.0", "openai"], include_package_data=True, ) diff --git a/python/plugins/phidata/setup.py b/python/plugins/phidata/setup.py index e9f2f72a8ae..8a359972cdb 100644 --- a/python/plugins/phidata/setup.py +++ b/python/plugins/phidata/setup.py @@ -9,7 +9,7 @@ setup( name="composio_phidata", - version="0.5.52-rc.2", + version="0.6.0", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio to get an array of tools with your Phidata Plugin.", @@ -23,8 +23,8 @@ ], python_requires=">=3.9,<4", install_requires=[ - "composio_core>=0.5.50,<=0.5.52-rc.2", - "composio_openai>=0.5.50,<=0.5.52-rc.2", + "composio_core>=0.5.0,<=0.6.0", + "composio_openai>=0.5.0,<=0.6.0", "phidata", ], include_package_data=True, diff --git a/python/plugins/praisonai/setup.py b/python/plugins/praisonai/setup.py index acb2e1a5a3f..e48ce36d6a9 100644 --- a/python/plugins/praisonai/setup.py +++ b/python/plugins/praisonai/setup.py @@ -9,7 +9,7 @@ setup( name="composio_praisonai", - version="0.5.52-rc.2", + version="0.6.0", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio Tools to enhance your PraisonAI agents capabilities.", @@ -22,6 +22,6 @@ "Operating System :: OS Independent", ], python_requires=">=3.9", - install_requires=["composio_core>=0.5.50,<=0.5.52-rc.2", "PraisonAI>=0.0.2"], + install_requires=["composio_core>=0.5.0,<=0.6.0", "PraisonAI>=0.0.2"], include_package_data=True, ) diff --git a/python/pytest.ini b/python/pytest.ini index 0abc7484a3d..1e524c1c5f3 100644 --- a/python/pytest.ini +++ b/python/pytest.ini @@ -1,3 +1,4 @@ [pytest] markers = - e2e: marks test which depend on external service as end-to-end + e2e: marks tests which depend on external service as end-to-end + swe: marks swebench tests which run on the remote docker workspace diff --git a/python/scripts/bump.py b/python/scripts/bump.py index 5fa8222afeb..55f88269ad4 100644 --- a/python/scripts/bump.py +++ b/python/scripts/bump.py @@ -83,10 +83,12 @@ def _bump_dockerfile(file: Path, bump_type: BumpType) -> None: content = file.read_text(encoding="utf-8") try: (version_str,) = re.findall( - pattern=r"composio-core\[all\]==(\d+.\d+.\d+) ", string=content + pattern=r"composio-core\[all\]==(\d+\.\d+\.\d+.*?) ", string=content ) except ValueError as error: print(f"{error=}") + global failed + failed = True return version = VersionInfo.parse(version=version_str) print(f"Current version {version}") @@ -103,7 +105,9 @@ def _bump_dockerfile(file: Path, bump_type: BumpType) -> None: def _bump_dockerfiles(bump_type: BumpType) -> None: cwd = Path.cwd() - for setup in (cwd / "dockerfiles").glob("**/Dockerfile*"): + for setup in (cwd / "dockerfiles").glob("**/Dockerfile"): + if setup.suffix == ".ci": + continue _bump_dockerfile(file=setup, bump_type=bump_type) @@ -128,6 +132,9 @@ def bump(bump_type: BumpType) -> None: if __name__ == "__main__": + failed = False bump( bump_type=BumpType(sys.argv[1].replace("--", "")), ) + if failed: + sys.exit(1) diff --git a/python/setup.py b/python/setup.py index 14a743b6e97..3f8c5475a61 100644 --- a/python/setup.py +++ b/python/setup.py @@ -90,7 +90,7 @@ def scan_for_package_data( setup( name="composio_core", - version="0.5.52-rc.2", + version="0.6.0", author="Utkarsh", author_email="utkarsh@composio.dev", description="Core package to act as a bridge between composio platform and other services.", diff --git a/python/swe/setup.py b/python/swe/setup.py index 165929d4043..686377583bb 100644 --- a/python/swe/setup.py +++ b/python/swe/setup.py @@ -35,7 +35,7 @@ def scan_for_package_data( setup( name="swekit", - version="0.2.50-rc.2", + version="0.3.1", author="Shubhra", author_email="shubhra@composio.dev", description="Tools for running a SWE agent using Composio platform", @@ -66,7 +66,7 @@ def scan_for_package_data( "swebench==2.1.0", "datasets>=2.20.0", "gitpython>=3.1.43", - "composio_core>=0.5.50,<=0.5.52-rc.2", + "composio_core>=0.5.0,<=0.6.0", "unidiff==0.7.5", "tqdm==4.66.4", "rich", @@ -75,7 +75,7 @@ def scan_for_package_data( "langgraph": [ "langchain-aws==0.1.17", "langgraph>=0.2.16", - "composio_langgraph>=0.5.50,<=0.5.52-rc.2", + "composio_langgraph>=0.5.0,<=0.6.0", "python-dotenv==1.0.1", ] }, diff --git a/python/swe/tests/test_benchmark.py b/python/swe/tests/test_benchmark.py index 3786b37022a..541e4929c10 100644 --- a/python/swe/tests/test_benchmark.py +++ b/python/swe/tests/test_benchmark.py @@ -24,6 +24,7 @@ def mock_load_dataset(): yield mock +@pytest.mark.swe class TestIntegration: image_name = "composio/swe:testing" diff --git a/python/tests/test_client/test_enum.py b/python/tests/test_client/test_enum.py index 8781dee702b..9209f286982 100644 --- a/python/tests/test_client/test_enum.py +++ b/python/tests/test_client/test_enum.py @@ -117,6 +117,7 @@ def test_tag_enum() -> None: def test_app_enum() -> None: """Test `App` enum.""" assert App.GITHUB == "GITHUB" + assert str(App.GITHUB) == "GITHUB" assert not App.GITHUB.is_local assert App("OUTLOOK") == App.OUTLOOK assert App("gmail") == App.GMAIL diff --git a/python/tests/test_tools/test_toolset.py b/python/tests/test_tools/test_toolset.py index b14c39bb474..2e3bc8961aa 100644 --- a/python/tests/test_tools/test_toolset.py +++ b/python/tests/test_tools/test_toolset.py @@ -120,7 +120,7 @@ def test_invalid_account_id(self) -> None: with pytest.raises( ComposioSDKError, match=re.escape( - f"Invalid connected accounts found: [('App.GITHUB', '{self.connected_account}')]" + f"Invalid connected accounts found: [('GITHUB', '{self.connected_account}')]" ), ): ComposioToolSet( diff --git a/python/tox.ini b/python/tox.ini index f6294b70329..16107460eab 100644 --- a/python/tox.ini +++ b/python/tox.ini @@ -117,21 +117,21 @@ deps = tqdm==4.66.4 commands = ; Install swekit - pip install -e swe/ --no-deps + uv pip install -e swe/ --no-deps ; TODO: Extract plugin tests separately ; Installing separately because of the dependency conflicts - pip install plugins/langchain --no-deps + uv pip install plugins/langchain --no-deps pytest -vvv -rfE --doctest-modules composio/ tests/ swe/tests --junitxml=junit.xml --cov=composio --cov=examples --cov=swe --cov-report=html --cov-report=xml --cov-report=term --cov-report=term-missing --cov-config=.coveragerc {posargs} - ; pip3 install plugins/autogen - ; pip3 install plugins/claude - ; pip3 install plugins/crew_ai - ; pip3 install plugins/griptape - ; pip3 install plugins/julep - ; pip3 install plugins/lyzr - ; pip3 install plugins/openai + ; uv pip install plugins/autogen + ; uv pip install plugins/claude + ; uv pip install plugins/crew_ai + ; uv pip install plugins/griptape + ; uv pip install plugins/julep + ; uv pip install plugins/lyzr + ; uv pip install plugins/openai ; Linter config