diff --git a/agentstack/tools/agent_connect/__init__.py b/agentstack/tools/agent_connect/__init__.py index ff40bab5..2bf3115d 100644 --- a/agentstack/tools/agent_connect/__init__.py +++ b/agentstack/tools/agent_connect/__init__.py @@ -5,28 +5,32 @@ # An HTTP and WS service will be started in agent-connect # It can be an IP address or a domain name -host_domain = os.getenv("HOST_DOMAIN") +host_domain = os.getenv("AGENT_CONNECT_HOST_DOMAIN") # Host port, default is 80 -host_port = os.getenv("HOST_PORT") +host_port = os.getenv("AGENT_CONNECT_HOST_PORT") # WS path, default is /ws -host_ws_path = os.getenv("HOST_WS_PATH") +host_ws_path = os.getenv("AGENT_CONNECT_HOST_WS_PATH") # Path to store DID document -did_document_path = os.getenv("DID_DOCUMENT_PATH") +did_document_path = os.getenv("AGENT_CONNECT_DID_DOCUMENT_PATH") # SSL certificate path, if using HTTPS, certificate and key need to be provided -ssl_cert_path = os.getenv("SSL_CERT_PATH") -ssl_key_path = os.getenv("SSL_KEY_PATH") +ssl_cert_path = os.getenv("AGENT_CONNECT_SSL_CERT_PATH") +ssl_key_path = os.getenv("AGENT_CONNECT_SSL_KEY_PATH") if not host_domain: - raise Exception(( - "Host domain has not been provided.\n" - "Did you set the HOST_DOMAIN in you project's .env file?" - )) + raise Exception( + ( + "Host domain has not been provided.\n" + "Did you set the AGENT_CONNECT_HOST_DOMAIN in you project's .env file?" + ) + ) if not did_document_path: - raise Exception(( - "DID document path has not been provided.\n" - "Did you set the DID_DOCUMENT_PATH in you project's .env file?" - )) + raise Exception( + ( + "DID document path has not been provided.\n" + "Did you set the AGENT_CONNECT_DID_DOCUMENT_PATH in you project's .env file?" + ) + ) def generate_did_info(node: SimpleNode, did_document_path: str) -> None: @@ -48,7 +52,7 @@ def generate_did_info(node: SimpleNode, did_document_path: str) -> None: node.set_did_info(private_key_pem, did, did_document_json) # Save DID information - if os.path.dirname(did_document_path): # allow saving to current directory + if os.path.dirname(did_document_path): # allow saving to current directory os.makedirs(os.path.dirname(did_document_path), exist_ok=True) with open(did_document_path, "w") as f: json.dump( diff --git a/agentstack/tools/agent_connect/config.json b/agentstack/tools/agent_connect/config.json index 97e2c589..542c81e8 100644 --- a/agentstack/tools/agent_connect/config.json +++ b/agentstack/tools/agent_connect/config.json @@ -3,12 +3,12 @@ "url": "https://github.com/chgaowei/AgentConnect", "category": "network-protocols", "env": { - "HOST_DOMAIN": null, - "HOST_PORT": 80, - "HOST_WS_PATH": "/ws", - "DID_DOCUMENT_PATH": "data/agent_connect_did.json", - "SSL_CERT_PATH": null, - "SSL_KEY_PATH": null + "AGENT_CONNECT_HOST_DOMAIN": null, + "AGENT_CONNECT_HOST_PORT": 80, + "AGENT_CONNECT_HOST_WS_PATH": "/ws", + "AGENT_CONNECT_DID_DOCUMENT_PATH": "data/agent_connect_did.json", + "AGENT_CONNECT_SSL_CERT_PATH": null, + "AGENT_CONNECT_SSL_KEY_PATH": null }, "dependencies": [ "agent-connect>=0.3.0" diff --git a/agentstack/tools/composio/__init__.py b/agentstack/tools/composio/__init__.py index e69de29b..8b62d046 100644 --- a/agentstack/tools/composio/__init__.py +++ b/agentstack/tools/composio/__init__.py @@ -0,0 +1,75 @@ +"""Framework-agnostic implementation of composio tools.""" + +import os +from typing import Any, Dict, List, Optional + +from composio import Action, ComposioToolSet +from composio.constants import DEFAULT_ENTITY_ID + + +def _check_connected_account(app: str, toolset: ComposioToolSet) -> None: + """Check if connected account exists for the app.""" + connections = toolset.client.connected_accounts.get() + if app not in [connection.appUniqueId for connection in connections]: + raise RuntimeError( + f"No connected account found for app `{app}`; " f"Run `composio add {app}` to fix this" + ) + + +def execute_action( + action_name: str, + params: Dict[str, Any], + entity_id: Optional[str] = None, + no_auth: bool = False, +) -> Dict[str, Any]: + """ + Execute a composio action with given parameters. + + Args: + action_name: Name of the action to execute + params: Parameters for the action + entity_id: Optional entity ID (defaults to DEFAULT_ENTITY_ID) + no_auth: Whether the action requires authentication + + Returns: + Dict containing the action result + """ + toolset = ComposioToolSet() + action = Action(action_name) + + if not no_auth: + _check_connected_account(action.app, toolset) + + return toolset.execute_action( + action=action, + params=params, + entity_id=entity_id or DEFAULT_ENTITY_ID, + ) + + +def get_action_schema(action_name: str) -> Dict[str, Any]: + """Get the schema for a composio action.""" + toolset = ComposioToolSet() + action = Action(action_name) + (action_schema,) = toolset.get_action_schemas(actions=[action]) + return action_schema.model_dump(exclude_none=True) + + +def find_actions_by_use_case( + *apps: str, + use_case: str, +) -> List[Dict[str, Any]]: + """Find actions by use case.""" + toolset = ComposioToolSet() + actions = toolset.find_actions_by_use_case(*apps, use_case=use_case) + return [get_action_schema(action.name) for action in actions] + + +def find_actions_by_tags( + *apps: str, + tags: List[str], +) -> List[Dict[str, Any]]: + """Find actions by tags.""" + toolset = ComposioToolSet() + actions = toolset.find_actions_by_tags(*apps, tags=tags) + return [get_action_schema(action.name) for action in actions] diff --git a/agentstack/tools/composio/config.json b/agentstack/tools/composio/config.json index 5a5dfb33..cc9c2bd6 100644 --- a/agentstack/tools/composio/config.json +++ b/agentstack/tools/composio/config.json @@ -5,7 +5,14 @@ "env": { "COMPOSIO_API_KEY": "..." }, - "tools": ["composio_tools"], - "tools_bundled": true, - "cta": "!!! Composio provides 150+ tools. Additional setup is required in src/tools/composio_tool.py" -} \ No newline at end of file + "tools": [ + "execute_action", + "get_action_schema", + "find_actions_by_use_case", + "find_actions_by_tags" + ], + "dependencies": [ + "composio>=1.0.0" + ], + "cta": "!!! Composio provides 150+ tools. Additional setup is required in agentstack/tools/composio/__init__.py" +} diff --git a/agentstack/tools/composio/crewai.py b/agentstack/tools/composio/crewai.py deleted file mode 100644 index fde2fc88..00000000 --- a/agentstack/tools/composio/crewai.py +++ /dev/null @@ -1,8 +0,0 @@ -from composio_crewai import ComposioToolSet, App - -composio_tools = ComposioToolSet().get_tools(apps=[App.CODEINTERPRETER]) -# composio_tools = ComposioToolSet().get_tools(apps=[App.GITHUB]) -# etc - -# change App.CODEINTERPRETER to be the app you want to use -# For more info on tool selection, see https://docs.agentstack.sh/tools/tool/composio diff --git a/agentstack/tools/composio/pyproject.toml b/agentstack/tools/composio/pyproject.toml deleted file mode 100644 index 4afbc383..00000000 --- a/agentstack/tools/composio/pyproject.toml +++ /dev/null @@ -1,10 +0,0 @@ -[project] -name = "agentstack.composio" -version = "0.1" - -dependencies = [] - -[project.optional-dependencies] -crewai = [ - "composio-crewai" -] diff --git a/agentstack/tools/directory_search/__init__.py b/agentstack/tools/directory_search/__init__.py index e69de29b..2be73688 100644 --- a/agentstack/tools/directory_search/__init__.py +++ b/agentstack/tools/directory_search/__init__.py @@ -0,0 +1,4 @@ +"""Directory search tool for searching through files in a directory.""" +from .directory_search import search_directory, search_fixed_directory + +__all__ = ["search_directory", "search_fixed_directory"] diff --git a/agentstack/tools/directory_search/config.json b/agentstack/tools/directory_search/config.json index b412d03b..d23d6618 100644 --- a/agentstack/tools/directory_search/config.json +++ b/agentstack/tools/directory_search/config.json @@ -1,6 +1,12 @@ { "name": "directory_search", - "url": "https://github.com/crewAIInc/crewAI-tools/tree/main/crewai_tools/tools/directory_search_tool", "category": "computer-control", - "tools": ["dir_search_tool"] -} \ No newline at end of file + "tools": ["search_directory", "search_fixed_directory"], + "description": "Search through files in a directory using embedchain's DirectoryLoader", + "env": { + "DIRECTORY_SEARCH_PATH": "Optional. Path to directory for fixed directory search." + }, + "dependencies": [ + "embedchain>=0.1.0" + ] +} diff --git a/agentstack/tools/directory_search/directory_search.py b/agentstack/tools/directory_search/directory_search.py new file mode 100644 index 00000000..ab846acb --- /dev/null +++ b/agentstack/tools/directory_search/directory_search.py @@ -0,0 +1,34 @@ +"""Framework-agnostic directory search implementation using embedchain.""" +import os +from embedchain import DirectoryLoader + +def search_directory(directory: str, query: str) -> str: + """Search through files in a specified directory using embedchain's DirectoryLoader. + + Args: + directory: Path to the directory to search + query: Search query string + + Returns: + str: Search results as a string + """ + loader = DirectoryLoader(directory) + results = loader.search(query) + return str(results) + +def search_fixed_directory(query: str) -> str: + """Search through files in a preconfigured directory using embedchain's DirectoryLoader. + + Args: + query: Search query string + + Returns: + str: Search results as a string + + Raises: + ValueError: If DIRECTORY_SEARCH_PATH environment variable is not set + """ + directory = os.getenv("DIRECTORY_SEARCH_PATH") + if not directory: + raise ValueError("DIRECTORY_SEARCH_PATH environment variable must be set") + return search_directory(directory, query)