Skip to main content
Not all models support function calling. Please check the model card before using the model for function calling.
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 image and audio parts to your messages and tool responses.

Register Functions to Conversations

To enable function calling, function definitions should be registered to the Conversation instance before content generation. Conversation.registerFunction takes a LeapFunction instance as the input, which describes the name, parameters, and ability of the function.
val conversation = modelRunner.createConversation("You are a helpful assistant.")

conversation.registerFunction(
  LeapFunction(
    name = "get_weather",
    description = "Get the weather forecast of a city",
    parameters = listOf(
      LeapFunctionParameter(
        name = "city",
        type = LeapFunctionParameterType.String(),
        description = "The city name",
      ),
    ),
  ),
)
Generally speaking, function names and parameter names should be normal identifiers that are recognized by most common programming languages (e.g. Python, JavaScript, etc.). We recommend using descriptive names composed of only letters, underscores, and digits (not starting with digits).

Handle Function Calling Response

Function calling requests by the model are returned as part of the response stream from generateResponse. Each platform represents them differently:
On Android, function call requests arrive as a MessageResponse.FunctionCalls instance containing a list of function calls.
data class FunctionCalls(val functionCalls: List<LeapFunctionCall>): MessageResponse
Each LeapFunctionCall instance contains the name and arguments of the function call request. The arguments field is a map from String to Any?. The app needs to check whether the required parameters are filled by the model. It is possible (even though very unlikely) that some parameters are missing or the function name is invalid.
data class LeapFunctionCall(
  val name: String,
  val arguments: Map<String, Any?>,
)
To handle the function call response, add a new branch to match responses from the generateResponse flow:
conversation.generateResponse(userMessage).onEach { response ->
  when (response) {
    is MessageResponse.Chunk -> {
      // process text chunk
    }
    is MessageResponse.FunctionCalls {
      response.functionCalls.forEach { call ->
        // Process function calls here
        Log.d(TAG, "Call function: ${call.name}, arguments: ${call.arguments}")
      }
    }
    else -> {
      // other responses
    }
}
The function calls are also included in the assistant message generated by the model, so it is possible to delay function call processing until generation is complete:
conversation.generateResponse(userMessage).onEach { response ->
  when (response) {
    is MessageResponse.Complete -> {
      val assistantMessage = response.fullMessage
      val functionCalls = assistantMessage.functionCalls
      functionCalls?.forEach { call ->
        // process function calls here
        Log.d(TAG, "Call function: ${call.name}, arguments: ${call.arguments}")
      }
    }
    else -> {
      // process chunks
    }
  }
}

Function Definition

Functions for models to call are defined by LeapFunction instances. A LeapFunction has three fields: name, description, and parameters.
data class LeapFunction(
    val name: String,
    val description: String,
    val parameters: List<LeapFunctionParameter>,
)
  • name is the function name. It is recommended to use only English letters, underscores, and digits (not starting with digits) because this format is supported by most models.
  • description tells the model what this function does.
  • parameters declares what arguments the function accepts.

LeapFunctionParameter

The items of parameters are instances of LeapFunctionParameter.
data class LeapFunctionParameter(
    val name: String,
    val type: LeapFunctionParameterType,
    val description: String,
    val optional: Boolean = false,
)
  • name β€” The name of the parameter.
  • type β€” Data type of the parameter.
  • description β€” Tells the model what this parameter is about.
  • optional β€” Whether the parameter is optional.

LeapFunctionParameterType

LeapFunctionParameterType describes the data types of the parameters. They are translated into JSON Schema for the model to understand. The following types are supported:
LeapFunctionParameterType.String(enumValues: List<kotlin.String>? = null, description: kotlin.String? = null)
LeapFunctionParameterType.Number(enumValues: List<kotlin.Number>? = null, description: kotlin.String? = null)
LeapFunctionParameterType.Integer(enumValues: List<Int>? = null, description: kotlin.String? = null)
LeapFunctionParameterType.Boolean(description: kotlin.String? = null)
LeapFunctionParameterType.Array(itemType: LeapFunctionParameterType, description: kotlin.String? = null)
LeapFunctionParameterType.Object(
  properties: Map<kotlin.String, LeapFunctionParameterType>,
  required: List<kotlin.String> = listOf(),
  description: kotlin.String? = null,
)
  • String β€” String literals. Accepts optional enumValues to restrict valid values.
  • Number β€” Number literals including integers and floating point numbers. Accepts optional enumValues.
  • Integer β€” Integer literals. Accepts optional enumValues.
  • Boolean β€” Boolean literals.
  • Array β€” Arrays of a defined type. The itemType parameter describes the data type of its items.
  • Object β€” Objects with their own properties. properties maps property names to their data types. required lists the names of all non-optional properties.
All types accept an optional description, but it will be overridden if the type is used directly as LeapFunctionParameter.type. The description only takes effect when the type instance is used as Array.itemType or as a type within object properties.

Comprehensive Example

LeapFunction(
  name = "get_weather",
  description = "Get the weather forecast of cities",
  parameters = listOf(
    LeapFunctionParameter(
      name = "cities",
      type = LeapFunctionParameterType.Array(
        itemType = LeapFunctionParameterType.String()
      ),
      description = "City names to query",
    ),
    LeapFunctionParameter(
      name = "temperature_unit",
      type = LeapFunctionParameterType.String(
        enumValues = listOf(
          "Fahrenheit", "Celsius", "Kelvin"
        )
      ),
      description = "Units for temperature",
    ),
  ),
)

Function Call Parser

Function call parsers translate the model’s tool-call tokens into LeapFunctionCall values. Different models emit tool calls in different formats, so you need to use the parser that matches your checkpoint. By default, LFMFunctionCallParser is used. It supports Liquid Foundation Model (LFM2) Pythonic-style control tokens. For Qwen3 models and other models that use the Hermes function calling format, apply HermesFunctionCallParser by injecting a parser instance on the generation options:
val options = GenerationOptions.build {
  functionCallParser = HermesFunctionCallParser()
}
conversation.generateResponse(userMessage, options).onEach {
    // process message response here
}