Skip to content

Add Python tool call parser and use it for LFM2 models#93

Closed
atdrendel wants to merge 3 commits intoml-explore:mainfrom
shareup:python-tool-call-parser
Closed

Add Python tool call parser and use it for LFM2 models#93
atdrendel wants to merge 3 commits intoml-explore:mainfrom
shareup:python-tool-call-parser

Conversation

@atdrendel
Copy link
Copy Markdown
Contributor

Proposed changes

LFM2 models write LFM2 writes Pythonic function calls, not JSON tool calls. This pull request adds PythonToolCallParser and uses it for LFM2 models.

LFM2 generates Python-like tool calls

Before these changes were applied

Prior to these changes, testLFM2EndToEndToolCallGeneration always succeeded, but it succeeded because toolCalls was always empty since JSONToolCallParser could never parse the tool calls.

// ToolCallIntegrationTests.testLFM2EndToEndToolCallGeneration()
let (result, toolCalls) = try await generateWithTools(
    container: container,
    input: input,
    maxTokens: 100
)

print("LFM2 Output: \(result)")
print("LFM2 Tool Calls: \(toolCalls)")
LFM2 produces Python-like tool calls - deux

After these changes are applied

Now, testLFM2EndToEndToolCallGeneration succeeds and does recognize the tool calls correctly. Here's the output of one of the runs I did on my Mac.

Test Suite 'Selected tests' started at 2026-02-05 22:40:59.659.
Test Suite 'MLXLMIntegrationTests.xctest' started at 2026-02-05 22:40:59.659.
Test Suite 'ToolCallIntegrationTests' started at 2026-02-05 22:40:59.659.
Test Case '-[MLXLMIntegrationTests.ToolCallIntegrationTests testLFM2EndToEndToolCallGeneration]' started.
LFM2 Output: 
LFM2 Tool Calls: [MLXLMCommon.ToolCall(function: MLXLMCommon.ToolCall.Function(name: "get_weather", arguments: ["location": MLXLMCommon.JSONValue.string("Tokyo")]))]
Test Case '-[MLXLMIntegrationTests.ToolCallIntegrationTests testLFM2EndToEndToolCallGeneration]' passed (0.317 seconds).
Test Suite 'ToolCallIntegrationTests' passed at 2026-02-05 22:41:05.423.
	 Executed 1 test, with 0 failures (0 unexpected) in 0.317 (5.764) seconds
Test Suite 'MLXLMIntegrationTests.xctest' passed at 2026-02-05 22:41:05.423.
	 Executed 1 test, with 0 failures (0 unexpected) in 0.317 (5.764) seconds
Test Suite 'Selected tests' passed at 2026-02-05 22:41:05.423.
	 Executed 1 test, with 0 failures (0 unexpected) in 0.317 (5.764) seconds

Checklist

Put an x in the boxes that apply.

  • I have read the CONTRIBUTING document
  • I have run pre-commit run --all-files to format my code / installed pre-commit prior to committing changes
  • I have added tests that prove my fix is effective or that my feature works
  • I have updated the necessary documentation (if needed)

Copilot AI review requested due to automatic review settings February 5, 2026 23:07
@atdrendel
Copy link
Copy Markdown
Contributor Author

Oh, look at that, I pushed this without realizing that there was a similar pull request already open: #91

I'm fine with either one, of course. Feel free to close this one, if you want.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds a PythonToolCallParser to correctly parse LFM2 model outputs, which generate Python-style function calls rather than JSON. Previously, LFM2 models were incorrectly configured to use JSONToolCallParser, which couldn't parse the Python-style syntax, resulting in all tool calls being silently ignored.

Changes:

  • Implemented PythonToolCallParser to parse Python-style function calls with support for both single and double quotes, escape sequences, numeric types, booleans, and null values
  • Updated ToolCallFormat.swift to use PythonToolCallParser instead of JSONToolCallParser for LFM2 format
  • Replaced outdated LFM2 tests that verified JSON parsing with comprehensive new tests for Python-style parsing

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
Libraries/MLXLMCommon/Tool/Parsers/PythonToolCallParser.swift New parser implementation for Python-style function calls with comprehensive string, number, and type handling
Libraries/MLXLMCommon/Tool/ToolCallFormat.swift Updated LFM2 format to use PythonToolCallParser and corrected comment to reflect Python-style format
Tests/MLXLMTests/ToolTests.swift Removed obsolete JSON-based LFM2 tests and added comprehensive Python-style parser tests covering edge cases

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@atdrendel
Copy link
Copy Markdown
Contributor Author

The problem solved by this pull request has already been addressed by #91. So, I'll close this one.

@atdrendel atdrendel closed this Feb 10, 2026
@atdrendel atdrendel deleted the python-tool-call-parser branch February 10, 2026 21:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants