Skip to main content
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.
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):
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.
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:.

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.
  • 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

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.
Pass null / nil as the parser to disable tool-call parsing entirely β€” the raw tool-call text is then surfaced as ordinary Chunks.