joaomorossini commited on
Commit
2c7fb53
·
1 Parent(s): 2d6d97a

Add tests for ClickUp tools and agent functionality

Browse files
agency_ai_demo/tests/test_clickup_agent.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import traceback
4
+ from dotenv import load_dotenv
5
+ from openai import AzureOpenAI
6
+ from agency_swarm import set_openai_client, Agent, Agency
7
+
8
+ from tools.clickup_tools import initialize_clickup_tools
9
+
10
+ load_dotenv()
11
+
12
+
13
+ def main():
14
+ try:
15
+ # Accept query from command line arguments if provided
16
+ if len(sys.argv) > 1:
17
+ query = sys.argv[1]
18
+ else:
19
+ # Default query if no argument provided
20
+ query = 'Use the create_task_tool to create a new task in list_id 901307715461 with name "API TEST TASK" and assignees [81918955]. Make sure to pass the list_id parameter correctly.'
21
+
22
+ print("Initializing OpenAI client...")
23
+ client = AzureOpenAI(
24
+ api_key=os.getenv("AZURE_OPENAI_API_KEY"),
25
+ api_version=os.getenv("OPENAI_API_VERSION"),
26
+ azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
27
+ timeout=10,
28
+ max_retries=5,
29
+ )
30
+
31
+ set_openai_client(client)
32
+
33
+ print("Converting ClickUp tools...")
34
+ clickup_tools = initialize_clickup_tools()
35
+
36
+ # Instructions similar to what's in the notebook
37
+ clickup_instructions = """
38
+ 1. GERENCIAMENTO_DE_PROJETOS:
39
+ A equipe usa o ClickUp para gerenciar projetos e tarefas.
40
+
41
+ 1.1 ESTRUTURA_DO_CLICKUP
42
+ -> Workspace: O nível mais alto de organização no ClickUp. Contém todos os seus Espaços.
43
+ --> Space: Uma coleção de Pastas e Listas. É uma maneira de agrupar trabalhos relacionados.
44
+ ---> Folder: Usado para agrupar Listas.
45
+ ----> List: Usado para agrupar tarefas. As listas podem estar em uma Pasta ou diretamente em um Espaço.
46
+ -----> Task: A unidade básica de trabalho no ClickUp, atribuível com datas de vencimento.
47
+ ------> Subtask: Uma tarefa filha de uma Tarefa pai, atribuível a diferentes pessoas.
48
+
49
+ 1.1.1 IDS_PADRÃO_DO_CLICKUP
50
+ Use esses IDs, a menos que especificado de outra forma
51
+ - 'Workspace' (também conhecido como "team_id"): 12927880
52
+ - ID do espaço 'Projetos': 54804921
53
+ - ID da pasta 'Agentes': 90131663060
54
+ - ID da lista 'test_clickup_tool': 901307715461
55
+
56
+ 1.1.2 USUÁRIOS_ATIVOS_DO_CLICKUP (id, nome de usuário, email)
57
+ - 81918955, João Guilherme Silva Morossini, [email protected]
58
+ """
59
+
60
+ print("Creating ClickUp agent...")
61
+ clickup_agent = Agent(
62
+ name="clickup_agent",
63
+ description="I am a ClickUp agent that helps manage tasks and projects",
64
+ instructions=clickup_instructions,
65
+ model="gpt-4o",
66
+ tools=clickup_tools,
67
+ )
68
+
69
+ # Create the agency with a single agent
70
+ print("Creating agency...")
71
+ agency = Agency(
72
+ agency_chart=[
73
+ clickup_agent, # Just the clickup agent
74
+ ]
75
+ )
76
+
77
+ # Send the query to the agent
78
+ print("Sending query to agent...")
79
+ print(f"Query: '{query}'")
80
+ print("Using agency.get_completion() method...")
81
+ response = agency.get_completion(query)
82
+
83
+ print(f"\nAgent response: {response}")
84
+
85
+ print("\nDone!")
86
+
87
+ except Exception as e:
88
+ print(f"\nAn error occurred: {e}")
89
+ print("\nTraceback:")
90
+ traceback.print_exception(*sys.exc_info())
91
+
92
+
93
+ if __name__ == "__main__":
94
+ main()
agency_ai_demo/tests/test_clickup_tool_conversion.py ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import inspect
4
+ import logging
5
+ from typing import List, Type, Any, Callable, Dict, Tuple
6
+
7
+ # Setup logging
8
+ logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")
9
+ logger = logging.getLogger(__name__)
10
+
11
+ # Add the parent directory to sys.path to enable imports
12
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
13
+
14
+ # Import the tool wrapper
15
+ from utils.tool_wrapper import convert_langchain_tool, LangChainBaseTool
16
+
17
+ # Import all tools from the clickup_tools module
18
+ from tools.clickup_tools import (
19
+ CreateTaskTool,
20
+ DeleteTaskTool,
21
+ UpdateTaskTool,
22
+ CreateTaskCommentTool,
23
+ GetTaskCommentsTool,
24
+ AddTaskToListTool,
25
+ RemoveTaskFromListTool,
26
+ CreateFolderlessListTool,
27
+ GetListsTool,
28
+ AddDependencyTool,
29
+ GetAuthorizedTeamsWorkspacesTool,
30
+ GetAuthorizedUserTool,
31
+ GetFolderTool,
32
+ GetFoldersTool,
33
+ GetListTool,
34
+ GetListMembersTool,
35
+ GetTaskMembersTool,
36
+ GetSpaceTool,
37
+ GetSpacesTool,
38
+ GetFilteredTeamTasksTool,
39
+ GetTasksTool,
40
+ GetTaskTool,
41
+ GetWorkspaceSeatsTool,
42
+ date_to_timestamp,
43
+ )
44
+
45
+
46
+ def test_tool_conversion():
47
+ """
48
+ Test the conversion of all ClickUp tools to agency-swarm compatible tools.
49
+ """
50
+ # Define all tools to test explicitly
51
+ class_tools = [
52
+ CreateTaskTool,
53
+ DeleteTaskTool,
54
+ UpdateTaskTool,
55
+ CreateTaskCommentTool,
56
+ GetTaskCommentsTool,
57
+ AddTaskToListTool,
58
+ RemoveTaskFromListTool,
59
+ CreateFolderlessListTool,
60
+ GetListsTool,
61
+ AddDependencyTool,
62
+ GetAuthorizedTeamsWorkspacesTool,
63
+ GetAuthorizedUserTool,
64
+ GetFolderTool,
65
+ GetFoldersTool,
66
+ GetListTool,
67
+ GetListMembersTool,
68
+ GetTaskMembersTool,
69
+ GetSpaceTool,
70
+ GetSpacesTool,
71
+ GetFilteredTeamTasksTool,
72
+ GetTasksTool,
73
+ GetTaskTool,
74
+ GetWorkspaceSeatsTool,
75
+ ]
76
+
77
+ function_tools = [date_to_timestamp]
78
+
79
+ logger.info(
80
+ f"Testing {len(class_tools)} class-based tools and {len(function_tools)} function-based tools"
81
+ )
82
+
83
+ # Test conversion of class-based tools
84
+ successful_conversions = []
85
+ failed_conversions = []
86
+
87
+ # Convert and test each class-based tool
88
+ for tool_cls in class_tools:
89
+ tool_name = tool_cls.__name__
90
+ try:
91
+ logger.info(f"Converting {tool_name}...")
92
+ converted_tool = convert_langchain_tool(tool_cls)
93
+ successful_conversions.append((tool_name, converted_tool))
94
+ logger.info(f"✅ Successfully converted {tool_name}")
95
+ except Exception as e:
96
+ logger.error(f"❌ Failed to convert {tool_name}: {e}")
97
+ failed_conversions.append((tool_name, str(e)))
98
+
99
+ # Convert and test each function-based tool
100
+ for tool_func in function_tools:
101
+ # For function tools, use the function's name directly
102
+ if hasattr(tool_func, "__name__"):
103
+ tool_name = tool_func.__name__
104
+ else:
105
+ tool_name = "function_tool"
106
+
107
+ try:
108
+ logger.info(f"Converting {tool_name}...")
109
+ converted_tool = convert_langchain_tool(tool_func)
110
+ successful_conversions.append((tool_name, converted_tool))
111
+ logger.info(f"✅ Successfully converted {tool_name}")
112
+ except Exception as e:
113
+ logger.error(f"❌ Failed to convert {tool_name}: {e}")
114
+ failed_conversions.append((tool_name, str(e)))
115
+
116
+ # Print summary report
117
+ print("\n" + "=" * 50)
118
+ print("CONVERSION SUMMARY REPORT")
119
+ print("=" * 50)
120
+ print(f"Total tools tested: {len(class_tools) + len(function_tools)}")
121
+ print(f"Successfully converted: {len(successful_conversions)}")
122
+ print(f"Failed conversions: {len(failed_conversions)}")
123
+
124
+ if successful_conversions:
125
+ print("\n" + "-" * 25)
126
+ print("SUCCESSFULLY CONVERTED TOOLS:")
127
+ print("-" * 25)
128
+ for name, _ in successful_conversions:
129
+ print(f"✅ {name}")
130
+
131
+ if failed_conversions:
132
+ print("\n" + "-" * 25)
133
+ print("FAILED CONVERSIONS:")
134
+ print("-" * 25)
135
+ for name, error in failed_conversions:
136
+ print(f"❌ {name}: {error}")
137
+
138
+ return successful_conversions, failed_conversions
139
+
140
+
141
+ if __name__ == "__main__":
142
+ successful_tools, failed_tools = test_tool_conversion()
143
+
144
+ # Exit with non-zero code if any conversions failed
145
+ sys.exit(1 if failed_tools else 0)
agency_ai_demo/tests/test_clickup_tools.py ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ from dotenv import load_dotenv
4
+ import json
5
+
6
+ # Add the parent directory to sys.path to import modules
7
+ sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
8
+
9
+ from agency_ai_demo.tools.clickup_tools import (
10
+ CreateTaskTool,
11
+ DeleteTaskTool,
12
+ UpdateTaskTool,
13
+ AddDependencyTool,
14
+ GetListTool,
15
+ GetTasksTool,
16
+ GetTaskTool,
17
+ )
18
+
19
+ # Load environment variables
20
+ load_dotenv()
21
+
22
+
23
+ def test_create_task():
24
+ print("\n===== Testing CreateTaskTool =====")
25
+ tool = CreateTaskTool()
26
+ result = tool._run(
27
+ list_id="901307715461",
28
+ name="TEST TASK FROM DIRECT TOOL",
29
+ description="This is a test task created using the CreateTaskTool directly",
30
+ assignees=[81918955],
31
+ )
32
+ print("Result:", result)
33
+ return result
34
+
35
+
36
+ def test_get_tasks():
37
+ print("\n===== Testing GetTasksTool =====")
38
+ tool = GetTasksTool()
39
+ result = tool._run(list_id="901307715461")
40
+ print("Tasks found:", len(result))
41
+
42
+ # Print the first task details as an example
43
+ if result and len(result) > 0:
44
+ print("Example task:")
45
+ task = result[0]
46
+ print(f"ID: {task.get('id')}")
47
+ print(f"Name: {task.get('name')}")
48
+ print(f"Status: {task.get('status')}")
49
+ print(f"Assignees: {task.get('assignees')}")
50
+
51
+ return result
52
+
53
+
54
+ def test_get_task(task_id=None):
55
+ print("\n===== Testing GetTaskTool =====")
56
+ # If no task_id is provided, get the first task from the list
57
+ if not task_id:
58
+ tasks = test_get_tasks()
59
+ if tasks and len(tasks) > 0:
60
+ task_id = tasks[0].get("id")
61
+ print(f"Using first task ID: {task_id}")
62
+
63
+ tool = GetTaskTool()
64
+ result = tool._run(task_id=task_id)
65
+ print("Result:", json.dumps(result, indent=2))
66
+ return result
67
+
68
+
69
+ def test_update_task(task_id=None):
70
+ print("\n===== Testing UpdateTaskTool =====")
71
+ # If no task_id is provided, get the first task from the list
72
+ if not task_id:
73
+ tasks = test_get_tasks()
74
+ if tasks and len(tasks) > 0:
75
+ task_id = tasks[0].get("id")
76
+ print(f"Using first task ID: {task_id}")
77
+
78
+ tool = UpdateTaskTool()
79
+ result = tool._run(
80
+ task_id=task_id,
81
+ name="UPDATED TASK NAME",
82
+ description="This task was updated using the UpdateTaskTool directly",
83
+ )
84
+ print("Result:", result)
85
+ return result
86
+
87
+
88
+ def test_add_dependency(task_id=None, depends_on=None):
89
+ print("\n===== Testing AddDependencyTool =====")
90
+ # If no task_ids are provided, get the first two tasks from the list
91
+ if not task_id or not depends_on:
92
+ tasks = test_get_tasks()
93
+ if tasks and len(tasks) >= 2:
94
+ task_id = tasks[0].get("id")
95
+ depends_on = tasks[1].get("id")
96
+ print(f"Using task ID: {task_id}")
97
+ print(f"Using depends_on ID: {depends_on}")
98
+
99
+ tool = AddDependencyTool()
100
+ result = tool._run(task_id=task_id, depends_on=depends_on)
101
+ print("Result:", result)
102
+ return result
103
+
104
+
105
+ def test_delete_task(task_id=None):
106
+ print("\n===== Testing DeleteTaskTool =====")
107
+ # If no task_id is provided, create a new task to delete
108
+ if not task_id:
109
+ created_task = test_create_task()
110
+ if isinstance(created_task, dict) and "id" in created_task:
111
+ task_id = created_task["id"]
112
+ print(f"Using newly created task ID: {task_id}")
113
+
114
+ tool = DeleteTaskTool()
115
+ result = tool._run(task_id=task_id)
116
+ print("Result:", result)
117
+ return result
118
+
119
+
120
+ def test_get_list():
121
+ print("\n===== Testing GetListTool =====")
122
+ tool = GetListTool()
123
+ result = tool._run(list_id="901307715461")
124
+ print("Result:", json.dumps(result, indent=2))
125
+ return result
126
+
127
+
128
+ def test_all_tools():
129
+ print("Starting ClickUp tools tests...")
130
+
131
+ # Step 1: Get all tasks to see what's already there
132
+ tasks = test_get_tasks()
133
+
134
+ # Step 2: Create a new task
135
+ created_task = test_create_task()
136
+ if isinstance(created_task, dict) and "id" in created_task:
137
+ new_task_id = created_task.get("id")
138
+ print(f"Created new task with ID: {new_task_id}")
139
+
140
+ # Step 3: Get the task details
141
+ test_get_task(new_task_id)
142
+
143
+ # Step 4: Update the task
144
+ test_update_task(new_task_id)
145
+
146
+ # Step 5: Create another task for dependency testing
147
+ second_task = test_create_task()
148
+ if isinstance(second_task, dict) and "id" in second_task:
149
+ second_task_id = second_task.get("id")
150
+ print(f"Created second task with ID: {second_task_id}")
151
+
152
+ # Step 6: Add dependency between tasks
153
+ test_add_dependency(new_task_id, second_task_id)
154
+
155
+ # Step 7: Get list details
156
+ test_get_list()
157
+
158
+ # Step 8: Delete the tasks we created (cleanup)
159
+ test_delete_task(new_task_id)
160
+ test_delete_task(second_task_id)
161
+ else:
162
+ print("Failed to create second task, skipping dependency test")
163
+ else:
164
+ print("Failed to create task, skipping remaining tests")
165
+
166
+ print("\nAll tests completed!")
167
+
168
+
169
+ if __name__ == "__main__":
170
+ test_all_tools()
agency_ai_demo/tests/test_list_tasks.py ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from dotenv import load_dotenv
3
+ from openai import AzureOpenAI
4
+ from agency_swarm import set_openai_client
5
+ from agency_swarm import Agent
6
+
7
+ from tools.clickup_tools import initialize_clickup_tools
8
+
9
+ load_dotenv()
10
+
11
+
12
+ def main():
13
+ print("Initializing OpenAI client...")
14
+ client = AzureOpenAI(
15
+ api_key=os.getenv("AZURE_OPENAI_API_KEY"),
16
+ api_version=os.getenv("OPENAI_API_VERSION"),
17
+ azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
18
+ timeout=5,
19
+ max_retries=5,
20
+ )
21
+
22
+ set_openai_client(client)
23
+
24
+ print("Converting ClickUp tools...")
25
+ clickup_tools = initialize_clickup_tools()
26
+
27
+ print("Creating test agent...")
28
+ clickup_agent = Agent(
29
+ name="clickup_agent",
30
+ description="I am a simple agent for testing tools",
31
+ model="gpt-4o",
32
+ tools=clickup_tools,
33
+ )
34
+
35
+ print("\nTesting get_tasks_tool...")
36
+ # Test GetTasksTool directly without using the agent
37
+ from tools.clickup_tools import GetTasksTool
38
+
39
+ tool = GetTasksTool()
40
+ result = tool._run(list_id=901307715461)
41
+ print(f"Result from GetTasksTool: {result}")
42
+
43
+ print("\nDone!")
44
+
45
+
46
+ if __name__ == "__main__":
47
+ main()
agency_ai_demo/tests/test_tool_directly.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import json
4
+ import traceback
5
+ from dotenv import load_dotenv
6
+ from openai import AzureOpenAI
7
+ from agency_swarm import set_openai_client, Agent, Agency
8
+
9
+ from tools.clickup_tools import initialize_clickup_tools, GetTasksTool, GetTaskTool
10
+
11
+ load_dotenv()
12
+
13
+
14
+ def main():
15
+ try:
16
+ print("Initializing OpenAI client...")
17
+ client = AzureOpenAI(
18
+ api_key=os.getenv("AZURE_OPENAI_API_KEY"),
19
+ api_version=os.getenv("OPENAI_API_VERSION"),
20
+ azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
21
+ timeout=10,
22
+ max_retries=5,
23
+ )
24
+
25
+ set_openai_client(client)
26
+
27
+ # First test the tool directly
28
+ print("\n==== Testing GetTasksTool directly ====")
29
+ tool = GetTasksTool()
30
+ result = tool._run(list_id=901307715461)
31
+ print(f"Direct result: {json.dumps(result, indent=2)}")
32
+
33
+ print("\n==== Testing GetTaskTool directly ====")
34
+ get_task_tool = GetTaskTool()
35
+ task_id = "86a700c6e"
36
+ direct_result = get_task_tool._run(task_id=task_id)
37
+ print(f"Direct result: {json.dumps(direct_result, indent=2)}")
38
+
39
+ # Now test through Agency Swarm
40
+ print("\n==== Testing through Agency Swarm ====")
41
+
42
+ # Convert tools
43
+ print("Converting ClickUp tools...")
44
+ clickup_tools = initialize_clickup_tools()
45
+
46
+ # Instructions
47
+ clickup_instructions = """
48
+ You need to use the get_tasks_tool to retrieve tasks from list_id 901307715461.
49
+ Always show the full output to the user.
50
+ """
51
+
52
+ print("Creating ClickUp agent...")
53
+ clickup_agent = Agent(
54
+ name="clickup_agent",
55
+ description="I help with ClickUp tasks",
56
+ instructions=clickup_instructions,
57
+ model="gpt-4o",
58
+ tools=clickup_tools,
59
+ )
60
+
61
+ # Create the agency with a single agent
62
+ print("Creating agency...")
63
+ agency = Agency(
64
+ agency_chart=[
65
+ clickup_agent,
66
+ ]
67
+ )
68
+
69
+ # Run the query through the agency
70
+ print("\nSending query to agent...")
71
+ user_query = "Use the get_tasks_tool to get all tasks in list_id 901307715461 and show me the complete results without summarizing."
72
+ print(f"Query: '{user_query}'")
73
+
74
+ response = agency.get_completion(user_query)
75
+ print(f"\nAgent response: {response}")
76
+
77
+ print("\nDone!")
78
+
79
+ except Exception as e:
80
+ print(f"\nAn error occurred: {e}")
81
+ print("\nTraceback:")
82
+ traceback.print_exception(*sys.exc_info())
83
+
84
+
85
+ if __name__ == "__main__":
86
+ main()