Overview
Tool calling lets a model request one of your functions, receive the result, and fold it into its answer. The SDK runs the whole loop: generate, parse the tool call, execute your Kotlin lambda, feed the result back, generate the final response. Parsing lives in C++; there is no Kotlin fallback parser. Every entry point is an extension function on theRunAnywhere singleton. There is no
RunAnywhereToolCalling class.
Imports
string, int, double, bool, array, and object constructors on RAToolValue are
extension functions in com.runanywhere.sdk.public.extensions.LLM and have to be imported
individually.
Registering a tool
registerTool is a suspend function. The executor is a ToolExecutor, which is
suspend (Map<String, RAToolValue>) -> Map<String, RAToolValue>. Arguments and return values are
both typed value maps; the SDK marshals them to and from the JSON the model sees.
Generating with tools
null for the ones you do not need.
history is prior turns as a flat alternating list ([user0, assistant0, user1, ...]) excluding
the current turn, which is prompt. It is threaded to commons so the tool loop keeps multi-turn
context.
An explicit toolOptions overrides any tool_calling payload embedded in options. When both are
absent, the SDK derives options from options and falls back to
ToolCallingOptions.defaults().
Tool management
All are suspend functions on
RunAnywhere.
ToolDefinition
ToolParameter
ToolParameterType values are TOOL_PARAMETER_TYPE_STRING, NUMBER, BOOLEAN, OBJECT,
ARRAY, and UNSPECIFIED. Fully qualified, so ToolParameterType.TOOL_PARAMETER_TYPE_STRING, not
ToolParameterType.STRING.
ToolCallingOptions
Defaults aremax_tool_calls = 5, auto_execute = true, format = TOOL_CALL_FORMAT_NAME_JSON.
toolChoice and forcedToolName passed to generateWithTools() override whatever the options
carry.
ToolCallingResult
ToolCall carries id, name, arguments_json, type, created_at_ms, and raw_text.
Arguments arrive as a JSON string, not a map.
ToolResult carries tool_call_id, name, result_json, error, success, started_at_ms,
and completed_at_ms. The result is likewise a JSON string.
Pairing a call with its result:
ToolValue
RAToolValue is a typealias for the generated ToolValue. Build values with the companion
extensions and read them with the property extensions.
object is a Kotlin keyword, so both the constructor and the accessor need backticks:
RAToolValue.`object`(fields).
toJSONString(pretty), RAToolValue.parseObjectJSON(json), and RAToolValue.jsonString(map)
convert between value maps and JSON.
The accessor is .string, not .stringValue.
Examples
Calculator:Timeouts
Small on-device models sometimes fail to converge on a tool loop. Bound the call and cancel the generation when it expires, rather than leaving the UI waiting:Errors
generateWithTools() throws SDKException with ERROR_CODE_NOT_INITIALIZED before
RunAnywhere.initialize(). Individual tool failures come back on ToolResult, not as exceptions.
See Error handling.
Notes
Executors run inside the generation loop, so a slow one blocks inference for its duration. Keep network calls out, or bound them yourself. Descriptions are the only thing the model has to decide with. A description that names the inputs and says what comes back beats one that names the function again. Keep returned payloads small. Everything a tool returns is fed back through the context window.Related
LLM generation
Text generation
VLM
Vision language models
System prompts
Control model behavior
Error handling
Error handling patterns