Skip to content

Commit edf70d1

Browse files
committed
Add loop agent functionality and update task management in PraisonAI agents
- Introduced a new loop agent in `loop_agents.py` to create and manage a loop of tasks from a CSV file. - Added a new file `repetitive-manual-agents.py` that implements task identification, status checking, and updating functionalities. - Updated `process.py` to enhance task handling by allowing dynamic input files for loop tasks. - Removed the obsolete `repeat_agents.py` file to streamline the codebase. - Bumped the version of the `praisonaiagents` package from 0.0.42 to 0.0.43 in `pyproject.toml` and `uv.lock` to reflect these changes. These updates improve the task execution capabilities of the PraisonAI framework, particularly in handling repetitive tasks and enhancing agent functionality.
1 parent 7df3b9d commit edf70d1

File tree

8 files changed

+100
-11
lines changed

8 files changed

+100
-11
lines changed

agents/loop_agents.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from praisonaiagents import Agent, Task, PraisonAIAgents
2+
3+
agent = Agent(
4+
instructions="You are a loop agent that creating a loop of tasks.",
5+
llm="gpt-4o-mini"
6+
)
7+
8+
task = Task(
9+
description="Create the list of tasks to be looped through.",
10+
agent=agent,
11+
task_type="loop",
12+
input_file="tasks.csv"
13+
)
14+
15+
agents = PraisonAIAgents(
16+
agents=[agent],
17+
tasks=[task],
18+
process="workflow"
19+
)
20+
21+
agents.start()

agents/praisonaiagents/process/process.py

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
from ..agent.agent import Agent
66
from ..task.task import Task
77
from ..main import display_error, client
8+
import csv
9+
import os
810

911
class LoopItems(BaseModel):
1012
items: List[Any]
@@ -327,7 +329,76 @@ def workflow(self):
327329
if not start_task:
328330
start_task = list(self.tasks.values())[0]
329331
logging.info("No start task marked, using first task")
330-
332+
333+
# If loop type and no input_file, default to tasks.csv
334+
if start_task and start_task.task_type == "loop" and not start_task.input_file:
335+
start_task.input_file = "tasks.csv"
336+
337+
# --- If loop + input_file, read file & create tasks
338+
if start_task and start_task.task_type == "loop" and getattr(start_task, "input_file", None):
339+
try:
340+
file_ext = os.path.splitext(start_task.input_file)[1].lower()
341+
new_tasks = []
342+
343+
if file_ext == ".csv":
344+
# existing CSV reading logic
345+
with open(start_task.input_file, "r", encoding="utf-8") as f:
346+
# Try as simple CSV first
347+
reader = csv.reader(f)
348+
previous_task = None
349+
for i, row in enumerate(reader):
350+
if row: # Skip empty rows
351+
task_desc = row[0] # Take first column
352+
row_task = Task(
353+
description=task_desc, # Keep full row as description
354+
agent=start_task.agent,
355+
name=task_desc, # Use first column as name
356+
is_start=(i == 0),
357+
task_type="task",
358+
condition={
359+
"complete": ["next"],
360+
"retry": ["current"]
361+
}
362+
)
363+
self.tasks[row_task.id] = row_task
364+
new_tasks.append(row_task)
365+
366+
if previous_task:
367+
previous_task.next_tasks = [row_task.name]
368+
previous_task.condition["complete"] = [row_task.name]
369+
previous_task = row_task
370+
else:
371+
# If not CSV, read lines
372+
with open(start_task.input_file, "r", encoding="utf-8") as f:
373+
lines = f.read().splitlines()
374+
previous_task = None
375+
for i, line in enumerate(lines):
376+
row_task = Task(
377+
description=line.strip(),
378+
agent=start_task.agent,
379+
name=line.strip(),
380+
is_start=(i == 0),
381+
task_type="task",
382+
condition={
383+
"complete": ["next"],
384+
"retry": ["current"]
385+
}
386+
)
387+
self.tasks[row_task.id] = row_task
388+
new_tasks.append(row_task)
389+
390+
if previous_task:
391+
previous_task.next_tasks = [row_task.name]
392+
previous_task.condition["complete"] = [row_task.name]
393+
previous_task = row_task
394+
395+
if new_tasks:
396+
start_task = new_tasks[0]
397+
logging.info(f"Created {len(new_tasks)} tasks from: {start_task.input_file}")
398+
except Exception as e:
399+
logging.error(f"Failed to read file tasks: {e}")
400+
401+
# end of the new block
331402
current_task = start_task
332403
visited_tasks = set()
333404
loop_data = {} # Store loop-specific data

agents/praisonaiagents/task/task.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@ def __init__(
3737
is_start: bool = False,
3838
loop_state: Optional[Dict[str, Union[str, int]]] = None,
3939
memory=None,
40-
quality_check=True
40+
quality_check=True,
41+
input_file: Optional[str] = None
4142
):
43+
self.input_file = input_file
4244
self.id = str(uuid.uuid4()) if id is None else str(id)
4345
self.name = name
4446
self.description = description

agents/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "praisonaiagents"
7-
version = "0.0.42"
7+
version = "0.0.43"
88
description = "Praison AI agents for completing complex tasks with Self Reflection Agents"
99
authors = [
1010
{ name="Mervin Praison" }

agents/repeat_agents.py

Whitespace-only changes.
File renamed without changes.

agents/tasks.csv

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,2 @@
1-
task,status,loop_id
2-
write clear email format,Complete,1
3-
create technical documentation,Complete,2
4-
practice bullet points formatting,Complete,3
5-
improve paragraph structure,Complete,4
6-
learn markdown syntax,pending,5
7-
master business letter format,pending,6
1+
write clear email formatting template
2+
create technical documentation template

agents/uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)