A disambiguation index, not a spec. One line per term — what it means, what it's not — and a
→ pointer to the canonical definition. When the word and the definition disagree, the pointer
wins. Deliberately lean: only the terms that actually cause miscommunication live here — add a
line when a new one does.
- omo / OMO (oh-my-openagent) — the agent framework whose config oModel edits; the source of "what omo suggests." Bundled as a snapshot — never run or imported at runtime. → AGENTS.md "What this is"
- oModel /
omodel— this tool. Brand "oModel", command + Python packageomodel. - opencode — ⚠ overloaded: usually the CLI that reports "what you have", but also the name
of a provider (a gateway). Say "the
opencodeCLI" vs "theopencodeprovider". → catalog.py
- target — one editable slot. Four id shapes:
agent:<name>,agent:<name>.ultrawork,agent:<name>.compaction,cat:<name>(== the#targetsoption IDs). → CONTRACTS.md "Shared shapes" - agent / category — a named omo agent (sisyphus, hephaestus…; 11) / task category (deep, quick…; 8). → DESIGN §Problem
- sub-target —
ultrawork(model swapped in on anulwmessage; Sisyphus-only — omo honors it on no other agent) orcompaction(auto-summary model, any agent), nested under an agent. Agents only; categories have none. → DESIGN §Textual contract, app.py_ULTRAWORK_AGENTS
- fallbackChain — omo's ordered (priority) list of recommended models for a target. → suggestions.py
- candidate / candidate-row — the dict
resolve.candidates()yields andapp.pyrenders, one row per serving provider. The integration seam. → CONTRACTS.md (frozen), resolve.py - exact vs same-line substitute — exact = a connected provider serves the model, allowing a
trailing date stamp / sub-version tag (see noise suffix); substitute = no exact, so the
newest connected model of the same family (
glm-5→glm-5.1) — but never across a Claude line (haiku ≠ sonnet ≠ fable ≠ mythos). → resolve.pycandidates - noise suffix vs real modifier — a trailing id token an available id carries that the bare omo
id lacks. Noise (stripped when matching) = a date/build stamp (
…-20251001) or an unknown sub-version tag (…-jibao). Real modifier (kept; a distinct model) = a token omo itself uses in a chain id (mini,fast,flash,nano, …) — sogpt-5.4-mini-fast≠gpt-5.4-mini. NOT the same as a variant (reasoning mode). → resolve.py_matches_omo_id/real_tokens
- provider — the
provider/prefix that serves a model (openai,zhipuai,opencode…); an availability/routing ID. The set you're connected to is connected (first-seen order, never a set). → catalog.py - vendor — the company behind a family (via
FAMILY_VENDOR). Used only to classify providers. → suggestions.pyFAMILY_VENDOR - family — a model line (15: gpt-5, claude-opus, glm, kimi…), via
detect_family(a port of omo's heuristic). → suggestions.pydetect_family - gateway vs dedicated — gateway = serves ≥2 vendors (aggregator, e.g.
opencode); dedicated = single-vendor (e.g.openai). Dedicated sorts first in the pick list. → resolve.pyvendors_served/_ordered_providers
- variant — a model's reasoning-effort/mode (
max,high,thinking…). Offerings come from cachedopencode --verbose(Catalog.variants_for) — the source of truth for the pickers; the bundled family registry is now only the fallback for the omo-suggestion⚠warn when opencode reports nothing for that model. Family detection itself stays heuristic-only —--verbose.familyis never read. Anonevariant is treated as no variant: identical to the synthetic(none)clear row, so the pickers never offer it and saving drops thevariantkey (_is_no_variant). → DESIGN decision #14 - warn-but-allow (⚠) — oModel flags but never blocks you (bad variant, unavailable add). One hard
exception: Hephaestus is GPT-only (non-GPT blocked). → DESIGN decision #5, app.py
_GPT_ONLY_AGENTS
- edit-in-place / text-preserving save — the write splices only the top-level
agents/categoriesspans clean (no comments inside them) and keeps everything else byte-for-byte — other keys, formatting, and any comments / commented-out config outside those two. → config_io.pyrender - active-only / clean config — the canonical clean form (
serialize): JSON, no comments. Used for dirtiness + as the from-scratch/fallback writer; the first save drops omo's commented palette inside agents/categories (preserved verbatim inoriginal.jsonc). → config_io.pyserialize - backup vs history — backup = verbatim
.backup/<ts>.jsonccopy at each save (on disk, cross-session,--restore); history = the in-session undo/redo stack (u/ctrl+r). → config_io.py / history.py - the two refreshes —
--refresh-omorebuilds "what omo suggests" (bun + omo checkout);--refresh-models/rrebuilds "what you have" (re-runs opencode, busts the cache). → refresh.py vs catalog.refresh() - cache — the 24h on-disk cache of
opencodeCLI output (~/.cache/omodel). A perf layer, not an availability source. → cache.py
- DESIGN.md = the spec / design-of-record · CONTRACTS.md = frozen shapes + signatures · this file = the vocabulary index that points at both.