@@ -1603,6 +1603,30 @@ func TestNormalizeResponsesWebsocketRequestDropsDuplicateFunctionCallsByCallID(t
16031603 }
16041604}
16051605
1606+ func TestNormalizeResponsesWebsocketRequestDropsDuplicateInputItemsByID (t * testing.T ) {
1607+ lastRequest := []byte (`{"model":"test-model","stream":true,"input":[{"type":"message","id":"msg-1","role":"user"}]}` )
1608+ lastResponseOutput := []byte (`[
1609+ {"type":"function_call","id":"fc-1","call_id":"call-1","name":"tool"}
1610+ ]` )
1611+ raw := []byte (`{"type":"response.create","previous_response_id":"resp-1","input":[{"type":"function_call","id":"fc-1","call_id":"call-2","name":"tool"},{"type":"function_call_output","id":"tool-out-1","call_id":"call-2"}]}` )
1612+
1613+ normalized , _ , errMsg := normalizeResponsesWebsocketRequestWithMode (raw , lastRequest , lastResponseOutput , false , true )
1614+ if errMsg != nil {
1615+ t .Fatalf ("unexpected error: %v" , errMsg .Error )
1616+ }
1617+
1618+ items := gjson .GetBytes (normalized , "input" ).Array ()
1619+ if len (items ) != 3 {
1620+ t .Fatalf ("merged input len = %d, want 3: %s" , len (items ), normalized )
1621+ }
1622+ if items [0 ].Get ("id" ).String () != "msg-1" ||
1623+ items [1 ].Get ("id" ).String () != "fc-1" ||
1624+ items [1 ].Get ("call_id" ).String () != "call-2" ||
1625+ items [2 ].Get ("id" ).String () != "tool-out-1" {
1626+ t .Fatalf ("unexpected merged input order: %s" , normalized )
1627+ }
1628+ }
1629+
16061630func TestNormalizeResponsesWebsocketRequestTreatsCustomToolTranscriptReplacementAsReset (t * testing.T ) {
16071631 lastRequest := []byte (`{"model":"test-model","stream":true,"input":[{"type":"message","id":"msg-1"},{"type":"custom_tool_call","id":"ctc-1","call_id":"call-1","name":"apply_patch"},{"type":"custom_tool_call_output","id":"tool-out-1","call_id":"call-1"},{"type":"message","id":"assistant-1","role":"assistant"}]}` )
16081632 lastResponseOutput := []byte (`[
@@ -1654,6 +1678,22 @@ func TestNormalizeResponsesWebsocketRequestDropsDuplicateCustomToolCallsByCallID
16541678 }
16551679}
16561680
1681+ func TestDedupeResponsesWebsocketInputItemsByIDAfterRepair (t * testing.T ) {
1682+ payload := []byte (`{"input":[{"type":"custom_tool_call","id":"ctc-1","call_id":"call-1","name":"tool"},{"type":"custom_tool_call","id":"ctc-1","call_id":"call-2","name":"tool"},{"type":"custom_tool_call_output","id":"tool-out-1","call_id":"call-2"}]}` )
1683+
1684+ deduped := dedupeResponsesWebsocketInputItemsByID (payload )
1685+
1686+ items := gjson .GetBytes (deduped , "input" ).Array ()
1687+ if len (items ) != 2 {
1688+ t .Fatalf ("deduped input len = %d, want 2: %s" , len (items ), deduped )
1689+ }
1690+ if items [0 ].Get ("id" ).String () != "ctc-1" ||
1691+ items [0 ].Get ("call_id" ).String () != "call-2" ||
1692+ items [1 ].Get ("id" ).String () != "tool-out-1" {
1693+ t .Fatalf ("unexpected deduped input: %s" , deduped )
1694+ }
1695+ }
1696+
16571697func TestResponsesWebsocketCompactionResetsTurnStateOnCustomToolTranscriptReplacement (t * testing.T ) {
16581698 gin .SetMode (gin .TestMode )
16591699
0 commit comments