gpt_enterprise.scrum_master
🏂 Scrum Master 🏂
1""" 2\U0001F3C2 3Scrum Master 4\U0001F3C2 5""" 6 7import os 8import ast 9import time 10import json 11import asyncio 12from typing import List, Dict 13 14from gpt_enterprise.gpt_utils import generate_text 15from gpt_enterprise.employee import Employee 16 17 18MANAGER_PROMPTS_PATH = os.path.join(os.path.dirname(__file__), "prompts", "managers") 19 20 21class ScrumMaster: 22 """ 23 A scrum master will try to achieve CEO guidelines by creating tasks. 24 The scrum master will plan tasks and assign them to employees to achieve 25 CEO guidelines inside the given enterprise. 26 """ 27 28 def __init__( 29 self, 30 ceo_guidelines: str, 31 manager_retry: int, 32 output_directory: str, 33 interactive: bool = False, 34 ): 35 """ 36 37 Args: 38 ceo_guidelines (str): _description_ 39 manager_retry (int): _description_ 40 output_directory (str): _description_ 41 interactive (bool): Defaults to False 42 """ 43 with open( 44 os.path.join( 45 ( 46 MANAGER_PROMPTS_PATH 47 if not os.getenv("CUSTOM_MANAGER_PROMPTS_PATH") 48 else os.getenv("CUSTOM_MANAGER_PROMPTS_PATH") 49 ), 50 "scrum_master.txt", 51 ), 52 "r", 53 ) as file: 54 self.role = file.read() 55 self.ceo_guidelines = ceo_guidelines 56 self.manager_retry = manager_retry 57 self.output_directory = output_directory 58 self.interactive = interactive 59 self.emoji = "\U0001F3C2" 60 self.tasks = None 61 62 def plan_tasks(self, employees: List[Employee]) -> List[Dict]: 63 """ 64 Tell the scrum master to make create and plan tasks to achieve guidelines 65 66 Returns: 67 List[object]: A list with all tasks 68 """ 69 # Build the list of hired employees with their role name and name 70 hired_employees = [ 71 {"name": employee.name, "role_name": employee.role_name} 72 for employee in employees 73 if employee.name != "GUY" 74 ] 75 self.ceo_guidelines += f"AVAILABLE_EMPLOYEES: {hired_employees}" 76 for _ in range(self.manager_retry): 77 try: 78 print( 79 f"\n {self.emoji} Hey, I'm doing plans to achieve your guidelines !\n" 80 ) 81 response = generate_text( 82 system_prompt=self.role, 83 user_prompt=f"Here are the CEO guidelines : {self.ceo_guidelines}", 84 model=os.getenv("GPT_VERSION", "gpt-3.5-turbo"), # TODO 85 temperature=1.0, 86 ) 87 # Convert to dict 88 task_plan = ast.literal_eval(response.choices[0].message.content) 89 print(json.dumps(task_plan, indent=4)) 90 if self.interactive: 91 if "y" in ( 92 input( 93 f"\n {self.emoji} Is that task plan good for you ?" 94 ).lower() 95 or "y" 96 ): 97 return task_plan 98 else: 99 continue 100 return task_plan 101 except Exception as err: 102 print(err) 103 print( 104 f"\n {self.emoji} I've messed up, retrying to plan tasks... \n Error : \n {response.choices[0].message.content}\n" 105 ) 106 print(f"\n {self.emoji} I've messed up, I'm not able to do this...\n") 107 raise err 108 109 def do_plan(self, tasks: List[object], employees: List[Employee]) -> List[Dict]: 110 """ 111 Do the given sequence of tasks 112 113 Args: 114 tasks (List[object]): List of tasks to execute 115 Object must have fields task_name, employee_name, todo, type, requirements ("yes" or "no") 116 employees (List[Employee]): List of hired employees 117 118 Returns: 119 List[Dict]: Production of the team ! All tasks have the result field 120 """ 121 self.tasks = tasks 122 print(f"\n {self.emoji} Hey, I'm doing plan, just wait for the result !\n") 123 # Do until all tasks have the result field set 124 while not all(task.get("result") for task in self.tasks): 125 for index, task in enumerate(self.tasks): 126 # Do tasks without any requirements 127 # TODO: Do it asynchronously 128 if "no" in str(task.get("requirements", "")) and not task.get("result"): 129 if self.interactive and "y" not in ( 130 input( 131 f"{self.emoji} Ask {task['employee_name']} to go on with the task \n {task} ?" 132 ).lower() 133 or "y" 134 ): 135 continue 136 self._employee_task( 137 index, 138 task, 139 employees.get(task["employee_name"], employees.get("helpful")), 140 ) 141 # Do tasks that requires result of other tasks 142 elif ( 143 "no" not in str(task.get("requirements", "no")) 144 and not task.get("result") 145 and self.tasks[int(task["requirements"])].get("result") 146 ): 147 # Add the previous employee work to the current task to 148 # be used by the assigned employee. 149 task[ 150 "todo" 151 ] += f" Here is the work done by {self.tasks[int(task['requirements'])]['employee_name']} : {self.tasks[int(task['requirements'])]['result']}" 152 if self.interactive and "y" not in ( 153 input( 154 f"{self.emoji} Ask {task['employee_name']} to go on with the task \n {task} ?" 155 ).lower() 156 or "y" 157 ): 158 continue 159 self._employee_task( 160 index, 161 task, 162 employees.get(task["employee_name"], employees.get("helpful")), 163 ) 164 return self.tasks 165 166 async def do_plan_async( 167 self, tasks: List[object], employees: List[Employee] 168 ) -> List[Dict]: 169 """ 170 Do the given sequence of tasks asynchronously (not compatible with interactive mode). 171 172 Args: 173 tasks (List[object]): List of tasks to execute 174 Object must have fields task_name, employee_name, todo, type, requirements ("yes" or "no") 175 employees (List[Employee]): List of hired employees 176 177 Returns: 178 List[Dict]: Production of the team ! All tasks have the result field 179 """ 180 print(f"\n {self.emoji} Hey, I'm doing plan, just wait for the result !\n") 181 self.tasks = tasks 182 # Create futures 183 all_tasks = [] 184 for task_index, task in enumerate(tasks): 185 # employee_name field may be a list of employe name 186 if isinstance(task["employee_name"], list): 187 for employee_name in task["employee_name"]: 188 all_tasks.append( 189 asyncio.to_thread( 190 self._wait_for_result, 191 task_index, 192 task, 193 employees.get(employee_name, employees.get("helpful")), 194 ) 195 ) 196 else: 197 all_tasks.append( 198 asyncio.to_thread( 199 self._wait_for_result, 200 task_index, 201 task, 202 employees.get(task["employee_name"], employees.get("helpful")), 203 ) 204 ) 205 # Run all futures in parallel 206 await asyncio.gather(*all_tasks) 207 return self.tasks 208 209 def _wait_for_result(self, task_index: int, task: dict, employee: Employee) -> dict: 210 """ 211 Wait for required task result to be available if the current task requires it. 212 213 Args: 214 task (dict): _description_ 215 employee (Employee): _description_ 216 217 Returns: 218 dict: _description_ 219 """ 220 if "no" not in str(task.get("requirements", "no")): 221 counter = 0 222 # Test if requirements is an int or a list 223 try: 224 task_requirements = list(task["requirements"]) 225 except TypeError: 226 task_requirements = [int(task["requirements"])] 227 for task_idx in task_requirements: 228 # Test if it is an int, if not continue 229 try: 230 task_idx = int(task_idx) 231 except Exception as error: 232 continue 233 while not self.tasks[task_idx].get("result"): 234 time.sleep(0.01) 235 counter += 1 236 if counter >= 2000: 237 print( 238 f"Waiting for {self.tasks[int(task['requirements'])]['employee_name']} to finish..." 239 ) 240 counter = 0 241 # Add the previous employee work to the current task to 242 # be used by the assigned employee. 243 task[ 244 "todo" 245 ] += f" Here is the work done by {self.tasks[task_idx]['employee_name']} : {self.tasks[task_idx]['result']}" 246 247 print( 248 f"{self.emoji} {employee.name} is doing task {task_index} : {task['todo']}" 249 ) 250 self._employee_task(task_index, task, employee) 251 252 def _employee_task(self, task_index: int, task: dict, employee: Employee): 253 """ 254 Ask given employee to do the task and set the result field. 255 The global list of tasks is then updated with the modified task. 256 257 Args: 258 task_index (int): _description_ 259 task (dict): _description_ 260 employee (Employee): _description_ 261 """ 262 todo = task["todo"] 263 if task["type"] == "image": 264 # Get number of images to ask from the task todo 265 nb_image = 2 266 if "NB_IMAGES" in todo: 267 nb_image = int(todo.split("NB_IMAGES")[1][1]) 268 todo = todo.split("NB_IMAGES")[0] 269 task["result"] = employee.ask_image( 270 manager_request=todo, 271 output_directory=self.output_directory, 272 base_name=employee.name, 273 nb_image=min(nb_image, 5), 274 ) 275 elif task["type"] == "text": 276 task["result"] = employee.ask_task(todo) 277 self.tasks[task_index] = task
MANAGER_PROMPTS_PATH =
'/opt/hostedtoolcache/Python/3.11.8/x64/lib/python3.11/site-packages/gpt_enterprise/prompts/managers'
class
ScrumMaster:
22class ScrumMaster: 23 """ 24 A scrum master will try to achieve CEO guidelines by creating tasks. 25 The scrum master will plan tasks and assign them to employees to achieve 26 CEO guidelines inside the given enterprise. 27 """ 28 29 def __init__( 30 self, 31 ceo_guidelines: str, 32 manager_retry: int, 33 output_directory: str, 34 interactive: bool = False, 35 ): 36 """ 37 38 Args: 39 ceo_guidelines (str): _description_ 40 manager_retry (int): _description_ 41 output_directory (str): _description_ 42 interactive (bool): Defaults to False 43 """ 44 with open( 45 os.path.join( 46 ( 47 MANAGER_PROMPTS_PATH 48 if not os.getenv("CUSTOM_MANAGER_PROMPTS_PATH") 49 else os.getenv("CUSTOM_MANAGER_PROMPTS_PATH") 50 ), 51 "scrum_master.txt", 52 ), 53 "r", 54 ) as file: 55 self.role = file.read() 56 self.ceo_guidelines = ceo_guidelines 57 self.manager_retry = manager_retry 58 self.output_directory = output_directory 59 self.interactive = interactive 60 self.emoji = "\U0001F3C2" 61 self.tasks = None 62 63 def plan_tasks(self, employees: List[Employee]) -> List[Dict]: 64 """ 65 Tell the scrum master to make create and plan tasks to achieve guidelines 66 67 Returns: 68 List[object]: A list with all tasks 69 """ 70 # Build the list of hired employees with their role name and name 71 hired_employees = [ 72 {"name": employee.name, "role_name": employee.role_name} 73 for employee in employees 74 if employee.name != "GUY" 75 ] 76 self.ceo_guidelines += f"AVAILABLE_EMPLOYEES: {hired_employees}" 77 for _ in range(self.manager_retry): 78 try: 79 print( 80 f"\n {self.emoji} Hey, I'm doing plans to achieve your guidelines !\n" 81 ) 82 response = generate_text( 83 system_prompt=self.role, 84 user_prompt=f"Here are the CEO guidelines : {self.ceo_guidelines}", 85 model=os.getenv("GPT_VERSION", "gpt-3.5-turbo"), # TODO 86 temperature=1.0, 87 ) 88 # Convert to dict 89 task_plan = ast.literal_eval(response.choices[0].message.content) 90 print(json.dumps(task_plan, indent=4)) 91 if self.interactive: 92 if "y" in ( 93 input( 94 f"\n {self.emoji} Is that task plan good for you ?" 95 ).lower() 96 or "y" 97 ): 98 return task_plan 99 else: 100 continue 101 return task_plan 102 except Exception as err: 103 print(err) 104 print( 105 f"\n {self.emoji} I've messed up, retrying to plan tasks... \n Error : \n {response.choices[0].message.content}\n" 106 ) 107 print(f"\n {self.emoji} I've messed up, I'm not able to do this...\n") 108 raise err 109 110 def do_plan(self, tasks: List[object], employees: List[Employee]) -> List[Dict]: 111 """ 112 Do the given sequence of tasks 113 114 Args: 115 tasks (List[object]): List of tasks to execute 116 Object must have fields task_name, employee_name, todo, type, requirements ("yes" or "no") 117 employees (List[Employee]): List of hired employees 118 119 Returns: 120 List[Dict]: Production of the team ! All tasks have the result field 121 """ 122 self.tasks = tasks 123 print(f"\n {self.emoji} Hey, I'm doing plan, just wait for the result !\n") 124 # Do until all tasks have the result field set 125 while not all(task.get("result") for task in self.tasks): 126 for index, task in enumerate(self.tasks): 127 # Do tasks without any requirements 128 # TODO: Do it asynchronously 129 if "no" in str(task.get("requirements", "")) and not task.get("result"): 130 if self.interactive and "y" not in ( 131 input( 132 f"{self.emoji} Ask {task['employee_name']} to go on with the task \n {task} ?" 133 ).lower() 134 or "y" 135 ): 136 continue 137 self._employee_task( 138 index, 139 task, 140 employees.get(task["employee_name"], employees.get("helpful")), 141 ) 142 # Do tasks that requires result of other tasks 143 elif ( 144 "no" not in str(task.get("requirements", "no")) 145 and not task.get("result") 146 and self.tasks[int(task["requirements"])].get("result") 147 ): 148 # Add the previous employee work to the current task to 149 # be used by the assigned employee. 150 task[ 151 "todo" 152 ] += f" Here is the work done by {self.tasks[int(task['requirements'])]['employee_name']} : {self.tasks[int(task['requirements'])]['result']}" 153 if self.interactive and "y" not in ( 154 input( 155 f"{self.emoji} Ask {task['employee_name']} to go on with the task \n {task} ?" 156 ).lower() 157 or "y" 158 ): 159 continue 160 self._employee_task( 161 index, 162 task, 163 employees.get(task["employee_name"], employees.get("helpful")), 164 ) 165 return self.tasks 166 167 async def do_plan_async( 168 self, tasks: List[object], employees: List[Employee] 169 ) -> List[Dict]: 170 """ 171 Do the given sequence of tasks asynchronously (not compatible with interactive mode). 172 173 Args: 174 tasks (List[object]): List of tasks to execute 175 Object must have fields task_name, employee_name, todo, type, requirements ("yes" or "no") 176 employees (List[Employee]): List of hired employees 177 178 Returns: 179 List[Dict]: Production of the team ! All tasks have the result field 180 """ 181 print(f"\n {self.emoji} Hey, I'm doing plan, just wait for the result !\n") 182 self.tasks = tasks 183 # Create futures 184 all_tasks = [] 185 for task_index, task in enumerate(tasks): 186 # employee_name field may be a list of employe name 187 if isinstance(task["employee_name"], list): 188 for employee_name in task["employee_name"]: 189 all_tasks.append( 190 asyncio.to_thread( 191 self._wait_for_result, 192 task_index, 193 task, 194 employees.get(employee_name, employees.get("helpful")), 195 ) 196 ) 197 else: 198 all_tasks.append( 199 asyncio.to_thread( 200 self._wait_for_result, 201 task_index, 202 task, 203 employees.get(task["employee_name"], employees.get("helpful")), 204 ) 205 ) 206 # Run all futures in parallel 207 await asyncio.gather(*all_tasks) 208 return self.tasks 209 210 def _wait_for_result(self, task_index: int, task: dict, employee: Employee) -> dict: 211 """ 212 Wait for required task result to be available if the current task requires it. 213 214 Args: 215 task (dict): _description_ 216 employee (Employee): _description_ 217 218 Returns: 219 dict: _description_ 220 """ 221 if "no" not in str(task.get("requirements", "no")): 222 counter = 0 223 # Test if requirements is an int or a list 224 try: 225 task_requirements = list(task["requirements"]) 226 except TypeError: 227 task_requirements = [int(task["requirements"])] 228 for task_idx in task_requirements: 229 # Test if it is an int, if not continue 230 try: 231 task_idx = int(task_idx) 232 except Exception as error: 233 continue 234 while not self.tasks[task_idx].get("result"): 235 time.sleep(0.01) 236 counter += 1 237 if counter >= 2000: 238 print( 239 f"Waiting for {self.tasks[int(task['requirements'])]['employee_name']} to finish..." 240 ) 241 counter = 0 242 # Add the previous employee work to the current task to 243 # be used by the assigned employee. 244 task[ 245 "todo" 246 ] += f" Here is the work done by {self.tasks[task_idx]['employee_name']} : {self.tasks[task_idx]['result']}" 247 248 print( 249 f"{self.emoji} {employee.name} is doing task {task_index} : {task['todo']}" 250 ) 251 self._employee_task(task_index, task, employee) 252 253 def _employee_task(self, task_index: int, task: dict, employee: Employee): 254 """ 255 Ask given employee to do the task and set the result field. 256 The global list of tasks is then updated with the modified task. 257 258 Args: 259 task_index (int): _description_ 260 task (dict): _description_ 261 employee (Employee): _description_ 262 """ 263 todo = task["todo"] 264 if task["type"] == "image": 265 # Get number of images to ask from the task todo 266 nb_image = 2 267 if "NB_IMAGES" in todo: 268 nb_image = int(todo.split("NB_IMAGES")[1][1]) 269 todo = todo.split("NB_IMAGES")[0] 270 task["result"] = employee.ask_image( 271 manager_request=todo, 272 output_directory=self.output_directory, 273 base_name=employee.name, 274 nb_image=min(nb_image, 5), 275 ) 276 elif task["type"] == "text": 277 task["result"] = employee.ask_task(todo) 278 self.tasks[task_index] = task
A scrum master will try to achieve CEO guidelines by creating tasks. The scrum master will plan tasks and assign them to employees to achieve CEO guidelines inside the given enterprise.
ScrumMaster( ceo_guidelines: str, manager_retry: int, output_directory: str, interactive: bool = False)
29 def __init__( 30 self, 31 ceo_guidelines: str, 32 manager_retry: int, 33 output_directory: str, 34 interactive: bool = False, 35 ): 36 """ 37 38 Args: 39 ceo_guidelines (str): _description_ 40 manager_retry (int): _description_ 41 output_directory (str): _description_ 42 interactive (bool): Defaults to False 43 """ 44 with open( 45 os.path.join( 46 ( 47 MANAGER_PROMPTS_PATH 48 if not os.getenv("CUSTOM_MANAGER_PROMPTS_PATH") 49 else os.getenv("CUSTOM_MANAGER_PROMPTS_PATH") 50 ), 51 "scrum_master.txt", 52 ), 53 "r", 54 ) as file: 55 self.role = file.read() 56 self.ceo_guidelines = ceo_guidelines 57 self.manager_retry = manager_retry 58 self.output_directory = output_directory 59 self.interactive = interactive 60 self.emoji = "\U0001F3C2" 61 self.tasks = None
Arguments:
- ceo_guidelines (str): _description_
- manager_retry (int): _description_
- output_directory (str): _description_
- interactive (bool): Defaults to False
63 def plan_tasks(self, employees: List[Employee]) -> List[Dict]: 64 """ 65 Tell the scrum master to make create and plan tasks to achieve guidelines 66 67 Returns: 68 List[object]: A list with all tasks 69 """ 70 # Build the list of hired employees with their role name and name 71 hired_employees = [ 72 {"name": employee.name, "role_name": employee.role_name} 73 for employee in employees 74 if employee.name != "GUY" 75 ] 76 self.ceo_guidelines += f"AVAILABLE_EMPLOYEES: {hired_employees}" 77 for _ in range(self.manager_retry): 78 try: 79 print( 80 f"\n {self.emoji} Hey, I'm doing plans to achieve your guidelines !\n" 81 ) 82 response = generate_text( 83 system_prompt=self.role, 84 user_prompt=f"Here are the CEO guidelines : {self.ceo_guidelines}", 85 model=os.getenv("GPT_VERSION", "gpt-3.5-turbo"), # TODO 86 temperature=1.0, 87 ) 88 # Convert to dict 89 task_plan = ast.literal_eval(response.choices[0].message.content) 90 print(json.dumps(task_plan, indent=4)) 91 if self.interactive: 92 if "y" in ( 93 input( 94 f"\n {self.emoji} Is that task plan good for you ?" 95 ).lower() 96 or "y" 97 ): 98 return task_plan 99 else: 100 continue 101 return task_plan 102 except Exception as err: 103 print(err) 104 print( 105 f"\n {self.emoji} I've messed up, retrying to plan tasks... \n Error : \n {response.choices[0].message.content}\n" 106 ) 107 print(f"\n {self.emoji} I've messed up, I'm not able to do this...\n") 108 raise err
Tell the scrum master to make create and plan tasks to achieve guidelines
Returns:
List[object]: A list with all tasks
def
do_plan( self, tasks: List[object], employees: List[gpt_enterprise.employee.Employee]) -> List[Dict]:
110 def do_plan(self, tasks: List[object], employees: List[Employee]) -> List[Dict]: 111 """ 112 Do the given sequence of tasks 113 114 Args: 115 tasks (List[object]): List of tasks to execute 116 Object must have fields task_name, employee_name, todo, type, requirements ("yes" or "no") 117 employees (List[Employee]): List of hired employees 118 119 Returns: 120 List[Dict]: Production of the team ! All tasks have the result field 121 """ 122 self.tasks = tasks 123 print(f"\n {self.emoji} Hey, I'm doing plan, just wait for the result !\n") 124 # Do until all tasks have the result field set 125 while not all(task.get("result") for task in self.tasks): 126 for index, task in enumerate(self.tasks): 127 # Do tasks without any requirements 128 # TODO: Do it asynchronously 129 if "no" in str(task.get("requirements", "")) and not task.get("result"): 130 if self.interactive and "y" not in ( 131 input( 132 f"{self.emoji} Ask {task['employee_name']} to go on with the task \n {task} ?" 133 ).lower() 134 or "y" 135 ): 136 continue 137 self._employee_task( 138 index, 139 task, 140 employees.get(task["employee_name"], employees.get("helpful")), 141 ) 142 # Do tasks that requires result of other tasks 143 elif ( 144 "no" not in str(task.get("requirements", "no")) 145 and not task.get("result") 146 and self.tasks[int(task["requirements"])].get("result") 147 ): 148 # Add the previous employee work to the current task to 149 # be used by the assigned employee. 150 task[ 151 "todo" 152 ] += f" Here is the work done by {self.tasks[int(task['requirements'])]['employee_name']} : {self.tasks[int(task['requirements'])]['result']}" 153 if self.interactive and "y" not in ( 154 input( 155 f"{self.emoji} Ask {task['employee_name']} to go on with the task \n {task} ?" 156 ).lower() 157 or "y" 158 ): 159 continue 160 self._employee_task( 161 index, 162 task, 163 employees.get(task["employee_name"], employees.get("helpful")), 164 ) 165 return self.tasks
Do the given sequence of tasks
Arguments:
- tasks (List[object]): List of tasks to execute
- Object must have fields task_name, employee_name, todo, type, requirements ("yes" or "no")
- employees (List[Employee]): List of hired employees
Returns:
List[Dict]: Production of the team ! All tasks have the result field
async def
do_plan_async( self, tasks: List[object], employees: List[gpt_enterprise.employee.Employee]) -> List[Dict]:
167 async def do_plan_async( 168 self, tasks: List[object], employees: List[Employee] 169 ) -> List[Dict]: 170 """ 171 Do the given sequence of tasks asynchronously (not compatible with interactive mode). 172 173 Args: 174 tasks (List[object]): List of tasks to execute 175 Object must have fields task_name, employee_name, todo, type, requirements ("yes" or "no") 176 employees (List[Employee]): List of hired employees 177 178 Returns: 179 List[Dict]: Production of the team ! All tasks have the result field 180 """ 181 print(f"\n {self.emoji} Hey, I'm doing plan, just wait for the result !\n") 182 self.tasks = tasks 183 # Create futures 184 all_tasks = [] 185 for task_index, task in enumerate(tasks): 186 # employee_name field may be a list of employe name 187 if isinstance(task["employee_name"], list): 188 for employee_name in task["employee_name"]: 189 all_tasks.append( 190 asyncio.to_thread( 191 self._wait_for_result, 192 task_index, 193 task, 194 employees.get(employee_name, employees.get("helpful")), 195 ) 196 ) 197 else: 198 all_tasks.append( 199 asyncio.to_thread( 200 self._wait_for_result, 201 task_index, 202 task, 203 employees.get(task["employee_name"], employees.get("helpful")), 204 ) 205 ) 206 # Run all futures in parallel 207 await asyncio.gather(*all_tasks) 208 return self.tasks
Do the given sequence of tasks asynchronously (not compatible with interactive mode).
Arguments:
- tasks (List[object]): List of tasks to execute
- Object must have fields task_name, employee_name, todo, type, requirements ("yes" or "no")
- employees (List[Employee]): List of hired employees
Returns:
List[Dict]: Production of the team ! All tasks have the result field