release: v6.8.4 - #53
Conversation
…tion fetchDynamicModels previously pruned any managed model not in the latest backend response, including the model the user had just selected. A transient backend gap would silently delete it from AXON_MODELS and fall back to DEFAULT_MODEL_ID. Now skips the currently selected model during reconciliation.
TIP text under the thinking spinner now uses a dedicated info color (#C792EA dark / #7C4DFF light) instead of dim, making it visually distinct. Adds a new info theme token to branding and both themes.
Removes the local assets/orbcode-screenshot.webp and points README to a hosted image for better accessibility and repo size.
There was a problem hiding this comment.
🧪 PR Review is completed: Release bump plus a fix that preserves the user's selected model during dynamic-catalog pruning, and a new info theme token for spinner tips. The pruning guard only reads config.json, so selections made via settings.json or MATTERAI_MODEL are still vulnerable to being pruned.
Skipped files
CHANGELOG.md: Skipped file patternREADME.md: Skipped file patternassets/orbcode-screenshot.webp: File hunk diff too large
⬇️ Low Priority Suggestions (1)
src/api/models.ts (1 suggestion)
Location:
src/api/models.ts(Lines 12-21)🟡 Logic Error
Issue:
loadSettingsModel()only readsconfig.json, but perloadSettings()insrc/config/settings.ts, the effective model selection can also come fromsettings.json(user or project scope —modelis inSETTINGS_KEYS) or theMATTERAI_MODELenv var, which takes precedence over all files. If a user's selected model is set via either of those paths and the backend catalog no longer lists it, the pruning loop at line 476 will still delete it fromAXON_MODELS. The nextloadSettings()then failsisValidAxonModel()and silently resets the user toDEFAULT_MODEL_ID— exactly the behavior this PR intends to prevent.Fix: Check
MATTERAI_MODELfirst (it has highest precedence), then walk the same file precedence asloadSettings():config.json, usersettings.json, project.orbcode/settings.json, returning the firstmodelfound. Wrap each read in its own try/catch so a malformedconfig.jsondoesn't skip the settings.json candidates.Impact: Guarantees the user's actual effective model selection is never pruned, regardless of where it was configured.
- function loadSettingsModel(): string { - try { - const dir = process.env.MATTERAI_CONFIG_DIR || path.join(os.homedir(), ".orbcode") - const raw = fs.readFileSync(path.join(dir, "config.json"), "utf8") - const parsed = JSON.parse(raw) - return typeof parsed.model === "string" ? parsed.model : "" - } catch { - return "" - } - } + function loadSettingsModel(): string { + if (process.env.MATTERAI_MODEL) return process.env.MATTERAI_MODEL; + const dir = process.env.MATTERAI_CONFIG_DIR || path.join(os.homedir(), ".orbcode"); + const candidates = [ + path.join(dir, "config.json"), + path.join(dir, "settings.json"), + path.join(process.cwd(), ".orbcode", "settings.json"), + ]; + for (const file of candidates) { + try { + const parsed = JSON.parse(fs.readFileSync(file, "utf8")); + if (typeof parsed.model === "string") return parsed.model; + } catch { + // missing or malformed file — try the next candidate + } + } + return ""; + }
Release v6.8.4
Fixed
fetchDynamicModelsreconciles the registry against each backend response, but previously pruned any managed model not in the latest fetch — including the model the user had just selected. A transient backend gap (or a model temporarily missing from one/v1/modelsresponse) would delete it fromAXON_MODELS, and the nextloadSettings()would silently fall back toDEFAULT_MODEL_ID. The reconciliation now skips the currently selected model so a user's choice survives across/new,/resume, and mid-session usage refreshes.Changed
#C792EAdark /#7C4DFFlight) so it's clearly distinct from the thinking spinner. Added a newinfotheme token.assets/file.Chore
Checklist
npm run typecheckandnpm run buildpassv6.8.4on main to trigger publish