vibeostheog 0.23.56 → 0.23.58
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 +3 -0
- package/package.json +1 -1
- package/src/lib/classifiers.js +2 -2
- package/src/lib/hooks/footer.js +1 -1
- package/src/lib/hooks/shared-footer.js +31 -7
- package/src/lib/hooks/shell-env.js +3 -0
- package/src/lib/hooks/tool-execute.js +72 -69
- package/src/lib/pricing.js +1 -1
- package/src/lib/turn-classify.js +3 -3
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibeostheog",
|
|
3
|
-
"version": "0.23.
|
|
3
|
+
"version": "0.23.58",
|
|
4
4
|
"description": "Cost-aware delegation enforcer for OpenCode. Tracks model usage, routes Task subagents to cheaper tiers, surfaces cumulative savings in chat. Includes research audit, reporting framework, project memory, progressive scratchpad decadence, and trinity CLI for brain/medium/cheap slot switching.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"release": "node scripts/release.mjs",
|
package/src/lib/classifiers.js
CHANGED
|
@@ -96,10 +96,10 @@ export function classifyTurnSimple(userText) {
|
|
|
96
96
|
const lower = String(userText || "").trim();
|
|
97
97
|
if (!lower)
|
|
98
98
|
return "INIT";
|
|
99
|
-
if (/(security|vulnerability|audit|owasp|compliance|gdpr|privacy|analyze dependencies|license audit)/i.test(lower)) {
|
|
99
|
+
if (/(security|vulnerability|audit|owasp|compliance|gdpr|privacy|analyze dependencies|license audit|xss|csrf|authn|authz|pentest)/i.test(lower)) {
|
|
100
100
|
return "AUDIT";
|
|
101
101
|
}
|
|
102
|
-
if (/(inject|exploit|penetration|cve|attack|threat|encrypt|
|
|
102
|
+
if (/(inject|exploit|penetration|cve|attack|threat|encrypt|forensic|research|deep analysis|investigate|root cause|reverse engineer|disassemble|memory dump|core dump)/i.test(lower)) {
|
|
103
103
|
return "FORENSIC";
|
|
104
104
|
}
|
|
105
105
|
// Q&A / research patterns -> EXPLORING (relaxed enforcement)
|
package/src/lib/hooks/footer.js
CHANGED
|
@@ -273,7 +273,7 @@ async function _appendFooter(input, output, directory) {
|
|
|
273
273
|
if (stripped === _lastStrippedText)
|
|
274
274
|
return;
|
|
275
275
|
const ltTotal = ltTasks + ltCache;
|
|
276
|
-
const activeSlot = selNowFooter.
|
|
276
|
+
const activeSlot = selNowFooter.active_slot || "brain";
|
|
277
277
|
const optMode = (resolvedMode || "budget").toLowerCase();
|
|
278
278
|
const vibeBrand = resolveBrand(optModeFooter, activeSlot);
|
|
279
279
|
const flashIcon = isApiConnected() ? " \u26A1" : "";
|
|
@@ -11,8 +11,9 @@ const BRAND_MAP = {
|
|
|
11
11
|
};
|
|
12
12
|
const TIER_ICON = {
|
|
13
13
|
brain: "\u{1F9E0}",
|
|
14
|
-
medium: "\
|
|
15
|
-
cheap: "\
|
|
14
|
+
medium: "\u25D0",
|
|
15
|
+
cheap: "\u26A1",
|
|
16
|
+
free: "\u{1F381}",
|
|
16
17
|
};
|
|
17
18
|
export function resolveBrand(optMode, activeSlot) {
|
|
18
19
|
return BRAND_MAP[optMode] || (activeSlot === "brain" ? "VibeQMaX" : "VibeMaX");
|
|
@@ -20,6 +21,29 @@ export function resolveBrand(optMode, activeSlot) {
|
|
|
20
21
|
export function resolveTierIcon(slot) {
|
|
21
22
|
return TIER_ICON[slot] || "\u26A1";
|
|
22
23
|
}
|
|
24
|
+
export function formatVectorPulse(vectorChangedSlot) {
|
|
25
|
+
if (!vectorChangedSlot)
|
|
26
|
+
return "";
|
|
27
|
+
return `⟡ ${vectorChangedSlot}`;
|
|
28
|
+
}
|
|
29
|
+
export function formatEnforcementPulse(enfTags) {
|
|
30
|
+
const tags = new Set(enfTags || []);
|
|
31
|
+
const parts = [];
|
|
32
|
+
if (tags.has("[Q&A]")) {
|
|
33
|
+
parts.push("quiet mode");
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
if (tags.has("[ENF ON]") || tags.has("[STRICT]"))
|
|
37
|
+
parts.push("guarded");
|
|
38
|
+
if (tags.has("[FLOW ON]"))
|
|
39
|
+
parts.push("flow steady");
|
|
40
|
+
if (tags.has("[TDD ON]"))
|
|
41
|
+
parts.push("tests live");
|
|
42
|
+
}
|
|
43
|
+
if (tags.has("[LOCK ON]"))
|
|
44
|
+
parts.push("locked");
|
|
45
|
+
return parts.join(" · ");
|
|
46
|
+
}
|
|
23
47
|
export function trendGlyph(trend) {
|
|
24
48
|
if (trend === "up")
|
|
25
49
|
return "↗";
|
|
@@ -66,13 +90,13 @@ export function buildFooterLine(input) {
|
|
|
66
90
|
if (optMode && optMode !== "auto") {
|
|
67
91
|
line += ` ${optMode}`;
|
|
68
92
|
}
|
|
69
|
-
if (vectorChangedSlot) {
|
|
70
|
-
line += ` |
|
|
93
|
+
if (vectorChangedSlot && vectorChangedSlot !== activeSlot) {
|
|
94
|
+
line += ` | ${formatVectorPulse(vectorChangedSlot)}`;
|
|
71
95
|
}
|
|
72
|
-
|
|
73
|
-
|
|
96
|
+
const enforcementPulse = formatEnforcementPulse(enfTags);
|
|
97
|
+
if (enforcementPulse) {
|
|
98
|
+
line += ` | ${enforcementPulse}`;
|
|
74
99
|
}
|
|
75
|
-
line += ` | slot:${activeSlot}`;
|
|
76
100
|
if (sessionSlot && sessionSlot !== activeSlot) {
|
|
77
101
|
line += ` | session:${sessionSlot}`;
|
|
78
102
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
import { currentTier, currentModel } from "../state.js";
|
|
3
3
|
import { _refreshModel } from "../pricing.js";
|
|
4
|
+
import { resolveTierIcon } from "./shared-footer.js";
|
|
4
5
|
let directory = "";
|
|
5
6
|
export const setShellDirectory = (dir) => { directory = dir || ""; };
|
|
6
7
|
export const onShellEnv = async (_input, output) => {
|
|
@@ -11,6 +12,8 @@ export const onShellEnv = async (_input, output) => {
|
|
|
11
12
|
output.env ??= {};
|
|
12
13
|
output.env.OPENCODE_MODEL_TIER = currentTier || "unknown";
|
|
13
14
|
output.env.OPENCODE_MODEL = currentModel || "unknown";
|
|
15
|
+
const shellTier = currentTier === "high" ? "brain" : currentTier === "mid" ? "medium" : currentTier === "budget" ? "cheap" : currentTier === "free" ? "free" : currentTier || "unknown";
|
|
16
|
+
output.env.VIBEOS_SHELL_BADGE = `${resolveTierIcon(shellTier)} ${shellTier} | ${currentModel || "unknown"}`;
|
|
14
17
|
}
|
|
15
18
|
catch (e) {
|
|
16
19
|
console.error("[vibeOS] shell.env error:", e);
|
|
@@ -8,7 +8,7 @@ import { latestUserIntent } from "./chat-transform.js";
|
|
|
8
8
|
import { loadSessionOptMode } from "../selection-manager.js";
|
|
9
9
|
import { loadOptimizationMode } from "../turn-classify.js";
|
|
10
10
|
import { loadCredit, refreshCreditSnapshot } from "../credit-api.js";
|
|
11
|
-
import { buildFooterLine, buildEnforcementTags, resolveBrand } from "./shared-footer.js";
|
|
11
|
+
import { buildFooterLine, buildEnforcementTags, resolveBrand, resolveTierIcon } from "./shared-footer.js";
|
|
12
12
|
function modeCapitalized(mode) {
|
|
13
13
|
if (!mode)
|
|
14
14
|
return "Budget";
|
|
@@ -557,7 +557,7 @@ export const onToolExecuteBefore = async (input, output) => {
|
|
|
557
557
|
// Credit < 40%: non-task tool — record and nudge to step aside.
|
|
558
558
|
if (_credit < 40 && !compatibilityMode) {
|
|
559
559
|
const total = recordSaving(t, "credit<40% high-tier", _estOpus, { firstWord: _firstWord });
|
|
560
|
-
const msg = `[vibeOS]
|
|
560
|
+
const msg = `[vibeOS] Quick win: ${resolveTierIcon("cheap")} cheap lane open · switch to ${resolveTierIcon("medium")} medium to save about ~$${_estOpus.toFixed(3)}/turn.`;
|
|
561
561
|
if (shouldLogWarn(`${t}|credit|${_tierWord}`) && process.env.VIBEOS_DEBUG_DELEGATION === "1") {
|
|
562
562
|
console.error(`[vibeOS] [delegation] ${msg}`);
|
|
563
563
|
}
|
|
@@ -584,7 +584,7 @@ export const onToolExecuteBefore = async (input, output) => {
|
|
|
584
584
|
if (isBlocked) {
|
|
585
585
|
_mutateBlockedToolArgs(tLower, argSources, originalPath, output);
|
|
586
586
|
const total = recordSaving(t, "delegation enforced", savings, { firstWord: _firstWord });
|
|
587
|
-
pendingUiNote = `[ENF]
|
|
587
|
+
pendingUiNote = `[ENF] ${resolveTierIcon("brain")} brain paused · delegate via Task or switch to ${resolveTierIcon("medium")} medium.`;
|
|
588
588
|
enforcementBlocked = true;
|
|
589
589
|
if (shouldLogWarn(`${t}|enforced|${_tierWord}`))
|
|
590
590
|
console.error(`[vibeOS] [enforcement] BLOCKED direct ${t} on high tier → delegate via Task`);
|
|
@@ -593,7 +593,7 @@ export const onToolExecuteBefore = async (input, output) => {
|
|
|
593
593
|
}
|
|
594
594
|
const total = recordSaving(t, "direct edit", _estEdit, { firstWord: _firstWord });
|
|
595
595
|
if (!compatibilityMode) {
|
|
596
|
-
const msg = `[vibeOS] ${
|
|
596
|
+
const msg = `[vibeOS] ${resolveTierIcon("cheap")} cheap lane · save about ~$${_estEdit.toFixed(3)} by delegating to Task. Try ${resolveTierIcon("medium")} medium.`;
|
|
597
597
|
if (shouldLogWarn(`${t}|direct|${_tierWord}`) && process.env.VIBEOS_DEBUG_DELEGATION === "1") {
|
|
598
598
|
console.error(`[vibeOS] [delegation] ${msg}`);
|
|
599
599
|
}
|
|
@@ -681,72 +681,75 @@ export const onToolExecuteAfter = async (input, output) => {
|
|
|
681
681
|
// ── Generate footer alert (prepended to tool result, visible in chat) ──
|
|
682
682
|
let _footerText = "";
|
|
683
683
|
try {
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
let liveModel = "";
|
|
696
|
-
try {
|
|
697
|
-
const cfg = await client.config.get("model");
|
|
698
|
-
if (cfg)
|
|
699
|
-
liveModel = String(cfg);
|
|
700
|
-
}
|
|
701
|
-
catch { }
|
|
702
|
-
if (!liveModel) {
|
|
703
|
-
liveModel = readConfig(projectDirectory) || readConfig(join(process.env.HOME || "", ".config", "opencode")) || process?.env?.OPENCODE_MODEL || "";
|
|
704
|
-
}
|
|
705
|
-
const displayModel = resolveDisplayModelId(liveModel || currentModel || "", projectDirectory) || liveModel || currentModel;
|
|
706
|
-
const resolvedModel = displayModel || liveModel || currentModel || "";
|
|
707
|
-
if (resolvedModel && resolvedModel !== currentModel) {
|
|
708
|
-
setCurrentModel(resolvedModel);
|
|
709
|
-
setCurrentTier(classify(resolvedModel));
|
|
710
|
-
}
|
|
711
|
-
const execution = resolveExecutionIdentity(input?.args?.model || resolvedModel || "", projectDirectory);
|
|
712
|
-
const currentSid = _OC_SID;
|
|
713
|
-
const optModeFooter = loadSessionOptMode(currentSid + "_opt") || loadOptimizationMode() || "budget";
|
|
714
|
-
const activeSlot = execution.quality === "brain" ? "brain" : execution.quality === "medium" ? "medium" : "cheap";
|
|
715
|
-
const vibeBrand = resolveBrand(optModeFooter, activeSlot);
|
|
716
|
-
const flashIcon = VIBEOS_API_ENABLED ? " \u26A1" : "";
|
|
717
|
-
_footerText = buildFooterLine({
|
|
718
|
-
activeSlot,
|
|
719
|
-
providerLabel: execution.provider_label,
|
|
720
|
-
modelName: modelDisplayName(execution.model),
|
|
721
|
-
ltTotal,
|
|
722
|
-
ltTrend: sv.sesTrend,
|
|
723
|
-
vibeBrand,
|
|
724
|
-
optMode: optModeFooter,
|
|
725
|
-
flashIcon,
|
|
726
|
-
enfTags,
|
|
727
|
-
}) + "\n\n";
|
|
728
|
-
const footerTarget = _payload(output);
|
|
729
|
-
output.title = _footerText.trim();
|
|
730
|
-
if (footerTarget !== output && footerTarget && typeof footerTarget === "object") {
|
|
731
|
-
footerTarget.title = _footerText.trim();
|
|
732
|
-
}
|
|
733
|
-
if (typeof footerTarget?.output === "string")
|
|
734
|
-
footerTarget.output = _footerText + footerTarget.output;
|
|
735
|
-
else if (typeof footerTarget?.result === "string")
|
|
736
|
-
footerTarget.result = _footerText + footerTarget.result;
|
|
737
|
-
else if (typeof footerTarget?.text === "string")
|
|
738
|
-
footerTarget.text = _footerText + footerTarget.text;
|
|
739
|
-
else if (typeof footerTarget?.content === "string")
|
|
740
|
-
footerTarget.content = _footerText + footerTarget.content;
|
|
741
|
-
else
|
|
742
|
-
footerTarget.output = _footerText;
|
|
743
|
-
_autoReportCount = (_autoReportCount || 0) + 1;
|
|
744
|
-
if (_autoReportCount % 5 === 0 && ltTotal > 0) {
|
|
745
|
-
saveReport({
|
|
746
|
-
type: "session", summary: `Session cost: $${formatUsd(ltCost)} | cache saved: $${formatUsd(ltCache)} | delegation saved: $${formatUsd(ltTasks)}`,
|
|
747
|
-
metrics: { sessionId: _OC_SID, sessionCost: ltCost, cacheSavings: ltCache, delegationSavingsUsd: ltTasks, model: resolvedModel || currentModel, slot: selNow.active_slot || "unknown" },
|
|
748
|
-
tags: ["auto", "cost"],
|
|
684
|
+
if (t !== "task") {
|
|
685
|
+
const { ltTasks, ltCache, ltCost, sesTrend } = readLifetimeSavings();
|
|
686
|
+
const ltTotal = ltTasks + ltCache;
|
|
687
|
+
const selNow = loadSelection();
|
|
688
|
+
const bbMode = resolveEnforcementMode();
|
|
689
|
+
const enfTags = buildEnforcementTags({
|
|
690
|
+
delegationEnforce: selNow.delegation_enforce,
|
|
691
|
+
flowEnforce: selNow.flow_enforce,
|
|
692
|
+
tddEnforce: selNow.tdd_enforce,
|
|
693
|
+
bbMode,
|
|
694
|
+
modelLocked: _modelLocked,
|
|
749
695
|
});
|
|
696
|
+
let liveModel = "";
|
|
697
|
+
try {
|
|
698
|
+
const cfg = await client.config.get("model");
|
|
699
|
+
if (cfg)
|
|
700
|
+
liveModel = String(cfg);
|
|
701
|
+
}
|
|
702
|
+
catch { }
|
|
703
|
+
if (!liveModel) {
|
|
704
|
+
liveModel = readConfig(projectDirectory) || readConfig(join(process.env.HOME || "", ".config", "opencode")) || process?.env?.OPENCODE_MODEL || "";
|
|
705
|
+
}
|
|
706
|
+
const displayModel = resolveDisplayModelId(liveModel || currentModel || "", projectDirectory) || liveModel || currentModel;
|
|
707
|
+
const resolvedModel = displayModel || liveModel || currentModel || "";
|
|
708
|
+
if (resolvedModel && resolvedModel !== currentModel) {
|
|
709
|
+
setCurrentModel(resolvedModel);
|
|
710
|
+
setCurrentTier(classify(resolvedModel));
|
|
711
|
+
}
|
|
712
|
+
const execution = resolveExecutionIdentity(input?.args?.model || resolvedModel || "", projectDirectory);
|
|
713
|
+
const currentSid = _OC_SID;
|
|
714
|
+
const optModeFooter = loadSessionOptMode(currentSid + "_opt") || loadOptimizationMode() || "budget";
|
|
715
|
+
const activeSlot = selNow.active_slot || (execution.quality === "brain" ? "brain" : execution.quality === "medium" ? "medium" : "cheap");
|
|
716
|
+
const vibeBrand = resolveBrand(optModeFooter, activeSlot);
|
|
717
|
+
const flashIcon = VIBEOS_API_ENABLED ? " \u26A1" : "";
|
|
718
|
+
_footerText = buildFooterLine({
|
|
719
|
+
activeSlot,
|
|
720
|
+
providerLabel: execution.provider_label,
|
|
721
|
+
modelName: modelDisplayName(execution.model),
|
|
722
|
+
ltTotal,
|
|
723
|
+
ltTrend: sesTrend || "",
|
|
724
|
+
vibeBrand,
|
|
725
|
+
optMode: optModeFooter,
|
|
726
|
+
flashIcon,
|
|
727
|
+
enfTags,
|
|
728
|
+
vectorChangedSlot: selNow.vector_changed_slot,
|
|
729
|
+
}) + "\n\n";
|
|
730
|
+
const footerTarget = _payload(output);
|
|
731
|
+
output.title = _footerText.trim();
|
|
732
|
+
if (footerTarget !== output && footerTarget && typeof footerTarget === "object") {
|
|
733
|
+
footerTarget.title = _footerText.trim();
|
|
734
|
+
}
|
|
735
|
+
if (typeof footerTarget?.output === "string")
|
|
736
|
+
footerTarget.output = _footerText + footerTarget.output;
|
|
737
|
+
else if (typeof footerTarget?.result === "string")
|
|
738
|
+
footerTarget.result = _footerText + footerTarget.result;
|
|
739
|
+
else if (typeof footerTarget?.text === "string")
|
|
740
|
+
footerTarget.text = _footerText + footerTarget.text;
|
|
741
|
+
else if (typeof footerTarget?.content === "string")
|
|
742
|
+
footerTarget.content = _footerText + footerTarget.content;
|
|
743
|
+
else
|
|
744
|
+
footerTarget.output = _footerText;
|
|
745
|
+
_autoReportCount = (_autoReportCount || 0) + 1;
|
|
746
|
+
if (_autoReportCount % 5 === 0 && ltTotal > 0) {
|
|
747
|
+
saveReport({
|
|
748
|
+
type: "session", summary: `Session cost: $${formatUsd(ltCost)} | cache saved: $${formatUsd(ltCache)} | delegation saved: $${formatUsd(ltTasks)}`,
|
|
749
|
+
metrics: { sessionId: _OC_SID, sessionCost: ltCost, cacheSavings: ltCache, delegationSavingsUsd: ltTasks, model: resolvedModel || currentModel, slot: selNow.active_slot || "unknown" },
|
|
750
|
+
tags: ["auto", "cost"],
|
|
751
|
+
});
|
|
752
|
+
}
|
|
750
753
|
}
|
|
751
754
|
}
|
|
752
755
|
catch { }
|
package/src/lib/pricing.js
CHANGED
|
@@ -123,7 +123,7 @@ export function classify(m) {
|
|
|
123
123
|
// Provider prefix is stripped before matching (everything before last "/").
|
|
124
124
|
export function modelToSlotLabel(modelId, effectiveTier) {
|
|
125
125
|
const tier = effectiveTier ?? classify(modelId);
|
|
126
|
-
const icon = tier === "high" ? "🧠" : tier === "mid" ? "
|
|
126
|
+
const icon = tier === "high" ? "🧠" : tier === "mid" ? "◐" : "⚡";
|
|
127
127
|
return `[${icon} ${tier.charAt(0).toUpperCase() + tier.slice(1)}]`;
|
|
128
128
|
}
|
|
129
129
|
export function getModelProvider(modelId) {
|
package/src/lib/turn-classify.js
CHANGED
|
@@ -36,7 +36,7 @@ export function resolveOptimizationMode(subRegime, stressMultiplier, optimizatio
|
|
|
36
36
|
}
|
|
37
37
|
export function resolveOptimizationSlot(mode) {
|
|
38
38
|
const normalized = String(mode || "budget").toLowerCase();
|
|
39
|
-
return normalized === "speed" || normalized === "vibemax" || normalized === "vibelitex" ? "medium"
|
|
39
|
+
return normalized === "speed" || normalized === "vibemax" || normalized === "vibelitex" || normalized === "litex" ? "medium"
|
|
40
40
|
: normalized === "quality" || normalized === "longrun" || normalized === "vibeultrax" || normalized === "vibeqmax" || normalized === "forensic" || normalized === "audit" ? "brain"
|
|
41
41
|
: "cheap";
|
|
42
42
|
}
|
|
@@ -91,14 +91,14 @@ export async function selectOptimizationModeRemote(subRegime, stressMultiplier,
|
|
|
91
91
|
}
|
|
92
92
|
function computeControlVector(_state, _action, _optimizationMode) {
|
|
93
93
|
const mode = resolveOptimizationMode(_state?.sub_regime, _state?.latest_stress_multiplier, _optimizationMode);
|
|
94
|
-
const isStrict = mode === "quality" || mode === "vibemax" || mode === "forensic" || mode === "audit";
|
|
94
|
+
const isStrict = mode === "quality" || mode === "vibemax" || mode === "vibeqmax" || mode === "vibeultrax" || mode === "forensic" || mode === "audit";
|
|
95
95
|
const isRelaxed = mode === "budget" || mode === "speed";
|
|
96
96
|
const subRegime = _state?.sub_regime || "INIT";
|
|
97
97
|
const stress = Number(_state?.latest_stress_multiplier ?? 0);
|
|
98
98
|
const tierBias = stress > QUALITY_STRESS_THRESHOLD ? "brain"
|
|
99
99
|
: subRegime === "CONVERGING" || subRegime === "CLOSED" ? "brain"
|
|
100
100
|
: subRegime === "REFINING" || subRegime === "LOOPING" ? "medium"
|
|
101
|
-
: mode === "quality" || mode === "longrun" || mode === "forensic" || mode === "audit" ? "brain"
|
|
101
|
+
: mode === "quality" || mode === "longrun" || mode === "vibeultrax" || mode === "vibeqmax" || mode === "forensic" || mode === "audit" ? "brain"
|
|
102
102
|
: mode === "speed" || mode === "vibemax" || mode === "vibelitex" ? "medium"
|
|
103
103
|
: mode === "balanced" ? "auto"
|
|
104
104
|
: "cheap";
|