fix(workflow): dedupe progress rows, close leaked coroutines, cap runaway loops#191
Conversation
…away loops - render_progress() re-listed agents truncated by the per-phase max_agents cap as duplicate "unphased" rows; now filters by phase membership instead of a rendered-id set. - parallel() left already-created agent() coroutines unclosed when its argument validation raised, leaking "never awaited" warnings. - The Python port dropped the reference implementation's 1000-agent lifetime backstop, so a workflow script with an unbounded loop and no token_budget could spawn subagents forever; restored the cap.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughThis PR fixes duplicate agent rows in workflow progress rendering by switching truncation logic from ID-based tracking to phase-order membership, closes leaked coroutines when ChangesWorkflow progress and engine fixes
Estimated code review effort: 2 (Simple) | ~12 minutes Sequence Diagram(s)sequenceDiagram
participant Caller
participant Parallel
participant CloseCoroutines
Caller->>Parallel: parallel(items)
Parallel->>Parallel: validate items
alt invalid argument or item
Parallel->>CloseCoroutines: _close_coroutines(items)
Parallel-->>Caller: raise WorkflowRuntimeError
else valid
Parallel-->>Caller: proceed with execution
end
Suggested labels: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Summary
Three bugs found in a post-merge review of #186 (Workflow tool):
render_progress()re-listed agents that had been truncated by the per-phasemax_agentscap as duplicate "unphased" rows at the bottom of the progressblock — a phase with 8 agents and
max_agents=6showed the two oldestagents twice. Fixed by filtering the trailing "unphased" section on phase
membership instead of a rendered-id set.
parallel()raised on invalid arguments (non-list, or a bare function mixedinto the list) without closing the
agent()coroutines already created forthe other list items, leaking "coroutine was never awaited" warnings.
lifetime backstop. A workflow script with an unbounded loop (e.g.
while True: await agent(...)) and notoken_budgetset could spawnsubagents indefinitely. Restored the cap as
MAX_TOTAL_AGENTS = 1000,checked inside the concurrency semaphore alongside the existing budget
check.
No behavior changes outside these three fixes; no new dependencies.
Test plan
rendering, lifetime-cap enforcement, and coroutine-leak-on-validation-
failure (via
warnings.catch_warnings)make check-pythinker-code(ruff + format + pyright + ty) — cleanmake test-pythinker-code— 6505 passed, 7 skipped, 1 xfailed (unit);65 passed, 4 skipped (e2e)
CHANGELOG.mdupdated under## UnreleasedSummary by CodeRabbit