vibeostheog 0.24.18 → 0.24.21
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 +17 -0
- package/dist/vibeOS.js +125 -84
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
## 0.24.21
|
|
2
|
+
- feat: pass user_text to RF prediction engine via control-vector API (#146)
|
|
3
|
+
- feat: pass user_text to RF prediction engine via control-vector API
|
|
4
|
+
- fix: extend ci test timeout
|
|
5
|
+
- fix: use EMBEDDED_API_TOKEN as bootstrap token fallback instead of direct API token (#148)
|
|
6
|
+
- fix: repair reload recovery and fallback mode state (#147)
|
|
7
|
+
- test: cover cold start maintenance user flow (#144)
|
|
8
|
+
- chore: v0.24.20
|
|
9
|
+
- chore: v0.24.19 (#145)
|
|
10
|
+
Prune stale active jobs and stabilize report tests
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## 0.24.19
|
|
14
|
+
- test: cover cold start maintenance user flow (#144)
|
|
15
|
+
Prune stale active jobs and stabilize report tests
|
|
16
|
+
|
|
17
|
+
|
|
1
18
|
## 0.24.18
|
|
2
19
|
- fix: keep Return codename through 0.24 patch releases (#143)
|
|
3
20
|
- fix: preserve live metrics context in reports (#137)
|
package/dist/vibeOS.js
CHANGED
|
@@ -1104,7 +1104,7 @@ var init_vibemax = __esm({
|
|
|
1104
1104
|
|
|
1105
1105
|
// src/index.ts
|
|
1106
1106
|
init_flow_enforcer();
|
|
1107
|
-
import { readFileSync as readFileSync17, writeFileSync as writeFileSync15, existsSync as existsSync18, mkdirSync as mkdirSync13, copyFileSync as copyFileSync2, renameSync as renameSync6 } from "node:fs";
|
|
1107
|
+
import { readFileSync as readFileSync17, writeFileSync as writeFileSync15, existsSync as existsSync18, mkdirSync as mkdirSync13, copyFileSync as copyFileSync2, renameSync as renameSync6, statSync as statSync9 } from "node:fs";
|
|
1108
1108
|
import { join as join18, dirname as dirname13, basename as basename5 } from "node:path";
|
|
1109
1109
|
|
|
1110
1110
|
// src/vibeOS-lib/session-metrics.js
|
|
@@ -2117,8 +2117,8 @@ function readBootstrapTokenFromDisk() {
|
|
|
2117
2117
|
return "";
|
|
2118
2118
|
}
|
|
2119
2119
|
var VIBEOS_API_DISABLED = readApiDisabledFromDisk() || isTruthyFlag(process.env.VIBEOS_API_DISABLED);
|
|
2120
|
-
var VIBEOS_API_TOKEN = VIBEOS_API_DISABLED ? "" : readTokenFromDisk() || normalizeApiToken(process.env.VIBEOS_API_TOKEN, "")
|
|
2121
|
-
var VIBEOS_API_BOOTSTRAP_TOKEN = VIBEOS_API_DISABLED ? "" : readBootstrapTokenFromDisk() || process.env.VIBEOS_API_BOOTSTRAP_TOKEN ||
|
|
2120
|
+
var VIBEOS_API_TOKEN = VIBEOS_API_DISABLED ? "" : readTokenFromDisk() || normalizeApiToken(process.env.VIBEOS_API_TOKEN, "");
|
|
2121
|
+
var VIBEOS_API_BOOTSTRAP_TOKEN = VIBEOS_API_DISABLED ? "" : readBootstrapTokenFromDisk() || process.env.VIBEOS_API_BOOTSTRAP_TOKEN || EMBEDDED_API_TOKEN;
|
|
2122
2122
|
var VIBEOS_API_ENABLED = !VIBEOS_API_DISABLED && process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN);
|
|
2123
2123
|
var _anomalyDetector = null;
|
|
2124
2124
|
function getAnomalyDetector() {
|
|
@@ -2284,7 +2284,7 @@ function syncApiTokenFromDisk() {
|
|
|
2284
2284
|
console.error("[vibeOS] API token loaded from VIBEOS_API_TOKEN env var");
|
|
2285
2285
|
} else {
|
|
2286
2286
|
VIBEOS_API_DISABLED = false;
|
|
2287
|
-
|
|
2287
|
+
VIBEOS_API_BOOTSTRAP_TOKEN ||= EMBEDDED_API_TOKEN;
|
|
2288
2288
|
VIBEOS_API_ENABLED = process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN);
|
|
2289
2289
|
}
|
|
2290
2290
|
}
|
|
@@ -2299,7 +2299,7 @@ function getApiClient2() {
|
|
|
2299
2299
|
}
|
|
2300
2300
|
return _apiClient;
|
|
2301
2301
|
}
|
|
2302
|
-
function
|
|
2302
|
+
function isApiFallback2() {
|
|
2303
2303
|
return _apiFallbackMode || !VIBEOS_API_ENABLED;
|
|
2304
2304
|
}
|
|
2305
2305
|
function isApiConnected2() {
|
|
@@ -2403,7 +2403,7 @@ function loadSelection() {
|
|
|
2403
2403
|
return DFLT_SEL;
|
|
2404
2404
|
const st = statSync3(TIERS_FILE3);
|
|
2405
2405
|
if (st.size > 10485760) {
|
|
2406
|
-
|
|
2406
|
+
_handleStateCorruption2(TIERS_FILE3);
|
|
2407
2407
|
return DFLT_SEL;
|
|
2408
2408
|
}
|
|
2409
2409
|
const j = safeJsonParse2(readFileSync3(TIERS_FILE3, "utf-8"));
|
|
@@ -2430,7 +2430,7 @@ function loadSelection() {
|
|
|
2430
2430
|
previous_default_agent: j?.selection?.previous_default_agent || null
|
|
2431
2431
|
};
|
|
2432
2432
|
} catch {
|
|
2433
|
-
|
|
2433
|
+
_handleStateCorruption2(TIERS_FILE3);
|
|
2434
2434
|
return DFLT_SEL;
|
|
2435
2435
|
}
|
|
2436
2436
|
}
|
|
@@ -3453,7 +3453,7 @@ function runStartupMaintenanceOnce() {
|
|
|
3453
3453
|
} catch {
|
|
3454
3454
|
}
|
|
3455
3455
|
}
|
|
3456
|
-
function
|
|
3456
|
+
function _handleStateCorruption2(path) {
|
|
3457
3457
|
const backupDir = join4(VIBEOS_HOME, ".backups");
|
|
3458
3458
|
mkdirSync3(backupDir, { recursive: true });
|
|
3459
3459
|
const backupPath = join4(backupDir, basename2(path) + ".corrupted." + Date.now());
|
|
@@ -3558,12 +3558,12 @@ function readJsonOrEmpty(filePath) {
|
|
|
3558
3558
|
return {};
|
|
3559
3559
|
const st = statSync4(filePath);
|
|
3560
3560
|
if (st.size > 10485760) {
|
|
3561
|
-
|
|
3561
|
+
_handleStateCorruption2(filePath);
|
|
3562
3562
|
return {};
|
|
3563
3563
|
}
|
|
3564
3564
|
return safeJsonParse3(readFileSync4(filePath, "utf-8"));
|
|
3565
3565
|
} catch {
|
|
3566
|
-
|
|
3566
|
+
_handleStateCorruption2(filePath);
|
|
3567
3567
|
return {};
|
|
3568
3568
|
}
|
|
3569
3569
|
}
|
|
@@ -3614,12 +3614,12 @@ function readFullState() {
|
|
|
3614
3614
|
return {};
|
|
3615
3615
|
const st = statSync4(delegationStateFile);
|
|
3616
3616
|
if (st.size > 10485760) {
|
|
3617
|
-
|
|
3617
|
+
_handleStateCorruption2(delegationStateFile);
|
|
3618
3618
|
return {};
|
|
3619
3619
|
}
|
|
3620
3620
|
return safeJsonParse3(readFileSync4(delegationStateFile, "utf-8"));
|
|
3621
3621
|
} catch {
|
|
3622
|
-
|
|
3622
|
+
_handleStateCorruption2(delegationStateFile);
|
|
3623
3623
|
return {};
|
|
3624
3624
|
}
|
|
3625
3625
|
}
|
|
@@ -3659,7 +3659,7 @@ function loadGlobalLearning() {
|
|
|
3659
3659
|
return DFLT_GL;
|
|
3660
3660
|
const st = statSync4(globalLearningFile);
|
|
3661
3661
|
if (st.size > 10485760) {
|
|
3662
|
-
|
|
3662
|
+
_handleStateCorruption2(globalLearningFile);
|
|
3663
3663
|
return DFLT_GL;
|
|
3664
3664
|
}
|
|
3665
3665
|
const j = safeJsonParse3(readFileSync4(globalLearningFile, "utf-8"));
|
|
@@ -3672,7 +3672,7 @@ function loadGlobalLearning() {
|
|
|
3672
3672
|
j.context7_last_seen ??= null;
|
|
3673
3673
|
return j;
|
|
3674
3674
|
} catch {
|
|
3675
|
-
|
|
3675
|
+
_handleStateCorruption2(globalLearningFile);
|
|
3676
3676
|
return DFLT_GL;
|
|
3677
3677
|
}
|
|
3678
3678
|
}
|
|
@@ -3734,7 +3734,7 @@ function loadBlackboxState() {
|
|
|
3734
3734
|
return { enabled: true, sessions: {} };
|
|
3735
3735
|
const st = statSync4(blackboxFile);
|
|
3736
3736
|
if (st.size > 10485760) {
|
|
3737
|
-
|
|
3737
|
+
_handleStateCorruption2(blackboxFile);
|
|
3738
3738
|
return { enabled: false, sessions: {} };
|
|
3739
3739
|
}
|
|
3740
3740
|
const raw = safeJsonParse3(readFileSync4(blackboxFile, "utf-8")) || { enabled: false, sessions: {} };
|
|
@@ -3774,7 +3774,7 @@ function loadBlackboxState() {
|
|
|
3774
3774
|
}
|
|
3775
3775
|
return raw;
|
|
3776
3776
|
} catch {
|
|
3777
|
-
|
|
3777
|
+
_handleStateCorruption2(blackboxFile);
|
|
3778
3778
|
return { enabled: false, sessions: {} };
|
|
3779
3779
|
}
|
|
3780
3780
|
}
|
|
@@ -4281,7 +4281,7 @@ function _readActiveJobsRaw() {
|
|
|
4281
4281
|
const raw = safeJsonParse3(readFileSync4(ACTIVE_JOBS_FILE, "utf-8"));
|
|
4282
4282
|
return raw && typeof raw === "object" ? raw : {};
|
|
4283
4283
|
} catch {
|
|
4284
|
-
|
|
4284
|
+
_handleStateCorruption2(ACTIVE_JOBS_FILE);
|
|
4285
4285
|
return {};
|
|
4286
4286
|
}
|
|
4287
4287
|
}
|
|
@@ -4337,7 +4337,7 @@ function loadActiveJobs() {
|
|
|
4337
4337
|
const now = Date.now();
|
|
4338
4338
|
for (const [key, value] of Object.entries(raw || {})) {
|
|
4339
4339
|
const norm = _normalizeActiveJobRecord(value, now, true);
|
|
4340
|
-
if (!norm.record) {
|
|
4340
|
+
if (!norm.record || norm.stale && norm.record.status === "completed" && norm.record.completedAt) {
|
|
4341
4341
|
changed = true;
|
|
4342
4342
|
continue;
|
|
4343
4343
|
}
|
|
@@ -4350,7 +4350,7 @@ function loadActiveJobs() {
|
|
|
4350
4350
|
return next;
|
|
4351
4351
|
});
|
|
4352
4352
|
} catch {
|
|
4353
|
-
|
|
4353
|
+
_handleStateCorruption2(ACTIVE_JOBS_FILE);
|
|
4354
4354
|
return {};
|
|
4355
4355
|
}
|
|
4356
4356
|
}
|
|
@@ -5543,7 +5543,7 @@ function _loadDynamicPricingCache() {
|
|
|
5543
5543
|
return {};
|
|
5544
5544
|
const st = statSync5(PRICING_CACHE_FILE2);
|
|
5545
5545
|
if (st.size > 10485760) {
|
|
5546
|
-
|
|
5546
|
+
_handleStateCorruption2(PRICING_CACHE_FILE2);
|
|
5547
5547
|
_dynamicPricingCache = {};
|
|
5548
5548
|
return {};
|
|
5549
5549
|
}
|
|
@@ -5551,7 +5551,7 @@ function _loadDynamicPricingCache() {
|
|
|
5551
5551
|
const map = raw?.models && typeof raw.models === "object" ? raw.models : {};
|
|
5552
5552
|
_dynamicPricingCache = map;
|
|
5553
5553
|
} catch {
|
|
5554
|
-
|
|
5554
|
+
_handleStateCorruption2(PRICING_CACHE_FILE2);
|
|
5555
5555
|
_dynamicPricingCache = {};
|
|
5556
5556
|
}
|
|
5557
5557
|
return _dynamicPricingCache;
|
|
@@ -5646,7 +5646,7 @@ function _loadPricingOverrides() {
|
|
|
5646
5646
|
return {};
|
|
5647
5647
|
const st = statSync5(tiersFile);
|
|
5648
5648
|
if (st.size > 10485760) {
|
|
5649
|
-
|
|
5649
|
+
_handleStateCorruption2(tiersFile);
|
|
5650
5650
|
_pricingOverridesCache = {};
|
|
5651
5651
|
return {};
|
|
5652
5652
|
}
|
|
@@ -5677,7 +5677,7 @@ function _loadPricingOverrides() {
|
|
|
5677
5677
|
}
|
|
5678
5678
|
_pricingOverridesCache = out;
|
|
5679
5679
|
} catch {
|
|
5680
|
-
|
|
5680
|
+
_handleStateCorruption2(join5(home, "model-tiers.json"));
|
|
5681
5681
|
_pricingOverridesCache = {};
|
|
5682
5682
|
}
|
|
5683
5683
|
return _pricingOverridesCache;
|
|
@@ -5813,7 +5813,7 @@ function loadSelection2() {
|
|
|
5813
5813
|
return DFLT_SEL2;
|
|
5814
5814
|
const st = statSync5(TIERS_FILE3);
|
|
5815
5815
|
if (st.size > 10485760) {
|
|
5816
|
-
|
|
5816
|
+
_handleStateCorruption2(TIERS_FILE3);
|
|
5817
5817
|
return DFLT_SEL2;
|
|
5818
5818
|
}
|
|
5819
5819
|
const j = safeJsonParse3(readFileSync5(TIERS_FILE3, "utf-8"));
|
|
@@ -5836,7 +5836,7 @@ function loadSelection2() {
|
|
|
5836
5836
|
executed_model: j?.selection?.executed_model || null
|
|
5837
5837
|
};
|
|
5838
5838
|
} catch {
|
|
5839
|
-
|
|
5839
|
+
_handleStateCorruption2(TIERS_FILE3);
|
|
5840
5840
|
return DFLT_SEL2;
|
|
5841
5841
|
}
|
|
5842
5842
|
}
|
|
@@ -6064,7 +6064,7 @@ function loadTrinitySlotsFromTiersFile() {
|
|
|
6064
6064
|
return false;
|
|
6065
6065
|
const st = statSync5(TIERS_FILE3);
|
|
6066
6066
|
if (st.size > 10485760) {
|
|
6067
|
-
|
|
6067
|
+
_handleStateCorruption2(TIERS_FILE3);
|
|
6068
6068
|
return false;
|
|
6069
6069
|
}
|
|
6070
6070
|
const tiersData = safeJsonParse3(readFileSync5(TIERS_FILE3, "utf-8")) || {};
|
|
@@ -6774,7 +6774,7 @@ function classifyTurnSimple2(userText) {
|
|
|
6774
6774
|
async function classifyTurnRemote(text) {
|
|
6775
6775
|
try {
|
|
6776
6776
|
const client2 = getApiClient2();
|
|
6777
|
-
if (!client2 ||
|
|
6777
|
+
if (!client2 || isApiFallback2())
|
|
6778
6778
|
return classifyTurnSimple(text);
|
|
6779
6779
|
const res = await client2.classifyQuery(text);
|
|
6780
6780
|
if (res && typeof res === "object" && "sub_regime" in res) {
|
|
@@ -6805,7 +6805,7 @@ function resolveOptimizationMode(subRegime, stressMultiplier, optimizationMode)
|
|
|
6805
6805
|
const normalized = String(optimizationMode || "auto").toLowerCase();
|
|
6806
6806
|
if (normalized === "auto" || normalized === "")
|
|
6807
6807
|
return autoSelectMode2(subRegime || "INIT", stressMultiplier);
|
|
6808
|
-
if (
|
|
6808
|
+
if (isApiFallback2())
|
|
6809
6809
|
return "vibelitex";
|
|
6810
6810
|
if (normalized === "balanced" || normalized === "budget" || normalized === "quality" || normalized === "speed" || normalized === "longrun" || normalized === "audit" || normalized === "forensic" || normalized === "vibeultrax" || normalized === "vibeqmax" || normalized === "vibemax" || normalized === "vibelitex") {
|
|
6811
6811
|
return normalized;
|
|
@@ -6817,7 +6817,7 @@ async function selectOptimizationModeRemote(subRegime, stressMultiplier, fallbac
|
|
|
6817
6817
|
const fallback2 = resolveOptimizationMode(subRegime, stressMultiplier, fallbackMode);
|
|
6818
6818
|
if (normalizedRequestedMode !== "auto" && normalizedRequestedMode !== "")
|
|
6819
6819
|
return fallback2;
|
|
6820
|
-
if (
|
|
6820
|
+
if (isApiFallback2())
|
|
6821
6821
|
return fallback2;
|
|
6822
6822
|
try {
|
|
6823
6823
|
const client2 = getApiClient2();
|
|
@@ -7085,7 +7085,7 @@ function resolveEnforcementMode() {
|
|
|
7085
7085
|
async function syncOutcomeToApi(outcome) {
|
|
7086
7086
|
try {
|
|
7087
7087
|
const client2 = getApiClient2();
|
|
7088
|
-
if (!client2 ||
|
|
7088
|
+
if (!client2 || isApiFallback2())
|
|
7089
7089
|
return;
|
|
7090
7090
|
await client2.blackboxOutcome(_OC_SID, outcome);
|
|
7091
7091
|
} catch {
|
|
@@ -7094,7 +7094,7 @@ async function syncOutcomeToApi(outcome) {
|
|
|
7094
7094
|
async function fetchBlackboxEnrichment(sessionId, localState) {
|
|
7095
7095
|
try {
|
|
7096
7096
|
const client2 = getApiClient2();
|
|
7097
|
-
if (!client2 ||
|
|
7097
|
+
if (!client2 || isApiFallback2())
|
|
7098
7098
|
return null;
|
|
7099
7099
|
const result = await client2.blackboxAnalyze(sessionId, {
|
|
7100
7100
|
userText: "",
|
|
@@ -7638,12 +7638,12 @@ function readJsonOrEmpty2(filePath) {
|
|
|
7638
7638
|
return {};
|
|
7639
7639
|
const st = statSync6(filePath);
|
|
7640
7640
|
if (st.size > 10485760) {
|
|
7641
|
-
|
|
7641
|
+
_handleStateCorruption2(filePath);
|
|
7642
7642
|
return {};
|
|
7643
7643
|
}
|
|
7644
7644
|
return safeJsonParse3(readFileSync10(filePath, "utf-8"));
|
|
7645
7645
|
} catch {
|
|
7646
|
-
|
|
7646
|
+
_handleStateCorruption2(filePath);
|
|
7647
7647
|
return {};
|
|
7648
7648
|
}
|
|
7649
7649
|
}
|
|
@@ -10565,7 +10565,11 @@ async function apiComputeControlVector(state, action, optimizationMode) {
|
|
|
10565
10565
|
const res = await remoteCall("blackboxControlVector", [state, action, optimizationMode], null);
|
|
10566
10566
|
if (res?.control_vector) {
|
|
10567
10567
|
const local = computeControlVector2(state, action, optimizationMode);
|
|
10568
|
-
|
|
10568
|
+
const merged = mergeRemoteControlVector(res.control_vector, local);
|
|
10569
|
+
if (res.rf_prediction?.mode && res.rf_prediction.mode !== res.control_vector?.optimization_mode) {
|
|
10570
|
+
merged.optimization_mode = res.rf_prediction.mode;
|
|
10571
|
+
}
|
|
10572
|
+
return merged;
|
|
10569
10573
|
}
|
|
10570
10574
|
} catch {
|
|
10571
10575
|
}
|
|
@@ -10749,7 +10753,8 @@ function syncControlSettings(cv, options = {}) {
|
|
|
10749
10753
|
writeIf("thinking_level", nextThinking);
|
|
10750
10754
|
}
|
|
10751
10755
|
if (persistOptimizationMode && cv.optimization_mode && userOptMode !== "auto") {
|
|
10752
|
-
|
|
10756
|
+
const fallbackPinned = isApiFallback() && cv.optimization_mode === "vibelitex" && currentSel.optimization_mode !== "vibelitex";
|
|
10757
|
+
if (!fallbackPinned && userOptMode !== cv.optimization_mode) {
|
|
10753
10758
|
writeIf("optimization_mode", cv.optimization_mode);
|
|
10754
10759
|
}
|
|
10755
10760
|
}
|
|
@@ -10929,6 +10934,7 @@ async function trackBlackbox(messages) {
|
|
|
10929
10934
|
localState.latest_stress_multiplier = st;
|
|
10930
10935
|
saveSessionStress(st, st > 1.5 ? "critical" : st > 0.7 ? "elevated" : st > 0.3 ? "moderate" : "none");
|
|
10931
10936
|
}
|
|
10937
|
+
localState.user_text = latestUserIntent;
|
|
10932
10938
|
const modePreview = peekBudgetFirstMode({
|
|
10933
10939
|
requestedMode: loadOptimizationMode(),
|
|
10934
10940
|
subRegime: localState.sub_regime || "INIT",
|
|
@@ -11083,13 +11089,15 @@ var onSystemTransform = async (_input, output) => {
|
|
|
11083
11089
|
const st = scoreStress(latestUserIntent);
|
|
11084
11090
|
_controlVector = await apiComputeControlVector({
|
|
11085
11091
|
sub_regime: classifiedRegime,
|
|
11086
|
-
latest_stress_multiplier: st || void 0
|
|
11092
|
+
latest_stress_multiplier: st || void 0,
|
|
11093
|
+
user_text: latestUserIntent
|
|
11087
11094
|
}, void 0, optimizationMode);
|
|
11088
11095
|
}
|
|
11089
11096
|
if (!_controlVector) {
|
|
11090
11097
|
_controlVector = await apiComputeControlVector({
|
|
11091
11098
|
sub_regime: "INIT",
|
|
11092
|
-
latest_stress_multiplier: latestUserIntent ? scoreStress(latestUserIntent) : void 0
|
|
11099
|
+
latest_stress_multiplier: latestUserIntent ? scoreStress(latestUserIntent) : void 0,
|
|
11100
|
+
user_text: latestUserIntent || void 0
|
|
11093
11101
|
}, void 0, optimizationMode);
|
|
11094
11102
|
}
|
|
11095
11103
|
const system = output?.system;
|
|
@@ -13570,26 +13578,28 @@ ${argsJson}
|
|
|
13570
13578
|
}
|
|
13571
13579
|
costDetector.record(modelCost);
|
|
13572
13580
|
}
|
|
13573
|
-
|
|
13574
|
-
|
|
13581
|
+
const tLower = String(t || "").toLowerCase();
|
|
13582
|
+
const lowCreditNudge = _credit < 40 && !compatibilityMode;
|
|
13583
|
+
if (lowCreditNudge) {
|
|
13584
|
+
const total = recordSaving(t, "credit<40% high-tier", _estEdit, {
|
|
13575
13585
|
firstWord: _firstWord,
|
|
13576
13586
|
projectFingerprint: currentProjectFingerprint,
|
|
13577
13587
|
projectName: currentProjectName || "",
|
|
13578
13588
|
sessionId: getCurrentSessionId()
|
|
13579
13589
|
});
|
|
13580
|
-
const msg = `[vibeOS] Quick win: ${resolveTierIcon("cheap")} cheap lane open \xB7 switch to ${resolveTierIcon("medium")} medium to save about ~$${
|
|
13590
|
+
const msg = `[vibeOS] Quick win: ${resolveTierIcon("cheap")} cheap lane open \xB7 switch to ${resolveTierIcon("medium")} medium to save about ~$${_estEdit.toFixed(3)}/turn.`;
|
|
13581
13591
|
if (shouldLogWarn(`${t}|credit|${_tierWord}`) && process.env.VIBEOS_DEBUG_DELEGATION === "1") {
|
|
13582
13592
|
console.error(`[vibeOS] [delegation] ${msg}`);
|
|
13583
13593
|
}
|
|
13584
13594
|
pendingUiNote = msg;
|
|
13585
|
-
|
|
13595
|
+
if (!WARN_ON_DIRECT.has(tLower))
|
|
13596
|
+
return;
|
|
13586
13597
|
}
|
|
13587
|
-
if (WARN_ON_DIRECT.has(
|
|
13598
|
+
if (WARN_ON_DIRECT.has(tLower)) {
|
|
13588
13599
|
const argSources = _toolArgSources(input, output);
|
|
13589
13600
|
if (process.env.VIBEOS_DEBUG_DELEGATION === "1")
|
|
13590
13601
|
console.error(`[vibeOS] [enforce-debug] tool=${t} tier=${currentTier} enforce=${sel?.delegation_enforce} argsType=${typeof args} argsExists=${argSources.length > 0}`);
|
|
13591
|
-
|
|
13592
|
-
if (!compatibilityMode && sel.delegation_enforce && currentTier === "high" && argSources.length > 0) {
|
|
13602
|
+
if (!compatibilityMode && sel.delegation_enforce && currentTier === "high") {
|
|
13593
13603
|
const originalPath = argSources.flatMap((src) => [src?.filePath, src?.file_path, src?.path]).find((v) => typeof v === "string" && v.trim()) || "";
|
|
13594
13604
|
const basename6 = originalPath.split("/").pop() || "blocked";
|
|
13595
13605
|
const apiResult = await remoteCall("delegateCheck", [tLower, currentTier, currentModel, _prompt], () => ({
|
|
@@ -13599,32 +13609,36 @@ ${argsJson}
|
|
|
13599
13609
|
const isBlocked = apiResult?.blocked !== false;
|
|
13600
13610
|
const savings = apiResult?.savings ?? _estEdit;
|
|
13601
13611
|
if (isBlocked) {
|
|
13602
|
-
|
|
13603
|
-
|
|
13604
|
-
|
|
13605
|
-
|
|
13606
|
-
|
|
13607
|
-
|
|
13612
|
+
if (!lowCreditNudge) {
|
|
13613
|
+
const total = recordSaving(t, "delegation enforced", savings, {
|
|
13614
|
+
firstWord: _firstWord,
|
|
13615
|
+
projectFingerprint: currentProjectFingerprint,
|
|
13616
|
+
projectName: currentProjectName || "",
|
|
13617
|
+
sessionId: getCurrentSessionId()
|
|
13618
|
+
});
|
|
13619
|
+
}
|
|
13608
13620
|
pendingUiNote = `[delegation] This is a good candidate for a Task subagent \u2014 ${resolveTierIcon("brain")} brain handles orchestration, let cheaper tiers do the write/edit. Switch to ${resolveTierIcon("medium")} medium with \`trinity medium\` if you'd rather do it directly.`;
|
|
13609
13621
|
enforcementBlocked = true;
|
|
13610
13622
|
if (shouldLogWarn(`${t}|enforced|${_tierWord}`))
|
|
13611
13623
|
console.error(`[vibeOS] [enforcement] BLOCKED direct ${t} on high tier \u2192 delegate via Task`);
|
|
13612
13624
|
return;
|
|
13613
13625
|
}
|
|
13614
|
-
|
|
13615
|
-
|
|
13616
|
-
|
|
13617
|
-
|
|
13618
|
-
|
|
13619
|
-
|
|
13620
|
-
|
|
13621
|
-
|
|
13622
|
-
|
|
13623
|
-
|
|
13624
|
-
|
|
13626
|
+
if (!lowCreditNudge) {
|
|
13627
|
+
const total = recordSaving(t, "direct edit", _estEdit, {
|
|
13628
|
+
firstWord: _firstWord,
|
|
13629
|
+
projectFingerprint: currentProjectFingerprint,
|
|
13630
|
+
projectName: currentProjectName || "",
|
|
13631
|
+
sessionId: getCurrentSessionId()
|
|
13632
|
+
});
|
|
13633
|
+
}
|
|
13634
|
+
if (!compatibilityMode) {
|
|
13635
|
+
const msg = `[vibeOS] ${resolveTierIcon("cheap")} cheap lane \xB7 save about ~$${_estEdit.toFixed(3)} by delegating to Task. Try ${resolveTierIcon("medium")} medium.`;
|
|
13636
|
+
if (shouldLogWarn(`${t}|direct|${_tierWord}`) && process.env.VIBEOS_DEBUG_DELEGATION === "1") {
|
|
13637
|
+
console.error(`[vibeOS] [delegation] ${msg}`);
|
|
13638
|
+
}
|
|
13639
|
+
pendingUiNote = msg;
|
|
13640
|
+
return;
|
|
13625
13641
|
}
|
|
13626
|
-
pendingUiNote = msg;
|
|
13627
|
-
return;
|
|
13628
13642
|
}
|
|
13629
13643
|
}
|
|
13630
13644
|
if (SOFT_QUOTA.has(t)) {
|
|
@@ -14260,9 +14274,30 @@ function _loadActiveJobForProject(directory3, fp2 = "") {
|
|
|
14260
14274
|
}
|
|
14261
14275
|
return getActiveJobForProject(fp2);
|
|
14262
14276
|
}
|
|
14263
|
-
|
|
14277
|
+
function _tiersNeedRepair(tiers) {
|
|
14278
|
+
const slots = ["brain", "medium", "cheap"];
|
|
14279
|
+
if (!tiers || typeof tiers !== "object") return true;
|
|
14280
|
+
return slots.some((slot) => {
|
|
14281
|
+
const oc = String(tiers?.trinity?.[slot]?.oc || "").trim();
|
|
14282
|
+
return !oc || PLACEHOLDER_RE.test(oc);
|
|
14283
|
+
});
|
|
14284
|
+
}
|
|
14285
|
+
async function _seedOrRepairModelTiers(directory3) {
|
|
14264
14286
|
const TIERS_FILE3 = getTiersFile();
|
|
14265
|
-
|
|
14287
|
+
let existing = null;
|
|
14288
|
+
if (existsSync18(TIERS_FILE3)) {
|
|
14289
|
+
try {
|
|
14290
|
+
const st = statSync9(TIERS_FILE3);
|
|
14291
|
+
if (st.size > 10485760) {
|
|
14292
|
+
_handleStateCorruption(TIERS_FILE3);
|
|
14293
|
+
return false;
|
|
14294
|
+
}
|
|
14295
|
+
existing = safeJsonParse3(readFileSync17(TIERS_FILE3, "utf-8")) || {};
|
|
14296
|
+
} catch {
|
|
14297
|
+
existing = null;
|
|
14298
|
+
}
|
|
14299
|
+
}
|
|
14300
|
+
if (existing && !_tiersNeedRepair(existing))
|
|
14266
14301
|
return false;
|
|
14267
14302
|
const providers = _loadOpenCodeProviders(directory3);
|
|
14268
14303
|
const auth = typeof _readAuth === "function" ? _readAuth() : {};
|
|
@@ -14285,25 +14320,31 @@ async function _seedModelTiersIfMissing(directory3) {
|
|
|
14285
14320
|
cheap = "deepseek/deepseek-chat";
|
|
14286
14321
|
console.error("[vibeOS] no providers detected \u2014 using default model tiers (brain=v4-pro, medium=v4-flash, cheap=v4-chat)");
|
|
14287
14322
|
}
|
|
14323
|
+
const existingSelection = existing?.selection && typeof existing.selection === "object" ? existing.selection : {};
|
|
14324
|
+
const existingTrinity = existing?.trinity && typeof existing.trinity === "object" ? existing.trinity : {};
|
|
14325
|
+
const nextTrinity = {
|
|
14326
|
+
brain: existingTrinity.brain?.manual === true && String(existingTrinity.brain?.oc || "").trim() && !PLACEHOLDER_RE.test(String(existingTrinity.brain?.oc || "")) ? { ...existingTrinity.brain, cc: existingTrinity.brain?.cc || modelToCcAlias(String(existingTrinity.brain?.oc || "")) } : { oc: brain, cc: modelToCcAlias(brain) },
|
|
14327
|
+
medium: existingTrinity.medium?.manual === true && String(existingTrinity.medium?.oc || "").trim() && !PLACEHOLDER_RE.test(String(existingTrinity.medium?.oc || "")) ? { ...existingTrinity.medium, cc: existingTrinity.medium?.cc || modelToCcAlias(String(existingTrinity.medium?.oc || "")) } : { oc: medium, cc: modelToCcAlias(medium) },
|
|
14328
|
+
cheap: existingTrinity.cheap?.manual === true && String(existingTrinity.cheap?.oc || "").trim() && !PLACEHOLDER_RE.test(String(existingTrinity.cheap?.oc || "")) ? { ...existingTrinity.cheap, cc: existingTrinity.cheap?.cc || modelToCcAlias(String(existingTrinity.cheap?.oc || "")) } : { oc: cheap, cc: modelToCcAlias(cheap) }
|
|
14329
|
+
};
|
|
14330
|
+
const activeSlot = ["brain", "medium", "cheap"].includes(String(existingSelection.active_slot || "").trim()) ? String(existingSelection.active_slot) : "brain";
|
|
14288
14331
|
const tiers = {
|
|
14332
|
+
...existing,
|
|
14289
14333
|
selection: {
|
|
14290
|
-
|
|
14291
|
-
|
|
14292
|
-
|
|
14293
|
-
|
|
14294
|
-
|
|
14295
|
-
|
|
14296
|
-
|
|
14297
|
-
|
|
14298
|
-
|
|
14299
|
-
|
|
14300
|
-
|
|
14334
|
+
...existingSelection,
|
|
14335
|
+
enabled: existingSelection.enabled !== false,
|
|
14336
|
+
active_slot: activeSlot,
|
|
14337
|
+
thinking_level: existingSelection.thinking_level || "off",
|
|
14338
|
+
delegation_enforce: existingSelection.delegation_enforce !== false,
|
|
14339
|
+
flow_enabled: existingSelection.flow_enabled === true,
|
|
14340
|
+
flow_enforce: existingSelection.flow_enforce === true,
|
|
14341
|
+
tdd_enforce: existingSelection.tdd_enforce === true,
|
|
14342
|
+
tdd_strict: existingSelection.tdd_strict === true,
|
|
14343
|
+
tdd_quality: existingSelection.tdd_quality !== false,
|
|
14344
|
+
onboarding_mode: existingSelection.onboarding_mode || "assist",
|
|
14345
|
+
setup_completed_at: existingSelection.setup_completed_at || (/* @__PURE__ */ new Date()).toISOString()
|
|
14301
14346
|
},
|
|
14302
|
-
trinity:
|
|
14303
|
-
brain: { oc: brain, cc: modelToCcAlias(brain) },
|
|
14304
|
-
medium: { oc: medium, cc: modelToCcAlias(medium) },
|
|
14305
|
-
cheap: { oc: cheap, cc: modelToCcAlias(cheap) }
|
|
14306
|
-
}
|
|
14347
|
+
trinity: nextTrinity
|
|
14307
14348
|
};
|
|
14308
14349
|
mkdirSync13(dirname13(TIERS_FILE3), { recursive: true });
|
|
14309
14350
|
writeFileSync15(TIERS_FILE3, JSON.stringify(tiers, null, 2) + "\n", "utf-8");
|
|
@@ -14435,7 +14476,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
14435
14476
|
if (!existsSync18(getTiersFile())) {
|
|
14436
14477
|
console.error(`[vibeOS] model-tiers.json missing at load; will seed on first hook`);
|
|
14437
14478
|
}
|
|
14438
|
-
await
|
|
14479
|
+
await _seedOrRepairModelTiers(directory3);
|
|
14439
14480
|
loadTrinitySlotsFromTiersFile();
|
|
14440
14481
|
} catch {
|
|
14441
14482
|
}
|
|
@@ -14589,7 +14630,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
14589
14630
|
setBlackboxEnabled,
|
|
14590
14631
|
loadBlackboxState,
|
|
14591
14632
|
saveBlackboxState,
|
|
14592
|
-
isApiFallback: () =>
|
|
14633
|
+
isApiFallback: () => isApiFallback2(),
|
|
14593
14634
|
get _apiFallbackSince() {
|
|
14594
14635
|
return _apiFallbackSince2;
|
|
14595
14636
|
},
|
|
@@ -14843,7 +14884,7 @@ ${report.narrative}`);
|
|
|
14843
14884
|
fallbackThinking: thinkingLevel(loadCredit()),
|
|
14844
14885
|
backendConnected: isApiConnected2(),
|
|
14845
14886
|
backendHealthUrl: `${VIBEOS_API_URL}/health`,
|
|
14846
|
-
apiFallbackMode:
|
|
14887
|
+
apiFallbackMode: isApiFallback2(),
|
|
14847
14888
|
apiFallbackSince: _apiFallbackSince2,
|
|
14848
14889
|
modelLocked: _modelLocked,
|
|
14849
14890
|
lockedSlot: _lockedSlot,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibeostheog",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.21",
|
|
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",
|