DEV Community

Discussion on: Amnesia and déjà vu: how our AI agents failed after every restart (and how we fixed it)

Collapse
 
anis_meziani_52aab42304a8 profile image
Anis Meziani •

You’re right, and thank you for reading the code this closely. I checked: stream_adk_agent re-sends the same request on a 429, up to twice, with no check on whether a function call has already gone through the stream. So the list in the post is missing an entry, and that entry breaks the rule the post is built on: after send_email, the second attempt leaves the decision to the model. I’ll add an update to the post crediting you.

Some context on why that retry exists: it was added after forwarding the 429 led the model to claim it had written a row when no tool had actually run. Your fix keeps that case intact (no function call seen yet, so retrying is safe, exactly like the empty-turn check) and only changes the case that matters: once a call has passed, forward the 429 and let a human decide.

You’ve essentially written the patch already. Would you like to open the PR? Note the function call as it passes through the stream, forward the 429 once one has been seen, plus a test that streams a functionCall then a 429 and asserts there’s no retry. I’ll review it quickly, happy to pair on it, and you’d be credited by name in the repo and in the post. If you’d rather not, no problem at all: I’ll open the issue and credit you for the find.

Repo: github.com/apowerb/apowerb

thanks for the exchange

Collapse
 
izgorodin profile image
Edward Izgorodin •

An issue fits this better than a pull request, and one thing is worth putting in it. Forwarding the 429 hands the decision to a person only if the person can tell that a tool already ran. The paths that forward a 429 today point the other way: the test for a provider delay above the cap describes it as surfacing the original error and letting the user retry manually, and the message after the retries run out says to try again in a minute. A person who resends the request after send_email went through rebuilds by hand the history the automatic retry would have produced, with the request twice and the email already sent.

So the forwarded error could name the calls that completed in that turn, send_email here, the way the replay refusal lists what a run already did, and the new test could assert that the name is in it as well as that nothing was retried. A second test with the 429 before any function call, still retried, keeps the 7 May case from coming back if someone later simplifies the rule to forward every 429.