Skip to main content

Documentation Index

Fetch the complete documentation index at: https://liquidai-fix-android-sdk-qa-issues.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Function calling lets the model invoke predefined functions provided by your app β€” query an API, run a calculation, fetch external state. Register LeapFunction definitions on the Conversation, run generation as usual, and the model’s tool-call tokens come back as MessageResponse.functionCalls.
Not all models support function calling. Check the model card on Hugging Face before assuming a checkpoint supports tool use.
Vision and audio-capable models require companion files. Bundles embed these references; GGUF checkpoints expect siblings such as mmproj-*.gguf (vision) and audio decoder/tokenizer files. When detected, you can attach ChatMessageContent.image / .audio parts to your tool responses as well as user messages.

Register functions on the conversation

Conversation.registerFunction takes a LeapFunction instance describing name, parameters, and purpose.
The Kotlin LeapFunction / LeapFunctionParameter constructors carry @ObjCName annotations on description:, so the Swift labels are functionDescription: and parameterDescription:. LeapFunctionParameter’s optional parameter has no Swift default β€” pass optional: false for required parameters.
conversation.registerFunction(
  function: LeapFunction(
    name: "get_weather",
    functionDescription: "Query the weather of a city",
    parameters: [
      LeapFunctionParameter(
        name: "city",
        type: LeapFunctionParameterType.LeapStr(enumValues: nil, description: nil),
        parameterDescription: "The city to query weather for",
        optional: false
      ),
      LeapFunctionParameter(
        name: "unit",
        type: LeapFunctionParameterType.LeapStr(
          enumValues: ["celsius", "fahrenheit"],
          description: nil
        ),
        parameterDescription: "Temperature unit (celsius or fahrenheit)",
        optional: false
      ),
    ]
  )
)
Use normal identifiers β€” letters, underscores, and digits (not starting with a digit). Most models trained for tool use recognize that shape.
The Kotlin parameter type classes are named with a Leap prefix (LeapStr, LeapNum, LeapInt, LeapBool, LeapArr, LeapObj, LeapNull) to avoid collisions with Kotlin’s built-in String, Number, Int, Boolean, etc. The Swift bindings expose the same names β€” there are no separate .string(...) / .number(...) aliases; SKIE preserves the Kotlin nested-class names.

Handle the response

Function calls arrive as the MessageResponse.FunctionCalls variant on both platforms, wrapping a list of LeapFunctionCall payloads.
LeapFunctionCall is a Kotlin data class bridged into Swift. arguments is a Kotlin Map<String, Any?> exposed as Swift [String: Any] (the ObjC bridge collapses Any? to non-optional id):
public class LeapFunctionCall {
  public var name: String
  public var arguments: [String: Any]
}
let userMessage = ChatMessage(role: .user, textContent: "What's the weather in NYC?")

for try await response in conversation.generateResponse(message: userMessage) {
    switch onEnum(of: response) {
    case .functionCalls(let payload):
        for call in payload.functionCalls {
            print("Function call: \(call.name) \(call.arguments)")
            // dispatch to your tool implementation
        }
    case .chunk, .reasoningChunk, .audioSample, .complete:
        break
    }
}
The model may emit missing or invalid arguments β€” defensively validate the arguments map against your tool’s expected shape before dispatching.

Sending tool results back

Append the tool’s output as a tool-role message and continue the conversation. Both platforms use the same shape β€” see also Quick Start β†’ Add tool results back to history.
let toolMessage = ChatMessage(
  role: .tool,
  textContent: #"{"temperature":72,"conditions":"sunny"}"#
)

let updatedHistory = conversation.history + [toolMessage]
let nextConversation = conversation.modelRunner.createConversationFromHistory(history: updatedHistory)
// Continue generation against `nextConversation`.
Then call generateResponse(...) on the new conversation to get the model’s tool-aware reply.

LeapFunction

Both types are Kotlin data classes bridged into Swift. @ObjCName annotations rename the description parameter on the Swift inits to functionDescription: / parameterDescription:.
public class LeapFunction {
  public var name: String
  public var functionDescription: String       // ObjC-renamed from Kotlin `description`
  public var parameters: [LeapFunctionParameter]

  public init(name: String, functionDescription: String, parameters: [LeapFunctionParameter])
}

public class LeapFunctionParameter {
  public var name: String
  public var type: LeapFunctionParameterType
  public var parameterDescription: String      // ObjC-renamed from Kotlin `description`
  public var optional: Bool

  public init(
    name: String,
    type: LeapFunctionParameterType,
    parameterDescription: String,
    optional: Bool                              // no default in Swift β€” pass `false` for required
  )
}

Parameter types

LeapFunctionParameterType is translated into JSON Schema for the model. The same primitive set is exposed on both platforms.
LeapFunctionParameterType is a Kotlin sealed class. SKIE generates an onEnum(of:)-compatible enum view, but the constructors you use to build instances keep the Kotlin nested-class names β€” there is no .string(...) / .number(...) alias.
// Direct constructors (use these to build parameter types):
LeapFunctionParameterType.LeapStr(enumValues: [String]?, description: String?)
LeapFunctionParameterType.LeapNum(enumValues: [NSNumber]?, description: String?)
LeapFunctionParameterType.LeapInt(enumValues: [KotlinInt]?, description: String?)
LeapFunctionParameterType.LeapBool(description: String?)
LeapFunctionParameterType.LeapArr(itemType: LeapFunctionParameterType, description: String?)
LeapFunctionParameterType.LeapObj(
  properties: [String: LeapFunctionParameterType],
  required: [String],
  description: String?
)
LeapFunctionParameterType.LeapNull()   // no description parameter
  • LeapStr / LeapNum / LeapInt accept enumValues to constrain valid values.
  • LeapArr has itemType describing the element type.
  • LeapObj has properties: [String: LeapFunctionParameterType] and required: [String].
  • The nested description is overridden when the type is used directly as LeapFunctionParameter.type; it’s only consulted when the type is used inside LeapArr.itemType or LeapObj.properties.

Example: array + enum parameters

LeapFunction(
  name: "get_weather",
  functionDescription: "Query the weather of cities",
  parameters: [
    LeapFunctionParameter(
      name: "cities",
      type: LeapFunctionParameterType.LeapArr(
        itemType: LeapFunctionParameterType.LeapStr(enumValues: nil, description: nil),
        description: nil
      ),
      parameterDescription: "Names of the cities to query weather for",
      optional: false
    ),
    LeapFunctionParameter(
      name: "unit",
      type: LeapFunctionParameterType.LeapStr(
        enumValues: ["celsius", "fahrenheit"],
        description: nil
      ),
      parameterDescription: "Temperature unit",
      optional: false
    ),
  ]
)

Function call parser

Different models emit tool-call tokens in different shapes. The parser translates those tokens into LeapFunctionCall values. The default LFMFunctionCallParser handles Liquid Foundation Model (LFM2) Pythonic-style control tokens (<|tool_call_start|> ... <|tool_call_end|>). For Qwen3 and other models using the Hermes function-calling format, use HermesFunctionCallParser.
var options = GenerationOptions()
options.functionCallParser = HermesFunctionCallParser()

for try await response in conversation.generateResponse(
  message: userMessage,
  generationOptions: options
) {
  // ...
}
Pass null / nil as the parser to disable tool-call parsing entirely β€” the raw tool-call text is then surfaced as ordinary Chunks.