diff --git a/python/Makefile b/python/Makefile index de102e65a5..e00d7250af 100644 --- a/python/Makefile +++ b/python/Makefile @@ -83,11 +83,7 @@ fmt: format-code .PHONY: check-code check-code: - tox -e isort-check - tox -e black-check - tox -e flake8 - tox -e mypy - tox -e pylint + tox run-parallel -e isort-check,black-check,flake8,mypy,pylint .PHONY: chk chk: check-code diff --git a/python/composio/client/enums/base.py b/python/composio/client/enums/base.py index 70d36cd5e3..c6330fea6b 100644 --- a/python/composio/client/enums/base.py +++ b/python/composio/client/enums/base.py @@ -2,6 +2,7 @@ Enum helper base. """ +import os import typing as t import warnings from pathlib import Path @@ -25,6 +26,10 @@ ACTIONS_CACHE = LOCAL_CACHE_DIRECTORY / "actions" TRIGGERS_CACHE = LOCAL_CACHE_DIRECTORY / "triggers" +NO_REMOTE_ENUM_FETCHING = ( + os.environ.get("COMPOSIO_NO_REMOTE_ENUM_FETCHING", "false") == "true" +) + class EnumStringNotFound(ComposioSDKError): """Raise when user provides invalid enum string.""" @@ -197,6 +202,16 @@ def _cache_from_local(self) -> t.Optional[EntityType]: return None def _cache_from_remote(self) -> EntityType: + if NO_REMOTE_ENUM_FETCHING: + raise ComposioSDKError( + message=( + f"No metadata found for enum `{self.slug}`, " + "You might be trying to use an app or action " + "that is deprecated, run `composio apps update` " + "and try again" + ) + ) + from composio.client import Composio # pylint: disable=import-outside-toplevel from composio.client.endpoints import ( # pylint: disable=import-outside-toplevel v2, diff --git a/python/plugins/claude/claude_demo.py b/python/plugins/claude/claude_demo.py index 691431fdfe..aff2c88b65 100644 --- a/python/plugins/claude/claude_demo.py +++ b/python/plugins/claude/claude_demo.py @@ -1,11 +1,11 @@ """ -Anthropic claude demo. +Anthropic claude demo.7 """ import anthropic import dotenv -from composio_claude import App, ComposioToolset +from composio_claude import App, ComposioToolSet # Load environment variables from .env @@ -13,7 +13,7 @@ # Initialize tools. claude_client = anthropic.Anthropic() -composio_toolset = ComposioToolset() +composio_toolset = ComposioToolSet() # Define task. task = "Star a repo composiohq/composio on GitHub" @@ -21,8 +21,17 @@ # Get GitHub tools that are pre-configured actions = composio_toolset.get_tools(apps=[App.GITHUB]) +# Get executor +try: + # anthropic<0.27.0 + executor = claude_client.beta.tools +except AttributeError: + # anthropic>=0.27.0 + executor = claude_client + + # Get response from the LLM -response = claude_client.beta.tools.messages.create( +response = executor.messages.create( model="claude-3-opus-20240229", max_tokens=1024, tools=actions, diff --git a/python/plugins/claude/composio_claude/__init__.py b/python/plugins/claude/composio_claude/__init__.py index 3e40c033cd..b7507b260a 100644 --- a/python/plugins/claude/composio_claude/__init__.py +++ b/python/plugins/claude/composio_claude/__init__.py @@ -1,6 +1,9 @@ from composio import Action, App, Tag, Trigger, WorkspaceType -from composio_claude.toolset import ComposioToolset +from composio_claude.toolset import ComposioToolSet + + +ComposioToolset = ComposioToolSet __all__ = ( @@ -10,4 +13,5 @@ "Trigger", "WorkspaceType", "ComposioToolset", + "ComposioToolSet", ) diff --git a/python/plugins/claude/composio_claude/toolset.py b/python/plugins/claude/composio_claude/toolset.py index ce92bed36f..982c4b68e4 100644 --- a/python/plugins/claude/composio_claude/toolset.py +++ b/python/plugins/claude/composio_claude/toolset.py @@ -1,8 +1,15 @@ import typing as t import typing_extensions as te -from anthropic.types.beta.tools import ToolUseBlock, ToolsBetaMessage -from anthropic.types.beta.tools.tool_param import ToolParam + + +try: + from anthropic.types.beta.tools import ToolUseBlock, ToolsBetaMessage + from anthropic.types.beta.tools.tool_param import ToolParam +except ModuleNotFoundError: + from anthropic.types.tool_use_block import ToolUseBlock + from anthropic.types.tool_param import ToolParam + from anthropic.types.message import Message as ToolsBetaMessage from composio import Action, ActionType, AppType, TagType from composio.constants import DEFAULT_ENTITY_ID @@ -10,7 +17,7 @@ from composio.tools.schema import ClaudeSchema, SchemaType -class ComposioToolset( +class ComposioToolSet( BaseComposioToolSet, runtime="claude", description_char_limit=1024, @@ -22,7 +29,7 @@ class ComposioToolset( ```python import anthropic import dotenv - from composio_claude import App, ComposioToolset + from composio_claude import App, ComposioToolSet # Load environment variables from .env @@ -30,7 +37,7 @@ class ComposioToolset( # Initialize tools. claude_client = anthropic.Anthropic() - composio_tools = ComposioToolset() + composio_tools = ComposioToolSet() # Define task. task = "Star a repo composiohq/composio on GitHub" diff --git a/python/tests/test_client/test_enum.py b/python/tests/test_client/test_enum.py index dc8ef7a6c3..d9b6ae55d2 100644 --- a/python/tests/test_client/test_enum.py +++ b/python/tests/test_client/test_enum.py @@ -5,10 +5,12 @@ from typing import Dict, List from unittest import mock +import pytest from pydantic import BaseModel from composio import action -from composio.client.enums import Action, App, Tag, Trigger +from composio.client.enums import Action, App, Tag, Trigger, base +from composio.exceptions import ComposioSDKError from composio.tools.base.local import LocalAction, LocalTool @@ -83,6 +85,27 @@ def test_load_remote_trigger(self, _patch) -> None: assert enum.slug == Trigger.GITHUB_COMMIT_EVENT.slug +class TestDisableRemoteCaching: + def setup_method(self) -> None: + base.NO_REMOTE_ENUM_FETCHING = True + + def teardown_method(self) -> None: + base.NO_REMOTE_ENUM_FETCHING = False + + def test_error(self) -> None: + """Test `NO_REMOTE_ENUM_FETCHING` set to True.""" + enum = Action.GITHUB_META_ROOT + with pytest.raises( + ComposioSDKError, + match=( + "No metadata found for enum `GITHUB_META_ROOT`, You might be " + "trying to use an app or action that is deprecated, run " + "`composio apps update` and try again" + ), + ): + enum._cache_from_remote() # pylint: disable=protected-access + + def test_tag_enum() -> None: """Test `Tag` enum.""" tag = Tag("ASANA_ALLOCATIONS") diff --git a/python/tests/test_example.py b/python/tests/test_example.py index 5f794b7dcc..7982b7b9bc 100644 --- a/python/tests/test_example.py +++ b/python/tests/test_example.py @@ -145,7 +145,10 @@ "values": ["composio_output/CODEINTERPRETER_GET_FILE_CMD_default_", ""], }, "env": {"OPENAI_API_KEY": OPENAI_API_KEY, "COMPOSIO_API_KEY": COMPOSIO_API_KEY}, - "cwd": EXAMPLES_PATH / "quickstarters" / "sql_agent" / "sql_agent_plotter_crewai", + "cwd": EXAMPLES_PATH + / "quickstarters" + / "sql_agent" + / "sql_agent_plotter_crewai", }, "multi_entity_api_key": { "plugin": "langchain",