From 1245a64a728160f8ef040ac6eaf8f03b1bbf63c7 Mon Sep 17 00:00:00 2001 From: rferrari <495887+rferrari@users.noreply.github.com> Date: Sat, 10 Oct 2026 18:55:27 -0300 Subject: [PATCH] feat(models): stop suggesting Phi-3.5-mini; it stays listed where it's installed --- src/models/manifest.test.ts | 9 +++++++++ src/models/manifest.ts | 11 +++++++++++ src/ui-android/ModelCatalogScreen.tsx | 4 ++-- src/ui-android/ModelSetupScreen.tsx | 4 ++-- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/models/manifest.test.ts b/src/models/manifest.test.ts index c04cfb0a5..175faf4be 100644 --- a/src/models/manifest.test.ts +++ b/src/models/manifest.test.ts @@ -11,6 +11,7 @@ import { totalManifestBytes, isPinnedSourceUrl, displayNameOf, + isListed, } from "./manifest"; describe("totalManifestBytes", () => { @@ -69,6 +70,14 @@ describe("MODEL_CATALOG", () => { expect(m.sourceUrl).toMatch(/^https:\/\//); } }); + + it("no longer suggests Phi-3.5-mini, but keeps it listed where it's installed", () => { + const phi = MODEL_CATALOG.find((m) => m.id === "phi-3.5-mini-instruct-q4km")!; + expect(isListed(phi, false)).toBe(false); + expect(isListed(phi, true)).toBe(true); + // Nothing the setup or the app needs is hidden. + for (const m of [...REQUIRED_MODELS, ...ANSWER_MODELS]) expect(m.hidden).toBeFalsy(); + }); }); describe("TIERS", () => { diff --git a/src/models/manifest.ts b/src/models/manifest.ts index a08c7472f..f4493f3c1 100644 --- a/src/models/manifest.ts +++ b/src/models/manifest.ts @@ -53,6 +53,11 @@ export interface CatalogModel { * "compact". Setup is complete with the required assets plus ONE of these. */ answerTier?: "default" | "compact"; + /** + * No longer suggested: the catalog lists it only on a phone that already has it, where it keeps working + * (Phi-3.5-mini: ~4 tok/s on the X6 and it invented citations in our device benchmark). + */ + hidden?: boolean; /** * Ships inside the app build itself (see plugins/withBundledModels.js). * Not used by default — see module doc comment — but kept available. @@ -96,6 +101,11 @@ export const RAM_BUDGET_BYTES = 12 * 1024 * 1024 * 1024; // 12GB * on the phone after every download and import (ModelManager). Run * `npm run manifest:verify` to re-check sizes and hashes against the hosts. */ +/** Whether a catalog entry is offered: everything but a `hidden` one, which shows only once it's on the phone. */ +export function isListed(m: Pick, present: boolean): boolean { + return !m.hidden || present; +} + export const MODEL_CATALOG: CatalogModel[] = [ { id: "phi-3.5-mini-instruct-q4km", @@ -110,6 +120,7 @@ export const MODEL_CATALOG: CatalogModel[] = [ license: "MIT", description: "3.8B dense. Most complete comparisons and syntheses in our device benchmark, but slow (~4 tok/s). ~2.4GB.", required: false, + hidden: true, capabilities: { roles: ["general", "reasoning"] }, }, { diff --git a/src/ui-android/ModelCatalogScreen.tsx b/src/ui-android/ModelCatalogScreen.tsx index 80d4f2535..f08eed40b 100644 --- a/src/ui-android/ModelCatalogScreen.tsx +++ b/src/ui-android/ModelCatalogScreen.tsx @@ -3,7 +3,7 @@ import { View, StyleSheet, FlatList, Pressable, ScrollView } from "react-native" import { Text } from "./components/AppText"; import { impact, ImpactFeedbackStyle } from "../services/haptics"; import { useTranslation } from "react-i18next"; -import { MODEL_CATALOG, CatalogModel, AssetKind } from "../models/manifest"; +import { MODEL_CATALOG, CatalogModel, AssetKind, isListed } from "../models/manifest"; import { ModelManager } from "../models/ModelManager"; import { getActiveModelId, setActiveModelId } from "../models/settings"; import { @@ -114,7 +114,7 @@ export function ModelCatalogScreen({ onClose }: Props) { [refreshStatus, t] ); - const allModels = [...MODEL_CATALOG, ...discoveredModels]; + const allModels = [...MODEL_CATALOG.filter((m) => isListed(m, presence[m.id] ?? false)), ...discoveredModels]; const filteredModels = allModels.filter((m) => { if (selectedFilter === "all") return true; if (selectedFilter === "llm") return m.kind === "llm"; diff --git a/src/ui-android/ModelSetupScreen.tsx b/src/ui-android/ModelSetupScreen.tsx index 2197b8557..60f99f04b 100644 --- a/src/ui-android/ModelSetupScreen.tsx +++ b/src/ui-android/ModelSetupScreen.tsx @@ -12,7 +12,7 @@ import { import { Text } from "./components/AppText"; import { impact, notification, ImpactFeedbackStyle, NotificationFeedbackType, setHapticsEnabledCache } from "../services/haptics"; import { useTranslation } from "react-i18next"; -import { MODEL_CATALOG, CatalogModel, AssetKind, CORPUS_CATALOG, REQUIRED_MODELS } from "../models/manifest"; +import { MODEL_CATALOG, CatalogModel, AssetKind, CORPUS_CATALOG, REQUIRED_MODELS, isListed } from "../models/manifest"; import { llamaEngine } from "../inference/LlamaEngine"; import { ModelManager } from "../models/ModelManager"; import { getActiveModelId, setActiveModelId, getHapticsEnabled, setHapticsEnabled } from "../models/settings"; @@ -244,7 +244,7 @@ export function ModelSetupScreen(props: Props) { {t("modelSetupScreen.installedModels")} m.kind === "llm" || m.kind === "embedding"), + ...MODEL_CATALOG.filter((m) => (m.kind === "llm" || m.kind === "embedding") && isListed(m, presence[m.id] ?? false)), // A search result for a file that's now in the curated catalog would be listed twice. ...discoveredModels.filter((d) => !MODEL_CATALOG.some((c) => c.filename === d.filename)), ]}