diff --git a/ai-agent-local/ai-agent-local.html b/ai-agent-local/ai-agent-local.html
index 0ac3b8fc..6b7412b5 100644
--- a/ai-agent-local/ai-agent-local.html
+++ b/ai-agent-local/ai-agent-local.html
@@ -63,14 +63,16 @@
Core functionality
Model safety checks — inspects a selected .gguf
header and refuses embedding-only models for chat, with a clear error
instead of a native crash.
- Actionable load failures — a failed load is classified (missing,
- empty, not a GGUF, out of memory, unsupported quantization) and reported as
- a message that says what to do next.
- Storage-picker support — a model chosen as a
- content:// document is copied once into private storage so the
- native loader can open it, and only the current model is kept.
+ Actionable load failures — a failed load is classified (no longer
+ reachable, streamed rather than local, empty, not a GGUF, out of memory,
+ unsupported quantization) and
+ reported as a message that says what to do next.
+ Direct storage access — a model chosen as a content://
+ document is read in place, through the read grant the picker persisted.
+ Nothing is copied into private storage, so a multi-gigabyte model costs no
+ device space beyond the file you downloaded.
Its own settings pane — browse for a .gguf file,
- re-load a previously imported model, record the model's published SHA-256,
+ re-load the model already selected, record the model's published SHA-256,
and choose between the short system prompt small models follow
reliably and the full tool-calling one. A model too large for the device's
free RAM raises a warning first.
@@ -82,14 +84,15 @@ Technical architecture
LocalLlmPlugin | Plugin entry point. Registers the
backend with AI Core on activation, re-registering if AI Core activates
later; frees the native model on dispose. |
- LocalLlmBackend | The inference engine. Resolves
- the selected model to a real file path, manages loading and unloading, and
- serializes generations against the shared native context. |
+ LocalLlmBackend | The inference engine. Opens the
+ selected model in place and hands the native loader that descriptor, manages
+ loading and unloading, and serializes generations against the shared native
+ context. |
GgufModelInspector | Minimal GGUF header reader
that classifies a model as chat- or embedding-only. |
ModelLoadDiagnostics | Classifies a load failure
- from the file, free memory and the native error text, as a pure function
- that is unit-tested off-device. |
+ from the model's size and readability, free memory and the native error
+ text, as a pure function that is unit-tested off-device.
ModelLoadMessages | Renders a diagnosis as
user-facing text, keeping string resources out of the engine. |
LocalLlmSettingsFragment | The settings pane AI
@@ -107,11 +110,14 @@ Usage
Manager, then restart the IDE.
Open Preferences → Configuration → Agent and select the
local backend. This plugin's own pane appears below it.
- Tap Browse and pick a .gguf model file. The file is
- copied once into private storage, then loaded; a model larger than the free
- RAM asks you to confirm first.
+ Tap Browse and pick a .gguf model file. It is loaded
+ from wherever you saved it, with no copy made; a model larger than the free
+ RAM asks you to confirm first. Leave the file in place — moving or deleting
+ it breaks the selection. The picker offers device-local documents only: a
+ model still in a cloud folder can only be read as a stream, which the
+ in-place loader cannot use.
Optionally record the model's published SHA-256, or use Load
- from saved to return to a model you already imported.
+ from saved to return to the model you already selected.
Model choice drives whether this works at all on a given device. A Q4_K_M
diff --git a/ai-agent-local/build.gradle.kts b/ai-agent-local/build.gradle.kts
index 0b99ef6b..638a36df 100644
--- a/ai-agent-local/build.gradle.kts
+++ b/ai-agent-local/build.gradle.kts
@@ -81,6 +81,9 @@ dependencies {
testImplementation(files("../libs/plugin-api.jar"))
testImplementation("junit:junit:4.13.2")
testImplementation("io.mockk:mockk:1.13.8")
+ // LiveData's postValue needs the arch-core executor swapped for a synchronous one; the
+ // settings pane publishes its state through it, so its tests cannot run without this.
+ testImplementation("androidx.arch.core:core-testing:2.2.0")
}
// The one ABI this plugin ships. Shared by the packaging check and the unit tests.
diff --git a/ai-agent-local/src/main/AndroidManifest.xml b/ai-agent-local/src/main/AndroidManifest.xml
index 3988f4c1..80896e03 100644
--- a/ai-agent-local/src/main/AndroidManifest.xml
+++ b/ai-agent-local/src/main/AndroidManifest.xml
@@ -36,8 +36,10 @@
android:name="plugin.max_ide_version"
android:value="26.99" />
-
+
diff --git a/ai-agent-local/src/main/assets/docs/index.html b/ai-agent-local/src/main/assets/docs/index.html
index c25acac5..5db9e206 100644
--- a/ai-agent-local/src/main/assets/docs/index.html
+++ b/ai-agent-local/src/main/assets/docs/index.html
@@ -57,13 +57,16 @@ The settings pane
controls:
- Browse — opens the system file picker to choose a
-
.gguf model. A model selected as a content://
- document is copied once into the plugin's private storage so the native
- loader can open it, and only the current model is kept on disk. If the file
- is larger than the device's free RAM, a warning asks you to confirm before
- loading.
- - Load from saved — reloads the model already in private storage
- without picking it again. Use this after restarting the IDE, or when a load
+
.gguf model. The plugin keeps read access to the document you
+ picked and reads it where it is — on internal storage, an SD card or a USB
+ volume. Nothing is copied, so a multi-gigabyte model costs no extra device
+ storage. Keep the file where it is: moving or deleting it breaks the
+ selection. The picker offers only documents already stored on the device,
+ because a model still in a cloud folder has to be read as a stream and
+ cannot be loaded in place. If the file is larger than the device's free RAM,
+ a warning asks you to confirm before loading.
+ - Load from saved — reloads the model you already selected without
+ picking it again. Use this after restarting the IDE, or when a load
failed for a transient reason such as low memory.
- SHA-256 — optional. Paste the checksum published alongside the
model download to keep a record of which exact file is configured. It is
@@ -93,6 +96,16 @@
Troubleshooting
the safest starting point).
- The
local backend never appears — AI Core isn't
installed or activated; install it and restart the IDE.
+ - "The selected model can no longer be reached" — the model is read
+ where you saved it rather than from a copy, so moving, renaming or deleting
+ the file, or removing the SD card it lives on, breaks the selection.
+ Clearing the IDE's app data also withdraws the permission to read it. Pick
+ the model again with Browse.
+ - "This model is streamed from its storage location" — the file
+ you picked lives in a cloud folder (Google Drive, OneDrive) rather than on
+ the device, and can only be read as a stream. Download the
+
.gguf to the device — Downloads is fine — and pick
+ it from there.
|