fix: surface retry/backoff status in the CLI#3325
Conversation
|
@coderabbitai review |
|
/review |
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
✅ Action performedReview finished.
|
|
Warning Review limit reached
Next review available in: 50 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
Greptile SummaryThis follow-up refactors retry stream-event construction and emission while expanding coverage for asynchronous callbacks and non-JSON output.
Confidence Score: 4/5The PR is not yet safe to merge because retry status events remain one attempt behind the model call they announce. Both retry loops still emit src/praisonai-agents/praisonaiagents/agent/chat_mixin.py Important Files Changed
Reviews (3): Last reviewed commit: "fix: dispatch async retry stream events ..." | Re-trigger Greptile |
|
@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
Phase 2: FIX Valid Issues Phase 3: Final Verdict |
|
Claude finished @MervinPraison's task —— View job Final Architecture Review — PR #3325 — ✅ Approved
Phase 1 — Architecture (per AGENTS.md)
Phase 2 — Reviewer feedback triage
Files modified (this review)
Tests
VerdictLightweight, protocol-driven, backward-compatible, no hot-path regression. Valid P2 bug fixed; P1 correctly assessed as a non-issue. Approving. Job run · branch |
|
@claude this PR has merge conflicts with |
|
Claude finished @MervinPraison's task —— View job Rebased PR #3325 onto latest
|
| File | Resolution |
|---|---|
praisonaiagents/streaming/events.py |
Kept single StreamEventType.RETRY = "retry" (both sides added the same member). |
praisonaiagents/agent/chat_mixin.py |
Adopted the helper-based approach from the P2 fix commit: both sync and async retry loops now call _emit_retry_stream_event / _aemit_retry_stream_event (shared _build_retry_stream_event). The async path uses emit_async so async-only add_async_callback() consumers receive RETRY events — the correct fix, not inline dup. Backoff/retry-after logic unchanged. |
praisonai-code/.../cli/output/event_bridge.py |
Kept canonical run.retry mapping (attempt/max_attempts/delay/reason), consistent with main's schema_version-stamped emit. |
tests/unit/test_streaming_events.py |
Kept the fuller suite: metadata test + sync helper no-op/emit tests + 2 async tests (async-only callback delivery, async no-op). |
praisonai/tests/unit/cli/test_run_event_bridge.py |
Kept run.retry mapping test plus schema_version assertion and the new test_retry_event_silent_in_text_mode. |
Skipped / not changed: Greptile P1 "attempt offset" — intentionally left as-is (attempt k+1/N matches the existing OnRetry hook retry_count and the Retry k/N log line; "Retry 1/N" is the established convention). No new Agent params, modules, or exports — scope stayed lightweight.
Tests (rebased HEAD)
test_streaming_events.py— 29 passedtest_run_event_bridge.py— 11 passed
Force-pushed 8b14d3b54…1aff8c7d6 → branch is now conflict-free against main.
Job run · branch claude/issue-3311-20260723-1026
Add StreamEventType.RETRY emitted alongside the existing ON_RETRY hook (guarded by has_callbacks for zero-overhead) in both sync and async retry loops, carrying attempt/max_attempts/delay/reason in metadata. Map it to a canonical run.retry NDJSON event in the CLI stream-json bridge so consumers get a live 'retrying in Ns (attempt k/N)' signal. Non-JSON/silent modes stay silent. Co-authored-by: Mervin Praison <MervinPraison@users.noreply.github.com>
|
Merge gate scan — eligible for assessment. Claude merge gate will assess and may auto-merge if |
|
Merged by Claude PR merge gate ( |
|
Merge gate scan — not eligible for auto-merge.
Actions: wait for CI and the Claude review chain, or add label |
Fixes #3311
Summary
When a model call hits a rate limit or transient error, the runtime backs off and retries (honouring retry-after), but the wait was silent — a multi-second backoff was indistinguishable from a frozen CLI. This surfaces the retry signal as a first-class streaming event and maps it into the CLI NDJSON stream so a live 'retrying in Ns (attempt k/N)' status is available.
Changes (minimal, lightweight)
Architecture / scope review
No new Agent params, modules, or exports. Reuses the existing stream_emitter, StreamEvent.metadata, and the existing bridge dispatch. Keeps the package lightweight.
Tests
Generated with Claude Code