@vibgrate/cli 2026.722.2 → 2026.727.2
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/DOCS.md +418 -213
- package/README.md +34 -8
- package/dist/baseline-TG4ATZGZ.js +8 -0
- package/dist/{baseline-BD3A7EXD.js.map → baseline-TG4ATZGZ.js.map} +1 -1
- package/dist/chunk-2MBL43EJ.js +82 -0
- package/dist/chunk-2MBL43EJ.js.map +1 -0
- package/dist/chunk-2XQDMLKB.js +465 -0
- package/dist/chunk-2XQDMLKB.js.map +1 -0
- package/dist/{chunk-PY3DNX5H.js → chunk-3Q7QBWFW.js} +13 -2
- package/dist/chunk-3Q7QBWFW.js.map +1 -0
- package/dist/chunk-3V24O47U.js +478 -0
- package/dist/chunk-3V24O47U.js.map +1 -0
- package/dist/chunk-5I4VSBWQ.js +764 -0
- package/dist/chunk-5I4VSBWQ.js.map +1 -0
- package/dist/{chunk-WNIIKCNF.js → chunk-6ABXHZRN.js} +59 -311
- package/dist/chunk-6ABXHZRN.js.map +1 -0
- package/dist/chunk-6AYDFFP5.js +136 -0
- package/dist/chunk-6AYDFFP5.js.map +1 -0
- package/dist/chunk-6UQMXIAG.js +122 -0
- package/dist/chunk-6UQMXIAG.js.map +1 -0
- package/dist/chunk-7N4Y3E47.js +108 -0
- package/dist/chunk-7N4Y3E47.js.map +1 -0
- package/dist/chunk-BPF3YX2U.js +64 -0
- package/dist/chunk-BPF3YX2U.js.map +1 -0
- package/dist/chunk-BWPBB45M.js +88 -0
- package/dist/chunk-BWPBB45M.js.map +1 -0
- package/dist/{chunk-6CXTPC74.js → chunk-CY4WKXB2.js} +27 -6
- package/dist/chunk-CY4WKXB2.js.map +1 -0
- package/dist/chunk-DGUM43GV.js +10 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/{chunk-NONYJLOJ.js → chunk-EX4PQT6W.js} +3 -3
- package/dist/{chunk-NONYJLOJ.js.map → chunk-EX4PQT6W.js.map} +1 -1
- package/dist/chunk-IS7VTH2Q.js +627 -0
- package/dist/chunk-IS7VTH2Q.js.map +1 -0
- package/dist/chunk-IZDH67DX.js +289 -0
- package/dist/chunk-IZDH67DX.js.map +1 -0
- package/dist/chunk-J4RFRKZH.js +2496 -0
- package/dist/chunk-J4RFRKZH.js.map +1 -0
- package/dist/chunk-J7LKEB2R.js +51 -0
- package/dist/chunk-J7LKEB2R.js.map +1 -0
- package/dist/chunk-JIBOJTGS.js +313 -0
- package/dist/chunk-JIBOJTGS.js.map +1 -0
- package/dist/chunk-K3MZIVZW.js +88 -0
- package/dist/chunk-K3MZIVZW.js.map +1 -0
- package/dist/chunk-K7REHDQS.js +776 -0
- package/dist/chunk-K7REHDQS.js.map +1 -0
- package/dist/{chunk-2O5YZVZV.js → chunk-KCKYKDMS.js} +23 -19
- package/dist/chunk-KCKYKDMS.js.map +1 -0
- package/dist/{chunk-3MXNNBLI.js → chunk-KNELIQJO.js} +1647 -2042
- package/dist/chunk-KNELIQJO.js.map +1 -0
- package/dist/chunk-KSBHGWRV.js +613 -0
- package/dist/chunk-KSBHGWRV.js.map +1 -0
- package/dist/chunk-LKVMI67M.js +1695 -0
- package/dist/chunk-LKVMI67M.js.map +1 -0
- package/dist/chunk-NDMDSPFX.js +69 -0
- package/dist/chunk-NDMDSPFX.js.map +1 -0
- package/dist/{chunk-CS37OBE3.js → chunk-OFUC6RYN.js} +791 -783
- package/dist/chunk-OFUC6RYN.js.map +1 -0
- package/dist/chunk-OOIG3RUM.js +276 -0
- package/dist/chunk-OOIG3RUM.js.map +1 -0
- package/dist/chunk-PMYWZRRS.js +62 -0
- package/dist/chunk-PMYWZRRS.js.map +1 -0
- package/dist/chunk-PXHNTC6D.js +382 -0
- package/dist/chunk-PXHNTC6D.js.map +1 -0
- package/dist/{chunk-I7GY7MVN.js → chunk-RNP3SMTV.js} +60 -12
- package/dist/chunk-RNP3SMTV.js.map +1 -0
- package/dist/chunk-TCDAZZNP.js +843 -0
- package/dist/chunk-TCDAZZNP.js.map +1 -0
- package/dist/{chunk-5BDHQ7DD.js → chunk-WGUL45AV.js} +24 -17
- package/dist/chunk-WGUL45AV.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +3373 -617
- package/dist/cli.js.map +1 -1
- package/dist/execution-env-ZU45JZ4G.js +4 -0
- package/dist/execution-env-ZU45JZ4G.js.map +1 -0
- package/dist/federation-SZWZIFZ7.js +7 -0
- package/dist/federation-SZWZIFZ7.js.map +1 -0
- package/dist/{fs-IPY4FJKH.js → fs-B5HZ2MIU.js} +3 -2
- package/dist/fs-B5HZ2MIU.js.map +1 -0
- package/dist/{fs-KCABDURV.js → fs-O5IQYXHO.js} +3 -2
- package/dist/fs-O5IQYXHO.js.map +1 -0
- package/dist/git-ref-XDXB6JP5.js +4 -0
- package/dist/git-ref-XDXB6JP5.js.map +1 -0
- package/dist/graph-backend-73URGTFY.js +11 -0
- package/dist/graph-backend-73URGTFY.js.map +1 -0
- package/dist/index.d.ts +472 -137
- package/dist/index.js +15 -7
- package/dist/index.js.map +1 -1
- package/dist/{interactive-A4DISSIW.js → interactive-372NLI5C.js} +186 -226
- package/dist/interactive-372NLI5C.js.map +1 -0
- package/dist/llm-host-7GWDO6IX.js +9 -0
- package/dist/llm-host-7GWDO6IX.js.map +1 -0
- package/dist/load-I333TGNI.js +8 -0
- package/dist/load-I333TGNI.js.map +1 -0
- package/dist/local-runtime-5O2NN3GA.js +5 -0
- package/dist/local-runtime-5O2NN3GA.js.map +1 -0
- package/dist/mcp-tools-I7JK3S2M.js +4 -0
- package/dist/{mcp-tools-I6PME3AV.js.map → mcp-tools-I7JK3S2M.js.map} +1 -1
- package/dist/model-execution-profile-TFBKCNJG.js +4 -0
- package/dist/model-execution-profile-TFBKCNJG.js.map +1 -0
- package/dist/model-orchestrator-TVONAUPS.js +9 -0
- package/dist/model-orchestrator-TVONAUPS.js.map +1 -0
- package/dist/parse-worker.d.ts +1 -1
- package/dist/parse-worker.js +2 -1
- package/dist/parse-worker.js.map +1 -1
- package/dist/paths-2RAH3GME.js +6 -0
- package/dist/paths-2RAH3GME.js.map +1 -0
- package/dist/resolve-gguf-VPL4YQ6J.js +8 -0
- package/dist/resolve-gguf-VPL4YQ6J.js.map +1 -0
- package/dist/runtime-session-JRKCQUHY.js +18 -0
- package/dist/runtime-session-JRKCQUHY.js.map +1 -0
- package/dist/session-ITPYQ5XI.js +11 -0
- package/dist/{session-POJUDFPH.js.map → session-ITPYQ5XI.js.map} +1 -1
- package/dist/session-store-WFBX7HXL.js +4 -0
- package/dist/{session-store-W5RZZHA3.js.map → session-store-WFBX7HXL.js.map} +1 -1
- package/dist/{stream-json-Q2JGWPHB.js → stream-json-SLMDKLXP.js} +17 -6
- package/dist/stream-json-SLMDKLXP.js.map +1 -0
- package/dist/{types-Jl6RJ175.d.ts → types-7AHBUbFm.d.ts} +8 -2
- package/dist/ui-Q6DJ3GCU.js +5 -0
- package/dist/ui-Q6DJ3GCU.js.map +1 -0
- package/dist/vgd-7JV5KCNJ.js +17 -0
- package/dist/vgd-7JV5KCNJ.js.map +1 -0
- package/package.json +9 -6
- package/dist/baseline-BD3A7EXD.js +0 -7
- package/dist/chunk-2O5YZVZV.js.map +0 -1
- package/dist/chunk-3MXNNBLI.js.map +0 -1
- package/dist/chunk-5BDHQ7DD.js.map +0 -1
- package/dist/chunk-6CXTPC74.js.map +0 -1
- package/dist/chunk-CS37OBE3.js.map +0 -1
- package/dist/chunk-GGJZA3Q6.js +0 -961
- package/dist/chunk-GGJZA3Q6.js.map +0 -1
- package/dist/chunk-I7GY7MVN.js.map +0 -1
- package/dist/chunk-JBXNQCGE.js +0 -484
- package/dist/chunk-JBXNQCGE.js.map +0 -1
- package/dist/chunk-PY3DNX5H.js.map +0 -1
- package/dist/chunk-WNIIKCNF.js.map +0 -1
- package/dist/fs-IPY4FJKH.js.map +0 -1
- package/dist/fs-KCABDURV.js.map +0 -1
- package/dist/interactive-A4DISSIW.js.map +0 -1
- package/dist/mcp-tools-I6PME3AV.js +0 -3
- package/dist/session-POJUDFPH.js +0 -6
- package/dist/session-store-W5RZZHA3.js +0 -3
- package/dist/stream-json-Q2JGWPHB.js.map +0 -1
- package/dist/ui-HOVOPWMX.js +0 -4
- package/dist/ui-HOVOPWMX.js.map +0 -1
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
import { estimateModelBytes } from './chunk-7N4Y3E47.js';
|
|
2
|
+
import { MODEL_EXECUTION_PROFILE_SCHEMA_VERSION } from './chunk-IZDH67DX.js';
|
|
3
|
+
import { vibgrateDataDir } from './chunk-BWPBB45M.js';
|
|
4
|
+
import * as fs from 'fs';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
|
|
7
|
+
var MODEL_ORCHESTRATOR_SCHEMA_VERSION = "model-orchestrator/0";
|
|
8
|
+
var PACK_CHANNEL = "2026.07.3";
|
|
9
|
+
var QUALIFIED_PACKS = [
|
|
10
|
+
{
|
|
11
|
+
packId: `spark@${PACK_CHANNEL}`,
|
|
12
|
+
mode: "spark",
|
|
13
|
+
displayName: "Spark",
|
|
14
|
+
promise: "Fastest capable local coding \u2014 simple edits, minimal memory.",
|
|
15
|
+
primary: {
|
|
16
|
+
backend: "llama.cpp",
|
|
17
|
+
weightsRef: "qwen2.5-coder-3b-q4_k_m.gguf",
|
|
18
|
+
quant: "q4_k_m",
|
|
19
|
+
license: "Apache-2.0",
|
|
20
|
+
weightsBytes: estimateModelBytes("qwen2.5-coder:3b").bytes
|
|
21
|
+
},
|
|
22
|
+
fallback: [
|
|
23
|
+
{
|
|
24
|
+
backend: "ollama",
|
|
25
|
+
weightsRef: "qwen2.5-coder:3b",
|
|
26
|
+
quant: "q4_k_m",
|
|
27
|
+
license: "Apache-2.0",
|
|
28
|
+
weightsBytes: estimateModelBytes("qwen2.5-coder:3b").bytes
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
backend: "ollama",
|
|
32
|
+
weightsRef: "qwen2.5-coder:1.5b",
|
|
33
|
+
quant: "q4_k_m",
|
|
34
|
+
license: "Apache-2.0",
|
|
35
|
+
weightsBytes: estimateModelBytes("qwen2.5-coder:1.5b").bytes
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
contract: {
|
|
39
|
+
toolCalling: "grammar",
|
|
40
|
+
editFormat: "patch_ir_json",
|
|
41
|
+
capsuleBudgetTokens: 2e3,
|
|
42
|
+
maxRepairRounds: 2,
|
|
43
|
+
maxParallelEdits: 2,
|
|
44
|
+
minEffectiveScore: 0.55,
|
|
45
|
+
constrainedDecoding: true,
|
|
46
|
+
preferredInference: "llama.cpp",
|
|
47
|
+
inferenceIsolation: "embedded",
|
|
48
|
+
kvCacheStrategy: "stable_prefix",
|
|
49
|
+
securityTier: "L1"
|
|
50
|
+
},
|
|
51
|
+
resources: { minRamGb: 4, estimatedKvPer1kContext: 2 * 1024 * 1024 },
|
|
52
|
+
provenance: {
|
|
53
|
+
notes: "Spark@2026.07.3 \u2014 Approach B default: GGUF primary, PatchIR grammar fail-closed, Ollama fallback"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
packId: `flow@${PACK_CHANNEL}`,
|
|
58
|
+
mode: "flow",
|
|
59
|
+
displayName: "Flow",
|
|
60
|
+
promise: "Best everyday graph-guided coding for this machine.",
|
|
61
|
+
primary: {
|
|
62
|
+
backend: "llama.cpp",
|
|
63
|
+
weightsRef: "qwen2.5-coder-7b-q4_k_m.gguf",
|
|
64
|
+
quant: "q4_k_m",
|
|
65
|
+
license: "Apache-2.0",
|
|
66
|
+
weightsBytes: estimateModelBytes("qwen2.5-coder:7b").bytes
|
|
67
|
+
},
|
|
68
|
+
fallback: [
|
|
69
|
+
{
|
|
70
|
+
backend: "ollama",
|
|
71
|
+
weightsRef: "qwen2.5-coder:7b",
|
|
72
|
+
quant: "q4_k_m",
|
|
73
|
+
license: "Apache-2.0",
|
|
74
|
+
weightsBytes: estimateModelBytes("qwen2.5-coder:7b").bytes
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
backend: "ollama",
|
|
78
|
+
weightsRef: "qwen2.5-coder:3b",
|
|
79
|
+
quant: "q4_k_m",
|
|
80
|
+
license: "Apache-2.0",
|
|
81
|
+
weightsBytes: estimateModelBytes("qwen2.5-coder:3b").bytes
|
|
82
|
+
}
|
|
83
|
+
],
|
|
84
|
+
contract: {
|
|
85
|
+
toolCalling: "native",
|
|
86
|
+
editFormat: "auto",
|
|
87
|
+
capsuleBudgetTokens: 3500,
|
|
88
|
+
maxRepairRounds: 2,
|
|
89
|
+
maxParallelEdits: 4,
|
|
90
|
+
minEffectiveScore: 0.65,
|
|
91
|
+
constrainedDecoding: false,
|
|
92
|
+
preferredInference: "llama.cpp",
|
|
93
|
+
inferenceIsolation: "embedded",
|
|
94
|
+
kvCacheStrategy: "stable_prefix",
|
|
95
|
+
securityTier: "L1"
|
|
96
|
+
},
|
|
97
|
+
resources: { minRamGb: 8, minVramGb: 6, estimatedKvPer1kContext: 4 * 1024 * 1024 },
|
|
98
|
+
provenance: {
|
|
99
|
+
notes: "Flow@2026.07.3 \u2014 Approach B default GGUF when fit allows; Ollama fallback for machines without store"
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
packId: `forge@${PACK_CHANNEL}`,
|
|
104
|
+
mode: "forge",
|
|
105
|
+
displayName: "Forge",
|
|
106
|
+
promise: "Strongest deep work that safely fits (migrations, multi-file).",
|
|
107
|
+
primary: {
|
|
108
|
+
backend: "ollama",
|
|
109
|
+
weightsRef: "qwen2.5-coder:14b",
|
|
110
|
+
quant: "q4_k_m",
|
|
111
|
+
license: "Apache-2.0",
|
|
112
|
+
weightsBytes: estimateModelBytes("qwen2.5-coder:14b").bytes
|
|
113
|
+
},
|
|
114
|
+
fallback: [
|
|
115
|
+
{
|
|
116
|
+
backend: "ollama",
|
|
117
|
+
weightsRef: "qwen2.5-coder:7b",
|
|
118
|
+
quant: "q4_k_m",
|
|
119
|
+
license: "Apache-2.0",
|
|
120
|
+
weightsBytes: estimateModelBytes("qwen2.5-coder:7b").bytes
|
|
121
|
+
}
|
|
122
|
+
],
|
|
123
|
+
contract: {
|
|
124
|
+
toolCalling: "native",
|
|
125
|
+
editFormat: "patch_ir_json",
|
|
126
|
+
capsuleBudgetTokens: 6e3,
|
|
127
|
+
maxRepairRounds: 3,
|
|
128
|
+
maxParallelEdits: 6,
|
|
129
|
+
minEffectiveScore: 0.7,
|
|
130
|
+
constrainedDecoding: false,
|
|
131
|
+
preferredInference: "ollama",
|
|
132
|
+
kvCacheStrategy: "stable_prefix",
|
|
133
|
+
securityTier: "L1"
|
|
134
|
+
},
|
|
135
|
+
resources: { minRamGb: 16, minVramGb: 12, estimatedKvPer1kContext: 8 * 1024 * 1024 },
|
|
136
|
+
provenance: { notes: "Forge@2026.07.2 \u2014 deep work; PatchIR-oriented edits without forced grammar yet" }
|
|
137
|
+
}
|
|
138
|
+
];
|
|
139
|
+
var GiB = 1024 ** 3;
|
|
140
|
+
var DEFAULT_RESERVES = {
|
|
141
|
+
ideBytes: 1.5 * GiB,
|
|
142
|
+
osBytes: 2 * GiB,
|
|
143
|
+
graphBytes: 0.5 * GiB,
|
|
144
|
+
testsBytes: 0.25 * GiB,
|
|
145
|
+
safetyMarginBytes: 1 * GiB
|
|
146
|
+
};
|
|
147
|
+
var IDE_OS_GROWTH_FRACTION = 0.25;
|
|
148
|
+
function packForMode(mode, packs = QUALIFIED_PACKS) {
|
|
149
|
+
return packs.find((p) => p.mode === mode) ?? null;
|
|
150
|
+
}
|
|
151
|
+
function packById(packId, packs = QUALIFIED_PACKS) {
|
|
152
|
+
return packs.find((p) => p.packId === packId) ?? null;
|
|
153
|
+
}
|
|
154
|
+
function listModes() {
|
|
155
|
+
return ["spark", "flow", "forge"];
|
|
156
|
+
}
|
|
157
|
+
function fitPack(input) {
|
|
158
|
+
const r = { ...DEFAULT_RESERVES, ...input.reserves };
|
|
159
|
+
const pack = input.pack;
|
|
160
|
+
const weightsBytes = pack.primary.weightsBytes ?? estimateModelBytes(pack.primary.weightsRef).bytes;
|
|
161
|
+
const ctxTokens = input.contextBudgetTokens ?? pack.contract.capsuleBudgetTokens * 2;
|
|
162
|
+
const kvPer1k = pack.resources.estimatedKvPer1kContext ?? 2 * 1024 * 1024;
|
|
163
|
+
const kvBytes = Math.round(ctxTokens / 1e3 * kvPer1k);
|
|
164
|
+
const modelBytes = weightsBytes;
|
|
165
|
+
const needBytes = modelBytes + kvBytes;
|
|
166
|
+
const useVram = typeof input.system.vramTotalBytes === "number" && input.system.vramTotalBytes > 0;
|
|
167
|
+
const freeNow = useVram ? input.system.vramFreeBytes ?? 0 : input.system.freeRamBytes;
|
|
168
|
+
const loadedBytes = input.system.loaded.reduce((n, m) => n + m.bytes, 0);
|
|
169
|
+
const freePool = freeNow + loadedBytes;
|
|
170
|
+
const graphBump = (input.repo?.graphNodeCount ?? 0) > 5e4 ? 0.5 * GiB : (input.repo?.fileCount ?? 0) > 5e3 ? 0.25 * GiB : 0;
|
|
171
|
+
const graphBytes = r.graphBytes + graphBump;
|
|
172
|
+
const reserved = useVram ? r.safetyMarginBytes : graphBytes + r.testsBytes + r.safetyMarginBytes + IDE_OS_GROWTH_FRACTION * (r.ideBytes + r.osBytes);
|
|
173
|
+
const freeAfterReserves = Math.max(0, freePool - reserved);
|
|
174
|
+
const availableBytes = freeAfterReserves;
|
|
175
|
+
const reasons = [];
|
|
176
|
+
const headroom = availableBytes - needBytes;
|
|
177
|
+
const ratio = needBytes > 0 ? availableBytes / needBytes : 0;
|
|
178
|
+
let label;
|
|
179
|
+
let reducedCapsuleBudgetTokens;
|
|
180
|
+
if (availableBytes < needBytes * 0.85) {
|
|
181
|
+
label = "will_not_fit";
|
|
182
|
+
reasons.push(
|
|
183
|
+
`needs ~${fmtGb(needBytes)} but only ~${fmtGb(availableBytes)} is free after reserves`
|
|
184
|
+
);
|
|
185
|
+
} else if (ratio < 1.1 || headroom < 0.5 * GiB) {
|
|
186
|
+
label = "tight";
|
|
187
|
+
reducedCapsuleBudgetTokens = Math.max(
|
|
188
|
+
1200,
|
|
189
|
+
Math.floor(pack.contract.capsuleBudgetTokens * 0.65)
|
|
190
|
+
);
|
|
191
|
+
reasons.push("tight fit \u2014 capsule budget will be reduced automatically");
|
|
192
|
+
} else if (ratio >= 1.6 && headroom >= 2 * GiB) {
|
|
193
|
+
label = "flies";
|
|
194
|
+
reasons.push("comfortable headroom for this mode");
|
|
195
|
+
} else {
|
|
196
|
+
label = "comfortable";
|
|
197
|
+
reasons.push("within policy for this machine");
|
|
198
|
+
}
|
|
199
|
+
if (pack.mode === "forge" && ((input.repo?.fileCount ?? 0) > 1e4 || (input.repo?.graphNodeCount ?? 0) > 1e5) && label === "comfortable") {
|
|
200
|
+
reasons.push("large repository \u2014 prefer moderated capsule + graph paging");
|
|
201
|
+
}
|
|
202
|
+
let score = Math.max(0, Math.min(100, Math.round(ratio * 50)));
|
|
203
|
+
if (label === "will_not_fit") score = Math.min(score, 20);
|
|
204
|
+
if (label === "tight") score = Math.min(Math.max(score, 25), 45);
|
|
205
|
+
if (label === "comfortable") score = Math.min(Math.max(score, 50), 75);
|
|
206
|
+
if (label === "flies") score = Math.max(score, 80);
|
|
207
|
+
return {
|
|
208
|
+
label,
|
|
209
|
+
score,
|
|
210
|
+
needBytes,
|
|
211
|
+
availableBytes,
|
|
212
|
+
breakdown: {
|
|
213
|
+
modelBytes,
|
|
214
|
+
kvBytes,
|
|
215
|
+
// Report the charged growth headroom (not the full static IDE/OS footprint).
|
|
216
|
+
ideBytes: useVram ? 0 : IDE_OS_GROWTH_FRACTION * r.ideBytes,
|
|
217
|
+
osBytes: useVram ? 0 : IDE_OS_GROWTH_FRACTION * r.osBytes,
|
|
218
|
+
graphBytes: useVram ? 0 : graphBytes,
|
|
219
|
+
testsBytes: useVram ? 0 : r.testsBytes,
|
|
220
|
+
freeAfterReservesBytes: freeAfterReserves
|
|
221
|
+
},
|
|
222
|
+
reducedCapsuleBudgetTokens,
|
|
223
|
+
reasons
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
function fmtGb(bytes) {
|
|
227
|
+
return `${(bytes / GiB).toFixed(1)} GiB`;
|
|
228
|
+
}
|
|
229
|
+
function packToProfile(pack, underlying, fit) {
|
|
230
|
+
const budget = fit.label === "tight" && fit.reducedCapsuleBudgetTokens ? fit.reducedCapsuleBudgetTokens : pack.contract.capsuleBudgetTokens;
|
|
231
|
+
return {
|
|
232
|
+
schemaVersion: MODEL_EXECUTION_PROFILE_SCHEMA_VERSION,
|
|
233
|
+
id: underlying.weightsRef,
|
|
234
|
+
displayName: `${pack.displayName} \xB7 ${underlying.weightsRef}`,
|
|
235
|
+
mode: pack.mode,
|
|
236
|
+
backend: underlying.backend === "ollama" ? "ollama" : underlying.backend === "llama.cpp" ? "llama.cpp" : underlying.backend === "lm-studio" ? "openai-compatible" : "other",
|
|
237
|
+
toolCalling: pack.contract.toolCalling,
|
|
238
|
+
editFormat: pack.contract.editFormat,
|
|
239
|
+
capsuleBudgetTokens: budget,
|
|
240
|
+
maxParallelEdits: pack.contract.maxParallelEdits,
|
|
241
|
+
maxRepairRounds: pack.contract.maxRepairRounds,
|
|
242
|
+
temperature: 0,
|
|
243
|
+
constrainedDecoding: pack.contract.constrainedDecoding ?? false,
|
|
244
|
+
kvCacheStrategy: pack.contract.kvCacheStrategy,
|
|
245
|
+
resources: {
|
|
246
|
+
minRamGb: pack.resources.minRamGb,
|
|
247
|
+
minVramGb: pack.resources.minVramGb,
|
|
248
|
+
quant: underlying.quant
|
|
249
|
+
},
|
|
250
|
+
securityTier: pack.contract.securityTier,
|
|
251
|
+
inferenceIsolation: pack.contract.inferenceIsolation ?? "embedded"
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
function tryWeights(pack, weights, system, repo, taskClass) {
|
|
255
|
+
const trial = { ...pack, primary: weights };
|
|
256
|
+
return { fit: fitPack({ system, pack: trial, repo}), underlying: weights };
|
|
257
|
+
}
|
|
258
|
+
function resolveMode(opts) {
|
|
259
|
+
const packs = opts.packs ?? QUALIFIED_PACKS;
|
|
260
|
+
const defaultMode = opts.defaultMode ?? "flow";
|
|
261
|
+
let mode = opts.mode ?? defaultMode;
|
|
262
|
+
let selection = opts.mode ? "explicit" : "default";
|
|
263
|
+
if (!opts.mode && opts.autoFit !== false) {
|
|
264
|
+
mode = recommendMode(opts.system, opts.repo, packs);
|
|
265
|
+
selection = "auto_fit";
|
|
266
|
+
}
|
|
267
|
+
let pack = packForMode(mode, packs);
|
|
268
|
+
if (!pack) {
|
|
269
|
+
pack = packForMode("flow", packs);
|
|
270
|
+
mode = "flow";
|
|
271
|
+
selection = "default";
|
|
272
|
+
}
|
|
273
|
+
if (opts.pin && opts.pin.mode === mode) {
|
|
274
|
+
const pinned = packById(opts.pin.packId, packs);
|
|
275
|
+
if (pinned && pinned.mode === mode) {
|
|
276
|
+
pack = pinned;
|
|
277
|
+
selection = "pinned";
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
const candidates = [pack.primary, ...pack.fallback ?? []];
|
|
281
|
+
let best = null;
|
|
282
|
+
for (const w of candidates) {
|
|
283
|
+
const trial = tryWeights(pack, w, opts.system, opts.repo, opts.taskClass);
|
|
284
|
+
if (!best || fitRank(trial.fit) > fitRank(best.fit)) best = trial;
|
|
285
|
+
if (trial.fit.label === "flies" || trial.fit.label === "comfortable") {
|
|
286
|
+
best = trial;
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
const chosen = best ?? tryWeights(pack, pack.primary, opts.system, opts.repo, opts.taskClass);
|
|
291
|
+
const profile = packToProfile(pack, chosen.underlying, chosen.fit);
|
|
292
|
+
return {
|
|
293
|
+
schemaVersion: MODEL_ORCHESTRATOR_SCHEMA_VERSION,
|
|
294
|
+
mode,
|
|
295
|
+
pack,
|
|
296
|
+
underlying: chosen.underlying,
|
|
297
|
+
fit: chosen.fit,
|
|
298
|
+
profile,
|
|
299
|
+
pinned: selection === "pinned",
|
|
300
|
+
selection
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
function fitRank(f) {
|
|
304
|
+
const order = {
|
|
305
|
+
flies: 4,
|
|
306
|
+
comfortable: 3,
|
|
307
|
+
tight: 2,
|
|
308
|
+
will_not_fit: 1
|
|
309
|
+
};
|
|
310
|
+
return order[f.label] * 1e3 + f.score;
|
|
311
|
+
}
|
|
312
|
+
function recommendMode(system, repo, packs = QUALIFIED_PACKS) {
|
|
313
|
+
const order = ["forge", "flow", "spark"];
|
|
314
|
+
let bestTight = null;
|
|
315
|
+
for (const mode of order) {
|
|
316
|
+
const pack = packForMode(mode, packs);
|
|
317
|
+
if (!pack) continue;
|
|
318
|
+
const resolved = resolveMode({
|
|
319
|
+
mode,
|
|
320
|
+
autoFit: false,
|
|
321
|
+
system,
|
|
322
|
+
repo,
|
|
323
|
+
packs
|
|
324
|
+
});
|
|
325
|
+
if (resolved.fit.label === "flies" || resolved.fit.label === "comfortable") {
|
|
326
|
+
if (mode === "forge") {
|
|
327
|
+
const flow = resolveMode({ mode: "flow", autoFit: false, system, repo, packs });
|
|
328
|
+
if (flow.fit.label === "flies" || flow.fit.label === "comfortable") {
|
|
329
|
+
const files = repo?.fileCount ?? 0;
|
|
330
|
+
if (files < 2e3) return "flow";
|
|
331
|
+
}
|
|
332
|
+
return "forge";
|
|
333
|
+
}
|
|
334
|
+
return mode;
|
|
335
|
+
}
|
|
336
|
+
if (resolved.fit.label === "tight" && !bestTight) bestTight = mode;
|
|
337
|
+
}
|
|
338
|
+
return bestTight ?? "spark";
|
|
339
|
+
}
|
|
340
|
+
function buildOrchestratorStatus(opts) {
|
|
341
|
+
const packs = opts.packs ?? QUALIFIED_PACKS;
|
|
342
|
+
const installed = new Set((opts.installedNames ?? []).map((n) => n.toLowerCase()));
|
|
343
|
+
const recommended = recommendMode(opts.system, opts.repo, packs);
|
|
344
|
+
const pinFor = (mode) => {
|
|
345
|
+
const fromMap = opts.pins?.[mode];
|
|
346
|
+
if (fromMap) return { mode, packId: fromMap };
|
|
347
|
+
if (opts.pin?.mode === mode) return opts.pin;
|
|
348
|
+
return null;
|
|
349
|
+
};
|
|
350
|
+
const modes = listModes().map((mode) => {
|
|
351
|
+
const resolved = resolveMode({
|
|
352
|
+
mode,
|
|
353
|
+
autoFit: false,
|
|
354
|
+
system: opts.system,
|
|
355
|
+
repo: opts.repo,
|
|
356
|
+
pin: pinFor(mode),
|
|
357
|
+
packs
|
|
358
|
+
});
|
|
359
|
+
const id = resolved.underlying.weightsRef.toLowerCase();
|
|
360
|
+
const installedHit = installed.has(id) || [...installed].some((n) => n.includes(id) || id.includes(n));
|
|
361
|
+
return {
|
|
362
|
+
mode,
|
|
363
|
+
packId: resolved.pack.packId,
|
|
364
|
+
displayName: resolved.pack.displayName,
|
|
365
|
+
promise: resolved.pack.promise,
|
|
366
|
+
underlyingModelId: resolved.underlying.weightsRef,
|
|
367
|
+
backend: resolved.underlying.backend,
|
|
368
|
+
fit: resolved.fit.label,
|
|
369
|
+
fitScore: resolved.fit.score,
|
|
370
|
+
needBytes: resolved.fit.needBytes,
|
|
371
|
+
availableBytes: resolved.fit.availableBytes,
|
|
372
|
+
installed: installedHit,
|
|
373
|
+
pinned: resolved.pinned
|
|
374
|
+
};
|
|
375
|
+
});
|
|
376
|
+
const recResolved = resolveMode({
|
|
377
|
+
mode: recommended,
|
|
378
|
+
autoFit: false,
|
|
379
|
+
system: opts.system,
|
|
380
|
+
repo: opts.repo,
|
|
381
|
+
pin: pinFor(recommended),
|
|
382
|
+
packs
|
|
383
|
+
});
|
|
384
|
+
return {
|
|
385
|
+
schemaVersion: MODEL_ORCHESTRATOR_SCHEMA_VERSION,
|
|
386
|
+
defaultMode: opts.defaultMode ?? "flow",
|
|
387
|
+
pin: pinFor(recommended),
|
|
388
|
+
modes,
|
|
389
|
+
recommended,
|
|
390
|
+
system: {
|
|
391
|
+
totalRamBytes: opts.system.totalRamBytes,
|
|
392
|
+
freeRamBytes: opts.system.freeRamBytes,
|
|
393
|
+
...typeof opts.system.vramTotalBytes === "number" ? { vramTotalBytes: opts.system.vramTotalBytes } : {},
|
|
394
|
+
...typeof opts.system.vramFreeBytes === "number" ? { vramFreeBytes: opts.system.vramFreeBytes } : {},
|
|
395
|
+
loaded: opts.system.loaded.map((l) => ({ name: l.name, bytes: l.bytes }))
|
|
396
|
+
},
|
|
397
|
+
memoryBreakdown: recResolved.fit.breakdown
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
function orchestratorStatePath(env = process.env, platform = process.platform, home) {
|
|
401
|
+
return path.join(vibgrateDataDir(env, platform, home), "model-orchestrator", "state.json");
|
|
402
|
+
}
|
|
403
|
+
function readOrchestratorState(env = process.env, platform = process.platform, home) {
|
|
404
|
+
const p = orchestratorStatePath(env, platform, home);
|
|
405
|
+
try {
|
|
406
|
+
const raw = JSON.parse(fs.readFileSync(p, "utf8"));
|
|
407
|
+
return {
|
|
408
|
+
schemaVersion: "model-orchestrator-pin/0",
|
|
409
|
+
pins: raw.pins && typeof raw.pins === "object" ? raw.pins : {},
|
|
410
|
+
defaultMode: raw.defaultMode === "spark" || raw.defaultMode === "flow" || raw.defaultMode === "forge" ? raw.defaultMode : void 0,
|
|
411
|
+
updatedAt: typeof raw.updatedAt === "string" ? raw.updatedAt : (/* @__PURE__ */ new Date(0)).toISOString()
|
|
412
|
+
};
|
|
413
|
+
} catch {
|
|
414
|
+
return {
|
|
415
|
+
schemaVersion: "model-orchestrator-pin/0",
|
|
416
|
+
pins: {},
|
|
417
|
+
updatedAt: (/* @__PURE__ */ new Date(0)).toISOString()
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
function writeOrchestratorState(state, env = process.env, platform = process.platform, home) {
|
|
422
|
+
const p = orchestratorStatePath(env, platform, home);
|
|
423
|
+
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
424
|
+
const next = {
|
|
425
|
+
...state,
|
|
426
|
+
schemaVersion: "model-orchestrator-pin/0",
|
|
427
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
428
|
+
};
|
|
429
|
+
fs.writeFileSync(p, JSON.stringify(next, null, 2) + "\n", "utf8");
|
|
430
|
+
return p;
|
|
431
|
+
}
|
|
432
|
+
function pinPack(mode, packId, env, platform, home) {
|
|
433
|
+
const state = readOrchestratorState(env, platform, home);
|
|
434
|
+
if (!packById(packId)) {
|
|
435
|
+
throw new Error(`unknown pack id: ${packId}`);
|
|
436
|
+
}
|
|
437
|
+
state.pins[mode] = packId;
|
|
438
|
+
writeOrchestratorState(state, env, platform, home);
|
|
439
|
+
return state;
|
|
440
|
+
}
|
|
441
|
+
function unpinPack(mode, env, platform, home) {
|
|
442
|
+
const state = readOrchestratorState(env, platform, home);
|
|
443
|
+
delete state.pins[mode];
|
|
444
|
+
writeOrchestratorState(state, env, platform, home);
|
|
445
|
+
return state;
|
|
446
|
+
}
|
|
447
|
+
function setDefaultMode(mode, env, platform, home) {
|
|
448
|
+
const state = readOrchestratorState(env, platform, home);
|
|
449
|
+
state.defaultMode = mode;
|
|
450
|
+
writeOrchestratorState(state, env, platform, home);
|
|
451
|
+
return state;
|
|
452
|
+
}
|
|
453
|
+
function activePin(mode, state = readOrchestratorState()) {
|
|
454
|
+
const packId = state.pins[mode];
|
|
455
|
+
return packId ? { mode, packId } : null;
|
|
456
|
+
}
|
|
457
|
+
function providerForBackend(backend) {
|
|
458
|
+
switch (backend) {
|
|
459
|
+
case "ollama":
|
|
460
|
+
return "ollama";
|
|
461
|
+
case "llama.cpp":
|
|
462
|
+
return "llama-cpp";
|
|
463
|
+
case "lm-studio":
|
|
464
|
+
return "lmstudio";
|
|
465
|
+
default:
|
|
466
|
+
return "ollama";
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
function parseMode(raw) {
|
|
470
|
+
if (!raw) return null;
|
|
471
|
+
const m = raw.trim().toLowerCase();
|
|
472
|
+
if (m === "spark" || m === "flow" || m === "forge") return m;
|
|
473
|
+
return null;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
export { MODEL_ORCHESTRATOR_SCHEMA_VERSION, QUALIFIED_PACKS, activePin, buildOrchestratorStatus, fitPack, listModes, orchestratorStatePath, packById, packForMode, parseMode, pinPack, providerForBackend, readOrchestratorState, recommendMode, resolveMode, setDefaultMode, unpinPack, writeOrchestratorState };
|
|
477
|
+
//# sourceMappingURL=chunk-3V24O47U.js.map
|
|
478
|
+
//# sourceMappingURL=chunk-3V24O47U.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/model-orchestrator.ts"],"names":[],"mappings":"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","file":"chunk-3V24O47U.js","sourcesContent":["/**\n * Vibgrate Model Orchestrator — Code Modes (Spark / Flow / Forge).\n *\n * Product stance (PRD): users and agents select outcome-oriented **Code Modes**,\n * never GGUF names by default. This module:\n * 1. Declares versioned **qualified packs** (contract + primary/fallback weights)\n * 2. Runs a **fit** algorithm (available memory now × reserves × repo signals)\n * 3. Resolves mode → pack → concrete model / backend\n * 4. Supports pin/unpin for reproducibility\n *\n * Pure resolve + fit helpers have no I/O. Registry pin state uses the global\n * Vibgrate data dir (never in-repo). Pull/ensure is a separate CLI concern that\n * calls into `vg models pull` after resolve.\n *\n * schemaVersion: model-orchestrator/0\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { estimateModelBytes, type SystemMemory } from '../code/capability.js';\nimport {\n MODEL_EXECUTION_PROFILE_SCHEMA_VERSION,\n type ModelExecutionProfile,\n type ModelMode,\n type ToolCallingMode,\n type EditFormatPreference,\n} from './model-execution-profile.js';\nimport { vibgrateDataDir } from './paths.js';\n\nexport const MODEL_ORCHESTRATOR_SCHEMA_VERSION = 'model-orchestrator/0' as const;\n\n/** UX fit vocabulary (stricter than “weights fit”). */\nexport type FitLabel = 'flies' | 'comfortable' | 'tight' | 'will_not_fit';\n\nexport type TaskClass = 'spark_task' | 'flow_task' | 'forge_task' | 'explicit_mode';\n\nexport interface PackWeightsRef {\n /** Backend that can load these weights. */\n backend: 'ollama' | 'llama.cpp' | 'lm-studio' | 'foundry-local' | 'other';\n /** Concrete model id / slug (e.g. qwen2.5-coder:3b). */\n weightsRef: string;\n quant?: string;\n /** SPDX / short license note for first-download surface. */\n license?: string;\n /** Approx weights size in bytes (for fit when not discoverable). */\n weightsBytes?: number;\n /**\n * Optional HTTPS GGUF URL for the first-party weight store (must pass host\n * allowlist). When set, `vg models install` can download without Ollama.\n */\n downloadUrl?: string;\n /** Optional content hash for downloaded GGUF. */\n sha256?: string;\n}\n\nexport interface PackContract {\n toolCalling: ToolCallingMode;\n editFormat: EditFormatPreference;\n capsuleBudgetTokens: number;\n maxRepairRounds: number;\n maxParallelEdits: number;\n /** Minimum qualification score (0–1) this pack was gated on. */\n minEffectiveScore?: number;\n constrainedDecoding?: boolean;\n kvCacheStrategy?: ModelExecutionProfile['kvCacheStrategy'];\n securityTier?: ModelExecutionProfile['securityTier'];\n /**\n * Preferred inference path when available (ADR-005). Weights may still be\n * pulled via Ollama; embedded llama.cpp is preferred for sampler/grammar.\n */\n preferredInference?: 'ollama' | 'llama.cpp';\n /** Process isolation for preferredInference llama.cpp (default embedded). */\n inferenceIsolation?: ModelExecutionProfile['inferenceIsolation'];\n}\n\nexport interface QualifiedPack {\n /** e.g. flow@2026.07.1 */\n packId: string;\n mode: ModelMode;\n displayName: string;\n /** User-facing promise (one line). */\n promise: string;\n primary: PackWeightsRef;\n fallback?: PackWeightsRef[];\n contract: PackContract;\n resources: {\n minRamGb: number;\n minVramGb?: number;\n /** Estimated KV cache bytes per 1k context tokens. */\n estimatedKvPer1kContext?: number;\n };\n provenance?: {\n evalRunIds?: string[];\n notes?: string;\n };\n}\n\nexport interface RepoSignals {\n /** Approximate source file count (0 = unknown). */\n fileCount?: number;\n /** Graph node count when a map is warm (0 = unknown). */\n graphNodeCount?: number;\n /** Dominant languages (optional). */\n languages?: string[];\n}\n\nexport interface FitInput {\n system: SystemMemory;\n pack: QualifiedPack;\n repo?: RepoSignals;\n taskClass?: TaskClass;\n /**\n * Static reserves (bytes) for IDE / OS / graph / tests.\n * Defaults applied when omitted.\n */\n reserves?: {\n ideBytes?: number;\n osBytes?: number;\n graphBytes?: number;\n testsBytes?: number;\n safetyMarginBytes?: number;\n };\n /** Context budget used to estimate KV (tokens). Defaults from pack contract. */\n contextBudgetTokens?: number;\n}\n\nexport interface FitResult {\n label: FitLabel;\n /** 0–100; higher is more headroom. */\n score: number;\n needBytes: number;\n availableBytes: number;\n /** Breakdown for “memory pie” UX. */\n breakdown: {\n modelBytes: number;\n kvBytes: number;\n ideBytes: number;\n osBytes: number;\n graphBytes: number;\n testsBytes: number;\n freeAfterReservesBytes: number;\n };\n /** When tight: suggested reduced capsule budget. */\n reducedCapsuleBudgetTokens?: number;\n reasons: string[];\n}\n\nexport interface ResolvedMode {\n schemaVersion: typeof MODEL_ORCHESTRATOR_SCHEMA_VERSION;\n mode: ModelMode;\n pack: QualifiedPack;\n /** Concrete weights chosen (primary or fallback after fit). */\n underlying: PackWeightsRef;\n fit: FitResult;\n profile: ModelExecutionProfile;\n /** True when pack id was pinned by the user. */\n pinned: boolean;\n /** How the mode was chosen. */\n selection: 'explicit' | 'default' | 'auto_fit' | 'pinned';\n}\n\nexport interface OrchestratorStatus {\n schemaVersion: typeof MODEL_ORCHESTRATOR_SCHEMA_VERSION;\n defaultMode: ModelMode;\n pin?: { mode: ModelMode; packId: string } | null;\n modes: Array<{\n mode: ModelMode;\n packId: string;\n displayName: string;\n promise: string;\n underlyingModelId: string;\n backend: string;\n fit: FitLabel;\n fitScore: number;\n needBytes: number;\n availableBytes: number;\n installed: boolean;\n pinned: boolean;\n }>;\n recommended: ModelMode;\n system: {\n totalRamBytes: number;\n freeRamBytes: number;\n vramTotalBytes?: number;\n vramFreeBytes?: number;\n loaded: Array<{ name: string; bytes: number }>;\n };\n memoryBreakdown?: FitResult['breakdown'];\n}\n\n// ── Curated packs (versioned; weights may change under the same mode contract) ─\n\n/** Pack channel — bump when contracts or weight refs change under stable mode names. */\nconst PACK_CHANNEL = '2026.07.3';\n\n/**\n * Current qualified packs — one primary per mode.\n *\n * Approach B default: Spark/Flow **primary** is first-party GGUF (llama.cpp)\n * for install + inference when fit allows. Ollama remains an explicit fallback\n * adapter, not the default path.\n */\nexport const QUALIFIED_PACKS: QualifiedPack[] = [\n {\n packId: `spark@${PACK_CHANNEL}`,\n mode: 'spark',\n displayName: 'Spark',\n promise: 'Fastest capable local coding — simple edits, minimal memory.',\n primary: {\n backend: 'llama.cpp',\n weightsRef: 'qwen2.5-coder-3b-q4_k_m.gguf',\n quant: 'q4_k_m',\n license: 'Apache-2.0',\n weightsBytes: estimateModelBytes('qwen2.5-coder:3b').bytes,\n },\n fallback: [\n {\n backend: 'ollama',\n weightsRef: 'qwen2.5-coder:3b',\n quant: 'q4_k_m',\n license: 'Apache-2.0',\n weightsBytes: estimateModelBytes('qwen2.5-coder:3b').bytes,\n },\n {\n backend: 'ollama',\n weightsRef: 'qwen2.5-coder:1.5b',\n quant: 'q4_k_m',\n license: 'Apache-2.0',\n weightsBytes: estimateModelBytes('qwen2.5-coder:1.5b').bytes,\n },\n ],\n contract: {\n toolCalling: 'grammar',\n editFormat: 'patch_ir_json',\n capsuleBudgetTokens: 2000,\n maxRepairRounds: 2,\n maxParallelEdits: 2,\n minEffectiveScore: 0.55,\n constrainedDecoding: true,\n preferredInference: 'llama.cpp',\n inferenceIsolation: 'embedded',\n kvCacheStrategy: 'stable_prefix',\n securityTier: 'L1',\n },\n resources: { minRamGb: 4, estimatedKvPer1kContext: 2 * 1024 * 1024 },\n provenance: {\n notes: 'Spark@2026.07.3 — Approach B default: GGUF primary, PatchIR grammar fail-closed, Ollama fallback',\n },\n },\n {\n packId: `flow@${PACK_CHANNEL}`,\n mode: 'flow',\n displayName: 'Flow',\n promise: 'Best everyday graph-guided coding for this machine.',\n primary: {\n backend: 'llama.cpp',\n weightsRef: 'qwen2.5-coder-7b-q4_k_m.gguf',\n quant: 'q4_k_m',\n license: 'Apache-2.0',\n weightsBytes: estimateModelBytes('qwen2.5-coder:7b').bytes,\n },\n fallback: [\n {\n backend: 'ollama',\n weightsRef: 'qwen2.5-coder:7b',\n quant: 'q4_k_m',\n license: 'Apache-2.0',\n weightsBytes: estimateModelBytes('qwen2.5-coder:7b').bytes,\n },\n {\n backend: 'ollama',\n weightsRef: 'qwen2.5-coder:3b',\n quant: 'q4_k_m',\n license: 'Apache-2.0',\n weightsBytes: estimateModelBytes('qwen2.5-coder:3b').bytes,\n },\n ],\n contract: {\n toolCalling: 'native',\n editFormat: 'auto',\n capsuleBudgetTokens: 3500,\n maxRepairRounds: 2,\n maxParallelEdits: 4,\n minEffectiveScore: 0.65,\n constrainedDecoding: false,\n preferredInference: 'llama.cpp',\n inferenceIsolation: 'embedded',\n kvCacheStrategy: 'stable_prefix',\n securityTier: 'L1',\n },\n resources: { minRamGb: 8, minVramGb: 6, estimatedKvPer1kContext: 4 * 1024 * 1024 },\n provenance: {\n notes: 'Flow@2026.07.3 — Approach B default GGUF when fit allows; Ollama fallback for machines without store',\n },\n },\n {\n packId: `forge@${PACK_CHANNEL}`,\n mode: 'forge',\n displayName: 'Forge',\n promise: 'Strongest deep work that safely fits (migrations, multi-file).',\n primary: {\n backend: 'ollama',\n weightsRef: 'qwen2.5-coder:14b',\n quant: 'q4_k_m',\n license: 'Apache-2.0',\n weightsBytes: estimateModelBytes('qwen2.5-coder:14b').bytes,\n },\n fallback: [\n {\n backend: 'ollama',\n weightsRef: 'qwen2.5-coder:7b',\n quant: 'q4_k_m',\n license: 'Apache-2.0',\n weightsBytes: estimateModelBytes('qwen2.5-coder:7b').bytes,\n },\n ],\n contract: {\n toolCalling: 'native',\n editFormat: 'patch_ir_json',\n capsuleBudgetTokens: 6000,\n maxRepairRounds: 3,\n maxParallelEdits: 6,\n minEffectiveScore: 0.7,\n constrainedDecoding: false,\n preferredInference: 'ollama',\n kvCacheStrategy: 'stable_prefix',\n securityTier: 'L1',\n },\n resources: { minRamGb: 16, minVramGb: 12, estimatedKvPer1kContext: 8 * 1024 * 1024 },\n provenance: { notes: 'Forge@2026.07.2 — deep work; PatchIR-oriented edits without forced grammar yet' },\n },\n];\n\nconst GiB = 1024 ** 3;\n\n/**\n * Static reserves applied on top of *available* RAM.\n *\n * Important: `freeRamBytes` is already residual after currently-running\n * processes (IDE, OS, browsers, …). Subtracting a full IDE/OS footprint again\n * double-counts and falsely zeros fit on healthy machines. Keep growth\n * headroom for graph/tests (often not yet resident) + safety, and a modest\n * fraction of IDE/OS for workspace growth under load.\n */\nconst DEFAULT_RESERVES = {\n ideBytes: 1.5 * GiB,\n osBytes: 2 * GiB,\n graphBytes: 0.5 * GiB,\n testsBytes: 0.25 * GiB,\n safetyMarginBytes: 1 * GiB,\n};\n\n/** Fraction of IDE+OS reserves kept as growth headroom on the free-RAM path. */\nconst IDE_OS_GROWTH_FRACTION = 0.25;\n\n// ── Pack lookup ───────────────────────────────────────────────────────────────\n\nexport function packForMode(mode: ModelMode, packs: QualifiedPack[] = QUALIFIED_PACKS): QualifiedPack | null {\n return packs.find((p) => p.mode === mode) ?? null;\n}\n\nexport function packById(packId: string, packs: QualifiedPack[] = QUALIFIED_PACKS): QualifiedPack | null {\n return packs.find((p) => p.packId === packId) ?? null;\n}\n\nexport function listModes(): ModelMode[] {\n return ['spark', 'flow', 'forge'];\n}\n\n// ── Fit algorithm ─────────────────────────────────────────────────────────────\n\n/**\n * Fit decision: available memory *now* after IDE/OS/graph/tests reserves and\n * safety margin — not only “weights fit in total RAM”.\n *\n * Target: < 100 ms once system snapshot is warm (pure arithmetic).\n */\nexport function fitPack(input: FitInput): FitResult {\n const r = { ...DEFAULT_RESERVES, ...input.reserves };\n const pack = input.pack;\n const weightsBytes =\n pack.primary.weightsBytes ??\n estimateModelBytes(pack.primary.weightsRef).bytes;\n const ctxTokens = input.contextBudgetTokens ?? pack.contract.capsuleBudgetTokens * 2;\n const kvPer1k = pack.resources.estimatedKvPer1kContext ?? 2 * 1024 * 1024;\n const kvBytes = Math.round((ctxTokens / 1000) * kvPer1k);\n const modelBytes = weightsBytes;\n const needBytes = modelBytes + kvBytes;\n\n const useVram =\n typeof input.system.vramTotalBytes === 'number' && input.system.vramTotalBytes > 0;\n const freeNow = useVram\n ? (input.system.vramFreeBytes ?? 0)\n : input.system.freeRamBytes;\n const loadedBytes = input.system.loaded.reduce((n, m) => n + m.bytes, 0);\n // Prefer free-after-unload for fit of *next* load when something is resident.\n const freePool = freeNow + loadedBytes;\n\n const graphBump =\n (input.repo?.graphNodeCount ?? 0) > 50_000\n ? 0.5 * GiB\n : (input.repo?.fileCount ?? 0) > 5_000\n ? 0.25 * GiB\n : 0;\n const graphBytes = r.graphBytes + graphBump;\n\n // On discrete VRAM, only model+KV compete for VRAM — host reserves stay on RAM.\n // On unified / CPU path: free/available RAM already excludes current IDE/OS\n // usage, so only charge growth (graph/tests/safety + modest IDE/OS headroom).\n const reserved = useVram\n ? r.safetyMarginBytes\n : graphBytes +\n r.testsBytes +\n r.safetyMarginBytes +\n IDE_OS_GROWTH_FRACTION * (r.ideBytes + r.osBytes);\n const freeAfterReserves = Math.max(0, freePool - reserved);\n\n const availableBytes = freeAfterReserves;\n const reasons: string[] = [];\n const headroom = availableBytes - needBytes;\n const ratio = needBytes > 0 ? availableBytes / needBytes : 0;\n\n let label: FitLabel;\n let reducedCapsuleBudgetTokens: number | undefined;\n\n if (availableBytes < needBytes * 0.85) {\n label = 'will_not_fit';\n reasons.push(\n `needs ~${fmtGb(needBytes)} but only ~${fmtGb(availableBytes)} is free after reserves`,\n );\n } else if (ratio < 1.1 || headroom < 0.5 * GiB) {\n label = 'tight';\n reducedCapsuleBudgetTokens = Math.max(\n 1200,\n Math.floor(pack.contract.capsuleBudgetTokens * 0.65),\n );\n reasons.push('tight fit — capsule budget will be reduced automatically');\n } else if (ratio >= 1.6 && headroom >= 2 * GiB) {\n label = 'flies';\n reasons.push('comfortable headroom for this mode');\n } else {\n label = 'comfortable';\n reasons.push('within policy for this machine');\n }\n\n // Large monorepo + forge → soft-downgrade score (does not force will_not_fit).\n if (\n pack.mode === 'forge' &&\n ((input.repo?.fileCount ?? 0) > 10_000 || (input.repo?.graphNodeCount ?? 0) > 100_000) &&\n label === 'comfortable'\n ) {\n reasons.push('large repository — prefer moderated capsule + graph paging');\n }\n\n // Score: map ratio into 0–100 with floors for labels.\n let score = Math.max(0, Math.min(100, Math.round(ratio * 50)));\n if (label === 'will_not_fit') score = Math.min(score, 20);\n if (label === 'tight') score = Math.min(Math.max(score, 25), 45);\n if (label === 'comfortable') score = Math.min(Math.max(score, 50), 75);\n if (label === 'flies') score = Math.max(score, 80);\n\n return {\n label,\n score,\n needBytes,\n availableBytes,\n breakdown: {\n modelBytes,\n kvBytes,\n // Report the charged growth headroom (not the full static IDE/OS footprint).\n ideBytes: useVram ? 0 : IDE_OS_GROWTH_FRACTION * r.ideBytes,\n osBytes: useVram ? 0 : IDE_OS_GROWTH_FRACTION * r.osBytes,\n graphBytes: useVram ? 0 : graphBytes,\n testsBytes: useVram ? 0 : r.testsBytes,\n freeAfterReservesBytes: freeAfterReserves,\n },\n reducedCapsuleBudgetTokens,\n reasons,\n };\n}\n\nfunction fmtGb(bytes: number): string {\n return `${(bytes / GiB).toFixed(1)} GiB`;\n}\n\n// ── Resolve mode → pack → underlying ──────────────────────────────────────────\n\nexport interface ResolveModeOptions {\n mode?: ModelMode;\n /** Prefer auto-fit when no mode set (default true for first-run wizard). */\n autoFit?: boolean;\n system: SystemMemory;\n repo?: RepoSignals;\n taskClass?: TaskClass;\n /** Installed model names (ollama/lmstudio) for installed: true. */\n installedNames?: string[];\n /** Pin map mode → packId. */\n pin?: { mode: ModelMode; packId: string } | null;\n packs?: QualifiedPack[];\n defaultMode?: ModelMode;\n}\n\nfunction packToProfile(pack: QualifiedPack, underlying: PackWeightsRef, fit: FitResult): ModelExecutionProfile {\n const budget =\n fit.label === 'tight' && fit.reducedCapsuleBudgetTokens\n ? fit.reducedCapsuleBudgetTokens\n : pack.contract.capsuleBudgetTokens;\n return {\n schemaVersion: MODEL_EXECUTION_PROFILE_SCHEMA_VERSION,\n id: underlying.weightsRef,\n displayName: `${pack.displayName} · ${underlying.weightsRef}`,\n mode: pack.mode,\n backend:\n underlying.backend === 'ollama'\n ? 'ollama'\n : underlying.backend === 'llama.cpp'\n ? 'llama.cpp'\n : underlying.backend === 'lm-studio'\n ? 'openai-compatible'\n : 'other',\n toolCalling: pack.contract.toolCalling,\n editFormat: pack.contract.editFormat,\n capsuleBudgetTokens: budget,\n maxParallelEdits: pack.contract.maxParallelEdits,\n maxRepairRounds: pack.contract.maxRepairRounds,\n temperature: 0,\n constrainedDecoding: pack.contract.constrainedDecoding ?? false,\n kvCacheStrategy: pack.contract.kvCacheStrategy,\n resources: {\n minRamGb: pack.resources.minRamGb,\n minVramGb: pack.resources.minVramGb,\n quant: underlying.quant,\n },\n securityTier: pack.contract.securityTier,\n inferenceIsolation: pack.contract.inferenceIsolation ?? 'embedded',\n };\n}\n\nfunction tryWeights(\n pack: QualifiedPack,\n weights: PackWeightsRef,\n system: SystemMemory,\n repo?: RepoSignals,\n taskClass?: TaskClass,\n): { fit: FitResult; underlying: PackWeightsRef } {\n const trial: QualifiedPack = { ...pack, primary: weights };\n return { fit: fitPack({ system, pack: trial, repo, taskClass }), underlying: weights };\n}\n\n/**\n * Resolve a Code Mode to a pack, concrete weights, fit label, and MEP.\n * Refuses primary load when fit is will_not_fit and tries fallbacks; if all\n * fail, returns the best effort with label will_not_fit (caller must not load).\n */\nexport function resolveMode(opts: ResolveModeOptions): ResolvedMode {\n const packs = opts.packs ?? QUALIFIED_PACKS;\n const defaultMode = opts.defaultMode ?? 'flow';\n let mode: ModelMode = opts.mode ?? defaultMode;\n let selection: ResolvedMode['selection'] = opts.mode ? 'explicit' : 'default';\n\n if (!opts.mode && opts.autoFit !== false) {\n mode = recommendMode(opts.system, opts.repo, packs);\n selection = 'auto_fit';\n }\n\n let pack = packForMode(mode, packs);\n if (!pack) {\n pack = packForMode('flow', packs)!;\n mode = 'flow';\n selection = 'default';\n }\n\n if (opts.pin && opts.pin.mode === mode) {\n const pinned = packById(opts.pin.packId, packs);\n if (pinned && pinned.mode === mode) {\n pack = pinned;\n selection = 'pinned';\n }\n }\n\n const candidates = [pack.primary, ...(pack.fallback ?? [])];\n let best: { fit: FitResult; underlying: PackWeightsRef } | null = null;\n\n for (const w of candidates) {\n const trial = tryWeights(pack, w, opts.system, opts.repo, opts.taskClass);\n if (!best || fitRank(trial.fit) > fitRank(best.fit)) best = trial;\n if (trial.fit.label === 'flies' || trial.fit.label === 'comfortable') {\n best = trial;\n break;\n }\n }\n\n const chosen = best ?? tryWeights(pack, pack.primary, opts.system, opts.repo, opts.taskClass);\n const profile = packToProfile(pack, chosen.underlying, chosen.fit);\n\n return {\n schemaVersion: MODEL_ORCHESTRATOR_SCHEMA_VERSION,\n mode,\n pack,\n underlying: chosen.underlying,\n fit: chosen.fit,\n profile,\n pinned: selection === 'pinned',\n selection,\n };\n}\n\nfunction fitRank(f: FitResult): number {\n const order: Record<FitLabel, number> = {\n flies: 4,\n comfortable: 3,\n tight: 2,\n will_not_fit: 1,\n };\n return order[f.label] * 1000 + f.score;\n}\n\n/**\n * Pick the strongest mode that still fits at least “comfortable” (or tight\n * for spark). Prefer Flow when both Flow and Forge are comfortable.\n */\nexport function recommendMode(\n system: SystemMemory,\n repo?: RepoSignals,\n packs: QualifiedPack[] = QUALIFIED_PACKS,\n): ModelMode {\n const order: ModelMode[] = ['forge', 'flow', 'spark'];\n let bestTight: ModelMode | null = null;\n for (const mode of order) {\n const pack = packForMode(mode, packs);\n if (!pack) continue;\n const resolved = resolveMode({\n mode,\n autoFit: false,\n system,\n repo,\n packs,\n });\n if (resolved.fit.label === 'flies' || resolved.fit.label === 'comfortable') {\n // Prefer Flow as daily default when Forge also fits, unless repo is tiny.\n if (mode === 'forge') {\n const flow = resolveMode({ mode: 'flow', autoFit: false, system, repo, packs });\n if (flow.fit.label === 'flies' || flow.fit.label === 'comfortable') {\n const files = repo?.fileCount ?? 0;\n if (files < 2000) return 'flow';\n }\n return 'forge';\n }\n return mode;\n }\n if (resolved.fit.label === 'tight' && !bestTight) bestTight = mode;\n }\n return bestTight ?? 'spark';\n}\n\n/** Build orchestrator status for `vg models status` / host UIs. */\nexport function buildOrchestratorStatus(opts: {\n system: SystemMemory;\n repo?: RepoSignals;\n installedNames?: string[];\n /** Single pin (legacy) or full pin map. */\n pin?: { mode: ModelMode; packId: string } | null;\n pins?: Partial<Record<ModelMode, string>>;\n defaultMode?: ModelMode;\n packs?: QualifiedPack[];\n}): OrchestratorStatus {\n const packs = opts.packs ?? QUALIFIED_PACKS;\n const installed = new Set((opts.installedNames ?? []).map((n) => n.toLowerCase()));\n const recommended = recommendMode(opts.system, opts.repo, packs);\n const pinFor = (mode: ModelMode): { mode: ModelMode; packId: string } | null => {\n const fromMap = opts.pins?.[mode];\n if (fromMap) return { mode, packId: fromMap };\n if (opts.pin?.mode === mode) return opts.pin;\n return null;\n };\n const modes = listModes().map((mode) => {\n const resolved = resolveMode({\n mode,\n autoFit: false,\n system: opts.system,\n repo: opts.repo,\n pin: pinFor(mode),\n packs,\n });\n const id = resolved.underlying.weightsRef.toLowerCase();\n const installedHit =\n installed.has(id) ||\n [...installed].some((n) => n.includes(id) || id.includes(n));\n return {\n mode,\n packId: resolved.pack.packId,\n displayName: resolved.pack.displayName,\n promise: resolved.pack.promise,\n underlyingModelId: resolved.underlying.weightsRef,\n backend: resolved.underlying.backend,\n fit: resolved.fit.label,\n fitScore: resolved.fit.score,\n needBytes: resolved.fit.needBytes,\n availableBytes: resolved.fit.availableBytes,\n installed: installedHit,\n pinned: resolved.pinned,\n };\n });\n\n const recResolved = resolveMode({\n mode: recommended,\n autoFit: false,\n system: opts.system,\n repo: opts.repo,\n pin: pinFor(recommended),\n packs,\n });\n\n return {\n schemaVersion: MODEL_ORCHESTRATOR_SCHEMA_VERSION,\n defaultMode: opts.defaultMode ?? 'flow',\n pin: pinFor(recommended),\n modes,\n recommended,\n system: {\n totalRamBytes: opts.system.totalRamBytes,\n freeRamBytes: opts.system.freeRamBytes,\n ...(typeof opts.system.vramTotalBytes === 'number'\n ? { vramTotalBytes: opts.system.vramTotalBytes }\n : {}),\n ...(typeof opts.system.vramFreeBytes === 'number'\n ? { vramFreeBytes: opts.system.vramFreeBytes }\n : {}),\n loaded: opts.system.loaded.map((l) => ({ name: l.name, bytes: l.bytes })),\n },\n memoryBreakdown: recResolved.fit.breakdown,\n };\n}\n\n// ── Pin registry (global storage, not in-repo) ────────────────────────────────\n\nexport interface OrchestratorPinState {\n schemaVersion: 'model-orchestrator-pin/0';\n /** mode → packId */\n pins: Partial<Record<ModelMode, string>>;\n /** Workspace / global default mode preference. */\n defaultMode?: ModelMode;\n updatedAt: string;\n}\n\nexport function orchestratorStatePath(\n env: NodeJS.ProcessEnv = process.env,\n platform: NodeJS.Platform = process.platform,\n home?: string,\n): string {\n return path.join(vibgrateDataDir(env, platform, home), 'model-orchestrator', 'state.json');\n}\n\nexport function readOrchestratorState(\n env: NodeJS.ProcessEnv = process.env,\n platform: NodeJS.Platform = process.platform,\n home?: string,\n): OrchestratorPinState {\n const p = orchestratorStatePath(env, platform, home);\n try {\n const raw = JSON.parse(fs.readFileSync(p, 'utf8')) as Partial<OrchestratorPinState>;\n return {\n schemaVersion: 'model-orchestrator-pin/0',\n pins: raw.pins && typeof raw.pins === 'object' ? raw.pins : {},\n defaultMode:\n raw.defaultMode === 'spark' || raw.defaultMode === 'flow' || raw.defaultMode === 'forge'\n ? raw.defaultMode\n : undefined,\n updatedAt: typeof raw.updatedAt === 'string' ? raw.updatedAt : new Date(0).toISOString(),\n };\n } catch {\n return {\n schemaVersion: 'model-orchestrator-pin/0',\n pins: {},\n updatedAt: new Date(0).toISOString(),\n };\n }\n}\n\nexport function writeOrchestratorState(\n state: OrchestratorPinState,\n env: NodeJS.ProcessEnv = process.env,\n platform: NodeJS.Platform = process.platform,\n home?: string,\n): string {\n const p = orchestratorStatePath(env, platform, home);\n fs.mkdirSync(path.dirname(p), { recursive: true });\n const next: OrchestratorPinState = {\n ...state,\n schemaVersion: 'model-orchestrator-pin/0',\n updatedAt: new Date().toISOString(),\n };\n fs.writeFileSync(p, JSON.stringify(next, null, 2) + '\\n', 'utf8');\n return p;\n}\n\nexport function pinPack(\n mode: ModelMode,\n packId: string,\n env?: NodeJS.ProcessEnv,\n platform?: NodeJS.Platform,\n home?: string,\n): OrchestratorPinState {\n const state = readOrchestratorState(env, platform, home);\n if (!packById(packId)) {\n throw new Error(`unknown pack id: ${packId}`);\n }\n state.pins[mode] = packId;\n writeOrchestratorState(state, env, platform, home);\n return state;\n}\n\nexport function unpinPack(\n mode: ModelMode,\n env?: NodeJS.ProcessEnv,\n platform?: NodeJS.Platform,\n home?: string,\n): OrchestratorPinState {\n const state = readOrchestratorState(env, platform, home);\n delete state.pins[mode];\n writeOrchestratorState(state, env, platform, home);\n return state;\n}\n\nexport function setDefaultMode(\n mode: ModelMode,\n env?: NodeJS.ProcessEnv,\n platform?: NodeJS.Platform,\n home?: string,\n): OrchestratorPinState {\n const state = readOrchestratorState(env, platform, home);\n state.defaultMode = mode;\n writeOrchestratorState(state, env, platform, home);\n return state;\n}\n\n/** Active pin for a mode, if any. */\nexport function activePin(\n mode: ModelMode,\n state: OrchestratorPinState = readOrchestratorState(),\n): { mode: ModelMode; packId: string } | null {\n const packId = state.pins[mode];\n return packId ? { mode, packId } : null;\n}\n\n/** Map backend hint to vg code --provider id. */\nexport function providerForBackend(backend: PackWeightsRef['backend']): string {\n switch (backend) {\n case 'ollama':\n return 'ollama';\n case 'llama.cpp':\n return 'llama-cpp';\n case 'lm-studio':\n return 'lmstudio';\n default:\n return 'ollama';\n }\n}\n\n/** Parse mode from user string; null if invalid. */\nexport function parseMode(raw: string | undefined | null): ModelMode | null {\n if (!raw) return null;\n const m = raw.trim().toLowerCase();\n if (m === 'spark' || m === 'flow' || m === 'forge') return m;\n return null;\n}\n"]}
|