Skip to content

feat: container signature status/progress + mageflow.astatus#135

Merged
yedidyakfir merged 9 commits into
developfrom
feat/134-container-status
Jul 24, 2026
Merged

feat: container signature status/progress + mageflow.astatus#135
yedidyakfir merged 9 commits into
developfrom
feat/134-container-status

Conversation

@yedidyakfir

@yedidyakfir yedidyakfir commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Closes #134

Summary

Adds the ability to inspect how far along a container signature (Swarm / Chain) is, plus a client function to query several containers at once.

  • ContainerStatus — structured per-container breakdown: total, finished, failed, running, pending, percentage, status, is_done. Percentage is terminal-state: (finished + failed) / total, guarded for total == 0.
  • ContainersStatus — wraps list[ContainerStatus] with an aggregate overall_percentage.
  • container_status() — abstract on ContainerTaskSignature; swarm derives from its bookkeeping lists, chain classifies children by task_status.
  • mageflow.astatus(*ids) — loads signatures, raises MissingSignatureError / NotAContainerError when appropriate, returns a ContainersStatus. Exposed as HatchetMageflow.astatus and re-exported from the package.

Commits

  1. status result models + NotAContainerError
  2. container_status() for swarm and chain
  3. astatus aggregator + client method + exports
  4. unit tests

Testing

New unit tests cover swarm/chain breakdowns (terminal percentage, done, empty), multi-container aggregation, and the missing / non-container raise paths.

  • third-magic: 134 passed
  • mageflow: 261 passed

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added container status reporting with task counts, completion state, and progress percentages.
    • Added aggregate status reporting across multiple containers.
    • Added support for retrieving container statuses through the Hatchet integration.
    • Added clear errors for missing signatures and non-container tasks.
  • Tests

    • Added coverage for single-container, multi-container, empty, completed, and error scenarios.

yedidyakfir and others added 4 commits July 23, 2026 21:33
Add ContainerStatus (per-container breakdown with terminal-state
percentage) and ContainersStatus (aggregate wrapper) to the signature
status module, plus a NotAContainerError for the status lookups.

Refs #134

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add an abstract container_status() to ContainerTaskSignature. Swarm
derives counts from its bookkeeping lists; chain classifies children by
their task_status.

Refs #134

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add astatus(*ids) that loads signatures, verifies each is a container
(raising MissingSignatureError / NotAContainerError otherwise) and
returns their ContainersStatus. Exposed as HatchetMageflow.astatus and
re-exported from the mageflow package.

Refs #134

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add unit tests for swarm/chain container_status (terminal percentage,
done, empty) and for astatus (single, aggregate, and the missing /
non-container raise paths).

Refs #134

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d6a89d04-c635-4628-a1ce-18daf66d93ca

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds structured progress reporting for swarm and chain container signatures, concurrent multi-container status aggregation, new error handling, and Mageflow/Hatchet API exports with unit coverage.

Changes

Container status feature

