From 37e36c2fbc6c717daf3e733cd3d7522afdee7112 Mon Sep 17 00:00:00 2001 From: Link Dupont Date: Sat, 4 Apr 2026 22:48:46 -0400 Subject: [PATCH] fix(fm): remove synthesized finish tool call from stream path FoundationModelsClient.stream() was emitting a synthetic 'finish' tool call after streaming completed. This caused Chat to try executing it as a real tool, fail with 'Tool finish does not exist', and loop. The content is already streamed via .content() deltas so the synthetic finish is unnecessary. The generate() path retains it for the Agent class which expects it. --- .../FoundationModelsClient.swift | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/Sources/AgentRunKitFoundationModels/FoundationModelsClient.swift b/Sources/AgentRunKitFoundationModels/FoundationModelsClient.swift index 0928bb7..c4d2289 100644 --- a/Sources/AgentRunKitFoundationModels/FoundationModelsClient.swift +++ b/Sources/AgentRunKitFoundationModels/FoundationModelsClient.swift @@ -62,7 +62,6 @@ let stream = session.streamResponse(to: mapped.prompt) var previousUTF8Count = 0 - var accumulatedContent = "" for try await snapshot in stream { let current = snapshot.content @@ -77,21 +76,9 @@ continuation.yield(.content(delta)) } } - accumulatedContent = current previousUTF8Count = currentUTF8Count } - let finishMessage = Self.synthesizeFinish( - content: accumulatedContent - ) - if let finishCall = finishMessage.toolCalls.first { - continuation.yield(.toolCallStart( - index: 0, id: finishCall.id, name: finishCall.name - )) - continuation.yield(.toolCallDelta( - index: 0, arguments: finishCall.arguments - )) - } continuation.yield(.finished(usage: nil)) continuation.finish() } catch {