Skip to content

fix: bound while-loop iterations without ToolCall by the step limit#142

Open
Mingye-Lu wants to merge 2 commits into
mainfrom
fix/while-loop-step-limit
Open

fix: bound while-loop iterations without ToolCall by the step limit#142
Mingye-Lu wants to merge 2 commits into
mainfrom
fix/while-loop-step-limit

Conversation

@Mingye-Lu

Copy link
Copy Markdown
Owner

Summary

  • execute_while_loop only called check_limits() per iteration; step_counter was only ever incremented in execute_node's ToolCall arm. A loop body containing only Assign/Expression re-evaluation (no ToolCall) never advanced step_counter, so such a loop was bounded only by the wall-clock timeout (max_timeout_secs), not max_steps — it could spin unthrottled, burning CPU, until the much larger wall-clock deadline caught it.
  • Fixed by incrementing step_counter on every while iteration regardless of whether a tool call occurred, so max_steps bounds it as intended.

Test plan

  • cargo fmt --package agent
  • cargo test -p agent (629 passed, including new regression test while_loop_without_tool_calls_is_bounded_by_step_limit, which uses a tool-call-free body and a short max_timeout_secs so the test fails fast rather than hanging if this regresses)
  • cargo clippy -p agent --all-targets -- -D warnings (clean)

execute_while_loop only called check_limits() per iteration, and
step_counter was only ever incremented in execute_node's ToolCall arm.
A loop body containing only Assign/Expression re-evaluation (no
ToolCall) never advanced step_counter, so such a loop was bounded only
by the wall-clock timeout (up to max_timeout_secs), not max_steps --
it could spin unthrottled, burning CPU, until the much larger
wall-clock deadline caught it. Increment step_counter on every while
iteration regardless of whether a tool call occurred.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@Mingye-Lu

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a3a2da851c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// that only does Assign/Expression re-evaluation never
// advances step_counter, and this loop is bounded only by
// the wall-clock timeout in check_limits(), not max_steps.
self.step_counter.fetch_add(1, Ordering::Relaxed);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Don't double-charge while-loop tool iterations

When a while body contains a ToolCall, this increment is followed by execute_node incrementing step_counter again in the ToolCall arm, so these loops now consume two steps per browser action. A script that pages through results with one click/read_content per while iteration and limits.max_steps: 50 will abort after roughly 25 tool calls, unlike the same work in a for/for_each loop or straight-line script where each tool call consumes one step; consider only applying the synthetic iteration charge when the body did not otherwise advance the counter, or centralizing counting consistently per executed node.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Fixed in 23a90e5 — the synthetic iteration charge is now conditional: only applied when the while-loop body did not already advance step_counter (i.e., no ToolCall ran). While loops with ToolCall bodies now consume one step per iteration, matching for/for_each and straight-line behavior.

… bodies

Before this fix, execute_while_loop unconditionally incremented step_counter
on every iteration, and execute_node's ToolCall arm also incremented it. This
meant each iteration with a browser action consumed 2 steps. Now the synthetic
iteration charge is only applied when the body did NOT already advance the
counter (i.e., no ToolCall ran), so while loops with ToolCall bodies consume
one step per iteration like for/for_each loops and straight-line scripts.

PR #142 — resolves review comment 3566182334
@Mingye-Lu

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

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.

2 participants