Layer / File(s) Summary
Status models and container contract
libs/third-magic/thirdmagic/signature/status.py, libs/third-magic/thirdmagic/container.py, libs/third-magic/thirdmagic/errors.py, libs/third-magic/thirdmagic/signature/__init__.py
Defines ContainerStatus and ContainersStatus, adds terminal-progress calculations, declares container_status(), and introduces NotAContainerError.
Swarm and chain status computation
libs/third-magic/thirdmagic/swarm/model.py, libs/third-magic/thirdmagic/chain/model.py, libs/third-magic/tests/unit/test_container_status.py
Computes container counts and completion state for swarm and chain signatures, with tests for terminal, active, pending, empty, and completed cases.
Status loading and aggregation
libs/third-magic/thirdmagic/status.py
Validates requested signatures, loads multiple containers concurrently, invokes their status methods, and returns ContainersStatus.
Mageflow API exposure and validation
libs/mageflow/mageflow/__init__.py, libs/mageflow/mageflow/clients/hatchet/mageflow.py, libs/mageflow/tests/unit/workflows/test_astatus.py
Exports astatus and status models, adds HatchetMageflow.astatus, and tests aggregation plus missing and non-container errors.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Mageflow
  participant thirdmagic.status
  participant Rapyer
  participant ContainerTaskSignature
  Mageflow->>thirdmagic.status: astatus(*signature_ids)
  thirdmagic.status->>Rapyer: Load signatures
  Rapyer-->>thirdmagic.status: Return signatures
  thirdmagic.status->>ContainerTaskSignature: container_status()
  ContainerTaskSignature-->>thirdmagic.status: Return ContainerStatus
  thirdmagic.status-->>Mageflow: Return ContainersStatus
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly names the new container status/progress feature and the mageflow.astatus addition.
Linked Issues check ✅ Passed The changes cover container_status, astatus aggregation, error handling, exports, and tests as requested.
Out of Scope Changes check ✅ Passed The diff stays focused on container status/progress APIs and related tests, with no obvious unrelated additions.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/134-container-status

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@libs/mageflow/tests/unit/workflows/test_astatus.py`:
- Around line 11-33: Extend test_astatus_returns_status_for_single_container to
assert the running count is 1 and the completion flag is false, matching the
fixture’s current_running=1 and unfinished task state. Keep the existing status
assertions unchanged.

In `@libs/third-magic/thirdmagic/swarm/model.py`:
- Around line 190-201: Update the swarm task-management logic around add_tasks()
and is_swarm_done() to reject duplicate signature keys for new additions and
compare task-key multiplicities so persisted duplicates cannot report completion
early; preserve accurate total, finished, and percentage status values. In
libs/third-magic/thirdmagic/swarm/model.py lines 190-201, apply the completion
fix through the existing container_status() flow; in
libs/third-magic/tests/unit/test_container_status.py lines 35-52, add regression
coverage verifying duplicate additions are rejected or completion remains false
until every duplicate instance is completed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 231431a9-d7b1-4432-9706-09e223294d8b

📥 Commits

Reviewing files that changed from the base of the PR and between 5fa65c2 and 5278c9a.

📒 Files selected for processing (11)
  • libs/mageflow/mageflow/__init__.py
  • libs/mageflow/mageflow/clients/hatchet/mageflow.py
  • libs/mageflow/tests/unit/workflows/test_astatus.py
  • libs/third-magic/tests/unit/test_container_status.py
  • libs/third-magic/thirdmagic/chain/model.py
  • libs/third-magic/thirdmagic/container.py
  • libs/third-magic/thirdmagic/errors.py
  • libs/third-magic/thirdmagic/signature/__init__.py
  • libs/third-magic/thirdmagic/signature/status.py
  • libs/third-magic/thirdmagic/status.py
  • libs/third-magic/thirdmagic/swarm/model.py

Comment on lines +11 to +33
async def test_astatus_returns_status_for_single_container(mock_adapter):
# Arrange
setup = await create_swarm_item_test_setup(
num_tasks=4,
stop_after_n_failures=None,
current_running=1,
tasks_left_indices=[3],
finished_indices=[0],
failed_indices=[1],
)

# Act
result = await mageflow.astatus(setup.swarm_task.key)

# Assert
assert isinstance(result, ContainersStatus)
status = result.containers[0]
assert status.signature_id == setup.swarm_task.key
assert status.total == 4
assert status.finished == 1
assert status.failed == 1
assert status.pending == 1
assert status.percentage == 50.0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Assert the running and completion fields too.

This fixture deliberately creates one running task, but the test never verifies status.running or status.is_done. A regression that drops either field could still pass the current assertions.

Proposed test additions
     assert status.failed == 1
+    assert status.running == 1
     assert status.pending == 1
     assert status.percentage == 50.0
+    assert status.is_done is False

As per path instructions, tests should cover contract completeness and edge cases.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async def test_astatus_returns_status_for_single_container(mock_adapter):
# Arrange
setup = await create_swarm_item_test_setup(
num_tasks=4,
stop_after_n_failures=None,
current_running=1,
tasks_left_indices=[3],
finished_indices=[0],
failed_indices=[1],
)
# Act
result = await mageflow.astatus(setup.swarm_task.key)
# Assert
assert isinstance(result, ContainersStatus)
status = result.containers[0]
assert status.signature_id == setup.swarm_task.key
assert status.total == 4
assert status.finished == 1
assert status.failed == 1
assert status.pending == 1
assert status.percentage == 50.0
async def test_astatus_returns_status_for_single_container(mock_adapter):
# Arrange
setup = await create_swarm_item_test_setup(
num_tasks=4,
stop_after_n_failures=None,
current_running=1,
tasks_left_indices=[3],
finished_indices=[0],
failed_indices=[1],
)
# Act
result = await mageflow.astatus(setup.swarm_task.key)
# Assert
assert isinstance(result, ContainersStatus)
status = result.containers[0]
assert status.signature_id == setup.swarm_task.key
assert status.total == 4
assert status.finished == 1
assert status.failed == 1
assert status.running == 1
assert status.pending == 1
assert status.percentage == 50.0
assert status.is_done is False
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@libs/mageflow/tests/unit/workflows/test_astatus.py` around lines 11 - 33,
Extend test_astatus_returns_status_for_single_container to assert the running
count is 1 and the completion flag is false, matching the fixture’s
current_running=1 and unfinished task state. Keep the existing status assertions
unchanged.

