diff --git a/composio/client/collections.py b/composio/client/collections.py index 0cd877e0df..b59f8eee42 100644 --- a/composio/client/collections.py +++ b/composio/client/collections.py @@ -384,6 +384,24 @@ class TriggerModel(BaseModel): logo: t.Optional[str] = None +class ExecutionDetailsModel(BaseModel): + """Execution details data model.""" + + executed: bool + + +class SuccessExecuteActionResponseModel(BaseModel): + """Success execute action response data model.""" + + execution_details: ExecutionDetailsModel + response_data: str + + +class FileModel(BaseModel): + name: str + content: bytes + + class Triggers(Collection[TriggerModel]): """Collection of triggers.""" diff --git a/composio/client/enums.py b/composio/client/enums.py index 2ad141540e..b804fe589e 100644 --- a/composio/client/enums.py +++ b/composio/client/enums.py @@ -435,9 +435,9 @@ def is_local(self) -> bool: "ragtool", "webtool", "greptile", + "submitpatchtool", "sqltool", "filetool", - "submitpatchtool", ] APIFY = "apify" @@ -2779,6 +2779,11 @@ def from_app_and_action(cls, app: str, name: str) -> "Action": "codeinterpreter_execute_code", True, ) + CODEINTERPRETER_GET_FILE_CMD = ( + "codeinterpreter", + "codeinterpreter_get_file_cmd", + True, + ) CODEINTERPRETER_RUN_TERMINAL_CMD = ( "codeinterpreter", "codeinterpreter_run_terminal_cmd", diff --git a/composio/tools/__init__.py b/composio/tools/__init__.py index 0368a00011..6f822c8607 100644 --- a/composio/tools/__init__.py +++ b/composio/tools/__init__.py @@ -2,13 +2,19 @@ Composio SDK tools. """ +import base64 +import json import os import time import typing as t from pathlib import Path from composio.client import Composio -from composio.client.collections import ActionModel +from composio.client.collections import ( + ActionModel, + FileModel, + SuccessExecuteActionResponseModel, +) from composio.client.enums import Action, App, Tag from composio.client.local_handler import LocalToolHandler from composio.constants import ( @@ -100,17 +106,15 @@ def execute_action( ) output = self.client.get_entity(entity_id).execute(action=action, params=params) - if self.output_in_file: - if not os.path.exists( + if not os.path.exists( + Path.home() / LOCAL_CACHE_DIRECTORY_NAME / LOCAL_OUTPUT_FILE_DIRECTORY_NAME + ): + os.makedirs( Path.home() / LOCAL_CACHE_DIRECTORY_NAME / LOCAL_OUTPUT_FILE_DIRECTORY_NAME - ): - os.makedirs( - Path.home() - / LOCAL_CACHE_DIRECTORY_NAME - / LOCAL_OUTPUT_FILE_DIRECTORY_NAME - ) + ) + if self.output_in_file: output_file_path = ( Path.home() / LOCAL_CACHE_DIRECTORY_NAME @@ -120,8 +124,38 @@ def execute_action( with open(output_file_path, "w", encoding="utf-8") as file: file.write(str(output)) return {"output_file": f"{output_file_path}"} + + try: + output_modified = self._save_files( + f"{action.name}_{entity_id}_{time.time()}", output + ) + return output_modified + except Exception as e: + print(f"Error checking file response: {e}") return output + def _save_files(self, file_name_prefix: str, output: dict) -> dict: + success_response_model = SuccessExecuteActionResponseModel.model_validate( + output + ) + resp_data = json.loads(success_response_model.response_data) + for key, val in resp_data.items(): + try: + file_model = FileModel.model_validate(val) + output_file_path = ( + Path.home() + / LOCAL_CACHE_DIRECTORY_NAME + / LOCAL_OUTPUT_FILE_DIRECTORY_NAME + / f"{file_name_prefix}_{file_model.name.replace('/', '_')}" + ) + print(f"Saving file to: {output_file_path}") + with open(output_file_path, "wb") as file: + file.write(base64.b64decode(file_model.content)) + resp_data[key] = str(output_file_path) + except Exception: + pass + return resp_data + def get_action_schemas( self, apps: t.Optional[t.Sequence[App]] = None, diff --git a/examples/crewai_ci_chart.py b/examples/crewai_ci_chart.py new file mode 100644 index 0000000000..f89d3665ee --- /dev/null +++ b/examples/crewai_ci_chart.py @@ -0,0 +1,40 @@ +from crewai import Agent, Task, Crew +from composio_crewai import ComposioToolSet +from composio import App, Action +from langchain_openai import ChatOpenAI + +llm = ChatOpenAI(model="gpt-4-turbo") + +while True: + main_task = input("Enter the task you want to perform (or type 'exit' to quit): ") + if main_task.lower() == 'exit': + break + + code_interpreter_tools = ComposioToolSet().get_tools([App.CODEINTERPRETER]) + + code_interpreter_agent = Agent( + role="Python Code Interpreter Agent", + goal=f"""Run I a code to get acheive a task given by the user""", + backstory="""You are an agent that helps users run Python code.""", + verbose=True, + tools=code_interpreter_tools, + llm=llm, + memory=True, + ) + + code_interpreter_task = Task( + description=f"""Run Python code to get acheive a task - {main_task}""", + expected_output=f"""Python code executed successfully. The result of the task is returned - {main_task}""", + agent=code_interpreter_agent, + ) + + crew = Crew( + agents=[code_interpreter_agent], + tasks=[code_interpreter_task], + memory=True, + ) + + result = crew.kickoff() + print(result) + +