Files
oh-my-pi/packages/coding-agent/src/tiny/models.ts
T
can1357 14bd572f49 refactor(shake): removed shake-summary mode and local-model compressor
- Dropped `summarizeShakeRegions`, the shake-summary prompt, and related types.
- Removed `shake-summary` compaction strategy and `providers.shakeSummaryModel` setting.
- Migrated existing `shake-summary` configs to plain `shake` on load.
- Simplified `/shake` to `elide` and `images` modes only.
2026-05-31 14:14:37 +02:00

243 lines
8.7 KiB
TypeScript

/** Default session-title model: the online pi/smol path (no local download / on-device inference). */
export const ONLINE_TINY_TITLE_MODEL_KEY = "online";
/** Local model the `tiny-models` CLI downloads when none is named. Not the session-title default — that is {@link ONLINE_TINY_TITLE_MODEL_KEY}. */
export const DEFAULT_TINY_TITLE_LOCAL_MODEL_KEY = "lfm2-700m";
export interface TinyTitleLocalModelSpec {
key: string;
repo: string;
dtype: "q4";
label: string;
description: string;
contextNote: string;
}
export const TINY_TITLE_LOCAL_MODELS = [
{
key: "lfm2-350m",
repo: "onnx-community/LFM2-350M-ONNX",
dtype: "q4",
label: "LFM2 350M",
description: "Recommended local model; best speed/quality balance, about 212 MB cached.",
contextNote: "Best local default from the title-generation spike.",
},
{
key: "qwen3-0.6b",
repo: "onnx-community/Qwen3-0.6B-ONNX",
dtype: "q4",
label: "Qwen3 0.6B",
description: "Most robust local option; slower first load, about 500 MB cached.",
contextNote: "Use when title quality matters more than local startup cost.",
},
{
key: "gemma-270m",
repo: "onnx-community/gemma-3-270m-it-ONNX",
dtype: "q4",
label: "Gemma 270M",
description: "Smallest viable local option; lower quality, lowest cache footprint.",
contextNote: "Use on constrained machines that still need local titles.",
},
{
key: "qwen2.5-0.5b",
repo: "onnx-community/Qwen2.5-0.5B-Instruct",
dtype: "q4",
label: "Qwen2.5 0.5B",
description: "Balanced local fallback; moderate quality and cache footprint.",
contextNote: "Useful when Qwen3 is too heavy but Gemma quality is insufficient.",
},
{
key: "lfm2-700m",
repo: "onnx-community/LFM2-700M-ONNX",
dtype: "q4",
label: "LFM2 700M",
description: "Highest-quality local option; larger and slower than LFM2 350M.",
contextNote: "Use when local title quality is preferred over startup cost.",
},
] as const satisfies readonly TinyTitleLocalModelSpec[];
export const TINY_TITLE_MODEL_VALUES = [
ONLINE_TINY_TITLE_MODEL_KEY,
"lfm2-350m",
"qwen3-0.6b",
"gemma-270m",
"qwen2.5-0.5b",
"lfm2-700m",
] as const;
export type TinyTitleModelKey = (typeof TINY_TITLE_MODEL_VALUES)[number];
export type TinyTitleLocalModelKey = (typeof TINY_TITLE_LOCAL_MODELS)[number]["key"];
type MissingTinyTitleModelValue = Exclude<
typeof ONLINE_TINY_TITLE_MODEL_KEY | TinyTitleLocalModelKey,
TinyTitleModelKey
>;
type ExtraTinyTitleModelValue = Exclude<TinyTitleModelKey, typeof ONLINE_TINY_TITLE_MODEL_KEY | TinyTitleLocalModelKey>;
const TINY_TITLE_MODEL_VALUES_MATCH_REGISTRY: MissingTinyTitleModelValue extends never
? ExtraTinyTitleModelValue extends never
? true
: never
: never = true;
void TINY_TITLE_MODEL_VALUES_MATCH_REGISTRY;
export const TINY_TITLE_MODEL_OPTIONS = [
{
value: ONLINE_TINY_TITLE_MODEL_KEY,
label: "Online (pi/smol)",
description: "Current online title generation path; no local model download or on-device inference.",
},
...TINY_TITLE_LOCAL_MODELS.map(model => ({
value: model.key,
label: model.label,
description: model.description,
})),
] satisfies ReadonlyArray<{ value: TinyTitleModelKey; label: string; description: string }>;
export function isTinyTitleLocalModelKey(value: string): value is TinyTitleLocalModelKey {
return TINY_TITLE_LOCAL_MODELS.some(model => model.key === value);
}
export function getTinyTitleModelSpec(key: TinyTitleLocalModelKey): (typeof TINY_TITLE_LOCAL_MODELS)[number] {
const spec = TINY_TITLE_LOCAL_MODELS.find(model => model.key === key);
if (!spec) throw new Error(`Unknown tiny title model: ${key}`);
return spec;
}
/** Default memory model: the online path (the configured smol / remote LLM; no local download). */
export const ONLINE_MEMORY_MODEL_KEY = "online";
/** Recommended local model for memory tasks when none is named. */
export const DEFAULT_MEMORY_LOCAL_MODEL_KEY = "qwen3-1.7b";
/**
* Local models for Mnemopi memory tasks (fact extraction + consolidation).
* These are larger (1B-1.7B) than the title models: structured extraction and
* faithful summarization need more capacity than 3-6 word titles. All q4.
* Ranking/recipe rationale lives in docs/local-models.md.
*/
export const TINY_MEMORY_LOCAL_MODELS = [
{
key: "qwen3-1.7b",
repo: "onnx-community/Qwen3-1.7B-ONNX",
dtype: "q4",
label: "Qwen3 1.7B",
description:
"Recommended; most disciplined extraction (ignores chit-chat), good consolidation, about 1.1 GB cached.",
contextNote: "Best single-model pick for memory from the local experiment.",
},
{
key: "gemma-3-1b",
repo: "onnx-community/gemma-3-1b-it-ONNX",
dtype: "q4",
label: "Gemma 3 1B",
description: "Best consolidation/dedup; lighter footprint, but leaks small talk during extraction.",
contextNote: "Use when consolidation quality and size matter most.",
},
{
key: "qwen2.5-1.5b",
repo: "onnx-community/Qwen2.5-1.5B-Instruct",
dtype: "q4",
label: "Qwen2.5 1.5B",
description: "Best extraction granularity (atomic facts); weaker consolidation.",
contextNote: "Use when fine-grained, deduplicatable facts matter more than summaries.",
},
{
key: "lfm2-1.2b",
repo: "onnx-community/LFM2-1.2B-ONNX",
dtype: "q4",
label: "LFM2 1.2B",
description: "Fastest load; solid all-rounder, slightly noisier extraction labels.",
contextNote: "Use when local startup cost is the priority.",
},
] as const satisfies readonly TinyTitleLocalModelSpec[];
export const TINY_MEMORY_MODEL_VALUES = [
ONLINE_MEMORY_MODEL_KEY,
"qwen3-1.7b",
"gemma-3-1b",
"qwen2.5-1.5b",
"lfm2-1.2b",
] as const;
export type TinyMemoryModelKey = (typeof TINY_MEMORY_MODEL_VALUES)[number];
export type TinyMemoryLocalModelKey = (typeof TINY_MEMORY_LOCAL_MODELS)[number]["key"];
type MissingTinyMemoryModelValue = Exclude<
typeof ONLINE_MEMORY_MODEL_KEY | TinyMemoryLocalModelKey,
TinyMemoryModelKey
>;
type ExtraTinyMemoryModelValue = Exclude<TinyMemoryModelKey, typeof ONLINE_MEMORY_MODEL_KEY | TinyMemoryLocalModelKey>;
const TINY_MEMORY_MODEL_VALUES_MATCH_REGISTRY: MissingTinyMemoryModelValue extends never
? ExtraTinyMemoryModelValue extends never
? true
: never
: never = true;
void TINY_MEMORY_MODEL_VALUES_MATCH_REGISTRY;
export const TINY_MEMORY_MODEL_OPTIONS = [
{
value: ONLINE_MEMORY_MODEL_KEY,
label: "Online (smol/remote)",
description:
"Use the configured Mnemopi LLM mode (smol or remote); no local model download or on-device inference.",
},
...TINY_MEMORY_LOCAL_MODELS.map(model => ({
value: model.key,
label: model.label,
description: model.description,
})),
] satisfies ReadonlyArray<{ value: TinyMemoryModelKey; label: string; description: string }>;
export function isTinyMemoryLocalModelKey(value: string): value is TinyMemoryLocalModelKey {
return TINY_MEMORY_LOCAL_MODELS.some(model => model.key === value);
}
export function getTinyMemoryModelSpec(key: TinyMemoryLocalModelKey): (typeof TINY_MEMORY_LOCAL_MODELS)[number] {
const spec = TINY_MEMORY_LOCAL_MODELS.find(model => model.key === key);
if (!spec) throw new Error(`Unknown tiny memory model: ${key}`);
return spec;
}
/** Any local model key (title or memory), used by the shared inference worker. */
export type TinyLocalModelKey = TinyTitleLocalModelKey | TinyMemoryLocalModelKey;
/** Resolve a local model spec by key across both the title and memory registries. */
export function getTinyLocalModelSpec(key: string): TinyTitleLocalModelSpec | undefined {
return (
TINY_TITLE_LOCAL_MODELS.find(model => model.key === key) ??
TINY_MEMORY_LOCAL_MODELS.find(model => model.key === key)
);
}
export function isTinyLocalModelKey(value: string): value is TinyLocalModelKey {
return getTinyLocalModelSpec(value) !== undefined;
}
/** Combined local model registry (title + memory) for the shared tiny-models CLI. */
export const TINY_LOCAL_MODELS = [
...TINY_TITLE_LOCAL_MODELS,
...TINY_MEMORY_LOCAL_MODELS,
] as const satisfies readonly TinyTitleLocalModelSpec[];
/**
* Difficulty-classifier model for the `auto` thinking level. Defaults to the
* online smol path; the local options reuse the memory-model registry because
* the shared worker's `complete()` only accepts memory local keys, and the
* 1B+ memory models classify coding difficulty far more reliably than the
* sub-1B title models.
*/
export const ONLINE_AUTO_THINKING_MODEL_KEY = ONLINE_MEMORY_MODEL_KEY;
export const AUTO_THINKING_MODEL_VALUES = TINY_MEMORY_MODEL_VALUES;
export type AutoThinkingModelKey = TinyMemoryModelKey;
export const AUTO_THINKING_MODEL_OPTIONS = [
{
value: ONLINE_AUTO_THINKING_MODEL_KEY,
label: "Online (smol)",
description: "Classify prompt difficulty with the online smol model; no local download or on-device inference.",
},
...TINY_MEMORY_LOCAL_MODELS.map(model => ({
value: model.key,
label: model.label,
description: model.description,
})),
] satisfies ReadonlyArray<{ value: AutoThinkingModelKey; label: string; description: string }>;