Skip to content

fix: extract shared _retry_backoff helper in workflows.py - #3833

Open
praisonai-triage-agent[bot] wants to merge 1 commit into
mainfrom
claude/issue-3832-20260809-1715
Open

fix: extract shared _retry_backoff helper in workflows.py#3833
praisonai-triage-agent[bot] wants to merge 1 commit into
mainfrom
claude/issue-3832-20260809-1715

Conversation

@praisonai-triage-agent

@praisonai-triage-agent praisonai-triage-agent Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Fixes #3832

Summary

The step retry exponential-backoff + progress-print block was duplicated byte-for-byte between two places in praisonaiagents/workflows/workflows.py:

  • the inline copy in the top-level _run_impl loop, and
  • the shared _apply_step_policies helper.

This PR takes the minimal, sanctioned interim path from the issue: extract just the duplicated retry-delay-and-print into a single private Workflow._retry_backoff(step, retry_count, max_retries, error, verbose) helper, and call it from both paths.

What changed

  • Added _retry_backoff staticmethod containing the 2 ** (retry_count - 1) backoff, the byte-identical verbose progress line, and time.sleep(...).
  • Replaced the inline backoff block in _run_impl with a call to it.
  • Replaced the backoff block in _apply_step_policies with a call to it.

Behaviour preserved (zero change)

  • Exponential backoff timing (2 ** (retry_count - 1)), max_retries semantics, and the is_retryable early-break.
  • The verbose progress/failure prints (identical string).
  • Guardrail validation, validation_feedback propagation, retry-on-invalid.
  • on_step_error callback firing and the guardrail_failed flag / downstream step_failed handling (left exactly as-is on the top-level path).
  • output_file writing behaviour.

The larger "fold the whole per-step body into a run_body closure" merge was intentionally not done: it would require converting ~140 lines of the top-level loop body into a closure and threading on_step_error/guardrail_failed back out β€” invasive and risky. This change removes the most-copied lines with no behaviour change, per AGENTS.md (lightweight, minimal, backward-compatible).

Testing

  • tests/test_workflow_patterns.py β€” 86 passed
  • tests/test_validation_feedback.py β€” 6 passed
  • tests/unit/workflows/ β€” 129 passed (5 pre-existing failures are unrelated litellm optional-dependency import errors)

Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved retry handling for workflow steps.
    • Preserved exponential backoff delays and retry messages for both standard and nested workflow execution.

The step retry exponential-backoff + progress-print block was duplicated
byte-for-byte between the top-level _run_impl loop and the shared
_apply_step_policies helper. Extract it into a single private
_retry_backoff() used by both paths. Behaviour is unchanged: same
2**(retry_count-1) timing, same verbose print, same time.sleep. All
retryability, guardrail, on_step_error and guardrail_failed semantics are
preserved.

Co-authored-by: MervinPraison <MervinPraison@users.noreply.github.com>
@MervinPraison

Copy link
Copy Markdown
Owner

@coderabbitai review

@MervinPraison

Copy link
Copy Markdown
Owner

/review

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more β†’

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account β†’

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us β†’

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor
βœ… Action performed

Review finished.

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.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. πŸŽ‰

ℹ️ Recent review info
βš™οΈ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3bb25c61-d5ff-4847-9a58-3f2e38091dc9

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 84752e7 and 1e00f62.

πŸ“’ Files selected for processing (1)
  • src/praisonai-agents/praisonaiagents/workflows/workflows.py

πŸ“ Walkthrough

Walkthrough

The workflow retry backoff logic now uses a shared _retry_backoff helper. Top-level and nested step execution retain the existing exponential delay, verbose retry message, and sleep behavior.

Changes

Workflow retry backoff

Layer / File(s) Summary
Centralize retry backoff behavior
src/praisonai-agents/praisonaiagents/workflows/workflows.py
The private _retry_backoff helper centralizes retry delay calculation, verbose retry reporting, and sleeping. Top-level and nested step retries call the helper.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: mervinpraison

πŸš₯ Pre-merge checks | βœ… 5
βœ… Passed checks (5 passed)
Check name Status Explanation
Description Check βœ… Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check βœ… Passed The title clearly describes the primary change: extracting the shared retry backoff helper in workflows.py.
Linked Issues check βœ… Passed The PR implements the linked issue's permitted interim solution by extracting shared retry-delay and progress-print logic without changing behavior.
Out of Scope Changes check βœ… Passed The changes are limited to the requested internal retry backoff refactor in workflows.py and contain no unrelated scope.
Docstring Coverage βœ… Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
πŸ“ Generate docstrings
  • Create stacked PR
  • Commit on current branch
πŸ§ͺ Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/issue-3832-20260809-1715

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.

@greptile-apps

greptile-apps Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR extracts duplicated retry delay and progress-reporting logic into a private static helper without changing retry semantics.

  • Adds AgentFlow._retry_backoff for exponential delay, verbose progress output, and sleeping.
  • Uses the helper from both the top-level workflow loop and nested step-policy path.

Confidence Score: 5/5

The PR appears safe to merge with no actionable regressions identified.

Both retry paths invoke a shared helper containing the same backoff calculation, verbose message, and sleep behavior as the removed inline blocks.

Important Files Changed

Filename Overview
src/praisonai-agents/praisonaiagents/workflows/workflows.py Consolidates two equivalent retry-backoff blocks into one helper while preserving their arguments, conditions, output, and timing.

