Skip to content

feat(mcp): chat-side tool routing core (wave 1)#61

Merged
magicnight merged 2 commits into
mainfrom
feat/mcp-tool-routing
Jul 8, 2026
Merged

feat(mcp): chat-side tool routing core (wave 1)#61
magicnight merged 2 commits into
mainfrom
feat/mcp-tool-routing

Conversation

@magicnight

Copy link
Copy Markdown
Owner

MacMLXCore foundation for MCP tool calling in chat — the v0.5 roadmap closer. GUI wiring (chat bubbles, AppState pool lifecycle, Integrations screen) is wave 2, following this.

What lands (tasks T1-T5)

  • ToolValueBridge — total, lossless MCP ValueJSONValue + MCP Tool → OpenAI function-spec; .data→base64 (documented lossy edge).
  • GenerateRequest.tools injected into UserInput.tools; the upstream ToolCallProcessor (10 model formats, auto-inferred at load) engages only when the request carries tools — all non-tool /v1/chat/completions + GUI chat keep byte-for-byte passthrough.
  • Streaming tool-call detection in runLLMGeneration: terminal chunk carries ToolCallRequest[] + finishReason:.toolCalls; tool syntax stripped before reasoning-split; extended prompt-cache key unaffected.
  • ChatMessage gains .tool role + toolCallID/toolCalls (all decodeIfPresent — legacy conversations still decode), mapped to upstream Chat.Message.
  • ToolCallingSession — closure-injected generate + callTool agent loop: sequential tools, per-call cancellation-aware timeout, iteration cap, unknown-tool/throw/timeout fed back as error results, cancellation propagation. Value-type Sendable, no leaked tasks.
  • Server still drops incoming role:"tool" turns until wave 2 (avoids a chat-template 500 on replayed tool history).

Review + verification

Adversarially reviewed (REQUEST_CHANGES → both blockers fixed): the HIGH ToolCallProcessor unconditional-activation regression and the MEDIUM .tool decode-leak are both fixed with dedicated tests. Loop state machine (exactly-once finish), timeout race, value bridge (int/double fidelity), Codable back-compat, and the struct: Sendable concurrency model all adjudicated sound; zero force-unwraps/try!/as!. 27 tests; verified green under both xcodebuild (Metal, 80 XCTest + DeepSeek parity) and bare swift test (236 tests, 0 MLX errors) — the two CI-equivalent conditions.

MacMLXCore foundation for MCP tool calling in chat (GUI wiring = wave 2).

- ToolValueBridge: total, lossless MCP Value <-> JSONValue conversion +
  MCP Tool -> OpenAI function-spec; .data -> base64 (documented lossy edge)
- GenerateRequest.tools ([JSONValue]?) injected into UserInput.tools; the
  ToolCallProcessor engages ONLY when the request carries tools, so all
  non-tool /v1/chat/completions + GUI chat keep byte-for-byte passthrough
  (makeToolProcessor gate)
- Streaming tool-call detection in runLLMGeneration via upstream
  ToolCallProcessor (10 model formats auto-inferred at load); terminal
  chunk carries ToolCallRequest[] + finishReason .toolCalls; tool syntax
  stripped before reasoning-split, extended prompt-cache key unaffected
- ChatMessage gains .tool role + toolCallID/toolCalls (all decodeIfPresent,
  legacy conversations still decode); mapped to upstream Chat.Message
- ToolCallingSession: closure-injected generate + callTool agent loop —
  sequential tools, per-call cancellation-aware timeout, iteration cap,
  unknown-tool/throw/timeout fed back as error results, cancellation
  propagation. Value-type Sendable, no leaked tasks.
- Server: incoming role:"tool" turns still dropped until wave 2 wires
  proper pairing (avoids a chat-template 500 on replayed tool history)

27 tests (value bridge, detection, session loop incl. deterministic
cancellation, Codable back-compat, the two review-fix gates). Verified
green under xcodebuild (Metal) + bare swift test.
@cursor

cursor Bot commented Jul 8, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@magicnight magicnight merged commit ca80f22 into main Jul 8, 2026
3 checks passed
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.

1 participant