import Foundation enum ToolCallParserError: LocalizedError, Sendable, Equatable { case multipleCalls case malformedCall case contentOutsideCall case invalidPayload case unexpectedFields([String]) case missingName case missingArguments var errorDescription: String? { switch self { case .multipleCalls: "The model requested more than one tool in a single turn." case .malformedCall: "The model returned an incomplete tool-call envelope." case .contentOutsideCall: "The model mixed a tool call with other response content." case .invalidPayload: "The tool call was not valid JSON." case .unexpectedFields(let fields): "The tool call included unexpected fields: \(fields.joined(separator: ", "))." case .missingName: "The tool call did not include a valid function name." case .missingArguments: "The tool call arguments must be a JSON object." } } } struct ToolCallParser: Sendable { private static let openingTag = "" private static let closingTag = "" static func parse(_ text: String) throws -> AgentToolCall? { let openingRanges = text.ranges(of: openingTag) let closingRanges = text.ranges(of: closingTag) if openingRanges.isEmpty && closingRanges.isEmpty { return nil } guard openingRanges.count == 1, closingRanges.count == 1 else { throw ToolCallParserError.multipleCalls } guard let opening = openingRanges.first, let closing = closingRanges.first, opening.upperBound <= closing.lowerBound else { throw ToolCallParserError.malformedCall } let prefix = text[.. [Range] { var result: [Range] = [] var searchRange = startIndex..