@@ -213,17 +213,15 @@ public class ToolCallIntegrationTests: XCTestCase {
213213
214214 // MARK: - Mistral3 Tests
215215
216- func testMistral3ToolCallFormatDefaultsToJSON ( ) async throws {
216+ func testMistral3ToolCallFormatAutoDetection ( ) async throws {
217217 guard let container = Self . mistral3Container else {
218218 throw XCTSkip ( " Mistral3 model not available " )
219219 }
220220
221221 let config = await container. configuration
222- // Mistral3 uses the default JSON tool call format (infer returns nil)
223- let format = config. toolCallFormat ?? . json
224222 XCTAssertEqual (
225- format , . json ,
226- " Mistral3 model should use default .json tool call format "
223+ config . toolCallFormat , . mistral ,
224+ " Mistral3 model should auto-detect .mistral tool call format "
227225 )
228226 }
229227
@@ -264,6 +262,69 @@ public class ToolCallIntegrationTests: XCTestCase {
264262 }
265263 }
266264
265+ func testMistral3MultipleToolCallGeneration( ) async throws {
266+ guard let container = Self . mistral3Container else {
267+ throw XCTSkip ( " Mistral3 model not available " )
268+ }
269+
270+ let multiToolSchema : [ [ String : any Sendable ] ] =
271+ Self . weatherToolSchema + [
272+ [
273+ " type " : " function " ,
274+ " function " : [
275+ " name " : " get_time " ,
276+ " description " : " Get the current time in a given timezone " ,
277+ " parameters " : [
278+ " type " : " object " ,
279+ " properties " : [
280+ " timezone " : [
281+ " type " : " string " ,
282+ " description " :
283+ " The timezone, e.g. America/New_York, Asia/Tokyo " ,
284+ ] as [ String : any Sendable ]
285+ ] as [ String : any Sendable ] ,
286+ " required " : [ " timezone " ] ,
287+ ] as [ String : any Sendable ] ,
288+ ] as [ String : any Sendable ] ,
289+ ]
290+ ]
291+
292+ let input = UserInput (
293+ chat: [
294+ . system(
295+ " You are a helpful assistant with access to tools. Always use the available tools to answer questions. Call multiple tools in parallel when needed. "
296+ ) ,
297+ . user(
298+ " What's the weather in Tokyo and what time is it there? "
299+ ) ,
300+ ] ,
301+ tools: multiToolSchema
302+ )
303+
304+ let ( result, toolCalls) = try await generateWithTools (
305+ container: container,
306+ input: input,
307+ maxTokens: 150
308+ )
309+
310+ print ( " Mistral3 Output: \( result) " )
311+ print ( " Mistral3 Calls: \( toolCalls) " )
312+
313+ // Verify all returned tool calls have valid names from our schema
314+ let validNames : Set < String > = [ " get_weather " , " get_time " ]
315+ for toolCall in toolCalls {
316+ XCTAssertTrue (
317+ validNames. contains ( toolCall. function. name) ,
318+ " Unexpected tool call: \( toolCall. function. name) "
319+ )
320+ }
321+
322+ // If the model made multiple calls, verify we got more than one
323+ if toolCalls. count > 1 {
324+ print ( " Successfully parsed \( toolCalls. count) tool calls from Mistral3 " )
325+ }
326+ }
327+
267328 // MARK: - Helper Methods
268329
269330 /// Generate text and collect any tool calls
0 commit comments