@@ -1719,6 +1719,129 @@ describe("Bug 6: item_reference for assistant text turns counted in assistantCou
17191719 } ) ;
17201720} ) ;
17211721
1722+ // ─── Bug fix: reasoning_summary_text.done must include item_id ──────────────
1723+
1724+ describe ( "reasoning_summary_text.done includes item_id" , ( ) => {
1725+ it ( "reasoning_summary_text.done has item_id matching the reasoning item" , ( ) => {
1726+ const events = buildTextStreamEvents ( "result" , "gpt-4" , 100 , "thinking hard" ) ;
1727+ const textDone = events . find ( ( e ) => e . type === "response.reasoning_summary_text.done" ) ;
1728+ expect ( textDone ) . toBeDefined ( ) ;
1729+ expect ( textDone ! . item_id ) . toBeDefined ( ) ;
1730+ expect ( typeof textDone ! . item_id ) . toBe ( "string" ) ;
1731+
1732+ // Verify it matches the reasoning item id
1733+ const reasoningAdded = events . find (
1734+ ( e ) =>
1735+ e . type === "response.output_item.added" &&
1736+ ( e . item as { type : string } ) ?. type === "reasoning" ,
1737+ ) ;
1738+ const reasoningId = ( reasoningAdded ! . item as { id : string } ) . id ;
1739+ expect ( textDone ! . item_id ) . toBe ( reasoningId ) ;
1740+ } ) ;
1741+ } ) ;
1742+
1743+ // ─── Bug fix: multi-fco after single item_reference ─────────────────────────
1744+
1745+ describe ( "multi-fco after single item_reference" , ( ) => {
1746+ it ( "[user, item_reference, fco_A, fco_B] produces assistantCount=1 with 2 tool_calls" , ( ) => {
1747+ const messages = responsesInputToMessages ( {
1748+ model : "gpt-4" ,
1749+ input : [
1750+ { role : "user" , content : "hello" } ,
1751+ { type : "item_reference" , id : "ref_multi_fc" } ,
1752+ { type : "function_call_output" , call_id : "call_A" , output : '{"a":1}' } ,
1753+ { type : "function_call_output" , call_id : "call_B" , output : '{"b":2}' } ,
1754+ ] ,
1755+ } ) ;
1756+
1757+ const assistantMsgs = messages . filter ( ( m ) => m . role === "assistant" ) ;
1758+ expect ( assistantMsgs ) . toHaveLength ( 1 ) ;
1759+ expect ( assistantMsgs [ 0 ] . tool_calls ) . toHaveLength ( 2 ) ;
1760+ expect ( assistantMsgs [ 0 ] . tool_calls ! [ 0 ] . id ) . toBe ( "call_A" ) ;
1761+ expect ( assistantMsgs [ 0 ] . tool_calls ! [ 1 ] . id ) . toBe ( "call_B" ) ;
1762+
1763+ const toolMsgs = messages . filter ( ( m ) => m . role === "tool" ) ;
1764+ expect ( toolMsgs ) . toHaveLength ( 2 ) ;
1765+ } ) ;
1766+
1767+ it ( "[user, item_reference, fco_A, fco_B, user] produces assistantCount=1" , ( ) => {
1768+ const messages = responsesInputToMessages ( {
1769+ model : "gpt-4" ,
1770+ input : [
1771+ { role : "user" , content : "hello" } ,
1772+ { type : "item_reference" , id : "ref_multi_fc" } ,
1773+ { type : "function_call_output" , call_id : "call_A" , output : '{"a":1}' } ,
1774+ { type : "function_call_output" , call_id : "call_B" , output : '{"b":2}' } ,
1775+ { role : "user" , content : "next question" } ,
1776+ ] ,
1777+ } ) ;
1778+
1779+ const assistantCount = messages . filter ( ( m ) => m . role === "assistant" ) . length ;
1780+ expect ( assistantCount ) . toBe ( 1 ) ;
1781+ } ) ;
1782+ } ) ;
1783+
1784+ // ─── e2e: turnIndex + item_reference via Responses API ──────────────────────
1785+
1786+ describe ( "turnIndex + item_reference via Responses API (e2e)" , ( ) => {
1787+ it ( "selects turnIndex:1 fixture when input has item_reference + fco (assistantCount=1)" , async ( ) => {
1788+ const turn0Fixture : Fixture = {
1789+ match : { userMessage : "turn-index-test" , turnIndex : 0 } ,
1790+ response : { content : "turn zero response" } ,
1791+ } ;
1792+ const turn1Fixture : Fixture = {
1793+ match : { userMessage : "turn-index-test" , turnIndex : 1 } ,
1794+ response : { content : "turn one response" } ,
1795+ } ;
1796+ instance = await createServer ( [ turn0Fixture , turn1Fixture ] ) ;
1797+
1798+ // Input: [user, item_reference, function_call_output, user]
1799+ // This should produce assistantCount=1 → turnIndex 1 match
1800+ const res = await post ( `${ instance . url } /v1/responses` , {
1801+ model : "gpt-4" ,
1802+ input : [
1803+ { role : "user" , content : "first question" } ,
1804+ { type : "item_reference" , id : "ref_prev_assistant" } ,
1805+ { type : "function_call_output" , call_id : "call_prev" , output : '{"done":true}' } ,
1806+ { role : "user" , content : "turn-index-test" } ,
1807+ ] ,
1808+ stream : false ,
1809+ } ) ;
1810+
1811+ expect ( res . status ) . toBe ( 200 ) ;
1812+ const body = JSON . parse ( res . body ) ;
1813+ expect ( body . output [ 0 ] . content [ 0 ] . text ) . toBe ( "turn one response" ) ;
1814+ } ) ;
1815+
1816+ it ( "multi-fco [user, item_reference, fco_A, fco_B, user] produces assistantCount=1" , async ( ) => {
1817+ const turn0Fixture : Fixture = {
1818+ match : { userMessage : "multi-fco-turn-test" , turnIndex : 0 } ,
1819+ response : { content : "should not match" } ,
1820+ } ;
1821+ const turn1Fixture : Fixture = {
1822+ match : { userMessage : "multi-fco-turn-test" , turnIndex : 1 } ,
1823+ response : { content : "correct turn one" } ,
1824+ } ;
1825+ instance = await createServer ( [ turn0Fixture , turn1Fixture ] ) ;
1826+
1827+ const res = await post ( `${ instance . url } /v1/responses` , {
1828+ model : "gpt-4" ,
1829+ input : [
1830+ { role : "user" , content : "initial" } ,
1831+ { type : "item_reference" , id : "ref_2tool_assistant" } ,
1832+ { type : "function_call_output" , call_id : "call_X" , output : '{"x":1}' } ,
1833+ { type : "function_call_output" , call_id : "call_Y" , output : '{"y":2}' } ,
1834+ { role : "user" , content : "multi-fco-turn-test" } ,
1835+ ] ,
1836+ stream : false ,
1837+ } ) ;
1838+
1839+ expect ( res . status ) . toBe ( 200 ) ;
1840+ const body = JSON . parse ( res . body ) ;
1841+ expect ( body . output [ 0 ] . content [ 0 ] . text ) . toBe ( "correct turn one" ) ;
1842+ } ) ;
1843+ } ) ;
1844+
17221845// ─── Debug logging in handleResponses ───────────────────────────────────────
17231846
17241847describe ( "handleResponses debug logging" , ( ) => {
0 commit comments