vibeostheog 0.25.33 → 0.25.34
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/assets/dashboard/vibeos-dashboard-config.js +1 -1
- package/dist/vibeOS.js +38 -28
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
## 0.25.34
|
|
2
|
+
- fix: remove hardcoded model names from fallback
|
|
3
|
+
- fix: restore apiRoute gate for cascade (#239)
|
|
4
|
+
- fix: cascade triggered only by ML_ENABLED, not apiRoute (#238)
|
|
5
|
+
- fix: cascade router must run regardless of remote API route (#237)
|
|
6
|
+
- fix: cascade fallback only when ML API route is unavailable
|
|
7
|
+
- fix: race condition in token refresh with concurrent session renewal (#235)
|
|
8
|
+
- fix: cascade applySlot fires for all tools regardless of delegation_enforce
|
|
9
|
+
- fix: rename pipeline tier 'local' to 'cheap' (#232)
|
|
10
|
+
- docs: add TDD template + branch-first workflow to AGENTS.md
|
|
11
|
+
- build: strip sync-ts-build from pipeline, esbuild-only bundle (#242)
|
|
12
|
+
Reapply "fix: remove hardcoded model names from fallback" (#244)
|
|
13
|
+
Revert "fix: remove hardcoded model names from fallback"
|
|
14
|
+
Fix fail-open delegation and remove hardcoded fallback (#243)
|
|
15
|
+
Remove hardcoded task fallback model (#241)
|
|
16
|
+
|
|
17
|
+
|
|
1
18
|
## 0.25.31
|
|
2
19
|
- feat: anti-loop cost guard with per-turn memoization
|
|
3
20
|
- feat: remove auto-lock on slot/mode change, README/skills use vibe, lock regression tests
|
|
@@ -1 +1 @@
|
|
|
1
|
-
window.__VIBEOS_DASHBOARD_BASE__ = "http://127.0.0.1:
|
|
1
|
+
window.__VIBEOS_DASHBOARD_BASE__ = "http://127.0.0.1:42977";
|
package/dist/vibeOS.js
CHANGED
|
@@ -4200,16 +4200,16 @@ function learnedRouteFromGraph(text) {
|
|
|
4200
4200
|
}
|
|
4201
4201
|
function profileFromCascade(decision, learned = null) {
|
|
4202
4202
|
if (learned?.learnedTier === "cheap")
|
|
4203
|
-
return { profile: "direct", cascade_depth: 1, pipeline_root: ["
|
|
4203
|
+
return { profile: "direct", cascade_depth: 1, pipeline_root: ["cheap"], tier_bias: "cheap" };
|
|
4204
4204
|
if (learned?.learnedTier === "medium")
|
|
4205
4205
|
return { profile: "standard", cascade_depth: 2, pipeline_root: ["medium", "brain"], tier_bias: "medium" };
|
|
4206
4206
|
if (learned?.learnedTier === "brain")
|
|
4207
|
-
return { profile: "deep", cascade_depth: 3, pipeline_root: ["
|
|
4207
|
+
return { profile: "deep", cascade_depth: 3, pipeline_root: ["cheap", "medium", "brain"], tier_bias: "brain" };
|
|
4208
4208
|
if (decision.useCheap && decision.escalate)
|
|
4209
|
-
return { profile: "deep", cascade_depth: 3, pipeline_root: ["
|
|
4209
|
+
return { profile: "deep", cascade_depth: 3, pipeline_root: ["cheap", "medium", "brain"], tier_bias: "brain" };
|
|
4210
4210
|
if (decision.escalate)
|
|
4211
4211
|
return { profile: "standard", cascade_depth: 2, pipeline_root: ["medium", "brain"], tier_bias: "brain" };
|
|
4212
|
-
return { profile: "direct", cascade_depth: 1, pipeline_root: ["
|
|
4212
|
+
return { profile: "direct", cascade_depth: 1, pipeline_root: ["cheap"], tier_bias: "cheap" };
|
|
4213
4213
|
}
|
|
4214
4214
|
function getPivotCache2() {
|
|
4215
4215
|
if (!globalThis.__vibeultraxPivotCache)
|
|
@@ -5378,7 +5378,8 @@ function setApiToken(newToken) {
|
|
|
5378
5378
|
VIBEOS_API_TOKEN = normalizeDirectApiToken(newToken);
|
|
5379
5379
|
VIBEOS_API_BOOTSTRAP_TOKEN = readBootstrapTokenFromDisk() || VIBEOS_API_BOOTSTRAP_TOKEN;
|
|
5380
5380
|
syncApiEnabledState(process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
|
|
5381
|
-
|
|
5381
|
+
_apiClientGen++;
|
|
5382
|
+
_apiClientHolder = { client: null, gen: _apiClientGen, tokenSnapshot: VIBEOS_API_TOKEN };
|
|
5382
5383
|
_apiFallbackMode = false;
|
|
5383
5384
|
_apiFallbackSince = null;
|
|
5384
5385
|
persistPrimaryApiEnvState({ token: VIBEOS_API_TOKEN, disabled: false });
|
|
@@ -5396,7 +5397,8 @@ function invalidateApiToken() {
|
|
|
5396
5397
|
VIBEOS_API_TOKEN = "";
|
|
5397
5398
|
VIBEOS_API_BOOTSTRAP_TOKEN = "";
|
|
5398
5399
|
syncApiEnabledState(false);
|
|
5399
|
-
|
|
5400
|
+
_apiClientGen++;
|
|
5401
|
+
_apiClientHolder = { client: null, gen: _apiClientGen, tokenSnapshot: "" };
|
|
5400
5402
|
_apiFallbackMode = false;
|
|
5401
5403
|
_apiFallbackSince = null;
|
|
5402
5404
|
if (_anomalyDetector)
|
|
@@ -5422,7 +5424,8 @@ function setApiBootstrapToken(newToken) {
|
|
|
5422
5424
|
console.error("[vibeOS] Failed to update alpha bootstrap token:", e.message);
|
|
5423
5425
|
}
|
|
5424
5426
|
}
|
|
5425
|
-
var
|
|
5427
|
+
var _apiClientHolder = { client: null, gen: 0, tokenSnapshot: "" };
|
|
5428
|
+
var _apiClientGen = 0;
|
|
5426
5429
|
var _apiFallbackMode = false;
|
|
5427
5430
|
var _apiFallbackSince = null;
|
|
5428
5431
|
var _bootstrapExchangeInFlight = null;
|
|
@@ -5499,7 +5502,8 @@ function syncApiTokenFromDisk() {
|
|
|
5499
5502
|
VIBEOS_API_TOKEN = "";
|
|
5500
5503
|
VIBEOS_API_BOOTSTRAP_TOKEN = "";
|
|
5501
5504
|
syncApiEnabledState(false);
|
|
5502
|
-
|
|
5505
|
+
_apiClientGen++;
|
|
5506
|
+
_apiClientHolder = { client: null, gen: _apiClientGen, tokenSnapshot: "" };
|
|
5503
5507
|
_apiFallbackMode = false;
|
|
5504
5508
|
_apiFallbackSince = null;
|
|
5505
5509
|
resetApiConnection();
|
|
@@ -5511,7 +5515,8 @@ function syncApiTokenFromDisk() {
|
|
|
5511
5515
|
VIBEOS_API_DISABLED = false;
|
|
5512
5516
|
VIBEOS_API_TOKEN = diskToken;
|
|
5513
5517
|
syncApiEnabledState(process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
|
|
5514
|
-
|
|
5518
|
+
_apiClientGen++;
|
|
5519
|
+
_apiClientHolder = { client: null, gen: _apiClientGen, tokenSnapshot: VIBEOS_API_TOKEN };
|
|
5515
5520
|
_apiFallbackMode = false;
|
|
5516
5521
|
_apiFallbackSince = null;
|
|
5517
5522
|
markApiConnected();
|
|
@@ -5547,14 +5552,21 @@ function syncApiTokenFromDisk() {
|
|
|
5547
5552
|
}
|
|
5548
5553
|
function getApiClient2() {
|
|
5549
5554
|
syncApiTokenFromDisk();
|
|
5550
|
-
if (
|
|
5551
|
-
|
|
5555
|
+
if (_apiClientHolder.client && _apiClientHolder.gen === _apiClientGen) {
|
|
5556
|
+
return _apiClientHolder.client;
|
|
5557
|
+
}
|
|
5558
|
+
if (isApiEnabled() && VIBEOS_API_TOKEN) {
|
|
5559
|
+
_apiClientHolder.client = new VibeOSApiClient({
|
|
5552
5560
|
baseUrl: VIBEOS_API_URL,
|
|
5553
5561
|
apiToken: VIBEOS_API_TOKEN,
|
|
5554
5562
|
timeout: 5e3
|
|
5555
5563
|
});
|
|
5564
|
+
_apiClientHolder.gen = _apiClientGen;
|
|
5565
|
+
_apiClientHolder.tokenSnapshot = VIBEOS_API_TOKEN;
|
|
5566
|
+
} else {
|
|
5567
|
+
_apiClientHolder.client = null;
|
|
5556
5568
|
}
|
|
5557
|
-
return
|
|
5569
|
+
return _apiClientHolder.client;
|
|
5558
5570
|
}
|
|
5559
5571
|
function isApiFallback() {
|
|
5560
5572
|
return _apiFallbackMode || isApiFallbackMode() || !isApiEnabled();
|
|
@@ -5570,7 +5582,6 @@ async function remoteCall(method, args, fallbackFn) {
|
|
|
5570
5582
|
syncApiTokenFromDisk();
|
|
5571
5583
|
if (!VIBEOS_API_TOKEN && VIBEOS_API_BOOTSTRAP_TOKEN) {
|
|
5572
5584
|
await ensureBootstrapExchange();
|
|
5573
|
-
syncApiTokenFromDisk();
|
|
5574
5585
|
}
|
|
5575
5586
|
if (tryResetFallbackCooldown()) {
|
|
5576
5587
|
if (process.env.VIBEOS_DEBUG)
|
|
@@ -9273,14 +9284,14 @@ var BRANDED_MODES = [
|
|
|
9273
9284
|
index: 1,
|
|
9274
9285
|
name: "VibeUltraX",
|
|
9275
9286
|
icon: "\u{1F3C6}",
|
|
9276
|
-
pipeline: ["
|
|
9287
|
+
pipeline: ["cheap", "medium", "brain"],
|
|
9277
9288
|
thinking: "full",
|
|
9278
9289
|
tdd: "quality",
|
|
9279
9290
|
enforcement: "strict",
|
|
9280
9291
|
flow: "strict",
|
|
9281
9292
|
qualityVsBrain: 107,
|
|
9282
9293
|
costVsBrain: 58,
|
|
9283
|
-
desc: "3-model debate:
|
|
9294
|
+
desc: "3-model debate: cheap proposes, medium reviews, brain refines."
|
|
9284
9295
|
},
|
|
9285
9296
|
{
|
|
9286
9297
|
id: "vibeqmax",
|
|
@@ -12206,7 +12217,7 @@ function syncControlSettings(cv, options = {}) {
|
|
|
12206
12217
|
if (cv?.pipeline_root && Array.isArray(cv.pipeline_root)) {
|
|
12207
12218
|
writeIf("active_pipeline", JSON.stringify(cv.pipeline_root));
|
|
12208
12219
|
} else if (cv?.cascade_depth && cv.cascade_depth >= 3) {
|
|
12209
|
-
writeIf("active_pipeline", JSON.stringify(["
|
|
12220
|
+
writeIf("active_pipeline", JSON.stringify(["cheap", "medium", "brain"]));
|
|
12210
12221
|
}
|
|
12211
12222
|
writeIf("enabled", true);
|
|
12212
12223
|
const compatibilityMode = currentSel.onboarding_mode === "assist";
|
|
@@ -12587,8 +12598,7 @@ function orchestratorDirective(cv, sel) {
|
|
|
12587
12598
|
const mediumModel = TRINITY_MEDIUM || "the medium model";
|
|
12588
12599
|
const targetModel = tierBias === "cheap" ? cheapModel : tierBias === "medium" ? mediumModel : tierBias === "brain" ? brainModel : `${cheapModel} or ${mediumModel}`;
|
|
12589
12600
|
const compatibilityMode = sel?.onboarding_mode === "assist";
|
|
12590
|
-
const cheapSlot = TRINITY_CHEAP ||
|
|
12591
|
-
const mediumSlot = TRINITY_MEDIUM || "deepseek/deepseek-v4-flash";
|
|
12601
|
+
const cheapSlot = TRINITY_CHEAP || cheapModel;
|
|
12592
12602
|
return `[AI ORCHESTRATOR AGENT] You are an AI orchestrator agent. Delegate heavy work to Task subagents (runs on ${targetModel}). Your role is to verify, fill gaps, and synthesize cleanly. ` + (compatibilityMode ? "Compatibility mode is active, so direct Write/Edit stays available until strict guardrails are enabled." : "Brain-tier focuses on orchestration \u2014 hand file writes and edits to Task subagents (cheaper, same quality). Use medium directly with `trinity medium` if the task is simple enough.") + ` [delegation guide] When a write/edit is blocked, use the \`task\` tool with: subagent_type="general" model="${cheapSlot}" prompt="write <path> with: <content>". The task subagent runs on the cheap tier and handles file operations transparently. Parallel task calls are encouraged for independent file changes. Always display the vibeOS cost footer.` + (tierBias !== "auto" ? ` [tier routing] This turn is biased toward ${tierBias} tier.` : "");
|
|
12593
12603
|
}
|
|
12594
12604
|
function flowTodosDirective() {
|
|
@@ -15301,13 +15311,13 @@ ${argsJson}
|
|
|
15301
15311
|
}
|
|
15302
15312
|
}
|
|
15303
15313
|
const activePipeline = loadSelection().active_pipeline;
|
|
15304
|
-
if (activePipeline && Array.isArray(activePipeline) && activePipeline.length > 1 && TRINITY_CHEAP && TRINITY_MEDIUM) {
|
|
15314
|
+
if (!apiRoute?.target && activePipeline && Array.isArray(activePipeline) && activePipeline.length > 1 && TRINITY_CHEAP && TRINITY_MEDIUM) {
|
|
15305
15315
|
try {
|
|
15306
15316
|
const cheapCost = 1e-3;
|
|
15307
15317
|
const mediumCost = 5e-3;
|
|
15308
15318
|
const brainCost = 0.02;
|
|
15309
15319
|
const cascadeResult = cascadeDecide(_prompt, cheapCost, mediumCost, brainCost, 0.85);
|
|
15310
|
-
const tierMap = { cheap: TRINITY_CHEAP, medium: TRINITY_MEDIUM, brain: TRINITY_BRAIN
|
|
15320
|
+
const tierMap = { cheap: TRINITY_CHEAP, medium: TRINITY_MEDIUM, brain: TRINITY_BRAIN };
|
|
15311
15321
|
const pipelineModels = activePipeline.map((t2) => tierMap[t2] || TRINITY_CHEAP);
|
|
15312
15322
|
if (cascadeResult.escalate && pipelineModels.length > 1) {
|
|
15313
15323
|
if (pipelineModels.length > 2 && cascadeResult.confidence >= 0.8) {
|
|
@@ -15350,7 +15360,7 @@ ${argsJson}
|
|
|
15350
15360
|
try {
|
|
15351
15361
|
const selNow = loadSelection();
|
|
15352
15362
|
const desiredSlot = _target === TRINITY_CHEAP ? "cheap" : _target === TRINITY_MEDIUM ? "medium" : _target === TRINITY_BRAIN ? "brain" : null;
|
|
15353
|
-
if (
|
|
15363
|
+
if (desiredSlot && selNow.active_slot !== desiredSlot) {
|
|
15354
15364
|
taskSlotRestore = selNow.active_slot || "brain";
|
|
15355
15365
|
const switched = applySlot(desiredSlot);
|
|
15356
15366
|
if (switched?.ok) {
|
|
@@ -15445,8 +15455,8 @@ ${argsJson}
|
|
|
15445
15455
|
const originalPath = argSources.flatMap((src) => [src?.filePath, src?.file_path, src?.path]).find((v) => typeof v === "string" && v.trim()) || "";
|
|
15446
15456
|
const basename6 = originalPath.split("/").pop() || "blocked";
|
|
15447
15457
|
const apiResult = await remoteCall("delegateCheck", [tLower, currentTier, currentModel, _prompt], () => ({
|
|
15448
|
-
blocked:
|
|
15449
|
-
savings:
|
|
15458
|
+
blocked: false,
|
|
15459
|
+
savings: 0,
|
|
15450
15460
|
_fallback: true
|
|
15451
15461
|
}));
|
|
15452
15462
|
const remoteSavings = Number(apiResult?.savings);
|
|
@@ -15461,7 +15471,7 @@ ${argsJson}
|
|
|
15461
15471
|
projectName: currentProjectName || "",
|
|
15462
15472
|
sessionId: getCurrentSessionId()
|
|
15463
15473
|
});
|
|
15464
|
-
const taskModel = TRINITY_CHEAP || "
|
|
15474
|
+
const taskModel = TRINITY_CHEAP || TRINITY_MEDIUM || currentModel || TRINITY_BRAIN || "";
|
|
15465
15475
|
pendingUiNote = `[delegation] ${t} blocked on brain tier. Use a task subagent instead: \`task subagent_type="general" model="${taskModel}" prompt="${t} <file> with the intended content"\`. Keeps brain focused on orchestration.`;
|
|
15466
15476
|
enforcementBlocked = true;
|
|
15467
15477
|
_mutateBlockedToolArgs(t, argSources, originalPath, output);
|
|
@@ -16201,10 +16211,10 @@ async function _seedOrRepairModelTiers(directory3) {
|
|
|
16201
16211
|
let medium = trinity?.medium || brain;
|
|
16202
16212
|
let cheap = trinity?.cheap || medium || brain;
|
|
16203
16213
|
if (!brain) {
|
|
16204
|
-
brain = "
|
|
16205
|
-
medium = "
|
|
16206
|
-
cheap = "
|
|
16207
|
-
console.error(
|
|
16214
|
+
brain = "generic/brain";
|
|
16215
|
+
medium = "generic/medium";
|
|
16216
|
+
cheap = "generic/cheap";
|
|
16217
|
+
console.error('[vibeOS] no providers or trinity config found \u2014 run "vibe rebuild" to set model tiers');
|
|
16208
16218
|
}
|
|
16209
16219
|
const existingSelection = existing?.selection && typeof existing.selection === "object" ? existing.selection : {};
|
|
16210
16220
|
const existingTrinity = existing?.trinity && typeof existing.trinity === "object" ? existing.trinity : {};
|
package/package.json
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibeostheog",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.34",
|
|
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",
|
|
7
7
|
"release:patch": "node scripts/release.mjs patch --yes",
|
|
8
8
|
"release:minor": "node scripts/release.mjs minor --yes",
|
|
9
9
|
"release:major": "node scripts/release.mjs major --yes",
|
|
10
|
-
"build": "npm run build:bundle && node scripts/deploy.mjs",
|
|
11
|
-
"build:bundle": "
|
|
10
|
+
"build": "npm run typecheck && npm run build:bundle && node scripts/deploy.mjs",
|
|
11
|
+
"build:bundle": "node scripts/build-bundle.mjs",
|
|
12
12
|
"build:single": "node scripts/build-bundle.mjs",
|
|
13
13
|
"deploy": "node scripts/deploy.mjs",
|
|
14
14
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
15
15
|
"checkpoint:validate": "node scripts/checkpoint-validate.mjs",
|
|
16
16
|
"test:scripts": "node scripts/run-test-suite.mjs scripts",
|
|
17
17
|
"ts:audit": "node scripts/ts-audit.mjs",
|
|
18
|
-
"test": "
|
|
19
|
-
"test:ci": "
|
|
18
|
+
"test": "tsc -p tsconfig.json && node scripts/build-bundle.mjs && node scripts/run-test-suite.mjs full",
|
|
19
|
+
"test:ci": "tsc -p tsconfig.json && node scripts/build-bundle.mjs && node scripts/run-test-suite.mjs ci",
|
|
20
20
|
"guard": "bash plugins/vibetheog-guard/scripts/run-guard.sh",
|
|
21
21
|
"guard:full": "VIBETHEOG_GUARD_FULL=1 bash plugins/vibetheog-guard/scripts/run-guard.sh",
|
|
22
22
|
"hook:precommit": "bash plugins/vibetheog-guard/hooks/pre-commit.sh",
|