Repository navigation
Conversation
Keep Hugging Face primary and offer one-time revocable consent for a bounded alternative attempt. Pin seven mirror artifacts and validate size, LiteRT-LM header, and SHA-256 before finalizing. Allow public-artifact failover after network or temporary-server failures. Gated artifacts require valid model bytes from the current primary transfer before a later network interruption can select the mirror. Never treat a stored token, stale preflight result, or cached partial as access permission. Require trusted HTTPS origins for Hugging Face credentials, preserve authentication and license denials, and keep credentials off alternate hosts. Isolate resumable files by provider and mirror checksum; clean obsolete partials without touching unrelated downloads. Include consent UI, source/error reporting, independent checksum and access-boundary regressions, and provenance documentation. Keep upstream minimum SDK, build tooling, application version, and source layout unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
3 of 11 tasks
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Two critical and three moderate unresolved findings affect authentication, fallback behavior, and download progress.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 2
Open (2)
What changed in this PR
Adds an opt-in ModelScope fallback for supported Hugging Face model downloads, including consent handling, checksum validation, provider-specific resume support, UI updates, documentation, and tests.
Changes:
- Adds pinned ModelScope mappings and validated fallback transfers.
- Adds consent settings, source status, and failure reporting.
- Adds extensive unit tests and documentation.
| File | Summary / final review comment |
|---|---|
docs/TROUBLESHOOTING.md |
Documents fallback troubleshooting and gated-model behavior. |
docs/MODELS.md |
Documents fallback scope, validation, and limitations. |
Android/src/app/src/test/java/com/ollitert/llm/server/worker/ModelFileDownloaderTest.kt |
Tests transfer, resume, security, and integrity behavior. |
Android/src/app/src/test/java/com/ollitert/llm/server/ui/modelmanager/ModelUrlProbeTest.kt |
Tests probing and cancellation. Critical (1 vote): the probe sends the redacted token literal instead of Bearer $accessToken, blocking gated downloads. |
Android/src/app/src/test/java/com/ollitert/llm/server/ui/modelmanager/ModelManagerFallbackTest.kt |
Tests consent and retry state. |
Android/src/app/src/test/java/com/ollitert/llm/server/ui/modelmanager/DownloadGateCoordinatorTest.kt |
Tests fallback gating decisions. |
Android/src/app/src/test/java/com/ollitert/llm/server/ui/modelmanager/ConfiguredHfTokenTest.kt |
Tests credential-origin validation. |
Android/src/app/src/test/java/com/ollitert/llm/server/data/repository/ModelStorageRepositoryTest.kt |
Tests mirror partial discovery. |
Android/src/app/src/test/java/com/ollitert/llm/server/data/repository/FakePreferencesRepository.kt |
Supports fallback preference tests. |
Android/src/app/src/test/java/com/ollitert/llm/server/data/repository/DownloadRequestDataTest.kt |
Tests fallback metadata serialization. |
Android/src/app/src/test/java/com/ollitert/llm/server/data/prefs/ModelScopeConsentTest.kt |
Tests consent persistence and revocation. |
Android/src/app/src/test/java/com/ollitert/llm/server/data/download/ModelScopeFallbackTest.kt |
Tests mappings and transient failures. |
Android/src/app/src/main/res/values/strings.xml |
Adds fallback UI strings. |
Android/src/app/src/main/java/com/ollitert/llm/server/worker/ModelFileDownloader.kt |
Implements primary and mirror downloads. Critical (1 vote, lines 167–168): a redirect to a Hugging Face CDN can receive the primary bearer token. |
Android/src/app/src/main/java/com/ollitert/llm/server/worker/DownloadWorker.kt |
Integrates fallback downloads into WorkManager. |
Android/src/app/src/main/java/com/ollitert/llm/server/ui/settings/SettingsDefinitions.kt |
Adds fallback settings registration. |
Android/src/app/src/main/java/com/ollitert/llm/server/ui/settings/ModelSettingsDefs.kt |
Defines the fallback toggle. |
Android/src/app/src/main/java/com/ollitert/llm/server/ui/settings/HfTokenCard.kt |
Renders the fallback setting. |
Android/src/app/src/main/java/com/ollitert/llm/server/ui/modelmanager/ModelManagerViewModel.kt |
Manages consent and retry state. |
Android/src/app/src/main/java/com/ollitert/llm/server/ui/modelmanager/DownloadGateCoordinator.kt |
Handles preflight fallback decisions. |
Android/src/app/src/main/java/com/ollitert/llm/server/ui/modelmanager/components/DownloadAndTryButton.kt |
Adds consent dialog and source status. |
Android/src/app/src/main/java/com/ollitert/llm/server/data/storage/ModelFileManager.kt |
Detects provider-specific partial files. Moderate (1 vote, line 109): progress can report the mirror partial while the next retry resumes from Hugging Face. |
Android/src/app/src/main/java/com/ollitert/llm/server/data/storage/DownloadConstants.kt |
Adds fallback storage and worker keys. |
Android/src/app/src/main/java/com/ollitert/llm/server/data/repository/PreferencesRepository.kt |
Exposes fallback preference access. |
Android/src/app/src/main/java/com/ollitert/llm/server/data/repository/DownloadRepository.kt |
Propagates fallback metadata and status. |
Android/src/app/src/main/java/com/ollitert/llm/server/data/prefs/ServerPrefsNetwork.kt |
Stores fallback consent. |
Android/src/app/src/main/java/com/ollitert/llm/server/data/prefs/ServerPrefs.kt |
Provides preference wrappers. |
Android/src/app/src/main/java/com/ollitert/llm/server/data/model/Model.kt |
Adds fallback status fields. |
Android/src/app/src/main/java/com/ollitert/llm/server/data/download/ModelScopeFallback.kt |
Defines pinned mirrors and failure classification. Moderate (1 vote, line 92): network exceptions are wrapped, preventing prior specific worker error handling. Moderate (1 vote, line 81): lookup ignores query parameters, allowing non-canonical URLs to inherit a mirror. |
Android/src/app/src/main/java/com/ollitert/llm/server/data/allowlist/BoundedHttpFetcher.kt |
Adds retry classification and stricter URL validation. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Restrict mirror lookup to the canonical download query, retain specific network error messages, and keep persisted and active progress tied to the correct provider. Add downloader, worker, storage, gate, and observer regressions while preserving the WorkManager constructor contract. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Comment on lines
+77
to
+78
| } catch (error: IOException) { | ||
| throw ModelScopeDownloadException(failure, error) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Breaking change
No intended breaking change. Fallback is off by default. The minimum Android version, application version, build tooling, and HTTP API remain unchanged.
Proposed change
Keep Hugging Face primary and offer an opt-in ModelScope alternative for supported model downloads interrupted by network or temporary-server failures.
LITERTLMheader, and the mirror digest before completion; remove obsolete partials only for the same artifact. Show the active source and report both provider failures.ModelScope copies are community uploads. Their checksums identify the selected mirror artifacts; they do not establish publisher endorsement or equality with the Hugging Face files. Applicable model licenses still apply.
This is the fallback portion of #42, rebuilt directly on upstream
mainatb49ca661. It contains no Android 11 compatibility work, root Gradle entry point, or AGP/Gradle/JDK upgrade. It can be reviewed and merged independently of the platform change.Screenshots
Not attached yet. Visual changes are the one-time consent dialog, the fallback setting under Hugging Face Token, and the download-source label.
Type of change
Additional information
Independent branch validation used upstream's AGP 9.2.0 and Gradle 9.4.1:
testDevDebugUnitTestandtestStableDebugUnitTest: each completed with 1,612 passed, 1 skipped, and no failures.lintDevDebugandlintStableDebug: no errors. No new development-variant lint findings compared with a clean upstream build.assembleDevDebugpassed; the APK retains minimum API 31, target API 35, and ARM64.The review findings from #42 were evaluated before preparing this PR. Regressions cover HTTP/token scoping, gated access before and during transfers, stale preflight results, cancellation, source-specific resume, obsolete-partial cleanup, and positive bearer-token delivery without forwarding it to the CDN. The checksum fixture now uses an independently calculated literal digest. The original boxed-Byte formatting claim did not reproduce; explicit unsigned formatting follows the existing repository pattern.
All seven pinned endpoints returned bounded 64-byte samples with the expected header and total length from ModelScope's CDN during endpoint checks. These were not complete downloads or tests from the phone's network in China. Earlier physical-device text-serving checks used the combined Android 11 development build, not this standalone APK. Complete on-device fallback, consent UI acceptance, and screenshots remain pending.
Checklist
./gradlew :app:compileStableDebugKotlin)./gradlew lintThe unchecked items retain the remaining acceptance work. Scoped lint and independent regression suites passed, but aggregate
lint, full device fallback, and broader runtime regression have not been established.