vibeostheog 0.25.52 → 0.25.53

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,10 @@
1
+ ## 0.25.53
2
+ - fix: add project/blackbox cards to home summary, fix template source detection, expand recommendations (#302)
3
+ Merge release v0.25.52 into master
4
+ Fix backend-authoritative slot sync (#301)
5
+ Make vibeultrax start on cheap (#300)
6
+
7
+
1
8
  ## 0.25.52
2
9
  - feat: ship universal /vibe command
3
10
  - feat: add stable dashboard command alias
package/dist/vibeOS.js CHANGED
@@ -51,11 +51,13 @@ function loadSelectionImpl() {
51
51
  return DFLT_SEL;
52
52
  }
53
53
  const j = safeJsonParse(readFileSync(TIERS_FILE3, "utf-8"));
54
+ const activePipelineRaw = j?.selection?.active_pipeline;
55
+ const activePipeline = Array.isArray(activePipelineRaw) ? activePipelineRaw : typeof activePipelineRaw === "string" ? safeJsonParse(activePipelineRaw) : null;
54
56
  return {
55
57
  enabled: j?.selection?.enabled !== false,
56
58
  active_slot: j?.selection?.active_slot || null,
57
59
  slot_locked: j?.selection?.slot_locked === true,
58
- active_pipeline: j?.selection?.active_pipeline || null,
60
+ active_pipeline: Array.isArray(activePipeline) ? activePipeline : null,
59
61
  optimization_mode: j?.selection?.optimization_mode || null,
60
62
  thinking_level: j?.selection?.thinking_level || "off",
61
63
  flow_enabled: j?.selection?.flow_enabled === true,
@@ -1049,7 +1051,7 @@ function normalizeSessionTemplate(raw, fallbackId = DEFAULT_TEMPLATE) {
1049
1051
  const preset = TEMPLATES[baseId] || TEMPLATES[DEFAULT_TEMPLATE];
1050
1052
  const body = normalizeTemplateBody(raw.body ?? raw.directive, preset.directive);
1051
1053
  const label = typeof raw.label === "string" && raw.label.trim() ? raw.label.trim() : typeof raw.name === "string" && raw.name.trim() ? raw.name.trim() : baseId in TEMPLATES ? baseId === "save" ? "Save" : baseId.charAt(0).toUpperCase() + baseId.slice(1) : "Custom template";
1052
- const source = raw.source === "preset" || raw.source !== "custom" && baseId in TEMPLATES && !raw.body && !raw.directive ? "preset" : "custom";
1054
+ const source = raw.source === "custom" ? "custom" : baseId in TEMPLATES ? "preset" : "custom";
1053
1055
  const revision = Number.isFinite(Number(raw.revision)) && Number(raw.revision) > 0 ? Number(raw.revision) : 1;
1054
1056
  const id2 = typeof raw.id === "string" && raw.id.trim() ? raw.id.trim() : source === "preset" ? baseId : `session-${templateDigest(`${label}
1055
1057
  ${body}
@@ -1519,7 +1521,7 @@ function pickSessionMetrics(session, metrics = {}) {
1519
1521
  duration_seconds: Number(metrics?.sesDuration ?? session?.duration_seconds ?? 0) || 0
1520
1522
  };
1521
1523
  }
1522
- function recommendationForSession(session, currentSession = false) {
1524
+ function recommendationForSession(session, currentSession = false, blackbox) {
1523
1525
  if (!session)
1524
1526
  return currentSession ? "Open the active session" : "Select a session";
1525
1527
  if (session.archived)
@@ -1532,6 +1534,9 @@ function recommendationForSession(session, currentSession = false) {
1532
1534
  return "Apply a TDD template";
1533
1535
  if ((session.notes_count || 0) === 0)
1534
1536
  return "Add a note";
1537
+ const subRegime = blackbox?.sub_regime || blackbox?.regime;
1538
+ if (subRegime === "LOOPING")
1539
+ return "Review loop intervention";
1535
1540
  return currentSession ? "Continue with the next step" : "Review session details";
1536
1541
  }
1537
1542
  function sortSessions(items) {
@@ -1597,16 +1602,16 @@ function buildSessionDetail(sessionId, session, metrics = {}, blackbox = {}, sel
1597
1602
  ...orchestration,
1598
1603
  template,
1599
1604
  notes_count: orchestration.notes.length
1600
- }, sessionId === selection?.current_session_id),
1605
+ }, sessionId === selection?.current_session_id, blackbox),
1601
1606
  notes: orchestration.notes,
1602
1607
  lifecycle: orchestration.lifecycle,
1603
1608
  orchestration
1604
1609
  };
1605
1610
  return summary;
1606
1611
  }
1607
- function buildDashboardHomeModel({ currentSessionId: currentSessionId3, status = {}, savings = {}, todos = [], blackbox = {}, sessions = {}, metrics = {}, templates = TEMPLATE_LIBRARY2 }) {
1612
+ function buildDashboardHomeModel({ currentSessionId: currentSessionId3, status = {}, savings = {}, todos = [], blackbox = {}, sessions = {}, metrics = {}, templates = TEMPLATE_LIBRARY2, currentProjectName: currentProjectName3 = "" }) {
1608
1613
  const rows = Object.entries(sessions || {}).map(([sessionId, session]) => buildSessionListItem(sessionId, session, sessionId === currentSessionId3 ? metrics : {}, sessionId === currentSessionId3));
1609
- const currentSession = buildSessionDetail(currentSessionId3, sessions?.[currentSessionId3] || {}, metrics, blackbox, { ...status, current_session_id: currentSessionId3 });
1614
+ const currentSession = buildSessionDetail(currentSessionId3, sessions?.[currentSessionId3] || {}, metrics, blackbox, { ...status, current_session_id: currentSessionId3, project_name: currentProjectName3 });
1610
1615
  const totalSavings = Number(savings?.lifetime?.delegation_usd || 0) + Number(savings?.lifetime?.cache_usd || 0);
1611
1616
  const currentSavings = Number(savings?.current_session?.delegation_usd || 0) + Number(savings?.current_session?.cache_usd || 0);
1612
1617
  const pendingTodos = asArray(todos).filter((todo) => todo?.status === "pending").length;
@@ -1617,9 +1622,11 @@ function buildDashboardHomeModel({ currentSessionId: currentSessionId3, status =
1617
1622
  recommendation: currentSession.recommendation,
1618
1623
  cards: [
1619
1624
  { label: "Session", value: currentSession.session_id },
1625
+ { label: "Project", value: currentSession.project_name || "unknown" },
1620
1626
  { label: "Slot", value: status?.active_slot || "brain" },
1621
1627
  { label: "Mode", value: status?.optimization_mode || "auto" },
1622
1628
  { label: "Stress", value: blackbox?.sub_regime || "INIT" },
1629
+ { label: "Blackbox", value: currentSession.blackbox?.sub_regime || "INIT" },
1623
1630
  { label: "Savings", value: `$${totalSavings.toFixed(2)}` },
1624
1631
  { label: "TODOs", value: String(pendingTodos) }
1625
1632
  ]
@@ -4147,6 +4154,33 @@ function recordBackendVersion(payload) {
4147
4154
  if (version)
4148
4155
  _backendVersion = version;
4149
4156
  }
4157
+ async function probeApiHealth(client2) {
4158
+ try {
4159
+ const controller = new AbortController();
4160
+ const timeoutId = setTimeout(() => controller.abort(), client2.timeout);
4161
+ try {
4162
+ const res = await fetch(client2.baseUrl + "/health", {
4163
+ method: "GET",
4164
+ headers: client2.apiToken ? {
4165
+ "Content-Type": "application/json",
4166
+ Authorization: "Bearer " + client2.apiToken
4167
+ } : {
4168
+ "Content-Type": "application/json"
4169
+ },
4170
+ signal: controller.signal
4171
+ });
4172
+ if (res.ok) {
4173
+ markApiConnected();
4174
+ return true;
4175
+ }
4176
+ return false;
4177
+ } finally {
4178
+ clearTimeout(timeoutId);
4179
+ }
4180
+ } catch {
4181
+ return false;
4182
+ }
4183
+ }
4150
4184
  async function ensureBootstrapExchange() {
4151
4185
  syncApiTokenFromDisk();
4152
4186
  if (VIBEOS_API_DISABLED)
@@ -4305,6 +4339,9 @@ async function remoteCall(method, args, fallbackFn) {
4305
4339
  return fallbackFn();
4306
4340
  return null;
4307
4341
  }
4342
+ if (method === "health") {
4343
+ await probeApiHealth(client2);
4344
+ }
4308
4345
  const startedAt = Date.now();
4309
4346
  const result = await client2[method](...args);
4310
4347
  if (shouldApplyLatencyGuard(method)) {
@@ -4615,8 +4652,8 @@ var init_api_client = __esm({
4615
4652
  embedding: entry.embedding || null
4616
4653
  });
4617
4654
  }
4618
- async blackboxState(sessionId) {
4619
- return this.request("/api/v1/blackbox/state", { session_id: sessionId });
4655
+ async blackboxState(sessionId, payload = {}) {
4656
+ return this.request("/api/v1/blackbox/state", { session_id: sessionId, ...payload });
4620
4657
  }
4621
4658
  async blackboxReset(sessionId) {
4622
4659
  return this.request("/api/v1/blackbox/reset", { session_id: sessionId });
@@ -4631,7 +4668,8 @@ var init_api_client = __esm({
4631
4668
  return this.request("/api/v1/blackbox/calibration?project_id=" + (projectId || "global"), null);
4632
4669
  }
4633
4670
  async blackboxControlVector(state, action, optimizationMode) {
4634
- return this.request("/api/v1/blackbox/control-vector", { ...state, action, optimization_mode: optimizationMode });
4671
+ const decision = typeof optimizationMode === "string" ? { optimization_mode: optimizationMode } : optimizationMode || {};
4672
+ return this.request("/api/v1/blackbox/control-vector", { ...state, action, ...decision });
4635
4673
  }
4636
4674
  async blackboxSelectMode(subRegime, stressMultiplier) {
4637
4675
  return this.request("/api/v1/blackbox/select-mode", { sub_regime: subRegime, stress_multiplier: stressMultiplier });
@@ -5696,13 +5734,13 @@ function profileFromCascade(decision, learned = null) {
5696
5734
  if (learned?.learnedTier === "cheap")
5697
5735
  return { profile: "direct", cascade_depth: 1, pipeline_root: ["cheap"], tier_bias: "cheap" };
5698
5736
  if (learned?.learnedTier === "medium")
5699
- return { profile: "standard", cascade_depth: 2, pipeline_root: ["medium", "brain"], tier_bias: "medium" };
5737
+ return { profile: "standard", cascade_depth: 2, pipeline_root: ["medium", "brain"], tier_bias: "cheap" };
5700
5738
  if (learned?.learnedTier === "brain")
5701
- return { profile: "deep", cascade_depth: 3, pipeline_root: ["cheap", "medium", "brain"], tier_bias: "brain" };
5739
+ return { profile: "deep", cascade_depth: 3, pipeline_root: ["cheap", "medium", "brain"], tier_bias: "cheap" };
5702
5740
  if (decision.useCheap && decision.escalate)
5703
- return { profile: "deep", cascade_depth: 3, pipeline_root: ["cheap", "medium", "brain"], tier_bias: "brain" };
5741
+ return { profile: "deep", cascade_depth: 3, pipeline_root: ["cheap", "medium", "brain"], tier_bias: "cheap" };
5704
5742
  if (decision.escalate)
5705
- return { profile: "standard", cascade_depth: 2, pipeline_root: ["medium", "brain"], tier_bias: "brain" };
5743
+ return { profile: "standard", cascade_depth: 2, pipeline_root: ["medium", "brain"], tier_bias: "cheap" };
5706
5744
  return { profile: "direct", cascade_depth: 1, pipeline_root: ["cheap"], tier_bias: "cheap" };
5707
5745
  }
5708
5746
  function getPivotCache2() {
@@ -6721,13 +6759,15 @@ function createMcpServer(deps) {
6721
6759
  blackbox,
6722
6760
  sessions: getSessionsFromState(state),
6723
6761
  metrics: deps.getSessionMetrics(currentSessionId3),
6724
- templates: typeof deps.listSessionTemplates === "function" ? deps.listSessionTemplates() : TEMPLATE_LIBRARY2
6762
+ templates: typeof deps.listSessionTemplates === "function" ? deps.listSessionTemplates() : TEMPLATE_LIBRARY2,
6763
+ currentProjectName: deps.currentProjectName || ""
6725
6764
  });
6726
6765
  json(res, 200, {
6727
6766
  ...home,
6728
6767
  status: state,
6729
6768
  blackbox,
6730
6769
  backend_connected: state?.backend_connected ?? false,
6770
+ backend_status: state?.backend_connected ? "online" : "degraded",
6731
6771
  backend_health_url: BACKEND_HEALTH_URL,
6732
6772
  backend_version: state?.backend_version || null
6733
6773
  });
@@ -7362,15 +7402,15 @@ function buildDeterministicTrinity(models, options = {}) {
7362
7402
  const scoped = providerModels.length > 0 ? providerModels : list;
7363
7403
  const qualityRanked = _sortByQualityDesc(scoped);
7364
7404
  const costRanked = _sortByCostAsc(scoped);
7365
- const brain = selectedModel || qualityRanked[0] || costRanked[0] || scoped[0] || list[0];
7405
+ const brain = qualityRanked[0] || costRanked[0] || scoped[0] || list[0];
7366
7406
  const medium = qualityRanked.find((m) => m.id !== brain?.id) || brain;
7367
7407
  const freeModel = scoped.find((m) => isModelFree(m.id));
7368
7408
  const cheap = freeModel || costRanked[0] || medium;
7369
- const brainClass = isModelFree(brain?.id) ? "free" : classify(brain?.id);
7409
+ const selectedTier = selectedModel ? isModelFree(selectedModel.id) ? "free" : classify(selectedModel.id) : isModelFree(brain?.id) ? "free" : classify(brain?.id);
7370
7410
  return {
7371
7411
  provider,
7372
- selected_tier: brainClass,
7373
- selected_model: brain?.id || selectedModelId || "",
7412
+ selected_tier: selectedTier,
7413
+ selected_model: selectedModel?.id || selectedModelId || brain?.id || "",
7374
7414
  brain: brain?.id || "",
7375
7415
  medium: medium?.id || "",
7376
7416
  cheap: cheap?.id || "",
@@ -8272,7 +8312,7 @@ function _refreshModel(directory3) {
8272
8312
  console.error(`[vibeOS] auto-detected model: ${currentModel} (tier=${currentTier})`);
8273
8313
  }
8274
8314
  }
8275
- if (!(_modelLocked || sel.slot_locked === true)) {
8315
+ if (!(_modelLocked || sel.slot_locked === true) && !slotOcModel) {
8276
8316
  const activeIsManual = tiersData?.trinity?.[activeSlot]?.manual === true;
8277
8317
  const currentSlotModel = activeIsManual ? "" : slotOcModel;
8278
8318
  if (!currentSlotModel && !currentModel) {
@@ -9409,6 +9449,14 @@ function resolveOptimizationMode(subRegime, stressMultiplier, optimizationMode)
9409
9449
  }
9410
9450
  return isSupportedOptimizationMode(normalized) ? normalized : "budget";
9411
9451
  }
9452
+ function resolveOptimizationSlot(mode) {
9453
+ const normalized = normalizeOptimizationMode(mode);
9454
+ if (MEDIUM_ROOT_MODES.has(normalized))
9455
+ return "medium";
9456
+ if (BRAIN_ROOT_MODES.has(normalized))
9457
+ return "brain";
9458
+ return "cheap";
9459
+ }
9412
9460
  function buildModeRoot(mode) {
9413
9461
  if (mode === "vibeqmax") {
9414
9462
  return { mode_root: "vibeqmax", mode_family: "brain-ml", cascade_depth: 1, pipeline_root: ["brain"] };
@@ -9522,25 +9570,6 @@ function buildOfflineControlVector(state, mode) {
9522
9570
  ] : []
9523
9571
  };
9524
9572
  }
9525
- async function selectOptimizationModeRemote(subRegime, stressMultiplier, fallbackMode) {
9526
- const normalizedRequestedMode = normalizeOptimizationMode(fallbackMode);
9527
- const fallback2 = resolveOptimizationMode(subRegime, stressMultiplier, fallbackMode);
9528
- if (normalizedRequestedMode !== "auto" && normalizedRequestedMode !== "")
9529
- return fallback2;
9530
- if (isApiFallback())
9531
- return fallback2;
9532
- try {
9533
- const client2 = getApiClient();
9534
- if (client2) {
9535
- const res = await client2.blackboxSelectMode(subRegime || "INIT", Number(stressMultiplier ?? 0));
9536
- const selected = normalizeOptimizationMode(res?.mode || "");
9537
- if (isSupportedOptimizationMode(selected) && selected !== "auto")
9538
- return selected;
9539
- }
9540
- } catch {
9541
- }
9542
- return fallback2;
9543
- }
9544
9573
  function computeControlVector2(_state, _action, _optimizationMode) {
9545
9574
  const mode = resolveOptimizationMode(_state?.sub_regime, _state?.latest_stress_multiplier, _optimizationMode);
9546
9575
  if (mode === "vibeqmax") {
@@ -9992,7 +10021,7 @@ function recoverOptimizationModeFromLiveState(sel) {
9992
10021
  return "budget";
9993
10022
  return recoverOptimizationModeFromSelection(sel);
9994
10023
  }
9995
- function loadOptimizationMode() {
10024
+ function loadOptimizationMode2() {
9996
10025
  try {
9997
10026
  const sel = loadSelection();
9998
10027
  const persistedMode = sel.optimization_mode || null;
@@ -11140,7 +11169,9 @@ function createTrinityTool(deps) {
11140
11169
  const providers = typeof deps._loadOpenCodeProviders === "function" ? deps._loadOpenCodeProviders(deps.directory) : {};
11141
11170
  const auth = deps._readAuth();
11142
11171
  const models = await deps.discoverAvailableModels(providers, auth);
11143
- const trinity = buildDeterministicTrinity(models, { selectedModelId: deps.currentModel });
11172
+ const trinity = buildDeterministicTrinity(models, {
11173
+ selectedModelId: sel.selected_model || sel.executed_model || deps.currentModel
11174
+ });
11144
11175
  if (trinity && trinity.brain) {
11145
11176
  const probed = {
11146
11177
  brain: models.find((m) => m.id === trinity.brain) || { id: trinity.brain, cost: deps._modelCost(trinity.brain), tier: deps._modelTier(trinity.brain) },
@@ -11159,15 +11190,15 @@ function createTrinityTool(deps) {
11159
11190
  }
11160
11191
  tiersData.selection ??= {};
11161
11192
  tiersData.selection.selected_provider = trinity.provider || resolveExecutionIdentity(deps.currentModel, deps.directory)?.provider || "";
11162
- tiersData.selection.selected_model = deps.currentModel;
11193
+ tiersData.selection.selected_model = sel.selected_model || deps.currentModel;
11163
11194
  tiersData.selection.executed_provider = tiersData.selection.selected_provider;
11164
- tiersData.selection.executed_model = deps.currentModel;
11195
+ tiersData.selection.executed_model = sel.executed_model || sel.selected_model || deps.currentModel;
11165
11196
  const _tmp = deps.TIERS_FILE + ".tmp." + Date.now();
11166
11197
  deps.writeFileSync(_tmp, JSON.stringify(tiersData, null, 2) + "\n", "utf-8");
11167
11198
  deps.renameSync(_tmp, deps.TIERS_FILE);
11168
11199
  tiers = tiersData.trinity;
11169
11200
  sel.selected_provider = tiersData.selection.selected_provider;
11170
- sel.selected_model = deps.currentModel;
11201
+ sel.selected_model = tiersData.selection.selected_model;
11171
11202
  }
11172
11203
  } catch (e) {
11173
11204
  console.error("[vibeOS] auto-rebuild on model change failed:", e.message);
@@ -11385,10 +11416,16 @@ function createTrinityTool(deps) {
11385
11416
  const allEntries = [...BRANDED_MODES, ...RUNTIME_MODES];
11386
11417
  const modeEntry = allEntries.find((e) => e.id === slot);
11387
11418
  if (modeEntry) {
11388
- const tierSlot = resolveCascadeSlot(modeEntry.pipeline);
11419
+ const tierSlot = slot === "vibeultrax" ? "cheap" : resolveCascadeSlot(modeEntry.pipeline);
11389
11420
  deps.writeSessionSlot(deps._OC_SID, tierSlot);
11390
11421
  deps.writeSelection("active_slot", tierSlot);
11391
11422
  deps.writeSelection("active_pipeline", modeEntry.pipeline);
11423
+ if (slot === "vibeultrax") {
11424
+ deps._modelLocked = false;
11425
+ deps._lockedSlot = null;
11426
+ deps._lockedModel = null;
11427
+ deps.writeSelection("slot_locked", false);
11428
+ }
11392
11429
  deps.writeSelection("onboarding_mode", modeEntry.tdd === "quality" || modeEntry.enforcement === "strict" ? "strict" : "assist");
11393
11430
  deps.writeSelection("delegation_enforce", modeEntry.enforcement === "strict" || modeEntry.enforcement === "on");
11394
11431
  deps.writeSelection("flow_enabled", modeEntry.flow === "strict" || modeEntry.flow === "on" || modeEntry.flow === "audit");
@@ -12078,7 +12115,8 @@ ${L.repeat(40)}`);
12078
12115
  const providers = typeof deps._loadOpenCodeProviders === "function" ? deps._loadOpenCodeProviders(deps.directory) : {};
12079
12116
  const auth = deps._readAuth();
12080
12117
  const models = await deps.discoverAvailableModels(providers, auth);
12081
- const selectedModel = deps.currentModel || deps.loadSelection?.().selected_model || deps.loadSelection?.().executed_model || "";
12118
+ const currentSelection = deps.loadSelection?.() || {};
12119
+ const selectedModel = currentSelection.selected_model || currentSelection.executed_model || deps.currentModel || "";
12082
12120
  const trinity = buildDeterministicTrinity(models, { selectedModelId: selectedModel });
12083
12121
  if (!trinity) {
12084
12122
  return "\u274C No models discovered from any configured provider.";
@@ -12936,10 +12974,7 @@ function evaluateClaimVerification({ text, vibeHome = process.env.VIBEOS_HOME ||
12936
12974
 
12937
12975
  // src/lib/mode-policy.js
12938
12976
  init_state();
12939
- var STRESS_QUALITY_THRESHOLD = 1.5;
12940
12977
  var BASELINE_MODE = "budget";
12941
- var LOOP_REGIMES = /* @__PURE__ */ new Set(["LOOPING", "DIVERGENT"]);
12942
- var QUALITY_REGIMES = /* @__PURE__ */ new Set(["CONVERGING", "CLOSED"]);
12943
12978
  var MANUAL_MODES = /* @__PURE__ */ new Set(["balanced", "quality", "speed", "longrun", "audit", "forensic", "vibemax", "vibeqmax", "vibeultrax"]);
12944
12979
  function normalizeMode(mode) {
12945
12980
  const normalized = String(mode || BASELINE_MODE).toLowerCase();
@@ -12956,19 +12991,6 @@ function normalizeRegime(regime) {
12956
12991
  function isManualOverride(mode) {
12957
12992
  return MANUAL_MODES.has(normalizeMode(mode));
12958
12993
  }
12959
- function chooseEpisodeMode(regime, suggestedMode, stress) {
12960
- if (suggestedMode === "vibeultrax" || suggestedMode === "vibeqmax" || suggestedMode === "vibemax" || suggestedMode === "audit" || suggestedMode === "forensic")
12961
- return suggestedMode;
12962
- if (regime === "LOOPING")
12963
- return "quality";
12964
- if (suggestedMode === "speed")
12965
- return "speed";
12966
- if (LOOP_REGIMES.has(regime))
12967
- return "speed";
12968
- if (QUALITY_REGIMES.has(regime) || suggestedMode === "quality")
12969
- return "quality";
12970
- return stress > STRESS_QUALITY_THRESHOLD ? "quality" : "budget";
12971
- }
12972
12994
  function defaultPolicy() {
12973
12995
  return {
12974
12996
  active: false,
@@ -13049,46 +13071,6 @@ function peekBudgetFirstMode(input = {}) {
13049
13071
  shouldPersistRequestedMode: false
13050
13072
  };
13051
13073
  }
13052
- function applyBudgetFirstMode(input = {}) {
13053
- const requestedMode = normalizeMode(input.requestedMode);
13054
- if (isManualOverride(requestedMode)) {
13055
- return {
13056
- active: false,
13057
- mode: requestedMode,
13058
- reason: "manual",
13059
- shouldPersistRequestedMode: true
13060
- };
13061
- }
13062
- return withFileLock(BLACKBOX_STATE_FILE, () => {
13063
- const { state, session, policy } = loadSessionPolicy();
13064
- const interactions = Number(input.nInteractions ?? state.sessions?.[_OC_SID]?.n_interactions ?? 0);
13065
- const regime = normalizeRegime(input.subRegime || policy.last_sub_regime);
13066
- const stress = Number(input.stress ?? policy.last_stress ?? 0);
13067
- const suggested = normalizeMode(input.suggestedMode);
13068
- policy.baseline_mode = BASELINE_MODE;
13069
- policy.last_sub_regime = regime;
13070
- policy.last_stress = stress;
13071
- policy.updated_at = (/* @__PURE__ */ new Date()).toISOString();
13072
- if (policy.active && policy.active_mode && normalizeMode(policy.active_mode) !== BASELINE_MODE) {
13073
- return persistSessionPolicy(state, session, policy, policy.active_mode);
13074
- }
13075
- const shouldStartEpisode = LOOP_REGIMES.has(regime) || suggested === "speed" || QUALITY_REGIMES.has(regime) || Number(policy.problem_streak || 0) >= 2 || Number(policy.problem_streak || 0) >= 1 && stress > 1.5;
13076
- if (shouldStartEpisode) {
13077
- const nextMode = chooseEpisodeMode(regime, suggested, stress);
13078
- policy.active = true;
13079
- policy.active_mode = nextMode;
13080
- policy.reason = LOOP_REGIMES.has(regime) ? "loop" : QUALITY_REGIMES.has(regime) ? "quality" : stress > 1.5 ? "stress" : "problem";
13081
- policy.episode_id = policy.episode_id || `${_OC_SID}:${Date.now()}`;
13082
- policy.started_at = policy.started_at || (/* @__PURE__ */ new Date()).toISOString();
13083
- policy.stable_streak = 0;
13084
- return persistSessionPolicy(state, session, policy, nextMode);
13085
- }
13086
- policy.active = false;
13087
- policy.active_mode = BASELINE_MODE;
13088
- policy.reason = null;
13089
- return persistSessionPolicy(state, session, policy, BASELINE_MODE);
13090
- });
13091
- }
13092
13074
  function recordBudgetFirstOutcome(input = {}) {
13093
13075
  const outcome = String(input.outcome || "").toLowerCase();
13094
13076
  if (outcome !== "positive" && outcome !== "negative") {
@@ -13829,15 +13811,102 @@ var _turnCountInject = 0;
13829
13811
  var _pivotLastCheckTurn = 0;
13830
13812
  var _pivotLastRegime = null;
13831
13813
  var _calBuffer = [];
13814
+ var _pendingOrchestratorDirective = "";
13832
13815
  var correctionSeenKeys = /* @__PURE__ */ new Set();
13833
13816
  async function apiComputeControlVector(state, action, optimizationMode) {
13834
13817
  try {
13835
- const res = await remoteCall("blackboxControlVector", [state, action, optimizationMode], null);
13836
- if (res?.control_vector)
13837
- return res.control_vector;
13818
+ const requestedMode = typeof optimizationMode === "string" ? optimizationMode : String(optimizationMode?.optimization_mode || optimizationMode?.requested_mode || "auto");
13819
+ const res = await remoteCall("blackboxControlVector", [state, action, {
13820
+ optimization_mode: requestedMode,
13821
+ requested_mode: requestedMode,
13822
+ requested_slot: typeof optimizationMode === "object" ? optimizationMode?.requested_slot || null : null,
13823
+ pipeline_root: typeof optimizationMode === "object" ? optimizationMode?.pipeline_root || null : null,
13824
+ source: typeof optimizationMode === "object" ? optimizationMode?.source || null : null
13825
+ }], null);
13826
+ if (res && typeof res === "object") {
13827
+ return normalizeBackendDecision(res, requestedMode);
13828
+ }
13838
13829
  } catch {
13839
13830
  }
13840
- return computeControlVector2(state, action, optimizationMode);
13831
+ const fallbackMode = typeof optimizationMode === "string" ? optimizationMode : String(optimizationMode?.optimization_mode || optimizationMode?.requested_mode || "auto");
13832
+ const controlVector = computeControlVector2(state, action, fallbackMode);
13833
+ return normalizeBackendDecision({
13834
+ ...controlVector,
13835
+ control_vector: controlVector,
13836
+ decision: {
13837
+ optimization_mode: controlVector.optimization_mode || fallbackMode,
13838
+ tier_bias: controlVector.tier_bias || null,
13839
+ pipeline_root: controlVector.pipeline_root || [],
13840
+ source: "local",
13841
+ requested_mode: fallbackMode,
13842
+ requested_slot: controlVector.tier_bias || null
13843
+ }
13844
+ }, fallbackMode);
13845
+ }
13846
+ function normalizeSlot(value) {
13847
+ const normalized = String(value || "").trim().toLowerCase();
13848
+ if (normalized === "brain" || normalized === "medium" || normalized === "cheap")
13849
+ return normalized;
13850
+ return null;
13851
+ }
13852
+ function slotFromMode(mode) {
13853
+ const normalized = String(mode || "").trim().toLowerCase();
13854
+ if (!normalized || normalized === "auto")
13855
+ return null;
13856
+ if (normalized === "speed" || normalized === "vibemax" || normalized === "vibelitex")
13857
+ return "medium";
13858
+ if (normalized === "quality" || normalized === "longrun" || normalized === "audit" || normalized === "forensic" || normalized === "vibeqmax")
13859
+ return "brain";
13860
+ if (normalized === "vibeultrax")
13861
+ return "cheap";
13862
+ if (normalized === "budget" || normalized === "balanced")
13863
+ return "cheap";
13864
+ return null;
13865
+ }
13866
+ function normalizePipelineRoot(value, tierBias) {
13867
+ if (Array.isArray(value)) {
13868
+ const out = value.map((entry) => normalizeSlot(entry)).filter(Boolean);
13869
+ if (out.length > 0)
13870
+ return out;
13871
+ }
13872
+ const slot = normalizeSlot(value) || normalizeSlot(tierBias);
13873
+ return slot ? [slot] : [];
13874
+ }
13875
+ function normalizeBackendDecision(raw, fallbackMode = null) {
13876
+ if (!raw || typeof raw !== "object")
13877
+ return raw;
13878
+ const sourceDecision = raw.decision && typeof raw.decision === "object" ? raw.decision : raw;
13879
+ const requestedMode = String(sourceDecision.requested_mode || sourceDecision.requestedMode || fallbackMode || raw.requested_mode || raw.requestedMode || "").trim().toLowerCase() || null;
13880
+ const requestedSlot = normalizeSlot(sourceDecision.requested_slot || sourceDecision.requestedSlot || slotFromMode(requestedMode)) || null;
13881
+ const optimizationMode = String(sourceDecision.optimization_mode || sourceDecision.mode || fallbackMode || raw.optimization_mode || raw.mode || requestedMode || "auto").trim().toLowerCase();
13882
+ const tierBias = normalizeSlot(sourceDecision.tier_bias || sourceDecision.active_slot || raw.tier_bias || raw.active_slot || slotFromMode(optimizationMode) || requestedSlot) || null;
13883
+ const pipelineRoot = normalizePipelineRoot(sourceDecision.pipeline_root || raw.pipeline_root || raw.active_pipeline, tierBias);
13884
+ const source = String(sourceDecision.source || raw.source || raw.optimization_source || "backend");
13885
+ const decision = {
13886
+ optimization_mode: optimizationMode || null,
13887
+ tier_bias: tierBias,
13888
+ pipeline_root: pipelineRoot,
13889
+ source,
13890
+ requested_mode: requestedMode,
13891
+ requested_slot: requestedSlot
13892
+ };
13893
+ const controlVector = raw.control_vector && typeof raw.control_vector === "object" ? {
13894
+ ...raw.control_vector,
13895
+ optimization_mode: decision.optimization_mode,
13896
+ tier_bias: decision.tier_bias,
13897
+ pipeline_root: decision.pipeline_root
13898
+ } : void 0;
13899
+ return {
13900
+ ...raw,
13901
+ optimization_mode: decision.optimization_mode,
13902
+ tier_bias: decision.tier_bias,
13903
+ pipeline_root: decision.pipeline_root,
13904
+ source: decision.source,
13905
+ requested_mode: decision.requested_mode,
13906
+ requested_slot: decision.requested_slot,
13907
+ decision,
13908
+ control_vector: controlVector || raw.control_vector || null
13909
+ };
13841
13910
  }
13842
13911
  function observeUserCorrection(text) {
13843
13912
  if (!text || typeof text !== "string")
@@ -14032,9 +14101,11 @@ function syncControlSettings(cv, options = {}) {
14032
14101
  }
14033
14102
  }
14034
14103
  const persistOptimizationMode = options.persistOptimizationMode !== false;
14104
+ const backendDecision = options.backendDecision && typeof options.backendDecision === "object" ? options.backendDecision : null;
14105
+ const authoritative = options.authoritative === true || backendDecision && backendDecision.source !== "manual";
14035
14106
  const currentSel = loadSelection();
14036
14107
  const userSetMode = loadSessionOptMode(sid + "_opt");
14037
- const userOptMode = userSetMode || loadOptimizationMode();
14108
+ const userOptMode = userSetMode || loadOptimizationMode2();
14038
14109
  const isManualMode = userSetMode && userOptMode !== "auto";
14039
14110
  const writeIf = (key, val) => {
14040
14111
  const sel = loadSelection();
@@ -14084,40 +14155,49 @@ function syncControlSettings(cv, options = {}) {
14084
14155
  if (currentSel.thinking_level !== nextThinking)
14085
14156
  writeIf("thinking_level", nextThinking);
14086
14157
  }
14087
- if (persistOptimizationMode && cv.optimization_mode && userOptMode !== "auto") {
14158
+ const previousOptMode = typeof currentSel.previous_optimization_mode === "string" ? currentSel.previous_optimization_mode : null;
14159
+ const prevSessionKey = `${sid}_prev_opt`;
14160
+ const sessionPreviousOptMode = loadSessionOptMode(prevSessionKey);
14161
+ const liveSlot = String(currentSel.active_slot || cv.tier_bias || "").toLowerCase();
14162
+ const inferredRecoveryMode = liveSlot === "brain" ? "quality" : liveSlot === "medium" ? "vibemax" : "budget";
14163
+ if (persistOptimizationMode && cv.optimization_mode && (userOptMode !== "auto" || authoritative)) {
14164
+ if (authoritative) {
14165
+ writeIf("requested_optimization_mode", cv.optimization_mode);
14166
+ }
14088
14167
  const fallbackPinned = isApiFallback() && cv.optimization_mode === "vibelitex";
14089
- const previousOptMode2 = typeof currentSel.previous_optimization_mode === "string" ? currentSel.previous_optimization_mode : null;
14090
- const prevSessionKey2 = `${sid}_prev_opt`;
14091
- const sessionPreviousOptMode = loadSessionOptMode(prevSessionKey2);
14092
- const liveSlot = String(currentSel.active_slot || cv.tier_bias || "").toLowerCase();
14093
- const inferredRecoveryMode = liveSlot === "brain" ? "quality" : liveSlot === "medium" ? "vibemax" : "budget";
14094
- const restoreMode = sessionPreviousOptMode || previousOptMode2 || inferredRecoveryMode;
14095
- const canRestorePrevious = !!restoreMode && cv.optimization_mode !== "vibelitex" && (previousOptMode2 !== null || sessionPreviousOptMode !== null);
14168
+ const restoreMode = sessionPreviousOptMode || previousOptMode || inferredRecoveryMode;
14169
+ const canRestorePrevious = !!restoreMode && cv.optimization_mode !== "vibelitex" && (previousOptMode !== null || sessionPreviousOptMode !== null);
14096
14170
  if (fallbackPinned) {
14097
- const snapshotMode = currentSel.optimization_mode && currentSel.optimization_mode !== "vibelitex" ? currentSel.optimization_mode : previousOptMode2 || sessionPreviousOptMode || inferredRecoveryMode;
14171
+ const snapshotMode = currentSel.optimization_mode && currentSel.optimization_mode !== "vibelitex" ? currentSel.optimization_mode : previousOptMode || sessionPreviousOptMode || inferredRecoveryMode;
14098
14172
  if (snapshotMode && snapshotMode !== "vibelitex") {
14099
14173
  writeIf("previous_optimization_mode", snapshotMode);
14100
- writeSessionOptMode(prevSessionKey2, snapshotMode);
14174
+ writeSessionOptMode(prevSessionKey, snapshotMode);
14101
14175
  }
14102
14176
  } else if (canRestorePrevious) {
14103
14177
  writeIf("optimization_mode", restoreMode);
14104
14178
  writeIf("previous_optimization_mode", null);
14105
14179
  writeSessionOptMode(sid, restoreMode);
14106
- writeSessionOptMode(prevSessionKey2, "");
14180
+ writeSessionOptMode(prevSessionKey, "");
14107
14181
  } else if (userOptMode !== cv.optimization_mode) {
14108
14182
  writeIf("optimization_mode", cv.optimization_mode);
14109
- if (previousOptMode2)
14183
+ if (previousOptMode)
14110
14184
  writeIf("previous_optimization_mode", null);
14111
14185
  }
14112
14186
  }
14113
14187
  const slot = cv.tier_bias;
14114
14188
  const slotLocked = currentSel.slot_locked === true;
14115
- if (slot && slot !== "auto" && !slotLocked && !_modelLocked) {
14189
+ const canApplySlot = slot && slot !== "auto" && (authoritative || !slotLocked && !_modelLocked);
14190
+ if (canApplySlot) {
14116
14191
  const existingSlot = loadSessionSlot(sid);
14117
14192
  if (existingSlot !== slot) {
14118
14193
  writeSessionSlot(sid, slot);
14194
+ writeIf("active_slot", slot);
14119
14195
  writeIf("vector_changed_slot", slot);
14120
14196
  writeIf("vector_changed_at", Date.now());
14197
+ if (cv.optimization_mode)
14198
+ writeIf("vector_changed_mode", cv.optimization_mode);
14199
+ if (cv.pipeline_root)
14200
+ writeIf("vector_changed_pipeline", JSON.stringify(cv.pipeline_root));
14121
14201
  const applied = applySlot2(slot);
14122
14202
  if (!applied?.ok) {
14123
14203
  console.error(`[vibeOS] failed to apply slot ${slot}: ${applied?.reason || "unknown"}`);
@@ -14162,8 +14242,8 @@ function syncControlSettings(cv, options = {}) {
14162
14242
  if (cv.optimization_mode && cv.optimization_mode !== "vibelitex") {
14163
14243
  const finalSel = loadSelection();
14164
14244
  if (finalSel.optimization_mode === "vibelitex") {
14165
- const liveSlot = String(finalSel.active_slot || currentSel.active_slot || cv.tier_bias || "").toLowerCase();
14166
- const restoreCandidate = finalSel.previous_optimization_mode || loadSessionOptMode(prevSessionKey) || previousOptMode || (liveSlot === "brain" ? "quality" : liveSlot === "medium" ? "vibemax" : "budget");
14245
+ const liveSlot2 = String(finalSel.active_slot || currentSel.active_slot || cv.tier_bias || "").toLowerCase();
14246
+ const restoreCandidate = finalSel.previous_optimization_mode || loadSessionOptMode(prevSessionKey) || previousOptMode || (liveSlot2 === "brain" ? "quality" : liveSlot2 === "medium" ? "vibemax" : "budget");
14167
14247
  if (restoreCandidate && restoreCandidate !== "vibelitex") {
14168
14248
  writeSelection("optimization_mode", restoreCandidate);
14169
14249
  writeSelection("previous_optimization_mode", null);
@@ -14172,7 +14252,19 @@ function syncControlSettings(cv, options = {}) {
14172
14252
  }
14173
14253
  }
14174
14254
  }
14175
- } catch {
14255
+ return {
14256
+ applied_slot: canApplySlot ? slot : currentSel.active_slot || null,
14257
+ applied_mode: cv.optimization_mode || null,
14258
+ applied_pipeline: Array.isArray(cv.pipeline_root) ? cv.pipeline_root : [],
14259
+ authoritative,
14260
+ decision: backendDecision || null,
14261
+ optimization_mode: cv.optimization_mode || null,
14262
+ tier_bias: cv.tier_bias || null,
14263
+ pipeline_root: Array.isArray(cv.pipeline_root) ? cv.pipeline_root : []
14264
+ };
14265
+ } catch (err) {
14266
+ console.error("[vibeOS] syncControlSettings failed:", err?.message || err);
14267
+ return null;
14176
14268
  }
14177
14269
  }
14178
14270
  function pushSystem(output, text) {
@@ -14313,7 +14405,7 @@ async function trackBlackbox(messages) {
14313
14405
  }
14314
14406
  localState.user_text = latestUserIntent;
14315
14407
  const modePreview = peekBudgetFirstMode({
14316
- requestedMode: loadOptimizationMode(),
14408
+ requestedMode: loadOptimizationMode2(),
14317
14409
  subRegime: localState.sub_regime || "INIT",
14318
14410
  stress: st || 0
14319
14411
  });
@@ -14536,55 +14628,98 @@ var onSystemTransform = async (_input, output) => {
14536
14628
  if (latestUserIntent)
14537
14629
  observeUserCorrection(latestUserIntent);
14538
14630
  const classifiedRegime = _latestBlackboxState3?.sub_regime || (latestUserIntent ? await classifyTurnRemote(latestUserIntent) : "INIT");
14539
- const optimizationSuggestion = await selectOptimizationModeRemote(classifiedRegime, latestUserIntent ? scoreStress(latestUserIntent) : 0, loadOptimizationMode());
14540
- const optimizationDecision = applyBudgetFirstMode({
14541
- requestedMode: loadOptimizationMode(),
14542
- suggestedMode: optimizationSuggestion,
14543
- subRegime: classifiedRegime,
14544
- stress: latestUserIntent ? scoreStress(latestUserIntent) : 0,
14545
- nInteractions: _latestBlackboxState3?.n_interactions ?? 0
14546
- });
14547
- const optimizationMode = optimizationDecision.mode;
14631
+ const requestedOptimizationMode = loadOptimizationMode2();
14632
+ const backendAutoModes = /* @__PURE__ */ new Set(["auto", "vibeultrax", "vibeqmax", "vibemax", "vibelitex"]);
14633
+ const useBackendDecision = backendAutoModes.has(String(requestedOptimizationMode || "").toLowerCase());
14634
+ let optimizationDecision = null;
14635
+ let optimizationMode = requestedOptimizationMode;
14548
14636
  let _controlVector = null;
14549
14637
  ensureProjectContext(hookDirectory);
14550
- if (_latestBlackboxState3) {
14551
- const st = latestUserIntent ? scoreStress(latestUserIntent) : 0;
14552
- if (st)
14553
- _latestBlackboxState3.latest_stress_multiplier = st;
14554
- _controlVector = await apiComputeControlVector(_latestBlackboxState3, void 0, optimizationMode);
14555
- if (_controlVector) {
14556
- const fullState = loadBlackboxState() || { sessions: {}, enabled: true };
14557
- fullState.cv = _controlVector;
14558
- if (_latestBlackboxState3) {
14559
- if (_latestBlackboxState3.sub_regime)
14560
- fullState.sub_regime = _latestBlackboxState3.sub_regime;
14561
- if (_latestBlackboxState3.latest_stress_multiplier)
14562
- fullState.latest_stress_multiplier = _latestBlackboxState3.latest_stress_multiplier;
14563
- if (_latestBlackboxState3.n_interactions)
14564
- fullState.n_interactions = _latestBlackboxState3.n_interactions;
14565
- if (_latestBlackboxState3.resolution)
14566
- fullState.resolution = _latestBlackboxState3.resolution;
14567
- if (_latestBlackboxState3.momentum)
14568
- fullState.momentum = _latestBlackboxState3.momentum;
14569
- fullState.latest_control_vector_ts = Date.now();
14570
- }
14571
- fullState.sessions ??= {};
14572
- saveBlackboxState(fullState);
14573
- }
14574
- } else if (latestUserIntent) {
14575
- const st = scoreStress(latestUserIntent);
14576
- _controlVector = await apiComputeControlVector({
14577
- sub_regime: classifiedRegime,
14578
- latest_stress_multiplier: st || void 0,
14579
- user_text: latestUserIntent
14580
- }, void 0, optimizationMode);
14581
- }
14582
- if (!_controlVector) {
14583
- _controlVector = await apiComputeControlVector({
14584
- sub_regime: "INIT",
14585
- latest_stress_multiplier: latestUserIntent ? scoreStress(latestUserIntent) : void 0,
14586
- user_text: latestUserIntent || void 0
14587
- }, void 0, optimizationMode);
14638
+ const st = latestUserIntent ? scoreStress(latestUserIntent) : 0;
14639
+ const cvState = _latestBlackboxState3 ? { ..._latestBlackboxState3, latest_stress_multiplier: st || _latestBlackboxState3.latest_stress_multiplier || 0 } : {
14640
+ sub_regime: classifiedRegime || "INIT",
14641
+ latest_stress_multiplier: st || void 0,
14642
+ user_text: latestUserIntent || void 0
14643
+ };
14644
+ const requestedDecision = {
14645
+ optimization_mode: requestedOptimizationMode,
14646
+ requested_mode: requestedOptimizationMode,
14647
+ requested_slot: null,
14648
+ source: useBackendDecision ? "backend" : "manual"
14649
+ };
14650
+ if (useBackendDecision) {
14651
+ const backendResult = await apiComputeControlVector(cvState, void 0, requestedDecision);
14652
+ optimizationDecision = backendResult?.decision || backendResult || null;
14653
+ _controlVector = backendResult?.control_vector || backendResult || null;
14654
+ optimizationMode = optimizationDecision?.optimization_mode || optimizationMode;
14655
+ } else {
14656
+ _controlVector = computeControlVector2(cvState, void 0, requestedOptimizationMode);
14657
+ optimizationDecision = normalizeBackendDecision({
14658
+ ..._controlVector,
14659
+ decision: {
14660
+ optimization_mode: _controlVector?.optimization_mode || requestedOptimizationMode,
14661
+ tier_bias: _controlVector?.tier_bias || null,
14662
+ pipeline_root: _controlVector?.pipeline_root || [],
14663
+ source: "manual",
14664
+ requested_mode: requestedOptimizationMode,
14665
+ requested_slot: _controlVector?.tier_bias || null
14666
+ }
14667
+ }, requestedOptimizationMode);
14668
+ optimizationMode = optimizationDecision?.optimization_mode || optimizationMode;
14669
+ }
14670
+ if (_controlVector) {
14671
+ const fullState = loadBlackboxState() || { sessions: {}, enabled: true };
14672
+ fullState.cv = _controlVector;
14673
+ if (_latestBlackboxState3) {
14674
+ if (_latestBlackboxState3.sub_regime)
14675
+ fullState.sub_regime = _latestBlackboxState3.sub_regime;
14676
+ if (_latestBlackboxState3.latest_stress_multiplier)
14677
+ fullState.latest_stress_multiplier = _latestBlackboxState3.latest_stress_multiplier;
14678
+ if (_latestBlackboxState3.n_interactions)
14679
+ fullState.n_interactions = _latestBlackboxState3.n_interactions;
14680
+ if (_latestBlackboxState3.resolution)
14681
+ fullState.resolution = _latestBlackboxState3.resolution;
14682
+ if (_latestBlackboxState3.momentum)
14683
+ fullState.momentum = _latestBlackboxState3.momentum;
14684
+ fullState.latest_control_vector_ts = Date.now();
14685
+ }
14686
+ fullState.sessions ??= {};
14687
+ saveBlackboxState(fullState);
14688
+ }
14689
+ try {
14690
+ const blackboxState = loadBlackboxState() || { sessions: {}, enabled: true };
14691
+ const existingSession = blackboxState.sessions?.[_OC_SID3] || null;
14692
+ if (!existingSession || !existingSession.sub_regime) {
14693
+ const sessionState = _latestBlackboxState3 || {
14694
+ sub_regime: classifiedRegime || "INIT",
14695
+ resolution: "unresolved",
14696
+ momentum: 0
14697
+ };
14698
+ const turnCounter = Number(existingSession?.turn_counter || 0) + 1;
14699
+ const controlHistory = Array.isArray(existingSession?.control_history) ? [...existingSession.control_history] : [];
14700
+ if (_controlVector) {
14701
+ const entry = buildControlHistoryEntry2(turnCounter, sessionState.sub_regime || "INIT", _controlVector);
14702
+ const lastEntry = controlHistory[controlHistory.length - 1];
14703
+ if (!lastEntry || JSON.stringify(lastEntry) !== JSON.stringify(entry)) {
14704
+ controlHistory.push(entry);
14705
+ }
14706
+ }
14707
+ blackboxState.sessions ??= {};
14708
+ blackboxState.sessions[_OC_SID3] = {
14709
+ ...existingSession,
14710
+ project_fingerprint: currentProjectFingerprint || existingSession?.project_fingerprint || "",
14711
+ sub_regime: sessionState.sub_regime || existingSession?.sub_regime || "INIT",
14712
+ regime: sessionState.sub_regime || existingSession?.regime || "INIT",
14713
+ resolution: sessionState.resolution || existingSession?.resolution || "unresolved",
14714
+ momentum: sessionState.momentum ?? existingSession?.momentum ?? 0,
14715
+ control_history: controlHistory,
14716
+ optimization_mode: optimizationDecision?.optimization_mode || existingSession?.optimization_mode || null,
14717
+ active_slot: optimizationDecision?.tier_bias || _controlVector?.tier_bias || existingSession?.active_slot || null,
14718
+ turn_counter: turnCounter
14719
+ };
14720
+ saveBlackboxState(blackboxState);
14721
+ }
14722
+ } catch {
14588
14723
  }
14589
14724
  const system = output?.system;
14590
14725
  if (!Array.isArray(system))
@@ -14613,7 +14748,27 @@ var onSystemTransform = async (_input, output) => {
14613
14748
  }
14614
14749
  }
14615
14750
  const sel = loadSelection();
14616
- syncControlSettings(_controlVector, { persistOptimizationMode: optimizationDecision.shouldPersistRequestedMode });
14751
+ const syncResult = syncControlSettings(_controlVector, {
14752
+ persistOptimizationMode: true,
14753
+ backendDecision: optimizationDecision,
14754
+ authoritative: useBackendDecision
14755
+ });
14756
+ if (useBackendDecision && syncResult) {
14757
+ try {
14758
+ const client2 = getApiClient();
14759
+ if (client2 && !isApiFallback()) {
14760
+ await client2.blackboxState(_OC_SID3, {
14761
+ applied_slot: syncResult.applied_slot,
14762
+ applied_mode: syncResult.applied_mode,
14763
+ applied_pipeline: syncResult.applied_pipeline,
14764
+ source: optimizationDecision?.source || "backend",
14765
+ requested_mode: optimizationDecision?.requested_mode || requestedOptimizationMode,
14766
+ requested_slot: optimizationDecision?.requested_slot || null
14767
+ });
14768
+ }
14769
+ } catch {
14770
+ }
14771
+ }
14617
14772
  const fp2 = ensureProjectContext(hookDirectory);
14618
14773
  const rawStress = latestUserIntent ? scoreStress(latestUserIntent) : 0;
14619
14774
  const stressScore = rawStress * (_controlVector?.stress_multiplier ?? 1);
@@ -15096,6 +15251,40 @@ function footerDebug(...args) {
15096
15251
  function getVibeOSHome10() {
15097
15252
  return process.env.VIBEOS_HOME || join19(process.env.HOME || "", ".claude");
15098
15253
  }
15254
+ var _cachedAutoMode = null;
15255
+ var _cachedAutoModeTs = 0;
15256
+ var AUTO_CACHE_TTL = 6e4;
15257
+ var DEFAULT_REGIME_MAP = {
15258
+ LOOPING: "vibemax",
15259
+ DIVERGENT: "vibemax",
15260
+ EXPLORING: "vibemax",
15261
+ INIT: "vibemax",
15262
+ REFINING: "vibemax",
15263
+ CONVERGING: "quality",
15264
+ CLOSED: "quality"
15265
+ };
15266
+ function regimeToMode(regime, stress) {
15267
+ if (stress > 1.5)
15268
+ return "quality";
15269
+ return DEFAULT_REGIME_MAP[regime] || "vibemax";
15270
+ }
15271
+ async function apiAutoSelectMode(regime, stress) {
15272
+ const now = Date.now();
15273
+ if (_cachedAutoMode && now - _cachedAutoModeTs < AUTO_CACHE_TTL)
15274
+ return _cachedAutoMode;
15275
+ try {
15276
+ const res = await remoteCall("blackboxSelectMode", [regime, stress], null);
15277
+ if (res?.mode) {
15278
+ _cachedAutoMode = res.mode;
15279
+ _cachedAutoModeTs = now;
15280
+ return res.mode;
15281
+ }
15282
+ } catch (e) {
15283
+ footerDebug("[vibeOS] apiAutoSelectMode error:", e.message);
15284
+ }
15285
+ const fallback2 = regimeToMode(regime, stress);
15286
+ return fallback2 || "balanced";
15287
+ }
15099
15288
  var STATE_FILE2 = join19(getVibeOSHome10(), "delegation-state.json");
15100
15289
  var SAVINGS_LEDGER_FILE2 = join19(getVibeOSHome10(), "savings-ledger.jsonl");
15101
15290
  var _prevOutputText = "";
@@ -15353,12 +15542,13 @@ async function _appendFooter(input, output, directory3) {
15353
15542
  if (stripped === _lastStrippedText && !claimTag)
15354
15543
  return;
15355
15544
  const ltTotal = ltTasks + ltCache;
15356
- const activeSlot = selNowFooter.active_slot || "brain";
15545
+ const backendMode = String(selNowFooter.requested_optimization_mode || selNowFooter.optimization_mode || loadOptimizationMode2() || _latestBlackboxState?.optimization_mode || "").trim().toLowerCase();
15546
+ const displayMode = backendMode || (isApiConnected() ? await apiAutoSelectMode(currentSubRegime, _footerStress) : autoSelectMode2(currentSubRegime, _footerStress));
15547
+ const activeSlot = displayMode === "vibeultrax" ? "cheap" : selNowFooter.active_slot || resolveOptimizationSlot(displayMode) || "brain";
15357
15548
  const flashIcon = isApiConnected() ? " \u26A1" : "";
15358
- const displayMode = autoSelectMode2(currentSubRegime, _footerStress);
15359
- const rawMode = (typeof loadSelection2 === "function" ? loadSelection2()?.requested_optimization_mode || loadSelection2()?.optimization_mode : null) || displayMode;
15549
+ const rawMode = displayMode;
15360
15550
  const cv = computeControlVector2({ sub_regime: currentSubRegime, latest_stress_multiplier: _footerStress, user_text: latestUserIntent || "" }, void 0, rawMode);
15361
- const vibeBrand = resolveBrand(loadOptimizationMode() || displayMode, activeSlot);
15551
+ const vibeBrand = resolveBrand(displayMode, activeSlot);
15362
15552
  let _rewardTag = "";
15363
15553
  let _rewardOutcome = null;
15364
15554
  let _rewardCredits = 0;
@@ -17833,8 +18023,9 @@ var onToolExecuteAfter = async (input, output) => {
17833
18023
  modelLocked: _modelLocked,
17834
18024
  quietIntent: isGreetingLike2(latestUserIntent || "")
17835
18025
  });
17836
- const activeSlot = selNow.active_slot || (execution.quality === "brain" ? "brain" : execution.quality === "medium" ? "medium" : "cheap");
17837
- const displayMode = autoSelectMode2(currentSubRegime, latestUserIntent ? scoreStress(latestUserIntent) : 0);
18026
+ const backendMode = String(selNow.requested_optimization_mode || selNow.optimization_mode || loadOptimizationMode() || loadBlackboxState()?.cv?.optimization_mode || "").trim().toLowerCase();
18027
+ const displayMode = backendMode || autoSelectMode2(currentSubRegime, latestUserIntent ? scoreStress(latestUserIntent) : 0);
18028
+ const activeSlot = displayMode === "vibeultrax" ? "cheap" : selNow.active_slot || resolveOptimizationSlot(displayMode) || (execution.quality === "brain" ? "brain" : execution.quality === "medium" ? "medium" : "cheap");
17838
18029
  const vibeBrand = resolveBrand(displayMode, activeSlot);
17839
18030
  const sessionSlot = loadSessionSlot(currentSid);
17840
18031
  const flashIcon = isApiConnected() ? " \u26A1" : "";
@@ -18738,6 +18929,7 @@ async function ensureMcpServerRunning() {
18738
18929
  getSessionOrchestration: (sessionId) => loadSessionOrchestration(sessionId),
18739
18930
  mutateSessionOrchestration: (sessionId, mutator) => mutateSessionOrchestration(sessionId, mutator),
18740
18931
  listSessionTemplates: () => TEMPLATE_LIBRARY,
18932
+ currentProjectName: currentProjectName || "",
18741
18933
  listReports: (filter) => {
18742
18934
  if (!existsSync21(getReportsDir2())) {
18743
18935
  const e = new Error("reports dir not found");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibeostheog",
3
- "version": "0.25.52",
3
+ "version": "0.25.53",
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",