Melange
LLM Inference

Function Calling

Connect ZeticMLange LLM output to app-defined tools on Android, iOS, and Flutter.

Function calling lets an on-device LLM ask your app to run a tool and feed the tool result back into the same generation session. Use it for app-local actions such as search, settings lookup, inventory checks, or deterministic calculations.

This page reflects ZeticMLange 1.11.0 on Android and iOS, and zetic_mlange 1.11.1 on Flutter.

Tool Shape

Each tool has a name, description, and JSON parameter schema. When it emits a tool call, the SDK invokes your registered executor and continues the tool session with the returned content.

val weatherTool = LLMToolSpec(
    name = "get_weather",
    description = "Get the weather for a city.",
    parametersJson = """
        {
          "type": "object",
          "properties": {
            "city": { "type": "string" }
          },
          "required": ["city"]
        }
    """.trimIndent(),
)

model.registerTool(weatherTool) { call ->
    LLMToolResult(content = """{"summary":"Sunny, 24C"}""")
}
let weatherTool = LLMToolSpec(
  name: "get_weather",
  description: "Get the weather for a city.",
  parametersJson: """
  {
    "type": "object",
    "properties": {
      "city": { "type": "string" }
    },
    "required": ["city"]
  }
  """
)

try model.registerTool(weatherTool) { call in
  LLMToolResult(content: #"{"summary":"Sunny, 24C"}"#)
}
final weatherTool = LLMToolSpec(
  name: 'get_weather',
  description: 'Get the weather for a city.',
  parametersJson: '''
{
  "type": "object",
  "properties": {
    "city": { "type": "string" }
  },
  "required": ["city"]
}
''',
);

model.registerTool(weatherTool, (call) async {
  return const LLMToolResult(content: '{"summary":"Sunny, 24C"}');
});

Run With Tools

Register tools before calling runWithTools(...). Use run(...) only when no tools are registered.

model.functionCallingSystemPrompt =
    "Use tools only when they are needed. Explain the final answer clearly."

model.runWithTools("What is the weather in Seoul?")
    .collect { token -> append(token) }
model.functionCallingSystemPrompt =
  "Use tools only when they are needed. Explain the final answer clearly."

for try await token in try model.runWithTools("What is the weather in Seoul?") {
  append(token)
}
model.functionCallingSystemPrompt =
    'Use tools only when they are needed. Explain the final answer clearly.';

await for (final token in model.runWithTools('What is the weather in Seoul?')) {
  append(token);
}

Tool Management

PlatformRegisterRemoveClearList
AndroidregisterTool(spec, executor)unregisterTool(name)clearTools()registeredTools()
iOSregisterTool(_:executor:)unregisterTool(name:)clearTools()registeredToolSpecs()
FlutterregisterTool(spec, executor)unregisterTool(name)clearTools()registeredTools()

Executor Behavior

Tool executors are asynchronous on every platform:

PlatformLLMToolExecutor
Androidsuspend fun execute(call: LLMToolCall): LLMToolResult
iOS(LLMToolCall) async throws -> LLMToolResult
FlutterFuture<LLMToolResult> Function(LLMToolCall call)

If an executor fails, the SDK returns a JSON error tool result such as {"error":"..."} to the model instead of emitting the executor failure through the token stream. Return an LLMToolResult yourself when the model needs an app-specific error response.

Cancelling the output stream ends the SDK request and ignores an executor completion that arrives later. It does not forcibly cancel app work already running in an Android coroutine, iOS task, or Flutter Future; make long-running app work cancellation-aware.

API Reference

On this page