Class LocalLlmClient
An LlmClient that runs a GGUF model on the device with llama.cpp. Create
one with LlmClient.local(String).
Nothing leaves the device and no network is needed. The model file is
loaded on the first request, which can take several seconds for a large
model, and stays in memory until close().
LocalLlmClient llm = LlmClient.local(FileSystemStorage.getInstance()
.getAppHomePath() + "qwen2.5-0.5b-instruct-q4_k_m.gguf");
llm.chat(ChatRequest.builder()
.addMessage(ChatMessage.user("Name three primes"))
.build()).ready(r -> Log.p(r.getText()));
The prompt is rendered by the chat template the model file carries, so any
instruction-tuned GGUF works without configuration.
ResponseFormat.JSON_OBJECT is enforced with a grammar, so the output is
always valid JSON. Tools and image parts are not supported and fail the
request with LlmException.ErrorType.INVALID_REQUEST.
Availability
Android and iOS. The builders link llama.cpp only into applications that
call LlmClient.local(String). Elsewhere, the simulator included, every
request fails with LlmException.ErrorType.INVALID_REQUEST; use
LlmClient.ollama() to develop against the same model on the desktop.
Requests run one at a time on a background thread, in the order they were made. Results and streaming callbacks arrive on the EDT.
-
Field Summary
Fields inherited from class LlmClient
DEFAULT_ANTHROPIC_URL, DEFAULT_GEMINI_URL, DEFAULT_OLLAMA_URL, DEFAULT_OPENAI_URL -
Method Summary
Modifier and TypeMethodDescriptionchat(ChatRequest req) Non-streaming chat.chatStream(ChatRequest req, StreamingListener listener) Streaming chat.voidclose()Unloads the model.embed(EmbeddingRequest req) Creates embeddings for one or more strings.One of"openai","anthropic","gemini","ollama","local".static booleanWhether this platform can run local models at all.setContextSize(int tokens) Sets the context window.setGpuLayers(int layers) Sets how many layers run on the GPU (Metal on iOS).setThreads(int threads) Sets the CPU threads used for generation.Methods inherited from class LlmClient
anthropic, gemini, getBaseUrl, getHttpTimeoutMs, local, localOpenAiCompatible, ollama, ollama, ollama, openai, runSafetyFilter, setBaseUrl, setHttpTimeoutMs
-
Method Details
-
getModelPath
- Returns:
- the model file this client loads
-
setContextSize
Sets the context window. Takes effect when the model is next loaded.- Parameters:
tokens- context size in tokens,0for the model's default- Returns:
- this client
-
setGpuLayers
Sets how many layers run on the GPU (Metal on iOS). Takes effect when the model is next loaded.- Parameters:
layers- layer count,0for CPU only,-1(the default) for all- Returns:
- this client
-
setThreads
Sets the CPU threads used for generation. Takes effect when the model is next loaded.- Parameters:
threads- thread count,0(the default) to let the port choose- Returns:
- this client
-
isSupported
public static boolean isSupported()Whether this platform can run local models at all.falsein the simulator and on any target the builder did not link llama.cpp into.- Returns:
truewhen requests can succeed
-
getProvider
Description copied from class:LlmClientOne of"openai","anthropic","gemini","ollama","local". Used byChatViewand tests to vary behaviour by provider.- Specified by:
getProviderin classLlmClient- Returns:
- stable provider family id
-
chat
Description copied from class:LlmClientNon-streaming chat. Equivalent tochatStreamwith a no-op listener but optimized -- the provider skips the SSE response and returns a single JSON object. -
chatStream
Description copied from class:LlmClientStreaming chat.listenerfires for every content delta / tool-call fragment on the EDT. The returnedAsyncResourcecompletes with the aggregated final response once the stream ends; cancel it to close the underlying socket.- Specified by:
chatStreamin classLlmClient- Parameters:
req- immutable chat requestlistener- incremental callbacks delivered on the EDT- Returns:
- asynchronous aggregated response
-
embed
Description copied from class:LlmClientCreates embeddings for one or more strings. -
close
public void close()Unloads the model. Requests already queued still run first; a later request loads the model again. The worker thread is kept, idle, so a request afterclose()can never reach the native session on a second thread while the first is still using or closing it.
-