praisonaiagents 0.0.27__py3-none-any.whl → 0.0.29__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- praisonaiagents/__init__.py +4 -0
- praisonaiagents/agent/agent.py +7 -3
- praisonaiagents/agents/__init__.py +2 -1
- praisonaiagents/agents/agents.py +169 -35
- praisonaiagents/agents/autoagents.py +335 -0
- praisonaiagents/memory/memory.py +928 -0
- praisonaiagents/task/task.py +157 -9
- {praisonaiagents-0.0.27.dist-info → praisonaiagents-0.0.29.dist-info}/METADATA +4 -2
- {praisonaiagents-0.0.27.dist-info → praisonaiagents-0.0.29.dist-info}/RECORD +11 -17
- {praisonaiagents-0.0.27.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.27.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
|