@@ -54,7 +54,7 @@ describe("buildGeminiRequest", () => {
5454 role : "model" ,
5555 parts : [
5656 { text : "thinking out loud" } ,
57- { functionCall : { name : "read" , args : { path : "a.ts" } } } ,
57+ { functionCall : { name : "read" , args : { path : "a.ts" } , id : "c1" } } ,
5858 ] ,
5959 } ,
6060 ] )
@@ -93,7 +93,7 @@ describe("buildGeminiRequest", () => {
9393 } ) ,
9494 )
9595 expect ( request . contents [ 0 ] ?. parts [ 0 ] ) . toEqual ( {
96- functionCall : { name : "read" , args : { path : "a.ts" } } ,
96+ functionCall : { name : "read" , args : { path : "a.ts" } , id : "c1" } ,
9797 thoughtSignature : "SIG123" ,
9898 } )
9999 } )
@@ -125,8 +125,70 @@ describe("buildGeminiRequest", () => {
125125 {
126126 role : "user" ,
127127 parts : [
128- { functionResponse : { name : "read" , response : { output : "file A" } } } ,
129- { functionResponse : { name : "grep" , response : { output : "match" } } } ,
128+ { functionResponse : { name : "read" , response : { output : "file A" } , id : "c1" } } ,
129+ { functionResponse : { name : "grep" , response : { output : "match" } , id : "c2" } } ,
130+ ] ,
131+ } ,
132+ ] )
133+ } )
134+
135+ it ( "preserves matching IDs across parallel tool calls and results" , ( ) => {
136+ const request = buildGeminiRequest (
137+ ctx ( {
138+ messages : [
139+ {
140+ role : "assistant" ,
141+ content : [
142+ { type : "toolCall" , id : "c1" , name : "read" , arguments : { path : "a.ts" } } ,
143+ { type : "toolCall" , id : "c2" , name : "grep" , arguments : { pattern : "TODO" } } ,
144+ ] ,
145+ api : "google-generative-ai" ,
146+ provider : "google-antigravity" ,
147+ model : "antigravity-claude-opus-4-6-thinking" ,
148+ usage : {
149+ input : 0 ,
150+ output : 0 ,
151+ cacheRead : 0 ,
152+ cacheWrite : 0 ,
153+ totalTokens : 0 ,
154+ cost : { input : 0 , output : 0 , cacheRead : 0 , cacheWrite : 0 , total : 0 } ,
155+ } ,
156+ stopReason : "toolUse" ,
157+ timestamp : 0 ,
158+ } ,
159+ {
160+ role : "toolResult" ,
161+ toolCallId : "c1" ,
162+ toolName : "read" ,
163+ content : [ { type : "text" , text : "file A" } ] ,
164+ isError : false ,
165+ timestamp : 1 ,
166+ } ,
167+ {
168+ role : "toolResult" ,
169+ toolCallId : "c2" ,
170+ toolName : "grep" ,
171+ content : [ { type : "text" , text : "match" } ] ,
172+ isError : false ,
173+ timestamp : 1 ,
174+ } ,
175+ ] ,
176+ } ) ,
177+ )
178+
179+ expect ( request . contents ) . toEqual ( [
180+ {
181+ role : "model" ,
182+ parts : [
183+ { functionCall : { name : "read" , args : { path : "a.ts" } , id : "c1" } } ,
184+ { functionCall : { name : "grep" , args : { pattern : "TODO" } , id : "c2" } } ,
185+ ] ,
186+ } ,
187+ {
188+ role : "user" ,
189+ parts : [
190+ { functionResponse : { name : "read" , response : { output : "file A" } , id : "c1" } } ,
191+ { functionResponse : { name : "grep" , response : { output : "match" } , id : "c2" } } ,
130192 ] ,
131193 } ,
132194 ] )
@@ -148,7 +210,7 @@ describe("buildGeminiRequest", () => {
148210 } ) ,
149211 )
150212 expect ( request . contents [ 0 ] ?. parts [ 0 ] ) . toEqual ( {
151- functionResponse : { name : "bash" , response : { error : "boom" } } ,
213+ functionResponse : { name : "bash" , response : { error : "boom" } , id : "c1" } ,
152214 } )
153215 } )
154216
0 commit comments