open-agents-ai 0.103.99 → 0.104.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/dist/index.js +233 -76
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -30893,6 +30893,7 @@ ${activitySummary}
|
|
|
30893
30893
|
});
|
|
30894
30894
|
|
|
30895
30895
|
// packages/cli/dist/tui/model-picker.js
|
|
30896
|
+
import { totalmem as totalmem2 } from "node:os";
|
|
30896
30897
|
async function fetchOllamaModels(baseUrl) {
|
|
30897
30898
|
const url = `${normalizeBaseUrl(baseUrl)}/api/tags`;
|
|
30898
30899
|
const resp = await fetch(url, {
|
|
@@ -30932,10 +30933,22 @@ async function fetchOllamaModels(baseUrl) {
|
|
|
30932
30933
|
}
|
|
30933
30934
|
}
|
|
30934
30935
|
if (show.model_info) {
|
|
30935
|
-
|
|
30936
|
-
|
|
30937
|
-
|
|
30938
|
-
|
|
30936
|
+
const info = show.model_info;
|
|
30937
|
+
const arch = info["general.architecture"];
|
|
30938
|
+
const paramCount = info["general.parameter_count"];
|
|
30939
|
+
const fileSizeGB = result[i].sizeBytes > 0 ? result[i].sizeBytes / 1024 ** 3 : paramCount ? paramCount * 0.6 / 1024 ** 3 : 4;
|
|
30940
|
+
if (arch) {
|
|
30941
|
+
const archMax = info[`${arch}.context_length`];
|
|
30942
|
+
const nLayers = info[`${arch}.block_count`];
|
|
30943
|
+
const nKVHeads = info[`${arch}.attention.head_count_kv`] ?? info[`${arch}.attention.head_count`];
|
|
30944
|
+
const keyDim = info[`${arch}.attention.key_length`];
|
|
30945
|
+
const valDim = info[`${arch}.attention.value_length`] ?? keyDim;
|
|
30946
|
+
if (archMax && nLayers && nKVHeads && keyDim && valDim) {
|
|
30947
|
+
const kvBytesPerToken = nLayers * nKVHeads * (keyDim + valDim) * 2;
|
|
30948
|
+
result[i].contextLength = estimateRealisticContext(kvBytesPerToken, archMax, fileSizeGB);
|
|
30949
|
+
} else if (archMax) {
|
|
30950
|
+
const kvEstimate = fileSizeGB <= 5 ? 524288 : fileSizeGB <= 20 ? 1048576 : 1572864;
|
|
30951
|
+
result[i].contextLength = estimateRealisticContext(kvEstimate, archMax, fileSizeGB);
|
|
30939
30952
|
}
|
|
30940
30953
|
}
|
|
30941
30954
|
}
|
|
@@ -31231,9 +31244,23 @@ async function queryModelContextSize(baseUrl, modelName) {
|
|
|
31231
31244
|
return parseInt(match[1], 10);
|
|
31232
31245
|
}
|
|
31233
31246
|
if (data.model_info) {
|
|
31234
|
-
|
|
31235
|
-
|
|
31236
|
-
|
|
31247
|
+
const info = data.model_info;
|
|
31248
|
+
const arch = info["general.architecture"];
|
|
31249
|
+
const paramCount = info["general.parameter_count"];
|
|
31250
|
+
const modelSizeGB2 = paramCount ? paramCount * 0.6 / 1024 ** 3 : 4;
|
|
31251
|
+
if (arch) {
|
|
31252
|
+
const archMax = info[`${arch}.context_length`];
|
|
31253
|
+
const nLayers = info[`${arch}.block_count`];
|
|
31254
|
+
const nKVHeads = info[`${arch}.attention.head_count_kv`] ?? info[`${arch}.attention.head_count`];
|
|
31255
|
+
const keyDim = info[`${arch}.attention.key_length`];
|
|
31256
|
+
const valDim = info[`${arch}.attention.value_length`] ?? keyDim;
|
|
31257
|
+
if (archMax && nLayers && nKVHeads && keyDim && valDim) {
|
|
31258
|
+
const kvBytesPerToken = nLayers * nKVHeads * (keyDim + valDim) * 2;
|
|
31259
|
+
return estimateRealisticContext(kvBytesPerToken, archMax, modelSizeGB2);
|
|
31260
|
+
}
|
|
31261
|
+
if (archMax) {
|
|
31262
|
+
const kvEstimate = modelSizeGB2 <= 5 ? 524288 : modelSizeGB2 <= 20 ? 1048576 : 1572864;
|
|
31263
|
+
return estimateRealisticContext(kvEstimate, archMax, modelSizeGB2);
|
|
31237
31264
|
}
|
|
31238
31265
|
}
|
|
31239
31266
|
}
|
|
@@ -31242,10 +31269,25 @@ async function queryModelContextSize(baseUrl, modelName) {
|
|
|
31242
31269
|
return null;
|
|
31243
31270
|
}
|
|
31244
31271
|
}
|
|
31272
|
+
function estimateRealisticContext(kvBytesPerToken, archMax, modelSizeGB2) {
|
|
31273
|
+
const totalMemGB = totalmem2() / 1024 ** 3;
|
|
31274
|
+
const usableBytes = totalMemGB * 0.7 * 1024 ** 3;
|
|
31275
|
+
const maxTokens = Math.floor(usableBytes / kvBytesPerToken);
|
|
31276
|
+
let numCtx = Math.max(2048, Math.floor(maxTokens / 1024) * 1024);
|
|
31277
|
+
numCtx = Math.min(numCtx, 131072, archMax);
|
|
31278
|
+
if (modelSizeGB2 && modelSizeGB2 > 0) {
|
|
31279
|
+
const maxKVBytes = modelSizeGB2 * 4 * 1024 ** 3;
|
|
31280
|
+
const budgetCap = Math.max(2048, Math.floor(maxKVBytes / kvBytesPerToken / 1024) * 1024);
|
|
31281
|
+
numCtx = Math.min(numCtx, budgetCap);
|
|
31282
|
+
}
|
|
31283
|
+
return numCtx;
|
|
31284
|
+
}
|
|
31245
31285
|
async function queryOpenAIContextSize(baseUrl, modelName, apiKey) {
|
|
31246
31286
|
try {
|
|
31247
31287
|
const models = await fetchOpenAIModels(baseUrl, apiKey);
|
|
31248
31288
|
const model = models.find((m) => m.name === modelName);
|
|
31289
|
+
if (model?.contextLength)
|
|
31290
|
+
return model.contextLength;
|
|
31249
31291
|
if (model?.size) {
|
|
31250
31292
|
const match = model.size.match(/(\d+)K ctx/);
|
|
31251
31293
|
if (match)
|
|
@@ -32155,20 +32197,30 @@ function recommendModel(specs) {
|
|
|
32155
32197
|
}
|
|
32156
32198
|
return QWEN_VARIANTS.find((v) => v.tag === "qwen3.5:cloud");
|
|
32157
32199
|
}
|
|
32158
|
-
function calculateContextWindow(specs, modelSizeGB2) {
|
|
32200
|
+
function calculateContextWindow(specs, modelSizeGB2, kvBytesPerToken, archMax) {
|
|
32159
32201
|
const totalAvail = Math.max(specs.gpuVramGB, specs.totalRamGB);
|
|
32160
|
-
const remaining = totalAvail - modelSizeGB2;
|
|
32161
|
-
|
|
32162
|
-
|
|
32163
|
-
if (
|
|
32164
|
-
|
|
32165
|
-
|
|
32166
|
-
|
|
32167
|
-
|
|
32168
|
-
|
|
32169
|
-
|
|
32170
|
-
|
|
32171
|
-
|
|
32202
|
+
const remaining = Math.max(0, totalAvail - modelSizeGB2);
|
|
32203
|
+
const usableGB = remaining * 0.85;
|
|
32204
|
+
let numCtx;
|
|
32205
|
+
if (kvBytesPerToken && kvBytesPerToken > 0) {
|
|
32206
|
+
const maxTokens = Math.floor(usableGB * 1024 ** 3 / kvBytesPerToken);
|
|
32207
|
+
numCtx = Math.max(2048, Math.floor(maxTokens / 1024) * 1024);
|
|
32208
|
+
} else {
|
|
32209
|
+
const kvEstimate = modelSizeGB2 <= 5 ? 524288 : modelSizeGB2 <= 20 ? 1048576 : 1572864;
|
|
32210
|
+
const maxTokens = Math.floor(usableGB * 1024 ** 3 / kvEstimate);
|
|
32211
|
+
numCtx = Math.max(2048, Math.floor(maxTokens / 1024) * 1024);
|
|
32212
|
+
}
|
|
32213
|
+
numCtx = Math.min(numCtx, 131072);
|
|
32214
|
+
if (archMax && archMax > 0)
|
|
32215
|
+
numCtx = Math.min(numCtx, archMax);
|
|
32216
|
+
if (kvBytesPerToken && kvBytesPerToken > 0 && modelSizeGB2 > 0) {
|
|
32217
|
+
const maxKVBytes = modelSizeGB2 * 4 * 1024 ** 3;
|
|
32218
|
+
const maxTokensFromBudget = Math.floor(maxKVBytes / kvBytesPerToken);
|
|
32219
|
+
const budgetCap = Math.max(2048, Math.floor(maxTokensFromBudget / 1024) * 1024);
|
|
32220
|
+
numCtx = Math.min(numCtx, budgetCap);
|
|
32221
|
+
}
|
|
32222
|
+
const label = numCtx >= 1024 ? `${Math.floor(numCtx / 1024)}K` : String(numCtx);
|
|
32223
|
+
return { numCtx, label };
|
|
32172
32224
|
}
|
|
32173
32225
|
function modelSupportsToolCalling(modelName) {
|
|
32174
32226
|
const lower = modelName.toLowerCase();
|
|
@@ -33512,9 +33564,40 @@ function modelSizeGB(models, modelName) {
|
|
|
33512
33564
|
const known = QWEN_VARIANTS.find((v) => modelName.includes(v.tag.split(":")[1] ?? ""));
|
|
33513
33565
|
return known?.sizeGB ?? 4;
|
|
33514
33566
|
}
|
|
33515
|
-
async function
|
|
33567
|
+
async function queryModelKVInfo(backendUrl, modelName) {
|
|
33568
|
+
try {
|
|
33569
|
+
const normalized = backendUrl.replace(/\/+$/, "");
|
|
33570
|
+
const res = await fetch(`${normalized}/api/show`, {
|
|
33571
|
+
method: "POST",
|
|
33572
|
+
headers: { "Content-Type": "application/json" },
|
|
33573
|
+
body: JSON.stringify({ name: modelName }),
|
|
33574
|
+
signal: AbortSignal.timeout(5e3)
|
|
33575
|
+
});
|
|
33576
|
+
if (!res.ok)
|
|
33577
|
+
return null;
|
|
33578
|
+
const data = await res.json();
|
|
33579
|
+
if (!data.model_info)
|
|
33580
|
+
return null;
|
|
33581
|
+
const info = data.model_info;
|
|
33582
|
+
const arch = info["general.architecture"];
|
|
33583
|
+
if (!arch)
|
|
33584
|
+
return null;
|
|
33585
|
+
const nLayers = info[`${arch}.block_count`];
|
|
33586
|
+
const nKVHeads = info[`${arch}.attention.head_count_kv`] ?? info[`${arch}.attention.head_count`];
|
|
33587
|
+
const keyDim = info[`${arch}.attention.key_length`];
|
|
33588
|
+
const valDim = info[`${arch}.attention.value_length`] ?? keyDim;
|
|
33589
|
+
const archMax = info[`${arch}.context_length`];
|
|
33590
|
+
if (!nLayers || !nKVHeads || !keyDim || !valDim || !archMax)
|
|
33591
|
+
return null;
|
|
33592
|
+
const kvBytesPerToken = nLayers * nKVHeads * (keyDim + valDim) * 2;
|
|
33593
|
+
return { kvBytesPerToken, archMax };
|
|
33594
|
+
} catch {
|
|
33595
|
+
return null;
|
|
33596
|
+
}
|
|
33597
|
+
}
|
|
33598
|
+
async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerToken, archMax) {
|
|
33516
33599
|
const customName = expandedModelName(baseModel);
|
|
33517
|
-
const ctx = calculateContextWindow(specs, sizeGB);
|
|
33600
|
+
const ctx = calculateContextWindow(specs, sizeGB, kvBytesPerToken, archMax);
|
|
33518
33601
|
try {
|
|
33519
33602
|
const numPredict = Math.min(16384, Math.max(2048, Math.floor(ctx.numCtx * 0.25)));
|
|
33520
33603
|
const modelfileContent = [
|
|
@@ -33537,37 +33620,51 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB) {
|
|
|
33537
33620
|
}
|
|
33538
33621
|
}
|
|
33539
33622
|
async function ensureExpandedContext(modelName, backendUrl) {
|
|
33540
|
-
if (modelName.startsWith("open-agents-")) {
|
|
33541
|
-
const specs2 = await detectSystemSpecsAsync();
|
|
33542
|
-
const ctx2 = calculateContextWindow(specs2, 4);
|
|
33543
|
-
return { model: modelName, created: false, contextLabel: ctx2.label, numCtx: ctx2.numCtx };
|
|
33544
|
-
}
|
|
33545
33623
|
if (modelName.includes("cloud") || modelName.includes(":cloud")) {
|
|
33546
33624
|
return { model: modelName, created: false, contextLabel: "remote", numCtx: 0 };
|
|
33547
33625
|
}
|
|
33548
|
-
const existing = await checkExpandedVariant(modelName, backendUrl);
|
|
33549
|
-
if (existing === null) {
|
|
33550
|
-
return { model: modelName, created: false, contextLabel: "", numCtx: 0 };
|
|
33551
|
-
}
|
|
33552
33626
|
const specs = await detectSystemSpecsAsync();
|
|
33553
|
-
|
|
33554
|
-
let sizeGB2 = 4;
|
|
33555
|
-
try {
|
|
33556
|
-
const models = await fetchOllamaModels(backendUrl);
|
|
33557
|
-
sizeGB2 = modelSizeGB(models, modelName);
|
|
33558
|
-
} catch {
|
|
33559
|
-
}
|
|
33560
|
-
const ctx2 = calculateContextWindow(specs, sizeGB2);
|
|
33561
|
-
return { model: existing, created: false, contextLabel: ctx2.label, numCtx: ctx2.numCtx };
|
|
33562
|
-
}
|
|
33627
|
+
const kvInfo = await queryModelKVInfo(backendUrl, modelName);
|
|
33563
33628
|
let sizeGB = 4;
|
|
33564
33629
|
try {
|
|
33565
33630
|
const models = await fetchOllamaModels(backendUrl);
|
|
33566
33631
|
sizeGB = modelSizeGB(models, modelName);
|
|
33567
33632
|
} catch {
|
|
33568
33633
|
}
|
|
33569
|
-
const ctx = calculateContextWindow(specs, sizeGB);
|
|
33570
|
-
|
|
33634
|
+
const ctx = calculateContextWindow(specs, sizeGB, kvInfo?.kvBytesPerToken, kvInfo?.archMax);
|
|
33635
|
+
if (modelName.startsWith("open-agents-")) {
|
|
33636
|
+
try {
|
|
33637
|
+
const normalized = backendUrl.replace(/\/+$/, "");
|
|
33638
|
+
const showRes = await fetch(`${normalized}/api/show`, {
|
|
33639
|
+
method: "POST",
|
|
33640
|
+
headers: { "Content-Type": "application/json" },
|
|
33641
|
+
body: JSON.stringify({ name: modelName }),
|
|
33642
|
+
signal: AbortSignal.timeout(5e3)
|
|
33643
|
+
});
|
|
33644
|
+
if (showRes.ok) {
|
|
33645
|
+
const showData = await showRes.json();
|
|
33646
|
+
const numCtxMatch = showData.parameters?.match(/num_ctx\s+(\d+)/);
|
|
33647
|
+
const currentNumCtx = numCtxMatch ? parseInt(numCtxMatch[1], 10) : 0;
|
|
33648
|
+
if (currentNumCtx !== ctx.numCtx) {
|
|
33649
|
+
const fromMatch = showData.modelfile?.match(/^FROM\s+(.+)$/m);
|
|
33650
|
+
const baseModel = fromMatch?.[1]?.trim();
|
|
33651
|
+
if (baseModel && !baseModel.startsWith("open-agents-")) {
|
|
33652
|
+
await createExpandedVariantAsync(baseModel, specs, sizeGB, kvInfo?.kvBytesPerToken, kvInfo?.archMax);
|
|
33653
|
+
}
|
|
33654
|
+
}
|
|
33655
|
+
}
|
|
33656
|
+
} catch {
|
|
33657
|
+
}
|
|
33658
|
+
return { model: modelName, created: false, contextLabel: ctx.label, numCtx: ctx.numCtx };
|
|
33659
|
+
}
|
|
33660
|
+
const existing = await checkExpandedVariant(modelName, backendUrl);
|
|
33661
|
+
if (existing === null) {
|
|
33662
|
+
return { model: modelName, created: false, contextLabel: "", numCtx: 0 };
|
|
33663
|
+
}
|
|
33664
|
+
if (typeof existing === "string") {
|
|
33665
|
+
return { model: existing, created: false, contextLabel: ctx.label, numCtx: ctx.numCtx };
|
|
33666
|
+
}
|
|
33667
|
+
const created = await createExpandedVariantAsync(modelName, specs, sizeGB, kvInfo?.kvBytesPerToken, kvInfo?.archMax);
|
|
33571
33668
|
if (created) {
|
|
33572
33669
|
return { model: created, created: true, contextLabel: ctx.label, numCtx: ctx.numCtx };
|
|
33573
33670
|
}
|
|
@@ -33610,6 +33707,45 @@ var init_setup = __esm({
|
|
|
33610
33707
|
}
|
|
33611
33708
|
});
|
|
33612
33709
|
|
|
33710
|
+
// packages/cli/dist/tui/overlay-lock.js
|
|
33711
|
+
function isOverlayActive() {
|
|
33712
|
+
return _overlayActive;
|
|
33713
|
+
}
|
|
33714
|
+
function bufferIfOverlay(stream, data) {
|
|
33715
|
+
if (!_overlayActive)
|
|
33716
|
+
return false;
|
|
33717
|
+
_buffer.push({ stream, data });
|
|
33718
|
+
return true;
|
|
33719
|
+
}
|
|
33720
|
+
function enterOverlay() {
|
|
33721
|
+
_depth++;
|
|
33722
|
+
_overlayActive = true;
|
|
33723
|
+
}
|
|
33724
|
+
function leaveOverlay() {
|
|
33725
|
+
_depth = Math.max(0, _depth - 1);
|
|
33726
|
+
if (_depth === 0) {
|
|
33727
|
+
_overlayActive = false;
|
|
33728
|
+
const pending = _buffer;
|
|
33729
|
+
_buffer = [];
|
|
33730
|
+
for (const { stream, data } of pending) {
|
|
33731
|
+
if (stream === "stdout") {
|
|
33732
|
+
process.stdout.write(data);
|
|
33733
|
+
} else {
|
|
33734
|
+
process.stderr.write(data);
|
|
33735
|
+
}
|
|
33736
|
+
}
|
|
33737
|
+
}
|
|
33738
|
+
}
|
|
33739
|
+
var _overlayActive, _depth, _buffer;
|
|
33740
|
+
var init_overlay_lock = __esm({
|
|
33741
|
+
"packages/cli/dist/tui/overlay-lock.js"() {
|
|
33742
|
+
"use strict";
|
|
33743
|
+
_overlayActive = false;
|
|
33744
|
+
_depth = 0;
|
|
33745
|
+
_buffer = [];
|
|
33746
|
+
}
|
|
33747
|
+
});
|
|
33748
|
+
|
|
33613
33749
|
// packages/cli/dist/tui/tui-select.js
|
|
33614
33750
|
function ansi3(code, text) {
|
|
33615
33751
|
return isTTY3 ? `\x1B[${code}m${text}\x1B[0m` : text;
|
|
@@ -33681,7 +33817,7 @@ function tuiSelect(opts) {
|
|
|
33681
33817
|
cursor = first >= 0 ? first : 0;
|
|
33682
33818
|
}
|
|
33683
33819
|
const selectChrome = 3;
|
|
33684
|
-
const contentArea = process.stdout.rows ?? 24;
|
|
33820
|
+
const contentArea = opts.availableRows ?? process.stdout.rows ?? 24;
|
|
33685
33821
|
const maxVisible = opts.maxVisible ?? Math.max(3, contentArea - selectChrome);
|
|
33686
33822
|
let scrollOffset = 0;
|
|
33687
33823
|
let lastRenderedLines = 0;
|
|
@@ -33704,6 +33840,7 @@ function tuiSelect(opts) {
|
|
|
33704
33840
|
}
|
|
33705
33841
|
stdin.resume();
|
|
33706
33842
|
process.stdout.write("\x1B[?1049h\x1B[2J\x1B[H\x1B[?25l");
|
|
33843
|
+
enterOverlay();
|
|
33707
33844
|
function clampScroll(displayList) {
|
|
33708
33845
|
const cursorPos = displayList.indexOf(cursor);
|
|
33709
33846
|
if (cursorPos < 0)
|
|
@@ -33797,6 +33934,7 @@ function tuiSelect(opts) {
|
|
|
33797
33934
|
function cleanup() {
|
|
33798
33935
|
stdin.removeListener("data", onData);
|
|
33799
33936
|
process.stdout.removeListener("resize", onResize);
|
|
33937
|
+
leaveOverlay();
|
|
33800
33938
|
process.stdout.write("\x1B[?1049l\x1B[?25h");
|
|
33801
33939
|
if (typeof stdin.setRawMode === "function") {
|
|
33802
33940
|
stdin.setRawMode(hadRawMode ?? false);
|
|
@@ -34052,6 +34190,7 @@ var isTTY3, selectColors;
|
|
|
34052
34190
|
var init_tui_select = __esm({
|
|
34053
34191
|
"packages/cli/dist/tui/tui-select.js"() {
|
|
34054
34192
|
"use strict";
|
|
34193
|
+
init_overlay_lock();
|
|
34055
34194
|
isTTY3 = process.stdout.isTTY ?? false;
|
|
34056
34195
|
selectColors = {
|
|
34057
34196
|
orange: (t) => fg2562(208, t),
|
|
@@ -34094,6 +34233,7 @@ function showDropPanel(opts) {
|
|
|
34094
34233
|
}
|
|
34095
34234
|
stdin.resume();
|
|
34096
34235
|
process.stdout.write("\x1B[?1049h\x1B[2J\x1B[H\x1B[?25h");
|
|
34236
|
+
enterOverlay();
|
|
34097
34237
|
let inputBuf = "";
|
|
34098
34238
|
let errorMsg = "";
|
|
34099
34239
|
function render() {
|
|
@@ -34137,6 +34277,7 @@ function showDropPanel(opts) {
|
|
|
34137
34277
|
}
|
|
34138
34278
|
function cleanup() {
|
|
34139
34279
|
stdin.removeListener("data", onData);
|
|
34280
|
+
leaveOverlay();
|
|
34140
34281
|
process.stdout.write("\x1B[?1049l\x1B[?25h");
|
|
34141
34282
|
if (typeof stdin.setRawMode === "function") {
|
|
34142
34283
|
stdin.setRawMode(hadRawMode ?? false);
|
|
@@ -34212,6 +34353,7 @@ var isTTY4, dc;
|
|
|
34212
34353
|
var init_drop_panel = __esm({
|
|
34213
34354
|
"packages/cli/dist/tui/drop-panel.js"() {
|
|
34214
34355
|
"use strict";
|
|
34356
|
+
init_overlay_lock();
|
|
34215
34357
|
isTTY4 = process.stdout.isTTY ?? false;
|
|
34216
34358
|
dc = {
|
|
34217
34359
|
bold: (t) => ansi4("1", t),
|
|
@@ -37180,9 +37322,7 @@ async function handleSlashCommand(input, ctx) {
|
|
|
37180
37322
|
return "handled";
|
|
37181
37323
|
}
|
|
37182
37324
|
if (arg === "list" || arg === "ls" || arg === "voices") {
|
|
37183
|
-
ctx.setOverlayActive?.(true);
|
|
37184
37325
|
await handleVoiceList(ctx);
|
|
37185
|
-
ctx.setOverlayActive?.(false);
|
|
37186
37326
|
return "handled";
|
|
37187
37327
|
}
|
|
37188
37328
|
const msg = await ctx.voiceSetModel(arg);
|
|
@@ -38268,7 +38408,6 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
|
|
|
38268
38408
|
{ key: "clone", label: "Clone Voice", detail: "drag & drop audio file" },
|
|
38269
38409
|
{ key: "list", label: "Manage Clone Voices", detail: "rename, play, delete" }
|
|
38270
38410
|
];
|
|
38271
|
-
ctx.setOverlayActive?.(true);
|
|
38272
38411
|
const result = await tuiSelect({
|
|
38273
38412
|
items,
|
|
38274
38413
|
title: "Voice Configuration",
|
|
@@ -38276,7 +38415,6 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
|
|
|
38276
38415
|
availableRows: ctx.availableContentRows?.(),
|
|
38277
38416
|
skipKeys: ["header-status", "header-config"]
|
|
38278
38417
|
});
|
|
38279
|
-
ctx.setOverlayActive?.(false);
|
|
38280
38418
|
if (!result.confirmed || !result.key)
|
|
38281
38419
|
return;
|
|
38282
38420
|
switch (result.key) {
|
|
@@ -38287,7 +38425,6 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
|
|
|
38287
38425
|
continue;
|
|
38288
38426
|
}
|
|
38289
38427
|
case "mode": {
|
|
38290
|
-
ctx.setOverlayActive?.(true);
|
|
38291
38428
|
const modeItems = [
|
|
38292
38429
|
{ key: "chat", label: "Chat", detail: "speaks streamed model text at normal pitch" },
|
|
38293
38430
|
{ key: "action", label: "Action", detail: "speaks tool call narrations with emotion pitch" },
|
|
@@ -38300,7 +38437,6 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
|
|
|
38300
38437
|
rl: ctx.rl,
|
|
38301
38438
|
availableRows: ctx.availableContentRows?.()
|
|
38302
38439
|
});
|
|
38303
|
-
ctx.setOverlayActive?.(false);
|
|
38304
38440
|
if (modeResult.confirmed && modeResult.key) {
|
|
38305
38441
|
const mode = modeResult.key;
|
|
38306
38442
|
ctx.voiceSetMode?.(mode);
|
|
@@ -38309,7 +38445,6 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
|
|
|
38309
38445
|
continue;
|
|
38310
38446
|
}
|
|
38311
38447
|
case "voice": {
|
|
38312
|
-
ctx.setOverlayActive?.(true);
|
|
38313
38448
|
const voiceItems = [
|
|
38314
38449
|
{ key: "header-onnx", label: selectColors.dim("\u2500\u2500\u2500 ONNX Voices \u2500\u2500\u2500") },
|
|
38315
38450
|
{ key: "glados", label: "GLaDOS", detail: "Portal AI voice (ONNX)" },
|
|
@@ -38330,15 +38465,13 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
|
|
|
38330
38465
|
availableRows: ctx.availableContentRows?.(),
|
|
38331
38466
|
skipKeys: ["header-onnx", "header-mlx", "header-clone"]
|
|
38332
38467
|
});
|
|
38333
|
-
ctx.setOverlayActive?.(false);
|
|
38334
38468
|
if (voiceResult.confirmed && voiceResult.key) {
|
|
38335
|
-
|
|
38469
|
+
await ctx.voiceSetModel(voiceResult.key);
|
|
38336
38470
|
save({ voice: true, voiceModel: voiceResult.key });
|
|
38337
38471
|
}
|
|
38338
38472
|
continue;
|
|
38339
38473
|
}
|
|
38340
38474
|
case "system": {
|
|
38341
|
-
ctx.setOverlayActive?.(true);
|
|
38342
38475
|
const sysItems = [
|
|
38343
38476
|
{ key: "onnx", label: "Piper ONNX", detail: "cross-platform, fast, offline" },
|
|
38344
38477
|
{ key: "luxtts", label: "LuxTTS", detail: "voice cloning, Python venv" },
|
|
@@ -38355,10 +38488,8 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
|
|
|
38355
38488
|
availableRows: ctx.availableContentRows?.(),
|
|
38356
38489
|
skipKeys: ["header-import"]
|
|
38357
38490
|
});
|
|
38358
|
-
ctx.setOverlayActive?.(false);
|
|
38359
38491
|
if (sysResult.confirmed && sysResult.key) {
|
|
38360
38492
|
if (sysResult.key === "import-onnx") {
|
|
38361
|
-
ctx.setOverlayActive?.(true);
|
|
38362
38493
|
const onnxDrop = await showDropPanel({
|
|
38363
38494
|
title: "Import Piper Voice \u2014 Drop .onnx File",
|
|
38364
38495
|
instruction: "Drag and drop the .onnx model file",
|
|
@@ -38366,11 +38497,9 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
|
|
|
38366
38497
|
typeLabel: "ONNX model",
|
|
38367
38498
|
rl: ctx.rl
|
|
38368
38499
|
});
|
|
38369
|
-
ctx.setOverlayActive?.(false);
|
|
38370
38500
|
if (!onnxDrop.confirmed || !onnxDrop.path) {
|
|
38371
38501
|
continue;
|
|
38372
38502
|
}
|
|
38373
|
-
ctx.setOverlayActive?.(true);
|
|
38374
38503
|
const jsonDrop = await showDropPanel({
|
|
38375
38504
|
title: "Import Piper Voice \u2014 Drop .onnx.json Config",
|
|
38376
38505
|
instruction: "Drag and drop the .onnx.json config file for the model",
|
|
@@ -38378,7 +38507,6 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
|
|
|
38378
38507
|
typeLabel: "JSON config",
|
|
38379
38508
|
rl: ctx.rl
|
|
38380
38509
|
});
|
|
38381
|
-
ctx.setOverlayActive?.(false);
|
|
38382
38510
|
if (!jsonDrop.confirmed || !jsonDrop.path) {
|
|
38383
38511
|
continue;
|
|
38384
38512
|
}
|
|
@@ -38409,7 +38537,6 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
|
|
|
38409
38537
|
continue;
|
|
38410
38538
|
}
|
|
38411
38539
|
case "clone": {
|
|
38412
|
-
ctx.setOverlayActive?.(true);
|
|
38413
38540
|
const dropResult = await showDropPanel({
|
|
38414
38541
|
title: "Voice Clone \u2014 Drop Audio File",
|
|
38415
38542
|
instruction: "Drag and drop an audio file to use as voice clone reference",
|
|
@@ -38417,20 +38544,15 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
|
|
|
38417
38544
|
typeLabel: "Audio files",
|
|
38418
38545
|
rl: ctx.rl
|
|
38419
38546
|
});
|
|
38420
|
-
ctx.setOverlayActive?.(false);
|
|
38421
38547
|
if (dropResult.confirmed && dropResult.path && ctx.voiceClone) {
|
|
38422
38548
|
await ctx.voiceClone(dropResult.path);
|
|
38423
38549
|
const newFilename = ctx.voiceGetLastClonedFilename?.();
|
|
38424
|
-
ctx.setOverlayActive?.(true);
|
|
38425
38550
|
await handleVoiceList(ctx, newFilename ?? void 0);
|
|
38426
|
-
ctx.setOverlayActive?.(false);
|
|
38427
38551
|
}
|
|
38428
38552
|
continue;
|
|
38429
38553
|
}
|
|
38430
38554
|
case "list": {
|
|
38431
|
-
ctx.setOverlayActive?.(true);
|
|
38432
38555
|
await handleVoiceList(ctx);
|
|
38433
|
-
ctx.setOverlayActive?.(false);
|
|
38434
38556
|
continue;
|
|
38435
38557
|
}
|
|
38436
38558
|
}
|
|
@@ -46312,7 +46434,7 @@ var init_braille_spinner = __esm({
|
|
|
46312
46434
|
});
|
|
46313
46435
|
|
|
46314
46436
|
// packages/cli/dist/tui/system-metrics.js
|
|
46315
|
-
import { loadavg as loadavg2, cpus as cpus2, totalmem as
|
|
46437
|
+
import { loadavg as loadavg2, cpus as cpus2, totalmem as totalmem3, freemem as freemem2, platform as platform4 } from "node:os";
|
|
46316
46438
|
import { exec as exec3 } from "node:child_process";
|
|
46317
46439
|
import { readFile as readFile16 } from "node:fs/promises";
|
|
46318
46440
|
function formatRate(bytesPerSec) {
|
|
@@ -46446,7 +46568,7 @@ function collectCpuRam() {
|
|
|
46446
46568
|
const [l1] = loadavg2();
|
|
46447
46569
|
const cores = cpus2().length;
|
|
46448
46570
|
const cpuModel = cpus2()[0]?.model ?? "";
|
|
46449
|
-
const totalMem =
|
|
46571
|
+
const totalMem = totalmem3();
|
|
46450
46572
|
const usedMem = totalMem - freemem2();
|
|
46451
46573
|
return {
|
|
46452
46574
|
cpuUtil: Math.min(100, Math.round(l1 / cores * 100)),
|
|
@@ -48410,14 +48532,18 @@ function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce
|
|
|
48410
48532
|
}
|
|
48411
48533
|
backend = new CascadeBackend(config.model, [primaryEndpoint, ...fallbackEndpoints], {
|
|
48412
48534
|
onSwitch: (_from, to, reason) => {
|
|
48413
|
-
|
|
48535
|
+
const msg = `
|
|
48414
48536
|
[cascade] Failover \u2192 ${to.label ?? to.url}: ${reason}
|
|
48415
|
-
|
|
48537
|
+
`;
|
|
48538
|
+
if (!bufferIfOverlay("stderr", msg))
|
|
48539
|
+
process.stderr.write(msg);
|
|
48416
48540
|
},
|
|
48417
48541
|
onProbeResult: (ep, success) => {
|
|
48418
48542
|
if (success) {
|
|
48419
|
-
|
|
48420
|
-
|
|
48543
|
+
const msg = `[cascade] Primary recovered: ${ep.label ?? ep.url}
|
|
48544
|
+
`;
|
|
48545
|
+
if (!bufferIfOverlay("stderr", msg))
|
|
48546
|
+
process.stderr.write(msg);
|
|
48421
48547
|
}
|
|
48422
48548
|
}
|
|
48423
48549
|
});
|
|
@@ -48657,8 +48783,22 @@ ${entry.fullContent}`
|
|
|
48657
48783
|
let streamStartMs = 0;
|
|
48658
48784
|
let streamTextBuffer = "";
|
|
48659
48785
|
const contentWrite = (fn) => {
|
|
48660
|
-
if (
|
|
48786
|
+
if (isOverlayActive()) {
|
|
48787
|
+
const origWrite = process.stdout.write;
|
|
48788
|
+
const chunks = [];
|
|
48789
|
+
process.stdout.write = ((chunk) => {
|
|
48790
|
+
chunks.push(chunk);
|
|
48791
|
+
return true;
|
|
48792
|
+
});
|
|
48793
|
+
try {
|
|
48794
|
+
fn();
|
|
48795
|
+
} finally {
|
|
48796
|
+
process.stdout.write = origWrite;
|
|
48797
|
+
}
|
|
48798
|
+
for (const chunk of chunks)
|
|
48799
|
+
bufferIfOverlay("stdout", chunk);
|
|
48661
48800
|
return;
|
|
48801
|
+
}
|
|
48662
48802
|
if (statusBar?.isActive) {
|
|
48663
48803
|
statusBar.beginContentWrite();
|
|
48664
48804
|
fn();
|
|
@@ -49410,8 +49550,22 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
49410
49550
|
}
|
|
49411
49551
|
}
|
|
49412
49552
|
function writeContent(fn) {
|
|
49413
|
-
if (
|
|
49553
|
+
if (isOverlayActive()) {
|
|
49554
|
+
const origWrite = process.stdout.write;
|
|
49555
|
+
const chunks = [];
|
|
49556
|
+
process.stdout.write = ((chunk) => {
|
|
49557
|
+
chunks.push(chunk);
|
|
49558
|
+
return true;
|
|
49559
|
+
});
|
|
49560
|
+
try {
|
|
49561
|
+
fn();
|
|
49562
|
+
} finally {
|
|
49563
|
+
process.stdout.write = origWrite;
|
|
49564
|
+
}
|
|
49565
|
+
for (const chunk of chunks)
|
|
49566
|
+
bufferIfOverlay("stdout", chunk);
|
|
49414
49567
|
return;
|
|
49568
|
+
}
|
|
49415
49569
|
if (statusBar.isActive) {
|
|
49416
49570
|
statusBar.beginContentWrite();
|
|
49417
49571
|
try {
|
|
@@ -49749,7 +49903,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
49749
49903
|
return voiceEngine.lastClonedFilename;
|
|
49750
49904
|
},
|
|
49751
49905
|
setOverlayActive(active) {
|
|
49752
|
-
|
|
49906
|
+
if (active)
|
|
49907
|
+
enterOverlay();
|
|
49908
|
+
else
|
|
49909
|
+
leaveOverlay();
|
|
49753
49910
|
},
|
|
49754
49911
|
streamToggle() {
|
|
49755
49912
|
streamEnabled = !streamEnabled;
|
|
@@ -51439,7 +51596,7 @@ async function runWithTUI(task, config, repoPath) {
|
|
|
51439
51596
|
process.exit(1);
|
|
51440
51597
|
}
|
|
51441
51598
|
}
|
|
51442
|
-
var
|
|
51599
|
+
var taskManager;
|
|
51443
51600
|
var init_interactive = __esm({
|
|
51444
51601
|
"packages/cli/dist/tui/interactive.js"() {
|
|
51445
51602
|
"use strict";
|
|
@@ -51475,7 +51632,7 @@ var init_interactive = __esm({
|
|
|
51475
51632
|
init_telegram_bridge();
|
|
51476
51633
|
init_status_bar();
|
|
51477
51634
|
init_dist6();
|
|
51478
|
-
|
|
51635
|
+
init_overlay_lock();
|
|
51479
51636
|
taskManager = new BackgroundTaskManager();
|
|
51480
51637
|
}
|
|
51481
51638
|
});
|
package/package.json
CHANGED