refactor: simplify Task module and update related tests/examples
Description
Fixes: #3071
This pull request refactors the Task module to streamline its functionality and improve maintainability by reassigning responsibilities to the Workforce module where appropriate.
Changes Made
The previous Task module included functionalities that were better suited for the Workforce module and were only utilized in related tests and examples. As part of this refactoring, we have made the following changes:
Removed from Task Module:
- task_prompt.py
- TaskManagement class
Moved to Workforce Module:
- Task decomposition functionalities
Updated to Reflect Changes:
- Tests in test/tasks
- Examples in examples/tasks
- Documentation in docs/mintlify/key_modules
These changes ensure a clearer separation of concerns, improve module cohesion, and align the codebase with its intended design. The refactoring eliminates code duplication, clarifies module responsibilities, and improves maintainability by separating data structure (Task) from execution logic (Workforce).
Checklist
Go over all the following points, and put an x in all the boxes that apply.
- [x] I have read the CONTRIBUTION guide (required)
- [x] I have linked this PR to an issue using the Development section on the right sidebar or by adding
Fixes #issue-numberin the PR description (required) - [x] I have checked if any dependencies need to be added or updated in
pyproject.tomlanduv lock - [x] I have updated the tests accordingly (required for a bug fix or a new feature)
- [x] I have updated the documentation if needed:
- [ ] I have added examples if this is a new feature
If you are unsure about any of these, don't hesitate to ask. We are here to help!
[!IMPORTANT]
Review skipped
Auto reviews are disabled on this repository.
Please check the settings in the CodeRabbit UI or the
.coderabbit.yamlfile in this repository. To trigger a single review, invoke the@coderabbitai reviewcommand.You can disable this status message by setting the
reviews.review_statustofalsein the CodeRabbit configuration file.
Walkthrough
Removes decomposition/management logic and prompts from Task module; shifts decomposition into Workforce with streaming and non‑streaming flows; updates public exports to only Task and TaskState; expands Task as a data structure with validation utilities; updates docs and tests; deletes old examples and adds new multimodal/basic examples; minor import/source adjustments.
Changes
| Cohort / File(s) | Summary |
|---|---|
Task module cleanupcamel/tasks/task.py |
Removes decompose/compose, streaming/non-streaming parsers, TaskManager; adds TaskValidationMode and validate_task_content; expands Task fields (ids, state=TaskState.FAILED, media, dependencies, etc.); refactors insufficiency check and annotations. |
Tasks package exportscamel/tasks/__init__.py |
Narrows exports to Task and TaskState; removes TaskManager and prompt exports; updates import source to TaskState. |
Workforce streaming decompositioncamel/societies/workforce/workforce.py |
Adds streaming-aware decomposition via task_agent and StreamingChatAgentResponse; introduces _parse_partial_tasks, _parse_response, _decompose_streaming, _decompose_non_streaming; normalizes dict keys; memory sharing reconstruction; signature annotations updated. |
Worker import tweakcamel/societies/workforce/worker.py |
Changes import of Task/TaskState to come from camel.tasks. |
Prompt removalcamel/tasks/task_prompt.py |
Deletes module and its public prompts (TASK_DECOMPOSE_PROMPT, TASK_COMPOSE_PROMPT, TASK_EVOLVE_PROMPT). |
Docs updatedocs/mintlify/key_modules/tasks.mdx |
Overhauls Task docs to data-structure focus, adds new attributes/sections, updates method notes and state type to TaskState. |
Examples removedexamples/tasks/task_generation.py, examples/tasks/multi_modal_task_generation.py |
Deletes legacy examples relying on TaskManager/decompose flows. |
New examplesexamples/tasks/multi_modal_task.py, examples/tasks/sub_task.py |
Adds multimodal Task construction demo and basic Task/subtask/state example without TaskManager. |
Tests refactortest/tasks/test_task.py |
Replaces string states with TaskState; removes TaskManager usage; adds hierarchy/state/media attribute tests; updates names and assertions. |
Sequence Diagram(s)
sequenceDiagram
autonumber
participant C as Coordinator
participant WF as Workforce
participant TA as Task Agent
participant Parser as Decompose Parser
C->>WF: request_decompose(task)
WF->>TA: send(decompose_prompt)
alt Streaming response
TA-->>WF: StreamingChatAgentResponse (chunks)
loop chunks
WF->>Parser: _parse_partial_tasks(task, chunk)
Parser-->>WF: [subtasks*]
WF->>WF: attach subtasks, set parent/deps
end
else Non-streaming
TA-->>WF: Full response
WF->>Parser: _parse_response(response)
Parser-->>WF: [subtasks]
WF->>WF: attach subtasks, set parent/deps
end
WF-->>C: subtasks (progressive or final)
Estimated code review effort
🎯 4 (Complex) | ⏱️ ~60 minutes
Assessment against linked issues
| Objective | Addressed | Explanation |
|---|---|---|
| Clean up unused/overlapping functionality in Task module by removing decompose/compose/management, aligning with Workforce (#3071) | ✅ |
Assessment against linked issues: Out-of-scope changes
| Code Change | Explanation |
|---|---|
| Introduce streaming-aware decomposition, partial parsing, and memory sharing in Workforce (camel/societies/workforce/workforce.py, multiple locations) | Extends Workforce functionality beyond the stated cleanup of the Task module. |
| Add new multimodal and basic task examples (examples/tasks/multi_modal_task.py, examples/tasks/sub_task.py) | New demos are not explicitly required by the cleanup objective. |
| Broad docs overhaul beyond noting removals (docs/mintlify/key_modules/tasks.mdx, multiple sections) | Documentation additions exceed minimal cleanup; though related, scope was limited to code cleanup. |
Possibly related PRs
- camel-ai/camel#2747 — Adjusts Task/Workforce around validation and worker assignment; overlaps with state/assignment fields and validation pathways.
- camel-ai/camel#2690 — Modifies Task defaults and Workforce behavior; intersects with this PR’s Task state and Workforce control flow.
- camel-ai/camel#2635 — Changes task decomposition logic and Workforce APIs; directly related to moving decomposition into Workforce.
Suggested labels
enhancement
Suggested reviewers
- Wendong-Fan
Poem
Hoppity hops through fields of code,
I trimmed the twigs from Task’s old load.
Prompts packed away, the streams now flow,
In Workforce burrows, subtasks grow.
With tidy paws and whiskers bright—
I chase the bugs by moonlit byte.
Thump-thump! The roadmap feels just right.
✨ Finishing touches
🧪 Generate unit tests
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
[!TIP]
👮 Agentic pre-merge checks are now available in preview!
Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
- Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
- Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.
Please see the documentation for more information.
Example:
reviews: pre_merge_checks: custom_checks: - name: "Undocumented Breaking Changes" mode: "warning" instructions: | Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).Please share your feedback with us on this Discord post.
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.
@coderabbitai review
✅ Actions performed
Review triggered.
Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
Hey @zack-nova. Thanks for the PR and the hard work that went into it.
The current implementation of moving the decompose into workforce is wrong. maybe in the codebase we only decompose tasks for workforce operations, but developers may simply use it for other purposes outside of workforce too. and it doesn't seem intuitive at all, to take Task related operations out of Task and put them somewhere else as private method.
so let's say i want to decompose tasks for some purpose outside workforce, like creating my own multi-agent structure.
before:
# Simple one-liner decomposition
task = Task(content="Plan a birthday party", id="main")
agent = ChatAgent("You are a party planner")
subtasks = task.decompose(agent)
now:
# must create heavyweight workforce infrastructure
workforce = Workforce(
description="Task decomposition workforce",
coordinator_agent=coordinator_agent,
task_agent=task_agent,
new_worker_agent=new_worker_agent
)
task = Task(content="Plan a birthday party", id="main")
subtasks = workforce._decompose_task(task, prompt) # Private
method!
I can see the motivation behind your reasoning. But I think it will confuse the devs, especially with no backward compatibility.
my understanding is thath:
- Task should handle task-specific operations such as decompose. dumping everything into the Workforce and turning it into a god module will not be good in the long run.
- a simple task decompose would require creating a workforce, with at least 3 agents.
- the dev should have access to the decompose method, being private will be confusing for them. task.decompose is a useful and common operation. it's totally normal for classes to have methods operating on them, in this case, task.decompose.
- we can't keep a number of operations in Task (update result, add_substack) and then simply move one method to a different place.
hey @nitpicker55555 @hesamsheikh @a7m-1st,
Just bumping this review as comments have now been addressed since last review.