@@ -171,6 +171,78 @@ describe("NanoGptHandler", () => {
171171 expect ( mockCreate . mock . calls [ 0 ] [ 0 ] ) . not . toHaveProperty ( "max_completion_tokens" )
172172 } )
173173
174+ it ( "keeps Muse Spark tool-result history contiguous across turns" , async ( ) => {
175+ const modelId = "meta/muse-spark-1.2-contributor"
176+ vi . mocked ( getModels ) . mockResolvedValue ( {
177+ [ modelId ] : {
178+ maxTokens : 65_536 ,
179+ contextWindow : 1_000_000 ,
180+ supportsPromptCache : false ,
181+ } ,
182+ } )
183+ const tools : OpenAI . Chat . ChatCompletionTool [ ] = [
184+ { type : "function" , function : { name : "read_file" , parameters : { type : "object" } } } ,
185+ ]
186+ const toolHistory : Anthropic . Messages . MessageParam [ ] = [
187+ {
188+ role : "assistant" ,
189+ content : [ { type : "tool_use" , id : "call_1" , name : "read_file" , input : { path : "first.txt" } } ] ,
190+ } ,
191+ {
192+ role : "user" ,
193+ content : [
194+ { type : "tool_result" , tool_use_id : "call_1" , content : "first result" } ,
195+ { type : "text" , text : "<environment_details>first context</environment_details>" } ,
196+ ] ,
197+ } ,
198+ {
199+ role : "assistant" ,
200+ content : [ { type : "tool_use" , id : "call_2" , name : "read_file" , input : { path : "second.txt" } } ] ,
201+ } ,
202+ {
203+ role : "user" ,
204+ content : [
205+ { type : "tool_result" , tool_use_id : "call_2" , content : "second result" } ,
206+ { type : "text" , text : "<environment_details>second context</environment_details>" } ,
207+ ] ,
208+ } ,
209+ ]
210+
211+ await collectStream (
212+ new NanoGptHandler ( { nanoGptModelId : modelId } ) . createMessage ( "sys" , toolHistory , {
213+ taskId : "task" ,
214+ tools,
215+ tool_choice : "auto" ,
216+ parallelToolCalls : true ,
217+ } ) ,
218+ )
219+
220+ expect ( mockCreate ) . toHaveBeenCalledWith (
221+ expect . objectContaining ( {
222+ model : modelId ,
223+ messages : [
224+ { role : "system" , content : "sys" } ,
225+ expect . objectContaining ( { role : "assistant" , tool_calls : [ expect . anything ( ) ] } ) ,
226+ {
227+ role : "tool" ,
228+ tool_call_id : "call_1" ,
229+ content : "first result\n\n<environment_details>first context</environment_details>" ,
230+ } ,
231+ expect . objectContaining ( { role : "assistant" , tool_calls : [ expect . anything ( ) ] } ) ,
232+ {
233+ role : "tool" ,
234+ tool_call_id : "call_2" ,
235+ content : "second result\n\n<environment_details>second context</environment_details>" ,
236+ } ,
237+ ] ,
238+ tools : [ expect . objectContaining ( { function : expect . objectContaining ( { name : "read_file" } ) } ) ] ,
239+ tool_choice : "auto" ,
240+ parallel_tool_calls : true ,
241+ } ) ,
242+ expect . anything ( ) ,
243+ )
244+ } )
245+
174246 it ( "omits temperature when it was not explicitly configured" , async ( ) => {
175247 await collectStream ( new NanoGptHandler ( { nanoGptModelId : "model:thinking" } ) . createMessage ( "sys" , messages ) )
176248 expect ( mockCreate . mock . calls [ 0 ] [ 0 ] ) . not . toHaveProperty ( "temperature" )
0 commit comments