praisonaiagents 0.0.28__py3-none-any.whl → 0.0.29__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- praisonaiagents/__init__.py +2 -0
- praisonaiagents/agent/agent.py +2 -2
- praisonaiagents/agents/agents.py +169 -35
- praisonaiagents/memory/memory.py +928 -0
- praisonaiagents/task/task.py +157 -9
- {praisonaiagents-0.0.28.dist-info → praisonaiagents-0.0.29.dist-info}/METADATA +4 -2
- {praisonaiagents-0.0.28.dist-info → praisonaiagents-0.0.29.dist-info}/RECORD +9 -16
- {praisonaiagents-0.0.28.dist-info → praisonaiagents-0.0.29.dist-info}/WHEEL +1 -1
- praisonaiagents/build/lib/praisonaiagents/__init__.py +0 -1
- praisonaiagents/build/lib/praisonaiagents/agent/__init__.py +0 -4
- praisonaiagents/build/lib/praisonaiagents/agent/agent.py +0 -350
- praisonaiagents/build/lib/praisonaiagents/agents/__init__.py +0 -4
- praisonaiagents/build/lib/praisonaiagents/agents/agents.py +0 -318
- praisonaiagents/build/lib/praisonaiagents/main.py +0 -112
- praisonaiagents/build/lib/praisonaiagents/task/__init__.py +0 -4
- praisonaiagents/build/lib/praisonaiagents/task/task.py +0 -48
- {praisonaiagents-0.0.28.dist-info → praisonaiagents-0.0.29.dist-info}/top_level.txt +0 -0
@@ -1,318 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import time
|
3
|
-
import json
|
4
|
-
import logging
|
5
|
-
from typing import Any, Dict, Optional
|
6
|
-
from pydantic import BaseModel
|
7
|
-
from rich.text import Text
|
8
|
-
from rich.panel import Panel
|
9
|
-
from rich.console import Console
|
10
|
-
from ..main import display_error, TaskOutput, error_logs, client
|
11
|
-
from ..agent.agent import Agent
|
12
|
-
from ..task.task import Task
|
13
|
-
|
14
|
-
class Agents:
|
15
|
-
def __init__(self, agents, tasks, verbose=0, completion_checker=None, max_retries=5, process="sequential", manager_llm=None):
|
16
|
-
self.agents = agents
|
17
|
-
self.tasks = {}
|
18
|
-
if max_retries < 3:
|
19
|
-
max_retries = 3
|
20
|
-
self.completion_checker = completion_checker if completion_checker else self.default_completion_checker
|
21
|
-
self.task_id_counter = 0
|
22
|
-
self.verbose = verbose
|
23
|
-
self.max_retries = max_retries
|
24
|
-
self.process = process
|
25
|
-
self.manager_llm = manager_llm
|
26
|
-
for task in tasks:
|
27
|
-
self.add_task(task)
|
28
|
-
task.status = "not started"
|
29
|
-
|
30
|
-
def add_task(self, task):
|
31
|
-
task_id = self.task_id_counter
|
32
|
-
task.id = task_id
|
33
|
-
self.tasks[task_id] = task
|
34
|
-
self.task_id_counter += 1
|
35
|
-
return task_id
|
36
|
-
|
37
|
-
def clean_json_output(self, output: str) -> str:
|
38
|
-
cleaned = output.strip()
|
39
|
-
if cleaned.startswith("```json"):
|
40
|
-
cleaned = cleaned[len("```json"):].strip()
|
41
|
-
if cleaned.startswith("```"):
|
42
|
-
cleaned = cleaned[len("```"):].strip()
|
43
|
-
if cleaned.endswith("```"):
|
44
|
-
cleaned = cleaned[:-3].strip()
|
45
|
-
return cleaned
|
46
|
-
|
47
|
-
def default_completion_checker(self, task, agent_output):
|
48
|
-
if task.output_json and task.result and task.result.json_dict:
|
49
|
-
return True
|
50
|
-
if task.output_pydantic and task.result and task.result.pydantic:
|
51
|
-
return True
|
52
|
-
return len(agent_output.strip()) > 0
|
53
|
-
|
54
|
-
def execute_task(self, task_id):
|
55
|
-
if task_id not in self.tasks:
|
56
|
-
display_error(f"Error: Task with ID {task_id} does not exist")
|
57
|
-
return
|
58
|
-
task = self.tasks[task_id]
|
59
|
-
if task.status == "not started":
|
60
|
-
task.status = "in progress"
|
61
|
-
|
62
|
-
executor_agent = task.agent
|
63
|
-
|
64
|
-
task_prompt = f"""
|
65
|
-
You need to do the following task: {task.description}.
|
66
|
-
Expected Output: {task.expected_output}.
|
67
|
-
"""
|
68
|
-
if task.context:
|
69
|
-
context_results = ""
|
70
|
-
for context_task in task.context:
|
71
|
-
if context_task.result:
|
72
|
-
context_results += f"Result of previous task {context_task.name if context_task.name else context_task.description}: {context_task.result.raw}\n"
|
73
|
-
else:
|
74
|
-
context_results += f"Previous task {context_task.name if context_task.name else context_task.description} had no result.\n"
|
75
|
-
task_prompt += f"""
|
76
|
-
Here are the results of previous tasks that might be useful:\n
|
77
|
-
{context_results}
|
78
|
-
"""
|
79
|
-
task_prompt += "Please provide only the final result of your work. Do not add any conversation or extra explanation."
|
80
|
-
|
81
|
-
if self.verbose >= 2:
|
82
|
-
logging.info(f"Executing task {task_id}: {task.description} using {executor_agent.name}")
|
83
|
-
logging.debug(f"Starting execution of task {task_id} with prompt:\n{task_prompt}")
|
84
|
-
agent_output = executor_agent.chat(task_prompt, tools=task.tools)
|
85
|
-
if agent_output:
|
86
|
-
task_output = TaskOutput(
|
87
|
-
description=task.description,
|
88
|
-
summary=task.description[:10],
|
89
|
-
raw=agent_output,
|
90
|
-
agent=executor_agent.name,
|
91
|
-
output_format="RAW"
|
92
|
-
)
|
93
|
-
|
94
|
-
if task.output_json:
|
95
|
-
cleaned = self.clean_json_output(agent_output)
|
96
|
-
try:
|
97
|
-
parsed = json.loads(cleaned)
|
98
|
-
task_output.json_dict = parsed
|
99
|
-
task_output.output_format = "JSON"
|
100
|
-
except:
|
101
|
-
logging.warning(f"Warning: Could not parse output of task {task_id} as JSON")
|
102
|
-
logging.debug(f"Output that failed JSON parsing: {agent_output}")
|
103
|
-
|
104
|
-
if task.output_pydantic:
|
105
|
-
cleaned = self.clean_json_output(agent_output)
|
106
|
-
try:
|
107
|
-
parsed = json.loads(cleaned)
|
108
|
-
pyd_obj = task.output_pydantic(**parsed)
|
109
|
-
task_output.pydantic = pyd_obj
|
110
|
-
task_output.output_format = "Pydantic"
|
111
|
-
except:
|
112
|
-
logging.warning(f"Warning: Could not parse output of task {task_id} as Pydantic Model")
|
113
|
-
logging.debug(f"Output that failed Pydantic parsing: {agent_output}")
|
114
|
-
|
115
|
-
task.result = task_output
|
116
|
-
return task_output
|
117
|
-
else:
|
118
|
-
task.status = "failed"
|
119
|
-
return None
|
120
|
-
|
121
|
-
def save_output_to_file(self, task, task_output):
|
122
|
-
if task.output_file:
|
123
|
-
try:
|
124
|
-
if task.create_directory:
|
125
|
-
os.makedirs(os.path.dirname(task.output_file), exist_ok=True)
|
126
|
-
with open(task.output_file, "w") as f:
|
127
|
-
f.write(str(task_output))
|
128
|
-
if self.verbose >= 1:
|
129
|
-
logging.info(f"Task output saved to {task.output_file}")
|
130
|
-
except Exception as e:
|
131
|
-
display_error(f"Error saving task output to file: {e}")
|
132
|
-
|
133
|
-
def run_task(self, task_id):
|
134
|
-
if task_id not in self.tasks:
|
135
|
-
display_error(f"Error: Task with ID {task_id} does not exist")
|
136
|
-
return
|
137
|
-
task = self.tasks[task_id]
|
138
|
-
if task.status == "completed":
|
139
|
-
logging.info(f"Task with ID {task_id} is already completed")
|
140
|
-
return
|
141
|
-
|
142
|
-
retries = 0
|
143
|
-
while task.status != "completed" and retries < self.max_retries:
|
144
|
-
logging.debug(f"Attempt {retries+1} for task {task_id}")
|
145
|
-
if task.status in ["not started", "in progress"]:
|
146
|
-
task_output = self.execute_task(task_id)
|
147
|
-
if task_output and self.completion_checker(task, task_output.raw):
|
148
|
-
task.status = "completed"
|
149
|
-
if task.callback:
|
150
|
-
task.callback(task_output)
|
151
|
-
self.save_output_to_file(task, task_output)
|
152
|
-
if self.verbose >= 1:
|
153
|
-
logging.info(f"Task {task_id} completed successfully.")
|
154
|
-
else:
|
155
|
-
task.status = "in progress"
|
156
|
-
if self.verbose >= 1:
|
157
|
-
logging.info(f"Task {task_id} not completed, retrying")
|
158
|
-
time.sleep(1)
|
159
|
-
retries += 1
|
160
|
-
else:
|
161
|
-
if task.status == "failed":
|
162
|
-
logging.info("Task is failed, resetting to in-progress for another try...")
|
163
|
-
task.status = "in progress"
|
164
|
-
else:
|
165
|
-
logging.info("Invalid Task status")
|
166
|
-
break
|
167
|
-
|
168
|
-
if retries == self.max_retries and task.status != "completed":
|
169
|
-
logging.info(f"Task {task_id} failed after {self.max_retries} retries.")
|
170
|
-
|
171
|
-
def run_all_tasks(self):
|
172
|
-
if self.process == "sequential":
|
173
|
-
for task_id in self.tasks:
|
174
|
-
if self.tasks[task_id].status != "completed":
|
175
|
-
self.run_task(task_id)
|
176
|
-
elif self.process == "hierarchical":
|
177
|
-
logging.debug(f"Starting hierarchical task execution with {len(self.tasks)} tasks")
|
178
|
-
manager_agent = Agent(
|
179
|
-
name="Manager",
|
180
|
-
role="Project manager",
|
181
|
-
goal="Manage the entire flow of tasks and delegate them to the right agent",
|
182
|
-
backstory="Expert project manager to coordinate tasks among agents",
|
183
|
-
llm=self.manager_llm,
|
184
|
-
verbose=self.verbose,
|
185
|
-
markdown=True,
|
186
|
-
self_reflect=False
|
187
|
-
)
|
188
|
-
|
189
|
-
class ManagerInstructions(BaseModel):
|
190
|
-
task_id: int
|
191
|
-
agent_name: str
|
192
|
-
action: str
|
193
|
-
|
194
|
-
manager_task = Task(
|
195
|
-
name="manager_task",
|
196
|
-
description="Decide the order of tasks and which agent executes them",
|
197
|
-
expected_output="All tasks completed successfully",
|
198
|
-
agent=manager_agent
|
199
|
-
)
|
200
|
-
manager_task_id = self.add_task(manager_task)
|
201
|
-
logging.info(f"Created manager task with ID {manager_task_id}")
|
202
|
-
|
203
|
-
completed_count = 0
|
204
|
-
total_tasks = len(self.tasks) - 1
|
205
|
-
logging.info(f"Need to complete {total_tasks} tasks (excluding manager task)")
|
206
|
-
|
207
|
-
while completed_count < total_tasks:
|
208
|
-
tasks_summary = []
|
209
|
-
for tid, tk in self.tasks.items():
|
210
|
-
if tk.name == "manager_task":
|
211
|
-
continue
|
212
|
-
task_info = {
|
213
|
-
"task_id": tid,
|
214
|
-
"name": tk.name,
|
215
|
-
"description": tk.description,
|
216
|
-
"status": tk.status if tk.status else "not started",
|
217
|
-
"agent": tk.agent.name if tk.agent else "No agent"
|
218
|
-
}
|
219
|
-
tasks_summary.append(task_info)
|
220
|
-
logging.info(f"Task {tid} status: {task_info}")
|
221
|
-
|
222
|
-
manager_prompt = f"""
|
223
|
-
Here is the current status of all tasks except yours (manager_task):
|
224
|
-
{tasks_summary}
|
225
|
-
|
226
|
-
Provide a JSON with the structure:
|
227
|
-
{{
|
228
|
-
"task_id": <int>,
|
229
|
-
"agent_name": "<string>",
|
230
|
-
"action": "<execute or stop>"
|
231
|
-
}}
|
232
|
-
"""
|
233
|
-
|
234
|
-
try:
|
235
|
-
logging.info("Requesting manager instructions...")
|
236
|
-
manager_response = client.beta.chat.completions.parse(
|
237
|
-
model=self.manager_llm,
|
238
|
-
messages=[
|
239
|
-
{"role": "system", "content": manager_task.description},
|
240
|
-
{"role": "user", "content": manager_prompt}
|
241
|
-
],
|
242
|
-
temperature=0.7,
|
243
|
-
response_format=ManagerInstructions
|
244
|
-
)
|
245
|
-
parsed_instructions = manager_response.choices[0].message.parsed
|
246
|
-
logging.info(f"Manager instructions: {parsed_instructions}")
|
247
|
-
except Exception as e:
|
248
|
-
display_error(f"Manager parse error: {e}")
|
249
|
-
logging.error(f"Manager parse error: {str(e)}", exc_info=True)
|
250
|
-
break
|
251
|
-
|
252
|
-
selected_task_id = parsed_instructions.task_id
|
253
|
-
selected_agent_name = parsed_instructions.agent_name
|
254
|
-
action = parsed_instructions.action
|
255
|
-
|
256
|
-
logging.info(f"Manager selected task_id={selected_task_id}, agent={selected_agent_name}, action={action}")
|
257
|
-
|
258
|
-
if action.lower() == "stop":
|
259
|
-
logging.info("Manager decided to stop task execution")
|
260
|
-
break
|
261
|
-
|
262
|
-
if selected_task_id not in self.tasks:
|
263
|
-
error_msg = f"Manager selected invalid task id {selected_task_id}"
|
264
|
-
display_error(error_msg)
|
265
|
-
logging.error(error_msg)
|
266
|
-
break
|
267
|
-
|
268
|
-
original_agent = self.tasks[selected_task_id].agent.name if self.tasks[selected_task_id].agent else "None"
|
269
|
-
for a in self.agents:
|
270
|
-
if a.name == selected_agent_name:
|
271
|
-
self.tasks[selected_task_id].agent = a
|
272
|
-
logging.info(f"Changed agent for task {selected_task_id} from {original_agent} to {selected_agent_name}")
|
273
|
-
break
|
274
|
-
|
275
|
-
if self.tasks[selected_task_id].status != "completed":
|
276
|
-
logging.info(f"Starting execution of task {selected_task_id}")
|
277
|
-
self.run_task(selected_task_id)
|
278
|
-
logging.info(f"Finished execution of task {selected_task_id}, status: {self.tasks[selected_task_id].status}")
|
279
|
-
|
280
|
-
if self.tasks[selected_task_id].status == "completed":
|
281
|
-
completed_count += 1
|
282
|
-
logging.info(f"Task {selected_task_id} completed. Total completed: {completed_count}/{total_tasks}")
|
283
|
-
|
284
|
-
self.tasks[manager_task.id].status = "completed"
|
285
|
-
if self.verbose >= 1:
|
286
|
-
logging.info("All tasks completed under manager supervision.")
|
287
|
-
logging.info("Hierarchical task execution finished")
|
288
|
-
|
289
|
-
def get_task_status(self, task_id):
|
290
|
-
if task_id in self.tasks:
|
291
|
-
return self.tasks[task_id].status
|
292
|
-
return None
|
293
|
-
|
294
|
-
def get_all_tasks_status(self):
|
295
|
-
return {task_id: self.tasks[task_id].status for task_id in self.tasks}
|
296
|
-
|
297
|
-
def get_task_result(self, task_id):
|
298
|
-
if task_id in self.tasks:
|
299
|
-
return self.tasks[task_id].result
|
300
|
-
return None
|
301
|
-
|
302
|
-
def get_task_details(self, task_id):
|
303
|
-
if task_id in self.tasks:
|
304
|
-
return str(self.tasks[task_id])
|
305
|
-
return None
|
306
|
-
|
307
|
-
def get_agent_details(self, agent_name):
|
308
|
-
agent = [task.agent for task in self.tasks.values() if task.agent and task.agent.name == agent_name]
|
309
|
-
if agent:
|
310
|
-
return str(agent[0])
|
311
|
-
return None
|
312
|
-
|
313
|
-
def start(self):
|
314
|
-
self.run_all_tasks()
|
315
|
-
return {
|
316
|
-
"task_status": self.get_all_tasks_status(),
|
317
|
-
"task_results": {task_id: self.get_task_result(task_id) for task_id in self.tasks}
|
318
|
-
}
|
@@ -1,112 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import time
|
3
|
-
import json
|
4
|
-
import logging
|
5
|
-
from typing import List, Optional, Dict, Any, Union, Literal, Type
|
6
|
-
from openai import OpenAI
|
7
|
-
from pydantic import BaseModel
|
8
|
-
from rich import print
|
9
|
-
from rich.console import Console
|
10
|
-
from rich.panel import Panel
|
11
|
-
from rich.text import Text
|
12
|
-
from rich.markdown import Markdown
|
13
|
-
from rich.logging import RichHandler
|
14
|
-
from rich.live import Live
|
15
|
-
|
16
|
-
LOGLEVEL = os.environ.get('LOGLEVEL', 'INFO').upper()
|
17
|
-
|
18
|
-
logging.basicConfig(
|
19
|
-
level=getattr(logging, LOGLEVEL, logging.INFO),
|
20
|
-
format="%(asctime)s %(filename)s:%(lineno)d %(levelname)s %(message)s",
|
21
|
-
datefmt="[%X]",
|
22
|
-
handlers=[RichHandler(rich_tracebacks=True)]
|
23
|
-
)
|
24
|
-
|
25
|
-
# Global list to store error logs
|
26
|
-
error_logs = []
|
27
|
-
|
28
|
-
def display_interaction(message: str, response: str, markdown: bool = True, generation_time: Optional[float] = None):
|
29
|
-
console = Console()
|
30
|
-
if generation_time is not None:
|
31
|
-
console.print(Text(f"Response generated in {generation_time:.1f}s", style="dim"))
|
32
|
-
else:
|
33
|
-
console.print(Text("Response Generation Complete", style="dim"))
|
34
|
-
|
35
|
-
if markdown:
|
36
|
-
console.print(Panel.fit(Markdown(message), title="Message", border_style="cyan"))
|
37
|
-
console.print(Panel.fit(Markdown(response), title="Response", border_style="cyan"))
|
38
|
-
else:
|
39
|
-
console.print(Panel.fit(Text(message, style="bold green"), title="Message", border_style="cyan"))
|
40
|
-
console.print(Panel.fit(Text(response, style="bold white"), title="Response", border_style="cyan"))
|
41
|
-
|
42
|
-
def display_self_reflection(message: str):
|
43
|
-
console = Console()
|
44
|
-
console.print(Panel.fit(Text(message, style="bold yellow"), title="Self Reflection", border_style="magenta"))
|
45
|
-
|
46
|
-
def display_instruction(message: str):
|
47
|
-
console = Console()
|
48
|
-
console.print(Panel.fit(Text(message, style="bold blue"), title="Instruction", border_style="cyan"))
|
49
|
-
|
50
|
-
def display_tool_call(message: str):
|
51
|
-
console = Console()
|
52
|
-
console.print(Panel.fit(Text(message, style="bold cyan"), title="Tool Call", border_style="green"))
|
53
|
-
|
54
|
-
def display_error(message: str):
|
55
|
-
console = Console()
|
56
|
-
console.print(Panel.fit(Text(message, style="bold red"), title="Error", border_style="red"))
|
57
|
-
# Store errors
|
58
|
-
error_logs.append(message)
|
59
|
-
|
60
|
-
def display_generating(content: str = "", start_time: Optional[float] = None):
|
61
|
-
elapsed_str = ""
|
62
|
-
if start_time is not None:
|
63
|
-
elapsed = time.time() - start_time
|
64
|
-
elapsed_str = f" {elapsed:.1f}s"
|
65
|
-
return Panel(Markdown(content), title=f"Generating...{elapsed_str}", border_style="green")
|
66
|
-
|
67
|
-
def clean_triple_backticks(text: str) -> str:
|
68
|
-
"""Remove triple backticks and surrounding json fences from a string."""
|
69
|
-
cleaned = text.strip()
|
70
|
-
if cleaned.startswith("```json"):
|
71
|
-
cleaned = cleaned[len("```json"):].strip()
|
72
|
-
if cleaned.startswith("```"):
|
73
|
-
cleaned = cleaned[len("```"):].strip()
|
74
|
-
if cleaned.endswith("```"):
|
75
|
-
cleaned = cleaned[:-3].strip()
|
76
|
-
return cleaned
|
77
|
-
|
78
|
-
class ReflectionOutput(BaseModel):
|
79
|
-
reflection: str
|
80
|
-
satisfactory: Literal["yes", "no"]
|
81
|
-
|
82
|
-
client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
|
83
|
-
|
84
|
-
class TaskOutput(BaseModel):
|
85
|
-
description: str
|
86
|
-
summary: Optional[str] = None
|
87
|
-
raw: str
|
88
|
-
pydantic: Optional[BaseModel] = None
|
89
|
-
json_dict: Optional[Dict[str, Any]] = None
|
90
|
-
agent: str
|
91
|
-
output_format: Literal["RAW", "JSON", "Pydantic"] = "RAW"
|
92
|
-
|
93
|
-
def json(self) -> Optional[str]:
|
94
|
-
if self.output_format == "JSON" and self.json_dict:
|
95
|
-
return json.dumps(self.json_dict)
|
96
|
-
return None
|
97
|
-
|
98
|
-
def to_dict(self) -> dict:
|
99
|
-
output_dict = {}
|
100
|
-
if self.json_dict:
|
101
|
-
output_dict.update(self.json_dict)
|
102
|
-
if self.pydantic:
|
103
|
-
output_dict.update(self.pydantic.model_dump())
|
104
|
-
return output_dict
|
105
|
-
|
106
|
-
def __str__(self):
|
107
|
-
if self.pydantic:
|
108
|
-
return str(self.pydantic)
|
109
|
-
elif self.json_dict:
|
110
|
-
return json.dumps(self.json_dict)
|
111
|
-
else:
|
112
|
-
return self.raw
|
@@ -1,48 +0,0 @@
|
|
1
|
-
import logging
|
2
|
-
from typing import List, Optional, Dict, Any, Type
|
3
|
-
from pydantic import BaseModel
|
4
|
-
from ..main import TaskOutput
|
5
|
-
from ..agent.agent import Agent
|
6
|
-
|
7
|
-
class Task:
|
8
|
-
def __init__(
|
9
|
-
self,
|
10
|
-
description: str,
|
11
|
-
expected_output: str,
|
12
|
-
agent: Optional[Agent] = None,
|
13
|
-
name: Optional[str] = None,
|
14
|
-
tools: Optional[List[Any]] = None,
|
15
|
-
context: Optional[List["Task"]] = None,
|
16
|
-
async_execution: Optional[bool] = False,
|
17
|
-
config: Optional[Dict[str, Any]] = None,
|
18
|
-
output_file: Optional[str] = None,
|
19
|
-
output_json: Optional[Type[BaseModel]] = None,
|
20
|
-
output_pydantic: Optional[Type[BaseModel]] = None,
|
21
|
-
callback: Optional[Any] = None,
|
22
|
-
status: str = "not started",
|
23
|
-
result: Optional[TaskOutput] = None,
|
24
|
-
create_directory: Optional[bool] = False,
|
25
|
-
id: Optional[int] = None
|
26
|
-
):
|
27
|
-
self.description = description
|
28
|
-
self.expected_output = expected_output
|
29
|
-
self.name = name
|
30
|
-
self.agent = agent
|
31
|
-
self.tools = tools if tools else []
|
32
|
-
self.context = context if context else []
|
33
|
-
self.async_execution = async_execution
|
34
|
-
self.config = config if config else {}
|
35
|
-
self.output_file = output_file
|
36
|
-
self.output_json = output_json
|
37
|
-
self.output_pydantic = output_pydantic
|
38
|
-
self.callback = callback
|
39
|
-
self.status = status
|
40
|
-
self.result = result
|
41
|
-
self.create_directory = create_directory
|
42
|
-
self.id = id
|
43
|
-
|
44
|
-
if self.output_json and self.output_pydantic:
|
45
|
-
raise ValueError("Only one output type can be defined")
|
46
|
-
|
47
|
-
def __str__(self):
|
48
|
-
return f"Task(name='{self.name if self.name else 'None'}', description='{self.description}', agent='{self.agent.name if self.agent else 'None'}', status='{self.status}')"
|
File without changes
|