vibeostheog 0.24.6 → 0.24.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/vibeOS.js +44 -30
  2. package/package.json +3 -3
package/dist/vibeOS.js CHANGED
@@ -4680,7 +4680,6 @@ function _sortByCostAsc(models = []) {
4680
4680
  function buildDeterministicTrinity(models, options = {}) {
4681
4681
  const list = Array.isArray(models) ? models.filter((m) => m && typeof m === "object" && String(m.id || "").trim()) : [];
4682
4682
  if (list.length === 0) return null;
4683
- const selectedTier = String(options.selectedTier || "brain").toLowerCase();
4684
4683
  const selectedModelId = String(options.selectedModelId || "").trim();
4685
4684
  const providerHint = String(options.provider || "").trim();
4686
4685
  const selectedModel = selectedModelId ? list.find((m) => m.id === selectedModelId || normalizeModelId(m.id) === normalizeModelId(selectedModelId)) || null : null;
@@ -4689,14 +4688,15 @@ function buildDeterministicTrinity(models, options = {}) {
4689
4688
  const scoped = providerModels.length > 0 ? providerModels : list;
4690
4689
  const qualityRanked = _sortByQualityDesc(scoped);
4691
4690
  const costRanked = _sortByCostAsc(scoped);
4692
- const selected = selectedModel || qualityRanked[0] || costRanked[0] || scoped[0] || list[0];
4693
- const brain = selectedTier === "medium" || selectedTier === "cheap" || selectedTier === "free" ? selected : qualityRanked[0] || selected;
4694
- const medium = selectedTier === "brain" ? qualityRanked.find((m) => m.id !== brain?.id) || brain || selected : selected;
4695
- const cheap = costRanked[0] || selected;
4691
+ const brain = selectedModel || qualityRanked[0] || costRanked[0] || scoped[0] || list[0];
4692
+ const medium = qualityRanked.find((m) => m.id !== brain?.id) || brain;
4693
+ const freeModel = scoped.find((m) => isModelFree(m.id));
4694
+ const cheap = freeModel || costRanked[0] || medium;
4695
+ const brainClass = isModelFree(brain?.id) ? "free" : classify(brain?.id);
4696
4696
  return {
4697
4697
  provider,
4698
- selected_tier: selectedTier,
4699
- selected_model: selected?.id || selectedModelId || "",
4698
+ selected_tier: brainClass,
4699
+ selected_model: brain?.id || selectedModelId || "",
4700
4700
  brain: brain?.id || "",
4701
4701
  medium: medium?.id || "",
4702
4702
  cheap: cheap?.id || "",
@@ -5545,7 +5545,8 @@ function _refreshModel(directory3) {
5545
5545
  }
5546
5546
  }
5547
5547
  if (!_modelLocked) {
5548
- const cfgModel = readConfig(directory3) || readConfig(getOpenCodeHome()) || "";
5548
+ const activeIsManual = tiersData?.trinity?.[activeSlot]?.manual === true;
5549
+ const cfgModel = activeIsManual ? "" : readConfig(directory3) || readConfig(getOpenCodeHome()) || "";
5549
5550
  if (cfgModel && cfgModel.includes("/") && cfgModel !== currentModel) {
5550
5551
  const oldModel = currentModel;
5551
5552
  const oldTier = currentTier;
@@ -7531,7 +7532,7 @@ function createTrinityTool(deps) {
7531
7532
  const providers = deps._loadOpenCodeProviders();
7532
7533
  const auth = deps._readAuth();
7533
7534
  const models = await deps.discoverAvailableModels(providers, auth);
7534
- const trinity = buildDeterministicTrinity(models, { selectedModelId: deps.currentModel, selectedTier: sel.active_slot || "brain" });
7535
+ const trinity = buildDeterministicTrinity(models, { selectedModelId: deps.currentModel });
7535
7536
  if (trinity && trinity.brain) {
7536
7537
  const probed = {
7537
7538
  brain: models.find((m) => m.id === trinity.brain) || { id: trinity.brain, cost: deps._modelCost(trinity.brain), tier: deps._modelTier(trinity.brain) },
@@ -7667,12 +7668,24 @@ function createTrinityTool(deps) {
7667
7668
  if (!tiers.trinity[slot]) tiers.trinity[slot] = {};
7668
7669
  tiers.trinity[slot].oc = model;
7669
7670
  tiers.trinity[slot].cc = model;
7671
+ tiers.trinity[slot].manual = true;
7670
7672
  const _tmp = deps.TIERS_FILE + ".tmp." + Date.now() + "." + Math.random().toString(36).slice(2, 8);
7671
7673
  deps.writeFileSync(_tmp, JSON.stringify(tiers, null, 2) + "\n");
7672
7674
  deps.renameSync(_tmp, deps.TIERS_FILE);
7673
7675
  } catch (e) {
7674
7676
  return `\u274C Failed to write model to tiers: ${e.message}`;
7675
7677
  }
7678
+ } else {
7679
+ try {
7680
+ const tiers = deps.safeJsonParse(deps.readFileSync(deps.TIERS_FILE, "utf-8"));
7681
+ if (tiers?.trinity?.[slot]?.manual) {
7682
+ delete tiers.trinity[slot].manual;
7683
+ const _tmp = deps.TIERS_FILE + ".tmp." + Date.now() + "." + Math.random().toString(36).slice(2, 8);
7684
+ deps.writeFileSync(_tmp, JSON.stringify(tiers, null, 2) + "\n");
7685
+ deps.renameSync(_tmp, deps.TIERS_FILE);
7686
+ }
7687
+ } catch {
7688
+ }
7676
7689
  }
7677
7690
  let targetModel = "";
7678
7691
  try {
@@ -7889,8 +7902,7 @@ Lock is per-session (resets on restart).`;
7889
7902
  } catch {
7890
7903
  }
7891
7904
  const selectedModel = deps.currentModel || existing?.selection?.selected_model || existing?.selection?.executed_model || "";
7892
- const selectedTier = existing?.selection?.active_slot || "brain";
7893
- const trinity = buildDeterministicTrinity(discovered, { selectedModelId: selectedModel, selectedTier });
7905
+ const trinity = buildDeterministicTrinity(discovered, { selectedModelId: selectedModel });
7894
7906
  const brain = trinity?.brain || existing?.trinity?.brain?.oc || selectedModel || "";
7895
7907
  const medium = trinity?.medium || existing?.trinity?.medium?.oc || brain;
7896
7908
  const cheap = trinity?.cheap || existing?.trinity?.cheap?.oc || medium || brain;
@@ -7909,14 +7921,14 @@ Lock is per-session (resets on restart).`;
7909
7921
  tiers.selection.thinking_level = "off";
7910
7922
  tiers.selection.setup_completed_at = now;
7911
7923
  tiers.selection.selected_provider = trinity?.provider || resolveExecutionIdentity(selectedModel, deps.directory)?.provider || "";
7912
- tiers.selection.selected_quality_tier = trinity?.selected_tier || selectedTier || "brain";
7924
+ tiers.selection.selected_quality_tier = trinity?.selected_tier || "brain";
7913
7925
  tiers.selection.selected_model = trinity?.selected_model || selectedModel || "";
7914
7926
  tiers.selection.executed_provider = tiers.selection.selected_provider;
7915
7927
  tiers.selection.executed_quality_tier = tiers.selection.selected_quality_tier;
7916
7928
  tiers.selection.executed_model = tiers.selection.selected_model;
7917
- if (brain) tiers.trinity.brain = { oc: brain, cc: deps.modelToCcAlias(brain) };
7918
- if (medium) tiers.trinity.medium = { oc: medium, cc: deps.modelToCcAlias(medium) };
7919
- if (cheap) tiers.trinity.cheap = { oc: cheap, cc: deps.modelToCcAlias(cheap) };
7929
+ if (brain && existing?.trinity?.brain?.manual !== true) tiers.trinity.brain = { oc: brain, cc: deps.modelToCcAlias(brain) };
7930
+ if (medium && existing?.trinity?.medium?.manual !== true) tiers.trinity.medium = { oc: medium, cc: deps.modelToCcAlias(medium) };
7931
+ if (cheap && existing?.trinity?.cheap?.manual !== true) tiers.trinity.cheap = { oc: cheap, cc: deps.modelToCcAlias(cheap) };
7920
7932
  deps.mkdirSync(dirname9(deps.TIERS_FILE), { recursive: true });
7921
7933
  deps.writeFileSync(deps.TIERS_FILE, JSON.stringify(tiers, null, 2) + "\n");
7922
7934
  if (typeof deps._refreshModel === "function") deps._refreshModel(deps.directory);
@@ -8249,8 +8261,7 @@ ${L.repeat(40)}`);
8249
8261
  const auth = deps._readAuth();
8250
8262
  const models = await deps.discoverAvailableModels(providers, auth);
8251
8263
  const selectedModel = deps.currentModel || deps.loadSelection?.().selected_model || deps.loadSelection?.().executed_model || "";
8252
- const selectedTier = deps.loadSelection?.().active_slot || "brain";
8253
- const trinity = buildDeterministicTrinity(models, { selectedModelId: selectedModel, selectedTier });
8264
+ const trinity = buildDeterministicTrinity(models, { selectedModelId: selectedModel });
8254
8265
  if (!trinity) {
8255
8266
  return "\u274C No models discovered from any configured provider.";
8256
8267
  }
@@ -8271,14 +8282,15 @@ ${L.repeat(40)}`);
8271
8282
  }
8272
8283
  try {
8273
8284
  const tiers = deps.safeJsonParse(deps.readFileSync(deps.TIERS_FILE, "utf-8"));
8285
+ const existing = tiers.trinity || {};
8274
8286
  tiers.trinity = {
8275
- brain: { oc: probed.brain.id, cc: deps.modelToCcAlias(probed.brain.id) },
8276
- medium: { oc: probed.medium.id, cc: deps.modelToCcAlias(probed.medium.id) },
8277
- cheap: { oc: probed.cheap.id, cc: deps.modelToCcAlias(probed.cheap.id) }
8287
+ brain: existing.brain?.manual === true ? { ...existing.brain } : { oc: probed.brain.id, cc: deps.modelToCcAlias(probed.brain.id) },
8288
+ medium: existing.medium?.manual === true ? { ...existing.medium } : { oc: probed.medium.id, cc: deps.modelToCcAlias(probed.medium.id) },
8289
+ cheap: existing.cheap?.manual === true ? { ...existing.cheap } : { oc: probed.cheap.id, cc: deps.modelToCcAlias(probed.cheap.id) }
8278
8290
  };
8279
8291
  tiers.selection ??= {};
8280
8292
  tiers.selection.selected_provider = trinity.provider || resolveExecutionIdentity(selectedModel, deps.directory)?.provider || "";
8281
- tiers.selection.selected_quality_tier = trinity.selected_tier || selectedTier || "brain";
8293
+ tiers.selection.selected_quality_tier = trinity.selected_tier || "brain";
8282
8294
  tiers.selection.selected_model = trinity.selected_model || selectedModel || "";
8283
8295
  tiers.selection.executed_provider = tiers.selection.selected_provider;
8284
8296
  tiers.selection.executed_quality_tier = tiers.selection.selected_quality_tier;
@@ -8294,11 +8306,14 @@ ${L.repeat(40)}`);
8294
8306
  } catch (e) {
8295
8307
  console.error("[vibeOS] auto-activate brain failed:", e.message);
8296
8308
  }
8309
+ const _finalTiers = deps.safeJsonParse(deps.readFileSync(deps.TIERS_FILE, "utf-8"));
8310
+ const _trinity = _finalTiers?.trinity || {};
8311
+ const _pMan = (s) => _trinity[s]?.manual === true ? " [manual, preserved]" : "";
8297
8312
  const lines = [
8298
8313
  `\u{1F50D} Auto-detected models from provider: ${trinity.provider || "unknown"}`,
8299
- " \u{1F9E0} brain \u2192 " + probed.brain.id + " (tier: " + probed.brain.tier + ", $" + probed.brain.cost.toFixed(4) + "/turn) \u2705",
8300
- " \u2699 medium \u2192 " + probed.medium.id + " (tier: " + probed.medium.tier + ", $" + probed.medium.cost.toFixed(4) + "/turn) \u2705",
8301
- " \u26A1 cheap \u2192 " + probed.cheap.id + " (tier: " + probed.cheap.tier + ", $" + probed.cheap.cost.toFixed(4) + "/turn) \u2705"
8314
+ " \u{1F9E0} brain \u2192 " + probed.brain.id + " (tier: " + probed.brain.tier + ", $" + probed.brain.cost.toFixed(4) + "/turn) \u2705" + _pMan("brain"),
8315
+ " \u2699 medium \u2192 " + probed.medium.id + " (tier: " + probed.medium.tier + ", $" + probed.medium.cost.toFixed(4) + "/turn) \u2705" + _pMan("medium"),
8316
+ " \u26A1 cheap \u2192 " + probed.cheap.id + " (tier: " + probed.cheap.tier + ", $" + probed.cheap.cost.toFixed(4) + "/turn) \u2705" + _pMan("cheap")
8302
8317
  ];
8303
8318
  if (failed.length > 0) {
8304
8319
  lines.push("", "Probe failures (skipped):");
@@ -13126,15 +13141,14 @@ async function _seedModelTiersIfMissing(directory3) {
13126
13141
  discovered = await discoverAvailableModels(providers, auth);
13127
13142
  } catch {
13128
13143
  }
13129
- let ranked = null;
13144
+ let trinity = null;
13130
13145
  try {
13131
- ranked = classifyAndRankModels(discovered);
13146
+ trinity = buildDeterministicTrinity(discovered, { selectedModelId: currentModel });
13132
13147
  } catch {
13133
13148
  }
13134
- const fallbackModel = currentModel || readConfig(directory3) || readConfig(getOpenCodeHome3()) || process?.env?.OPENCODE_MODEL || "";
13135
- let brain = ranked?.brain?.id || fallbackModel;
13136
- let medium = ranked?.medium?.id || brain;
13137
- let cheap = ranked?.cheap?.id || medium || brain;
13149
+ let brain = trinity?.brain || currentModel || readConfig(directory3) || readConfig(getOpenCodeHome3()) || process?.env?.OPENCODE_MODEL || "";
13150
+ let medium = trinity?.medium || brain;
13151
+ let cheap = trinity?.cheap || medium || brain;
13138
13152
  if (!brain) {
13139
13153
  brain = "deepseek/deepseek-v4-pro";
13140
13154
  medium = "deepseek/deepseek-v4-flash";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibeostheog",
3
- "version": "0.24.6",
3
+ "version": "0.24.7",
4
4
  "description": "Cost-aware delegation enforcer for OpenCode. Tracks model usage, routes Task subagents to cheaper tiers, surfaces cumulative savings in chat. Includes research audit, reporting framework, project memory, progressive scratchpad decadence, and trinity CLI for brain/medium/cheap slot switching.",
5
5
  "scripts": {
6
6
  "release": "node scripts/release.mjs",
@@ -32,7 +32,7 @@
32
32
  "type": "module",
33
33
  "main": "./dist/vibeOS.js",
34
34
  "bin": {
35
- "vibeostheog": "./bin/setup.js"
35
+ "vibeostheog": "bin/setup.js"
36
36
  },
37
37
  "exports": {
38
38
  ".": "./dist/vibeOS.js",
@@ -71,7 +71,7 @@
71
71
  ],
72
72
  "repository": {
73
73
  "type": "git",
74
- "url": "https://github.com/DrunkkToys/vibeOS.git"
74
+ "url": "git+https://github.com/DrunkkToys/vibeOS.git"
75
75
  },
76
76
  "homepage": "https://github.com/DrunkkToys/vibeOS#readme",
77
77
  "bugs": {