Repository navigation
Commit 5ffe5ca
Python: Keep every queued approval result in the AG-UI thread snapshot (#8851)
* Python: Keep every queued approval result in the AG-UI thread snapshot
With ToolApprovalMiddleware, decisions collected across separate resumes are
released as one batch. Both calls ran and streamed TOOL_CALL_RESULT, but the
snapshot kept only the result whose approval arrived in the final request, so
the next turn replayed both calls with one result.
Native approval results are dropped from the flow on the assumption that the
snapshot merge restores them from the request's messages. A decision collected
in an earlier request has no approval response there, so its result was lost.
Carry those results into the merge so each is persisted next to its call.
Fixes #8789
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Python: Keep every result for a reused call id in the AG-UI snapshot merge
Distinct function-call occurrences can share one provider call id, for
example hidden siblings released with a guarded call. The snapshot merge
keyed resolved results by call id, so only the last one survived and the
emitted and persisted snapshots dropped the rest.
_resolved_tool_result_snapshot_messages now groups results by call id in
resolution order, and the merge places every result for a call id after
the assistant message that declares it. Results carried from earlier
requests are matched by result object instead of call id, so a reused id
cannot hide a result that was never folded into this request's messages.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Python: Keep one replayed tool result per reused call id occurrence
The provider history sanitizer collapsed function calls that share a
call id into a single pending id, so the first result consumed it and
the results of later occurrences were dropped from replay.
_deduplicate_messages did the same by keying tool results on call id
alone.
The sanitizer now tracks one pending entry per function call and clears
one per result, while still injecting a single synthetic result per
missing call id. Deduplication keeps as many results for a call id as
the kept assistant messages declare occurrences of it, and still drops
or fills in replays beyond that.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Python: Pair reused call id results with their own turn in AG-UI history
A later turn that reuses a call id already completed earlier lost its
pairing in two places:
- _deduplicate_messages keyed assistant tool-call messages by call ids
only, so the later turn's call was dropped as a duplicate and its
result went with it. Assistant messages with a message_id are now
deduplicated by id like other messages, and each declared occurrence
opens one result slot, so a replayed result is still dropped.
- _merge_resolved_approval_results_into_snapshot bucketed results by
call id across the whole snapshot and drained the bucket at the first
declaring assistant message, attaching the new result to the earlier
call and keeping the old one twice. Results are now keyed by call id
and declaration occurrence and placed after the matching assistant
message.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Python: Skip abandoned AG-UI calls that reuse an earlier turn's call id
_sanitize_tool_history treated a call id as answered when a result for it
appeared anywhere in history, so a later turn reusing a completed call id
and then abandoning it got no synthetic skipped result and replayed as an
unpaired call. Only results from the flush point on, before the call id is
declared again, now count as answering the pending occurrence.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Python: Narrow tool_calls type in reused-call-id endpoint test
Fixes the reportOptionalIterable error from the test typing checks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Python: Don't let settled approvals protect a later reused AG-UI call id
_approval_state_tool_call_ids returned the call ids of every approval
occurrence the lifecycle still holds, including terminal ones that are
only retained for replay. A later turn that reuses such a call id and is
then abandoned was treated as server-owned, so _sanitize_tool_history
never added a skipped result and the next request replayed an unpaired
call. Only non-terminal occurrences (and queued approval state) now
protect their call ids.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>1 parent c9b237c commit 5ffe5ca
5 files changed
Lines changed: 642 additions & 82 deletions
File tree
- python/packages/ag-ui
- agent_framework_ag_ui
- tests/ag_ui
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1109 | 1109 | | |
1110 | 1110 | | |
1111 | 1111 | | |
| 1112 | + | |
| 1113 | + | |
| 1114 | + | |
| 1115 | + | |
1112 | 1116 | | |
1113 | 1117 | | |
1114 | 1118 | | |
| |||
2238 | 2242 | | |
2239 | 2243 | | |
2240 | 2244 | | |
2241 | | - | |
2242 | | - | |
2243 | | - | |
| 2245 | + | |
| 2246 | + | |
| 2247 | + | |
| 2248 | + | |
| 2249 | + | |
| 2250 | + | |
| 2251 | + | |
| 2252 | + | |
| 2253 | + | |
| 2254 | + | |
| 2255 | + | |
| 2256 | + | |
2244 | 2257 | | |
2245 | | - | |
| 2258 | + | |
| 2259 | + | |
| 2260 | + | |
| 2261 | + | |
| 2262 | + | |
| 2263 | + | |
| 2264 | + | |
| 2265 | + | |
| 2266 | + | |
| 2267 | + | |
2246 | 2268 | | |
2247 | 2269 | | |
2248 | 2270 | | |
| |||
2265 | 2287 | | |
2266 | 2288 | | |
2267 | 2289 | | |
2268 | | - | |
2269 | | - | |
| 2290 | + | |
| 2291 | + | |
| 2292 | + | |
| 2293 | + | |
| 2294 | + | |
| 2295 | + | |
| 2296 | + | |
| 2297 | + | |
| 2298 | + | |
| 2299 | + | |
| 2300 | + | |
| 2301 | + | |
| 2302 | + | |
| 2303 | + | |
| 2304 | + | |
| 2305 | + | |
| 2306 | + | |
| 2307 | + | |
| 2308 | + | |
| 2309 | + | |
2270 | 2310 | | |
2271 | 2311 | | |
2272 | 2312 | | |
2273 | 2313 | | |
2274 | 2314 | | |
2275 | 2315 | | |
2276 | | - | |
2277 | | - | |
2278 | | - | |
| 2316 | + | |
| 2317 | + | |
| 2318 | + | |
| 2319 | + | |
| 2320 | + | |
| 2321 | + | |
| 2322 | + | |
| 2323 | + | |
| 2324 | + | |
2279 | 2325 | | |
2280 | 2326 | | |
2281 | 2327 | | |
| 2328 | + | |
| 2329 | + | |
| 2330 | + | |
2282 | 2331 | | |
2283 | | - | |
2284 | | - | |
2285 | | - | |
2286 | | - | |
| 2332 | + | |
| 2333 | + | |
2287 | 2334 | | |
2288 | | - | |
2289 | | - | |
2290 | | - | |
| 2335 | + | |
| 2336 | + | |
| 2337 | + | |
| 2338 | + | |
| 2339 | + | |
2291 | 2340 | | |
| 2341 | + | |
2292 | 2342 | | |
2293 | 2343 | | |
2294 | 2344 | | |
2295 | 2345 | | |
2296 | | - | |
2297 | | - | |
2298 | | - | |
2299 | | - | |
2300 | | - | |
| 2346 | + | |
| 2347 | + | |
| 2348 | + | |
| 2349 | + | |
2301 | 2350 | | |
2302 | | - | |
| 2351 | + | |
2303 | 2352 | | |
2304 | | - | |
2305 | | - | |
2306 | | - | |
2307 | | - | |
| 2353 | + | |
| 2354 | + | |
| 2355 | + | |
2308 | 2356 | | |
2309 | | - | |
| 2357 | + | |
| 2358 | + | |
2310 | 2359 | | |
2311 | 2360 | | |
2312 | 2361 | | |
| |||
3686 | 3735 | | |
3687 | 3736 | | |
3688 | 3737 | | |
| 3738 | + | |
3689 | 3739 | | |
3690 | 3740 | | |
3691 | 3741 | | |
| |||
3780 | 3830 | | |
3781 | 3831 | | |
3782 | 3832 | | |
| 3833 | + | |
3783 | 3834 | | |
3784 | 3835 | | |
3785 | 3836 | | |
| |||
4047 | 4098 | | |
4048 | 4099 | | |
4049 | 4100 | | |
4050 | | - | |
| 4101 | + | |
| 4102 | + | |
| 4103 | + | |
| 4104 | + | |
| 4105 | + | |
| 4106 | + | |
| 4107 | + | |
| 4108 | + | |
| 4109 | + | |
| 4110 | + | |
| 4111 | + | |
| 4112 | + | |
| 4113 | + | |
| 4114 | + | |
| 4115 | + | |
| 4116 | + | |
| 4117 | + | |
4051 | 4118 | | |
4052 | 4119 | | |
4053 | 4120 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
| |||
58 | 59 | | |
59 | 60 | | |
60 | 61 | | |
61 | | - | |
| 62 | + | |
| 63 | + | |
62 | 64 | | |
63 | 65 | | |
64 | 66 | | |
| |||
76 | 78 | | |
77 | 79 | | |
78 | 80 | | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | | - | |
88 | | - | |
89 | | - | |
90 | | - | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
91 | 85 | | |
| 86 | + | |
| 87 | + | |
92 | 88 | | |
93 | | - | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
94 | 92 | | |
95 | | - | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
96 | 96 | | |
97 | | - | |
98 | | - | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
99 | 104 | | |
100 | 105 | | |
101 | 106 | | |
| |||
108 | 113 | | |
109 | 114 | | |
110 | 115 | | |
111 | | - | |
| 116 | + | |
112 | 117 | | |
113 | | - | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
114 | 123 | | |
115 | 124 | | |
116 | 125 | | |
| |||
123 | 132 | | |
124 | 133 | | |
125 | 134 | | |
126 | | - | |
| 135 | + | |
127 | 136 | | |
128 | 137 | | |
129 | 138 | | |
130 | 139 | | |
131 | | - | |
| 140 | + | |
132 | 141 | | |
133 | 142 | | |
134 | 143 | | |
| |||
250 | 259 | | |
251 | 260 | | |
252 | 261 | | |
253 | | - | |
| 262 | + | |
254 | 263 | | |
255 | 264 | | |
256 | 265 | | |
| |||
268 | 277 | | |
269 | 278 | | |
270 | 279 | | |
271 | | - | |
| 280 | + | |
272 | 281 | | |
273 | | - | |
274 | | - | |
275 | | - | |
276 | | - | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
277 | 285 | | |
278 | 286 | | |
279 | 287 | | |
| |||
291 | 299 | | |
292 | 300 | | |
293 | 301 | | |
294 | | - | |
| 302 | + | |
295 | 303 | | |
296 | 304 | | |
297 | 305 | | |
| |||
307 | 315 | | |
308 | 316 | | |
309 | 317 | | |
310 | | - | |
| 318 | + | |
311 | 319 | | |
312 | 320 | | |
313 | 321 | | |
| |||
317 | 325 | | |
318 | 326 | | |
319 | 327 | | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
320 | 334 | | |
321 | 335 | | |
322 | 336 | | |
323 | 337 | | |
324 | 338 | | |
325 | 339 | | |
326 | | - | |
327 | | - | |
328 | | - | |
329 | | - | |
330 | | - | |
| 340 | + | |
331 | 341 | | |
332 | | - | |
333 | | - | |
334 | | - | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
335 | 345 | | |
336 | | - | |
337 | | - | |
338 | | - | |
339 | | - | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
340 | 356 | | |
341 | 357 | | |
342 | 358 | | |
343 | 359 | | |
344 | | - | |
| 360 | + | |
345 | 361 | | |
346 | 362 | | |
347 | 363 | | |
348 | 364 | | |
349 | 365 | | |
350 | 366 | | |
351 | | - | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
352 | 370 | | |
353 | 371 | | |
354 | 372 | | |
355 | 373 | | |
356 | 374 | | |
357 | 375 | | |
358 | 376 | | |
| 377 | + | |
| 378 | + | |
359 | 379 | | |
360 | 380 | | |
361 | 381 | | |
| |||
0 commit comments