fix(loop): Responses degenerate retry — honor custom_tool_call, keep every attempt's usage
#1862: two defects at the same degenerate-retry boundary on the Responses wire. A (eligibility): adapter-responses forwarded custom_tool_call lifecycle frames as inert meta without counting the call, so a completed reasoning+custom-tool turn (no text delta) satisfied the degenerate gate (calls.length === 0) and the request was re-issued even though executable output had already reached the client. Count the completed custom_tool_call like function_call (toolCallsEmitted++ plus a passthrough tool_call) so it suppresses the false retry; passthrough keeps the wire bytes verbatim and prevents a duplicate re-emission. B (accounting): recordUsage runs once per outer round, after the inner retry loop's usage reset, so a successful retry silently dropped the replaced attempt's measured usage. Settle each attempt's usage the moment a retry replaces it (success path only); a failed retry never reaches the settle, so the surviving attempt is recorded once — no double count. The client-facing completion still carries only the final attempt's usage (emitCompletion reads `usage`, which this never mutates). Adds regression guards A1/B1/B2 to loop-degenerate-retry.test.ts; A1 and B1 fail on the pre-fix code, B2 pins the failure path against over-counting/fabrication.
E
ework-agent committed
8120b14db7d595052e1f2185bc11231a031e99d2
Parent: 815027f