praisonaiagents 0.0.14__py3-none-any.whl → 0.0.16__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/agents/agents.py +15 -247
- praisonaiagents/process/__init__.py +3 -0
- praisonaiagents/process/process.py +263 -0
- {praisonaiagents-0.0.14.dist-info → praisonaiagents-0.0.16.dist-info}/METADATA +1 -1
- {praisonaiagents-0.0.14.dist-info → praisonaiagents-0.0.16.dist-info}/RECORD +7 -5
- {praisonaiagents-0.0.14.dist-info → praisonaiagents-0.0.16.dist-info}/WHEEL +0 -0
- {praisonaiagents-0.0.14.dist-info → praisonaiagents-0.0.16.dist-info}/top_level.txt +0 -0
praisonaiagents/agents/agents.py
CHANGED
@@ -10,9 +10,7 @@ from rich.console import Console
|
|
10
10
|
from ..main import display_error, TaskOutput, error_logs, client
|
11
11
|
from ..agent.agent import Agent
|
12
12
|
from ..task.task import Task
|
13
|
-
|
14
|
-
class LoopItems(BaseModel):
|
15
|
-
items: List[Any]
|
13
|
+
from ..process.process import Process, LoopItems
|
16
14
|
|
17
15
|
def encode_file_to_base64(file_path: str) -> str:
|
18
16
|
"""Base64-encode a file."""
|
@@ -256,254 +254,24 @@ Expected Output: {task.expected_output}.
|
|
256
254
|
|
257
255
|
def run_all_tasks(self):
|
258
256
|
"""Execute tasks based on execution mode"""
|
257
|
+
process = Process(
|
258
|
+
tasks=self.tasks,
|
259
|
+
agents=self.agents,
|
260
|
+
manager_llm=self.manager_llm,
|
261
|
+
verbose=self.verbose
|
262
|
+
)
|
263
|
+
|
259
264
|
if self.process == "workflow":
|
260
|
-
|
261
|
-
for task in self.tasks.values():
|
262
|
-
if task.next_tasks:
|
263
|
-
for next_task_name in task.next_tasks:
|
264
|
-
next_task = next((t for t in self.tasks.values() if t.name == next_task_name), None)
|
265
|
-
if next_task:
|
266
|
-
next_task.previous_tasks.append(task.name)
|
267
|
-
|
268
|
-
# Find start task
|
269
|
-
start_task = None
|
270
|
-
for task_id, task in self.tasks.items():
|
271
|
-
if task.is_start:
|
272
|
-
start_task = task
|
273
|
-
break
|
274
|
-
|
275
|
-
if not start_task:
|
276
|
-
start_task = list(self.tasks.values())[0]
|
277
|
-
logging.info("No start task marked, using first task")
|
278
|
-
|
279
|
-
current_task = start_task
|
280
|
-
visited_tasks = set()
|
281
|
-
loop_data = {} # Store loop-specific data
|
282
|
-
|
283
|
-
while current_task and current_task.id not in visited_tasks:
|
284
|
-
task_id = current_task.id
|
285
|
-
logging.info(f"Executing workflow task: {current_task.name if current_task.name else task_id}")
|
286
|
-
|
287
|
-
# Add context from previous tasks to description
|
288
|
-
if current_task.previous_tasks or current_task.context:
|
289
|
-
context = "\nInput data from previous tasks:"
|
290
|
-
|
291
|
-
# Add data from previous tasks in workflow
|
292
|
-
for prev_name in current_task.previous_tasks:
|
293
|
-
prev_task = next((t for t in self.tasks.values() if t.name == prev_name), None)
|
294
|
-
if prev_task and prev_task.result:
|
295
|
-
# Handle loop data
|
296
|
-
if current_task.task_type == "loop":
|
297
|
-
# create a loop manager Agent
|
298
|
-
loop_manager = Agent(
|
299
|
-
name="Loop Manager",
|
300
|
-
role="Loop data processor",
|
301
|
-
goal="Process loop data and convert it to list format",
|
302
|
-
backstory="Expert at handling loop data and converting it to proper format",
|
303
|
-
llm=self.manager_llm,
|
304
|
-
verbose=self.verbose,
|
305
|
-
markdown=True
|
306
|
-
)
|
307
|
-
|
308
|
-
# get the loop data convert it to list using calling Agent class chat
|
309
|
-
loop_prompt = f"""
|
310
|
-
Process this data into a list format:
|
311
|
-
{prev_task.result.raw}
|
312
|
-
|
313
|
-
Return a JSON object with an 'items' array containing the items to process.
|
314
|
-
"""
|
315
|
-
loop_data_str = loop_manager.chat(
|
316
|
-
prompt=loop_prompt,
|
317
|
-
output_json=LoopItems
|
318
|
-
)
|
319
|
-
|
320
|
-
try:
|
321
|
-
# The response will already be parsed into LoopItems model
|
322
|
-
loop_data[f"loop_{current_task.name}"] = {
|
323
|
-
"items": loop_data_str.items,
|
324
|
-
"index": 0,
|
325
|
-
"remaining": len(loop_data_str.items)
|
326
|
-
}
|
327
|
-
context += f"\nCurrent loop item: {loop_data_str.items[0]}"
|
328
|
-
except Exception as e:
|
329
|
-
display_error(f"Failed to process loop data: {e}")
|
330
|
-
context += f"\n{prev_name}: {prev_task.result.raw}"
|
331
|
-
else:
|
332
|
-
context += f"\n{prev_name}: {prev_task.result.raw}"
|
333
|
-
|
334
|
-
# Add data from context tasks
|
335
|
-
if current_task.context:
|
336
|
-
for ctx_task in current_task.context:
|
337
|
-
if ctx_task.result and ctx_task.name != current_task.name:
|
338
|
-
context += f"\n{ctx_task.name}: {ctx_task.result.raw}"
|
339
|
-
|
340
|
-
# Update task description with context
|
341
|
-
current_task.description = current_task.description + context
|
342
|
-
|
343
|
-
# Execute task using existing run_task method
|
265
|
+
for task_id in process.workflow():
|
344
266
|
self.run_task(task_id)
|
345
|
-
visited_tasks.add(task_id)
|
346
|
-
|
347
|
-
# Handle loop progression
|
348
|
-
if current_task.task_type == "loop":
|
349
|
-
loop_key = f"loop_{current_task.name}"
|
350
|
-
if loop_key in loop_data:
|
351
|
-
loop_info = loop_data[loop_key]
|
352
|
-
loop_info["index"] += 1
|
353
|
-
has_more = loop_info["remaining"] > 0
|
354
|
-
|
355
|
-
# Update result to trigger correct condition
|
356
|
-
if current_task.result:
|
357
|
-
result = current_task.result.raw
|
358
|
-
if has_more:
|
359
|
-
result += "\nmore"
|
360
|
-
else:
|
361
|
-
result += "\ndone"
|
362
|
-
current_task.result.raw = result
|
363
|
-
|
364
|
-
# Determine next task based on result
|
365
|
-
next_task = None
|
366
|
-
if current_task.result:
|
367
|
-
if current_task.task_type in ["decision", "loop"]:
|
368
|
-
result = current_task.result.raw.lower()
|
369
|
-
# Check conditions
|
370
|
-
for condition, tasks in current_task.condition.items():
|
371
|
-
if condition.lower() in result and tasks:
|
372
|
-
next_task_name = tasks[0]
|
373
|
-
next_task = next((t for t in self.tasks.values() if t.name == next_task_name), None)
|
374
|
-
# For loops, allow revisiting the same task
|
375
|
-
if next_task and next_task.id == current_task.id:
|
376
|
-
visited_tasks.discard(current_task.id)
|
377
|
-
break
|
378
|
-
|
379
|
-
if not next_task and current_task.next_tasks:
|
380
|
-
next_task_name = current_task.next_tasks[0]
|
381
|
-
next_task = next((t for t in self.tasks.values() if t.name == next_task_name), None)
|
382
|
-
|
383
|
-
current_task = next_task
|
384
|
-
if not current_task:
|
385
|
-
logging.info("Workflow execution completed")
|
386
|
-
break
|
387
|
-
|
388
267
|
elif self.process == "sequential":
|
389
|
-
|
390
|
-
|
391
|
-
if self.tasks[task_id].status != "completed":
|
392
|
-
self.run_task(task_id)
|
393
|
-
|
268
|
+
for task_id in process.sequential():
|
269
|
+
self.run_task(task_id)
|
394
270
|
elif self.process == "hierarchical":
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
role="Project manager",
|
400
|
-
goal="Manage the entire flow of tasks and delegate them to the right agent",
|
401
|
-
backstory="Expert project manager to coordinate tasks among agents",
|
402
|
-
llm=self.manager_llm,
|
403
|
-
verbose=self.verbose,
|
404
|
-
markdown=True,
|
405
|
-
self_reflect=False
|
406
|
-
)
|
407
|
-
|
408
|
-
class ManagerInstructions(BaseModel):
|
409
|
-
task_id: int
|
410
|
-
agent_name: str
|
411
|
-
action: str
|
412
|
-
|
413
|
-
manager_task = Task(
|
414
|
-
name="manager_task",
|
415
|
-
description="Decide the order of tasks and which agent executes them",
|
416
|
-
expected_output="All tasks completed successfully",
|
417
|
-
agent=manager_agent
|
418
|
-
)
|
419
|
-
manager_task_id = self.add_task(manager_task)
|
420
|
-
logging.info(f"Created manager task with ID {manager_task_id}")
|
421
|
-
|
422
|
-
completed_count = 0
|
423
|
-
total_tasks = len(self.tasks) - 1
|
424
|
-
logging.info(f"Need to complete {total_tasks} tasks (excluding manager task)")
|
425
|
-
|
426
|
-
while completed_count < total_tasks:
|
427
|
-
tasks_summary = []
|
428
|
-
for tid, tk in self.tasks.items():
|
429
|
-
if tk.name == "manager_task":
|
430
|
-
continue
|
431
|
-
task_info = {
|
432
|
-
"task_id": tid,
|
433
|
-
"name": tk.name,
|
434
|
-
"description": tk.description,
|
435
|
-
"status": tk.status if tk.status else "not started",
|
436
|
-
"agent": tk.agent.name if tk.agent else "No agent"
|
437
|
-
}
|
438
|
-
tasks_summary.append(task_info)
|
439
|
-
logging.info(f"Task {tid} status: {task_info}")
|
440
|
-
|
441
|
-
manager_prompt = f"""
|
442
|
-
Here is the current status of all tasks except yours (manager_task):
|
443
|
-
{tasks_summary}
|
444
|
-
|
445
|
-
Provide a JSON with the structure:
|
446
|
-
{{
|
447
|
-
"task_id": <int>,
|
448
|
-
"agent_name": "<string>",
|
449
|
-
"action": "<execute or stop>"
|
450
|
-
}}
|
451
|
-
"""
|
452
|
-
|
453
|
-
try:
|
454
|
-
logging.info("Requesting manager instructions...")
|
455
|
-
manager_response = client.beta.chat.completions.parse(
|
456
|
-
model=self.manager_llm,
|
457
|
-
messages=[
|
458
|
-
{"role": "system", "content": manager_task.description},
|
459
|
-
{"role": "user", "content": manager_prompt}
|
460
|
-
],
|
461
|
-
temperature=0.7,
|
462
|
-
response_format=ManagerInstructions
|
463
|
-
)
|
464
|
-
parsed_instructions = manager_response.choices[0].message.parsed
|
465
|
-
logging.info(f"Manager instructions: {parsed_instructions}")
|
466
|
-
except Exception as e:
|
467
|
-
display_error(f"Manager parse error: {e}")
|
468
|
-
logging.error(f"Manager parse error: {str(e)}", exc_info=True)
|
469
|
-
break
|
470
|
-
|
471
|
-
selected_task_id = parsed_instructions.task_id
|
472
|
-
selected_agent_name = parsed_instructions.agent_name
|
473
|
-
action = parsed_instructions.action
|
474
|
-
|
475
|
-
logging.info(f"Manager selected task_id={selected_task_id}, agent={selected_agent_name}, action={action}")
|
476
|
-
|
477
|
-
if action.lower() == "stop":
|
478
|
-
logging.info("Manager decided to stop task execution")
|
479
|
-
break
|
480
|
-
|
481
|
-
if selected_task_id not in self.tasks:
|
482
|
-
error_msg = f"Manager selected invalid task id {selected_task_id}"
|
483
|
-
display_error(error_msg)
|
484
|
-
logging.error(error_msg)
|
485
|
-
break
|
486
|
-
|
487
|
-
original_agent = self.tasks[selected_task_id].agent.name if self.tasks[selected_task_id].agent else "None"
|
488
|
-
for a in self.agents:
|
489
|
-
if a.name == selected_agent_name:
|
490
|
-
self.tasks[selected_task_id].agent = a
|
491
|
-
logging.info(f"Changed agent for task {selected_task_id} from {original_agent} to {selected_agent_name}")
|
492
|
-
break
|
493
|
-
|
494
|
-
if self.tasks[selected_task_id].status != "completed":
|
495
|
-
logging.info(f"Starting execution of task {selected_task_id}")
|
496
|
-
self.run_task(selected_task_id)
|
497
|
-
logging.info(f"Finished execution of task {selected_task_id}, status: {self.tasks[selected_task_id].status}")
|
498
|
-
|
499
|
-
if self.tasks[selected_task_id].status == "completed":
|
500
|
-
completed_count += 1
|
501
|
-
logging.info(f"Task {selected_task_id} completed. Total completed: {completed_count}/{total_tasks}")
|
502
|
-
|
503
|
-
self.tasks[manager_task.id].status = "completed"
|
504
|
-
if self.verbose >= 1:
|
505
|
-
logging.info("All tasks completed under manager supervision.")
|
506
|
-
logging.info("Hierarchical task execution finished")
|
271
|
+
for task_id in process.hierarchical():
|
272
|
+
if isinstance(task_id, Task):
|
273
|
+
task_id = self.add_task(task_id)
|
274
|
+
self.run_task(task_id)
|
507
275
|
|
508
276
|
def get_task_status(self, task_id):
|
509
277
|
if task_id in self.tasks:
|
@@ -0,0 +1,263 @@
|
|
1
|
+
import logging
|
2
|
+
from typing import Dict, Optional, List, Any
|
3
|
+
from pydantic import BaseModel
|
4
|
+
from ..agent.agent import Agent
|
5
|
+
from ..task.task import Task
|
6
|
+
from ..main import display_error, client
|
7
|
+
|
8
|
+
class LoopItems(BaseModel):
|
9
|
+
items: List[Any]
|
10
|
+
|
11
|
+
class Process:
|
12
|
+
def __init__(self, tasks: Dict[str, Task], agents: List[Agent], manager_llm: Optional[str] = None, verbose: bool = False):
|
13
|
+
self.tasks = tasks
|
14
|
+
self.agents = agents
|
15
|
+
self.manager_llm = manager_llm
|
16
|
+
self.verbose = verbose
|
17
|
+
|
18
|
+
def workflow(self):
|
19
|
+
# Build workflow relationships first
|
20
|
+
for task in self.tasks.values():
|
21
|
+
if task.next_tasks:
|
22
|
+
for next_task_name in task.next_tasks:
|
23
|
+
next_task = next((t for t in self.tasks.values() if t.name == next_task_name), None)
|
24
|
+
if next_task:
|
25
|
+
next_task.previous_tasks.append(task.name)
|
26
|
+
|
27
|
+
# Find start task
|
28
|
+
start_task = None
|
29
|
+
for task_id, task in self.tasks.items():
|
30
|
+
if task.is_start:
|
31
|
+
start_task = task
|
32
|
+
break
|
33
|
+
|
34
|
+
if not start_task:
|
35
|
+
start_task = list(self.tasks.values())[0]
|
36
|
+
logging.info("No start task marked, using first task")
|
37
|
+
|
38
|
+
current_task = start_task
|
39
|
+
visited_tasks = set()
|
40
|
+
loop_data = {} # Store loop-specific data
|
41
|
+
|
42
|
+
while current_task and current_task.id not in visited_tasks:
|
43
|
+
task_id = current_task.id
|
44
|
+
logging.info(f"Executing workflow task: {current_task.name if current_task.name else task_id}")
|
45
|
+
|
46
|
+
# Add context from previous tasks to description
|
47
|
+
if current_task.previous_tasks or current_task.context:
|
48
|
+
context = "\nInput data from previous tasks:"
|
49
|
+
|
50
|
+
# Add data from previous tasks in workflow
|
51
|
+
for prev_name in current_task.previous_tasks:
|
52
|
+
prev_task = next((t for t in self.tasks.values() if t.name == prev_name), None)
|
53
|
+
if prev_task and prev_task.result:
|
54
|
+
# Handle loop data
|
55
|
+
if current_task.task_type == "loop":
|
56
|
+
# create a loop manager Agent
|
57
|
+
loop_manager = Agent(
|
58
|
+
name="Loop Manager",
|
59
|
+
role="Loop data processor",
|
60
|
+
goal="Process loop data and convert it to list format",
|
61
|
+
backstory="Expert at handling loop data and converting it to proper format",
|
62
|
+
llm=self.manager_llm,
|
63
|
+
verbose=self.verbose,
|
64
|
+
markdown=True
|
65
|
+
)
|
66
|
+
|
67
|
+
# get the loop data convert it to list using calling Agent class chat
|
68
|
+
loop_prompt = f"""
|
69
|
+
Process this data into a list format:
|
70
|
+
{prev_task.result.raw}
|
71
|
+
|
72
|
+
Return a JSON object with an 'items' array containing the items to process.
|
73
|
+
"""
|
74
|
+
loop_data_str = loop_manager.chat(
|
75
|
+
prompt=loop_prompt,
|
76
|
+
output_json=LoopItems
|
77
|
+
)
|
78
|
+
|
79
|
+
try:
|
80
|
+
# The response will already be parsed into LoopItems model
|
81
|
+
loop_data[f"loop_{current_task.name}"] = {
|
82
|
+
"items": loop_data_str.items,
|
83
|
+
"index": 0,
|
84
|
+
"remaining": len(loop_data_str.items)
|
85
|
+
}
|
86
|
+
context += f"\nCurrent loop item: {loop_data_str.items[0]}"
|
87
|
+
except Exception as e:
|
88
|
+
display_error(f"Failed to process loop data: {e}")
|
89
|
+
context += f"\n{prev_name}: {prev_task.result.raw}"
|
90
|
+
else:
|
91
|
+
context += f"\n{prev_name}: {prev_task.result.raw}"
|
92
|
+
|
93
|
+
# Add data from context tasks
|
94
|
+
if current_task.context:
|
95
|
+
for ctx_task in current_task.context:
|
96
|
+
if ctx_task.result and ctx_task.name != current_task.name:
|
97
|
+
context += f"\n{ctx_task.name}: {ctx_task.result.raw}"
|
98
|
+
|
99
|
+
# Update task description with context
|
100
|
+
current_task.description = current_task.description + context
|
101
|
+
|
102
|
+
# Execute task using existing run_task method
|
103
|
+
yield task_id
|
104
|
+
visited_tasks.add(task_id)
|
105
|
+
|
106
|
+
# Handle loop progression
|
107
|
+
if current_task.task_type == "loop":
|
108
|
+
loop_key = f"loop_{current_task.name}"
|
109
|
+
if loop_key in loop_data:
|
110
|
+
loop_info = loop_data[loop_key]
|
111
|
+
loop_info["index"] += 1
|
112
|
+
has_more = loop_info["remaining"] > 0
|
113
|
+
|
114
|
+
# Update result to trigger correct condition
|
115
|
+
if current_task.result:
|
116
|
+
result = current_task.result.raw
|
117
|
+
if has_more:
|
118
|
+
result += "\nmore"
|
119
|
+
else:
|
120
|
+
result += "\ndone"
|
121
|
+
current_task.result.raw = result
|
122
|
+
|
123
|
+
# Determine next task based on result
|
124
|
+
next_task = None
|
125
|
+
if current_task.result:
|
126
|
+
if current_task.task_type in ["decision", "loop"]:
|
127
|
+
result = current_task.result.raw.lower()
|
128
|
+
# Check conditions
|
129
|
+
for condition, tasks in current_task.condition.items():
|
130
|
+
if condition.lower() in result and tasks:
|
131
|
+
next_task_name = tasks[0]
|
132
|
+
next_task = next((t for t in self.tasks.values() if t.name == next_task_name), None)
|
133
|
+
# For loops, allow revisiting the same task
|
134
|
+
if next_task and next_task.id == current_task.id:
|
135
|
+
visited_tasks.discard(current_task.id)
|
136
|
+
break
|
137
|
+
|
138
|
+
if not next_task and current_task.next_tasks:
|
139
|
+
next_task_name = current_task.next_tasks[0]
|
140
|
+
next_task = next((t for t in self.tasks.values() if t.name == next_task_name), None)
|
141
|
+
|
142
|
+
current_task = next_task
|
143
|
+
if not current_task:
|
144
|
+
logging.info("Workflow execution completed")
|
145
|
+
break
|
146
|
+
|
147
|
+
def sequential(self):
|
148
|
+
for task_id in self.tasks:
|
149
|
+
if self.tasks[task_id].status != "completed":
|
150
|
+
yield task_id
|
151
|
+
|
152
|
+
def hierarchical(self):
|
153
|
+
logging.debug(f"Starting hierarchical task execution with {len(self.tasks)} tasks")
|
154
|
+
manager_agent = Agent(
|
155
|
+
name="Manager",
|
156
|
+
role="Project manager",
|
157
|
+
goal="Manage the entire flow of tasks and delegate them to the right agent",
|
158
|
+
backstory="Expert project manager to coordinate tasks among agents",
|
159
|
+
llm=self.manager_llm,
|
160
|
+
verbose=self.verbose,
|
161
|
+
markdown=True,
|
162
|
+
self_reflect=False
|
163
|
+
)
|
164
|
+
|
165
|
+
class ManagerInstructions(BaseModel):
|
166
|
+
task_id: int
|
167
|
+
agent_name: str
|
168
|
+
action: str
|
169
|
+
|
170
|
+
manager_task = Task(
|
171
|
+
name="manager_task",
|
172
|
+
description="Decide the order of tasks and which agent executes them",
|
173
|
+
expected_output="All tasks completed successfully",
|
174
|
+
agent=manager_agent
|
175
|
+
)
|
176
|
+
manager_task_id = yield manager_task
|
177
|
+
logging.info(f"Created manager task with ID {manager_task_id}")
|
178
|
+
|
179
|
+
completed_count = 0
|
180
|
+
total_tasks = len(self.tasks) - 1
|
181
|
+
logging.info(f"Need to complete {total_tasks} tasks (excluding manager task)")
|
182
|
+
|
183
|
+
while completed_count < total_tasks:
|
184
|
+
tasks_summary = []
|
185
|
+
for tid, tk in self.tasks.items():
|
186
|
+
if tk.name == "manager_task":
|
187
|
+
continue
|
188
|
+
task_info = {
|
189
|
+
"task_id": tid,
|
190
|
+
"name": tk.name,
|
191
|
+
"description": tk.description,
|
192
|
+
"status": tk.status if tk.status else "not started",
|
193
|
+
"agent": tk.agent.name if tk.agent else "No agent"
|
194
|
+
}
|
195
|
+
tasks_summary.append(task_info)
|
196
|
+
logging.info(f"Task {tid} status: {task_info}")
|
197
|
+
|
198
|
+
manager_prompt = f"""
|
199
|
+
Here is the current status of all tasks except yours (manager_task):
|
200
|
+
{tasks_summary}
|
201
|
+
|
202
|
+
Provide a JSON with the structure:
|
203
|
+
{{
|
204
|
+
"task_id": <int>,
|
205
|
+
"agent_name": "<string>",
|
206
|
+
"action": "<execute or stop>"
|
207
|
+
}}
|
208
|
+
"""
|
209
|
+
|
210
|
+
try:
|
211
|
+
logging.info("Requesting manager instructions...")
|
212
|
+
manager_response = client.beta.chat.completions.parse(
|
213
|
+
model=self.manager_llm,
|
214
|
+
messages=[
|
215
|
+
{"role": "system", "content": manager_task.description},
|
216
|
+
{"role": "user", "content": manager_prompt}
|
217
|
+
],
|
218
|
+
temperature=0.7,
|
219
|
+
response_format=ManagerInstructions
|
220
|
+
)
|
221
|
+
parsed_instructions = manager_response.choices[0].message.parsed
|
222
|
+
logging.info(f"Manager instructions: {parsed_instructions}")
|
223
|
+
except Exception as e:
|
224
|
+
display_error(f"Manager parse error: {e}")
|
225
|
+
logging.error(f"Manager parse error: {str(e)}", exc_info=True)
|
226
|
+
break
|
227
|
+
|
228
|
+
selected_task_id = parsed_instructions.task_id
|
229
|
+
selected_agent_name = parsed_instructions.agent_name
|
230
|
+
action = parsed_instructions.action
|
231
|
+
|
232
|
+
logging.info(f"Manager selected task_id={selected_task_id}, agent={selected_agent_name}, action={action}")
|
233
|
+
|
234
|
+
if action.lower() == "stop":
|
235
|
+
logging.info("Manager decided to stop task execution")
|
236
|
+
break
|
237
|
+
|
238
|
+
if selected_task_id not in self.tasks:
|
239
|
+
error_msg = f"Manager selected invalid task id {selected_task_id}"
|
240
|
+
display_error(error_msg)
|
241
|
+
logging.error(error_msg)
|
242
|
+
break
|
243
|
+
|
244
|
+
original_agent = self.tasks[selected_task_id].agent.name if self.tasks[selected_task_id].agent else "None"
|
245
|
+
for a in self.agents:
|
246
|
+
if a.name == selected_agent_name:
|
247
|
+
self.tasks[selected_task_id].agent = a
|
248
|
+
logging.info(f"Changed agent for task {selected_task_id} from {original_agent} to {selected_agent_name}")
|
249
|
+
break
|
250
|
+
|
251
|
+
if self.tasks[selected_task_id].status != "completed":
|
252
|
+
logging.info(f"Starting execution of task {selected_task_id}")
|
253
|
+
yield selected_task_id
|
254
|
+
logging.info(f"Finished execution of task {selected_task_id}, status: {self.tasks[selected_task_id].status}")
|
255
|
+
|
256
|
+
if self.tasks[selected_task_id].status == "completed":
|
257
|
+
completed_count += 1
|
258
|
+
logging.info(f"Task {selected_task_id} completed. Total completed: {completed_count}/{total_tasks}")
|
259
|
+
|
260
|
+
self.tasks[manager_task.id].status = "completed"
|
261
|
+
if self.verbose >= 1:
|
262
|
+
logging.info("All tasks completed under manager supervision.")
|
263
|
+
logging.info("Hierarchical task execution finished")
|
@@ -3,7 +3,7 @@ praisonaiagents/main.py,sha256=K2OxVKPmo4dNJbSWIsXDi_hm9CRx5O4km_74UGcszhk,5744
|
|
3
3
|
praisonaiagents/agent/__init__.py,sha256=sKO8wGEXvtCrvV1e834r1Okv0XAqAxqZCqz6hKLiTvA,79
|
4
4
|
praisonaiagents/agent/agent.py,sha256=zTYcDpJ5DzzBnefwLvhrtBlGQoRI4ZZAioDu5nKTPSs,24042
|
5
5
|
praisonaiagents/agents/__init__.py,sha256=7RDeQNSqZg5uBjD4M_0p_F6YgfWuDuxPFydPU50kDYc,120
|
6
|
-
praisonaiagents/agents/agents.py,sha256
|
6
|
+
praisonaiagents/agents/agents.py,sha256=-1Z-jIN2fkLM9P6nAq-OtKPTF8HIjA-a_Zznv8TfpFY,12964
|
7
7
|
praisonaiagents/build/lib/praisonaiagents/__init__.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
|
8
8
|
praisonaiagents/build/lib/praisonaiagents/main.py,sha256=zDhN5KKtKbfruolDNxlyJkcFlkSt4KQkQTDRfQVAhxc,3960
|
9
9
|
praisonaiagents/build/lib/praisonaiagents/agent/__init__.py,sha256=sKO8wGEXvtCrvV1e834r1Okv0XAqAxqZCqz6hKLiTvA,79
|
@@ -12,9 +12,11 @@ praisonaiagents/build/lib/praisonaiagents/agents/__init__.py,sha256=cgCLFLFcLp9S
|
|
12
12
|
praisonaiagents/build/lib/praisonaiagents/agents/agents.py,sha256=P2FAtlfD3kPib5a1oLVYanxlU6e4-GhBMQ0YDY5MHY4,13473
|
13
13
|
praisonaiagents/build/lib/praisonaiagents/task/__init__.py,sha256=VL5hXVmyGjINb34AalxpBMl-YW9m5EDcRkMTKkSSl7c,80
|
14
14
|
praisonaiagents/build/lib/praisonaiagents/task/task.py,sha256=4Y1qX8OeEFcid2yhAiPYylvHpuDmWORsyNL16_BiVvI,1831
|
15
|
+
praisonaiagents/process/__init__.py,sha256=lkYbL7Hn5a0ldvJtkdH23vfIIZLIcanK-65C0MwaorY,52
|
16
|
+
praisonaiagents/process/process.py,sha256=HN_xNeG02T5QwcvcuSw8OiABVYbKIYJ-J--3H8Hd89Q,11722
|
15
17
|
praisonaiagents/task/__init__.py,sha256=VL5hXVmyGjINb34AalxpBMl-YW9m5EDcRkMTKkSSl7c,80
|
16
18
|
praisonaiagents/task/task.py,sha256=oMC5Zz1dMj0Ceice69aBS1KQQXMLqphc8wNOQ9zcu0Q,2570
|
17
|
-
praisonaiagents-0.0.
|
18
|
-
praisonaiagents-0.0.
|
19
|
-
praisonaiagents-0.0.
|
20
|
-
praisonaiagents-0.0.
|
19
|
+
praisonaiagents-0.0.16.dist-info/METADATA,sha256=Nb_ZUqzMHYl2CzLFiDFAclzAAx4G0LWN6IWADmYu0LY,233
|
20
|
+
praisonaiagents-0.0.16.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
21
|
+
praisonaiagents-0.0.16.dist-info/top_level.txt,sha256=_HsRddrJ23iDx5TTqVUVvXG2HeHBL5voshncAMDGjtA,16
|
22
|
+
praisonaiagents-0.0.16.dist-info/RECORD,,
|
File without changes
|
File without changes
|