A ReAct loop needs more than one way to stop. The model finishing on its own is the happy path, but nothing guarantees it ever will — a confused model can loop forever, chasing the same dead end. Two independent safety nets exist for exactly this: a hard cap on the number of steps, and a hard cap on wall-clock time, since a handful of very slow tool calls could blow the time budget long before the step count does. A real loop has to check all three conditions, every step, in a well-defined order.
You're given the full log of steps a run actually took: (elapsed_seconds_after_this_step, action), in order, where elapsed_seconds is cumulative from the run's start. Implement find_loop_stop(steps, max_steps, max_seconds). Walk the steps in order (1-indexed), and at each step check, in this priority order, the first condition that applies:
action == "finish" -> (step_number, "FINISHED")step_number >= max_steps -> (step_number, "STEP_BUDGET")elapsed_seconds >= max_seconds -> (step_number, "TIME_BUDGET")Return (stop_step, reason) for whichever condition trips first.
max_steps >= 1, max_seconds > 0.Check the three conditions in the exact order given, as three separate if statements each returning immediately — not as a single combined boolean expression. When more than one condition is true at the same step, the priority order (not evaluation order of an or chain) is what decides which reason gets reported.
"finish" always wins, even on a step that would also have tripped the step or time budget. Check it first, unconditionally, before touching either budget.
No results yet
Run your code to check it against the examples, or submit to run every test.