Reviews (1): Last reviewed commit: "fix: extract shared _retry_backoff helpe..." | Re-trigger Greptile

@MervinPraison

Copy link
Copy Markdown
Owner

@claude You are the FINAL architecture reviewer. If the branch is under MervinPraison/PraisonAI (not a fork), you are able to make modifications to this branch and push directly. SCOPE: Focus ONLY on Python packages (praisonaiagents, praisonai). Do NOT modify praisonai-rust or praisonai-ts. Read ALL comments above from Gemini, Qodo, CodeRabbit, and Copilot carefully before responding.

Phase 1: Review per AGENTS.md

  1. Protocol-driven: check heavy implementations vs core SDK
  2. Backward compatible: ensure zero feature regressions
  3. Performance: no hot-path regressions
  4. SDK value: review in depth whether the change genuinely adds value to the SDK β€” never add features for the sake of adding them. It must strengthen the SDK (simpler, more user-friendly, robust, world-class, secure). If it does not clearly add value, request changes or recommend rejecting/closing rather than merging scope creep
  5. Do not bloat the Agent class with additional params β€” only if absolutely required; we already support many params.
  6. Repo routing: agent-callable tools β†’ PraisonAI-Tools; lifecycle plugins β†’ PraisonAI-Plugins; optional sandbox backends β†’ PraisonAI-Plugins (praisonai.sandbox entry point) β€” request changes if wrongly added to praisonaiagents/

Phase 2: FIX Valid Issues
7. For any VALID bugs or architectural flaws found by Gemini, CodeRabbit, Qodo, Copilot, or any other reviewer: implement the fix
8. Also independently identify and fix any gaps or issues you find in the changed code β€” do not rely only on prior reviewer feedback
9. Push all code fixes directly to THIS branch (do NOT create a new PR)
10. Comment a summary of exact files modified and what you skipped

Phase 3: Final Verdict
11. If all issues are resolved, approve the PR / close the Issue
12. If blocking issues remain, request changes / leave clear action items

@MervinPraison MervinPraison added pipeline/awaiting-merge-gate FINAL done; waiting for merge gate / CI pipeline/blocked:cooldown Blocked: post-push or @claude cooldown and removed pipeline/final-claude-pending Reviews done; waiting for FINAL @claude pipeline/blocked:no-final Blocked: no FINAL @claude trigger yet labels Aug 9, 2026
@praisonai-triage-agent

praisonai-triage-agent Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor Author

Claude finished @MervinPraison's task β€”β€” View job


Final Architecture Review β€” PR #3833 βœ… Approved

  • Read AGENTS.md guidelines
  • Review the _retry_backoff extraction in workflows.py
  • Verify behaviour preserved (both paths)
  • Run workflow tests β€” 92 passed
  • Final verdict

Phase 1 β€” Architecture Review (AGENTS.md)

Criterion Verdict
Protocol-driven βœ… Pure internal refactor in praisonaiagents/workflows/workflows.py. No heavy impl added, no new module/export.
Backward compatible βœ… Zero API surface change. Private _retry_backoff staticmethod only; behaviour byte-for-byte identical.
Performance βœ… No hot-path regression β€” one static call replacing an inline block; the dominant cost is the deliberate time.sleep(2**(retry_count-1)) which is unchanged.
SDK value βœ… Genuine value: removes the most-duplicated retry-delay/print block, single source of truth. No scope creep, no new knobs.
Agent bloat βœ… N/A β€” no changes to Agent, no new params.
Repo routing βœ… Correct β€” internal SDK refactor belongs in praisonaiagents/.

Phase 2 β€” Issue Fixes

Reviewed CodeRabbit, Greptile, and Qodo comments β€” no actionable issues were raised (CodeRabbit: "No actionable comments"; Greptile: 5/5 confidence, safe to merge).

Independent review β€” verified the two call sites and the helper:

  • workflows.py:1478 (top-level _run_impl loop) β†’ self._retry_backoff(...)
  • workflows.py:2442 (_apply_step_policies) β†’ self._retry_backoff(...)
  • workflows.py:2399 @staticmethod _retry_backoff β€” signature (step, retry_count, max_retries, error, verbose); backoff 2**(retry_count-1), identical verbose string, time.sleep(...).

Confirmed preserved on the top-level path: is_retryable early-break, on_step_error callback, guardrail_failed flag, validation_feedback propagation, and output_file writing β€” all untouched. Calling a @staticmethod via self. is valid Python and idiomatic here.

No fixes required. No files modified.

Phase 3 β€” Verdict

βœ… Approve. The change is minimal, lightweight, backward-compatible, and genuinely reduces duplication with zero behavioural change. Tests:

tests/test_workflow_patterns.py + tests/test_validation_feedback.py β€” 92 passed in 7.40s

Note: I cannot submit a formal GitHub approval (bot security restriction), but this is my approving architecture review. Safe to merge.

Branch claude/issue-3832-20260809-1715 Β· Job run

@praisonai-triage-agent praisonai-triage-agent Bot removed pipeline/blocked:ci Blocked: CI not green on HEAD pipeline/blocked:cooldown Blocked: post-push or @claude cooldown labels Aug 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pipeline/awaiting-merge-gate FINAL done; waiting for merge gate / CI pipeline/blocked:manual-review Blocked: requires manual review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Core SDK] Duplicate step retry/backoff/guardrail logic in workflows.py β€” top-level loop bypasses the shared _apply_step_policies helper

1 participant