Source: Path instructions

Comment on lines +190 to +201
async def container_status(self) -> ContainerStatus:
return ContainerStatus.from_counts(
signature_id=self.key,
task_name=self.task_name,
status=self.task_status.status,
total=len(self.tasks),
finished=len(self.finished_tasks),
failed=len(self.failed_tasks),
running=self.current_running_tasks,
pending=len(self.tasks_left_to_run),
is_done=await self.is_swarm_done(),
)

@coderabbitai coderabbitai Bot Jul 23, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Prevent duplicate task keys from reporting completion early.

add_tasks() permits the same signature key more than once, while is_swarm_done() compares sets. A closed swarm containing [A, A] reports is_done=True after one completion, even though this status returns total=2, finished=1, and percentage=50.0.

  • libs/third-magic/thirdmagic/swarm/model.py#L190-L201: preserve task-key uniqueness when adding tasks and make completion multiplicity-aware for existing persisted duplicates.
  • libs/third-magic/tests/unit/test_container_status.py#L35-L52: add a duplicate-key regression case that verifies duplicate additions are rejected or cannot report completion early.

As per path instructions, **/tests/**: “Focus on test coverage completeness and edge cases.”

📍 Affects 2 files
  • libs/third-magic/thirdmagic/swarm/model.py#L190-L201 (this comment)
  • libs/third-magic/tests/unit/test_container_status.py#L35-L52
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@libs/third-magic/thirdmagic/swarm/model.py` around lines 190 - 201, Update
the swarm task-management logic around add_tasks() and is_swarm_done() to reject
duplicate signature keys for new additions and compare task-key multiplicities
so persisted duplicates cannot report completion early; preserve accurate total,
finished, and percentage status values. In
libs/third-magic/thirdmagic/swarm/model.py lines 190-201, apply the completion
fix through the existing container_status() flow; in
libs/third-magic/tests/unit/test_container_status.py lines 35-52, add regression
coverage verifying duplicate additions are rejected or completion remains false
until every duplicate instance is completed.

Source: Path instructions

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the bug is with the add_task, not here, and will be fixed in the short future

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yedidyakfir Understood—the root cause is duplicate admission in add_task(). The current is_swarm_done() set comparison still makes persisted duplicates complete early, so I’ll leave this finding open until that follow-up lands. Would you like me to create a GitHub issue to track it?

Replace the per-id asyncio.gather of afind_one with one batch
rapyer.afind, and short-circuit on empty input so an empty id list
never triggers a full-DB extraction. Missing keys are detected via a
length check and still raise MissingSignatureError.

Refs #134

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
yedidyakfir and others added 2 commits July 24, 2026 13:15
The per-container progress method is now astatus() on
ContainerTaskSignature (and swarm/chain), matching the client-facing
mageflow.astatus naming.

Refs #134

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the Status section to the functions API reference, the client
method, and the swarm/chain container astatus() method, and record the
feature in the changelog (#134).

Refs #134

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ContainerStatus and ContainersStatus are now imported from thirdmagic
(top-level and thirdmagic.signature). The mageflow package only
re-exports the astatus function, not the result types.

Refs #134

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Build the entire expected ContainerStatus / ContainersStatus in the
arrange step and compare with equality, instead of asserting individual
fields.

Refs #134

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@yedidyakfir
yedidyakfir merged commit 52e0a45 into develop Jul 24, 2026
35 checks passed
@yedidyakfir
yedidyakfir deleted the feat/134-container-status branch July 24, 2026 13:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant