diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index b3eec1e0559..062eec85ca9 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -63,7 +63,7 @@ jobs: run: | pip install build twine - plugins="autogen camel claude crew_ai griptape julep langchain llamaindex lyzr openai praisonai langgraph phidata google" + plugins="autogen camel claude crew_ai griptape julep langchain llamaindex lyzr openai praisonai langgraph phidata google gemini agno" mkdir plugins_dist for plugin in $plugins; do cd plugins/$plugin diff --git a/docs/framework/phidata.mdx b/docs/framework/agno.mdx similarity index 63% rename from docs/framework/phidata.mdx rename to docs/framework/agno.mdx index dadf77ee7fa..dfdd5ace3c5 100644 --- a/docs/framework/phidata.mdx +++ b/docs/framework/agno.mdx @@ -1,22 +1,22 @@ --- -title: "Using Composio With Phidata" -sidebarTitle: "Phidata" -description: "Integrate Composio with Phidata agents to let them seamlessly interact with external apps" +title: "Using Composio With Agno" +sidebarTitle: "Agno" +description: "Integrate Composio with Agno agents to let them seamlessly interact with external apps" --- -## Star A Repository on Github -In this example, we will use Phidata Agent to star a repository on Github using Composio Tools +## Star A Repository on GitHub +In this example, we will use Agno Agent to star a repository on GitHub using Composio Tools ```bash Python -pip install composio-phidata +pip install composio-agno openai ``` ```python Python -from phi.assistant import Assistant -from composio_phidata import Action, App, ComposioToolSet +from agno.agent.agent import Agent +from composio_agno import Action, App, ComposioToolSet toolset = ComposioToolSet() ``` @@ -39,20 +39,20 @@ Don't forget to set your `COMPOSIO_API_KEY` and `OPENAI_API_KEY` in your environ - + You can get all the tools for a given app as shown below, but you can get **specific actions** and filter actions using **usecase** & **tags**. Learn more [here](../../patterns/tools/use-tools/use-specific-actions) ```python Python -composio_tools = toolset.get_tools(apps=[App.GITHUB]) +tools = toolset.get_tools(apps=[App.GITHUB]) ``` ```python Python -assistant = Assistant(tools=composio_tools, show_tool_calls=True) +agent = Agent(tools=tools, show_tool_calls=True) ``` ```python Python -assistant.print_response("Can you star composiohq/composio repo?") +agent.print_response("Can you star ComposioHQ/composio repo?") ``` \ No newline at end of file diff --git a/docs/framework/gemini.mdx b/docs/framework/gemini.mdx new file mode 100644 index 00000000000..fa4a1636f0e --- /dev/null +++ b/docs/framework/gemini.mdx @@ -0,0 +1,66 @@ +--- +title: "Using Composio With Gemini" +sidebarTitle: "Gemini" +description: "Integrate Composio with Gemini to let them seamlessly interact with external Apps" +--- + +## Star A Repository on GitHub +In this example, we will use Gemini to star a repository on GitHub using Composio Tools + + + +```bash Python +pip install composio-gemini +``` + + +```bash Python +from google.genai import types +from google import genai +from composio_gemini import Action, ComposioToolSet, App + +client = genai.Client(api_key="") +toolset = ComposioToolSet(api_key="") +``` + + +You need to have an active GitHub Integration. Learn how to do this [here](https://youtu.be/LmyWy4LiedQ?si=u5uFArlNL0tew0Wf) + +```shell CLI +composio login +composio add github +``` +```python Python +request = toolset.initiate_connection(app=App.GITHUB) +print(f"Open this URL to authenticate: {request.redirectUrl}") +``` + + +Don't forget to set your `COMPOSIO_API_KEY` and `GEMINI_API_KEY` in your environment variables. + + + + +You can get all the tools for a given app or specific actions as shown below. Learn more [here](../../patterns/tools/use-tools/use-specific-actions) +```python Python +tools = toolset.get_tools( + apps=[ + App.GITHUB + ] +) + +config = types.GenerateContentConfig(tools=tools) +``` + + +```python Python +chat = client.chats.create(model="gemini-2.0-flash", config=config) + +response = chat.send_message( + "Can you star composiohq/composio repository on github", +) + +print(response.text) +``` + + \ No newline at end of file diff --git a/docs/framework/groq.mdx b/docs/framework/groq.mdx index 8c08cf43f76..56a8f8f256d 100644 --- a/docs/framework/groq.mdx +++ b/docs/framework/groq.mdx @@ -1,5 +1,5 @@ --- -title: "🦜🔗 Using Composio With Groq" +title: "Using Composio With Groq" sidebarTitle: "Groq" description: "Integrate Composio with Groq to seamlessly interact with external apps" --- diff --git a/docs/framework/ibm.mdx b/docs/framework/ibm.mdx new file mode 100644 index 00000000000..17bb3764334 --- /dev/null +++ b/docs/framework/ibm.mdx @@ -0,0 +1,125 @@ +--- +title: "Using Composio With IBM" +sidebarTitle: "IBM" +description: "Integrate Composio with IBM's Granite Models to let them seamlessly interact with external apps" +--- + +**Composio enables** **IBM's Granite Models** to **connect** with many **tools**! + +Goal: Star a repository on GitHub with natural language + +## Video Guide + + +### Install Packages & Connect a Tool + +Ensure you have the necessary packages installed and connect your GitHub account to allow your IBM agents to utilize GitHub functionalities. + + ``` bash Run command + pip install composio-langchain + pip install langchain-ibm + + # Connect your GitHub so agents can use it. + composio add github + # Check all different apps which you can connect with + composio apps + ``` + + +### Goal: Prepare your environment by initializing necessary imports from Composio & IBM. + + + + +Prepare your environment by initializing necessary imports from Composio & IBM. + + + ```python Default Imports + from composio_langchain import ComposioToolSet, Action + from langchain_ibm import ChatWatsonx + import os + + os.environ['WATSONX_API_KEY'] = '' #add your ibm api key here + if not os.environ.get('WATSONX_API_KEY'): + raise ValueError("WATSONX_API_KEY environment variable is not set") + ``` + + + + + + + +This step involves fetching and integrating GitHub tools provided by Composio, enabling enhanced functionality for Agent operations. + + + ```python IBM Supported tools from Composio + composio_toolset = ComposioToolSet() + tools = composio_toolset.get_tools( + actions=[Action.GITHUB_ACTIVITY_STAR_REPO_FOR_AUTHENTICATED_USER] + ) + ``` + + + + + + +This step involves configuring and executing the agent to carry out actions, such as starring a GitHub repository. + + + ```python IBM Agent Setup + parameters = { + "decoding_method": "sample", + "max_new_tokens": 100, + "min_new_tokens": 1, + "temperature": 0.5, + "top_k": 50, + "top_p": 1, + } + url = input('Add your IBM Cloud URL here: ') + project_id = input('Add your IBM Project ID here: ') + watsonx_llm = ChatWatsonx( + model_id = 'ibm/granite-3-8b-instruct', + url = url, + project_id = project_id, + ) + + if not url or not project_id: + raise ValueError("IBM Cloud URL and Project ID must be provided") + + llm_with_tools = watsonx_llm.bind_tools(tools) + + + ``` + + + + + + +Execute the following code to execute the agent, ensuring that the intended task has been successfully completed. + + + ```python Agent Execution + response = llm_with_tools.invoke("Star the composiohq/composio repository") + print(response) + ``` + + + + diff --git a/docs/mint.json b/docs/mint.json index 351db4fbe31..185d30f72eb 100644 --- a/docs/mint.json +++ b/docs/mint.json @@ -135,6 +135,7 @@ "pages": [ "framework/autogen", "framework/crewai", + "framework/gemini", "framework/langchain", "framework/langflow", "framework/langgraph", @@ -154,7 +155,8 @@ "framework/phidata", "framework/praisonai", "javascript/vercel", - "framework/google" + "framework/google", + "framework/ibm" ] } ] diff --git a/python/composio/__version__.py b/python/composio/__version__.py index 49e0fc1e094..a5f830a2c0b 100644 --- a/python/composio/__version__.py +++ b/python/composio/__version__.py @@ -1 +1 @@ -__version__ = "0.7.0" +__version__ = "0.7.1" diff --git a/python/composio/client/__init__.py b/python/composio/client/__init__.py index 8a837a4f8dd..9a9afa18fd9 100644 --- a/python/composio/client/__init__.py +++ b/python/composio/client/__init__.py @@ -11,7 +11,7 @@ import requests from composio.client.collections import ( - AUTH_SCHEMES, + AUTH_SCHEME_WITH_INITIATE, Actions, ActiveTriggerModel, ActiveTriggers, @@ -446,9 +446,9 @@ def initiate_connection( app = self.client.apps.get(name=app_name_str) timestamp = datetime.now().strftime("%Y%m%d%H%M%S") if integration is None and auth_mode is not None: - if auth_mode not in AUTH_SCHEMES: + if auth_mode not in AUTH_SCHEME_WITH_INITIATE: raise ComposioClientError( - f"'auth_mode' should be one of {AUTH_SCHEMES}" + f"'auth_mode' should be one of {AUTH_SCHEME_WITH_INITIATE}" ) auth_mode = t.cast(AuthSchemeType, auth_mode) if "OAUTH" not in auth_mode: diff --git a/python/composio/client/collections.py b/python/composio/client/collections.py index 635c6351507..4ed61418e19 100644 --- a/python/composio/client/collections.py +++ b/python/composio/client/collections.py @@ -39,7 +39,8 @@ if t.TYPE_CHECKING: from composio.client import Composio -AUTH_SCHEMES = ("OAUTH2", "OAUTH1", "API_KEY", "BASIC", "BEARER_TOKEN") +ALL_AUTH_SCHEMES = ("OAUTH2", "OAUTH1", "API_KEY", "BASIC", "BEARER_TOKEN", "NO_AUTH") +AUTH_SCHEME_WITH_INITIATE = ("OAUTH2", "OAUTH1", "API_KEY", "BASIC", "BEARER_TOKEN") AuthSchemeType = t.Literal[ "OAUTH2", "OAUTH1", "API_KEY", "BASIC", "BEARER_TOKEN", "BASIC_WITH_JWT", "NO_AUTH" ] diff --git a/python/composio/tools/toolset.py b/python/composio/tools/toolset.py index 3227a07c36f..2b068f56606 100644 --- a/python/composio/tools/toolset.py +++ b/python/composio/tools/toolset.py @@ -24,7 +24,8 @@ from composio import Action, ActionType, App, AppType, TagType from composio.client import Composio, Entity from composio.client.collections import ( - AUTH_SCHEMES, + ALL_AUTH_SCHEMES, + AUTH_SCHEME_WITH_INITIATE, ActionModel, ActiveTriggerModel, AppAuthScheme, @@ -1111,7 +1112,7 @@ def get_auth_scheme_for_app( if auth_scheme is not None: return auth_schemes[auth_scheme] - for scheme in AUTH_SCHEMES: + for scheme in ALL_AUTH_SCHEMES: if scheme in auth_schemes: scheme = t.cast(AuthSchemeType, scheme) return auth_schemes[scheme] @@ -1273,6 +1274,12 @@ def create_integration( force_new_integration=force_new_integration, ) + def _validate_no_auth_scheme(self, auth_scheme): + if auth_scheme == "NO_AUTH": + raise ComposioSDKError( + "'NO_AUTH' does not require initiating a connection. Please use the `execute_action` method directly to execute actions for this app." + ) + def initiate_connection( self, integration_id: t.Optional[str] = None, @@ -1296,8 +1303,11 @@ def initiate_connection( :param auth_scheme: (Optional[AuthSchemeType]): Authentication scheme to use :return: (ConnectionRequestModel) Details of the connection request. """ - if auth_scheme is not None and auth_scheme not in AUTH_SCHEMES: - raise ComposioSDKError(f"'auth_scheme' must be one of {AUTH_SCHEMES}") + if auth_scheme is not None and auth_scheme not in AUTH_SCHEME_WITH_INITIATE: + self._validate_no_auth_scheme(auth_scheme) + raise ComposioSDKError( + f"'auth_scheme' must be one of {AUTH_SCHEME_WITH_INITIATE}" + ) if integration_id is None: if app is None: @@ -1308,6 +1318,12 @@ def initiate_connection( if auth_scheme is None: auth_scheme = self.get_auth_scheme_for_app(app).auth_mode + if auth_scheme is not None and auth_scheme not in AUTH_SCHEME_WITH_INITIATE: + self._validate_no_auth_scheme(auth_scheme) + raise ComposioSDKError( + f"'auth_scheme' must be one of {AUTH_SCHEME_WITH_INITIATE}" + ) + try: integration_id = self._get_integration_for_app( app=t.cast( diff --git a/python/dockerfiles/Dockerfile b/python/dockerfiles/Dockerfile index 5f7adb6ee12..460169c6ca2 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.7.0 fastapi playwright uvicorn +RUN python -m pip install composio-core[all]==0.7.1 fastapi playwright uvicorn # Install playwright deps RUN playwright install-deps diff --git a/python/examples/advanced_agents/domain_deep_research/readme.md b/python/examples/advanced_agents/domain_deep_research/readme.md index 68bd8cb6270..ccfbbc47037 100644 --- a/python/examples/advanced_agents/domain_deep_research/readme.md +++ b/python/examples/advanced_agents/domain_deep_research/readme.md @@ -25,6 +25,6 @@ Now, fill in the `.env` file with your secrets. ### 2. Run the Python Script ```shell -python cookbook/python-examples/advanced_agents/deepseek_research/main.py +python cookbook/python-examples/advanced_agents/domain_deep_research/main.py ``` diff --git a/python/examples/advanced_agents/domain_deep_research/setup.sh b/python/examples/advanced_agents/domain_deep_research/setup.sh index 8bcfc26006a..f707d080494 100644 --- a/python/examples/advanced_agents/domain_deep_research/setup.sh +++ b/python/examples/advanced_agents/domain_deep_research/setup.sh @@ -2,11 +2,11 @@ # Create a virtual environment echo "Creating virtual environment..." -python3 -m venv ~/.venvs/finance_researcher +python3 -m venv ~/.venvs/domain_researcher # Activate the virtual environment echo "Activating virtual environment..." -source ~/.venvs/finance_researcher/bin/activate +source ~/.venvs/domain_researcher/bin/activate # Install libraries from requirements.txt echo "Installing libraries from requirements.txt..." diff --git a/python/plugins/agno/README.md b/python/plugins/agno/README.md new file mode 100644 index 00000000000..8cb941e89c0 --- /dev/null +++ b/python/plugins/agno/README.md @@ -0,0 +1,54 @@ +## 🚀🔗 Leveraging Agno with Composio + +Facilitate the integration of Agno with Composio to empower LLMs to directly interact with external applications & knowledge base, broadening their capabilities and application scope. + +### Objective + +- **Automate starring a GitHub repository** using conversational instructions via Agno Tool Calls. + +### Installation and Setup + +Ensure you have the necessary packages installed and connect your GitHub account to allow your agents to utilize GitHub functionalities. + +```bash +# Install Composio LangChain package +pip install composio-agno + +# Connect your GitHub account +composio add github + +# View available applications you can connect with +composio apps +``` + +### Usage Steps + +#### 1. Import Base Packages + +Prepare your environment by initializing necessary imports from Agno. + +```python +from agno.agent import Agent +``` + +### Step 2: Integrating GitHub Tools with Composio + +This step involves fetching and integrating GitHub tools provided by Composio, enabling enhanced functionality for LangChain operations. +```python +from composio_agno import ComposioToolSet, Action + +toolset = ComposioToolSet() +composio_tools = toolset.get_actions(actions=[Action.GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER]) +``` + +### Step 3: Agent Execution + +This step involves configuring and executing the assistant to carry out actions, such as starring a GitHub repository. + +```python + +# Create a chat completion request to decide on the action +agent = Agent(tools=composio_tools, show_tool_calls=True) + +agent.print_response("Can you star ComposioHQ/composio repo?") +``` \ No newline at end of file diff --git a/python/plugins/agno/agno_demo.py b/python/plugins/agno/agno_demo.py new file mode 100644 index 00000000000..c06fe508a2e --- /dev/null +++ b/python/plugins/agno/agno_demo.py @@ -0,0 +1,10 @@ +from agno.agent import Agent +from composio_agno.toolset import Action, ComposioToolSet + + +toolset = ComposioToolSet() +composio_tools = toolset.get_tools(actions=[Action.GMAIL_GET_PROFILE]) + +agent = Agent(tools=composio_tools, show_tool_calls=True) + +agent.print_response("Can you get my profile") diff --git a/python/plugins/agno/composio_agno/__init__.py b/python/plugins/agno/composio_agno/__init__.py new file mode 100644 index 00000000000..df9d94264c2 --- /dev/null +++ b/python/plugins/agno/composio_agno/__init__.py @@ -0,0 +1,14 @@ +from composio_agno.toolset import ComposioToolSet + +from composio import Action, App, Tag, Trigger, WorkspaceType, action + + +__all__ = ( + "Action", + "App", + "Tag", + "ComposioToolSet", + "WorkspaceType", + "action", + "Trigger", +) diff --git a/python/plugins/agno/composio_agno/toolset.py b/python/plugins/agno/composio_agno/toolset.py new file mode 100644 index 00000000000..14f4b7c837a --- /dev/null +++ b/python/plugins/agno/composio_agno/toolset.py @@ -0,0 +1,144 @@ +""" +Agno tool spec. +""" + +import json +import typing as t +from inspect import Signature + +from agno.tools.function import Function +from agno.tools.toolkit import Toolkit +from pydantic import validate_call +from typing_extensions import Protocol + +from composio import Action, ActionType, AppType +from composio import ComposioToolSet as BaseComposioToolSet +from composio import TagType +from composio.tools.toolset import ProcessorsType +from composio.utils import shared + + +class ToolFunction(Protocol): + """Protocol for tool functions with required attributes.""" + + __signature__: Signature + __annotations__: t.Dict[str, t.Any] + __doc__: str + + def __call__(self, *args: t.Any, **kwargs: t.Any) -> str: ... + + +class ComposioToolSet( + BaseComposioToolSet, + runtime="agno", + description_char_limit=1024, + action_name_char_limit=64, +): + """ + Composio toolset for Agno framework. + """ + + def _wrap_tool( + self, + schema: t.Dict, + entity_id: t.Optional[str] = None, + ) -> Toolkit: + """ + Wrap composio tool as Agno `Toolkit` object. + """ + name = schema["name"] + description = schema["description"] + parameters = schema["parameters"] + + # Create a new Toolkit instance + toolkit = Toolkit(name=name) + + # Get function parameters from schema + params = shared.get_signature_format_from_schema_params(parameters) + + # Create function signature and annotations + sig = Signature(parameters=params) + annotations = {p.name: p.annotation for p in params} + annotations["return"] = str # Add return type annotation + + @validate_call + def function_template(*args, **kwargs) -> str: + # Bind the arguments to the signature + bound_args = sig.bind(*args, **kwargs) + bound_args.apply_defaults() + + return json.dumps( + self.execute_action( + action=Action(value=name), + params=bound_args.arguments, + entity_id=entity_id or self.entity_id, + _check_requested_actions=True, + ) + ) + + # Cast the function to our Protocol type to satisfy mypy + func = t.cast(ToolFunction, function_template) + + # Apply the signature and annotations to the function + func.__signature__ = sig + func.__annotations__ = annotations + func.__setattr__("__name__", name.lower()) + + # Format docstring in Agno standard format + docstring_parts = [description, "\nArgs:"] + if "properties" in parameters: + for param_name, param_info in parameters["properties"].items(): + param_desc = param_info.get("description", "No description available") + param_type = param_info.get("type", "any") + docstring_parts.append(f" {param_name} ({param_type}): {param_desc}") + + docstring_parts.append( + "\nReturns:\n str: JSON string containing the function execution result" + ) + func.__doc__ = "\n".join(docstring_parts) + + # Register the function with the toolkit + toolkit.register(func) + + return toolkit + + def get_tools( + self, + actions: t.Optional[t.Sequence[ActionType]] = None, + apps: t.Optional[t.Sequence[AppType]] = None, + tags: t.Optional[t.List[TagType]] = None, + *, + processors: t.Optional[ProcessorsType] = None, + check_connected_accounts: bool = True, + ) -> t.List[t.Union[Toolkit, t.Callable, t.Dict, Function]]: + """ + Get composio tools wrapped as Agno `Toolkit` objects. + + Args: + actions: List of actions to wrap + apps: List of apps to wrap + tags: Filter the apps by given tags + processors: Optional processors to apply + check_connected_accounts: Whether to check for connected accounts + + Returns: + List[Toolkit]: Composio tools wrapped as `Toolkit` objects + """ + self.validate_tools(apps=apps, actions=actions, tags=tags) + if processors is not None: + self._processor_helpers.merge_processors(processors) + return [ + self._wrap_tool( + schema=schema.model_dump( + exclude_none=True, + ), + entity_id=self.entity_id, + ) + for schema in self.get_action_schemas( + actions=actions, + apps=apps, + tags=tags, + check_connected_accounts=check_connected_accounts, + _populate_requested=True, + ) + ] diff --git a/python/plugins/agno/setup.py b/python/plugins/agno/setup.py new file mode 100644 index 00000000000..e4f0b38c220 --- /dev/null +++ b/python/plugins/agno/setup.py @@ -0,0 +1,29 @@ +""" +Setup configuration for Composio Agno plugin. +""" + +from pathlib import Path + +from setuptools import setup + + +setup( + name="composio_agno", + version="0.7.1", + author="Devanshu", + author_email="tech@composio.dev", + description="Use Composio to get an array of tools with your Agno Plugin.", + long_description=(Path(__file__).parent / "README.md").read_text(encoding="utf-8"), + long_description_content_type="text/markdown", + url="https://github.com/ComposioHQ/composio", + classifiers=[ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: Apache Software License", + "Operating System :: OS Independent", + ], + install_requires=[ + "composio_core>=0.7.0,<0.8.0", + "agno", + ], + include_package_data=True, +) diff --git a/python/plugins/autogen/setup.py b/python/plugins/autogen/setup.py index df3f617c5cb..fec8cad89b8 100644 --- a/python/plugins/autogen/setup.py +++ b/python/plugins/autogen/setup.py @@ -9,7 +9,7 @@ setup( name="composio_autogen", - version="0.7.0", + version="0.7.1", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio to get an array of tools with your Autogen agent.", diff --git a/python/plugins/camel/setup.py b/python/plugins/camel/setup.py index 7b074ce292f..4e719754fe4 100644 --- a/python/plugins/camel/setup.py +++ b/python/plugins/camel/setup.py @@ -9,7 +9,7 @@ setup( name="composio_camel", - version="0.7.0", + version="0.7.1", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio to get an array of tools with your Claude LLMs.", diff --git a/python/plugins/claude/setup.py b/python/plugins/claude/setup.py index 0fb6c76b357..8a6b21e7aef 100644 --- a/python/plugins/claude/setup.py +++ b/python/plugins/claude/setup.py @@ -9,7 +9,7 @@ setup( name="composio_claude", - version="0.7.0", + version="0.7.1", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio to get an array of tools with your Claude LLMs.", diff --git a/python/plugins/crew_ai/setup.py b/python/plugins/crew_ai/setup.py index 92712372f61..d87e0b0720d 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.7.0", + version="0.7.1", author="Himanshu", author_email="himanshu@composio.dev", description="Use Composio to get an array of tools with your CrewAI agent.", diff --git a/python/plugins/gemini/README.md b/python/plugins/gemini/README.md new file mode 100644 index 00000000000..55ee8bc5c57 --- /dev/null +++ b/python/plugins/gemini/README.md @@ -0,0 +1,72 @@ +## 🚀🔗 Integrating Composio with Google's Gemini SDK + +Streamline the integration of Composio with Google AI Python to enhance the capabilities of Gemini models, allowing them to interact directly with external applications and expanding their operational scope. + +### Objective + +- **Automate starring a GitHub repository** using conversational instructions via Google AI Python's Function Calling feature. + +### Installation and Setup + +Ensure you have the necessary packages installed and connect your GitHub account to allow your agents to utilize GitHub functionalities. + +```bash +# Install Composio Gemini package +pip install composio-gemini + +# Connect your GitHub account +composio add github + +# View available applications you can connect with +composio apps +``` + +### Usage Steps + +#### 1. Import Base Packages + +Prepare your environment by initializing necessary imports from Google AI Python and setting up your client. + +```python +from google import genai + +# Create google client +client = genai.Client() +``` + +### Step 2: Integrating GitHub Tools with Composio + +This step involves fetching and integrating GitHub tools provided by Composio, enabling enhanced functionality for Google AI Python operations. +```python +from google.genai import types + +from composio_gemini import Action, ComposioToolSet + +# Create composio client +toolset = ComposioToolSet() + +# Create tools +tools = toolset.get_tools( + actions=[ + Action.GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER, + ] +) + +# Create genai client config +config = types.GenerateContentConfig( + tools=tools, # type: ignore +) +``` + +### Step 3: Agent Execution + +This step involves configuring and executing the agent to carry out actions, such as starring a GitHub repository. + +```python +# Use the chat interface. +chat = client.chats.create(model="gemini-2.0-flash", config=config) +response = chat.send_message( + "Can you star composiohq/composio repository on github", +) +print(response.text) +``` diff --git a/python/plugins/gemini/composio_gemini/__init__.py b/python/plugins/gemini/composio_gemini/__init__.py new file mode 100644 index 00000000000..8b798ffe3ab --- /dev/null +++ b/python/plugins/gemini/composio_gemini/__init__.py @@ -0,0 +1,14 @@ +from composio import Action, App, Tag, Trigger, WorkspaceType, action + +from .toolset import ComposioToolSet + + +__all__ = ( + "Action", + "App", + "Tag", + "Trigger", + "WorkspaceType", + "action", + "ComposioToolSet", +) diff --git a/python/plugins/gemini/composio_gemini/toolset.py b/python/plugins/gemini/composio_gemini/toolset.py new file mode 100644 index 00000000000..69e66716bb1 --- /dev/null +++ b/python/plugins/gemini/composio_gemini/toolset.py @@ -0,0 +1,118 @@ +import types +import typing as t +from inspect import Signature + +from composio import ActionType, AppType, TagType +from composio.client.collections import ActionModel +from composio.tools import ComposioToolSet as BaseComposioToolSet +from composio.utils.shared import get_signature_format_from_schema_params + + +class ComposioToolSet( + BaseComposioToolSet, + runtime="google_gemini", + description_char_limit=1024, + action_name_char_limit=64, +): + """ + Composio toolset for Google AI Python Gemini framework. + + Example: + ```python + from google import genai + from google.genai import types + + from composio_gemini import Action, ComposioToolSet + + + # Create composio client + toolset = ComposioToolSet() + + # Create google client + client = genai.Client() + + # Create genai client config + config = types.GenerateContentConfig( + tools=toolset.get_tools( # type: ignore + actions=[ + Action.GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER, + ] + ) + ) + # Use the chat interface. + chat = client.chats.create(model="gemini-2.0-flash", config=config) + response = chat.send_message( + "Can you star composiohq/composio repository on github", + ) + print(response.text) + ``` + """ + + def _wrap_tool( + self, + schema: ActionModel, + entity_id: t.Optional[str] = None, + ) -> t.Callable: + """Wraps composio tool as Google Genai SDK compatible function calling object.""" + + docstring = schema.description + docstring += "\nArgs:" + for _param, _schema in schema.parameters.properties.items(): + docstring += "\n " + docstring += _param + ": " + _schema.get("description", _param.title()) + + docstring += "\nReturns:" + docstring += "\n A dictionary containing response from the action" + + def _execute(**kwargs: t.Any) -> t.Dict: + return self.execute_action( + action=schema.name, + params=kwargs, + entity_id=entity_id, + ) + + function = types.FunctionType( + code=_execute.__code__, + name=schema.name, + globals=globals(), + closure=_execute.__closure__, + ) + parameters = get_signature_format_from_schema_params( + schema_params=schema.parameters.model_dump(), + ) + setattr(function, "__signature__", Signature(parameters=parameters)) + setattr( + function, + "__annotations__", + {p.name: p.annotation for p in parameters} | {"return": dict}, + ) + function.__doc__ = docstring + return function + + def get_tools( + self, + actions: t.Optional[t.Sequence[ActionType]] = None, + apps: t.Optional[t.Sequence[AppType]] = None, + tags: t.Optional[t.List[TagType]] = None, + entity_id: t.Optional[str] = None, + ) -> t.List[t.Callable]: + """ + Get composio tools wrapped as Google Genai SDK compatible function calling object. + + :param actions: List of actions to wrap + :param apps: List of apps to wrap + :param tags: Filter the apps by given tags + :param entity_id: Entity ID for the function wrapper + + :return: Composio tools wrapped as python callable + """ + self.validate_tools(apps=apps, actions=actions, tags=tags) + return [ + self._wrap_tool(schema=tool, entity_id=entity_id) + for tool in self.get_action_schemas( + actions=actions, + apps=apps, + tags=tags, + _populate_requested=True, + ) + ] diff --git a/python/plugins/gemini/demo.py b/python/plugins/gemini/demo.py new file mode 100644 index 00000000000..c46851be797 --- /dev/null +++ b/python/plugins/gemini/demo.py @@ -0,0 +1,25 @@ +from composio_gemini import Action, ComposioToolSet +from google import genai +from google.genai import types + + +# Create composio client +toolset = ComposioToolSet() + +# Create google client +client = genai.Client() + +# Create genai client config +config = types.GenerateContentConfig( + tools=toolset.get_tools( # type: ignore + actions=[ + Action.GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER, + ] + ) +) +# Use the chat interface. +chat = client.chats.create(model="gemini-2.0-flash", config=config) +response = chat.send_message( + "Can you star composiohq/composio repository on github", +) +print(response.text) diff --git a/python/plugins/gemini/setup.py b/python/plugins/gemini/setup.py new file mode 100644 index 00000000000..f9924a5efd8 --- /dev/null +++ b/python/plugins/gemini/setup.py @@ -0,0 +1,30 @@ +""" +Setup configuration for Composio Gemin plugin +""" + +from pathlib import Path + +from setuptools import setup + + +setup( + name="composio_gemini", + version="0.7.1", + author="Composio", + author_email="tech@composio.dev", + description="Use Composio to get an array of tools with your Gemini agent.", + long_description=(Path(__file__).parent / "README.md").read_text(encoding="utf-8"), + long_description_content_type="text/markdown", + url="https://github.com/ComposioHQ/composio", + classifiers=[ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: Apache Software License", + "Operating System :: OS Independent", + ], + python_requires=">=3.9,<4", + install_requires=[ + "composio_core>=0.7.0,<0.8.0", + "google-genai", + ], + include_package_data=True, +) diff --git a/python/plugins/google/setup.py b/python/plugins/google/setup.py index 2ba269f2825..81a19ddede0 100644 --- a/python/plugins/google/setup.py +++ b/python/plugins/google/setup.py @@ -9,7 +9,7 @@ setup( name="composio_google", - version="0.7.0", + version="0.7.1", author="Assistant", author_email="karan@composio.dev", description="Use Composio to get an array of tools with your Google AI Python Gemini model.", diff --git a/python/plugins/griptape/setup.py b/python/plugins/griptape/setup.py index 6b01dd02f76..df3bf33e791 100644 --- a/python/plugins/griptape/setup.py +++ b/python/plugins/griptape/setup.py @@ -9,7 +9,7 @@ setup( name="composio_griptape", - version="0.7.0", + version="0.7.1", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio to get an array of tools with your Griptape workflow.", diff --git a/python/plugins/julep/setup.py b/python/plugins/julep/setup.py index 564f58bb6f4..cbb4ccd29ff 100644 --- a/python/plugins/julep/setup.py +++ b/python/plugins/julep/setup.py @@ -9,7 +9,7 @@ setup( name="composio_julep", - version="0.7.0", + version="0.7.1", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio to get an array of tools with your Julep workflow.", diff --git a/python/plugins/langchain/setup.py b/python/plugins/langchain/setup.py index 637b5d0eaa8..9c9698c1edf 100644 --- a/python/plugins/langchain/setup.py +++ b/python/plugins/langchain/setup.py @@ -9,7 +9,7 @@ setup( name="composio_langchain", - version="0.7.0", + version="0.7.1", author="Karan", author_email="karan@composio.dev", description="Use Composio to get an array of tools with your LangChain agent.", diff --git a/python/plugins/langgraph/setup.py b/python/plugins/langgraph/setup.py index 8a514f6b28a..17e8a774cea 100644 --- a/python/plugins/langgraph/setup.py +++ b/python/plugins/langgraph/setup.py @@ -9,7 +9,7 @@ setup( name="composio_langgraph", - version="0.7.0", + version="0.7.1", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio to get array of tools with LangGraph Agent Workflows", diff --git a/python/plugins/llamaindex/setup.py b/python/plugins/llamaindex/setup.py index 3f158347462..319b4b63ccf 100644 --- a/python/plugins/llamaindex/setup.py +++ b/python/plugins/llamaindex/setup.py @@ -9,7 +9,7 @@ setup( name="composio_llamaindex", - version="0.7.0", + version="0.7.1", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio to get an array of tools with your LlamaIndex agent.", diff --git a/python/plugins/lyzr/setup.py b/python/plugins/lyzr/setup.py index ce81c98259a..3a5dbfd4ecf 100644 --- a/python/plugins/lyzr/setup.py +++ b/python/plugins/lyzr/setup.py @@ -9,7 +9,7 @@ setup( name="composio_lyzr", - version="0.7.0", + version="0.7.1", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio to get an array of tools with your Lyzr workflow.", diff --git a/python/plugins/openai/setup.py b/python/plugins/openai/setup.py index 8d8e295354c..867afac937c 100644 --- a/python/plugins/openai/setup.py +++ b/python/plugins/openai/setup.py @@ -9,7 +9,7 @@ setup( name="composio_openai", - version="0.7.0", + version="0.7.1", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio to get an array of tools with your OpenAI Function Call.", diff --git a/python/plugins/phidata/composio_phidata/toolset.py b/python/plugins/phidata/composio_phidata/toolset.py index 104f91567df..0ca4d98c05a 100644 --- a/python/plugins/phidata/composio_phidata/toolset.py +++ b/python/plugins/phidata/composio_phidata/toolset.py @@ -31,6 +31,10 @@ class ToolFunction(Protocol): def __call__(self, *args: t.Any, **kwargs: t.Any) -> str: ... +@te.deprecated( + "composio_phidata is deprecated and will be removed on v0.8.0." + "\nUse composio_agno instead." +) class ComposioToolSet( BaseComposioToolSet, runtime="phidata", diff --git a/python/plugins/phidata/setup.py b/python/plugins/phidata/setup.py index 26ee81107b6..0a6cb980358 100644 --- a/python/plugins/phidata/setup.py +++ b/python/plugins/phidata/setup.py @@ -9,7 +9,7 @@ setup( name="composio_phidata", - version="0.7.0", + version="0.7.1", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio to get an array of tools with your Phidata Plugin.", diff --git a/python/plugins/praisonai/setup.py b/python/plugins/praisonai/setup.py index 329034afe41..77366cb1a0a 100644 --- a/python/plugins/praisonai/setup.py +++ b/python/plugins/praisonai/setup.py @@ -9,7 +9,7 @@ setup( name="composio_praisonai", - version="0.7.0", + version="0.7.1", author="Sawradip", author_email="sawradip@composio.dev", description="Use Composio Tools to enhance your PraisonAI agents capabilities.", diff --git a/python/plugins/pydanticai/setup.py b/python/plugins/pydanticai/setup.py index 89d96c7d24b..05c5b6804db 100644 --- a/python/plugins/pydanticai/setup.py +++ b/python/plugins/pydanticai/setup.py @@ -9,7 +9,7 @@ setup( name="composio_pydanticai", - version="0.7.0", + version="0.7.1", author="Siddharth", author_email="tech@composio.dev", description="Use Composio to get array of strongly typed tools for Pydantic AI", diff --git a/python/setup.py b/python/setup.py index b6bc448393d..d14cad0d7af 100644 --- a/python/setup.py +++ b/python/setup.py @@ -89,7 +89,7 @@ def scan_for_package_data( setup( name="composio_core", - version="0.7.0", + version="0.7.1", 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 f2e1e9cfbce..aa3c7dc6225 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.4.0", + version="0.4.1", author="Shubhra", author_email="shubhra@composio.dev", description="Tools for running a SWE agent using Composio platform",