vibeostheog 0.19.8 → 0.19.9

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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 0.19.9
2
+ - fix: show live run model in footer
3
+
1
4
  ## 0.19.8
2
5
  - fix: shorten live footer alerts
3
6
  - fix: add /g flag and \b word boundaries to ERROR_SIGNAL_WORDS regex
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibeostheog",
3
- "version": "0.19.8",
3
+ "version": "0.19.9",
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",
package/src/index.js CHANGED
@@ -3802,7 +3802,7 @@ var MODEL_USD_PER_TURN = {
3802
3802
  "haiku": 22e-4,
3803
3803
  // ── DeepSeek (OC platform + OpenRouter) ──────────────────
3804
3804
  "deepseek/deepseek-v4-pro": 57e-5,
3805
- "deepseek/deepseek-v4-flash": 0.00013,
3805
+ "deepseek/deepseek-v4-flash": 182e-6,
3806
3806
  "deepseek/deepseek-chat": 182e-6,
3807
3807
  "deepseek-chat": 182e-6,
3808
3808
  "deepseek/deepseek-v3": 182e-6,
@@ -8624,16 +8624,17 @@ async function _appendFooter(input, output, directory3) {
8624
8624
  let _footerStress = 0;
8625
8625
  if (latestUserIntent)
8626
8626
  _footerStress = scoreStress(latestUserIntent);
8627
- if (!currentModel) {
8628
- try {
8629
- const cfg = await client.config.get("model");
8630
- if (cfg) {
8631
- setCurrentModel(String(cfg));
8632
- setCurrentTier(classify(String(cfg)));
8627
+ try {
8628
+ const cfg = await client.config.get("model");
8629
+ if (cfg) {
8630
+ const cfgModel = String(cfg);
8631
+ if (cfgModel !== currentModel) {
8632
+ setCurrentModel(cfgModel);
8633
+ setCurrentTier(classify(cfgModel));
8633
8634
  console.error(`[vibeOS] client-detected model: ${currentModel} (tier=${currentTier})`);
8634
8635
  }
8635
- } catch {
8636
8636
  }
8637
+ } catch {
8637
8638
  }
8638
8639
  try {
8639
8640
  const messageID = input?.messageID || input?.messageId || input?.message?.id || output?.messageID || output?.messageId || output?.message?.id || null;
@@ -8650,12 +8651,23 @@ async function _appendFooter(input, output, directory3) {
8650
8651
  const sessionSlot = loadSessionSlot(_OC_SID5);
8651
8652
  const slot = sessionSlot || loadSelection3().active_slot || "brain";
8652
8653
  const brainModel = slot === "brain" ? TRINITY_BRAIN || currentModel : slot === "medium" ? TRINITY_MEDIUM || currentModel : TRINITY_CHEAP || currentModel || "";
8653
- let modelTag = `[${shortModelName(brainModel)}]`;
8654
+ let liveModel = "";
8655
+ try {
8656
+ const cfg = await client.config.get("model");
8657
+ if (cfg)
8658
+ liveModel = String(cfg);
8659
+ } catch {
8660
+ }
8661
+ if (!liveModel) {
8662
+ liveModel = readConfig(directory3) || readConfig(join14(process.env.HOME || "", ".config", "opencode")) || process?.env?.OPENCODE_MODEL || "";
8663
+ }
8664
+ const displayModel = liveModel || currentModel || brainModel;
8665
+ let modelTag = `[${shortModelName(displayModel)}]`;
8654
8666
  const _workerModel = slot === "brain" ? TRINITY_MEDIUM : null;
8655
8667
  const totalTurns = (sesModelTurns?.brain || 0) + (sesModelTurns?.worker || 0);
8656
8668
  if (_workerModel && _workerModel !== brainModel) {
8657
8669
  const brainPct = Math.round((sesModelTurns?.brain || 0) / (totalTurns || 1) * 100);
8658
- modelTag = `[${shortModelName(brainModel)} ${brainPct}% \u2192 ${shortModelName(_workerModel)} ${100 - brainPct}%]`;
8670
+ modelTag = `[${shortModelName(displayModel)} ${brainPct}% \u2192 ${shortModelName(_workerModel)} ${100 - brainPct}%]`;
8659
8671
  }
8660
8672
  _autoReportCount = (_autoReportCount || 0) + 1;
8661
8673
  if (_autoReportCount % 5 === 0) {
@@ -8718,19 +8730,9 @@ async function _appendFooter(input, output, directory3) {
8718
8730
  if (stripped !== text)
8719
8731
  return;
8720
8732
  const ltTotal = ltTasks + ltCache;
8721
- const modeVerbMap = {
8722
- balanced: "routing",
8723
- budget: "saving",
8724
- quality: "focusing",
8725
- speed: "moving",
8726
- longrun: "pacing",
8727
- auto: "vibing",
8728
- "web-research": "researching",
8729
- forensic: "investigating"
8730
- };
8731
8733
  const optMode = (resolvedMode || "budget").toLowerCase();
8732
- const modeVerb = modeVerbMap[optMode] || "vibing";
8733
- let vibeLine = `\u2014 ${flashIcon ? `${flashIcon} ` : ""}${modeVerb} on ${shortModelName(brainModel)}`;
8734
+ const modeLabel = optMode === "quality" ? "quality" : optMode === "speed" ? "speed" : optMode === "longrun" ? "longrun" : "";
8735
+ let vibeLine = `\u2014 ${flashIcon ? `${flashIcon} ` : ""}run: ${shortModelName(displayModel)}`;
8734
8736
  if (ltTotal > 0) {
8735
8737
  vibeLine += ` | $${formatUsd(ltTotal)} saved`;
8736
8738
  }
@@ -8742,6 +8744,8 @@ async function _appendFooter(input, output, directory3) {
8742
8744
  } else if (problemStreak > 0) {
8743
8745
  vibeLine += ` | recovery ${problemStreak}`;
8744
8746
  }
8747
+ if (modeLabel)
8748
+ vibeLine += ` | ${modeLabel}`;
8745
8749
  vibeLine += ` | VIBE${flashIcon ? " \u26A1" : ""}`;
8746
8750
  if (_footerStress > 0.4) {
8747
8751
  const stressLabel = _footerStress > 0.7 ? "high" : "elevated";
@@ -10652,8 +10656,19 @@ var onToolExecuteAfter = async (input, output) => {
10652
10656
  stressTag = ` stress:${label}`;
10653
10657
  }
10654
10658
  }
10659
+ let liveModel = "";
10660
+ try {
10661
+ const cfg = await client.config.get("model");
10662
+ if (cfg)
10663
+ liveModel = String(cfg);
10664
+ } catch {
10665
+ }
10666
+ if (!liveModel) {
10667
+ liveModel = readConfig(projectDirectory) || readConfig(join16(process.env.HOME || "", ".config", "opencode")) || process?.env?.OPENCODE_MODEL || "";
10668
+ }
10669
+ const displayModel = liveModel || currentModel;
10655
10670
  if (ltTotal > 0) {
10656
- _footerText = `\u2014 ${flashIcon ? `${flashIcon} ` : ""}saving on ${shortModelName(currentModel)} | $${formatUsd(ltTotal)} saved | VIBE${flashIcon ? " \u26A1" : ""} \u2014
10671
+ _footerText = `\u2014 ${flashIcon ? `${flashIcon} ` : ""}run: ${shortModelName(displayModel)} | $${formatUsd(ltTotal)} saved | VIBE${flashIcon ? " \u26A1" : ""} \u2014
10657
10672
 
10658
10673
  `;
10659
10674
  } else {
@@ -1,7 +1,7 @@
1
1
  // @ts-nocheck
2
2
  import { readFileSync, appendFileSync, mkdirSync } from "node:fs";
3
3
  import { join } from "node:path";
4
- import { classify, _refreshModel, TRINITY_BRAIN, TRINITY_MEDIUM, TRINITY_CHEAP, shortModelName, roundUsd, formatUsd } from "../pricing.js";
4
+ import { classify, _refreshModel, readConfig, TRINITY_BRAIN, TRINITY_MEDIUM, TRINITY_CHEAP, shortModelName, roundUsd, formatUsd } from "../pricing.js";
5
5
  import { latestUserIntent } from "./chat-transform.js";
6
6
  import { scoreStress, resolveEnforcementMode, detectOutcomeSignal, getBlackboxTracker, syncOutcomeToApi, loadOptimizationMode, classifyTurnSimple } from "../turn-classify.js";
7
7
  import { peekBudgetFirstMode, recordBudgetFirstOutcome } from "../mode-policy.js";
@@ -139,18 +139,19 @@ async function _appendFooter(input, output, directory) {
139
139
  let _footerStress = 0;
140
140
  if (latestUserIntent)
141
141
  _footerStress = scoreStress(latestUserIntent);
142
- // Lazy model detection: try client API once
143
- if (!currentModel) {
144
- try {
145
- const cfg = await client.config.get("model");
146
- if (cfg) {
147
- setCurrentModel(String(cfg));
148
- setCurrentTier(classify(String(cfg)));
142
+ // Always prefer the live OpenCode model setting when available.
143
+ try {
144
+ const cfg = await client.config.get("model");
145
+ if (cfg) {
146
+ const cfgModel = String(cfg);
147
+ if (cfgModel !== currentModel) {
148
+ setCurrentModel(cfgModel);
149
+ setCurrentTier(classify(cfgModel));
149
150
  console.error(`[vibeOS] client-detected model: ${currentModel} (tier=${currentTier})`);
150
151
  }
151
152
  }
152
- catch { /* client.config may not be available */ }
153
153
  }
154
+ catch { /* client.config may not be available */ }
154
155
  try {
155
156
  const messageID = input?.messageID ||
156
157
  input?.messageId ||
@@ -175,12 +176,23 @@ async function _appendFooter(input, output, directory) {
175
176
  const sessionSlot = loadSessionSlot(_OC_SID);
176
177
  const slot = sessionSlot || loadSelection().active_slot || "brain";
177
178
  const brainModel = slot === "brain" ? (TRINITY_BRAIN || currentModel) : slot === "medium" ? (TRINITY_MEDIUM || currentModel) : (TRINITY_CHEAP || currentModel || "");
178
- let modelTag = `[${shortModelName(brainModel)}]`;
179
+ let liveModel = "";
180
+ try {
181
+ const cfg = await client.config.get("model");
182
+ if (cfg)
183
+ liveModel = String(cfg);
184
+ }
185
+ catch { }
186
+ if (!liveModel) {
187
+ liveModel = readConfig(directory) || readConfig(join(process.env.HOME || "", ".config", "opencode")) || process?.env?.OPENCODE_MODEL || "";
188
+ }
189
+ const displayModel = liveModel || currentModel || brainModel;
190
+ let modelTag = `[${shortModelName(displayModel)}]`;
179
191
  const _workerModel = slot === "brain" ? TRINITY_MEDIUM : null;
180
192
  const totalTurns = (sesModelTurns?.brain || 0) + (sesModelTurns?.worker || 0);
181
193
  if (_workerModel && _workerModel !== brainModel) {
182
194
  const brainPct = Math.round(((sesModelTurns?.brain || 0) / (totalTurns || 1)) * 100);
183
- modelTag = `[${shortModelName(brainModel)} ${brainPct}% → ${shortModelName(_workerModel)} ${100 - brainPct}%]`;
195
+ modelTag = `[${shortModelName(displayModel)} ${brainPct}% → ${shortModelName(_workerModel)} ${100 - brainPct}%]`;
184
196
  }
185
197
  _autoReportCount = (_autoReportCount || 0) + 1;
186
198
  if (_autoReportCount % 5 === 0) {
@@ -248,19 +260,9 @@ async function _appendFooter(input, output, directory) {
248
260
  return;
249
261
  const ltTotal = ltTasks + ltCache;
250
262
  // Build dopamine footer
251
- const modeVerbMap = {
252
- balanced: 'routing',
253
- budget: 'saving',
254
- quality: 'focusing',
255
- speed: 'moving',
256
- longrun: 'pacing',
257
- auto: 'vibing',
258
- 'web-research': 'researching',
259
- forensic: 'investigating',
260
- };
261
263
  const optMode = (resolvedMode || 'budget').toLowerCase();
262
- const modeVerb = modeVerbMap[optMode] || 'vibing';
263
- let vibeLine = `— ${flashIcon ? `${flashIcon} ` : ""}${modeVerb} on ${shortModelName(brainModel)}`;
264
+ const modeLabel = optMode === "quality" ? "quality" : optMode === "speed" ? "speed" : optMode === "longrun" ? "longrun" : "";
265
+ let vibeLine = `— ${flashIcon ? `${flashIcon} ` : ""}run: ${shortModelName(displayModel)}`;
264
266
  if (ltTotal > 0) {
265
267
  vibeLine += ` | $${formatUsd(ltTotal)} saved`;
266
268
  }
@@ -273,6 +275,8 @@ async function _appendFooter(input, output, directory) {
273
275
  else if (problemStreak > 0) {
274
276
  vibeLine += ` | recovery ${problemStreak}`;
275
277
  }
278
+ if (modeLabel)
279
+ vibeLine += ` | ${modeLabel}`;
276
280
  vibeLine += ` | VIBE${flashIcon ? ' ⚡' : ''}`;
277
281
  if (_footerStress > 0.4) {
278
282
  const stressLabel = _footerStress > 0.7 ? 'high' : 'elevated';
@@ -2,7 +2,7 @@
2
2
  import { writeFileSync, appendFileSync, existsSync, mkdirSync } from 'node:fs';
3
3
  import { join, dirname, basename } from 'node:path';
4
4
  import { currentTier, currentModel, setCurrentModel, setCurrentTier, _OC_SID, _modelLocked, loadSelection, readLifetimeSavings, recordCacheSaving, recordMissedContext7, getScratchpadHit, recordScratchpadObservation, recordPrivacyTelemetry, updateState, SAVINGS_LEDGER_FILE, CONTEXT7_INSTALL_FLAG, SOFT_QUOTA_LIMIT, upsertTodo, ML_ENABLED, _mlGraph, _cacheDb, _mlSavePending, ML_CONFIDENCE_THRESHOLD, setMlSavePending, saveMLState, SCRATCHPAD_TOOLS, applyDecadence, } from '../state.js';
5
- import { classify, modelCostPerTurn, isModelFree, detectContext7, isDocsTarget, shortModelName, formatUsd, _refreshModel, TRINITY_CHEAP, TRINITY_MEDIUM, trendDisplay, modelToSlotLabel, } from '../pricing.js';
5
+ import { classify, modelCostPerTurn, isModelFree, detectContext7, isDocsTarget, shortModelName, formatUsd, _refreshModel, readConfig, TRINITY_CHEAP, TRINITY_MEDIUM, trendDisplay, modelToSlotLabel, } from '../pricing.js';
6
6
  import { latestUserIntent } from './chat-transform.js';
7
7
  import { scoreStress, extractFirstWordFromArgs, shouldLogWarn, isUserAskingForTests, resolveEnforcementMode, getLearnedExploratoryWords, noteTaskRoutingLearning, } from '../turn-classify.js';
8
8
  import { saveReport } from '../reporting.js';
@@ -604,8 +604,19 @@ export const onToolExecuteAfter = async (input, output) => {
604
604
  stressTag = ` stress:${label}`;
605
605
  }
606
606
  }
607
+ let liveModel = "";
608
+ try {
609
+ const cfg = await client.config.get("model");
610
+ if (cfg)
611
+ liveModel = String(cfg);
612
+ }
613
+ catch { }
614
+ if (!liveModel) {
615
+ liveModel = readConfig(projectDirectory) || readConfig(join(process.env.HOME || "", ".config", "opencode")) || process?.env?.OPENCODE_MODEL || "";
616
+ }
617
+ const displayModel = liveModel || currentModel;
607
618
  if (ltTotal > 0) {
608
- _footerText = `— ${flashIcon ? `${flashIcon} ` : ""}saving on ${shortModelName(currentModel)} | $${formatUsd(ltTotal)} saved | VIBE${flashIcon ? " ⚡" : ""} —\n\n`;
619
+ _footerText = `— ${flashIcon ? `${flashIcon} ` : ""}run: ${shortModelName(displayModel)} | $${formatUsd(ltTotal)} saved | VIBE${flashIcon ? " ⚡" : ""} —\n\n`;
609
620
  }
610
621
  else {
611
622
  _footerText = `${statusLine}${stressTag}\n\n`;